diff --git a/dartwrf/dart_nml.py b/dartwrf/dart_nml.py index 1c63560348471a31d1060d921e318505db85c6fb..78abffcac61d5bd1260a537f6b0eb773aa05b235 100644 --- a/dartwrf/dart_nml.py +++ b/dartwrf/dart_nml.py @@ -420,6 +420,7 @@ def write_namelist(cfg: Config, just_prior_values=False) -> dict: # write to file dir_dart_run = cfg.dir_dart_run.replace('<exp>', cfg.name) write_namelist_from_dict(nml, dir_dart_run + "/input.nml") + print('Wrote namelist to', dir_dart_run + "/input.nml") # append section for RTTOV if hasattr(cfg, 'rttov_nml'): @@ -433,4 +434,3 @@ if __name__ == "__main__": cfg = Config.from_file(sys.argv[1]) nml = write_namelist(cfg) - print(nml) diff --git a/templates/namelist.input b/templates/namelist.input index 430be87b04799e3cadea1d314996a65ba6fc5584..1f6f9a196e680dda4044169901d9616a827ed944 100644 --- a/templates/namelist.input +++ b/templates/namelist.input @@ -43,8 +43,8 @@ e_sn = 201, 43, 43, s_vert = 1, 1, 1, e_vert = 101, 41, 41, - dx = 1000, 666.6666667, 222.2222222 - dy = 1000, 666.6666667, 222.2222222 + dx = 2000, 666.6666667, 222.2222222 + dy = 2000, 666.6666667, 222.2222222 ztop = 22000, 20000, 20000, grid_id = 1, 2, 3, parent_id = 0, 1, 2, diff --git a/templates/namelist.input-testsinglenode b/templates/namelist.input-testsinglenode new file mode 100644 index 0000000000000000000000000000000000000000..07c2f4d6b3a2731e2f3d4b42e3fbab92061697ee --- /dev/null +++ b/templates/namelist.input-testsinglenode @@ -0,0 +1,130 @@ + &time_control + start_year = 2000, 2001, 2001, + start_month = 01, 01, 01, + start_day = 01, 01, 01, + start_hour = 00, 00, 00, + start_minute = 00, 00, 00, + start_second = 00, 00, 00, + end_year = 2001, 2001, 2001, + end_month = 01, 01, 01, + end_day = 01, 01, 01, + end_hour = 00, 00, 00, + end_minute = 00, 00, 00, + end_second = 00, 00, 00, + interval_seconds = 86400 + history_interval_s = 300, + write_hist_at_0h_rst = .true., + frames_per_outfile = 1, 1, 1, + restart = .false., + override_restart_timers = .true., + restart_interval = 99999, + io_form_history = 2 + io_form_restart = 2 + io_form_input = 2 + io_form_boundary = 2 + nwp_diagnostics = 0 + / + + &domains + use_adaptive_time_step = .true., + target_cfl = 1.2, 1.2, 1.2, + max_step_increase_pct = 5, 51, 51, + starting_time_step = 4, + max_time_step = 16, + min_time_step = 3, + time_step = 8, + time_step_fract_num = 0, + time_step_fract_den = 1, + step_to_output_time = .true., + max_dom = 1, + s_we = 1, 1, 1, + e_we = 201, 43, 43, + s_sn = 1, 1, 1, + e_sn = 201, 43, 43, + s_vert = 1, 1, 1, + e_vert = 11, 41, 41, + dx = 2000, 666.6666667, 222.2222222 + dy = 2000, 666.6666667, 222.2222222 + ztop = 10000, 20000, 20000, + grid_id = 1, 2, 3, + parent_id = 0, 1, 2, + i_parent_start = 0, 15, 15, + j_parent_start = 0, 15, 15, + parent_grid_ratio = 1, 3, 3, + parent_time_step_ratio = 1, 3, 3, + !eta_levels = 1.0000, 0.9969, 0.9923, 0.9857, 0.9762, 0.9627, 0.9443, 0.9200, 0.8892, 0.8525, 0.8111, 0.7671, 0.7223, 0.6782, 0.6357, 0.5949, 0.5558, 0.5183, 0.4824, 0.4482, 0.4155, 0.3844, 0.3547, 0.3266, 0.2999, 0.2750, 0.2519, 0.2304, 0.2105, 0.1919, 0.1747, 0.1586, 0.1437, 0.1299, 0.1170, 0.1050, 0.0939, 0.0836, 0.0740, 0.0650, 0.0567, 0.0490, 0.0419, 0.0352, 0.0290, 0.0232, 0.0179, 0.0129, 0.0083, 0.0040, 0.0000 + !eta_levels = 1.0000, 0.99, 0.98, 0.97, 0.96, 0.95, 0.94, 0.93, 0.92, 0.91, 0.9, 0.89, 0.88, 0.87, 0.86, 0.85, 0.84, 0.83, 0.82, 0.81, 0.8, 0.79, 0.78, 0.77, 0.76, 0.75, 0.74, 0.73, 0.72, 0.71, 0.7, 0.69, 0.68, 0.67, 0.66, 0.65, 0.64, 0.63, 0.62, 0.61, 0.6, 0.59, 0.58, 0.57, 0.56, 0.55, 0.54, 0.53, 0.52, 0.51, 0.5, 0.49, 0.48, 0.47, 0.46, 0.45, 0.44, 0.43, 0.42, 0.41, 0.4, 0.39, 0.38, 0.37, 0.36, 0.35, 0.34, 0.33, 0.32, 0.31, 0.3, 0.29, 0.28, 0.27, 0.26, 0.25, 0.24, 0.23, 0.22, 0.21, 0.2, 0.19, 0.18, 0.17, 0.16, 0.15, 0.14, 0.13, 0.12, 0.11, 0.1, 0.08999997, 0.07999998, 0.06999999, 0.06, 0.05000001, 0.04000002, 0.02999997, 0.01999998, 0.00999999, 0.0000 + / + + &physics + mp_physics = 1, 1, 1, + ra_lw_physics = 0, 0, 0, + ra_sw_physics = 0, 0, 0, + radt = 1, 30, 30, + sf_sfclay_physics = 1, 0, 0, + sf_surface_physics = 1, 0, 0, + bl_pbl_physics = 0, 0, 0, + bldt = 0, 0, 0, + cu_physics = 0, 0, 0, + cudt = 5, 5, 5, + do_radar_ref = 0, + icloud_bl = 1, + / + + &fdda + / + + &dynamics + hybrid_opt = 0, + rk_ord = 3, + diff_opt = 1, 1, 1, + km_opt = 4, 4, 2, + damp_opt = 2, + zdamp = 5000., 5000., 5000., + dampcoef = 0.003, 0.003, 0.003 + w_damping = 1, + khdif = 500, 500, 500, + kvdif = 500, 500, 500, + smdiv = 0.1, 0.1, 0.1, + emdiv = 0.01, 0.01, 0.01, + epssm = 0.1, 0.1, 0.1 + time_step_sound = 0, 6, 6, + h_mom_adv_order = 5, 5, 5, + v_mom_adv_order = 5, 3, 3, + h_sca_adv_order = 5, 5, 5, + v_sca_adv_order = 5, 3, 3, + moist_adv_opt = 1, 1, 1, + scalar_adv_opt = 1, 1, 1, + chem_adv_opt = 1, 1, 1, + tke_adv_opt = 1, 1, 1, + non_hydrostatic = .true., .true., .true., + mix_full_fields = .true., .true., .true., + use_theta_m = 1, + top_lid = .true., + pert_coriolis = .true., + / + + &bdy_control + periodic_x = .true., + symmetric_xs = .false., + symmetric_xe = .false., + open_xs = .false., + open_xe = .false., + periodic_y = .true., + symmetric_ys = .false., + symmetric_ye = .false., + open_ys = .false., + open_ye = .false., + / + + &grib2 + / + + &namelist_quilt + nio_tasks_per_group = 0, + nio_groups = 1, + / + + &ideal + ideal_case = 9 ! les + / diff --git a/test-singlenode.py b/test-singlenode.py index 5adb862914b068a1607468e14c3c16d13b26167b..110f414a43853443ae366573072224a7fbad9cdf 100644 --- a/test-singlenode.py +++ b/test-singlenode.py @@ -1,6 +1,7 @@ +"""Run experiments in one script without SLURM. +""" from timer import Timer - with Timer('imports'): import datetime as dt import pandas as pd @@ -11,11 +12,39 @@ with Timer('imports'): from config.jet_1node import cluster_defaults from config.defaults import dart_nml +def runWRF(cfg): + cmd = cfg.wrf_modules +'; ' + + for iens in range(1, cfg.ensemble_size+1): + dir_wrf_run = cfg.dir_wrf_run.replace('<exp>', cfg.name).replace('<ens>', str(iens)) + + cmd += 'cd ' + dir_wrf_run + '; ' + cmd += 'echo "'+dir_wrf_run+'"; ' + cmd += 'mpirun -np 4 ./wrf.exe & ' + + cmd += 'wait; ' + cmd += 'echo "WRF run completed."' + + # Run the command in the specified directory + run_bash_command_in_directory(cmd, dir_wrf_run) + +def runIdeal(cfg): + cmd = cfg.wrf_modules +'; ' + + for iens in range(1, cfg.ensemble_size+1): + dir_wrf_run = cfg.dir_wrf_run.replace('<exp>', cfg.name).replace('<ens>', str(iens)) + + cmd += 'cd ' + dir_wrf_run + '; ' + cmd += 'echo "'+dir_wrf_run+'"; ' + cmd += 'mpirun -np 1 ./ideal.exe & ' -ensemble_size = 5 + cmd += 'wait; ' + cmd += 'echo "ideal.exe completed."' -dart_nml['&filter_nml'].update(num_output_state_members=ensemble_size, - ens_size=ensemble_size) + # Run the command in the specified directory + run_bash_command_in_directory(cmd, dir_wrf_run) + +############################### t = dict(var_name='Temperature', unit='[K]', @@ -23,17 +52,32 @@ t = dict(var_name='Temperature', unit='[K]', # n_obs=22500, n_obs=1, obs_locations=[(45., 0.)], error_generate=0.2, error_assimilate=0.2, - heights=range(1000, 17001, 2000), + heights=range(1000, 3001, 1000), loc_horiz_km=1000, loc_vert_km=4) -assimilate_these_observations = [t,] #cf3, cf4, cf5,] +assimilate_these_observations = [t,] -time0 = dt.datetime(2008, 7, 30, 11) +time0 = dt.datetime(2008, 7, 30, 10) time_end = dt.datetime(2008, 7, 30, 11) id = None with Timer('Config()'): + # update defaults + ensemble_size = 4 + dart_nml['&filter_nml'].update(num_output_state_members=ensemble_size, + ens_size=ensemble_size) + dart_nml['&model_nml'].update( + dict(wrf_state_variables=[ + ['U', 'QTY_U_WIND_COMPONENT', 'TYPE_U', 'UPDATE', '999',], + ['V', 'QTY_V_WIND_COMPONENT', 'TYPE_V', 'UPDATE', '999',], + ['W', 'QTY_VERTICAL_VELOCITY', 'TYPE_W', 'UPDATE', '999',], + ['PH', 'QTY_GEOPOTENTIAL_HEIGHT', 'TYPE_GZ', 'UPDATE', '999',], + ['THM', 'QTY_POTENTIAL_TEMPERATURE', 'TYPE_T', 'UPDATE', '999',], + ['MU', 'QTY_PRESSURE', 'TYPE_MU', 'UPDATE', '999',], + ['QVAPOR', 'QTY_VAPOR_MIXING_RATIO','TYPE_QV', 'UPDATE', '999',], + ])) + cfg = Config(name='test-1node', model_dx = 2000, ensemble_size = ensemble_size, @@ -47,22 +91,43 @@ with Timer('Config()'): nature_wrfout_pattern = '/jetfs/home/lkugler/data/sim_archive/exp_v1.18_P1_nature+1/*/1/wrfout_d01_%Y-%m-%d_%H:%M:%S', geo_em_nature = '/jetfs/home/lkugler/data/sim_archive/geo_em.d01.nc.2km_200x200', - update_vars = ['U', 'V', 'W', 'THM', 'PH', 'MU', 'QVAPOR', 'QCLOUD', 'QICE', 'QSNOW', 'PSFC'], + update_vars = ['U', 'V', 'W', 'THM', 'PH', 'MU',], #input_profile = '/jetfs/home/lkugler/data/sim_archive/nat_250m_1600x1600x100/2008-07-30_08:00/1/input_sounding', verify_against = 'nat_250m_blockavg2km', **cluster_defaults) + + with Timer('prepare_WRFrundir'): w = WorkFlows(cfg) import dartwrf.prepare_wrfrundir as prepwrf prepwrf.run(cfg) - # w.prepare_WRFrundir(cfg) + + +with Timer('ideal.exe'): + runIdeal(cfg) + +# spinup +timedelta_integrate = dt.timedelta(hours=1) +t_spinup_end = time0 + timedelta_integrate +restart_interval = timedelta_integrate.total_seconds()/60 # in minutes + +cfg.update( WRF_start=time0, + WRF_end=t_spinup_end, + restart=False, # from wrfinput + restart_interval=restart_interval, + hist_interval_s=300, +) +import dartwrf.prepare_namelist as prepnl +prepnl.run(cfg) + +with Timer('run_WRF'): + runWRF(cfg) -# id = w.run_ideal(cfg, depends_on=id) # assimilate at these times timedelta_btw_assim = dt.timedelta(minutes=15) -assim_times = pd.date_range(time0, time_end, freq=timedelta_btw_assim) +assim_times = pd.date_range(t_spinup_end, time_end, freq=timedelta_btw_assim) #assim_times = [dt.datetime(2008, 7, 30, 12), dt.datetime(2008, 7, 30, 13), dt.datetime(2008, 7, 30, 14),] last_assim_time = assim_times[-1] @@ -70,12 +135,12 @@ last_assim_time = assim_times[-1] # loop over assimilations for i, t in enumerate(assim_times): - if i == 0 and t == dt.datetime(2008, 7, 30, 11): + if i == 0: cfg.update( time = t, - prior_init_time = dt.datetime(2008, 7, 30, 8), - prior_valid_time = t, - prior_path_exp = '/jetfs/home/lkugler/data/sim_archive/exp_nat250m_noDA/') + prior_init_time = time0, + prior_valid_time = t_spinup_end, + prior_path_exp = '/jetfs/home/lkugler/data/sim_archive/test-1node/') #'/jetfs/home/lkugler/data/sim_archive/exp_nat250m_noDA/') else: cfg.update( time = t, @@ -84,19 +149,16 @@ for i, t in enumerate(assim_times): prior_path_exp = cfg.dir_archive,) with Timer('assimilate'): - #id = w.assimilate(cfg, depends_on=id) - import dartwrf.assimilate as da - da.main(cfg) + import dartwrf.assimilate as assim + assim.main(cfg) with Timer('prepare_IC_from_prior'): # 1) Set posterior = prior - #id = w.prepare_IC_from_prior(cfg, depends_on=id) import dartwrf.prep_IC_prior as prep prep.main(cfg) with Timer('update_IC_from_DA'): # 2) Update posterior += updates from assimilation - #id = w.update_IC_from_DA(cfg, depends_on=id) import dartwrf.update_IC as upd upd.update_initials_in_WRF_rundir(cfg) @@ -115,21 +177,5 @@ for i, t in enumerate(assim_times): prepnl.run(cfg) # 3) Run WRF ensemble - #id = w.run_WRF(cfg, depends_on=id) - with Timer('run_WRF'): - # Example usage: - cmd = cfg.wrf_modules +'; ' - - for iens in range(1, cfg.ensemble_size+1): - dir_wrf_run = cfg.dir_wrf_run.replace('<exp>', cfg.name).replace('<ens>', str(iens)) - - cmd += 'cd ' + dir_wrf_run + '; ' - cmd += 'echo "'+dir_wrf_run+'"; ' - cmd += 'mpirun -np 4 ./wrf.exe & ' - - cmd += 'wait; ' - cmd += 'echo "WRF run completed."' - - # Run the command in the specified directory - run_bash_command_in_directory(cmd, dir_wrf_run) + runWRF(cfg) \ No newline at end of file