Skip to content

Commit

Permalink
Rework diagnostic writers
Browse files Browse the repository at this point in the history
- Transform writers to standalone objects instead of functions
- Have one writer for all the diagnostics
- Add support to general NetCDF writer

Now with support for all the configurations (including planes ✈️)
  • Loading branch information
Sbozzolo committed Oct 4, 2023
1 parent 6548c1f commit 61cbe72
Show file tree
Hide file tree
Showing 6 changed files with 528 additions and 95 deletions.
41 changes: 26 additions & 15 deletions docs/src/diagnostics.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ identifies the period over which to compute the reduction and how often to save
to disk. `output_name` is optional, and if provided, it identifies the name of the
output file.

The default `writer` is HDF5. If `writer` is `nc` or `netcdf`, the output is
The default `writer` is NetCDF. If `writer` is `nc` or `netcdf`, the output is
remapped non-conservatively on a Cartesian grid and saved to a NetCDF file.
Currently, only 3D fields on cubed spheres are supported.
Currently, the NetCDF writer does not support plane configurations.

### From a script

Expand Down Expand Up @@ -91,7 +91,7 @@ More specifically, a `ScheduledDiagnostic` contains the following pieces of data

- `variable`: The diagnostic variable that has to be computed and output.
- `output_every`: Frequency of how often to save the results to disk.
- `output_writer`: Function that controls out to save the computed diagnostic
- `output_writer`: Object that controls out to save the computed diagnostic
variable to disk.
- `reduction_time_func`: If not `nothing`, the `ScheduledDiagnostic` receives an
area of scratch space `acc` where to accumulate partial results. Then, at
Expand Down Expand Up @@ -134,18 +134,29 @@ that we have a neutral state for the accumulators that are used in the
reductions.

A key entry in a `ScheduledDiagnostic` is the `output_writer`, the function
responsible for saving the output to disk. `output_writer` is called with three
arguments: the value that has to be output, the `ScheduledDiagnostic`, and the
integrator. Internally, the integrator contains extra information (such as the
current timestep), so the `output_writer` can implement arbitrarily complex
behaviors. It is responsibility of the `output_writer` to properly use the
provided information for meaningful output. `ClimaAtmos` provides functions that
return `output_writer`s for standard operations. The main one is currently
`HDF5Writer`, which should be enough for most use cases. To use it, just
initialize a `ClimaAtmos.HDF5Writer` object with your choice of configuration
and pass it as a `output_writer` argument to the `ScheduledDiagnostic`. More
information about the options supported by `ClimaAtmos.HDF5Writer` is available
in its constructor.
responsible for saving the output to disk. `output_writer` is an object that
contains information on how to write the diagnostic to disk. It is called by
calling a function `write_field!(writer, field, diagnostic, integrator)`, where
`field` is the value that has to be output, `diagnostic`, the
`ScheduledDiagnostic`, and `integrator` is the `SciML` integrator. Internally,
the integrator contains extra information (such as the current timestep), so the
`output_writer` can implement arbitrarily complex behaviors. It is
responsibility of the `output_writer` to properly use the provided information
for meaningful output.

`ClimaAtmos` provides `output_writer`s for standard operations. The main writer
is `NetCDFWriter`, which produces NetCDF files for the fields on lat-long-z or
x-y-z coordinates. The `NetCDFWriter` performs a Lagrange interpolation of the
fields onto the desired coordinates. To use a `NetCDFWriter`, you just need to
provide how many points you want the target space to be along the various
dimensions. `NetCDFWriter` will interpolate on a linearly spaced grid defined by
the boundaries of the domain and the number of points provided.

Another writer one is the `HDF5Writer`, which saves diagnostics as defined on
the computational grid. To use it, just initialize a `ClimaAtmos.HDF5Writer`
object with your choice of configuration and pass it as a `output_writer`
argument to the `ScheduledDiagnostic`. More information about the options
supported by `ClimaAtmos.HDF5Writer` is available in its constructor.

There are two flavors of `ScheduledDiagnostic`s:
`ScheduledDiagnosticIterations`, and `ScheduledDiagnosticTime`. The main
Expand Down
7 changes: 6 additions & 1 deletion src/diagnostics/Diagnostics.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
module Diagnostics

import ClimaComms

import LinearAlgebra: dot

import ClimaCore: Fields, Geometry, InputOutput, Meshes, Spaces, Operators
import ClimaCore:
Fields, Geometry, InputOutput, Meshes, Spaces, Operators, Domains
import ClimaCore.Utilities: half
import Thermodynamics as TD

Expand Down Expand Up @@ -37,4 +40,6 @@ include(joinpath("..", "utils", "abbreviations.jl"))

include("diagnostic.jl")
include("writers.jl")

export close
end
7 changes: 6 additions & 1 deletion src/diagnostics/diagnostic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,12 @@ function get_callbacks_from_diagnostics(
diag.pre_output_hook!(storage[diag], counters[diag])

# Write to disk
diag.output_writer(storage[diag], diag, integrator)
write_field!(
diag.output_writer,
storage[diag],
diag,
integrator,
)

# accumulator[diag] is not defined for non-reductions
diag_accumulator = get(accumulators, diag, nothing)
Expand Down
Loading

0 comments on commit 61cbe72

Please sign in to comment.