4.14.1. User Subroutines
Warning
The use of user subroutines should be considered a last resort, especially for production simulations - most custom capabilities can be implemented using GPU-compatible, well-tested capabilities like string functions.
Fuego supports the inclusion of user subroutines for property evaluation, boundary conditions, and initial conditions. It is worth noting that simulations that use user subroutines will not run fully on the GPU on platforms where they are available and there may be a significant performance penalty relative to using string functions in those cases.
Fuego offers support of C and Fortran user subroutines through fixed-interface signatures. It is important to note that C subroutines provide some level of variable-type safety and bounds checking that is not supported with Fortran subroutines.
The C subroutine API is described in the following sections - Fortran is left as an exercise for the reader.
4.14.1.1. Building Usersubs
The process for building user subroutines is the same for C and Fortran subroutines. When you invoke the sierra --make command, the specified input file is scanned for imported shared object (.so) files and they are compiled from source files of the same name.
sierra --make fuego -i input.i
Note
The shared object generally does not have to be re-compiled between Fuego runs unless you change the contents of the C or F file, however it is a good practice to re-compile them when you change what version of Fuego you are running.
Subroutines can also be compiled using the buildsub command, which should produce an equivalent output
buildsub -e fuego -i input.i
4.14.1.2. Property Subroutines
A C user subroutine must be a text file of suffix .C that will be compiled to a shared object file of the same name with the .so extension. For example, a file named mysubs.C would be compiled to a file named mysubs.so and referenced from the Fuego input file using the line command
load user plugin file ./mysubs.so USING FUNCTION register_usersubs
Note that, since mysubs.so is a filename, its input file name is case-sensitive, and considerations must be made concerning its location path.
An example C file to provide a subroutine for enthalpy is shown below.
#include "Afgo_UserSubSig.h"
extern "C" void enthalpy_prop(
const int * num_results, // result size (usually 1 or num_species)
double * result, // result data
const int * num_inputs, // number of inputs (e.g. "2" for "temperature mass_fraction" inputs)
const unsigned int * inp_size, // size of each input (e.g. [1, num_species] for example above)
const int * num_input_data, // total inputs size (e.g. 1+num_species for example above)
const double * input_data, // flattened input data (e.g. [T, Y_0, Y_1, Y_2] for example above)
const int * num_user_params, // size of user supplied data (1 here)
const double * user_params // user supplied data (data = [Cp])
)
{
const double T = input_data[0];
const double Cp = user_params[0];
// h = Cp*T
result[0] = Cp*T;
}
extern "C" void register_usersubs() {
sierra::Afgo::AfgoPropSub::instance().
registerFunction(std::string("enthalpy_prop"), enthalpy_prop);
}
In the code above, the actual function (named enthalpy_prop) is declared with the required signature for a property. The function is then registered for use in Fuego with the following command (which must be after the function declaration)
sierra::Afgo::AfgoPropSub::instance().registerFunction
The registration function takes two arguments:
"enthalpy_prop"- The name of the evaluator, to be referenced in the input file.
enthalpy_prop- The function being registered.
Once registered, the subroutine can be referred to in a Fuego material using the registered name:
Begin Property Specification for Fuego Material air
# ...
subroutine for enthalpy = enthalpy_prop
input variables for enthalpy_prop = temperature
real data for enthalpy_prop = 500
End
4.14.1.3. Source Subroutines
Subroutines for source terms have a different signature than for properties, and cannot take custom inputs.
An example C file to provide a subroutine for a source term for enthalpy is shown below.
#include "Afgo_UserSubSig.h"
extern "C" void enth_src(
const int * num_results, // result size (usually 1)
const int * ndims, // problem dimension (2 or 3)
const int * nnodes, // number of nodes per element
const double* coords, // 2D array of coordinates (ndims X nnodes)
const double* vol_scv, // 1D array of scv volumes (nnodes)
const double* x_vel, // 1D array of X velocity (nnodes)
const double* y_vel, // 1D array of Y velocity (nnodes)
const double* z_vel, // 1D array of Z velocity (nnodes)
const double* density, // 1D array of density (nnodes)
const double* pressure, // 1D array of pressure (nnodes)
const double* time, // Current time (scalar)
double* lhs, // 2D LHS array (nnodes x nnodes)
double* rhs // 1D RHS array (nnodes)
)
{
for(int n = 0; n < *nnodes; ++n) {
rhs[n] = vol_scv[n]*500;
}
}
extern "C" void register_usersubs() {
sierra::Afgo::FMMSFgoUserSub::instance().
registerFunction(std::string("my_enth_src"), enth_src);
}
This is referred to in the input file in the Solution Options block with
Source term subroutine = my_enth_src for EQUATION ENTHALPY
4.14.1.4. IC/BC Subroutines
The IC and BC subroutine API is not currently documented. Use at your own peril, and contact sierra-help@sandia.gov if you need help.