10 #ifdef MOOSE_MFEM_ENABLED 19 #include "libmesh/string_to_enum.h" 34 params.
addClassDescription(
"Problem type for building and solving the finite element problem " 35 "using the MFEM finite element library.");
36 MooseEnum numeric_types(
"real complex",
"real");
37 params.
addParam<
MooseEnum>(
"numeric_type", numeric_types,
"Number type used for the problem");
43 :
ExternalProblem(params), _num_type{
static_cast<int>(getParam<MooseEnum>(
"numeric_type"))}
49 #ifdef LIBMESH_HAVE_OPENMP 50 omp_set_num_threads(1);
62 std::vector<MFEMRefinementMarker *> markers;
64 for (
auto marker : markers)
65 marker->initialSetup();
89 const std::string & name,
92 addObject<Moose::MFEM::SolverBase>(user_object_name,
name,
parameters);
97 const std::string & name,
100 auto estimator = addObject<MFEMIndicator>(user_object_name,
name,
parameters).front();
103 estimator->createEstimator();
108 const std::string & name,
112 addObject<MFEMRefinementMarker>(user_object_name,
name,
parameters).front();
117 const std::string & name,
120 auto object = addObject<Moose::MFEM::SolverBase>(user_object_name,
name,
parameters).front();
123 if (
auto lin_solver = std::dynamic_pointer_cast<Moose::MFEM::LinearSolverBase>(
object))
125 if (problem_data.jacobian_solver)
126 mooseError(
"Multiple linear solvers provided. '",
127 problem_data.jacobian_solver->name(),
131 problem_data.jacobian_solver = lin_solver;
133 else if (
auto nonlinear_solver =
134 std::dynamic_pointer_cast<Moose::MFEM::NonlinearSolverBase>(
object);
137 if (problem_data.nonlinear_solver)
138 mooseError(
"Multiple nonlinear solvers provided. '",
139 problem_data.nonlinear_solver->name(),
141 nonlinear_solver->name(),
143 problem_data.nonlinear_solver = nonlinear_solver;
147 "Unsupported MFEM solver object type '", user_object_name,
"' for solver '",
name,
"'.");
152 const std::string & name,
155 auto bc = addObject<MFEMBoundaryCondition>(bc_name,
name,
parameters).front();
156 const auto & mfem_bc = *bc;
158 if (dynamic_cast<const MFEMIntegratedBC *>(&mfem_bc))
167 "' because there is no corresponding equation system.");
169 else if (dynamic_cast<const MFEMComplexIntegratedBC *>(&mfem_bc))
177 mooseError(
"Cannot add complex integrated BC with name '" +
name +
178 "' because there is no corresponding equation system.");
180 else if (dynamic_cast<const MFEMComplexEssentialBC *>(&mfem_bc))
189 "' because there is no corresponding equation system.");
191 else if (dynamic_cast<const MFEMEssentialBC *>(&mfem_bc))
200 "' because there is no corresponding equation system.");
204 mooseError(
"Unsupported bc of type '", bc_name,
"' and name '",
name,
"' detected.");
212 "MFEM materials must be added through the 'FunctorMaterials' block and not 'Materials'");
217 const std::string & name,
225 const std::string & name,
237 const std::string & var_name,
246 const auto time_derivative_var_name =
247 getMFEMObject<MFEMVariable>(
"MooseVariableBase", var_name).getTimeDerivativeName();
249 time_derivative_var_name);
256 const std::string & var_name,
260 if (var_type ==
"MFEMVariable" || var_type ==
"MFEMComplexVariable")
263 if (var_type ==
"MFEMComplexVariable")
264 addObject<MFEMComplexVariable>(var_type, var_name,
parameters);
266 addObject<MFEMVariable>(var_type, var_name,
parameters);
275 addObject<MFEMVariable>(
"MFEMVariable", var_name, mfem_variable_params);
279 if (var_type ==
"MFEMComplexVariable")
282 getMFEMObject<MFEMComplexVariable>(
"MooseVariableBase", var_name);
288 MFEMVariable & mfem_variable = getMFEMObject<MFEMVariable>(
"MooseVariableBase", var_name);
296 const std::string & var_name,
306 const std::string & name,
314 const std::string & name,
317 auto kernel = addObject<MFEMKernel>(kernel_name,
name,
parameters).front();
318 const auto & kernel_object = *kernel;
320 if (dynamic_cast<const MFEMComplexKernel *>(&kernel_object))
329 "' because there is no corresponding equation system.");
339 "' because there is no corresponding equation system.");
345 const std::string & name,
350 parameters.
set<VariableName>(
"variable") = parent_ptr->getParam<VariableName>(
"variable");
351 auto kernel_ptr = addObject<MFEMKernel>(kernel_name,
name +
"_real",
parameters).front();
352 parent_ptr->setRealKernel(kernel_ptr);
357 const std::string & name,
362 parameters.
set<VariableName>(
"variable") = parent_ptr->getParam<VariableName>(
"variable");
363 auto kernel_ptr = addObject<MFEMKernel>(kernel_name,
name +
"_imag",
parameters).front();
364 parent_ptr->setImagKernel(kernel_ptr);
369 const std::string & name,
373 getMFEMObject<MFEMComplexIntegratedBC>(
"BoundaryCondition",
name).
getSharedPtr());
374 parameters.
set<VariableName>(
"variable") = parent_ptr->getParam<VariableName>(
"variable");
376 parent_ptr->getParam<std::vector<BoundaryName>>(
"boundary");
378 addObject<MFEMBoundaryCondition>(kernel_name,
name +
"_real",
parameters).front());
379 parent_ptr->setRealBC(bc_ptr);
384 const std::string & name,
388 getMFEMObject<MFEMComplexIntegratedBC>(
"BoundaryCondition",
name).
getSharedPtr());
389 parameters.
set<VariableName>(
"variable") = parent_ptr->getParam<VariableName>(
"variable");
391 parent_ptr->getParam<std::vector<BoundaryName>>(
"boundary");
393 addObject<MFEMBoundaryCondition>(kernel_name,
name +
"_imag",
parameters).front());
394 parent_ptr->setImagBC(bc_ptr);
402 if (parameters.
isParamSetByUser(
"expression_y") || type ==
"LevelSetOlssonVortex")
410 const std::vector<std::string>
SCALAR_FUNCS = {
"Axisymmetric2D3DSolutionFunction",
411 "BicubicSplineFunction",
412 "CoarsenedPiecewiseLinear",
417 "ParsedGradFunction",
421 "PiecewiseConstantFromCSV",
423 "PiecewiseLinearFromVectorPostprocessor",
424 "PiecewiseMultiInterpolation",
425 "PiecewiseMulticonstant",
429 "LevelSetOlssonBubble",
430 "LevelSetOlssonPlane",
431 "NearestReporterCoordinatesFunction",
432 "ParameterMeshFunction",
433 "ParsedOptimizationFunction",
436 "MultiControlDrumFunction",
437 "Grad2ParsedFunction",
438 "GradParsedFunction",
439 "ScaledAbsDifferenceDRLRewardFunction",
440 "CircularAreaHydraulicDiameterFunction",
441 "CosineHumpFunction",
442 "CosineTransitionFunction",
443 "CubicTransitionFunction",
444 "GeneralizedCircumference",
451 const std::string & name,
462 [&func](
const mfem::Vector & p, mfem::real_t t) -> mfem::real_t
471 [&func,
dim](
const mfem::Vector & p, mfem::real_t t, mfem::Vector & u)
475 for (
int i = 0; i <
dim; i++)
477 u[i] = vector_value(i);
481 else if (
"MFEMParsedFunction" !=
type)
485 " is scalar or vector; no MFEM coefficient object created.");
491 const std::string & name,
500 name, [&val](
const mfem::Vector &) -> mfem::real_t {
return val; });
508 const std::string & name,
536 case FEFamily::LAGRANGE:
539 case FEFamily::NEDELEC_ONE:
542 case FEFamily::RAVIART_THOMAS:
546 case FEFamily::MONOMIAL:
547 case FEFamily::L2_LAGRANGE:
550 case FEFamily::LAGRANGE_VEC:
554 case FEFamily::MONOMIAL_VEC:
555 case FEFamily::L2_LAGRANGE_VEC:
560 mooseError(
"Unable to set MFEM FESpace for MOOSE variable");
567 const auto fec_name = space +
"_" + std::to_string(
dim) +
"D_P" + std::to_string(order);
568 const auto fes_name = fec_name +
"_X" + std::to_string(vdim);
571 fespace_params.
set<std::string>(
"fec_name") = fec_name;
572 fespace_params.
set<
int>(
"vdim") = vdim;
575 addFESpace(
"MFEMGenericFESpace", fes_name, fespace_params);
577 variable_params.
set<MFEMFESpaceName>(
"fespace") = fes_name;
579 return variable_params;
586 if (
mesh().shouldDisplace())
593 std::optional<std::reference_wrapper<mfem::ParGridFunction const>>
598 if (displacement_variable)
611 if (pmesh.Nonconforming())
623 fe_space_pair.second->Update();
630 gridfunction_pair.second->Update();
633 std::vector<VariableName>
643 "Please choose the MFEMMesh mesh type for an MFEMProblem\n");
655 const std::string & var_name,
658 auto & mfem_submesh = *addObject<MFEMSubMesh>(var_type, var_name,
parameters).front();
665 const std::string & name,
676 const std::string & name,
685 std::vector<MFEMExecutedObject *> objects;
689 .condition<AttribExecOns>(exec_type)
693 std::map<std::string, const MFEMExecutedObject *> suppliers;
694 for (
auto *
const object : objects)
695 for (
const auto & item : object->getSuppliedItems())
697 const auto [it, inserted] = suppliers.emplace(item,
object);
698 if (!inserted && it->second !=
object)
699 mooseError(
"MFEM executed-object dependency ambiguity on ",
710 for (
auto *
const object : objects)
712 object->initialize();
716 if (
auto *
const pp = dynamic_cast<const Postprocessor *>(
object))
722 if (
auto *
const vpp = dynamic_cast<VectorPostprocessor *>(
object))
730 mooseAssert(solver_sys_num == 0,
"No support for multi-system with MFEM right now");
732 std::vector<std::string> solvers;
750 std::vector<MooseObject *> objs;
754 .condition<AttribThread>(0)
757 return !objs.empty();
std::shared_ptr< mfem::ParMesh > pmesh
void addGridFunction(const std::string &var_type, const std::string &var_name, InputParameters ¶meters)
Adds one MFEM GridFunction to be used in the MFEM solve.
Constructs and stores an mfem::ParComplexGridFunction object.
std::shared_ptr< mfem::ParComplexGridFunction > getComplexGridFunction() const
Returns a shared pointer to the constructed gridfunction.
void addMarker(const std::string &type, const std::string &name, InputParameters ¶meters) override
Override of FEProblemBase::addMarker.
void addMFEMPreconditioner(const std::string &user_object_name, const std::string &name, InputParameters ¶meters)
Method called in AddMFEMPreconditionerAction which will create the solver.
virtual void addTransfer(const std::string &transfer_name, const std::string &name, InputParameters ¶meters)
Add a Transfer to the problem.
KOKKOS_INLINE_FUNCTION const T * find(const T &target, const T *const begin, const T *const end)
Find a value in an array.
unsigned int dimension() const override
Returns MeshBase::mesh_dimension(), (not MeshBase::spatial_dimension()!) of the underlying libMesh me...
Factory & _factory
The Factory for building objects.
libMesh::Point libMeshPointFromMFEMVector(const mfem::Vector &vec)
Convert an MFEM position vector to a libMesh::Point.
virtual void AddKernel(std::shared_ptr< MFEMKernel > kernel)
Add kernels.
void addRealComponentToBC(const std::string &kernel_name, const std::string &name, InputParameters ¶meters)
Adds a real component BC to the parent MFEMComplexIntegratedBC.
Moose::MFEM::ComplexGridFunctions cmplx_gridfunctions
MFEMProblemData & getProblemData()
Method to get the current MFEMProblemData object storing the current data specifying the FE problem...
const std::string & name() const
const std::vector< std::string > SCALAR_FUNCS
void addImagComponentToBC(const std::string &kernel_name, const std::string &name, InputParameters ¶meters)
Adds an imaginary component BC to the parent MFEMComplexIntegratedBC.
void setPostprocessorValueByName(const PostprocessorName &name, const PostprocessorValue &value, std::size_t t_index=0)
Set the value of a PostprocessorValue.
void addPostprocessor(const std::string &type, const std::string &name, InputParameters ¶meters) override
Override of ExternalProblem::addPostprocessor.
std::optional< std::reference_wrapper< std::string const > > getMeshDisplacementVariable() const
Returns an optional reference to displacement variable name.
void addFunction(const std::string &type, const std::string &name, InputParameters ¶meters) override
Override of ExternalProblem::addFunction.
InputParameters addMFEMFESpaceFromMOOSEVariable(InputParameters &moosevar_params)
Method used to get an mfem FEC depending on the variable family specified in the input file...
static InputParameters validParams()
Return the input parameters used to construct an MFEM problem.
virtual MFEMMesh & mesh() override
Overwritten mesh() method from base MooseMesh to retrieve the correct mesh type, in this case MFEMMes...
const InputParameters & parameters() const
Get the parameters of the object.
registerMooseObject("MooseApp", MFEMProblem)
virtual void addVariable(const std::string &var_type, const std::string &var_name, InputParameters ¶meters) override
Override of ExternalProblem::addVariable.
InputParameters getValidParams(const std::string &name) const
Get valid parameters for the object.
static InputParameters validParams()
std::shared_ptr< Moose::MFEM::LinearSolverBase > jacobian_solver
Class to store weak form components (bilinear and linear forms, and optionally mixed and nonlinear fo...
void executeMFEMObjects(const ExecFlagType &exec_type)
Execute MFEM executed objects scheduled on the supplied execute flag.
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
std::string solverTypeString(unsigned int solver_sys_num) override
Return solver type as a human readable string.
virtual void AddEssentialBC(std::shared_ptr< MFEMEssentialBC > bc)
Add BC associated with essentially constrained DoFs on boundaries.
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
These are reworked from https://stackoverflow.com/a/11003103.
std::shared_ptr< MooseObject > getSharedPtr()
Get another shared pointer to this object that has the same ownership group.
int vectorFunctionDim(const std::string &type, const InputParameters ¶meters)
void setCurrentExecuteOnFlag(const ExecFlagType &)
void displaceMesh()
Displace the mesh, if mesh displacement is enabled.
MFEMProblemData _problem_data
Aggregated MFEM-side state for meshes, spaces, variables, coefficients, and solvers.
Moose::MFEM::FESpaces fespaces
Moose::MFEM::SubMeshes submeshes
Constructs and stores an mfem::ParGridFunction object.
Moose::MFEM::FECollections fecs
bool hasMFEMObject(const std::string &system, const std::string &name) const
Determine whether an MFEM object with the supplied system and name exists.
void AddComplexEssentialBCs(std::shared_ptr< MFEMComplexEssentialBC > bc)
Add complex essential BCs.
void checkUserObjectNameCollision(const std::string &name, const std::string &type) const
Check for name collision between different user objects.
virtual Function & getFunction(const std::string &name, const THREAD_ID tid=0)
virtual void addPostprocessor(const std::string &pp_name, const std::string &name, InputParameters ¶meters)
void mooseWarning(Args &&... args) const
virtual void execute(const ExecFlagType &exec_type)
Convenience function for performing execution of MOOSE systems.
void rebalanceMesh(mfem::ParMesh &pmesh)
Rebalance the (necessarily nonconforming) mesh.
ReporterData _reporter_data
const std::string & name() const
Get the name of the class.
mfem::Coefficient & declareScalar(const std::string &name, const std::string &existing_or_literal)
Declare an alias to an existing scalar coefficient or, if it does not exist, try interpreting the nam...
void addTimeDerivativeAssociation(const std::string &var_name, const std::string &time_derivative_var_name)
TheWarehouse & theWarehouse() const
T * Get(const std::string &field_name) const
Returns a non-owning pointer to the field. This is guaranteed to return a non-null pointer...
mfem::VectorCoefficient & declareVector(const std::string &name, const std::string &existing_or_literal)
Declare an alias to an existing vector coefficientor or, if it does not exist, try interpreting the n...
virtual void addFunction(const std::string &type, const std::string &name, InputParameters ¶meters)
Real PostprocessorValue
various MOOSE typedefs
virtual void addVectorPostprocessor(const std::string &pp_name, const std::string &name, InputParameters ¶meters)
Moose::MFEM::CoefficientManager & getCoefficients()
Method to get the PropertyManager object for storing material properties and converting them to MFEM ...
void addMaterial(const std::string &material_name, const std::string &name, InputParameters ¶meters) override
virtual void initialSetup() override
const std::string & type() const
Get the type of this class.
void initialSetup() override
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
void setMesh()
Set the mesh used by MFEM.
virtual const SystemBase & systemBaseAuxiliary() const override
Return the auxiliary system object as a base class reference.
virtual void addMFEMSolver(const std::string &user_object_name, const std::string &name, InputParameters ¶meters)
Method called in AddMFEMSolverAction which will create the solver.
void finalize(const std::string &object_name)
Helper function for performing post calculation actions via the ReporterContext objects.
void addAuxKernel(const std::string &kernel_name, const std::string &name, InputParameters ¶meters) override
Override of ExternalProblem::addAuxKernel.
std::shared_ptr< mfem::ParMesh > getMFEMParMeshPtr()
Copy a shared_ptr to the mfem::ParMesh object.
std::shared_ptr< mfem::ParGridFunction > getGridFunction() const
Returns a shared pointer to the constructed gridfunction.
const PostprocessorValue & getPostprocessorValueByName(const PostprocessorName &name, std::size_t t_index=0) const
Get a read-only reference to the value associated with a Postprocessor that exists.
std::shared_ptr< Moose::MFEM::EquationSystem > eqn_system
void AddComplexIntegratedBC(std::shared_ptr< MFEMComplexIntegratedBC > bc)
Add complex integrated BCs.
virtual void addVariable(const std::string &var_type, const std::string &var_name, InputParameters ¶ms)
Canonical method for adding a non-linear variable.
std::shared_ptr< MFEMRefinementMarker > refiner
void Register(const std::string &field_name, FieldArgs &&... args)
Construct new field with name field_name and register.
MFEMProblem(const InputParameters ¶ms)
Construct an MFEM problem from the supplied parameters.
void displace(mfem::GridFunction const &displacement)
Displace the nodes of the mesh by the given displacement.
void addFunctorMaterial(const std::string &material_name, const std::string &name, InputParameters ¶meters) override
Class for containing MooseEnum item information.
void addFESpace(const std::string &type, const std::string &name, InputParameters ¶meters)
Add an MFEM FESpace to the problem.
void updateGridFunctions()
Calls Update() on all gridfunctions.
void addIndicator(const std::string &type, const std::string &name, InputParameters ¶meters) override
Override of FEProblemBase::addIndicator.
MFEMMesh inherits a MOOSE mesh class which allows us to work with other MOOSE objects.
virtual std::vector< VariableName > getAuxVariableNames()
Returns all the variable names from the auxiliary system base.
Query query()
query creates and returns an initialized a query object for querying objects from the warehouse...
void addBoundaryCondition(const std::string &bc_name, const std::string &name, InputParameters ¶meters) override
const std::vector< std::string > VECTOR_FUNCS
virtual MooseMesh & mesh() override
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
const std::vector< VariableName > & getVariableNames() const
void updateFESpaces()
Calls Update() on all FE spaces.
void addImagComponentToKernel(const std::string &kernel_name, const std::string &name, InputParameters ¶meters)
Adds an imaginary component kernel to the parent MFEMComplexKernel.
QueryCache & condition(Args &&... args)
Adds a new condition to the query.
void addVectorPostprocessor(const std::string &type, const std::string &name, InputParameters ¶meters) override
Add a vector postprocessor and register its vectors with the MFEM execution system.
void addKernel(const std::string &kernel_name, const std::string &name, InputParameters ¶meters) override
Override of ExternalProblem::addKernel.
void declareCoefficients()
Declare default coefficients associated with this gridfunction.
virtual bool isTransient() const override
std::optional< std::reference_wrapper< mfem::ParGridFunction const > > getMeshDisplacementGridFunction()
Returns optional reference to the displacement GridFunction to apply to nodes.
Moose::MFEM::GridFunctions gridfunctions
void addAuxVariable(const std::string &var_type, const std::string &var_name, InputParameters ¶meters) override
Override of ExternalProblem::addAuxVariable.
std::string stringJoin(const std::vector< std::string > &values, const std::string &separator=" ")
Concatenates value into a single string separated by separator.
void addRealComponentToKernel(const std::string &kernel_name, const std::string &name, InputParameters ¶meters)
Adds a real component kernel to the parent MFEMComplexKernel.
virtual void AddIntegratedBC(std::shared_ptr< MFEMIntegratedBC > kernel)
void addSubMesh(const std::string &type, const std::string &name, InputParameters ¶meters)
Add an MFEM SubMesh to the problem.
void declareCoefficients()
Moose::MFEM::TimeDerivativeMap time_derivative_map
virtual void execute(const ExecFlagType &exec_type) override
Convenience function for performing execution of MOOSE systems.
std::string prettyCppType(const std::string &cpp_type)
void addTransfer(const std::string &transfer_name, const std::string &name, InputParameters ¶meters) override
Add transfers between MultiApps and/or MFEM SubMeshes.
void addInitialCondition(const std::string &ic_name, const std::string &name, InputParameters ¶meters) override
Add an MFEM initial condition to the problem.
void AddComplexKernel(std::shared_ptr< MFEMComplexKernel > kernel)
Add complex kernels.