common.fypp Source File


Contents

Source Code


Source Code

#:mute

#! Real kinds to be considered during templating
#:set REAL_KINDS = ["sp", "dp", "qp"]

#! Real types to be considere during templating
#:set REAL_TYPES = ["real({})".format(k) for k in REAL_KINDS]

#! Collected (kind, type) tuples for real types
#:set REAL_KINDS_TYPES = list(zip(REAL_KINDS, REAL_TYPES))

#! Complex kinds to be considered during templating
#:set CMPLX_KINDS = ["sp", "dp", "qp"]

#! Complex types to be considere during templating
#:set CMPLX_TYPES = ["complex({})".format(k) for k in CMPLX_KINDS]

#! Collected (kind, type) tuples for complex types
#:set CMPLX_KINDS_TYPES = list(zip(CMPLX_KINDS, CMPLX_TYPES))

#! Integer kinds to be considered during templating
#:set INT_KINDS = ["int8", "int16", "int32", "int64"]

#! Integer types to be considere during templating
#:set INT_TYPES = ["integer({})".format(k) for k in INT_KINDS]

#! Collected (kind, type) tuples for integer types
#:set INT_KINDS_TYPES = list(zip(INT_KINDS, INT_TYPES))


#! Whether Fortran 90 compatible code should be generated
#:set VERSION90 = defined('VERSION90')


#! Ranks to be generated when templates are created
#:if not defined('MAXRANK')
  #:if VERSION90
    #:set MAXRANK = 7
  #:else
    #:set MAXRANK = 15
  #:endif
#:endif


#! Generates an array rank suffix.
#!
#! Args:
#!     rank (int): Rank of the variable
#!
#! Returns:
#!     Array rank suffix string (e.g. (:,:) if rank = 2)
#!
#:def ranksuffix(rank)
#{if rank > 0}#(${":" + ",:" * (rank - 1)}$)#{endif}#
#:enddef


#! Joins stripped lines with given character string
#!
#! Args:
#!   txt (str): Text to process
#!   joinstr (str): String to use as connector
#!   prefix (str): String to add as prefix before the joined text
#!   suffix (str): String to add as suffix after the joined text
#!
#! Returns:
#!   Lines stripped and joined with the given string.
#!
#:def join_lines(txt, joinstr, prefix="", suffix="")
${prefix + joinstr.join([line.strip() for line in txt.split("\n")]) + suffix}$
#:enddef


#! Brace enclosed, comma separated Fortran expressions for a reduced shape.
#!
#! Rank of the original variable will be reduced by one. The routine generates
#! for each dimension a Fortan expression using merge(), which calculates the
#! size of the array for that dimension.
#!
#! Args:
#!   varname (str): Name of the variable to be used as origin
#!   origrank (int): Rank of the original variable
#!   idim (int): Index of the reduced dimension
#!
#! Returns:
#!   Shape expression enclosed in braces, so that it can be used as suffix to
#!   define array shapes in declarations.
#!
#:def reduced_shape(varname, origrank, idim)
  #:assert origrank > 0
  #:if origrank > 1
    #:call join_lines(joinstr=", ", prefix="(", suffix=")")
      #:for i in range(1, origrank)
        merge(size(${varname}$, ${i}$), size(${varname}$, ${i + 1}$), mask=${i}$<${idim}$)
      #:endfor
    #:endcall
  #:endif
#:enddef


#! Generates a routine name from a generic name, rank, type and kind
#!
#! Args:
#!   gname (str): Generic name
#!   rank (integer): Rank if exist
#!   type (str): Type of the input
#!   kind (str): kind of inputs variable
#!   suffix (str): other identifier (could be used for output type/kind)
#!
#! Returns:
#!   A string with a new name
#!
#:def rname(gname, rank, type, kind, suffix='')
  $:"{0}_{1}_{2}{3}_{2}{3}".format(gname, rank, type[0], kind) if suffix == '' else "{0}_{1}_{2}{3}_{4}".format(gname, rank, type[0], kind, suffix)
#:enddef


#! Generates an array rank suffix for subarrays reducing the dimension
#!
#! Args:
#!   rank (int): Rank of the original variable
#!   selectors (array): Dimension and name of the variable(s)
#!
#! Returns:
#!   Array rank suffix string enclosed in braces
#!
#! E.g.,
#!   select_subarray(5 , [(4, 'i'), (5, 'j')])}$
#!   -> (:, :, :, i, j)
#!
#:def select_subarray(rank, selectors)
  #:assert rank > 0
  #:set seldict = dict(selectors)
  #:call join_lines(joinstr=", ", prefix="(", suffix=")")
    #:for i in range(1, rank + 1)
      $:seldict.get(i, ":")
    #:endfor
  #:endcall
#:enddef

#:endmute