@@ -143,40 +143,29 @@ function CoupledSimulation(config_dict::AbstractDict)
143143 ) = get_coupler_args (config_dict)
144144
145145 #=
146- ### I/O Directory Setup `setup_output_dirs` returns `dir_paths.output =
147- COUPLER_OUTPUT_DIR`, which is the directory where the output of the simulation
148- will be saved, `dir_paths.artifacts` is the directory where the plots (from
149- postprocessing and the conservation checks) of the simulation will be saved,
150- #and `dir_paths.checkpoints`, where restart files are saved.
146+ ### I/O Directory Setup
147+ `setup_output_dirs` returns a NamedTuple with the paths to
148+ output directories for each component and the coupler,
149+ as well as paths to artifacts, regrid, and checkpoints directories.
151150 =#
152-
153- dir_paths =
154- Utilities. setup_output_dirs (output_dir = output_dir_root, comms_ctx = comms_ctx)
155- @info " Coupler output directory $(dir_paths. output) "
156- @info " Coupler artifacts directory $(dir_paths. artifacts) "
157- @info " Coupler checkpoint directory $(dir_paths. checkpoints) "
158-
159- atmos_output_dir = joinpath (dir_paths. output, " clima_atmos" )
160- isdir (atmos_output_dir) || mkpath (atmos_output_dir)
161- land_output_dir = joinpath (dir_paths. output, " clima_land" )
162- isdir (land_output_dir) || mkpath (land_output_dir)
163- ocean_output_dir = joinpath (dir_paths. output, " clima_ocean" )
164- isdir (ocean_output_dir) || mkpath (ocean_output_dir)
165-
151+ dir_paths = Utilities. setup_output_dirs (
152+ output_dir_root = output_dir_root,
153+ comms_ctx = comms_ctx,
154+ )
166155
167156 # # get component model dictionaries (if applicable)
168157 # # Note this step must come after parsing the coupler config dictionary, since
169158 # # some parameters are passed from the coupler config to the component model configs
170- atmos_config_dict = get_atmos_config_dict (config_dict, atmos_output_dir)
159+ atmos_config_dict = get_atmos_config_dict (config_dict, dir_paths . atmos_output_dir)
171160
172161 # # set unique random seed if desired, otherwise use default
173162 Random. seed! (random_seed)
174163 @info " Random seed set to $(random_seed) "
175164
176165 if detect_restart_files
177166 isnothing (restart_t) &&
178- (restart_t = Checkpointer. t_start_from_checkpoint (dir_paths. checkpoints ))
179- isnothing (restart_dir) && (restart_dir = dir_paths. checkpoints )
167+ (restart_t = Checkpointer. t_start_from_checkpoint (dir_paths. checkpoints_dir ))
168+ isnothing (restart_dir) && (restart_dir = dir_paths. checkpoints_dir )
180169 end
181170 should_restart = ! isnothing (restart_t) && ! isnothing (restart_dir)
182171 if should_restart
@@ -205,12 +194,6 @@ function CoupledSimulation(config_dict::AbstractDict)
205194
206195 tspan = (t_start, t_end)
207196
208- #=
209- ## Data File Paths
210- =#
211- land_mask_data =
212- joinpath (@clima_artifact (" landsea_mask_60arcseconds" , comms_ctx), " landsea_mask.nc" )
213-
214197 #=
215198 ## Component Model Initialization
216199 Here we set initial and boundary conditions for each component model. Each component model is required to have an `init` function that
@@ -275,6 +258,8 @@ function CoupledSimulation(config_dict::AbstractDict)
275258 =#
276259
277260 # Preprocess the file to be 1s and 0s before remapping into onto the grid
261+ land_mask_data =
262+ joinpath (@clima_artifact (" landsea_mask_60arcseconds" , comms_ctx), " landsea_mask.nc" )
278263 land_fraction = SpaceVaryingInput (land_mask_data, " landsea" , boundary_space)
279264 land_fraction = ifelse .(land_fraction .> eps (FT), FT (1 ), FT (0 ))
280265
@@ -325,7 +310,7 @@ function CoupledSimulation(config_dict::AbstractDict)
325310 dt = component_dt_dict[" dt_land" ],
326311 tspan,
327312 start_date,
328- output_dir = land_output_dir,
313+ output_dir = dir_paths . land_output_dir,
329314 area_fraction = land_fraction,
330315 shared_surface_space,
331316 surface_elevation,
@@ -342,7 +327,7 @@ function CoupledSimulation(config_dict::AbstractDict)
342327 dt = component_dt_dict[" dt_land" ],
343328 tspan,
344329 start_date,
345- output_dir = land_output_dir,
330+ output_dir = dir_paths . land_output_dir,
346331 area_fraction = land_fraction,
347332 shared_surface_space,
348333 land_spun_up_ic,
@@ -382,7 +367,7 @@ function CoupledSimulation(config_dict::AbstractDict)
382367 ocean_fraction,
383368 start_date,
384369 stop_date;
385- output_dir = ocean_output_dir,
370+ output_dir = dir_paths . ocean_output_dir,
386371 comms_ctx,
387372 )
388373 else
@@ -410,7 +395,7 @@ function CoupledSimulation(config_dict::AbstractDict)
410395 dt = component_dt_dict[" dt_land" ],
411396 tspan,
412397 start_date,
413- output_dir = land_output_dir,
398+ output_dir = dir_paths . land_output_dir,
414399 area_fraction = land_fraction,
415400 surface_elevation,
416401 land_temperature_anomaly,
@@ -450,9 +435,8 @@ function CoupledSimulation(config_dict::AbstractDict)
450435
451436 # # coupler exchange fields
452437 coupler_field_names = Interfacer. default_coupler_fields ()
453- for sim in model_sims
454- Interfacer. add_coupler_fields! (coupler_field_names, sim)
455- end
438+ foreach (sim -> Interfacer. add_coupler_fields! (coupler_field_names, sim), model_sims)
439+
456440 # add coupler fields required to track conservation, if specified
457441 energy_check && push! (coupler_field_names, :P_net )
458442
@@ -500,11 +484,9 @@ function CoupledSimulation(config_dict::AbstractDict)
500484 =#
501485 if use_coupler_diagnostics
502486 @info " Using default coupler diagnostics"
503- coupler_diags_path = joinpath (dir_paths. output, " coupler" )
504- isdir (coupler_diags_path) || mkpath (coupler_diags_path)
505487 diags_handler = coupler_diagnostics_setup (
506488 coupler_fields,
507- coupler_diags_path ,
489+ dir_paths . coupler_output_dir ,
508490 start_date,
509491 tspan[1 ],
510492 diagnostics_dt,
@@ -631,28 +613,23 @@ end
631613
632614Process the results after a simulation has completed, including generating
633615plots, checking conservation, and other diagnostics.
616+ All postprocessing is performed using the root process only, if applicable.
634617
635618When `conservation_softfail` is true, throw an error if conservation is not
636619respected.
637620
638621When `rmse_check` is true, compute the RMSE against observations and test
639622that it is below a certain threshold.
623+
624+ The postprocessing includes:
625+ - Energy and water conservation checks (if running SlabPlanet with checks enabled)
626+ - Animations (if not running in MPI)
627+ - AMIP plots of the final state of the model
628+ - Error against observations
629+ - Optional additional atmosphere diagnostics plots
630+ - Plots of useful coupler and component model fields for debugging
640631"""
641632function postprocess (cs; conservation_softfail = false , rmse_check = false )
642- #=
643- ## Postprocessing
644- All postprocessing is performed using the root process only, if applicable.
645- Our postprocessing consists of outputting a number of plots to visualize the model output.
646-
647- The postprocessing includes:
648- - Energy and water conservation checks (if running SlabPlanet with checks enabled)
649- - Animations (if not running in MPI)
650- - AMIP plots of the final state of the model
651- - Error against observations
652- - Optional additional atmosphere diagnostics plots
653- - Plots of useful coupler and component model fields for debugging
654- =#
655-
656633 if ClimaComms. iamroot (ClimaComms. context (cs)) && ! isnothing (cs. diags_handler)
657634 postprocessing_vars = (; conservation_softfail, rmse_check)
658635 postprocess_sim (cs, postprocessing_vars)
0 commit comments