From 234a26a9cd5287289292e105ce3b3be5c0233c20 Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Tue, 21 Oct 2025 16:15:25 +0100 Subject: [PATCH 1/4] #868 add text describing nlevels and ndata --- doc/user_guide/lfric.rst | 55 ++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/doc/user_guide/lfric.rst b/doc/user_guide/lfric.rst index e449270675..85584d6f24 100644 --- a/doc/user_guide/lfric.rst +++ b/doc/user_guide/lfric.rst @@ -162,24 +162,30 @@ least rank (number of dimensions) one. Scalar arrays are identified with Field +++++ -LFRic API fields, identified with ``GH_FIELD`` metadata, represent -FEM discretisations of various dynamical core prognostic and diagnostic +LFRic API fields, identified with ``GH_FIELD`` metadata, represent FEM +discretisations of various dynamical core prognostic and diagnostic variables. In FEM, variables are discretised by placing them into a function space (see :ref:`lfric-function-space`) from which they inherit a polynomial expansion via the basis functions of that space. Field values at points within a cell are evaluated as the sum of a set -of basis functions multiplied by coefficients which are the data points. -Points of evaluation are determined by a quadrature object +of basis functions multiplied by coefficients which are the data +points. Points of evaluation are determined by a quadrature object (:ref:`lfric-quadrature`) and are independent of the function space -the field is on. Placement of field data points, also called degrees of -freedom (hereafter "DoFs"), is determined by the function space the field -is on. +the field is on. Placement of field data points, also called degrees +of freedom (hereafter "DoFs"), is determined by the function space the +field is on. An LFRic multi-data field can have more than one value +associated with each data point. + LFRic fields passed as arguments to any :ref:`LFRic kernel ` can be of ``real`` or ``integer`` primitive type. In the LFRic infrastructure, these fields are represented by instances of the ``field_type`` and ``integer_field_type`` classes, respectively. +Typically, a field will have the same number of vertical layers as the +model mesh. However, this is not a requirement and the number of layers +can be as few as one (a 2D field). + .. _lfric-field-vector: Field Vector @@ -919,8 +925,8 @@ All three CMA-related kernel types must obey the following rules: 1) Since a CMA operator only acts within a single column of data, stencil operations are not permitted. -2) No vector quantities (e.g. ``GH_FIELD*3`` - see below) are - permitted as arguments. +2) No vector quantities (e.g. ``GH_FIELD*3`` - see below) or + multi-data fields are permitted as arguments. 3) The kernel must operate on cell-columns. @@ -1718,7 +1724,6 @@ be found in ``examples/lfric/eg5``. Inter-Grid Metadata ___________________ - The alternative form of the optional fifth metadata argument for a field specifies which mesh the associated field is on. This is required for inter-grid kernels which perform prolongation or @@ -1748,6 +1753,36 @@ meshes cannot be on the same function space while those on the same mesh must also be on the same function space. +Number of Layers Metadata +------------------------- + +If a particular field argument to a kernel has a number of vertical levels +that is not the same as the extruded mesh then this must be specified using +the ``NLEVELS`` option to GH_FIELD, e.g.:: + + arg_type(GH_FIELD, GH_REAL, GH_READ, W3, NLEVELS=1) + +The value specified for ``NLEVELS`` may be a literal if it is known at +compile time. Alternatively, it may be given the special value +``GH_RUNTIME`` which means that the number of levels is to be determined +at runtime (in the generated PSy layer). + + +Multi-Data Metadata +------------------- + +A multi-data field is the same as a standard field apart from having multiple +values associated with each DoF. This is indicated in the field metadata by +the optional ``NDATA`` argument to GH_FIELD, e.g.:: + + arg_type(GH_FIELD, GH_REAL, GH_READ, W2, NDATA=4) + +The value specified for ``NDATA`` may be a literal if it is known at +compile time. Alternatively, it may be given the special value +``GH_RUNTIME`` which means that the number of data values at each DoF is to be +determined at runtime (in the generated PSy layer). + + Column-wise Operators (CMA) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 060a1ea9ace723971e86454bf4064a3679c630e0 Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Tue, 21 Oct 2025 17:10:12 +0100 Subject: [PATCH 2/4] #868 update the rules for kernel arguments --- doc/user_guide/lfric.rst | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/doc/user_guide/lfric.rst b/doc/user_guide/lfric.rst index 85584d6f24..ddef8e2cb8 100644 --- a/doc/user_guide/lfric.rst +++ b/doc/user_guide/lfric.rst @@ -1642,7 +1642,7 @@ to have stencil accesses, these two options are mutually exclusive. The metadata for each case is described in the following sections. Stencil Metadata -________________ +"""""""""""""""" Stencil metadata specifies that the corresponding field argument is accessed @@ -1722,7 +1722,7 @@ be found in ``examples/lfric/eg5``. .. _lfric-intergrid-mdata: Inter-Grid Metadata -___________________ +""""""""""""""""""" The alternative form of the optional fifth metadata argument for a field specifies which mesh the associated field is on. This is @@ -1754,7 +1754,7 @@ mesh must also be on the same function space. Number of Layers Metadata -------------------------- +""""""""""""""""""""""""" If a particular field argument to a kernel has a number of vertical levels that is not the same as the extruded mesh then this must be specified using @@ -1769,7 +1769,7 @@ at runtime (in the generated PSy layer). Multi-Data Metadata -------------------- +""""""""""""""""""" A multi-data field is the same as a standard field apart from having multiple values associated with each DoF. This is indicated in the field metadata by @@ -2115,7 +2115,12 @@ conventions, are: 4) If the field entry stencil access is of type ``XORY1D`` then add an additional ``integer`` direction argument of kind ``i_def`` and with intent ``in``. - + 5) If the field is multi-data then the kernel must be passed the + value of ``NDATA``: add an additional ``integer``, scalar + argument of kind ``i_def`` and intent ``in``. + 6) If the field has a custom number of vertical levels then pass this as + an additional ``integer``, scalar argument of kind ``i_def`` and + intent ``in``. 3) If the current entry is a field vector then for each dimension of the vector, include a field array. The field array name is specified as @@ -2141,21 +2146,26 @@ conventions, are: the data type and kind specifed in the metadata. The ScalarArray must be denoted with intent ``in`` to match its read-only nature. -4) For each function space in the order they appear in the metadata arguments - (the ``to`` function space of an operator is considered to be before the +4) DoF maps for function spaces are handled in the order they appear in the + metadata arguments (the ``to`` function space of an operator is considered + to be before the ``from`` function space of the same operator as it appears first in - lexicographic order) + lexicographic order). Note that if a field on a given function space has a + non-standard number of vertical levels, it requires that a dofmap be supplied + (because the number of vertical levels alters the *values* within the map). For + each required DoF map: 1) Include the number of local degrees of freedom (i.e. number per-cell) for the function space. This is an ``integer`` of kind ``i_def`` and has intent ``in``. The name of this argument is ``"ndf_"``. + 2) If there is a field on this space 1) Include the unique number of degrees of freedom for the function space. This is an ``integer`` of kind ``i_def`` and has intent ``in``. The name of this argument is ``"undf_"``. - 2) Include the **dofmap** for this function space. This is an ``integer`` + 2) Include the **dofmap** itself. This is an ``integer`` array of kind ``i_def`` with intent ``in``. It has one dimension sized by the local degrees of freedom for the function space. From 716c908dcea6cf35d153f1f19eb6d27d9eb37dad Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Wed, 22 Oct 2025 12:00:35 +0100 Subject: [PATCH 3/4] #868 change nlevels to nlayers --- doc/user_guide/lfric.rst | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/doc/user_guide/lfric.rst b/doc/user_guide/lfric.rst index ddef8e2cb8..5072894dd0 100644 --- a/doc/user_guide/lfric.rst +++ b/doc/user_guide/lfric.rst @@ -1758,14 +1758,18 @@ Number of Layers Metadata If a particular field argument to a kernel has a number of vertical levels that is not the same as the extruded mesh then this must be specified using -the ``NLEVELS`` option to GH_FIELD, e.g.:: +the ``NLAYERS`` option to ``GH_FIELD``, e.g.:: - arg_type(GH_FIELD, GH_REAL, GH_READ, W3, NLEVELS=1) + arg_type(GH_FIELD, GH_REAL, GH_READ, W3, NLAYERS=1) -The value specified for ``NLEVELS`` may be a literal if it is known at +The value specified for ``NLAYERS`` may be a literal if it is known at compile time. Alternatively, it may be given the special value -``GH_RUNTIME`` which means that the number of levels is to be determined -at runtime (in the generated PSy layer). +``GH_RUNTIME`` which means that the number of levels is to be +determined at runtime by querying the field object (in the generated +PSy layer). If two different field arguments are on the same function +space but both have ``NLAYERS=GH_RUNTIME`` then it is assumed that +they may have *different* values of ``NLAYERS`` and hence a separate +dofmap is passed to the kernel for each. Multi-Data Metadata @@ -1779,8 +1783,9 @@ the optional ``NDATA`` argument to GH_FIELD, e.g.:: The value specified for ``NDATA`` may be a literal if it is known at compile time. Alternatively, it may be given the special value -``GH_RUNTIME`` which means that the number of data values at each DoF is to be -determined at runtime (in the generated PSy layer). +``GH_RUNTIME`` which means that the number of data values at each DoF +is to be determined at runtime by querying the field object (in the +generated PSy layer). Column-wise Operators (CMA) @@ -2488,8 +2493,9 @@ dofmap for both the to- and from-function spaces of the CMA operator. Since it does not have any LMA operator arguments it does not require the ``ncell_3d`` and ``nlayers`` scalar arguments. (Since a column-wise operator is, by definition, assembled for a whole column, -there is no loop over levels when applying it.) -The full set of rules is then: +there is no loop over levels when applying it.) Note that fields with +non-standard ``nlayers`` or ``ndata > 1`` cannot be supplied as +arguments to CMA kernels. The full set of rules is: 1) Include the ``cell`` argument. ``cell`` is an ``integer`` of kind ``i_def`` and has intent ``in``. From e878688566a1be274eb7709ad0630da832b2fa3f Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Wed, 5 Nov 2025 13:18:59 +0000 Subject: [PATCH 4/4] #868 extend docs to allow for naming of nlayers values --- doc/user_guide/lfric.rst | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/doc/user_guide/lfric.rst b/doc/user_guide/lfric.rst index 5072894dd0..4f04456a63 100644 --- a/doc/user_guide/lfric.rst +++ b/doc/user_guide/lfric.rst @@ -1763,13 +1763,17 @@ the ``NLAYERS`` option to ``GH_FIELD``, e.g.:: arg_type(GH_FIELD, GH_REAL, GH_READ, W3, NLAYERS=1) The value specified for ``NLAYERS`` may be a literal if it is known at -compile time. Alternatively, it may be given the special value -``GH_RUNTIME`` which means that the number of levels is to be +compile time. Alternatively, it may be given a named value (one of +``GH_NLAYERSM1`` TODO) or the special value +``GH_RUNTIME``. A named value means that the number of levels is to be determined at runtime by querying the field object (in the generated PSy layer). If two different field arguments are on the same function space but both have ``NLAYERS=GH_RUNTIME`` then it is assumed that they may have *different* values of ``NLAYERS`` and hence a separate -dofmap is passed to the kernel for each. +dofmap is passed to the kernel for each. However, if two or more field +arguments are on the same function space and have the same, named number +of layers which is not ``GH_RUNTIME`` then only one dofmap is passed to +the kernel for those arguments. Multi-Data Metadata @@ -2155,10 +2159,10 @@ conventions, are: metadata arguments (the ``to`` function space of an operator is considered to be before the ``from`` function space of the same operator as it appears first in - lexicographic order). Note that if a field on a given function space has a - non-standard number of vertical levels, it requires that a dofmap be supplied - (because the number of vertical levels alters the *values* within the map). For - each required DoF map: + lexicographic order). Note that if two fields on a given function space have + differing numbers of vertical layers, then each requires that a + dofmap be supplied (because the number of vertical layers alters the + *values* within the map). For each required DoF map: 1) Include the number of local degrees of freedom (i.e. number per-cell) for the function space. This is an ``integer`` of kind ``i_def`` and