Physics system
The Physics
system is meant to standardize the process of adding an equation and its discretization to a simulation. It is based on the Action system, with additional APIs defined to support the definition of an equation.
Interaction with Components
The interaction with Components is one of the main goals of the Physics system. Stay tuned for future developments.
Implementing your own Physics
If you have not created the kernels, boundary conditions, and so on, the Physics
system is not a good place to start. You must start with a working implementation of your equations before attempting to create a Physics
object.
If you do have a working set of kernels, boundary conditions, and other MOOSE objects, that let you solve an equation in MOOSE, you should consider the following before implementing a Physics
:
is user-friendliness a priority for the expansion of my work?
is the current workflow unsatisfactory in that regard?
would creating objects programmatically reduce the potential for user-error while allowing sufficient flexibility?
If the answer is yes to all three, then you may start implementing a Physics
object for your equation. The simple concepts behind the simulation setup in a Physics
is that the add<various MOOSE object>
routines are all called on the Physics
and they are all called at the same time in the setup as with a regular input file.
So for example, to make a DiffusionPhysics
create a finite element diffusion kernel, one can override addFEKernels
like this:
void
DiffusionPhysics::addFEKernels()
{
{
const std::string kernel_type = "ADDiffusion";
InputParameters params = getFactory().getValidParams(kernel_type);
params.set<NonlinearVariableName>("variable") = _temperature_name; // we saved the name of the variable as a class attribute
getProblem().addKernel(kernel_type, name() + "_diffusion", params);
}
}
Notice how we use the PhysicsBase::getFactory()
routine to get access to the Factory
that will get the parameters we need to fill, and the PhysicsBase::getProblem()
to get access to the Problem
which stores the objects created.
If you already have an Action
defined for your physics, converting it to a Physics
should be fairly straightforward. The principal advantages of doing so are:
benefit from new APIs implemented in the
Physics
systemfuture ability to leverage the
Components
system to define a complex system
Advice on implementation
Add a lot of checks
Do as much parameter checking as you can. The PhysicsBase
class defines utilities such as the ones below that let you check that the user inputs to your physics are correct.
void checkParamsBothSetOrNotSet(const std::string & param1, const std::string & param2) const;
template <typename T, typename S>
void checkVectorParamsSameLength(const std::string & param1, const std::string & param2) const;
template <typename T>
void checkVectorParamsNoOverlap(const std::vector<std::string> & param_vec) const;
Separate the definition of the equation from its discretization
The Physics base class you will create will hold the parameters that are shared between all the discretized versions of it.
Physics and spatial discretizations are as separated as we could make them, but they are still very much intertwined. So when you are adding a parameter you need to think about:
is this more tied to the strong form of the equation? If so then it likely belongs in a
XYZPhysicsBase
base classis this more tied to the discretization of the equation? If so then it likely belong in the derived, user-instantiated,
XYZPhysics
class.