From 8b9f806891f75e3b2e4c5d62a3e8c8645f613ac0 Mon Sep 17 00:00:00 2001 From: Julia Sloan Date: Mon, 16 Sep 2024 15:21:25 -0700 Subject: [PATCH 1/3] extend make_ci_plots for amip paperplots This generalizes the `make_ci_plots` function to `make_plots` which takes in variable names as an argument instead of hardcoding them within the function --- experiments/ClimaEarth/run_amip.jl | 37 ++++------------------ experiments/ClimaEarth/user_io/ci_plots.jl | 34 ++++++++------------ 2 files changed, 21 insertions(+), 50 deletions(-) diff --git a/experiments/ClimaEarth/run_amip.jl b/experiments/ClimaEarth/run_amip.jl index 4525d4a0d2..967f667b61 100644 --- a/experiments/ClimaEarth/run_amip.jl +++ b/experiments/ClimaEarth/run_amip.jl @@ -890,40 +890,17 @@ if ClimaComms.iamroot(comms_ctx) end ## plotting AMIP results - if cs.mode.name == "amip" && !isempty(cs.diagnostics) + if cs.mode.name == "amip" ## plot data that correspond to the model's last save_hdf5 call (i.e., last month) @info "AMIP plots" ## ClimaESM - include("user_io/amip_visualizer.jl") - post_spec = (; - T = (:regrid, :zonal_mean), - u = (:regrid, :zonal_mean), - q_tot = (:regrid, :zonal_mean), - toa_fluxes = (:regrid, :horizontal_slice), - precipitation_rate = (:regrid, :horizontal_slice), - T_sfc = (:regrid, :horizontal_slice), - turbulent_energy_fluxes = (:regrid, :horizontal_slice), - q_liq_ice = (:regrid, :zonal_mean), - ) + include("user_io/ci_plots.jl") + + # TODO add turbulent_energy_fluxes? + amip_short_names = ["ta", "ua", "hus", "clw", "pr", "ts", "toa_fluxes_net", "F_turb_energy"] + make_ci_plots([atmos_sim.integrator.p.output_dir], dir_paths.artifacts, short_names = amip_short_names) - plot_spec = (; - T = (; clims = (190, 320), units = "K"), - u = (; clims = (-50, 50), units = "m/s"), - q_tot = (; clims = (0, 30), units = "g/kg"), - toa_fluxes = (; clims = (-250, 250), units = "W/m^2"), - precipitation_rate = (clims = (0, 1e-4), units = "kg/m^2/s"), - T_sfc = (clims = (225, 310), units = "K"), - turbulent_energy_fluxes = (; clims = (-250, 250), units = "W/m^2"), - q_liq_ice = (; clims = (0, 10), units = "g/kg"), - ) - amip_data, fig_amip = amip_paperplots( - post_spec, - plot_spec, - dir_paths.output, - files_root = ".monthly", - output_dir = dir_paths.artifacts, - ) # Check this because we only want monthly data for making plots if t_end > 84600 * 31 * 3 && config_dict["output_default_diagnostics"] include("leaderboard/leaderboard.jl") @@ -936,7 +913,7 @@ if ClimaComms.iamroot(comms_ctx) if config_dict["ci_plots"] @info "Generating CI plots" include("user_io/ci_plots.jl") - make_plots(Val(:general_ci_plots), [atmos_sim.integrator.p.output_dir], dir_paths.artifacts) + make_ci_plots([atmos_sim.integrator.p.output_dir], dir_paths.artifacts) end ## plot all model states and coupler fields (useful for debugging) diff --git a/experiments/ClimaEarth/user_io/ci_plots.jl b/experiments/ClimaEarth/user_io/ci_plots.jl index adc4d8472c..c0a0a1cdf6 100644 --- a/experiments/ClimaEarth/user_io/ci_plots.jl +++ b/experiments/ClimaEarth/user_io/ci_plots.jl @@ -144,10 +144,10 @@ function map_comparison(func, simdirs, args) end """ - make_plots( - ::Union{Val{:general_ci_plots}}, + make_ci_plots( output_paths::Vector{<:AbstractString}, plot_path::AbstractString; + short_names::Vector{<:AbstractString} = ["mse", "lr", "edt", "ts"], reduction::String = "average", ) Create plots for the general CI diagnostics. The plots are saved to `plot_path`. @@ -155,19 +155,15 @@ This is the default plotting function for the CI diagnostics and it can be exten to include additional diagnostics. The `reduction` keyword argument should be consistent with the reduction used to save the diagnostics. """ -function make_plots( - ::Union{Val{:general_ci_plots}}, +function make_ci_plots( output_paths::Vector{<:AbstractString}, plot_path::AbstractString; + short_names::Vector{<:AbstractString} = ["mse", "lr", "edt", "ts"], reduction::String = "average", ) simdirs = CAN.SimDir.(output_paths) - # Default output diagnostics - short_names_3D = ["mse", "lr", "edt"] - short_names_2D = ["ts"] - - available_periods = CAN.available_periods(simdirs[1]; short_name = short_names_3D[1], reduction) + available_periods = CAN.available_periods(simdirs[1]; short_name = short_names[1], reduction) period = "" if "10d" in available_periods period = "10d" @@ -177,20 +173,18 @@ function make_plots( period = "12h" end - # Creates diagnostics vector - # 3D fields are zonally averaged platted onf the lat-z plane - # 2D fields are plotted on the lon-lat plane - vars_3D = map_comparison(simdirs, short_names_3D) do simdir, short_name - get(simdir; short_name, reduction, period) |> CAN.average_lon - end - - available_periods = CAN.available_periods(simdirs[1]; short_name = short_names_2D[1], reduction) - - vars_2D = map_comparison(simdirs, short_names_2D) do simdir, short_name + # Create a CAN.OutputVar for each input field + vars = map_comparison(simdirs, short_names) do simdir, short_name get(simdir; short_name, reduction, period) end + # Filter vars into 2D and 3D variable diagnostics vectors + # 3D fields are zonally averaged platted on the lat-z plane + # 2D fields are plotted on the lon-lat plane + vars_3D = map(var_3D -> CAN.average_lon(var_3D), filter(var -> CAN.has_altitude(var), vars)) + vars_2D = filter(var -> !CAN.has_altitude(var), vars) + + # Generate plots and save in `plot_path` make_plots_generic(output_paths, plot_path, vars_3D, time = LAST_SNAP, more_kwargs = YLINEARSCALE) make_plots_generic(output_paths, plot_path, vars_2D, time = LAST_SNAP, output_name = "summary_2D") - end From a44f9e0ffce6ce5df4a89cfcd951dedacf4c78fa Mon Sep 17 00:00:00 2001 From: Julia Sloan Date: Mon, 16 Sep 2024 15:21:41 -0700 Subject: [PATCH 2/3] use ClimaDiagnostics for AMIP diags The ClimaCoupler Diagnostics module had become redundant with ClimaDiagnostics.jl, a package designed to provide robust diagnostics across the CliMA ecosystem. Here we remove ClimaCoupler.Diagnostics and instead use ClimaDiagnostics. We're able to retrive most of the diagnostics we want directly from ClimaAtmos and ClimaLand, but also want some that come from coupler-computed quantities, such as `F_turb_energy`. In this PR we add this coupler quantity to our output diagnostics using the ClimaDiagnostics interface. This PR also removes the AMIP paperplots function, but this functionality is replaced by the generalized `make_plots` function. --- NEWS.md | 16 ++ config/ci_configs/slabplanet_atmos_diags.yml | 3 +- docs/make.jl | 3 +- docs/src/diagnostics.md | 102 ++++++-- docs/src/postprocessor.md | 7 +- experiments/ClimaEarth/Project.toml | 2 +- .../components/atmosphere/climaatmos.jl | 2 + .../atmosphere/climaatmos_extra_diags.jl | 23 ++ experiments/ClimaEarth/run_amip.jl | 171 ++++++++----- .../ClimaEarth/run_cloudless_aquaplanet.jl | 13 +- .../ClimaEarth/run_cloudy_aquaplanet.jl | 13 +- .../ClimaEarth/run_cloudy_slabplanet.jl | 13 +- experiments/ClimaEarth/run_dry_held_suarez.jl | 3 +- .../ClimaEarth/run_moist_held_suarez.jl | 13 +- .../ClimaEarth/user_io/amip_diagnostics.jl | 53 ++++ .../ClimaEarth/user_io/amip_visualizer.jl | 101 -------- experiments/ClimaEarth/user_io/ci_plots.jl | 42 +-- experiments/ClimaEarth/user_io/plot_helper.jl | 90 ------- .../ClimaEarth/user_io/user_diagnostics.jl | 110 -------- src/ClimaCoupler.jl | 1 - src/Diagnostics.jl | 242 ------------------ src/Interfacer.jl | 4 +- src/PostProcessor.jl | 2 +- test/conservation_checker_tests.jl | 4 +- test/debug/debug_amip_plots.jl | 2 +- test/diagnostics_tests.jl | 151 ----------- test/flux_calculator_tests.jl | 2 +- test/interfacer_tests.jl | 2 +- test/regridder_tests.jl | 2 +- test/runtests.jl | 3 - test/time_manager_tests.jl | 8 +- 31 files changed, 321 insertions(+), 882 deletions(-) create mode 100644 experiments/ClimaEarth/user_io/amip_diagnostics.jl delete mode 100644 experiments/ClimaEarth/user_io/amip_visualizer.jl delete mode 100644 experiments/ClimaEarth/user_io/user_diagnostics.jl delete mode 100644 src/Diagnostics.jl delete mode 100644 test/diagnostics_tests.jl diff --git a/NEWS.md b/NEWS.md index d14ac4b75e..d5d6ff20b8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -13,3 +13,19 @@ low-resolution version of such files is automatically downloaded when a higher-resolution version is not available. Please, refer to [ClimaArtifacts](https://github.com/CliMA/ClimaArtifacts) for more information. +### Code cleanup +#### Remove ClimaCoupler.Diagnostics module - PR [#953](https://github.com/CliMA/ClimaCoupler.jl/pull/953) +The ClimaCoupler Diagnostics module had become redundant with +ClimaDiagnostics.jl, a package designed to provide robust +diagnostics across the CliMA ecosystem. +Here we remove ClimaCoupler.Diagnostics and instead use +ClimaDiagnostics. + +We're able to retrieve most of the diagnostics +we want directly from ClimaAtmos and ClimaLand, but also want +some that come from coupler-computed quantities, such as +`F_turb_energy`. In this PR we add this coupler quantity +to our output diagnostics using the ClimaDiagnostics interface. + +This PR also removes the AMIP paperplots function, but this +functionality is replaced by the generalized `make_plots` function. diff --git a/config/ci_configs/slabplanet_atmos_diags.yml b/config/ci_configs/slabplanet_atmos_diags.yml index d555946bdb..f8d7d1477d 100644 --- a/config/ci_configs/slabplanet_atmos_diags.yml +++ b/config/ci_configs/slabplanet_atmos_diags.yml @@ -9,12 +9,11 @@ h_elem: 4 mode_name: "slabplanet" moist: "equil" mono_surface: true -output_default_diagnostics: false precip_model: "0M" rad: "gray" t_end: "10days" vert_diff: "true" diagnostics: - - short_name: [mse, lr, edt, evu, ts, mass_strf, stab, vt, egr] + - short_name: [mse, lr, edt, evu, ts, mass_strf, stab, vt, egr, toa_fluxes_net] reduction_time: average period: 1days diff --git a/docs/make.jl b/docs/make.jl index d1375f50d9..465c5c3756 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -59,7 +59,6 @@ experiment_pages = [ interface_pages = [ "checkpointer.md", "conservation.md", - "diagnostics.md", "fieldexchanger.md", "fluxcalculator.md", "interfacer.md", @@ -70,7 +69,7 @@ interface_pages = [ ] performance_pages = ["performance.md"] -output_pages = ["leaderboard.md"] +output_pages = ["diagnostics.md", "leaderboard.md"] pages = Any[ "Home" => "index.md", diff --git a/docs/src/diagnostics.md b/docs/src/diagnostics.md index 93ec335eb4..ac60c7802e 100644 --- a/docs/src/diagnostics.md +++ b/docs/src/diagnostics.md @@ -1,30 +1,76 @@ # Diagnostics -This module contains functions for defining, gathering and outputting model diagnostics from the Coupler. - -Note that `ClimaCoupler.Diagnostics` is deployed online (i.e., as the model runs), working with cached model data (usually) on the model grid. This does not include offline post-processing (i.e., manipulating saved model output after the model is run, such as regridding data to the latitude-longitude grid). See `ClimaCoupler.PostProcessor` for offline model data treatment. - -## Diagnostics API - -```@docs - ClimaCoupler.Diagnostics.AbstractOutputGroup - ClimaCoupler.Diagnostics.DiagnosticsGroup - ClimaCoupler.Diagnostics.AbstractDiagnosticsOperations - ClimaCoupler.Diagnostics.TimeMean - ClimaCoupler.Diagnostics.get_var - ClimaCoupler.Diagnostics.accumulate_diagnostics! - ClimaCoupler.Diagnostics.save_diagnostics - ClimaCoupler.Diagnostics.init_diagnostics -``` - - -## Diagnostics Internal Functions - -```@docs - ClimaCoupler.Diagnostics.collect_diags - ClimaCoupler.Diagnostics.iterate_operations - ClimaCoupler.Diagnostics.operation - ClimaCoupler.Diagnostics.pre_save - ClimaCoupler.Diagnostics.post_save - ClimaCoupler.Diagnostics.save_time_format -``` \ No newline at end of file +ClimaCoupler.jl utilizes other packages in the CliMA ecosystem to generate +and visualize diagnostics, namely ClimaDiagnostics.jl and ClimaAnalysis.jl. + +## Default AMIP diagnostics +We output a set of default diagnostics for all AMIP runs. +These currently include the following fields: + +Atmospheric quantiies: +- air temperature at the bottom of the atmosphere (3D) +- eastward near-surface wind (3D) +- specific humidity (3D) +- mass fraction of cloud liquid water (3D) +- net top-of-atmosphere fluxes (3D) +- precipitation (2D) +- surface temperature (2D) + +Coupler quantities +- turbulent energy fluxes (2D) + +These diagnostics are all averaged over a period of time that depends +on the length of the overall simulation according to the following rule: +- simulation length >= 90 days: 30-day mean +- simulation length >= 30 days and < 90 days: 10-day mean +- simulation length >= 1 day and < 30 days: 1-day mean +- simulation length < 1 day: 1-hour mean + +## How to add a new diagnostic variable +### Adding a diagnostic for a ClimaCoupler quantity +For diagnostics that come from coupler fields or that are computed using input +from multiple component models, we set up the diagnostics by directly creating +ClimaDiagnostics.jl objects. + +Specifically, we first create a `DiagnosticVariable` object containing the variable's name, +units, any comments, and the function to compute it. This is then used to create a +`ScheduledDiagnostic` variable, which includes saving and output time information. +Once we have created a `ScheduledDiagnostic` for each variable we're interested in, +we collect them in a vector and pass this to our `DiagnosticsHandler` object. + +An example of this process for the variable `F_turb_energy` can be found in +`experiments/ClimaEarth/user_io/amip_diagnostics.jl`. + +For more information about this process, please see the +ClimaDiagnostics.jl [documentation](https://clima.github.io/ClimaDiagnostics.jl/dev/). + +### Adding a diagnostic for a CliMA component model quantity +Many of our current diagnostics are values that we access directly from a component model. +To add a new diagnostic of this kind, you can add a new method `add_diagnostic_variable!` +extending this function from the component model package's Diagnostics module. + +For more information about this function and the form it takes, please see the +ClimaDiagnostics.jl [documentation](https://clima.github.io/ClimaDiagnostics.jl/dev/). + +#### ClimaAtmos.jl +To add a new diagnostic for the ClimaAtmos.jl atmosphere model, you can add this new method +for `ClimaAtmos.Diagnostics.add_diagnostic_variable!` in +`components/atmosphere/climaatmos_extra_diags.jl`. +The existing diagnostics in that file can be used as templates. + +For more information about ClimaAtmos diagnostics, and to see the default atmospheric diagnostics, +please see that package's [documentation](https://clima.github.io/ClimaAtmos.jl/dev/diagnostics/). + +#### ClimaLand.jl +To add a new diagnostic for the ClimaLand.jl bucket model, you can add this new method +for `ClimaLand.Diagnostics.add_diagnostic_variable!` in +`components/land/climaland_bucket_extra_diags.jl` (which doesn't exist at the time of writing). + +For more information about ClimaLand diagnostics, and to see the default land diagnostics, +please see that package's [documentation](https://clima.github.io/ClimaLand.jl/dev/diagnostics/users_diagnostics/). + +## Visualizing diagnostics +ClimaCoupler.jl uses ClimaAnalysis.jl to parse and visualize the outputs saved +using ClimaDiagnostics.jl. + +For more information about ClimaAnalysis.jl, please see that package's [documentation](https://clima.github.io/ClimaAnalysis.jl/dev/). diff --git a/docs/src/postprocessor.md b/docs/src/postprocessor.md index 0c88e728c1..0f6147ba81 100644 --- a/docs/src/postprocessor.md +++ b/docs/src/postprocessor.md @@ -1,10 +1,10 @@ # PostProcessor -This module contains functions for postprocessing model data that was saved during the simulation -by `ClimaCoupler.Diagnostics`. This module is used for offline regridding, slicing and spatial +This module contains functions for postprocessing model data that was saved during the simulation. +This module is used for offline regridding, slicing and spatial averages. It can also handle data from other sources (e.g., NCEP reanalysis). -## Diagnostics API +## PostProcessor API ```@docs ClimaCoupler.PostProcessor.postprocess @@ -17,4 +17,3 @@ ClimaCoupler.PostProcessor.RawData ClimaCoupler.PostProcessor.DataPackage ``` - diff --git a/experiments/ClimaEarth/Project.toml b/experiments/ClimaEarth/Project.toml index 47448e800c..2f7adc7eae 100644 --- a/experiments/ClimaEarth/Project.toml +++ b/experiments/ClimaEarth/Project.toml @@ -37,7 +37,7 @@ ArtifactWrappers = "0.2" ClimaAnalysis = "0.5.10" ClimaAtmos = "0.27" ClimaCorePlots = "0.2" -ClimaDiagnostics = "0.2" +ClimaDiagnostics = "0.2.6" ClimaLand = "0.14, 0.15" ClimaParams = "0.10" ClimaTimeSteppers = "0.7" diff --git a/experiments/ClimaEarth/components/atmosphere/climaatmos.jl b/experiments/ClimaEarth/components/atmosphere/climaatmos.jl index 78237bbb85..f1f7ccdeff 100644 --- a/experiments/ClimaEarth/components/atmosphere/climaatmos.jl +++ b/experiments/ClimaEarth/components/atmosphere/climaatmos.jl @@ -4,9 +4,11 @@ import Statistics import LinearAlgebra import ClimaAtmos as CA import ClimaAtmos: set_surface_albedo! +import ClimaAtmos.Parameters as CAP import ClimaCore as CC import ClimaCore.Geometry: ⊗ import SurfaceFluxes as SF +import Thermodynamics as TD import ClimaCoupler: Checkpointer, FieldExchanger, FluxCalculator, Interfacer, Utilities include("climaatmos_extra_diags.jl") diff --git a/experiments/ClimaEarth/components/atmosphere/climaatmos_extra_diags.jl b/experiments/ClimaEarth/components/atmosphere/climaatmos_extra_diags.jl index ac5cf75a1d..c04630ff6c 100644 --- a/experiments/ClimaEarth/components/atmosphere/climaatmos_extra_diags.jl +++ b/experiments/ClimaEarth/components/atmosphere/climaatmos_extra_diags.jl @@ -136,6 +136,29 @@ CAD.add_diagnostic_variable!( end, ) +CAD.add_diagnostic_variable!( + short_name = "toa_fluxes_net", + long_name = "Net TOA radiation fluxes", + standard_name = "net_toa_radiation_fluxes", + units = "W m^-2", + comments = "Net top of the atmosphere radiation fluxes, calculated by summing the upward and downward shortwave and longwave radiation fluxes.", + compute! = (out, state, cache, time) -> begin + # Perform sum of radiation fluxes (rsu + rlu - rsd - rld) + if isnothing(out) + return CC.Fields.array2field(cache.radiation.rrtmgp_model.face_sw_flux_up, axes(state.f)) .+ + CC.Fields.array2field(cache.radiation.rrtmgp_model.face_lw_flux_up, axes(state.f)) .- + CC.Fields.array2field(cache.radiation.rrtmgp_model.face_sw_flux_dn, axes(state.f)) .- + CC.Fields.array2field(cache.radiation.rrtmgp_model.face_lw_flux_dn, axes(state.f)) |> copy + else + out .= + CC.Fields.array2field(cache.radiation.rrtmgp_model.face_sw_flux_up, axes(state.f)) .+ + CC.Fields.array2field(cache.radiation.rrtmgp_model.face_lw_flux_up, axes(state.f)) .- + CC.Fields.array2field(cache.radiation.rrtmgp_model.face_sw_flux_dn, axes(state.f)) .- + CC.Fields.array2field(cache.radiation.rrtmgp_model.face_lw_flux_dn, axes(state.f)) + end + end, +) + """ static_stability(cache) diff --git a/experiments/ClimaEarth/run_amip.jl b/experiments/ClimaEarth/run_amip.jl index 967f667b61..746cc92321 100644 --- a/experiments/ClimaEarth/run_amip.jl +++ b/experiments/ClimaEarth/run_amip.jl @@ -48,15 +48,7 @@ import ClimaCore as CC # ## Coupler specific imports import ClimaCoupler import ClimaCoupler: - ConservationChecker, - Checkpointer, - Diagnostics, - FieldExchanger, - FluxCalculator, - Interfacer, - Regridder, - TimeManager, - Utilities + ConservationChecker, Checkpointer, FieldExchanger, FluxCalculator, Interfacer, Regridder, TimeManager, Utilities import ClimaUtilities.SpaceVaryingInputs: SpaceVaryingInput import ClimaUtilities.TimeVaryingInputs: TimeVaryingInput, evaluate! @@ -70,7 +62,7 @@ pkg_dir = pkgdir(ClimaCoupler) #= ### Helper Functions -These will be eventually moved to their respective component model and diagnostics packages, and so they should not +These will be eventually moved to their respective component model and utility packages, and so they should not contain any internals of the ClimaCoupler source code, except extensions to the Interfacer functions. =# @@ -82,7 +74,6 @@ include("components/ocean/prescr_seaice.jl") include("components/ocean/eisenman_seaice.jl") ## helpers for user-specified IO -include("user_io/user_diagnostics.jl") include("user_io/user_logging.jl") include("user_io/debug_plots.jl") include("user_io/io_helpers.jl") @@ -102,9 +93,9 @@ parsed_args = parse_commandline(argparse_settings()) ## modify parsed args for fast testing from REPL #hide if isinteractive() parsed_args["config_file"] = - isnothing(parsed_args["config_file"]) ? joinpath(pkg_dir, "config/ci_configs/interactive_debug.yml") : + isnothing(parsed_args["config_file"]) ? joinpath(pkg_dir, "config/ci_configs/coarse_single_ft32.yml") : #interactive_debug.yml") : parsed_args["config_file"] - parsed_args["job_id"] = "interactive_debug" + parsed_args["job_id"] = "coarse_single_ft32"#"interactive_debug" end ## the unique job id should be passed in via the command line @@ -122,12 +113,55 @@ random_seed = config_dict["unique_seed"] ? time_ns() : 1234 Random.seed!(random_seed) @info "Random seed set to $(random_seed)" +## set up diagnostics before retrieving atmos config +mode_name = config_dict["mode_name"] +use_coupler_diagnostics = config_dict["use_coupler_diagnostics"] +t_end = Float64(time_to_seconds(config_dict["t_end"])) +t_start = 0.0 + +function get_period(t_start, t_end) + sim_duration = t_end - t_start + secs_per_day = 86400 + if sim_duration >= 90 * secs_per_day + # if duration >= 90 days, take monthly means + period = "30days" + calendar_dt = Dates.Day(30) + elseif sim_duration >= 30 * secs_per_day + # if duration >= 30 days, take means over 10 days + period = "10days" + calendar_dt = Dates.Day(10) + elseif sim_duration >= secs_per_day + # if duration >= 1 day, take daily means + period = "1days" + calendar_dt = Dates.Day(1) + else + # if duration < 1 day, take hourly means + period = "1hours" + calendar_dt = Dates.Hour(1) + end + return (period, calendar_dt) +end + +if mode_name == "amip" && use_coupler_diagnostics + @info "Using default AMIP diagnostics" + (period, calendar_dt) = get_period(t_start, t_end) + + !haskey(config_dict, "diagnostics") && (config_dict["diagnostics"] = Vector{Dict{Any, Any}}()) + push!( + config_dict["diagnostics"], + Dict( + "short_name" => ["ta", "ua", "hus", "clw", "pr", "ts", "toa_fluxes_net"], + "reduction_time" => "average", + "period" => period, + ), + ) +end + ## get component model dictionaries (if applicable) atmos_config_dict, config_dict = get_atmos_config_dict(config_dict, job_id) atmos_config_object = CA.AtmosConfig(atmos_config_dict) ## read in some parsed command line arguments, required by this script -mode_name = config_dict["mode_name"] energy_check = config_dict["energy_check"] const FT = config_dict["FLOAT_TYPE"] == "Float64" ? Float64 : Float32 land_sim_name = "bucket" @@ -145,7 +179,6 @@ restart_dir = config_dict["restart_dir"] restart_t = Int(config_dict["restart_t"]) evolving_ocean = config_dict["evolving_ocean"] dt_rad = config_dict["dt_rad"] -use_coupler_diagnostics = config_dict["use_coupler_diagnostics"] use_land_diagnostics = config_dict["use_land_diagnostics"] #= @@ -490,37 +523,6 @@ model_sims = (atmos_sim = atmos_sim, ice_sim = ice_sim, land_sim = land_sim, oce ## dates dates = (; date = [date], date0 = [date0], date1 = [Dates.firstdayofmonth(date0)], new_month = [false]) -#= -### Online Diagnostics -The user can write custom diagnostics in the `user_diagnostics.jl` file. -Note, this will be replaced by the diagnostics framework currently in ClimaAtmos, once it is abstracted -into a more general package, so we can use it to save fields from surface models. -=# -if use_coupler_diagnostics - monthly_3d_diags = Diagnostics.init_diagnostics( - (:T, :u, :q_tot, :q_liq_ice), - atmos_sim.domain.center_space; - save = TimeManager.Monthly(), - operations = (; accumulate = Diagnostics.TimeMean([Int(0)])), - output_dir = dir_paths.output, - name_tag = "monthly_mean_3d_", - ) - - monthly_2d_diags = Diagnostics.init_diagnostics( - (:precipitation_rate, :toa_fluxes, :T_sfc, :turbulent_energy_fluxes), - boundary_space; - save = TimeManager.Monthly(), - operations = (; accumulate = Diagnostics.TimeMean([Int(0)])), - output_dir = dir_paths.output, - name_tag = "monthly_mean_2d_", - ) - - diagnostics = (monthly_3d_diags, monthly_2d_diags) - Utilities.show_memory_usage() -else - diagnostics = () -end - #= ## Initialize Conservation Checks @@ -594,13 +596,23 @@ else error("turb_flux_partition must be either PartitionedStateFluxes or CombinedStateFluxesMOST") end +#= Set up default AMIP diagnostics +Use ClimaDiagnostics for default AMIP diagnostics, which currently include turbulent energy fluxes. +=# +if mode_name == "amip" && use_coupler_diagnostics + include("user_io/amip_diagnostics.jl") + amip_diags_handler = amip_diagnostics_setup(coupler_fields, dir_paths.output, dates.date0[1], tspan[1], calendar_dt) +else + amip_diags_handler = nothing +end + #= ## Initialize Coupled Simulation The coupled simulation is initialized here and saved in a global `CoupledSimulation` struct, `cs`. It contains all the information required to run the coupled simulation, including the communication context, the dates, the boundary space, the coupler fields, the configuration dictionary, the conservation checks, the time span, the time step, the land fraction, the model simulations, the mode -specifics, the diagnostics, the callbacks, and the directory paths. +specifics, the callbacks, the directory paths, and diagnostics for AMIP simulations. =# cs = Interfacer.CoupledSimulation{FT}( @@ -615,11 +627,11 @@ cs = Interfacer.CoupledSimulation{FT}( Δt_cpl, model_sims, mode_specifics, - diagnostics, callbacks, dir_paths, turbulent_fluxes, thermo_params, + amip_diags_handler, ); Utilities.show_memory_usage() @@ -724,15 +736,6 @@ function solve_coupler!(cs) current_CO2 = zeros(boundary_space) evaluate!(current_CO2, cs.mode.CO2_timevaryinginput, t) Interfacer.update_field!(atmos_sim, Val(:co2), current_CO2) - - ## calculate and accumulate diagnostics at each timestep, if we're using diagnostics in this run - if !isempty(cs.diagnostics) - ClimaComms.barrier(comms_ctx) - Diagnostics.accumulate_diagnostics!(cs) - - ## save and reset monthly averages - Diagnostics.save_diagnostics(cs) - end end ## compute global energy and water conservation checks @@ -781,6 +784,12 @@ function solve_coupler!(cs) ## callback to checkpoint model state TimeManager.trigger_callback!(cs, cs.callbacks.checkpoint) + + ## compute/output AMIP diagnostics if scheduled for this timestep + ## wrap the current CoupledSimulation fields and time in a NamedTuple to match the ClimaDiagnostics interface + cs_nt = (; u = cs.fields, p = nothing, t = t, step = round(t / Δt_cpl)) + (cs.mode.name == "amip" && !isnothing(cs.amip_diags_handler)) && + CD.orchestrate_diagnostics(cs_nt, cs.amip_diags_handler) end return nothing end @@ -891,15 +900,33 @@ if ClimaComms.iamroot(comms_ctx) ## plotting AMIP results if cs.mode.name == "amip" - ## plot data that correspond to the model's last save_hdf5 call (i.e., last month) - @info "AMIP plots" - - ## ClimaESM - include("user_io/ci_plots.jl") - - # TODO add turbulent_energy_fluxes? - amip_short_names = ["ta", "ua", "hus", "clw", "pr", "ts", "toa_fluxes_net", "F_turb_energy"] - make_ci_plots([atmos_sim.integrator.p.output_dir], dir_paths.artifacts, short_names = amip_short_names) + if use_coupler_diagnostics + ## plot data that correspond to the model's last save_hdf5 call (i.e., last month) + @info "AMIP plots" + + ## ClimaESM + include("user_io/ci_plots.jl") + + # define variable names and output directories for each diagnostic + amip_short_names_atmos = ["ta", "ua", "hus", "clw", "pr", "ts", "toa_fluxes_net"] + output_dir_atmos = atmos_sim.integrator.p.output_dir + amip_short_names_coupler = ["F_turb_energy"] + output_dir_coupler = dir_paths.output + + # Check if all output variables are available in the specified directories + make_ci_plots( + output_dir_atmos, + dir_paths.artifacts, + short_names = amip_short_names_atmos, + output_prefix = "atmos_", + ) + make_ci_plots( + output_dir_coupler, + dir_paths.artifacts, + short_names = amip_short_names_coupler, + output_prefix = "coupler_", + ) + end # Check this because we only want monthly data for making plots if t_end > 84600 * 31 * 3 && config_dict["output_default_diagnostics"] @@ -913,15 +940,17 @@ if ClimaComms.iamroot(comms_ctx) if config_dict["ci_plots"] @info "Generating CI plots" include("user_io/ci_plots.jl") - make_ci_plots([atmos_sim.integrator.p.output_dir], dir_paths.artifacts) + make_ci_plots(atmos_sim.integrator.p.output_dir, dir_paths.artifacts) end ## plot all model states and coupler fields (useful for debugging) !CA.is_distributed(comms_ctx) && debug(cs, dir_paths.artifacts) - if isinteractive() #hide - ## clean up for interactive runs, retain all output otherwise #hide - rm(dir_paths.output; recursive = true, force = true) #hide - end #hide + # if isinteractive() #hide + # ## clean up for interactive runs, retain all output otherwise #hide + # rm(dir_paths.output; recursive = true, force = true) #hide + # end #hide + ## close all AMIP diagnostics file writers + mode_name == "amip" && map(diag -> close(diag.output_writer), amip_diags_handler.scheduled_diagnostics) end diff --git a/experiments/ClimaEarth/run_cloudless_aquaplanet.jl b/experiments/ClimaEarth/run_cloudless_aquaplanet.jl index 2e4995c556..41f2ceceb5 100644 --- a/experiments/ClimaEarth/run_cloudless_aquaplanet.jl +++ b/experiments/ClimaEarth/run_cloudless_aquaplanet.jl @@ -25,15 +25,7 @@ import ClimaCore as CC # ## Coupler specific imports import ClimaCoupler import ClimaCoupler: - ConservationChecker, - Checkpointer, - Diagnostics, - FieldExchanger, - FluxCalculator, - Interfacer, - Regridder, - TimeManager, - Utilities + ConservationChecker, Checkpointer, FieldExchanger, FluxCalculator, Interfacer, Regridder, TimeManager, Utilities pkg_dir = pkgdir(ClimaCoupler) @@ -46,7 +38,6 @@ include("components/atmosphere/climaatmos.jl") include("components/ocean/slab_ocean.jl") ## helpers for user-specified IO -include("user_io/user_diagnostics.jl") include("user_io/user_logging.jl") include("user_io/io_helpers.jl") @@ -267,11 +258,11 @@ cs = Interfacer.CoupledSimulation{FT}( Δt_cpl, model_sims, (;), # mode_specifics - (), # coupler diagnostics callbacks, dir_paths, turbulent_fluxes, thermo_params, + nothing, # amip_diags_handler ); #= diff --git a/experiments/ClimaEarth/run_cloudy_aquaplanet.jl b/experiments/ClimaEarth/run_cloudy_aquaplanet.jl index b447759596..fefc2edd01 100644 --- a/experiments/ClimaEarth/run_cloudy_aquaplanet.jl +++ b/experiments/ClimaEarth/run_cloudy_aquaplanet.jl @@ -25,15 +25,7 @@ import ClimaCore as CC # ## Coupler specific imports import ClimaCoupler import ClimaCoupler: - ConservationChecker, - Checkpointer, - Diagnostics, - FieldExchanger, - FluxCalculator, - Interfacer, - Regridder, - TimeManager, - Utilities + ConservationChecker, Checkpointer, FieldExchanger, FluxCalculator, Interfacer, Regridder, TimeManager, Utilities pkg_dir = pkgdir(ClimaCoupler) @@ -46,7 +38,6 @@ include("components/atmosphere/climaatmos.jl") include("components/ocean/slab_ocean.jl") ## helpers for user-specified IO -include("user_io/user_diagnostics.jl") include("user_io/user_logging.jl") include("user_io/io_helpers.jl") @@ -281,11 +272,11 @@ cs = Interfacer.CoupledSimulation{FT}( Δt_cpl, model_sims, (;), # mode_specifics - (), # coupler diagnostics callbacks, dir_paths, turbulent_fluxes, thermo_params, + nothing, # amip_diags_handler ); #= diff --git a/experiments/ClimaEarth/run_cloudy_slabplanet.jl b/experiments/ClimaEarth/run_cloudy_slabplanet.jl index f5783f9bb5..dfeba121cb 100644 --- a/experiments/ClimaEarth/run_cloudy_slabplanet.jl +++ b/experiments/ClimaEarth/run_cloudy_slabplanet.jl @@ -25,15 +25,7 @@ import ClimaCore as CC # ## Coupler specific imports import ClimaCoupler import ClimaCoupler: - ConservationChecker, - Checkpointer, - Diagnostics, - FieldExchanger, - FluxCalculator, - Interfacer, - Regridder, - TimeManager, - Utilities + ConservationChecker, Checkpointer, FieldExchanger, FluxCalculator, Interfacer, Regridder, TimeManager, Utilities pkg_dir = pkgdir(ClimaCoupler) @@ -47,7 +39,6 @@ include("components/ocean/slab_ocean.jl") include("components/land/climaland_bucket.jl") ## helpers for user-specified IO -include("user_io/user_diagnostics.jl") include("user_io/user_logging.jl") include("user_io/io_helpers.jl") @@ -334,11 +325,11 @@ cs = Interfacer.CoupledSimulation{FT}( Δt_cpl, model_sims, (;), # mode_specifics - (), # coupler diagnostics callbacks, dir_paths, turbulent_fluxes, thermo_params, + nothing, # amip_diags_handler ); #= diff --git a/experiments/ClimaEarth/run_dry_held_suarez.jl b/experiments/ClimaEarth/run_dry_held_suarez.jl index 876dd6377e..997d3ec210 100644 --- a/experiments/ClimaEarth/run_dry_held_suarez.jl +++ b/experiments/ClimaEarth/run_dry_held_suarez.jl @@ -38,7 +38,6 @@ pkg_dir = pkgdir(ClimaCoupler) include("components/atmosphere/climaatmos.jl") ## helpers for user-specified IO -include("user_io/user_diagnostics.jl") include("user_io/user_logging.jl") include("user_io/io_helpers.jl") @@ -204,11 +203,11 @@ cs = Interfacer.CoupledSimulation{FT}( Δt_cpl, model_sims, (;), # mode_specifics - (), # coupler diagnostics callbacks, dir_paths, nothing, # turbulent_fluxes thermo_params, + nothing, # amip_diags_handler ); #= diff --git a/experiments/ClimaEarth/run_moist_held_suarez.jl b/experiments/ClimaEarth/run_moist_held_suarez.jl index fc162370d4..6962ac974b 100644 --- a/experiments/ClimaEarth/run_moist_held_suarez.jl +++ b/experiments/ClimaEarth/run_moist_held_suarez.jl @@ -28,15 +28,7 @@ import ClimaCore as CC # ## Coupler specific imports import ClimaCoupler import ClimaCoupler: - ConservationChecker, - Checkpointer, - Diagnostics, - FieldExchanger, - FluxCalculator, - Interfacer, - Regridder, - TimeManager, - Utilities + ConservationChecker, Checkpointer, FieldExchanger, FluxCalculator, Interfacer, Regridder, TimeManager, Utilities pkg_dir = pkgdir(ClimaCoupler) @@ -48,7 +40,6 @@ pkg_dir = pkgdir(ClimaCoupler) include("components/atmosphere/climaatmos.jl") ## helpers for user-specified IO -include("user_io/user_diagnostics.jl") include("user_io/user_logging.jl") include("user_io/io_helpers.jl") @@ -263,11 +254,11 @@ cs = Interfacer.CoupledSimulation{FT}( Δt_cpl, model_sims, (;), # mode_specifics - (), # coupler diagnostics callbacks, dir_paths, turbulent_fluxes, thermo_params, + nothing, # amip_diags_handler ); #= diff --git a/experiments/ClimaEarth/user_io/amip_diagnostics.jl b/experiments/ClimaEarth/user_io/amip_diagnostics.jl new file mode 100644 index 0000000000..ca72ae33f1 --- /dev/null +++ b/experiments/ClimaEarth/user_io/amip_diagnostics.jl @@ -0,0 +1,53 @@ +import ClimaDiagnostics as CD +import ClimaCoupler: Interfacer +import Dates + +""" + amip_diagnostics_setup(fields, output_dir, start_date, t_start, calendar_dt) + +Set up the default diagnostics for an AMIP simulation, using ClimaDiagnostics. +The diagnostics are saved to NetCDF files. Currently, this just includes a +diagnostic for turbulent energy fluxes. + +Return a DiagnosticsHandler object to coordinate the diagnostics. +""" +function amip_diagnostics_setup(fields, output_dir, start_date, t_start, calendar_dt) + # Create schedules and writer + schedule_everystep = CD.Schedules.EveryStepSchedule() + schedule_calendar_dt = CD.Schedules.EveryCalendarDtSchedule(calendar_dt, start_date = start_date) + netcdf_writer = CD.Writers.NetCDFWriter(axes(fields.F_turb_energy), output_dir) + + # Create the diagnostic for turbulent energy fluxes + F_turb_energy_diag = CD.DiagnosticVariable(; + short_name = "F_turb_energy", + long_name = "Turbulent energy fluxes", + standard_name = "F_turb_energy", + units = "W m^-2", + comments = "When using partitioned surface fluxes, turbulent energy fluxes are calculated as + the sum of sensible and latent heat fluxes, weighted by surface simulation area. + When using combined surface fluxes, turbulent energy fluxes are calculated using + the surface conditions calculated in ClimaAtmos.", + compute! = (out, state, cache, time) -> begin + if isnothing(out) + return state.F_turb_energy + else + out .= state.F_turb_energy + end + end, + ) + + # Schedule the turbulent energy fluxes to save at every step, and output at the frequency calculated above + F_turb_energy_diag_sched = CD.ScheduledDiagnostic( + variable = F_turb_energy_diag, + output_writer = netcdf_writer, + reduction_time_func = (+), + compute_schedule_func = schedule_everystep, + output_schedule_func = schedule_calendar_dt, + pre_output_hook! = CD.average_pre_output_hook!, + ) + + # Create the diagnostics handler containing the scheduled diagnostics + scheduled_diags = [F_turb_energy_diag_sched] + amip_diags_handler = CD.DiagnosticsHandler(scheduled_diags, fields, nothing, t_start) + return amip_diags_handler +end diff --git a/experiments/ClimaEarth/user_io/amip_visualizer.jl b/experiments/ClimaEarth/user_io/amip_visualizer.jl deleted file mode 100644 index faa26b93f5..0000000000 --- a/experiments/ClimaEarth/user_io/amip_visualizer.jl +++ /dev/null @@ -1,101 +0,0 @@ -import Glob -import Plots -import Printf -import ClimaComms -import ClimaCore as CC -import ClimaCoupler: PostProcessor - -include("plot_helper.jl") - -""" - function amip_paperplots( - post_spec::NamedTuple, - plot_spec::NamedTuple, - files_dir::String; - output_dir = ".", - files_root = ".hdf5", - fig_name = "amip_paperplots", - ) - -Coordinates the postprocessing and plotting of sample fields (specified in `post_spec`) -of the last monthly mean file. Any specific plot customization should be done here. -""" -function amip_paperplots( - post_spec::NamedTuple, - plot_spec::NamedTuple, - files_dir::String; - output_dir = ".", - files_root = ".hdf5", - fig_name = "amip_paperplots", - nlat = 180, - nlon = 360, -) - diags_names = propertynames(post_spec) - - all_plots = [] - all_data = (;) - for name in diags_names - @info name - - # extract data - diag_data = read_latest_model_data(name, files_dir, files_root) - - # postprocess - post_data = PostProcessor.postprocess( - name, - diag_data, - getproperty(post_spec, name), - REGRID_DIR = files_dir, - nlat = nlat, - nlon = nlon, - ) - post_data.data[1] = sum(post_data.data) == 0 ? post_data.data[1] + eps() : post_data.data[1] # avoids InexactError - - # create individual plots - p = Plots.plot( - post_data, - zmd_params = (; getproperty(plot_spec, name)...), - hsd_params = (; getproperty(plot_spec, name)...), - ) - - push!(all_plots, p) - - # create a named tuple with data - data = post_data.data - all_data = merge(all_data, [name => data]) - end - - # combine plots and save figure - layout = Plots.@layout([A{0.05h}; [B C D; E F G; H I J]]) - title = - Plots.plot(plot_title = "AMIP Monthly Mean Fields", grid = false, showaxis = false, bottom_margin = -50Plots.px) - save_fig = Plots.plot( - title, - all_plots..., - size = (1500, 1200), - layout = layout, - titlefont = Plots.font(12), - margin = 2Plots.mm, - ) - - Plots.png(save_fig, joinpath(output_dir, fig_name * ".png")) - - return all_data, save_fig -end - -""" - read_latest_model_data(name::Symbol, filedir::String, root::String) - -Reads in a variable from a HDF5 file, as outputted by `ClimaCoupler.Dignostics`. -""" -function read_latest_model_data(name::Symbol, filedir::String, root::String) - varfile_root = Printf.@sprintf "%s%s" string(name) root - filename = Glob.glob("*" * varfile_root * "*", filedir)[end] - - # Ensure file gets read onto CPU for postprocessing - cpu_singleton_context = ClimaComms.SingletonCommsContext(ClimaComms.CPUSingleThreaded()) - hdfreader = CC.InputOutput.HDF5Reader(filename, cpu_singleton_context) - var = CC.InputOutput.read_field(hdfreader, string(name)) - close(hdfreader) - return var -end diff --git a/experiments/ClimaEarth/user_io/ci_plots.jl b/experiments/ClimaEarth/user_io/ci_plots.jl index c0a0a1cdf6..944c49f28a 100644 --- a/experiments/ClimaEarth/user_io/ci_plots.jl +++ b/experiments/ClimaEarth/user_io/ci_plots.jl @@ -145,10 +145,11 @@ end """ make_ci_plots( - output_paths::Vector{<:AbstractString}, + output_path::AbstractString, plot_path::AbstractString; short_names::Vector{<:AbstractString} = ["mse", "lr", "edt", "ts"], reduction::String = "average", + output_prefix = "", ) Create plots for the general CI diagnostics. The plots are saved to `plot_path`. This is the default plotting function for the CI diagnostics and it can be extended @@ -156,27 +157,21 @@ to include additional diagnostics. The `reduction` keyword argument should be consistent with the reduction used to save the diagnostics. """ function make_ci_plots( - output_paths::Vector{<:AbstractString}, + output_path::AbstractString, plot_path::AbstractString; short_names::Vector{<:AbstractString} = ["mse", "lr", "edt", "ts"], reduction::String = "average", + output_prefix = "", ) - simdirs = CAN.SimDir.(output_paths) - - available_periods = CAN.available_periods(simdirs[1]; short_name = short_names[1], reduction) - period = "" - if "10d" in available_periods - period = "10d" - elseif "1d" in available_periods - period = "1d" - elseif "12h" in available_periods - period = "12h" + + simdir = CAN.SimDir(output_path) + if !all(v -> v in CAN.available_vars(simdir), short_names) + @warn "Not all variables are available in the output directory $output_path" + return end # Create a CAN.OutputVar for each input field - vars = map_comparison(simdirs, short_names) do simdir, short_name - get(simdir; short_name, reduction, period) - end + vars = [get(simdir; short_name, reduction) for short_name in short_names] # Filter vars into 2D and 3D variable diagnostics vectors # 3D fields are zonally averaged platted on the lat-z plane @@ -185,6 +180,19 @@ function make_ci_plots( vars_2D = filter(var -> !CAN.has_altitude(var), vars) # Generate plots and save in `plot_path` - make_plots_generic(output_paths, plot_path, vars_3D, time = LAST_SNAP, more_kwargs = YLINEARSCALE) - make_plots_generic(output_paths, plot_path, vars_2D, time = LAST_SNAP, output_name = "summary_2D") + !isempty(vars_3D) && make_plots_generic( + output_path, + plot_path, + vars_3D, + time = LAST_SNAP, + output_name = output_prefix * "summary_3D", + more_kwargs = YLINEARSCALE, + ) + !isempty(vars_2D) && make_plots_generic( + output_path, + plot_path, + vars_2D, + time = LAST_SNAP, + output_name = output_prefix * "summary_2D", + ) end diff --git a/experiments/ClimaEarth/user_io/plot_helper.jl b/experiments/ClimaEarth/user_io/plot_helper.jl index ec2209bd90..76d5e061fa 100644 --- a/experiments/ClimaEarth/user_io/plot_helper.jl +++ b/experiments/ClimaEarth/user_io/plot_helper.jl @@ -2,96 +2,6 @@ import Plots import ClimaCoupler: PostProcessor import StaticArrays -""" - Plots.plot(post_data::DataPackage; zmd_params = (;), hsd_params = (;)) - -Coordinates plotting based on parsed data types. -""" -function Plots.plot(post_data::PostProcessor.DataPackage; zmd_params = (;), hsd_params = (;)) - if post_data.tag isa PostProcessor.ZLatData - plot_params = zmd_params - elseif post_data.tag isa PostProcessor.LatLonData - plot_params = hsd_params - else - plot_params = (;) - end - Plots.contourf(post_data.tag, post_data; plot_params...) -end - -""" - Plots.contourf( - ::PostProcessor.ZLatData, - p::PostProcessor.DataPackage; - xlabel = "lat (deg N)", - ylabel = "z (km)", - yaxis = (:log,), - yflip = false, - clims = nothing, - units = " ", - ) - -Plots a filled contour plot on the latitude-level plane. -""" -function Plots.contourf( - ::PostProcessor.ZLatData, - p::PostProcessor.DataPackage; - xlabel = "lat (deg N)", - ylabel = "z (km)", - yaxis = (:log,), - yflip = false, - clims = nothing, - units = " ", -) - clims = isnothing(clims) ? extrema(p.data) : clims - Plots.contourf( - p.coords.lat, - p.coords.lev, - p.data', - color = :rainbow, - title = string(p.name) * " [" * units * "]", - xlabel = xlabel, - ylabel = ylabel, - yaxis = yaxis, - yflip = yflip, - clims = clims, - ) -end - -""" - Plots.contourf( - ::PostProcessor.LatLonData, - p::PostProcessor.DataPackage; - xlabel = "lat (deg N)", - ylabel = "z (km)", - yaxis = (:log,), - yflip = false, - clims = nothing, - units = " ", - ) - -Plots a filled contour plot on the longitude-latitude plane. -""" -function Plots.contourf( - ::PostProcessor.LatLonData, - p::PostProcessor.DataPackage; - xlabel = "lon (deg E)", - ylabel = "lat (deg N)", - clims = nothing, - units = " ", -) - clims = isnothing(clims) ? extrema(p.data) : clims - Plots.contourf( - p.coords.lon, - p.coords.lat, - p.data', - color = :rainbow, - title = string(p.name) * " [" * units * "]", - xlabel = xlabel, - ylabel = ylabel, - clims = clims, - ) -end - """ get_ne(grid) diff --git a/experiments/ClimaEarth/user_io/user_diagnostics.jl b/experiments/ClimaEarth/user_io/user_diagnostics.jl deleted file mode 100644 index a384a5ce3a..0000000000 --- a/experiments/ClimaEarth/user_io/user_diagnostics.jl +++ /dev/null @@ -1,110 +0,0 @@ -import ClimaCore as CC -import ClimaAtmos.Parameters as CAP -import Thermodynamics as TD -import ClimaCoupler: Diagnostics, Interfacer, Utilities - -""" - Diagnostics.get_var(cs::Interfacer.CoupledSimulation, ::Val{:T}) - -Air temperature (K). -""" -function Diagnostics.get_var(cs::Interfacer.CoupledSimulation, ::Val{:T}) - p = cs.model_sims.atmos_sim.integrator.p - (; ᶜts) = p.precomputed - (; params) = p - thermo_params = CAP.thermodynamics_params(params) - @. TD.air_temperature(thermo_params, ᶜts) -end - -""" - Diagnostics.get_var(cs::Interfacer.CoupledSimulation, ::Val{:u}) - -Zonal wind (m s⁻¹). -""" -Diagnostics.get_var(cs::Interfacer.CoupledSimulation, ::Val{:u}) = - CC.Geometry.UVVector.(cs.model_sims.atmos_sim.integrator.u.c.uₕ).components.data.:1 - -""" - Diagnostics.get_var(cs::Interfacer.CoupledSimulation, ::Val{:q_tot}) - -Total specific humidity (g kg⁻¹). -""" -Diagnostics.get_var(cs::Interfacer.CoupledSimulation, ::Val{:q_tot}) = - cs.model_sims.atmos_sim.integrator.u.c.ρq_tot ./ cs.model_sims.atmos_sim.integrator.u.c.ρ .* - Interfacer.float_type(cs)(1000) - - -""" - Diagnostics.get_var(cs::Interfacer.CoupledSimulation, ::Val{:q_liq_ice}) - -Cloud specific humidity (g kg⁻¹). -""" -function Diagnostics.get_var(cs::Interfacer.CoupledSimulation, ::Val{:q_liq_ice}) - p = cs.model_sims.atmos_sim.integrator.p - (; ᶜts) = p.precomputed - (; params) = p - thermo_params = CAP.thermodynamics_params(params) - TD.liquid_specific_humidity.(thermo_params, ᶜts) .* Interfacer.float_type(cs)(1000) -end - -""" - Diagnostics.get_var(cs::Interfacer.CoupledSimulation, ::Val{:toa_fluxes}) - -Top of the atmosphere radiation fluxes (W m⁻²). -""" -function Diagnostics.get_var(cs::Interfacer.CoupledSimulation, ::Val{:toa_fluxes}) - atmos_sim = cs.model_sims.atmos_sim - face_space = axes(atmos_sim.integrator.u.f) - nz_faces = length(face_space.grid.vertical_grid.topology.mesh.faces) - - LWd_TOA = CC.Fields.level( - CC.Fields.array2field(FT.(atmos_sim.integrator.p.radiation.rrtmgp_model.face_lw_flux_dn), face_space), - nz_faces - CC.Utilities.half, - ) - LWu_TOA = CC.Fields.level( - CC.Fields.array2field(FT.(atmos_sim.integrator.p.radiation.rrtmgp_model.face_lw_flux_up), face_space), - nz_faces - CC.Utilities.half, - ) - SWd_TOA = CC.Fields.level( - CC.Fields.array2field(FT.(atmos_sim.integrator.p.radiation.rrtmgp_model.face_sw_flux_dn), face_space), - nz_faces - CC.Utilities.half, - ) - SWu_TOA = CC.Fields.level( - CC.Fields.array2field(FT.(atmos_sim.integrator.p.radiation.rrtmgp_model.face_sw_flux_up), face_space), - nz_faces - CC.Utilities.half, - ) - - radiation_sources = @. -(LWd_TOA + SWd_TOA - LWu_TOA - SWu_TOA) - Utilities.swap_space!(cs.boundary_space, radiation_sources) -end - -""" - Diagnostics.get_var(cs::Interfacer.CoupledSimulation, ::Val{:precipitation_rate}) - -Precipitation rate (Kg m⁻² s⁻¹). -""" -Diagnostics.get_var(cs::Interfacer.CoupledSimulation, ::Val{:precipitation_rate}) = - .-Utilities.swap_space!( - cs.boundary_space, - cs.model_sims.atmos_sim.integrator.p.precipitation.surface_rain_flux .+ - cs.model_sims.atmos_sim.integrator.p.precipitation.surface_snow_flux, - ) - -# coupler diagnotics -""" - Diagnostics.get_var(cs::Interfacer.CoupledSimulation, ::Val{:T_sfc}) - -Combined surface temperature (K). -""" -Diagnostics.get_var(cs::Interfacer.CoupledSimulation, ::Val{:T_sfc}) = - Utilities.swap_space!(cs.boundary_space, cs.fields.T_S) - -""" - Diagnostics.get_var(cs::Interfacer.CoupledSimulation, ::Val{:turbulent_energy_fluxes}) - -Combined aerodynamic turbulent energy surface fluxes (W m⁻²). -""" -Diagnostics.get_var(cs::Interfacer.CoupledSimulation, ::Val{:turbulent_energy_fluxes}) = - Utilities.swap_space!(cs.boundary_space, cs.fields.F_turb_energy) - -# land diagnotics diff --git a/src/ClimaCoupler.jl b/src/ClimaCoupler.jl index 1546a992da..15eef13fa7 100644 --- a/src/ClimaCoupler.jl +++ b/src/ClimaCoupler.jl @@ -12,7 +12,6 @@ include("Regridder.jl") include("ConservationChecker.jl") include("FluxCalculator.jl") include("FieldExchanger.jl") -include("Diagnostics.jl") include("PostProcessor.jl") include("Checkpointer.jl") diff --git a/src/Diagnostics.jl b/src/Diagnostics.jl deleted file mode 100644 index 29ec702d86..0000000000 --- a/src/Diagnostics.jl +++ /dev/null @@ -1,242 +0,0 @@ -""" - Diagnostics - -This module contains functions for defining, gathering and outputting online model diagnostics from the Coupler. -""" -module Diagnostics -import Dates -import ClimaCore as CC -import ..Interfacer, ..TimeManager - -export get_var, init_diagnostics, accumulate_diagnostics!, save_diagnostics, TimeMean - -""" - AbstractOutputGroup - -Abstract type for ClimaCoupler's output diagnostics groups. Each diagnostic group should -contain fields that are of the same type and size, so the extended methods for the group's -operation functions work in the same way for all the fields. -""" -abstract type AbstractOutputGroup end - -""" - DiagnosticsGroup{S, NTO <: NamedTuple} - -Defines a concrete diagnostics group type with fields `field_vector`, `operations`, `save`, -`output_dir` and `name_tag`. -""" -struct DiagnosticsGroup{S, NTO <: NamedTuple} <: AbstractOutputGroup - field_vector::CC.Fields.FieldVector - operations::NTO - save::S - output_dir::String - name_tag::String -end - -""" - AbstractDiagnosticsOperations - -Abstract type for operations to be performed on ClimaCoupler's diagnostics. -""" -abstract type AbstractDiagnosticsOperations end - -""" - TimeMean{C} - -Defines a concrete operation type for time-averaged diagnostics. The counter `ct` -is used to accumulate the sum of the diagnostics. -""" -struct TimeMean{C} <: AbstractDiagnosticsOperations - ct::C -end -# TODO: TemporalVariances, SpatialMean, SpatialVariances - -""" - function init_diagnostics( - names::Tuple, - space::CC.Spaces.AbstractSpace; - save = TimeManager.EveryTimestep(), - operations = (;), - output_dir = "", - name_tag = "", - ) - -Initializes diagnostics groups. -""" -function init_diagnostics( - names::Tuple, - space::CC.Spaces.AbstractSpace; - save = TimeManager.EveryTimestep(), - operations = (;), - output_dir = "", - name_tag = "", -) - data = NamedTuple{names}(ntuple(i -> CC.Fields.zeros(space), length(names))) - return DiagnosticsGroup(CC.Fields.FieldVector(; data...), operations, save, output_dir, name_tag) -end - -""" - get_var(cs::Interfacer.CoupledSimulation, x) - -Defines variable extraction from the coupler simulation. User specific diagnostics -should extend this function in the experiments folder. - -Example: - -get_var(cs, ::Val{:T_sfc}) = cs.fields.T_S - -""" -get_var(::Interfacer.CoupledSimulation, x) = @warn "Variable $x is not defined." - -""" - accumulate_diagnostics!(cs::Interfacer.CoupledSimulation) - -Accumulates user-defined diagnostics listed in the in the `field_vector` of each `dg`. -""" -function accumulate_diagnostics!(cs::Interfacer.CoupledSimulation) - for dg in cs.diagnostics - if dg.operations.accumulate !== nothing - # TODO: avoid collecting at each timestep where not needed - iterate_operations(cs, dg, collect_diags(cs, dg)) - end - end -end - -""" - collect_diags(cs::Interfacer.CoupledSimulation, dg::DiagnosticsGroup) - -Collects diagnostics in diags names. -""" -function collect_diags(cs::Interfacer.CoupledSimulation, dg::DiagnosticsGroup) - FT = Interfacer.float_type(cs) - diags = (;) - - diag_names = propertynames(dg.field_vector) - for name in diag_names - diags = (; diags..., zip((name,), (FT.(get_var(cs, Val(name))),))...) - end - - return CC.Fields.FieldVector(; diags...) -end - -""" - iterate_operations(cs::Interfacer.CoupledSimulation, dg::DiagnosticsGroup, diags::CC.Fields.FieldVector) - -Applies iteratively all specified diagnostics operations. -""" -function iterate_operations(cs::Interfacer.CoupledSimulation, dg::DiagnosticsGroup, new_diags::CC.Fields.FieldVector) - for op in dg.operations - operation(cs, dg, new_diags, op) - end -end - -""" - operation(cs::Interfacer.CoupledSimulation, dg::DiagnosticsGroup, new_diags::CC.Fields.FieldVector, ::TimeMean) - -Accumulates in time all entries in `new_diags` and saves the result in `dg.field_vector`, while -increasing the `dg.ct` counter. -""" -function operation(::Interfacer.CoupledSimulation, dg::DiagnosticsGroup, new_diags::CC.Fields.FieldVector, ::TimeMean) - dg.field_vector .+= new_diags - dg.operations.accumulate.ct[1] += Int(1) - - return nothing -end - -""" - operation(cs::Interfacer.CoupledSimulation, dg::DiagnosticsGroup, new_diags::CC.Fields.FieldVector, ::Nothing) - -Accumulates in time all entries in `new_diags` and saves the result in `dg.field_vector`, while -increasing the `dg.ct` counter. -""" -function operation(::Interfacer.CoupledSimulation, dg::DiagnosticsGroup, new_diags::CC.Fields.FieldVector, ::Nothing) - dg.field_vector .= new_diags - return nothing -end - -""" - save_diagnostics(cs::Interfacer.CoupledSimulation) - - save_diagnostics(cs::Interfacer.CoupledSimulation, dg::DiagnosticsGroup, output_dir::String) - -Saves all entries in `dg` in separate HDF5 files per variable in `output_dir`. -""" -function save_diagnostics(cs::Interfacer.CoupledSimulation) - for dg in cs.diagnostics - if TimeManager.trigger_callback(cs, dg.save) - pre_save(dg.operations.accumulate, cs, dg) - save_diagnostics(cs, dg) - post_save(dg.operations.accumulate, cs, dg) - end - end -end -function save_diagnostics(cs::Interfacer.CoupledSimulation, dg::DiagnosticsGroup) - - date = cs.dates.date[1] - tag = dg.name_tag - diag_save = dg.save - output_dir = dg.output_dir - - !isdir(output_dir) && mkpath(output_dir) - - diag_names = propertynames(dg.field_vector) - diag_values = map(x -> getproperty(dg.field_vector, x), diag_names) - - @info "Saving coupler diagnostics:" - - for (name, values) in zip(diag_names, diag_values) - output_file = joinpath(output_dir, "$name.$tag." * string(date) * ".hdf5") - @info " $output_file" - hdfwriter = CC.InputOutput.HDF5Writer(output_file, cs.comms_ctx) - CC.InputOutput.HDF5.write_attribute(hdfwriter.file, "unix time", save_time_format(date, diag_save)) - CC.InputOutput.write!(hdfwriter, values, string(name)) - Base.close(hdfwriter) - end - return nothing - -end - -""" - save_time_format(date::Dates.DateTime, ::TimeManager.Monthly) - -Converts the DateTime `date` to the conventional Unix format (seconds elapsed since 00:00:00 UTC on 1 January 1970). -""" -function save_time_format(date::Dates.DateTime, ::TimeManager.Monthly) - date_m1 = date - Dates.Day(1) # obtain previous month - datetime = Dates.DateTime(Dates.yearmonth(date_m1)[1], Dates.yearmonth(date_m1)[2]) - Dates.datetime2unix(datetime) -end - -save_time_format(date::Dates.DateTime, ::TimeManager.EveryTimestep) = Dates.datetime2unix(date) - -""" - pre_save(::TimeMean, cs::Interfacer.CoupledSimulation, dg::DiagnosticsGroup) - -Divides the accumulated sum by 'ct' to form the mean, before saving the diagnostics. -""" -function pre_save(::TimeMean, cs::Interfacer.CoupledSimulation, dg::DiagnosticsGroup) - dg.field_vector .= dg.field_vector / dg.operations.accumulate.ct[1] -end - -""" - pre_save(::Nothing, cs::Interfacer.CoupledSimulation, dg::DiagnosticsGroup - -Collects variables and performs all specified operations before saving the snapshot diagnostics. -""" -pre_save(::Nothing, cs::Interfacer.CoupledSimulation, dg::DiagnosticsGroup) = - iterate_operations(cs, dg, collect_diags(cs, dg)) - -""" - post_save(::TimeMean, cs::Interfacer.CoupledSimulation, dg::DiagnosticsGroup) - -Resets accumulating fields and counts after saving the diagnostics. -""" -function post_save(::TimeMean, cs::Interfacer.CoupledSimulation, dg::DiagnosticsGroup) - FT = eltype(dg.field_vector) - dg.field_vector .= FT(0.0) - dg.operations.accumulate.ct .= FT(0) -end - -post_save(::Nothing, cs::Interfacer.CoupledSimulation, dg::DiagnosticsGroup) = nothing - -end # module diff --git a/src/Interfacer.jl b/src/Interfacer.jl index cec27c33f5..d998d4a1f6 100644 --- a/src/Interfacer.jl +++ b/src/Interfacer.jl @@ -50,11 +50,11 @@ struct CoupledSimulation{ DTI <: Real, NTMS <: NamedTuple, NTM <: NamedTuple, - TD <: Tuple, NTC <: NamedTuple, NTP <: NamedTuple, TF, TP, + DH, } comms_ctx::X dates::D @@ -67,11 +67,11 @@ struct CoupledSimulation{ Δt_cpl::DTI model_sims::NTMS mode::NTM - diagnostics::TD callbacks::NTC dirs::NTP turbulent_fluxes::TF thermo_params::TP + amip_diags_handler::DH end CoupledSimulation{FT}(args...) where {FT} = CoupledSimulation{FT, typeof.(args[1:end])...}(args...) diff --git a/src/PostProcessor.jl b/src/PostProcessor.jl index ae9a747fff..80c2b09972 100644 --- a/src/PostProcessor.jl +++ b/src/PostProcessor.jl @@ -1,7 +1,7 @@ """ PostProcessor -This module contains functions for postprocessing model data (saved during the simulation by `Diagnostics.jl`) after the simulation is complete. +This module contains functions for postprocessing model data after the simulation is complete. """ module PostProcessor diff --git a/test/conservation_checker_tests.jl b/test/conservation_checker_tests.jl index 097c042541..4c43826224 100644 --- a/test/conservation_checker_tests.jl +++ b/test/conservation_checker_tests.jl @@ -93,11 +93,11 @@ for FT in (Float32, Float64) Int(200), # Δt_cpl model_sims, # model_sims (;), # mode - (), # diagnostics (;), # callbacks (;), # dirs nothing, # turbulent_fluxes nothing, # thermo_params + nothing, # amip_diags_handler ) # set non-zero radiation and precipitation @@ -175,11 +175,11 @@ for FT in (Float32, Float64) Int(200), # Δt_cpl model_sims, # model_sims (;), # mode - (), # diagnostics (;), # callbacks (;), # dirs nothing, # turbulent_fluxes nothing, # thermo_params + nothing, # amip_diags_handler ) tot_energy, tot_water = ConservationChecker.check_conservation!(cs) diff --git a/test/debug/debug_amip_plots.jl b/test/debug/debug_amip_plots.jl index 24689aa161..015d989ee0 100644 --- a/test/debug/debug_amip_plots.jl +++ b/test/debug/debug_amip_plots.jl @@ -75,11 +75,11 @@ plot_field_names(sim::Interfacer.SurfaceStub) = (:stub_field,) Int(200), # Δt_cpl model_sims, # model_sims (;), # mode - (), # diagnostics (;), # callbacks (;), # dirs nothing, # turbulent_fluxes nothing, # thermo_params + nothing, # amip_diags_handler ) output_plots = "test_debug" diff --git a/test/diagnostics_tests.jl b/test/diagnostics_tests.jl deleted file mode 100644 index e1f72c4bc4..0000000000 --- a/test/diagnostics_tests.jl +++ /dev/null @@ -1,151 +0,0 @@ -#= - Unit tests for ClimaCoupler Diagnostics module -=# -import Test: @test, @testset, @test_warn -import ClimaComms -@static pkgversion(ClimaComms) >= v"0.6" && ClimaComms.@import_required_backends -import Dates -import ClimaCore as CC -import ClimaCoupler: ConservationChecker, Diagnostics, Interfacer, TimeManager - -include("TestHelper.jl") -import .TestHelper - -Diagnostics.get_var(cs::Interfacer.CoupledSimulation, ::Val{:x}) = 1 - -for FT in (Float32, Float64) - @testset "init_diagnostics for FT=$FT" begin - names = (:x, :y) - space = TestHelper.create_space(FT) - dg = Diagnostics.init_diagnostics(names, space) - @test typeof(dg) == Diagnostics.DiagnosticsGroup{TimeManager.EveryTimestep, NamedTuple{(), Tuple{}}} - end - - @testset "accumulate_diagnostics!, collect_diags, iterate_operations, operation{accumulation{TimeMean, Nothing}}, get_var for FT=$FT" begin - cases = (nothing, Diagnostics.TimeMean([Int(0)])) - expected_results = (FT(2), FT(3)) - for (c_i, case) in enumerate(cases) - names = (:x,) - space = TestHelper.create_space(FT) - dg_2d = Diagnostics.init_diagnostics( - names, - space, - save = TimeManager.EveryTimestep(), - operations = (; accumulate = case), - ) - dg_2d.field_vector .= FT(2) - cs = Interfacer.CoupledSimulation{FT}( - nothing, # comms_ctx - nothing, # dates - nothing, # boundary_space - nothing, # fields - nothing, # parsed_args - nothing, # conservation_checks - (Int(0), Int(1000)), # tspan - Int(100), # t - Int(100), # Δt_cpl - (;), # model_sims - (;), # mode - (dg_2d,), - (;), # callbacks - (;), # dirs - nothing, # turbulent_fluxes - nothing, # thermo_params - ) - Diagnostics.accumulate_diagnostics!(cs) - - ClimaComms.allowscalar(ClimaComms.device()) do - @test cs.diagnostics[1].field_vector[1] == expected_results[c_i] - end - - @test_warn "Variable Val{:z}() is not defined." Diagnostics.get_var(cs, Val(:z)) - end - end - - if !Sys.iswindows() # Windows has NetCDF / HDF5 support limitations - @testset "save_diagnostics" begin - test_dir = "diag_test_dir" - names = (:x,) - space = TestHelper.create_space(FT) - dg_2d = Diagnostics.init_diagnostics( - names, - space, - save = TimeManager.EveryTimestep(), - operations = (; accumulate = Diagnostics.TimeMean([Int(0)])), - output_dir = test_dir, - ) # or use accumulate = nothing for snapshop save - cs = Interfacer.CoupledSimulation{FT}( - ClimaComms.SingletonCommsContext(), # comms_ctx - (date = [Dates.DateTime(0, 2)], date1 = [Dates.DateTime(0, 1)]), # dates - nothing, # boundary_space - nothing, # fields - nothing, # parsed_args - nothing, # conservation_checks - (Int(0), Int(1000)),# tspan - Int(100), # t - Int(100), # Δt_cpl - (;), # model_sims - (;), # mode - (dg_2d,), # diagnostics - (;), # callbacks - (;), # dirs - nothing, # turbulent_fluxes - nothing, # thermo_params - ) - Diagnostics.save_diagnostics(cs, cs.diagnostics[1]) - file = filter(x -> endswith(x, ".hdf5"), readdir(test_dir)) - @test !isempty(file) - rm(test_dir; recursive = true, force = true) - - end - end - - @testset "save_time_format for FT=$FT" begin - date = Dates.DateTime(1970, 2, 1, 0, 1) - unix = Diagnostics.save_time_format(date, TimeManager.Monthly()) - @test unix == 0 - end - - @testset "pre_save{TimeMean, Nothing}, post_save for FT=$FT" begin - cases = (nothing, Diagnostics.TimeMean([Int(0)])) - expected_results = ((FT(3), FT(1), FT(1)), (FT(4), FT(2.5), FT(0))) - - for (c_i, case) in enumerate(cases) - names = (:x,) - space = TestHelper.create_space(FT) - dg_2d = Diagnostics.init_diagnostics( - names, - space, - save = TimeManager.EveryTimestep(), - operations = (; accumulate = case), - ) - dg_2d.field_vector .= FT(3) - cs = Interfacer.CoupledSimulation{FT}( - nothing, # comms_ctx - nothing, # dates - nothing, # boundary_space - nothing, # fields - nothing, # parsed_args - nothing, # conservation_checks - (Int(0), Int(1000)), # tspan - Int(100), # t - Int(100), # Δt_cpl - (;), # model_sims - (;), # mode - (dg_2d,), - (;), # callbacks - (;), # dirs - nothing, # turbulent_fluxes - nothing, # thermo_params - ) - Diagnostics.accumulate_diagnostics!(cs) - @test cs.diagnostics[1].field_vector[1] == expected_results[c_i][1] - Diagnostics.accumulate_diagnostics!(cs) - Diagnostics.pre_save(cs.diagnostics[1].operations.accumulate, cs, cs.diagnostics[1]) - @test cs.diagnostics[1].field_vector[1] == expected_results[c_i][2] - - Diagnostics.post_save(cs.diagnostics[1].operations.accumulate, cs, cs.diagnostics[1]) - @test cs.diagnostics[1].field_vector[1] == expected_results[c_i][3] - end - end -end diff --git a/test/flux_calculator_tests.jl b/test/flux_calculator_tests.jl index 83d614aa2a..08a736c1f5 100644 --- a/test/flux_calculator_tests.jl +++ b/test/flux_calculator_tests.jl @@ -320,11 +320,11 @@ for FT in (Float32, Float64) 0, # Δt_cpl model_sims, # model_sims (;), # mode - (), # diagnostics (;), # callbacks (;), # dirs nothing, # turbulent_fluxes nothing, # thermo_params + nothing, # amip_diags_handler ) FluxCalculator.water_albedo_from_atmosphere!(cs, nothing) @test sum(parent(cs.model_sims.ocean_sim.cache.α_direct) .- parent(ones(boundary_space)) .* 2) == 0 diff --git a/test/interfacer_tests.jl b/test/interfacer_tests.jl index bd28e3f78f..f752354d70 100644 --- a/test/interfacer_tests.jl +++ b/test/interfacer_tests.jl @@ -44,11 +44,11 @@ for FT in (Float32, Float64) Int(200), # Δt_cpl (;), # model_sims (;), # mode - (), # diagnostics (;), # callbacks (;), # dirs nothing, # turbulent_fluxes nothing, # thermo_params + nothing, # amip_diags_handler ) @test Interfacer.float_type(cs) == FT diff --git a/test/regridder_tests.jl b/test/regridder_tests.jl index b6b157566f..5c036166f9 100644 --- a/test/regridder_tests.jl +++ b/test/regridder_tests.jl @@ -83,11 +83,11 @@ for FT in (Float32, Float64) land_sim = DummyStub((; area_fraction = land_fraction)), ), # model_sims (;), # mode - (), # diagnostics (;), # callbacks (;), # dirs nothing, # turbulent_fluxes nothing, # thermo_params + nothing, # amip_diags_handler ) Regridder.update_surface_fractions!(cs) diff --git a/test/runtests.jl b/test/runtests.jl index a462ae293f..74e6437ca9 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -38,9 +38,6 @@ end @safetestset "FluxCalculator tests" begin include("flux_calculator_tests.jl") end -gpu_broken || @safetestset "Diagnostics tests" begin - include("diagnostics_tests.jl") -end gpu_broken || @safetestset "PostProcessor tests" begin include("postprocessor_tests.jl") end diff --git a/test/time_manager_tests.jl b/test/time_manager_tests.jl index f6f77d6076..95cc9a0ab6 100644 --- a/test/time_manager_tests.jl +++ b/test/time_manager_tests.jl @@ -27,11 +27,11 @@ for FT in (Float32, Float64) Int(Δt_cpl), # Δt_cpl (;), # model_sims (;), # mode - (), # diagnostics (;), # callbacks (;), # dirs nothing, # turbulent_fluxes nothing, # thermo_params + nothing, # amip_diags_handler ) for t in ((tspan[1] + Δt_cpl):Δt_cpl:tspan[end]) @@ -67,11 +67,11 @@ end Int(200), # Δt_cpl (;), # model_sims (;), # mode - (), # diagnostics (;), # callbacks (;), # dirs nothing, # turbulent_fluxes nothing, # thermo_params + nothing, # amip_diags_handler ) @test TimeManager.trigger_callback(cs, TimeManager.Monthly()) == true end @@ -103,7 +103,6 @@ end Int(200), # Δt_cpl (;), # model_sims (;), # mode - (), # diagnostics (; twhohourly_inactive = twhohourly_inactive, twhohourly_nothing = twhohourly_nothing, @@ -113,6 +112,7 @@ end (;), # dirs nothing, # turbulent_fluxes nothing, # thermo_params + nothing, # amip_diags_handler ) TimeManager.trigger_callback!(cs, cs.callbacks.twhohourly_inactive) @@ -171,11 +171,11 @@ end Int(200), # Δt_cpl (;), # model_sims (;), # mode - (), # diagnostics (;), # callbacks (;), # dirs nothing, # turbulent_fluxes nothing, # thermo_params + nothing, # amip_diags_handler ) TimeManager.update_firstdayofmonth!(cs, nothing) From e4bbc3008ab4a6fd0ea91bf184f589070d930849 Mon Sep 17 00:00:00 2001 From: Julia Sloan Date: Tue, 1 Oct 2024 16:56:21 -0700 Subject: [PATCH 3/3] make artifacts subdir of output --- .buildkite/amip/pipeline.yml | 8 +-- .buildkite/benchmarks/pipeline.yml | 16 ++--- .buildkite/longruns/pipeline.yml | 38 +++++------ .buildkite/nightly/pipeline.yml | 8 +-- .buildkite/pipeline.yml | 66 ++++++++++---------- experiments/ClimaEarth/run_amip.jl | 2 + experiments/ClimaEarth/user_io/io_helpers.jl | 2 +- 7 files changed, 71 insertions(+), 69 deletions(-) diff --git a/.buildkite/amip/pipeline.yml b/.buildkite/amip/pipeline.yml index 5b35e999d0..c4497aa656 100644 --- a/.buildkite/amip/pipeline.yml +++ b/.buildkite/amip/pipeline.yml @@ -45,7 +45,7 @@ steps: command: - echo "--- Run simulation" - "srun --cpu-bind=threads --cpus-per-task=4 julia --threads=3 --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/amip.yml --job_id amip" - artifact_paths: "experiments/ClimaEarth/output/amip/amip_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/amip/artifacts/*" timeout_in_minutes: 5760 env: CLIMACOMMS_DEVICE: "CUDA" @@ -64,9 +64,9 @@ steps: - label: ":envelope: Slack report: current AMIP" command: - - for file in $(find experiments/ClimaEarth/output/amip/amip_artifacts/ -regextype posix-extended -regex '.*/bias_[A-Z]{3}\.png'); do label=$(basename "$file" | grep -oP '(?<=bias_)[A-Za-z]{3}'); convert "$file" -gravity North -pointsize 50 -annotate +0+0 "$label" "experiments/ClimaEarth/output/amip/amip_artifacts/tmp_bias_$label.png"; done - - convert +append "experiments/ClimaEarth/output/amip/amip_artifacts/tmp_bias_???.png" experiments/ClimaEarth/output/amip/amip_artifacts/bias_all_seasons.png + - for file in $(find experiments/ClimaEarth/output/amip/amip/artifacts/ -regextype posix-extended -regex '.*/bias_[A-Z]{3}\.png'); do label=$(basename "$file" | grep -oP '(?<=bias_)[A-Za-z]{3}'); convert "$file" -gravity North -pointsize 50 -annotate +0+0 "$label" "experiments/ClimaEarth/output/amip/amip/artifacts/tmp_bias_$label.png"; done + - convert +append "experiments/ClimaEarth/output/amip/amip/artifacts/tmp_bias_???.png" experiments/ClimaEarth/output/amip/amip/artifacts/bias_all_seasons.png - | - find experiments/ClimaEarth/output/amip/amip_artifacts/ -type f -name 'bias*.png' -print0 | while IFS= read -r -d '' file; do + find experiments/ClimaEarth/output/amip/amip/artifacts/ -type f -name 'bias*.png' -print0 | while IFS= read -r -d '' file; do slack-upload -c "#coupler-report" -f "$$file" -m png -n "$$(basename "$$file" .png)" -x "$$(basename "$$file" .png)" done diff --git a/.buildkite/benchmarks/pipeline.yml b/.buildkite/benchmarks/pipeline.yml index e14d809f4f..4382d245f9 100644 --- a/.buildkite/benchmarks/pipeline.yml +++ b/.buildkite/benchmarks/pipeline.yml @@ -45,7 +45,7 @@ steps: - label: "CPU ClimaAtmos without diagnostic EDMF" key: "climaatmos" command: "srun julia --color=yes --project=test/ test/component_model_tests/climaatmos_standalone/atmos_driver.jl --config_file $BENCHMARK_CONFIG_PATH/climaatmos.yml --job_id climaatmos" - artifact_paths: "experiments/ClimaEarth/output/climaatmos/climaatmos_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/climaatmos/climaatmos/artifacts/*" env: CLIMACOMMS_CONTEXT: "MPI" BUILD_HISTORY_HANDLE: "" @@ -58,7 +58,7 @@ steps: - label: "CPU ClimaAtmos with diagnostic EDMF" key: "climaatmos_diagedmf" command: "srun julia --color=yes --project=test/ test/component_model_tests/climaatmos_standalone/atmos_driver.jl --config_file $BENCHMARK_CONFIG_PATH/climaatmos_diagedmf.yml --job_id climaatmos_diagedmf" - artifact_paths: "experiments/ClimaEarth/output/climaatmos/climaatmos_diagedmf_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/climaatmos/climaatmos_diagedmf/artifacts/*" env: CLIMACOMMS_CONTEXT: "MPI" BUILD_HISTORY_HANDLE: "" @@ -71,7 +71,7 @@ steps: - label: "CPU AMIP with diagnostic EDMF" key: "amip_diagedmf" command: "srun julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $BENCHMARK_CONFIG_PATH/amip_diagedmf.yml --job_id amip_diagedmf" - artifact_paths: "experiments/ClimaEarth/output/amip/amip_diagedmf_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/amip_diagedmf/artifacts/*" env: CLIMACOMMS_CONTEXT: "MPI" BUILD_HISTORY_HANDLE: "" @@ -84,7 +84,7 @@ steps: - label: "CPU AMIP with diagnostic EDMF and io" key: "amip_diagedmf_io" command: "srun julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $BENCHMARK_CONFIG_PATH/amip_diagedmf_io.yml --job_id amip_diagedmf_io" - artifact_paths: "experiments/ClimaEarth/output/amip/amip_diagedmf_io_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/amip_diagedmf_io/artifacts/*" env: CLIMACOMMS_CONTEXT: "MPI" BUILD_HISTORY_HANDLE: "" @@ -99,7 +99,7 @@ steps: - label: "GPU ClimaAtmos without diagnostic EDMF" key: "gpu_climaatmos" command: "srun julia --threads=3 --color=yes --project=test/ test/component_model_tests/climaatmos_standalone/atmos_driver.jl --config_file $BENCHMARK_CONFIG_PATH/climaatmos.yml --job_id gpu_climaatmos" - artifact_paths: "experiments/ClimaEarth/output/climaatmos/gpu_climaatmos_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/climaatmos/gpu_climaatmos/artifacts/*" env: CLIMACOMMS_CONTEXT: "MPI" CLIMACOMMS_DEVICE: "CUDA" @@ -112,7 +112,7 @@ steps: - label: "GPU ClimaAtmos with diagnostic EDMF" key: "gpu_climaatmos_diagedmf" command: "srun julia --threads=3 --color=yes --project=test/ test/component_model_tests/climaatmos_standalone/atmos_driver.jl --config_file $BENCHMARK_CONFIG_PATH/climaatmos_diagedmf.yml --job_id gpu_climaatmos_diagedmf" - artifact_paths: "experiments/ClimaEarth/output/climaatmos/gpu_climaatmos_diagedmf_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/climaatmos/gpu_climaatmos_diagedmf/artifacts/*" env: CLIMACOMMS_CONTEXT: "MPI" CLIMACOMMS_DEVICE: "CUDA" @@ -125,7 +125,7 @@ steps: - label: "GPU AMIP with diagnostic EDMF" key: "gpu_amip_diagedmf" command: "srun julia --threads=3 --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $BENCHMARK_CONFIG_PATH/amip_diagedmf.yml --job_id gpu_amip_diagedmf" - artifact_paths: "experiments/ClimaEarth/output/amip/gpu_amip_diagedmf_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/gpu_amip_diagedmf/artifacts/*" env: CLIMACOMMS_CONTEXT: "MPI" CLIMACOMMS_DEVICE: "CUDA" @@ -138,7 +138,7 @@ steps: - label: "GPU AMIP with diagnostic EDMF and IO" key: "gpu_amip_diagedmf_io" command: "srun julia --threads=3 --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $BENCHMARK_CONFIG_PATH/amip_diagedmf_io.yml --job_id gpu_amip_diagedmf_io" - artifact_paths: "experiments/ClimaEarth/output/amip/gpu_amip_diagedmf_io_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/gpu_amip_diagedmf_io/artifacts/*" env: CLIMACOMMS_CONTEXT: "MPI" CLIMACOMMS_DEVICE: "CUDA" diff --git a/.buildkite/longruns/pipeline.yml b/.buildkite/longruns/pipeline.yml index 0df5d75237..38c54b6461 100644 --- a/.buildkite/longruns/pipeline.yml +++ b/.buildkite/longruns/pipeline.yml @@ -73,7 +73,7 @@ steps: - label: "Slabplanet_aqua: nocouple" key: "slabplanet_aqua_atmos_sf_nocouple" # SF at each Atmos stage, no coupling, prescribed SST from atmos command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_aqua_atmos_sf_nocouple.yml --job_id slabplanet_aqua_atmos_sf_nocouple" - artifact_paths: "experiments/ClimaEarth/output/slabplanet_aqua/slabplanet_aqua_atmos_sf_nocouple_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet_aqua/slabplanet_aqua_atmos_sf_nocouple/artifacts/*" env: BUILD_HISTORY_HANDLE: "" agents: @@ -85,7 +85,7 @@ steps: - label: "Slabplanet_aqua: couple" key: "slabplanet_aqua_atmos_sf_couple" # SF at each Atmos stage, coupling, prescribed SST from coupler - identical results to the above confirm 1) initial conditions in Atmos are unchanged compared to the slab, 2) coupling not introducing variability when constant surface command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_aqua_atmos_sf_couple.yml --job_id slabplanet_aqua_atmos_sf_couple" - artifact_paths: "experiments/ClimaEarth/output/slabplanet_aqua/slabplanet_aqua_atmos_sf_couple_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet_aqua/slabplanet_aqua_atmos_sf_couple/artifacts/*" env: BUILD_HISTORY_HANDLE: "" agents: @@ -97,7 +97,7 @@ steps: - label: "Slabplanet_aqua: coupler fluxes" key: "slabplanet_aqua_coupler_sf" # SF at each coupler timestep, constant ocean - comparing to the above runs, this tests the sensitivity of less frequent flux calculation command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_aqua_coupler_sf.yml --job_id slabplanet_aqua_coupler_sf" - artifact_paths: "experiments/ClimaEarth/output/slabplanet_aqua/slabplanet_aqua_coupler_sf_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet_aqua/slabplanet_aqua_coupler_sf/artifacts/*" env: BUILD_HISTORY_HANDLE: "" agents: @@ -109,7 +109,7 @@ steps: - label: "Slabplanet_aqua: coupler fluxes, evolving ocean" key: "slabplanet_aqua_coupler_sf_evolve_ocn" # SF at each coupler timestep, evolving ocean - comparing to the above run, tests the sensitivity of evolving ocean command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_aqua_coupler_sf_evolve_ocn.yml --job_id slabplanet_aqua_coupler_sf_evolve_ocn" - artifact_paths: "experiments/ClimaEarth/output/slabplanet_aqua/slabplanet_aqua_coupler_sf_evolve_ocn_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet_aqua/slabplanet_aqua_coupler_sf_evolve_ocn/artifacts/*" env: BUILD_HISTORY_HANDLE: "" agents: @@ -121,7 +121,7 @@ steps: - label: "Slabplanet_terra: coupler fluxes, evolving bucket" key: "slabplanet_terra" # SF at each coupler timestep, evolving ocean - comparing to the above run, tests the sensitivity of evolving bucket command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_terra.yml --job_id slabplanet_terra" - artifact_paths: "experiments/ClimaEarth/output/slabplanet_terra/slabplanet_terra_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet_terra/slabplanet_terra/artifacts/*" env: BUILD_HISTORY_HANDLE: "" agents: @@ -133,7 +133,7 @@ steps: - label: "Slabplanet: coupler fluxes, evolving ocean and land" key: "slabplanet_coupler_sf_evolve_ocn" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_coupler_sf_evolve_ocn.yml --job_id slabplanet_coupler_sf_evolve_ocn" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_coupler_sf_evolve_ocn_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_coupler_sf_evolve_ocn/artifacts/*" env: BUILD_HISTORY_HANDLE: "" agents: @@ -162,7 +162,7 @@ steps: - label: "TARGET IDEALIZED: new target aqua - fixed ocean T, nocouple, atmos flux calc" key: "slabplanet_aqua_target_nocouple" command: "srun julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_aqua_target_nocouple.yml --job_id slabplanet_aqua_target_nocouple" - artifact_paths: "experiments/ClimaEarth/output/slabplanet_aqua/slabplanet_aqua_target_nocouple_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet_aqua/slabplanet_aqua_target_nocouple/artifacts/*" env: CLIMACOMMS_CONTEXT: "MPI" BUILD_HISTORY_HANDLE: "" @@ -175,7 +175,7 @@ steps: - label: "TARGET IDEALIZED: new target aqua - fixed ocean T, coupler flux calc" key: "slabplanet_aqua_target" command: "srun julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_aqua_target.yml --job_id slabplanet_aqua_target" - artifact_paths: "experiments/ClimaEarth/output/slabplanet_aqua/slabplanet_aqua_target_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet_aqua/slabplanet_aqua_target/artifacts/*" env: CLIMACOMMS_CONTEXT: "MPI" BUILD_HISTORY_HANDLE: "" @@ -188,7 +188,7 @@ steps: - label: "TARGET IDEALIZED: new target aqua - evolving slab ocean T" key: "slabplanet_aqua_target_evolve_ocn" command: "srun julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_aqua_target_evolve_ocn.yml --job_id slabplanet_aqua_target_evolve_ocn" - artifact_paths: "experiments/ClimaEarth/output/slabplanet_aqua/slabplanet_aqua_target_evolve_ocn_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet_aqua/slabplanet_aqua_target_evolve_ocn/artifacts/*" env: CLIMACOMMS_CONTEXT: "MPI" BUILD_HISTORY_HANDLE: "" @@ -201,7 +201,7 @@ steps: - label: "TARGET IDEALIZED: new target slab - fixed ocean T, bucket" key: "slabplanet_target" command: "srun julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_target.yml --job_id slabplanet_target" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_target_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_target/artifacts/*" env: CLIMACOMMS_CONTEXT: "MPI" BUILD_HISTORY_HANDLE: "" @@ -214,7 +214,7 @@ steps: - label: "TARGET IDEALIZED: new target slab - evolving slab ocean T, bucket" key: "slabplanet_target_evolve_ocn" command: "srun julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_target_evolve_ocn.yml --job_id slabplanet_target_evolve_ocn" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_target_evolve_ocn_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_target_evolve_ocn/artifacts/*" env: CLIMACOMMS_CONTEXT: "MPI" BUILD_HISTORY_HANDLE: "" @@ -231,7 +231,7 @@ steps: - label: "MPI AMIP FINE: new target amip" key: "amip_target" command: "srun julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/amip_target.yml --job_id amip_target" - artifact_paths: "experiments/ClimaEarth/output/amip/amip_target_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/amip_target/artifacts/*" env: CLIMACOMMS_CONTEXT: "MPI" BUILD_HISTORY_HANDLE: "" @@ -244,7 +244,7 @@ steps: - label: "MPI AMIP FINE: new target amip: topo" key: "amip_target_topo" command: "srun julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/amip_target_topo.yml --job_id amip_target_topo" - artifact_paths: "experiments/ClimaEarth/output/amip/amip_target_topo_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/amip_target_topo/artifacts/*" env: CLIMACOMMS_CONTEXT: "MPI" BUILD_HISTORY_HANDLE: "" @@ -257,7 +257,7 @@ steps: - label: "MPI AMIP FINE: new target amip: topo + diagedmf" key: "amip_target_topo_diagedmf_cpu" command: "srun julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/amip_target_topo_diagedmf_cpu.yml --job_id amip_target_topo_diagedmf_cpu" - artifact_paths: "experiments/ClimaEarth/output/amip/amip_target_topo_diagedmf_cpu_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/amip_target_topo_diagedmf_cpu/artifacts/*" env: CLIMACOMMS_CONTEXT: "MPI" BUILD_HISTORY_HANDLE: "" @@ -274,7 +274,7 @@ steps: - label: "GPU AMIP FINE: new target amip: topo" key: "amip_target_topo_gpu" command: "srun julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/amip_target_topo.yml --job_id amip_target_topo_gpu" - artifact_paths: "experiments/ClimaEarth/output/amip/amip_target_topo_gpu_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/amip_target_topo_gpu/artifacts/*" env: CLIMACOMMS_CONTEXT: "MPI" CLIMACOMMS_DEVICE: "CUDA" @@ -288,7 +288,7 @@ steps: command: - echo "--- Run simulation" - "srun --cpu-bind=threads --cpus-per-task=4 julia --threads=3 --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/amip_target_topo_diagedmf_gpu.yml --job_id amip_target_topo_diagedmf_gpu" - artifact_paths: "experiments/ClimaEarth/output/amip/amip_target_topo_diagedmf_gpu_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/amip_target_topo_diagedmf_gpu/artifacts/*" timeout_in_minutes: 1440 env: CLIMACOMMS_CONTEXT: "MPI" @@ -308,7 +308,7 @@ steps: command: - echo "--- Run simulation" - "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/longrun_amip_dyamond.yml --job_id longrun_amip_dyamond_gpu" - artifact_paths: "experiments/ClimaEarth/output/amip/longrun_amip_dyamond_gpu_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/longrun_amip_dyamond_gpu/artifacts/*" env: CLIMACOMMS_DEVICE: "CUDA" agents: @@ -335,5 +335,5 @@ steps: - label: ":envelope: Slack report: Slabplanet" command: - - slack-upload -c "#coupler-report" -f experiments/ClimaEarth/output/slabplanet/slabplanet_coupler_sf_evolve_ocn_artifacts/total_energy_bucket.png -m png -n slab_coarse -x "Slabplanet energy conservation" - - slack-upload -c "#coupler-report" -f experiments/ClimaEarth/output/slabplanet/slabplanet_coupler_sf_evolve_ocn_artifacts/total_water_bucket.png -m png -n slab_coarse_w -x "Slabplanet water conservation" + - slack-upload -c "#coupler-report" -f experiments/ClimaEarth/output/slabplanet/slabplanet_coupler_sf_evolve_ocn/artifacts/total_energy_bucket.png -m png -n slab_coarse -x "Slabplanet energy conservation" + - slack-upload -c "#coupler-report" -f experiments/ClimaEarth/output/slabplanet/slabplanet_coupler_sf_evolve_ocn/artifacts/total_water_bucket.png -m png -n slab_coarse_w -x "Slabplanet water conservation" diff --git a/.buildkite/nightly/pipeline.yml b/.buildkite/nightly/pipeline.yml index bbbd2d2353..2b043f25cf 100644 --- a/.buildkite/nightly/pipeline.yml +++ b/.buildkite/nightly/pipeline.yml @@ -55,7 +55,7 @@ steps: command: - echo "--- Run simulation" - "julia --threads=3 --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/amip_coarse.yml --job_id amip_coarse" - artifact_paths: "experiments/ClimaEarth/output/amip/amip_coarse_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/amip_coarse/artifacts/*" timeout_in_minutes: 840 env: CLIMACOMMS_DEVICE: "CUDA" @@ -70,7 +70,7 @@ steps: command: - echo "--- Run simulation" - "julia --threads=3 --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/amip_coarse_random.yml --job_id amip_coarse_random1" - artifact_paths: "experiments/ClimaEarth/output/amip/amip_coarse_random1_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/amip_coarse_random1/artifacts/*" timeout_in_minutes: 1080 env: CLIMACOMMS_DEVICE: "CUDA" @@ -85,7 +85,7 @@ steps: command: - echo "--- Run simulation" - "julia --threads=3 --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/amip_coarse_random.yml --job_id amip_coarse_random2" - artifact_paths: "experiments/ClimaEarth/output/amip/amip_coarse_random2_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/amip_coarse_random2/artifacts/*" timeout_in_minutes: 1080 env: CLIMACOMMS_DEVICE: "CUDA" @@ -100,7 +100,7 @@ steps: command: - echo "--- Run simulation" - "julia --threads=3 --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/amip_coarse_random.yml --job_id amip_coarse_random3" - artifact_paths: "experiments/ClimaEarth/output/amip/amip_coarse_random3_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/amip_coarse_random3/artifacts/*" timeout_in_minutes: 1080 env: CLIMACOMMS_DEVICE: "CUDA" diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 4ebd9c31a6..25b863cb8b 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -146,70 +146,70 @@ steps: - label: "Slabplanet: default" key: "slabplanet_default" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_default.yml --job_id slabplanet_default" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_default_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_default/artifacts/*" agents: slurm_mem: 20GB - label: "Slabplanet: dry, no radiation" key: "slabplanet_dry_norad" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_dry_norad.yml --job_id slabplanet_dry_norad" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_dry_norad_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_dry_norad/artifacts/*" agents: slurm_mem: 20GB - label: "Slabplanet: default with Float32" key: "slabplanet_ft32" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_ft32.yml --job_id slabplanet_ft32" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_ft32_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_ft32/artifacts/*" agents: slurm_mem: 20GB - label: "Slabplanet: partitioned turbulent fluxes" key: "slabplanet_partitioned_fluxes" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_partitioned_fluxes.yml --job_id slabplanet_partitioned_fluxes" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_partitioned_fluxes_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_partitioned_fluxes/artifacts/*" agents: slurm_mem: 20GB - label: "Slabplanet: non-monotonous surface remap" key: "slabplanet_nonmono" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_nonmono.yml --job_id slabplanet_nonmono" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_nonmono_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_nonmono/artifacts/*" agents: slurm_mem: 20GB - label: "Slabplanet: albedo from static map" key: "slabplanet_albedo_static_map" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_albedo_static_map.yml --job_id slabplanet_albedo_static_map" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_albedo_static_map_artifacts/total_energy*.png" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_albedo_static_map/artifacts/total_energy*.png" agents: slurm_mem: 20GB - label: "Slabplanet: albedo from temporal map" key: "slabplanet_albedo_temporal_map" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_albedo_temporal_map.yml --job_id slabplanet_albedo_temporal_map" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_albedo_temporal_map_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_albedo_temporal_map/artifacts/*" agents: slurm_mem: 20GB - label: "Slabplanet: albedo from function" key: "slabplanet_albedo_function" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_albedo_function.yml --job_id slabplanet_albedo_function" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_albedo_function_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_albedo_function/artifacts/*" agents: slurm_mem: 20GB - label: "Slabplanet: eisenman sea ice" key: "slabplanet_eisenman" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_eisenman.yml --job_id slabplanet_eisenman" - artifact_paths: "experiments/ClimaEarth/output/slabplanet_eisenman/slabplanet_eisenman_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet_eisenman/slabplanet_eisenman/artifacts/*" agents: slurm_mem: 20GB - label: "Slabplanet: extra atmos diagnostics" key: "slabplanet_atmos_diags" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_atmos_diags.yml --job_id slabplanet_atmos_diags" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_atmos_diags_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/slabplanet_atmos_diags/artifacts/*" agents: slurm_mem: 20GB @@ -224,7 +224,7 @@ steps: - label: ":rocket: Slabplanet: default (unthreaded)" key: "slabplanet_unthreaded" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/default_unthreaded.yml --job_id default_unthreaded" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/default_unthreaded_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/default_unthreaded/artifacts/*" env: FLAME_PLOT: "" BUILD_HISTORY_HANDLE: "" @@ -256,7 +256,7 @@ steps: - label: "heat-diffusion" command: "julia --color=yes --project=experiments/ClimaCore/ experiments/ClimaCore/heat-diffusion/run.jl" - artifact_paths: "experiments/ClimaCore/output/heat-diffusion_artifacts/*" + artifact_paths: "experiments/ClimaCore/output/heat-diffusion/artifacts/*" agents: slurm_mem: 20GB @@ -264,48 +264,48 @@ steps: - label: "Moist earth with slab surface - default: monin gray no_sponge idealinsol freq_dt_cpl" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/default_mono.yml --job_id default_mono" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/default_mono_artifacts/total_energy*.png" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/default_mono/artifacts/total_energy*.png" agents: slurm_mem: 20GB - label: "Moist earth with slab surface - notmono: monin gray no_sponge idealinsol freq_dt_cpl notmono" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/default_notmono.yml --job_id default_notmono" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/default_notmono_artifacts/total_energy*.png" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/default_notmono/artifacts/total_energy*.png" agents: slurm_mem: 20GB # - label: "Moist earth with slab surface - test: monin allsky sponge idealinsol infreq_dt_cpl" # command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --FLOAT_TYPE Float64 --coupled true --surface_setup PrescribedSurface --moist equil --vert_diff true --rad allskywithclear --rayleigh_sponge true --alpha_rayleigh_uh 0 --alpha_rayleigh_w 10 --energy_check true --mode_name slabplanet --t_end 10days --dt_save_to_sol 3600secs --dt_cpl 21600 --dt 200secs --dt_rad 6hours --mono_surface true --h_elem 4 --precip_model 0M --job_id target_params_in_slab_test1" # Unconverged SF (reproduced locally); works with 200s dt_cpl - # artifact_paths: "experiments/ClimaEarth/output/slabplanet/target_params_in_slab_test1_artifacts/total_energy*.png" + # artifact_paths: "experiments/ClimaEarth/output/slabplanet/target_params_in_slab_test1/artifacts/total_energy*.png" - label: "Moist earth with slab surface - test: bulk allsky sponge realinsol infreq_dt_cpl" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/target_params_in_slab_test2.yml --job_id target_params_in_slab_test2" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/target_params_in_slab_test2_artifacts/total_energy*.png" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/target_params_in_slab_test2/artifacts/total_energy*.png" agents: slurm_mem: 20GB - label: "Moist earth with slab surface - test: monin gray sponge realinsol infreq_dt_cpl" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/target_params_in_slab_test3.yml --job_id target_params_in_slab_test3" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/target_params_in_slab_test3_artifacts/total_energy*.png" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/target_params_in_slab_test3/artifacts/total_energy*.png" agents: slurm_mem: 20GB # breaking: # - label: "Moist earth with slab surface - monin allsky no_sponge idealinsol infreq_dt_cpl" # command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --coupled true --surface_setup PrescribedSurface --moist equil --vert_diff true --rad allskywithclear --rayleigh_sponge false --energy_check true --mode_name slabplanet --t_end 10days --dt_save_to_sol 3600secs --dt_cpl 21600 --dt 200secs --dt_rad 6hours --idealized_insolation true --mono_surface true --h_elem 4 --precip_model 0M --job_id target_params_in_slab1" - # artifact_paths: "experiments/ClimaEarth/output/slabplanet/target_params_in_slab1_artifacts/total_energy*.png" + # artifact_paths: "experiments/ClimaEarth/output/slabplanet/target_params_in_slab1/artifacts/total_energy*.png" - label: "AMIP target: albedo from function" key: "target_amip_albedo_function" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/target_amip_albedo_function.yml --job_id target_amip_albedo_function" - artifact_paths: "experiments/ClimaEarth/output/amip/target_amip_albedo_function_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/target_amip_albedo_function/artifacts/*" agents: slurm_mem: 20GB - label: "AMIP - Float64 + hourly checkpoint" key: "amip" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/coarse_single_ft64_hourly_checkpoints.yml --job_id coarse_single_ft64_hourly_checkpoints" - artifact_paths: "experiments/ClimaEarth/output/amip/coarse_single_ft64_hourly_checkpoints_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/coarse_single_ft64_hourly_checkpoints/artifacts/*" env: FLAME_PLOT: "" BUILD_HISTORY_HANDLE: "" @@ -315,21 +315,21 @@ steps: - label: "AMIP - Float64 test" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/coarse_single_ft64.yml --job_id coarse_single_ft64" - artifact_paths: "experiments/ClimaEarth/output/amip/coarse_single_ft64_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/coarse_single_ft64/artifacts/*" agents: slurm_ntasks: 1 slurm_mem: 20GB - label: "AMIP - Float32 test" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/coarse_single_ft32.yml --job_id coarse_single_ft32" - artifact_paths: "experiments/ClimaEarth/output/amip/coarse_single_ft32_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/coarse_single_ft32/artifacts/*" agents: slurm_ntasks: 1 slurm_mem: 20GB - label: "MPI AMIP" command: "srun julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/coarse_mpi_n4.yml --job_id coarse_mpi_n4" - artifact_paths: "experiments/ClimaEarth/output/amip/coarse_mpi_n4_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/coarse_mpi_n4/artifacts/*" timeout_in_minutes: 240 env: CLIMACOMMS_CONTEXT: "MPI" @@ -342,7 +342,7 @@ steps: - label: "Unthreaded AMIP FINE" # also reported by longruns with a flame graph key: "unthreaded_amip_fine" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/target_amip_n1_shortrun.yml --job_id target_amip_n1_shortrun" - artifact_paths: "experiments/ClimaEarth/output/amip/target_amip_n1_shortrun_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/target_amip_n1_shortrun/artifacts/*" env: BUILD_HISTORY_HANDLE: "" agents: @@ -424,7 +424,7 @@ steps: - label: "GPU Slabplanet: albedo from function" key: "gpu_slabplanet_albedo_function" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_albedo_function.yml --job_id gpu_slabplanet_albedo_function" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/gpu_slabplanet_albedo_function_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/gpu_slabplanet_albedo_function/artifacts/*" env: CLIMACOMMS_DEVICE: "CUDA" agents: @@ -434,7 +434,7 @@ steps: - label: "GPU Slabplanet: albedo from static map" key: "gpu_slabplanet_albedo_static_map" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_albedo_static_map.yml --job_id gpu_slabplanet_albedo_static_map" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/gpu_slabplanet_albedo_static_map_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/gpu_slabplanet_albedo_static_map/artifacts/*" env: CLIMACOMMS_DEVICE: "CUDA" agents: @@ -444,7 +444,7 @@ steps: - label: "GPU Slabplanet: albedo from temporal map" key: "gpu_slabplanet_albedo_temporal_map" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_albedo_temporal_map.yml --job_id gpu_slabplanet_albedo_temporal_map" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/gpu_slabplanet_albedo_temporal_map_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/gpu_slabplanet_albedo_temporal_map/artifacts/*" env: CLIMACOMMS_DEVICE: "CUDA" agents: @@ -454,7 +454,7 @@ steps: - label: "GPU Slabplanet: extra atmos diagnostics" key: "gpu_slabplanet_atmos_diags" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/slabplanet_atmos_diags.yml --job_id gpu_slabplanet_atmos_diags" - artifact_paths: "experiments/ClimaEarth/output/slabplanet/gpu_slabplanet_atmos_diags_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/slabplanet/gpu_slabplanet_atmos_diags/artifacts/*" env: CLIMACOMMS_DEVICE: "CUDA" agents: @@ -465,7 +465,7 @@ steps: - label: "GPU AMIP test: albedo from function" key: "gpu_amip_albedo_function" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/gpu_amip_albedo_function.yml --job_id gpu_amip_albedo_function" - artifact_paths: "experiments/ClimaEarth/output/amip/gpu_amip_albedo_function_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/gpu_amip_albedo_function/artifacts/*" env: CLIMACOMMS_DEVICE: "CUDA" agents: @@ -475,7 +475,7 @@ steps: - label: "GPU AMIP target: topography and diagnostic EDMF" key: "gpu_amip_target_topo_diagedmf_shortrun" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/gpu_amip_target_topo_diagedmf_shortrun.yml --job_id gpu_amip_target_topo_diagedmf_shortrun" - artifact_paths: "experiments/ClimaEarth/output/amip/gpu_amip_target_topo_diagedmf_shortrun_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/gpu_amip_target_topo_diagedmf_shortrun/artifacts/*" env: CLIMACOMMS_DEVICE: "CUDA" agents: @@ -485,7 +485,7 @@ steps: - label: "GPU AMIP: albedo from static map" key: "gpu_amip_albedo_static_map" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/gpu_amip_albedo_static_map.yml --job_id gpu_amip_albedo_static_map" - artifact_paths: "experiments/ClimaEarth/output/amip/gpu_amip_albedo_static_map_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/gpu_amip_albedo_static_map/artifacts/*" env: CLIMACOMMS_DEVICE: "CUDA" agents: @@ -495,7 +495,7 @@ steps: - label: "GPU AMIP: albedo from temporal map + 0M" key: "gpu_amip_albedo_temporal_map" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/gpu_amip_albedo_temporal_map.yml --job_id gpu_amip_albedo_temporal_map" - artifact_paths: "experiments/ClimaEarth/output/amip/gpu_amip_albedo_temporal_map_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/gpu_amip_albedo_temporal_map/artifacts/*" env: CLIMACOMMS_DEVICE: "CUDA" agents: @@ -505,7 +505,7 @@ steps: - label: "GPU AMIP: albedo from temporal map + 1M" key: "gpu_amip_albedo_temporal_map_1M" command: "julia --color=yes --project=experiments/ClimaEarth/ experiments/ClimaEarth/run_amip.jl --config_file $CONFIG_PATH/gpu_amip_albedo_temporal_map_1M.yml --job_id gpu_amip_albedo_temporal_map_1M" - artifact_paths: "experiments/ClimaEarth/output/amip/gpu_amip_albedo_temporal_map_1M_artifacts/*" + artifact_paths: "experiments/ClimaEarth/output/amip/gpu_amip_albedo_temporal_map_1M/artifacts/*" env: CLIMACOMMS_DEVICE: "CUDA" agents: diff --git a/experiments/ClimaEarth/run_amip.jl b/experiments/ClimaEarth/run_amip.jl index 746cc92321..ebda26adee 100644 --- a/experiments/ClimaEarth/run_amip.jl +++ b/experiments/ClimaEarth/run_amip.jl @@ -202,6 +202,8 @@ temporary files will be saved. COUPLER_OUTPUT_DIR = joinpath(config_dict["coupler_output_dir"], joinpath(mode_name, job_id)) dir_paths = setup_output_dirs(output_dir = COUPLER_OUTPUT_DIR, comms_ctx = comms_ctx) +@info "Coupler output directory $(dir_paths.output)" +@info "Coupler artifacts directory $(dir_paths.artifacts)" @info(dir_paths.output) config_dict["print_config_dict"] && @info(config_dict) diff --git a/experiments/ClimaEarth/user_io/io_helpers.jl b/experiments/ClimaEarth/user_io/io_helpers.jl index 03642dfe9f..ae50e51380 100644 --- a/experiments/ClimaEarth/user_io/io_helpers.jl +++ b/experiments/ClimaEarth/user_io/io_helpers.jl @@ -21,7 +21,7 @@ function setup_output_dirs(; output_dir = nothing, artifacts_dir = nothing, comm output_dir = "." end if artifacts_dir === nothing - artifacts_dir = output_dir * "_artifacts" + artifacts_dir = joinpath(output_dir, "artifacts") end @info(output_dir)