Reference Guide  2.5.0
psyclone.dynamo0p3.DynBasisFunctions Class Reference
Inheritance diagram for psyclone.dynamo0p3.DynBasisFunctions:
Collaboration diagram for psyclone.dynamo0p3.DynBasisFunctions:

Public Member Functions

def __init__ (self, node)
 
def initialise (self, parent)
 
def deallocate (self, parent)
 
- Public Member Functions inherited from psyclone.domain.lfric.lfric_collection.LFRicCollection
def declarations (self, parent)
 

Static Public Member Functions

def basis_first_dim_name (function_space)
 
def basis_first_dim_value (function_space)
 
def diff_basis_first_dim_name (function_space)
 
def diff_basis_first_dim_value (function_space)
 

Static Public Attributes

dictionary qr_dim_vars
 
dictionary qr_weight_vars
 

Detailed Description

 Holds all information on the basis and differential basis
functions required by an invoke or kernel call. This covers both those
required for quadrature and for evaluators.

:param node: either the schedule of an Invoke or a single Kernel object
             for which to extract information on all required
             basis/diff-basis functions.
:type node: :py:class:`psyclone.domain.lfric.LFRicInvokeSchedule` or
            :py:class:`psyclone.domain.lfric.LFRicKern`

:raises InternalError: if a call has an unrecognised evaluator shape.

Definition at line 2627 of file dynamo0p3.py.

Member Function Documentation

◆ basis_first_dim_name()

def psyclone.dynamo0p3.DynBasisFunctions.basis_first_dim_name (   function_space)
static
Get the name of the variable holding the first dimension of a
basis function

:param function_space: the function space the basis function is for
:type function_space: :py:class:`psyclone.domain.lfric.FunctionSpace`
:return: a Fortran variable name
:rtype: str

Definition at line 2712 of file dynamo0p3.py.

2712  def basis_first_dim_name(function_space):
2713  '''
2714  Get the name of the variable holding the first dimension of a
2715  basis function
2716 
2717  :param function_space: the function space the basis function is for
2718  :type function_space: :py:class:`psyclone.domain.lfric.FunctionSpace`
2719  :return: a Fortran variable name
2720  :rtype: str
2721 
2722  '''
2723  return "dim_" + function_space.mangled_name
2724 
Here is the caller graph for this function:

◆ basis_first_dim_value()

def psyclone.dynamo0p3.DynBasisFunctions.basis_first_dim_value (   function_space)
static
Get the size of the first dimension of a basis function.

:param function_space: the function space the basis function is for
:type function_space: :py:class:`psyclone.domain.lfric.FunctionSpace`
:return: an integer length.
:rtype: string

:raises GenerationError: if an unsupported function space is supplied \
                         (e.g. ANY_SPACE_*, ANY_DISCONTINUOUS_SPACE_*)

Definition at line 2726 of file dynamo0p3.py.

2726  def basis_first_dim_value(function_space):
2727  '''
2728  Get the size of the first dimension of a basis function.
2729 
2730  :param function_space: the function space the basis function is for
2731  :type function_space: :py:class:`psyclone.domain.lfric.FunctionSpace`
2732  :return: an integer length.
2733  :rtype: string
2734 
2735  :raises GenerationError: if an unsupported function space is supplied \
2736  (e.g. ANY_SPACE_*, ANY_DISCONTINUOUS_SPACE_*)
2737  '''
2738  if function_space.has_scalar_basis:
2739  first_dim = "1"
2740  elif function_space.has_vector_basis:
2741  first_dim = "3"
2742  else:
2743  # It is not possible to determine explicitly the first basis
2744  # function array dimension from the metadata for any_space or
2745  # any_discontinuous_space. This information needs to be passed
2746  # from the PSy layer to the kernels (see issue #461).
2747  const = LFRicConstants()
2748  raise GenerationError(
2749  f"Unsupported space for basis function, "
2750  f"expecting one of {const.VALID_FUNCTION_SPACES} but found "
2751  f"'{function_space.orig_name}'")
2752  return first_dim
2753 
Here is the caller graph for this function:

◆ deallocate()

def psyclone.dynamo0p3.DynBasisFunctions.deallocate (   self,
  parent 
)
Add code to deallocate all basis/diff-basis function arrays

:param parent: node in the f2pygen AST to which the deallocate \
               calls will be added.
:type parent: :py:class:`psyclone.f2pygen.SubroutineGen`

:raises InternalError: if an unrecognised type of basis function \
                       is encountered.

Definition at line 3485 of file dynamo0p3.py.

3485  def deallocate(self, parent):
3486  '''
3487  Add code to deallocate all basis/diff-basis function arrays
3488 
3489  :param parent: node in the f2pygen AST to which the deallocate \
3490  calls will be added.
3491  :type parent: :py:class:`psyclone.f2pygen.SubroutineGen`
3492 
3493  :raises InternalError: if an unrecognised type of basis function \
3494  is encountered.
3495  '''
3496  if self._basis_fns:
3497  # deallocate all allocated basis function arrays
3498  parent.add(CommentGen(parent, ""))
3499  parent.add(CommentGen(parent, " Deallocate basis arrays"))
3500  parent.add(CommentGen(parent, ""))
3501 
3502  func_space_var_names = set()
3503  for basis_fn in self._basis_fns:
3504  # add the basis array name to the list to use later
3505  if basis_fn["type"] == "basis":
3506  basis_name = "gh_basis"
3507  elif basis_fn["type"] == "diff-basis":
3508  basis_name = "gh_diff_basis"
3509  else:
3510  raise InternalError(
3511  f"Unrecognised type of basis function: "
3512  f"'{basis_fn['''type''']}'. Should be one of 'basis' or "
3513  f"'diff-basis'.")
3514  for fspace in basis_fn["nodal_fspaces"]:
3515  op_name = basis_fn["fspace"].\
3516  get_operator_name(basis_name,
3517  qr_var=basis_fn["qr_var"],
3518  on_space=fspace)
3519  func_space_var_names.add(op_name)
3520 
3521  if func_space_var_names:
3522  # add the required deallocate call
3523  parent.add(DeallocateGen(parent, sorted(func_space_var_names)))
3524 
3525 

References psyclone.dynamo0p3.DynBasisFunctions._basis_fns.

◆ diff_basis_first_dim_name()

def psyclone.dynamo0p3.DynBasisFunctions.diff_basis_first_dim_name (   function_space)
static
Get the name of the variable holding the first dimension of a
differential basis function.

:param function_space: the function space the diff-basis function \
                       is for.
:type function_space: :py:class:`psyclone.domain.lfric.FunctionSpace`
:return: a Fortran variable name.
:rtype: str

Definition at line 2755 of file dynamo0p3.py.

2755  def diff_basis_first_dim_name(function_space):
2756  '''
2757  Get the name of the variable holding the first dimension of a
2758  differential basis function.
2759 
2760  :param function_space: the function space the diff-basis function \
2761  is for.
2762  :type function_space: :py:class:`psyclone.domain.lfric.FunctionSpace`
2763  :return: a Fortran variable name.
2764  :rtype: str
2765 
2766  '''
2767  return "diff_dim_" + function_space.mangled_name
2768 
Here is the caller graph for this function:

◆ diff_basis_first_dim_value()

def psyclone.dynamo0p3.DynBasisFunctions.diff_basis_first_dim_value (   function_space)
static
Get the size of the first dimension of an array for a
differential basis function.

:param function_space: the function space the diff-basis function \
                       is for.
:type function_space: :py:class:`psyclone.domain.lfric.FunctionSpace`
:return: an integer length.
:rtype: str

:raises GenerationError: if an unsupported function space is \
                         supplied (e.g. ANY_SPACE_*, \
                         ANY_DISCONTINUOUS_SPACE_*)

Definition at line 2770 of file dynamo0p3.py.

2770  def diff_basis_first_dim_value(function_space):
2771  '''
2772  Get the size of the first dimension of an array for a
2773  differential basis function.
2774 
2775  :param function_space: the function space the diff-basis function \
2776  is for.
2777  :type function_space: :py:class:`psyclone.domain.lfric.FunctionSpace`
2778  :return: an integer length.
2779  :rtype: str
2780 
2781  :raises GenerationError: if an unsupported function space is \
2782  supplied (e.g. ANY_SPACE_*, \
2783  ANY_DISCONTINUOUS_SPACE_*)
2784 
2785  '''
2786  if function_space.has_scalar_diff_basis:
2787  first_dim = "1"
2788  elif function_space.has_vector_diff_basis:
2789  first_dim = "3"
2790  else:
2791  # It is not possible to determine explicitly the first
2792  # differential basis function array dimension from the metadata
2793  # for any_space or any_discontinuous_space. This information
2794  # needs to be passed from the PSy layer to the kernels
2795  # (see issue #461).
2796  const = LFRicConstants()
2797  raise GenerationError(
2798  f"Unsupported space for differential basis function, "
2799  f"expecting one of {const.VALID_FUNCTION_SPACES} but found "
2800  f"'{function_space.orig_name}'")
2801  return first_dim
2802 

References psyclone.dynamo0p3.DynBasisFunctions._basis_fn_declns(), psyclone.dynamo0p3.DynBasisFunctions._basis_fns, psyclone.domain.lfric.lfric_kern.LFRicKern._eval_targets, psyclone.domain.lfric.lfric_kern_metadata.LFRicKernMetadata._eval_targets, psyclone.dynamo0p3.DynBasisFunctions._eval_targets, psyclone.dynamo0p3.DynBasisFunctions._qr_vars, psyclone.domain.lfric.lfric_collection.LFRicCollection._symbol_table, psyclone.dynamo0p3.DynMeshes._symbol_table, psyclone.dynamo0p3.HaloDepth._symbol_table, psyclone.psyGen.HaloExchange._symbol_table, psyclone.psyir.backend.sympy_writer.SymPyWriter._symbol_table, and psyclone.psyir.nodes.scoping_node.ScopingNode._symbol_table.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ initialise()

def psyclone.dynamo0p3.DynBasisFunctions.initialise (   self,
  parent 
)
Create the declarations and assignments required for the
basis-functions required by an invoke. These are added as children
of the supplied parent node in the AST.

:param parent: the node in the f2pygen AST that will be the
               parent of all of the declarations and assignments.
:type parent: :py:class:`psyclone.f2pygen.SubroutineGen`

:raises InternalError: if an invalid entry is encountered in the \
                       self._basis_fns list.

Reimplemented from psyclone.domain.lfric.lfric_collection.LFRicCollection.

Definition at line 2973 of file dynamo0p3.py.

2973  def initialise(self, parent):
2974  '''
2975  Create the declarations and assignments required for the
2976  basis-functions required by an invoke. These are added as children
2977  of the supplied parent node in the AST.
2978 
2979  :param parent: the node in the f2pygen AST that will be the
2980  parent of all of the declarations and assignments.
2981  :type parent: :py:class:`psyclone.f2pygen.SubroutineGen`
2982 
2983  :raises InternalError: if an invalid entry is encountered in the \
2984  self._basis_fns list.
2985  '''
2986  # pylint: disable=too-many-branches, too-many-locals
2987  api_config = Config.get().api_conf("dynamo0.3")
2988  const = LFRicConstants()
2989  basis_declarations = []
2990 
2991  # We need BASIS and/or DIFF_BASIS if any kernel requires quadrature
2992  # or an evaluator
2993  if self._qr_vars or self._eval_targets:
2994  parent.add(
2995  UseGen(parent, name=const.
2996  FUNCTION_SPACE_TYPE_MAP["function_space"]["module"],
2997  only=True, funcnames=["BASIS", "DIFF_BASIS"]))
2998 
2999  if self._qr_vars:
3000  parent.add(CommentGen(parent, ""))
3001  parent.add(CommentGen(parent, " Look-up quadrature variables"))
3002  parent.add(CommentGen(parent, ""))
3003 
3004  # Look-up the module- and type-names from the QUADRATURE_TYPE_MAP
3005  for shp in self._qr_vars:
3006  quad_map = const.QUADRATURE_TYPE_MAP[shp]
3007  parent.add(UseGen(parent,
3008  name=quad_map["module"],
3009  only=True,
3010  funcnames=[quad_map["type"],
3011  quad_map["proxy_type"]]))
3012  self._initialise_xyz_qr(parent)
3013  self._initialise_xyoz_qr(parent)
3014  self._initialise_xoyoz_qr(parent)
3015  self._initialise_face_or_edge_qr(parent, "face")
3016  self._initialise_face_or_edge_qr(parent, "edge")
3017 
3018  if self._eval_targets:
3019  parent.add(CommentGen(parent, ""))
3020  parent.add(CommentGen(parent,
3021  " Initialise evaluator-related quantities "
3022  "for the target function spaces"))
3023  parent.add(CommentGen(parent, ""))
3024 
3025  for (fspace, arg) in self._eval_targets.values():
3026  # We need the list of nodes for each unique FS upon which we need
3027  # to evaluate basis/diff-basis functions
3028  nodes_name = "nodes_" + fspace.mangled_name
3029  parent.add(AssignGen(
3030  parent, lhs=nodes_name,
3031  rhs="%".join([arg.proxy_name_indexed, arg.ref_name(fspace),
3032  "get_nodes()"]),
3033  pointer=True))
3034  my_kind = api_config.default_kind["real"]
3035  parent.add(DeclGen(parent, datatype="real",
3036  kind=my_kind,
3037  pointer=True,
3038  entity_decls=[nodes_name+"(:,:) => null()"]))
3039  const_mod = const.UTILITIES_MOD_MAP["constants"]["module"]
3040  const_mod_uses = self._invoke.invokes.psy. \
3041  infrastructure_modules[const_mod]
3042  # Record that we will need to import the kind for a
3043  # pointer declaration (associated with a function
3044  # space) from the appropriate infrastructure module
3045  const_mod_uses.add(my_kind)
3046 
3047  if self._basis_fns:
3048  parent.add(CommentGen(parent, ""))
3049  parent.add(CommentGen(parent, " Allocate basis/diff-basis arrays"))
3050  parent.add(CommentGen(parent, ""))
3051 
3052  var_dim_list = []
3053  for basis_fn in self._basis_fns:
3054  # Get the extent of the first dimension of the basis array.
3055  if basis_fn['type'] == "basis":
3056  first_dim = self.basis_first_dim_name(basis_fn["fspace"])
3057  dim_space = "get_dim_space()"
3058  elif basis_fn['type'] == "diff-basis":
3059  first_dim = self.diff_basis_first_dim_name(
3060  basis_fn["fspace"])
3061  dim_space = "get_dim_space_diff()"
3062  else:
3063  raise InternalError(
3064  f"Unrecognised type of basis function: "
3065  f"'{basis_fn['''type''']}'. Should be either 'basis' or "
3066  f"'diff-basis'.")
3067 
3068  if first_dim not in var_dim_list:
3069  var_dim_list.append(first_dim)
3070  rhs = "%".join(
3071  [basis_fn["arg"].proxy_name_indexed,
3072  basis_fn["arg"].ref_name(basis_fn["fspace"]),
3073  dim_space])
3074  parent.add(AssignGen(parent, lhs=first_dim, rhs=rhs))
3075 
3076  var_dims, basis_arrays = self._basis_fn_declns()
3077 
3078  if var_dims:
3079  # declare dim and diff_dim for all function spaces
3080  parent.add(DeclGen(parent, datatype="integer",
3081  kind=api_config.default_kind["integer"],
3082  entity_decls=var_dims))
3083 
3084  basis_declarations = []
3085  for basis in basis_arrays:
3086  parent.add(
3087  AllocateGen(parent,
3088  basis+"("+", ".join(basis_arrays[basis])+")"))
3089  basis_declarations.append(
3090  basis+"("+",".join([":"]*len(basis_arrays[basis]))+")")
3091 
3092  # declare the basis function arrays
3093  if basis_declarations:
3094  my_kind = api_config.default_kind["real"]
3095  parent.add(DeclGen(parent, datatype="real", kind=my_kind,
3096  allocatable=True,
3097  entity_decls=basis_declarations))
3098  # Default kind (r_def) will always already exist due to
3099  # arrays associated with gh_shape, so there is no need to
3100  # declare it here.
3101 
3102  # Compute the values for any basis arrays
3103  self._compute_basis_fns(parent)
3104 

References psyclone.dynamo0p3.DynBasisFunctions._basis_fn_declns(), psyclone.dynamo0p3.DynBasisFunctions._basis_fns, psyclone.dynamo0p3.DynBasisFunctions._compute_basis_fns(), psyclone.domain.lfric.lfric_kern.LFRicKern._eval_targets, psyclone.domain.lfric.lfric_kern_metadata.LFRicKernMetadata._eval_targets, psyclone.dynamo0p3.DynBasisFunctions._eval_targets, psyclone.dynamo0p3.DynBasisFunctions._initialise_face_or_edge_qr(), psyclone.dynamo0p3.DynBasisFunctions._initialise_xoyoz_qr(), psyclone.dynamo0p3.DynBasisFunctions._initialise_xyoz_qr(), psyclone.dynamo0p3.DynBasisFunctions._initialise_xyz_qr(), psyclone.domain.lfric.lfric_collection.LFRicCollection._invoke, psyclone.nemo.NemoInvokeSchedule._invoke, psyclone.psyGen.InvokeSchedule._invoke, psyclone.domain.lfric.lfric_collection.LFRicCollection._kernel, psyclone.dynamo0p3.DynBasisFunctions._qr_vars, psyclone.dynamo0p3.DynBasisFunctions.basis_first_dim_name(), psyclone.dynamo0p3.DynBasisFunctions.basis_first_dim_value(), psyclone.dynamo0p3.DynBasisFunctions.diff_basis_first_dim_name(), and psyclone.dynamo0p3.DynBasisFunctions.diff_basis_first_dim_value().

Here is the call graph for this function:

Member Data Documentation

◆ qr_dim_vars

dictionary psyclone.dynamo0p3.DynBasisFunctions.qr_dim_vars
static
Initial value:
= {"xyoz": ["np_xy", "np_z"],
"edge": ["np_xyz", "nedges"],
"face": ["np_xyz", "nfaces"]}

Definition at line 2643 of file dynamo0p3.py.

◆ qr_weight_vars

dictionary psyclone.dynamo0p3.DynBasisFunctions.qr_weight_vars
static
Initial value:
= {"xyoz": ["weights_xy", "weights_z"],
"edge": ["weights_xyz"],
"face": ["weights_xyz"]}

Definition at line 2647 of file dynamo0p3.py.


The documentation for this class was generated from the following file: