def prepare_newrun(exp_dir, model, input_dir): """ Anything that needs to be done before the model starts. """ # Delete and remake old INPUT and RESTART dirs, these get polluted. e.g. by oasis writing over the restart files. for d, m in [('ATM_RUNDIR', 'atm'), ('ICE_RUNDIR', 'ice'), ('OCN_RUNDIR', 'ocn')]: rundir = os.path.join(exp_dir, d) if os.path.exists(rundir): shutil.rmtree(rundir) if model == 'access' and d == 'ATM_RUNDIR': input = rundir else: input = os.path.join(exp_dir, d, 'INPUT') restart = os.path.join(exp_dir, d, 'RESTART') history = os.path.join(exp_dir, d, 'HISTORY') os.makedirs(input) os.makedirs(restart) os.makedirs(history) # Copy over inputs and fix perms. for f in glob.glob('%s/*' % os.path.join(input_dir, m)): shutil.copy(f, input) os.chmod(os.path.join(input, os.path.basename(f)), 0664) # Copy oasis files into input dir. for f in glob.glob('%s/*' % os.path.join(input_dir, 'oasis')): if model == 'access': shutil.copy(f, rundir) os.chmod(os.path.join(rundir, os.path.basename(f)), 0664) else: shutil.copy(f, input) os.chmod(os.path.join(input, os.path.basename(f)), 0664) # For some reason cice needs o2i.nc in a special place. FIXME. if model == 'access' and d == 'ICE_RUNDIR': shutil.copy(os.path.join(rundir, 'o2i.nc'), os.path.join(restart, 'o2i.nc')) # Copy fresh config files into place. for f in glob.glob('%s/config/*' % exp_dir): shutil.copy(f, os.path.join(exp_dir, d)) shutil.copytree(os.path.join(exp_dir, 'atm_tmp_ctrl'), os.path.join(exp_dir, 'ATM_RUNDIR', 'tmp_ctrl')) os.makedirs(os.path.join(exp_dir, 'ATM_RUNDIR', 'tmp')) if model == 'access': # Tell CABLE that this is not a cont run. nml = FortranNamelist(os.path.join(exp_dir, 'ATM_RUNDIR', 'cable.nml')) nml.set_value('cable', 'cable_user%CABLE_RUNTIME_COUPLED', '.FALSE.') nml.write()
def prepare_contrun(exp_dir, model, cont_date): """ Anything that needs to be done before a continuation run, apart from setting up the dates. There are some things that the models should take care of themselves. """ cont_date_str = date_to_str(cont_date) ice_input = os.path.join(exp_dir, 'ICE_RUNDIR', 'INPUT') ice_restart = os.path.join(exp_dir, 'ICE_RUNDIR', 'RESTART') ocn_input = os.path.join(exp_dir, 'OCN_RUNDIR', 'INPUT') ocn_restart = os.path.join(exp_dir, 'OCN_RUNDIR', 'RESTART') # Copy over some CICE files. if model == 'access': shutil.copy(os.path.join(exp_dir, 'ICE_RUNDIR', 'mice.nc'), ice_input) else: shutil.copy(os.path.join(ice_restart, 'u_star.nc'), ice_input) shutil.copy(os.path.join(ice_restart, 'sicemass.nc'), ice_input) # Setup the CICE restart. # Check that restart file for this start date exists. assert(os.path.exists(os.path.join(ice_restart, 'iced.%s' % (cont_date_str)))) with open(os.path.join(ice_restart, 'ice.restart_file'), 'w') as f: f.write('iced.%s' % cont_date_str) # Copy over ocean restarts. for f in glob.glob('%s/*' % ocn_restart): shutil.copy(f, ocn_input) # Copy fresh config files into place. FIXME: This is being done in newrun also. for d in ['ATM_RUNDIR', 'ICE_RUNDIR','OCN_RUNDIR']: for f in glob.glob('%s/config/*' % exp_dir): shutil.copy(f, os.path.join(exp_dir, d)) if model == 'access': # Copy over the oasis restarts. FIXME: should this be done for auscom model? shutil.copy(os.path.join(ocn_input, 'o2i.nc'), ice_restart) # Copy over UM restart file. um_restart_src = os.path.join(exp_dir, 'ATM_RUNDIR', 'aiihca.da%s' % date_to_um_date(cont_date)) um_restart_dest = os.path.join(exp_dir, 'ATM_RUNDIR', 'PIC2C-0.25.astart') shutil.copy(um_restart_src, um_restart_dest) # Tell CABLE that this is a cont run. nml = FortranNamelist(os.path.join(exp_dir, 'ATM_RUNDIR', 'cable.nml')) nml.set_value('cable', 'cable_user%CABLE_RUNTIME_COUPLED', '.TRUE.') nml.write()
def set_next_startdate(exp_dir, init_date, prev_start_date, runtime_per_submit, submit_num, newrun, model): """ Tell the models when to start by modifying the input namelists. runtime_per_submit is in months. """ if prev_start_date is None: start_date = init_date else: prev_end_date = add_months_to_date(prev_start_date, runtime_per_submit) start_date = prev_end_date end_date = add_months_to_date(start_date, runtime_per_submit) assert(init_date.day == 1) assert((prev_start_date is None) or prev_start_date.day == 1) assert(start_date.day == 1) days_since_start = ndays_between_dates(init_date, start_date, model == 'access') days_this_run = ndays_between_dates(start_date, end_date, model == 'access') # init_date is the start date of the experiment. init_str = date_to_str(init_date) run_str = date_to_str(start_date) atm_rundir = os.path.join(exp_dir, 'ATM_RUNDIR') # Atmos. if model == 'auscom': nml = FortranNamelist(os.path.join(atm_rundir, 'input_atm.nml')) # The start of the experiment. nml.set_value('coupling', 'init_date', init_str) # The start of the run. nml.set_value('coupling', 'inidate', run_str) nml.set_value('coupling', 'truntime0', days_since_start*86400) nml.set_value('coupling', 'runtime', days_this_run*86400) nml.write() else: # Changes for the UM. nml = FortranNamelist(os.path.join(atm_rundir, 'tmp_ctrl', 'CNTLALL')) # Run length nml.set_value('NLSTCALL', 'RUN_TARGET_END', '0, 0, %s, 0, 0, 0' % days_this_run) # Resubmit increement nml.set_value('NLSTCALL', 'RUN_RESUBMIT_INC', '0, 0, %s, 0, 0, 0' % days_this_run) # Start time nml.set_value('NLSTCALL', 'MODEL_BASIS_TIME', '%s, %s, %s, 0, 0, 0' % (run_str[0:4], run_str[4:6], run_str[6:8])) nml.set_value('NLSTCALL', 'ANCIL_REFTIME', '%s, %s, %s, 0, 0, 0' % (run_str[0:4], run_str[4:6], run_str[6:8])) nml.write() nml = FortranNamelist(os.path.join(atm_rundir, 'tmp_ctrl', 'SIZES')) nml.set_value('STSHCOMP', 'RUN_TARGET_END', '0, 0, %s, 0, 0, 0' % days_this_run) nml.write() def dump_times_string(start_date, num_dumps): """ Create a string for the dump times. Presently we dump each month. """ assert(start_date.day == 1 and ((start_date.month + num_dumps - 1) <= 12)) str = '' total_days = 0 for m in range(num_dumps): _, days = calendar.monthrange(start_date.year, start_date.month + m) total_days += days str += '{0},'.format(total_days*48) str += '0,' * (160 - num_dumps) return str nml = FortranNamelist(os.path.join(atm_rundir, 'tmp_ctrl', 'CNTLGEN')) nml.set_value('NLSTCGEN', 'DUMPTIMESim', dump_times_string(start_date, runtime_per_submit)) nml.write() # Ice ice_rundir = os.path.join(exp_dir, 'ICE_RUNDIR') nml = FortranNamelist(os.path.join(ice_rundir, 'cice_in.nml')) nml.set_value('setup_nml', 'year_init', start_date.year) nml.set_value('setup_nml', 'runtype', '\'initial\'') if newrun else nml.set_value('setup_nml', 'runtype', '\'continue\'') nml.set_value('setup_nml', 'restart', '.false.') if newrun else nml.set_value('setup_nml', 'restart', '.true.') (dt, _, _) = nml.get_value('setup_nml', 'dt') assert(days_this_run*86400 % int(dt) == 0) nml.set_value('setup_nml', 'npt', (days_this_run*86400) // int(dt)) nml.write() nml = FortranNamelist(os.path.join(ice_rundir, 'input_ice.nml')) nml.set_value('coupling_nml', 'init_date', init_str) nml.set_value('coupling_nml', 'inidate', run_str) nml.set_value('coupling_nml', 'runtime0', days_since_start*86400) nml.set_value('coupling_nml', 'runtime', days_this_run*86400) nml.set_value('coupling_nml', 'jobnum', submit_num) nml.write() # Ocean ocn_rundir = os.path.join(exp_dir, 'OCN_RUNDIR') nml = FortranNamelist(os.path.join(ocn_rundir, 'input.nml')) nml.set_value('ocean_solo_nml', 'years', runtime_per_submit // 12) nml.set_value('ocean_solo_nml', 'months', runtime_per_submit % 12) nml.set_value('ocean_solo_nml', 'days', 0) nml.set_value('ocean_solo_nml', 'hours', 0) nml.set_value('ocean_solo_nml', 'minutes', 0) nml.set_value('ocean_solo_nml', 'seconds', 0) # This date_init value is read from RESTART/ocean_solo.res if it exists. nml.set_value('ocean_solo_nml', 'date_init', str(start_date.year).zfill(4) + ',' + str(start_date.month).zfill(2) + ',01,0,0,0') nml.write() # Oasis namcouple for r in [atm_rundir, ice_rundir, ocn_rundir]: nc = Namcouple(os.path.join(r, 'namcouple'), model) # FIXME: there is a bug in the models, an extra timestep is made at the end of a month. # This then causes an assertion failure in oasis. For the time being just increase the # oasis max by one day. nc.set_runtime((days_this_run + 1)*86400) nc.write() return (start_date, end_date)
def set_ice_timestep(exp, timestep): nml = FortranNamelist(input_ice.format(exp)) nml.set_value('coupling_nml', 'dt_cice', timestep) nml.write() nml = FortranNamelist(cice_in.format(exp)) # Read in the current timestep and runtime, needed to calculate new runtime # (in units of timestep). (dt, _, _) = nml.get_value('setup_nml', 'dt') (npt, _, _) = nml.get_value('setup_nml', 'npt') runtime = int(dt)*int(npt) new_npt = runtime // int(timestep) nml.set_value('setup_nml', 'dt', timestep) nml.set_value('setup_nml', 'npt', new_npt) nml.write() nc = Namcouple(namcouple.format(exp), 'access') nc.set_ice_timestep(timestep) nc.write()
def set_coupling_timestep(exp, timestep, uses_UM=False): # Change timestep in the namcouple file. nc = Namcouple(namcouple.format(exp), 'access') nc.set_ice_ocean_coupling_timestep(timestep) nc.write() if os.path.exists(input_atm.format(exp)) and not uses_UM: nml = FortranNamelist(input_atm.format(exp)) nml.set_value('coupling', 'dt_atm', timestep) nml.write() nml = FortranNamelist(input_ocn.format(exp)) nml.set_value('auscom_ice_nml', 'dt_cpl', timestep) nml.set_value('ocean_solo_nml', 'dt_cpld', timestep) nml.write() nml = FortranNamelist(input_ice.format(exp)) nml.set_value('coupling_nml', 'dt_cpl_io', timestep) nml.write()
def set_ocean_timestep(exp, timestep): nml = FortranNamelist(input_ocn.format(exp)) nml.set_value('ocean_model_nml', 'dt_ocean', timestep) nml.write()
def set_coupling_timestep(experiment, timestep, model): # Change timestep in the namcouple files. for n in namcouple: nc = Namcouple(n % (experiment), model) nc.set_ocean_timestep(timestep) nc.write() if model == 'auscom': nml = FortranNamelist(input_atm % (experiment)) nml.set_value('coupling', 'dt_atm', timestep) nml.write() nml = FortranNamelist(input_ocn % (experiment)) nml.set_value('auscom_ice_nml', 'dt_cpl', timestep) nml.set_value('ocean_solo_nml', 'dt_cpld', timestep) nml.write() nml = FortranNamelist(input_ice % (experiment)) nml.set_value('coupling_nml', 'dt_cpl_io', timestep) nml.write()
def set_ice_timestep(experiment, timestep): nml = FortranNamelist(input_ice % (experiment)) nml.set_value('coupling_nml', 'dt_cice', timestep) nml.write() nml = FortranNamelist(cice_in % (experiment)) # Read in the current timestep and runtime, needed to calculate new runtime (in units of timestep). (dt, _, _) = nml.get_value('setup_nml', 'dt') (npt, _, _) = nml.get_value('setup_nml', 'npt') runtime = int(dt)*int(npt) new_npt = runtime // int(timestep) nml.set_value('setup_nml', 'dt', timestep) nml.set_value('setup_nml', 'npt', new_npt) nml.write()
def set_ocean_timestep(experiment, timestep): nml = FortranNamelist(input_ocn % (experiment)) nml.set_value('ocean_model_nml', 'dt_ocean', timestep) nml.write()
def set_runtime(experiment, runtime): # Change runtime in the namcouple files. for n in namcouple: nc = Namcouple(n % (experiment)) nc.set_runtime(runtime) nc.write() nml = FortranNamelist(input_atm % (experiment)) nml.set_value('coupling', 'runtime', runtime) nml.write() nml = FortranNamelist(input_ice % (experiment)) nml.set_value('coupling_nml', 'runtime', runtime) nml.write() sec = timedelta(seconds=int(runtime)) d = datetime(1, 1, 1) + sec nml = FortranNamelist(input_ocn % (experiment)) nml.set_value('ocean_solo_nml', 'years', d.year - 1) nml.set_value('ocean_solo_nml', 'months', d.month - 1) nml.set_value('ocean_solo_nml', 'days', d.day - 1) nml.set_value('ocean_solo_nml', 'hours', d.hour) nml.set_value('ocean_solo_nml', 'minutes', d.minute) nml.set_value('ocean_solo_nml', 'seconds', d.second) nml.write()