Skip to content

Add the tmx package, its configuration and static states - #1457

Open
havogt wants to merge 15 commits into
mainfrom
tmx-package-setup
Open

Add the tmx package, its configuration and static states#1457
havogt wants to merge 15 commits into
mainfrom
tmx-package-setup

Conversation

@havogt

@havogt havogt commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

The tmx port (#1359, @jcanton) is ~16k lines across 155 files. This is the first of a series carving it into independently reviewable pieces: the package plus everything that needs no operators. Each later PR adds one subcomponent with its own datatest (diagnostics, scalar and momentum diffusion, energy update). Prescribed surface fluxes, including their configuration options, are in #1458, stacked on this one.

What is here

  • The package: pyproject.toml, README, workspace member, tach module (depends on common only), nox session, CI matrix entry.
  • TmxConfig and its enums, in tmx/config.py, so that reading the configuration does not import every stencil package the granule does.
  • Static states: TmxMetricState and TmxInterpolationState.
  • Metrics factory additions the states need: wgtfacq1_c/e, the inverse layer thicknesses (cells on half levels, edges on full levels), geopotential and height above ground — each with a savepoint test in test_metrics_factory.py.
  • Quadratic extrapolation weights in gt4py: wgtfacq_c/e and the new wgtfacq1_c/e replace the numpy implementations.
  • One savepoint (tmx_init) and the test-data version bump.
  • unnamed_index in the common config options (positional derived-type namelists), with its tests in common.
  • ISO-8601 duration parsing moved to common/utils/time_utils.py; the driver had its own copy.
  • get_grid_geometry keys its cache on the number of levels as well, since two experiments share the R02B04 grid file.

Not here

The states that flow between subcomponents (TmxInputState, TmxDiagnosticState, …) and everything with its first consumer in a later PR arrive with that PR.

Differences from #1359

Testing

gtfn_cpu, -n0. The embedded backend is not evidence here: several of these tests are xfail on it.

suite result
test_metrics_factory.py 85 passed
height above ground + geopotential, after the reference change 2 passed
weight factors, common math, common utils 45 passed
tmx, driver unit tests 42 passed
pre-commit pass

🤖 Generated with Claude Code

https://claude.ai/code/session_01QVSWPQauF9gNjADtuSTjxF

havogt and others added 2 commits September 3, 2026 19:03
…ates

First of a series carving the tmx port (#1359, author @jcanton) into
independently reviewable pieces. This one stands the package up and brings
the parts that need no operators, so the later PRs are one subcomponent each.

Package: workspace member, tach module (depends on common only), nox and CI
matrix entries. The uv.lock is hand-edited rather than regenerated, because
a newer uv reformats the whole file; `uv lock --check` accepts it.

TmxConfig lives in its own module: the granule imports every stencil at module
level, so reading a config would otherwise pull them all in. Verified that
importing it loads no stencil module.

Only the static states are here. The diagnostic, tendency, new and input
states are the subject of an ongoing design discussion and arrive with the
subcomponents that use them.

Half-level fields are typed on KHalfDim, dropping the port's workaround that
re-tagged them back to KDim. That needed three additions in common:
compute_reciprocal_on_cell_khalf, a program wrapping the existing
_cell_2_edge_interpolation_on_half_levels, and the field operators behind
them. test_static_fields validates the result against the serialized
reference and needs a compiled backend; it is xfail on embedded.

Also from the port, each with a consumer here: the metrics factory fields tmx
needs, positional derived-type namelist support in the common config options,
and three savepoints.

Co-authored-by: Jacopo Canton <jacopo.canton@mpimet.mpg.de>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QVSWPQauF9gNjADtuSTjxF
Seven accessors described half-level quantities but read them as full-level
fields: the three inverse half-level thicknesses, the geopotential above
ground, the Smagorinsky mixing length, the vertical wind and the interface
pressure. #1359 wrote them before #1429 made half levels their own dimension,
and they came over unexamined.

test_static_fields did not catch it because it compares values rather than
dimensions. It surfaces as soon as one of these fields is passed to a program,
since a program argument carries its grid.

Found while building the diagnostics component on top of this branch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QVSWPQauF9gNjADtuSTjxF
Comment thread model/common/src/icon4py/model/common/metrics/compute_weight_factors.py Outdated
Comment thread model/common/src/icon4py/model/common/metrics/compute_weight_factors.py Outdated
Comment thread model/common/src/icon4py/model/common/metrics/compute_weight_factors.py Outdated
Comment thread model/common/src/icon4py/model/common/math/operators.py Outdated
Comment thread model/common/src/icon4py/model/common/config/options.py
havogt and others added 4 commits September 4, 2026 08:32
Two review items from #1457.

TmxConfig._validate existed only to be called by __post_init__, which is
where validation belongs; it is now inline.

The comment explaining the uses_concat_where marker sat above the marker and
read as detached from it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QVSWPQauF9gNjADtuSTjxF
Replaces the four numpy quadratic-extrapolation weight functions with gt4py,
as asked on #1457.

The three coefficients are the same expression of four interface heights, so
one operator computes them and each level selects its own; because all three
levels read the same four heights, the shift differs per level: from full
level k, interface j is at KDim + (j - k) - 0.5. Verified bit-for-bit against
the numpy formula on embedded and gtfn_cpu before wiring it in.

The two edge variants need no code of their own. They are a cell-to-edge
interpolation of the cell weights, so they reuse the operator already in
common, and the halo exchange moves from inside the function to the factory
entry that owns it -- the second review point on the same file.

This needed one thing from the factory. A vertical sub-range in a provider's
compute domain is ambiguous: either the field spans the column and only part
of it is computed, as for rayleigh_w and coeff_dwdz, or the field exists on
those levels alone, as here. ProgramFieldProvider now takes
vertically_bounded_by_domain to say which, defaulting to the former, so these
weights stay three-row fields carrying their absolute level indices.

Co-authored-by: Jacopo Canton <jacopo.canton@mpimet.mpg.de>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QVSWPQauF9gNjADtuSTjxF
Everything here lives on the surface, one horizontal layer, so it is an
ordinary CellDim stencil. The surface pressure is the bottom interface row of
pressure_ifc, taken as a view of the live buffer rather than copied, so the
provider still reads whatever the caller updated this step.

sat_pres_water and specific_humidity gain field operators beside their numpy
versions, and PhysicsConstants gains the four values they reference: gtfn
needs constants used inside an operator to come from the wpfloat enum.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QVSWPQauF9gNjADtuSTjxF
The flux providers have no caller here -- only their own test -- which is
what the review pointed out. They belong with the component that consumes
them, so they move to their own PR: the providers, the surface-flux state and
its savepoint, the test, and the two thermodynamic field operators with the
four constants that nothing else uses.

The state-allocation test case goes with the state; it had no other state
left to exercise.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QVSWPQauF9gNjADtuSTjxF
The metric and interpolation fields tmx uses are registered in the common
factories, so their comparison against the savepoints belongs next to the
providers. The nine interpolation fields were already covered there by
test_interpolation_factory; the metric fields this branch adds had no test
in test_metrics_factory at all.

- test_metrics_factory: cover inv_ddqz_z_half, inv_ddqz_z_full_e,
  inv_ddqz_z_half_e, inv_ddqz_z_half_v, wgtfacq1_c, wgtfacq1_e,
  geopot_agl_ifc and height_above_ground. The first six are pinned to the
  AES physics experiment, whose 'tmx-init' savepoint holds the only
  serialized reference; height_above_ground is checked against
  'z_mc - z_ifc[:, -1:]' taken from the savepoints, not against the
  function under test.
- grid_utils: key the cached grid geometry on the number of levels too.
  The two aquaplanet experiments share the R02B04 grid file, so without it
  the first one to run fixes num_levels for the other.
- tmx: replace the static-fields datatest with a unit test of the
  'from_sources' wiring, which needs no serialized data. Its savepoint
  helpers move to the component PR that still uses them.
- tmx: drop test_default_config_matches_fortran_defaults. It asserted the
  dataclass defaults against literals copied from that dataclass;
  test_tmx_namelist_config checks them against what ICON's
  vdiff_config_init echoes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QVSWPQauF9gNjADtuSTjxF

@OngChia OngChia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am still thinking about the bunch of tests of tmx config. No clue yet. Could @DropD have a look at those config things?

Comment thread model/atmosphere/subgrid_scale_physics/tmx/tests/tmx/fixtures.py Outdated
Comment thread model/common/src/icon4py/model/common/metrics/metric_fields.py Outdated
Comment thread model/common/src/icon4py/model/common/metrics/metric_fields.py Outdated
self._do_exchange = do_exchange

def _field_extent(self, dim: gtx.Dimension, grid: GridProvider) -> tuple[int, int]:
"""The extent to allocate for ``dim``.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not know this.
So, just to confirm, we will create CellKField fields such as the quadratic extrapolation coefficients wgtfacq_c or wgtfacq1_c with only three levels in the vertical coordinate.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was extracted into #1463

Comment thread model/testing/src/icon4py/model/testing/serialbox.py Outdated
z_ifc(dims.KDim + 0.5),
z_ifc(dims.KDim + 1.5),
)
_, _, w3 = _quadratic_extrapolation_weights(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workaround of cyclic permutation of vertical levels to compute simple quadratic extrapolation weights seems not very ideal and hard to swallow. I guess this is because of gt4py limitations.

Comment thread model/common/src/icon4py/model/common/metrics/compute_weight_factors.py Outdated
- tmx_states, metric_fields: the docstring wordings he suggested, taken as
  proposed.
- compute_weight_factors: drop `_compute_z1_z2_z3`, left behind by the gt4py
  conversion and called from nowhere.
- serialbox: drop the `ta_phy` accessor. Nothing reads it, and the name is a
  trap: in ICON `ta_phy` is a member of the tendency list (mo_aes_phy_memory.f90
  l.544, [K/s]), but the field serialized under that name in 'tmx-entry' is
  bit-identical to `ta`.
- the ISO 8601 duration parser moves to common/utils/time_utils.py, with its
  unit tests; the driver and the tmx fixtures each had a copy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QVSWPQauF9gNjADtuSTjxF
havogt added a commit that referenced this pull request Sep 9, 2026
…mbers (#1462)

`EdgeParams` is a hand-written class whose attribute annotations do not
say which members a construction path may leave unset.

## What changes

- `EdgeParams` becomes dataclass.
- `| None` now means "some source cannot supply this"
- `edge_cell_distances` is new, from `t_grid_edges%edge_cell_length`.
**It's not needed required by dycore/diffusion, therefore not passed in
via Fortran bindings and we make it optional in this PR**. Alternative
could be to still pass it from Fortran, but since the Fortran array has
wrong layout it would require a copy.

## Why now

In #1457 it was originally added to tmx directly instead of EdgeParams,
therefore we extracted this refactoring in preparation for that PR.
havogt and others added 4 commits September 9, 2026 18:17
`grid_states.EdgeParams` carries it as `edge_cell_distances` since #1462, so
the granule's metric state no longer has to. `from_sources` needs only the
metrics source now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QVSWPQauF9gNjADtuSTjxF
The four interface heights are the same for all three coefficients; only their
address relative to the level being written changes. Selecting them with
concat_where evaluates the extrapolation once instead of three times with two
of every three results discarded.

Out-of-range shifts stay out of range only because concat_where restricts each
branch to its own region, as before — the reads just moved from the outputs to
the inputs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QVSWPQauF9gNjADtuSTjxF
Brings in #1463, which makes a ProgramFieldProvider's declared vertical range
the field's extent for every provider. That supersedes this branch's opt-in
`vertically_bounded_by_domain`:

- states/factory.py: main's version; this branch's changes there were the flag
  and nothing else.
- metrics_factory.py: this branch's version with #1463's rayleigh_w and
  coeff_dwdz domain fixes applied, the four `vertically_bounded_by_domain=True`
  dropped, and geopot_agl_ifc's `gtx.domain(...)` replaced by the bare
  dimensions, which NumpyDataProvider no longer accepts. Main's numpy
  wgtfacq_c/wgtfacq_e providers stay replaced by this branch's gt4py ones.

Also fixes the "acurate" typo in the coeff_dwdz docstring that #1463 carried.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QVSWPQauF9gNjADtuSTjxF
@havogt
havogt marked this pull request as ready for review September 11, 2026 11:37
havogt and others added 3 commits September 11, 2026 13:50
- test_tmx_states.py and `from_sources` go: the tests restated the mapping and
  checked common's metadata registry, and nothing calls `from_sources` yet.
- `_DiffusedTracer` leaves config.py: it is runtime data, used by the scalar
  diffusion, not configuration.
- `unnamed_index` gets its own tests in common's test_options.py; it was only
  exercised through TmxConfig.
- The tmx-entry savepoint, `mix_len_sq`, `scaling_factor_louis`, the
  `tmx_dtime` fixture and the unused datatest fixture re-exports move to the
  diagnostics PR; the surface-flux options (read from nh_testcase_nml) move to
  #1458 with their only consumer.
- `compute_geopot_agl_ifc` is named after the operation:
  `compute_geopotential_above_ground_on_half_levels`.
- test_package.py goes; no peer package has one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QVSWPQauF9gNjADtuSTjxF
- tmx: add the README the package metadata declares; drop the unused logging
  in config.py, the dead `z_mc`/`z_ifc` state members, and the stencil fixture
  re-exports no test here uses.
- common: the new inverse operators move next to `compute_inverse_on_edges` in
  math/utils.py as `compute_inverse_on_cell_khalf`/`_edge_k`, with the same
  zero guard, instead of a second "reciprocal" family in another module.
- The edge/vertex inverse half-level fields leave with their only consumer, the
  diffusion: attributes, providers, `cell_2_edge_interpolation_on_half_levels`,
  their factory test, savepoint accessors and state members.
- test_compute_wgtfacq_e_dsl goes: it ran cell_2_edge_interpolation only and
  duplicated test_factory_wgtfacq_e. The `relativetime_from_iso8601` re-export
  in common.utils had no user.
- Renames: `_compute_quadratic_extrapolation_weights`, `compute_wgtfacq_c`
  (the `_dsl` suffix was the numpy version's), and one
  `compute_height_above_surface` helper, with the geopotential as GRAV times it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QVSWPQauF9gNjADtuSTjxF
The reference was the formula under test applied to the savepoint's z_mc and
z_ifc, so only the provider wiring was checked. It now comes from ICON's
serialized geopot_agl_ifc, averaged onto full levels and divided by GRAV,
which is independent of our formula: taking the surface from the top row
instead of the bottom fails it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QVSWPQauF9gNjADtuSTjxF
@github-actions

Copy link
Copy Markdown

When developing, you can test your changes on CSCS CI before merge with the default pipeline: cscs-ci run default. This will run a default subset of tests.

You can pass options to override pipeline variables, for example:

  • cscs-ci run default;BACKENDS=gtfn_cpu;LEVELS=unit
  • cscs-ci run default;MODEL_SUBPACKAGES=common:driver;SESSIONS=model

Avoid running the pipeline for all tests when you are developing.

Available options are:

  • SESSIONS: model, model_mpi, or tools (correspond to nox sessions)
  • MODEL_SUBSETS: datatest, basic, or stencils (correspond to nox session selections)
  • MODEL_SUBPACKAGES: subpackages for non-MPI tests (last component, e.g. diffusion, driver)
  • MODEL_MPI_SUBPACKAGES: subpackages for MPI tests (as above)
  • BACKENDS: backends
  • GRIDS: grids for stencil tests (simple, icon_regional, or icon_global)
  • LEVELS: testing level for non-stencil tests (unit or integration)

For each option, all can be used as a shorthand for all possible values of that variable, e.g. LEVELS=all.

Multiple values can be given to each option with : used as the separator (; separates options and , separates pipelines).

See scripts/python/generate_ci_pipeline.py and noxfile.py for available values for each option.

The all pipeline can be run with cscs-ci run all. This will run all icon4py tests in CSCS CI which can be expensive. This pipeline runs on a schedule on main, and can be run when extensive validation is needed (e.g. before releases).

Merging

Once your PR is approved and ready for merging, add it to the merge queue. The merge CSCS CI pipeline will run automatically on the merge-queue branch and must pass before the PR is merged. A dummy merge check will be triggered on the PR itself since it's required to add a PR to the merge queue.

Optional Tests

To run benchmarks you can use:

  • cscs-ci run benchmark-bencher

For more detailed information please look at CI in the EXCLAIM universe.

@yiluchen1066 yiluchen1066 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! I did not find something need to be changed urgently. Mostly minor things. We can merge this one pretty soon!

"""
Type of the vertical diffusion solver.

Note: Called ``solver_type`` in ``mo_turb_vdiff_config.f90``.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Note: Called ``solver_type`` in ``mo_turb_vdiff_config.f90``.

No need to keep this, also for the rest of the codes.



@config_io.register_enum
class TurbulenceSolverType(int, enum.Enum):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shall we rename this to TmxSolverType?

Comment on lines +226 to +235
"""
Construct the configuration from the echoed ICON namelist.

``aes_vdf_nml`` is a derived-type namelist (``t_vdiff_config``), which
ICON echoes as an anonymous positional array of the member values in
declaration order, so the options are located by ``unnamed_index``
(pinned to mo_turb_vdiff_config.f90) instead of by name. Only the
first domain is read. The guards below make a change of the Fortran
type fail loudly instead of silently mis-assigning values.
"""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""
Construct the configuration from the echoed ICON namelist.
``aes_vdf_nml`` is a derived-type namelist (``t_vdiff_config``), which
ICON echoes as an anonymous positional array of the member values in
declaration order, so the options are located by ``unnamed_index``
(pinned to mo_turb_vdiff_config.f90) instead of by name. Only the
first domain is read. The guards below make a change of the Fortran
type fail loudly instead of silently mis-assigning values.
"""
"""
Build the configuration from the echoed ICON namelist.
ICON writes ```aes_vdf_config``` values in Fortran member order, without names.
We read the first domain using each options's ```unnamed_index```. The checks below
help detect changes to the expected Fortran layout
"""

let's simplify the doc string a bit.

Comment on lines +236 to +242
# number of members of the Fortran t_vdiff_config derived type
# (mo_turb_vdiff_config.f90); the echoed aes_vdf_nml namelist holds this
# many values per domain, in declaration order. Must be kept in sync with
# the 'unnamed_index' positions of the options above.
num_members = 42
# position of 'use_tmx' in t_vdiff_config, used as an order canary
use_tmx_index = 22

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# number of members of the Fortran t_vdiff_config derived type
# (mo_turb_vdiff_config.f90); the echoed aes_vdf_nml namelist holds this
# many values per domain, in declaration order. Must be kept in sync with
# the 'unnamed_index' positions of the options above.
num_members = 42
# position of 'use_tmx' in t_vdiff_config, used as an order canary
use_tmx_index = 22
# Layout of t_vdiff_config in mo_turb_vdiff_config.f90
# Keep these values and the options' unnamed_index positions in sync
num_members = 42
use_tmx_index = 22

Comment on lines 255 to 258
return config_cls(
**dict(iter_pairs_from_icon(config_cls, icon_config)),
**overrides,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was testing GPT-6 Astra, and it caught this here:

Suggested change
values = dict(iter_pairs_from_icon(config_cls, icon_config))
values.update(overrides)
return config_cls(**values)

Both dictionaries can contain km_const which caused the error


@pytest.mark.datatest
def test_compute_wgtfacq_c_dsl(
def test_compute_wgtfacq_c(

@yiluchen1066 yiluchen1066 Sep 11, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def test_compute_wgtfacq_c(
@pytest.mark.datatest
@pytest.mark.uses_concat_where
def test_compute_wgtfacq_c(

Comment on lines +1992 to +2003
def wgtfacq1_c(self):
# Top-extrapolation coefficients: unlike `wgtfacq_c` (bottom extrapolation, stored
# surface-first, i.e. reversed w.r.t. increasing k, hence flipped in its accessor),
# `wgtfacq1_c(jc,k,jb)` with k=1..3 multiplies the full level k counted from the model
# top (mo_vertical_grid.f90 ll. 955-968), which already matches icon4py's top-down KDim
# orientation. No flip needed.
return self._get_field("wgtfacq1_c", dims.CellDim, dims.KDim)

def wgtfacq1_e(self):
# No flip, see `wgtfacq1_c`. Usage in mo_vdf_atmo.f90 (interpolate_normal_velocity_
# edge_interface, ll. 1247-1250): vn_ie(je,1,jb) = sum_k wgtfacq1_e(je,k,jb)*vn(je,k,jb).
return self._get_field("wgtfacq1_e", dims.EdgeDim, dims.KDim)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def wgtfacq1_c(self):
# Top-extrapolation coefficients: unlike `wgtfacq_c` (bottom extrapolation, stored
# surface-first, i.e. reversed w.r.t. increasing k, hence flipped in its accessor),
# `wgtfacq1_c(jc,k,jb)` with k=1..3 multiplies the full level k counted from the model
# top (mo_vertical_grid.f90 ll. 955-968), which already matches icon4py's top-down KDim
# orientation. No flip needed.
return self._get_field("wgtfacq1_c", dims.CellDim, dims.KDim)
def wgtfacq1_e(self):
# No flip, see `wgtfacq1_c`. Usage in mo_vdf_atmo.f90 (interpolate_normal_velocity_
# edge_interface, ll. 1247-1250): vn_ie(je,1,jb) = sum_k wgtfacq1_e(je,k,jb)*vn(je,k,jb).
return self._get_field("wgtfacq1_e", dims.EdgeDim, dims.KDim)
def wgtfacq1_c(self):
return self._get_field("wgtfacq1_c", dims.CellDim, dims.KDim)
def wgtfacq1_e(self):
return self._get_field("wgtfacq1_e", dims.EdgeDim, dims.KDim)

let's remove the docs here

)


def load_fortran_dict(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shall we move this to model/testing/datatest_utils since it uses the helper function get_path_for_experiment and potentially other components would also need this helper

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants