Skip to content

User‐Defined Functions

Tim Wildey edited this page Jan 11, 2025 · 2 revisions

MrHyDE is designed such that most users will only need to understand how the physics modules interact with the input files. One of the key mechanisms to enable this interaction is through some customized capabilities in MrHyDE to interpret arbitrarily complex strings in the input files. This is enabled by the MrHyDE function manager and interpreter, and allows the user to define complicated source functions, coefficients, boundary conditions, and even couplings between physics modules.

At a high-level, the function manager is easy to describe. It takes functions, given as strings, defined by the user, the physics modules or elsewhere in MrHyDE, picks them apart looking for operations and data it knows about, and builds a tree structure to evaluate the function. Each function corresponds to a tree, and trees can belong to one of several forests. In MrHyDE, a forest is a collection of trees that all use the same evaluation points. There are only three forests in MrHyDE, although adding more would be straightforward). These forests are associated with the volumetric quadrature points, the side/face quadratures points, and individual points (for sensors and other pointwise evaluations).

A tree is further decomposed into branches and leafs. A branch corresponds to an operation on some data, e.g., plus, times, sin, exp, etc., and a leaf corresponds to a known quantity, e.g., something stored in the workset. A function gets evaluated by working down branches until leafs are found, and then working back up. An example of a decomposed function is shown in the figure below.

Screenshot 2024-12-27 at 9 12 52 PM

The function gets broken down into simpler components until everything is expressed as a leaf or a function of a leaf. In terms of a graph, the nodes represent data and the edges represent operators. The built-in leafs are shaded green, while a potentially unknown leaf is shaded in red. If the user has defined $\alpha$ as another function or as a parameter, then this function will decompose properly. Otherwise, an error will occur.

Here is a summary of the various types of data that the function manager understands:

  • Constant scalar quantities For example, “2/34” or “pi”.
  • Spatial coordinates Use only “x”, “y” or “z”. These cannot be used as names of any other variables.
  • Time Use only “t”. This cannot be used as the name of any other variable.
  • Normal and tangent vectors These can only be used along a boundary or on the face/edge of an element. As with other vector quantities, the component is required, e.g., "n[x]" or "t[y]". There is a slight abuse of notation here since "t" is time and "t[x]" is the x-component of the tangent vector, but the proper choice should be clear from the context.
  • Scalar state variables These can be used in a straightforward manner, e.g., “e”.
  • Vector state variables These need to be specified component-wise using “[ ]”, e.g., “B[x]”.
  • Derivatives of state variables For HGRAD variables, the gradient is a vector, so we use “grad(e)[x]”. For the divergence of an HDIV variable, we just use “div(u)” since the divergence gives a scalar. For the curl of an HCURL variable, we use “curl(E)[y]”.
  • Scalar parameters Any parameter defined in the Parameters sublist can be used. For scalar parameters, we just use the name, e.g., “p”. It is also valid to use "p(0)" since scalar parameters are actually vector parameters with one component.
  • Vector parameters For vector parameters, we use the name with the component, e.g., “p(1)”.
  • Discretized parameters These are treated identical to state variables, including derivatives of the parameters.
  • Functions Any function can be used as a variable in another function, e.g., “gamma” as above. The function manager also understands a number of standard mathematical operations: +, -, *, /, ^, sin, cos, tan, exp, log, abs, <, > , sqrt, and should utilize parenthesis properly.

The following image shows a few functions and how one would add them to the Functions sublist in the MrHyDE input file:

Functions:
    thermal source: 8*(pi*pi)*sin(2*pi*x)*sin(2*pi*y)
    density: 1.0+2.0*rho
    rho: gamma*exp(-2.0*t)
    gamma: 4.5
    absgradE: abs(grad(e)[x]) + abs(grad(e)[y])

We conclude this page with a few comments on the current limitations in using functions:

  • MrHyDE does provide some error checking for cyclic graphs, undefined variables, and extra/missing parenthesis. However, it is mostly up to the user to make sure the syntax in their expression is correct. See regression/functions/Valid for a set of valid functions, and regression/functions/Invalid for a few input files that make mistakes. The latter are not regression tests since they all trigger Teuchos exceptions, but running them does show the output MrHyDE provides.
  • The functions can be fairly complex, but not arbitrarily complex. There is a limit on the number of recursions for each tree. This is currently set to 50, and could be increased, but this is already a fairly complex string.
  • While the function manager is quite convenient as it allows the user to define almost anything from the input file, it is also typically slower to implement complex functions in this way - especially on a GPU. Navigating each branch requires launching another kernel, and complex functions have many branches. Efficiency can be regained by implementing the function directly in the physics module in C++.