diff --git a/include/ics/MFEMScalarIC.h b/include/ics/MFEMScalarIC.h new file mode 100644 index 00000000..843d27ce --- /dev/null +++ b/include/ics/MFEMScalarIC.h @@ -0,0 +1,9 @@ +#include "MFEMGeneralUserObject.h" + +class MFEMScalarIC : public MFEMGeneralUserObject +{ +public: + static InputParameters validParams(); + MFEMScalarIC(const InputParameters & params); + virtual void execute() override; +}; diff --git a/include/problem/MFEMProblem.h b/include/problem/MFEMProblem.h index 07156557..5a60f028 100644 --- a/include/problem/MFEMProblem.h +++ b/include/problem/MFEMProblem.h @@ -126,6 +126,10 @@ class MFEMProblem : public ExternalProblem const std::string & name, InputParameters & parameters) override; + void addInitialCondition(const std::string & ic_name, + const std::string & name, + InputParameters & parameters) override; + /** * Method called in AddMFEMPreconditionerAction which will create the solver. */ @@ -219,6 +223,16 @@ class MFEMProblem : public ExternalProblem std::optional> getMeshDisplacementGridFunction(); + /** + * @returns a shared pointer to an MFEM coefficient created using the [Coefficients] syntax + */ + std::shared_ptr getCoefficient(const std::string & name); + + /** + * @returns a shared pointer to an MFEM parallel grid function + */ + std::shared_ptr getGridFunction(const std::string & name); + protected: /** * Template method for adding kernels. We can only add kernels using equation system problem diff --git a/src/base/PlatypusApp.C b/src/base/PlatypusApp.C index 0bd90620..ac7da8ff 100644 --- a/src/base/PlatypusApp.C +++ b/src/base/PlatypusApp.C @@ -38,7 +38,8 @@ associateSyntaxInner(Syntax & syntax, ActionFactory & /*action_factory*/) addTaskDependency("add_material", "add_mfem_coefficients"); addTaskDependency("add_mfem_coefficients", "add_variable"); addTaskDependency("add_mfem_coefficients", "add_aux_variable"); - addTaskDependency("add_mfem_coefficients", "add_ic"); + addTaskDependency("add_ic", "add_mfem_coefficients"); + addTaskDependency("add_mfem_coefficients", "add_function"); // add vector coefficients registerMooseObjectTask("add_mfem_vector_coefficients", MFEMVectorCoefficient, false); diff --git a/src/ics/MFEMScalarIC.C b/src/ics/MFEMScalarIC.C new file mode 100644 index 00000000..271013fc --- /dev/null +++ b/src/ics/MFEMScalarIC.C @@ -0,0 +1,32 @@ +#include "MFEMScalarIC.h" +#include "MFEMProblem.h" +#include +#include + +registerMooseObject("PlatypusApp", MFEMScalarIC); + +InputParameters +MFEMScalarIC::validParams() +{ + auto params = MFEMGeneralUserObject::validParams(); + params.addRequiredParam("variable", + "The variable to apply the initial condition for"); + params.addRequiredParam("coefficient", "The scalar coefficient"); + params.registerBase("InitialCondition"); + // We cannot generally execute this at construction time since the coefficient may depend on, for + // instance, a MOOSE function which is not itself setup until its initialSetup is called. + // UserObject initial execution occurs after function initialSetup + params.set("execute_on") = {EXEC_INITIAL}; + params.suppressParameter("execute_on"); + return params; +} + +MFEMScalarIC::MFEMScalarIC(const InputParameters & params) : MFEMGeneralUserObject(params) {} + +void +MFEMScalarIC::execute() +{ + auto coeff = getMFEMProblem().getCoefficient(getParam("coefficient")); + auto grid_function = getMFEMProblem().getGridFunction(getParam("variable")); + grid_function->ProjectCoefficient(*coeff); +} diff --git a/src/problem/MFEMProblem.C b/src/problem/MFEMProblem.C index b225df27..98a5c3ee 100644 --- a/src/problem/MFEMProblem.C +++ b/src/problem/MFEMProblem.C @@ -1,4 +1,5 @@ #include "MFEMProblem.h" +#include "MFEMScalarIC.h" #include #include @@ -421,3 +422,24 @@ MFEMProblem::mesh() "Please choose the MFEMMesh mesh type for an MFEMProblem\n"); return (MFEMMesh &)_mesh; } + +std::shared_ptr +MFEMProblem::getCoefficient(const std::string & name) +{ + return getUserObject(name).getCoefficient(); +} + +std::shared_ptr +MFEMProblem::getGridFunction(const std::string & name) +{ + return getUserObject(name).getGridFunction(); +} + +void +MFEMProblem::addInitialCondition(const std::string & ic_name, + const std::string & name, + InputParameters & parameters) +{ + FEProblemBase::addUserObject(ic_name, name, parameters); + getUserObject(name); // error check +} diff --git a/test/tests/kernels/diffusion.i b/test/tests/kernels/diffusion.i index 188de73f..c1aa4034 100644 --- a/test/tests/kernels/diffusion.i +++ b/test/tests/kernels/diffusion.i @@ -23,12 +23,20 @@ [] [] +[ICs] + [diffused_ic] + type = MFEMScalarIC + coefficient = one + variable = diffused + [] +[] + [Functions] - [value_bottom] + [one] type = ParsedFunction expression = 1.0 [] - [value_top] + [zero] type = ParsedFunction expression = 0.0 [] @@ -39,13 +47,13 @@ type = MFEMScalarDirichletBC variable = diffused boundary = '1' - coefficient = BottomValue + coefficient = one [] [low_terminal] type = MFEMScalarDirichletBC variable = diffused boundary = '2' - coefficient = TopValue + coefficient = zero [] [] @@ -58,13 +66,13 @@ [] [Coefficients] - [TopValue] + [zero] type = MFEMFunctionCoefficient - function = value_top + function = zero [] - [BottomValue] + [one] type = MFEMFunctionCoefficient - function = value_bottom + function = one [] [] @@ -86,7 +94,7 @@ type = MFEMHypreGMRES preconditioner = boomeramg l_tol = 1e-16 - l_max_its = 1000 + l_max_its = 1000 [] [Executioner]