Skip to content

Instantly share code, notes, and snippets.

@jamesp
Created July 20, 2020 15:02
Show Gist options
  • Save jamesp/4b94941620cec9aa1c2546b6e8a536eb to your computer and use it in GitHub Desktop.
Save jamesp/4b94941620cec9aa1c2546b6e8a536eb to your computer and use it in GitHub Desktop.
import os
import numpy as np
from isca import IscaCodeBase, DiagTable, Experiment, Namelist, GFDL_BASE, FailedRunError
from isca.util import exp_progress
NCORES = 16
#cb = IscaCodeBase.from_directory(GFDL_BASE)
cb = IscaCodeBase.from_repo('https://github.com/jamesp/isca', 'jpbucket')
cb.compile() # compile the source code to working directory $GFDL_WORK/codebase
# create an Experiment object to handle the configuration of model parameters
# and output diagnostics
exp = Experiment('all_buckets_rrtm', codebase=cb)
#Add any input files that are necessary for a particular experiment.
exp.inputfiles = ['input/all_land.nc']
#Tell model how to write diagnostics
diag = DiagTable()
diag.add_file('daily', 1, 'days', time_units='days')
#Tell model which diagnostics to write
diag.add_field('dynamics', 'ps', time_avg=True)
diag.add_field('dynamics', 'bk')
diag.add_field('dynamics', 'pk')
diag.add_field('atmosphere', 'precipitation', time_avg=True)
diag.add_field('atmosphere', 'bucket_depth', time_avg=True)
diag.add_field('mixed_layer', 't_surf', time_avg=True)
diag.add_field('dynamics', 'sphum', time_avg=True)
diag.add_field('dynamics', 'ucomp', time_avg=True)
diag.add_field('dynamics', 'vcomp', time_avg=True)
diag.add_field('dynamics', 'temp', time_avg=True)
diag.add_field('dynamics', 'vor', time_avg=True)
diag.add_field('dynamics', 'div', time_avg=True)
diag.add_field('rrtm_radiation', 'coszen', time_avg=True)
exp.diag_table = diag
#Empty the run directory ready to run
exp.clear_rundir()
#Define values for the 'core' namelist
exp.namelist = namelist = Namelist({
'main_nml': {
'days' : 30,
'hours' : 0,
'minutes': 0,
'seconds': 0,
'dt_atmos': 600,
'current_date' : [0001,1,1,0,0,0],
'calendar' : 'thirty_day'
},
'idealized_moist_phys_nml': {
'do_damping': True,
'turb':True,
'mixed_layer_bc':True,
'do_virtual' :False,
'do_simple': True,
'roughness_mom':2.e-4, #Ocean roughness lengths
'roughness_heat':2.e-4,
'roughness_moist':2.e-4,
'two_stream_gray':False, #Don't use grey radiation
'do_rrtm_radiation':True, #Do use RRTM radiation
'convection_scheme':'SIMPLE_BETTS_MILLER', #Use the simple betts-miller convection scheme
'land_option':'input', #Use land mask from input file
'land_file_name': 'INPUT/all_land.nc', #Tell model where to find input file
'bucket':True, #Run with the bucket model
'init_bucket_depth_land':1., #Set initial bucket depth over land
'max_bucket_depth_land':2., #Set max bucket depth over land
},
'vert_turb_driver_nml': {
'do_mellor_yamada': False, # default: True
'do_diffusivity': True, # default: False
'do_simple': True, # default: False
'constant_gust': 0.0, # default: 1.0
'use_tau': False
},
'diffusivity_nml': {
'do_entrain':False,
'do_simple': True,
},
'surface_flux_nml': {
'use_virtual_temp': False,
'do_simple': True,
'old_dtaudv': True
},
'atmosphere_nml': {
'idealized_moist_model': True
},
#Use a large mixed-layer depth, and the Albedo of the CTRL case in Jucker & Gerber, 2017
'mixed_layer_nml': {
'tconst' : 285.,
'prescribe_initial_dist':True,
'evaporation':True,
'depth':20., #Mixed layer depth
'land_option':'input', #Tell mixed layer to get land mask from input file
'land_h_capacity_prefactor': 0.1, #What factor to multiply mixed-layer depth by over land.
'albedo_value': 0.25, #Ocean albedo value
'land_albedo_prefactor' : 1.3, #What factor to multiply ocean albedo by over land
'do_qflux' : False #Do not use prescribed qflux formula
},
'qe_moist_convection_nml': {
'rhbm':0.7,
'Tmin':160.,
'Tmax':350.
},
'rrtm_radiation_nml': {
'do_read_ozone':False,
#'ozone_file':'ozone_1990',
'solr_cnst': 1360., #s set solar constant to 1360, rather than default of 1368.22
'dt_rad': 7200,
'equinox_day': 0.0
},
'lscale_cond_nml': {
'do_simple':True,
'do_evap':True
},
'sat_vapor_pres_nml': {
'do_simple':True
},
'damping_driver_nml': {
'do_rayleigh': True,
'trayfric': -0.5, # neg. value: time in *days*
'sponge_pbottom': 150., #Setting the lower pressure boundary for the model sponge layer in Pa.
'do_conserve_energy': True,
},
# FMS Framework configuration
'diag_manager_nml': {
'mix_snapshot_average_fields': False # time avg fields are labelled with time in middle of window
},
'fms_nml': {
'domains_stack_size': 600000 # default: 0
},
'fms_io_nml': {
'threading_write': 'single', # default: multi
'fileset_write': 'single', # default: multi
},
'spectral_dynamics_nml': {
'damping_order': 4,
'water_correction_limit': 200.e2,
'reference_sea_level_press':1.0e5,
'num_levels':25,
'valid_range_t':[100.,800.],
'initial_sphum':[2.e-6],
'vert_coord_option':'uneven_sigma',
'scale_heights': 6.0,
'exponent': 7.5,
'surf_res': 0.5,
'robert_coeff':0.03
}
})
exps = []
dry = exp.derive('all_buckets_rrtm_dry')
dry.update_namelist({
'spectral_dynamics_nml': {
'initial_sphum': 2e-6
},
'damping_driver_nml': {
'sponge_pbottom': 1800.0, # 18hPa: approx 4 levels
},
'idealized_moist_phys_nml': {
'init_bucket_depth_land': 0.05, # m
'bucket_can_overflow': False, # unlimited depth of bucket
'bucket_max_evap_depth': 0.1 # when depth > 0.1m, evaporate at maximal velocity E0.
# E = (depth/max_evap_depth)*E0 otherwise
}
})
exps.append(dry)
# as above, but more water in the bucket
wet = dry.derive('all_buckets_rrtm_wet')
wet.update_namelist({
'idealized_moist_phys_nml': {
'init_bucket_depth_land': 0.5
}
})
exps.append(wet)
# # as above, but hotter
# hot = wet.derive('all_buckets_rrtm_dry')
# hot.update_namelist({
# 'mixed_layer_nml': {
# 'land_albedo_prefactor': 0.7 # default 1.0
# }
# })
# exps.append(hot)
deep = dry.derive('all_buckets_rrtm_inf_water')
deep.update_namelist({
'idealized_moist_phys_nml': {
'init_bucket_depth_land': 1e14
}
})
exps.append(deep)
for o in (0., 23., 40., 60.):
obl = wet.derive('all_buckets_rrtm_obl%d' % o)
obl.update_namelist({
'astronomy_nml': {
'obliq': o, # planetary obliquity
},
})
exps.append(obl)
for e in exps:
with exp_progress(e, description='{date}') as pbar:
e.run(1, use_restart=False, num_cores=NCORES)
broken = []
for i in range(2, 121):
for e in exps:
if e not in broken:
with exp_progress(e, description='{date}') as pbar:
try:
e.run(i, num_cores=NCORES, nice_score=5)
except FailedRunError as e:
broken.append(e)
continue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment