Function Callbacks

For input file types that support functions, e.g., Lua, functions can also be read from the input file into a std::function, the wrapper for callables provided by the C++ standard library.

Defining And Storing

This is accomplished by calling addFunction on an Inlet or Container object.

Consider the following Lua function that accepts a vector in R2 or R3 and returns a double:

coef = function (v)
  if v.dim == 2 then
    return v.x + (v.y * 0.5)
  else
    return v.x + (v.y * 0.5) + (v.z * 0.25)
  end
end

The schema for this function would be defined as follows:

    schema
      .addFunction("coef",
                   inlet::FunctionTag::Double,
                   {inlet::FunctionTag::Vector, inlet::FunctionTag::Double},
                   "The function representing the BC coefficient")

The return type and argument types are described with the inlet::FunctionTag enumeration, which has the following members:

  • Double - corresponds to a C++ double

  • String - corresponds to a C++ std::string

  • Vector - corresponds to a C++ inlet::InletVector

  • Void - corresponds to C++ void, should only be used for functions that don’t return a value

Note that a single type tag is passed for the return type, while a vector of tags is passed for the argument types. Currently a maximum of two arguments are supported. To declare a function with no arguments, simply leave the list of argument types empty.

Note

The InletVector type (and its Lua representation) are statically-sized vectors with a maximum dimension of three. That is, they can also be used to represent two-dimensional vectors.

In Lua, the following operations on the Vector type are supported (for Vector s u, v, and w):

  1. Construction of a 3D vector: u = Vector.new(1, 2, 3)

  2. Construction of a 2D vector: u = Vector.new(1, 2)

  3. Construction of an empty vector (default dimension is 3): u = Vector.new()

  4. Vector addition and subtraction: w = u + v, w = u - v

  5. Vector negation: v = -u

  6. Scalar multiplication: v = u * 0.5, v = 0.5 * u

  7. Indexing (1-indexed for consistency with Lua): d = u[1], u[1] = 0.5

  8. L2 norm and its square: d = u:norm(), d = u:squared_norm()

  9. Normalization: v = u:unitVector()

  10. Dot and cross products: d = u:dot(v), w = u:cross(v)

  11. Dimension retrieval: d = u.dim

  12. Component retrieval: d = u.x, d = u.y, d = u.z

Accessing

To retrieve a function, both the implicit conversion and get<T> syntax is supported. For example, a function can be retrieved as follows:

      // Retrieve the function (makes a copy) to be moved into the lambda
      auto func =
        base["coef"].get<std::function<double(FunctionType::Vector, double)>>();

It can also be assigned directly to a std::function without the need to use get<T>:

std::function<double(FunctionType::Vector)> coef = inlet["coef"];

Additionally, if a function does not need to be stored, the overhead of a copy can be eliminated by calling it directly:

double result = inlet["coef"].call<double>(axom::inlet::FunctionType::Vector{3, 5, 7});

Note

Using call<ReturnType>(ArgType1, ArgType2, ...) requires both that the return type be explicitly specified and that argument types be passed with the exact type as used in the signature defined as part of the schema. This is because the arguments do not participate in overload resolution.