Example #1
0
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()
Example #2
0
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()
Example #3
0
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)
Example #4
0
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()
Example #5
0
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()
Example #6
0
def set_ocean_timestep(exp, timestep):

    nml = FortranNamelist(input_ocn.format(exp))
    nml.set_value('ocean_model_nml', 'dt_ocean', timestep)
    nml.write()
Example #7
0
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()
Example #8
0
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()
Example #9
0
def set_ocean_timestep(experiment, timestep):

    nml = FortranNamelist(input_ocn % (experiment))
    nml.set_value('ocean_model_nml', 'dt_ocean', timestep)
    nml.write()
Example #10
0
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()