Add the tmx scalar diffusion component - #1490
Conversation
Tridiagonal matrix assembly for full-level cell, half-level cell and full-level edge fields, the implicit solve (Thomas algorithm as two vertical scans) on the same three grids, and the explicit update on full-level cells. Half-level fields are typed on KHalfDim. Co-authored-by: Jacopo Canton <jacopo.canton@gmail.com>
model/common/math/tridiagonal.py holds the Thomas algorithm as a forward sweep and a back substitution scan, in three variants: full levels (wp), half levels (wp) and half levels in mixed precision. The forward sweep carries q = -c' in all of them, as ICON's z_q does. The mixed-precision pair is dycore's former w solver, unchanged; the dycore stencils call it from common. tmx vertical diffusion uses the two wp pairs instead of its own scans. Co-authored-by: Jacopo Canton <jacopo.canton@gmail.com>
Its only caller is the scalar diffusion's explicit solver.
_solve_tridiagonal_matrix_on_{cells,cell_half_levels,edges} run the
forward sweep and the back substitution in one call. Field operators are
not generic over dimensions, so there is one per field type. The tmx
implicit vertical diffusion uses them.
Matrix assembly on V's operators, one program per tracer for the implicit vertical and the horizontal diffusion, and the energy path of the temperature diffusion. Co-authored-by: Jacopo Canton <jacopo.canton@gmail.com>
Co-authored-by: Jacopo Canton <jacopo.canton@gmail.com>
Co-authored-by: Jacopo Canton <jacopo.canton@gmail.com>
…iffusion datatests
# Conflicts: # model/atmosphere/subgrid_scale_physics/tmx/src/icon4py/model/atmosphere/subgrid_scale_physics/tmx/stencils/vertical_diffusion.py # model/common/src/icon4py/model/common/math/tridiagonal.py
…cit solver The energy type decides three operations (energy from temperature, surface energy flux, temperature from energy); each is now a named pair of field operators selected by the static use_internal_energy, and the energy goes through the same diffusion core as the tracers. The energy matrix is assembled inside the energy program. SolverType has only IMPLICIT; TmxConfig and namelist parsing reject the explicit solver, which was only used for early testing in ICON.
The explicit solver is removed from SolverType in the scalar-diffusion PR (#1490).
nfarabullini
left a comment
There was a problem hiding this comment.
just a couple of small things
|
wait for me on this one please, I have a couple of comments queued since Friday and will finish today |
jcanton
left a comment
There was a problem hiding this comment.
more comments than I though. the ones about the ser_data and its version are unfortunately blocking
| fields = ( | ||
| (setup.tendency_state.tend_qv, exit_savepoint.tend_qv(), "tend_qv", 5.0e-20), | ||
| (setup.tendency_state.tend_qc, exit_savepoint.tend_qc(), "tend_qc", 5.0e-21), | ||
| (setup.tendency_state.tend_qi, exit_savepoint.tend_qi(), "tend_qi", 3.0e-22), | ||
| (setup.new_state.qv, exit_savepoint.qv_new(), "qv_new", 2.0e-17), | ||
| (setup.new_state.qc, exit_savepoint.qc_new(), "qc_new", 2.0e-18), | ||
| (setup.new_state.qi, exit_savepoint.qi_new(), "qi_new", 7.0e-20), |
There was a problem hiding this comment.
should we have a more strict/precise per-backend dict of atol+rtol so crappier backends don't hide potential regressions in better backends? (again, since we're making this a template for future ports and we can measure atol/rtol at port-time with ICON4PY_DALLCLOSE_PRINT_INSTEAD_OF_FAIL: true
There was a problem hiding this comment.
Should we do it in the end after all components are in, because there are already the tests from the first PR which didn't do that?
| ) | ||
|
|
||
| log.debug("communication of energy (cells): start") | ||
| self._exchange.exchange(dims.CellDim, self.energy) |
There was a problem hiding this comment.
Just wondering whether we can remove this exchange by putting energy calculation into the subsequent stencil and gt4py does the rest.
There was a problem hiding this comment.
Let's maybe do it later in an optimization round, because currently we don't have mpi tests.
# Conflicts: # model/atmosphere/subgrid_scale_physics/tmx/src/icon4py/model/atmosphere/subgrid_scale_physics/tmx/config.py # model/atmosphere/subgrid_scale_physics/tmx/tests/tmx/fixtures.py # model/atmosphere/subgrid_scale_physics/tmx/tests/tmx/unit_tests/test_tmx_config.py
Catches up with #1466, which moved the Fortran-to-Python mapping out of the config classes and into `scripts/python/fortran_config_converter.py`, and makes the tmx datatests take their configuration from the experiment's `config.yml`: - drop `TmxConfig.from_fortran_dict` and the `icon_equivalent` annotations; the positional `aes_vdf_nml` pins live in the converter's `TMX` mapping. The converter reads `solver_type` as a plain int, so that `TmxConfig.__post_init__` reports the unported explicit solver rather than the bare enum conversion failing first. The `from_fortran_dict` unit tests go: the converter tests already cover the member count and `use_tmx` checks, and gain the explicit-solver rejection. - drop the `tmx_config` fixture: the datatests read `experiment.config.tmx`. - drop the `tmx_dtime` fixture, which read `dt_vdf` as the time step of the solver. ICON runs tmx with the model time step (`init_tmx(p_patch(jg), dt_loc)` with `dt_loc = get_model_timestep_sec(...)` in `mo_atmo_nonhydrostatic.f90`); `dt_vdf` only sets how often the process fires. The datatests now use `experiment.config.driver.dtime`. The two coincide in the archive (300 s), which is why the fixture passed. 🤖 Written by an agent on behalf of @jcanton
|
I took the liberty of pushing ad84851 updating with the changes merged in #1466 and fixing lots of my own review comments (which I'll now mark as resolved) there is still the non-blocking question of whether we drop the dry static energy entirely for which I wanted an opinion from @OngChia as well, but as I wrote to @havogt we can remove it already, it's easy to bring it back if needed. |
Remove the dry-static-energy path (EnergyType keeps only INTERNAL, with a clear error for 1), take the experiment dates from EXCLAIM_APE_AES.dates, add TODOs for the energy-function naming and the energy exchange, and drop the tmx_ prefix from the tmx integration and unit test file names.
…-scalar-diffusion # Conflicts: # model/atmosphere/subgrid_scale_physics/tmx/src/icon4py/model/atmosphere/subgrid_scale_physics/tmx/config.py # model/atmosphere/subgrid_scale_physics/tmx/tests/tmx/fixtures.py # model/atmosphere/subgrid_scale_physics/tmx/tests/tmx/unit_tests/test_tmx_config.py # scripts/tests/python/test_fortran_config_converter.py
|
When developing, you can test your changes on CSCS CI before merge with the You can pass options to override pipeline variables, for example:
Avoid running the pipeline for all tests when you are developing. Available options are:
For each option, Multiple values can be given to each option with See The Merging Once your PR is approved and ready for merging, add it to the merge queue. The Optional Tests To run benchmarks you can use:
For more detailed information please look at CI in the EXCLAIM universe. |
|
cscs-ci run default;SESSIONS=model;MODEL_SUBSETS=stencils:datatest;MODEL_SUBPACKAGES=tmx:muphys;BACKENDS=gtfn_gpu:dace_gpu;LEVELS=unit:integration |
| grid=Grids.R02B04_GLOBAL, | ||
| version=8, | ||
| version=11, | ||
| dates=("2008-09-01T00:00:00.000", "2008-09-01T00:05:00.000", "2008-09-01T00:10:00.000"), |
There was a problem hiding this comment.
ok for now, but should definitely be extracted from the ser_data metadata, not hardcoded here
will unify all tests in one separate PR
Part of the tmx port. This PR adds the scalar diffusion of qv, qc and qi and of the energy/temperature, with its stage interface.
Changes
tmx/stencils/scalar_diffusion.py: four programs.assemble_scalar_diffusion_matrix: Add the tmx vertical diffusion operators and a common tridiagonal solver #1488's_assemble_vertical_diffusion_matrix_on_cellswith1 / air_mass, for the tracers. It is a separate program because the matrix is reused for qv, qc and qi.diffuse_tracer: the diffusion core_diffuse_scalarfor one tracer, then the update._diffuse_scalaris shared with the energy and does three things:_solve_implicit_vertical_diffusion_on_cells);compute_energy_from_temperature:_compute_internal_energy_from_temperature.diffuse_energy_and_update_temperature: does three things in one program:zfactor);_compute_surface_internal_energy_flux;_compute_temperature_from_internal_energy, using the new qv, qc and qi.The energy is always the internal energy. ICON's dry static energy option (
energy_type=1) is not ported: it has not been used since internal energy became ICON's default (icon-mpim MR !326, 2024).tmx/scalar_diffusion.py: theScalarDiffusioncomponent.Diagnosticsand hasrun_hydrometeor_diffusionandrun_temperature_diffusion.tmx/config.py:SolverTypehas onlyIMPLICITandEnergyTypeonlyINTERNAL. ICON's explicit solver was only used for early testing.TmxConfigrejectssolver_type=1andenergy_type=1with a clear error.scripts/python/fortran_config_converter.py) reads both as plain ints, so the same error reaches it instead of a bare enum conversion failure.Tendency outputs. The solve writes the tendency instead of accumulating onto it, so there is no per-step zero fill. Rows outside the computed domain (cells
NUDGING..LOCAL, full column) are not written and keep whatever the caller's buffer holds.States and test infrastructure:
tmx_states.py:TmxInputStategains the tracers andair_mass.TmxNewStateandTmxTendencyState.TmxSurfaceFluxStatehas only the two fluxes this PR reads.model/testing/.../serialbox.py: accessors for the tmx entry tracers andmair, the hydrometeor and temperature exit savepoints, and the surface-flux savepoint (this PR's fields only). Additive only; nothing existing changes.model/testing/.../definitions.py:ExperimentDescriptiongainsdates, set forEXCLAIM_APE_AES. The tmx datatests usedates[1:](the first step is the initialization call), and the muphys datatest usesdates.tmx_prefix, so the integration and unit test names match the stencil tests (test_diagnostics.py,test_scalar_diffusion.py,test_namelist_config.py,test_config.py).The energy/temperature conversions reuse what is already in
model/common. There are no changes to common or dycore code.