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
Physicssystemfuture ability to leverage the
Componentssystem 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
XYZPhysicsBasebase classis this more tied to the discretization of the equation? If so then it likely belong in the derived, user-instantiated,
XYZPhysicsclass.