10 #ifdef MOOSE_MFEM_ENABLED 13 #include "libmesh/int_range.h" 31 const std::string & name)
const 33 auto iter =
std::find(the_vector.begin(), the_vector.end(),
name);
34 return (iter != the_vector.end());
70 auto trial_var_name = kernel->getTrialVariableName();
71 auto test_var_name = kernel->getTestVariableName();
74 auto kernel_field_map =
75 std::make_shared<Moose::MFEM::NamedFieldsMap<std::vector<std::shared_ptr<MFEMKernel>>>>();
82 auto kernels = std::make_shared<std::vector<std::shared_ptr<MFEMKernel>>>();
83 _kernels_map.
Get(test_var_name)->Register(trial_var_name, std::move(kernels));
93 auto trial_var_name = bc->getTrialVariableName();
94 auto test_var_name = bc->getTestVariableName();
97 auto integrated_bc_field_map = std::make_shared<
105 auto bcs = std::make_shared<std::vector<std::shared_ptr<MFEMIntegratedBC>>>();
114 auto test_var_name = bc->getTestVariableName();
117 auto bcs = std::make_shared<std::vector<std::shared_ptr<MFEMEssentialBC>>>();
130 if (!gridfunctions.
Has(test_var_name))
134 " requested by equation system during initialisation was " 135 "not found in gridfunctions");
141 std::make_unique<mfem::ParGridFunction>(gridfunctions.
Get(test_var_name)->ParFESpace()));
155 gridfunctions.
GetShared(eliminated_var_name));
160 mfem::ParGridFunction & trial_gf,
161 mfem::Array<int> & global_ess_markers)
166 for (
auto & bc : bcs)
169 bc->ApplyBC(trial_gf);
171 mfem::Array<int> ess_bdrs(bc->getBoundaryMarkers());
173 for (
auto it = 0; it != trial_gf.ParFESpace()->GetParMesh()->bdr_attributes.Max(); ++it)
174 global_ess_markers[it] =
std::max(global_ess_markers[it], ess_bdrs[it]);
187 mfem::Array<int> global_ess_markers(trial_gf.ParFESpace()->GetParMesh()->bdr_attributes.Max());
188 global_ess_markers = 0;
192 trial_gf.ParFESpace()->GetEssentialTrueDofs(global_ess_markers,
_ess_tdof_lists.at(i));
201 auto lf =
_lfs.
Get(test_var_name);
206 auto mblf =
_mblfs.
Get(test_var_name)->Get(eliminated_var_name);
208 mfem::Vector lf_prev(lf->Size());
218 mfem::BlockVector & trueX,
219 mfem::BlockVector & trueRHS)
224 case mfem::AssemblyLevel::LEGACY:
229 "Non-legacy assembly is only supported for single-variable systems");
232 "Non-legacy assembly is only supported for single test and trial variable systems");
239 mfem::BlockVector & trueX,
240 mfem::BlockVector & trueRHS)
243 auto blf =
_blfs.
Get(test_var_name);
244 auto lf =
_lfs.
Get(test_var_name);
245 mfem::BlockVector aux_x, aux_rhs;
246 mfem::OperatorPtr aux_a;
248 blf->FormLinearSystem(
251 trueX.GetBlock(0) = aux_x;
252 trueRHS.GetBlock(0) = aux_rhs;
253 trueX.SyncFromBlocks();
254 trueRHS.SyncFromBlocks();
256 op.Reset(aux_a.Ptr());
257 aux_a.SetOperatorOwner(
false);
266 std::vector<mfem::Array<int>> & ess_tdof_lists,
267 std::vector<std::unique_ptr<mfem::ParGridFunction>> & var_ess_constraints,
268 mfem::OperatorHandle & op,
269 mfem::BlockVector & trueX,
270 mfem::BlockVector & trueRHS)
279 auto blf = jac_blfs.
Get(test_var_name);
280 auto lf = rhs_lfs.
Get(test_var_name);
281 mfem::Vector aux_x, aux_rhs;
282 mfem::HypreParMatrix * aux_a =
new mfem::HypreParMatrix;
283 blf->FormLinearSystem(
284 ess_tdof_lists.at(i), *(var_ess_constraints.at(i)), *lf, *aux_a, aux_x, aux_rhs);
286 trueX.GetBlock(i) = aux_x;
287 trueRHS.GetBlock(i) = aux_rhs;
298 mfem::Vector aux_x, aux_rhs;
301 if (jac_mblfs.Has(test_var_name) && jac_mblfs.Get(test_var_name)->Has(trial_var_name))
303 auto mblf = jac_mblfs.Get(test_var_name)->Get(trial_var_name);
304 mfem::HypreParMatrix * aux_a =
new mfem::HypreParMatrix;
305 mblf->FormRectangularLinearSystem(ess_tdof_lists.at(j),
306 ess_tdof_lists.at(i),
307 *(var_ess_constraints.at(j)),
313 trueRHS.GetBlock(i) += aux_rhs;
318 trueX.SyncFromBlocks();
319 trueRHS.SyncFromBlocks();
322 op.Reset(mfem::HypreParMatrixFromBlocks(
_h_blocks));
327 mfem::BlockVector & trueX,
328 mfem::BlockVector & trueRHS)
336 height = trueX.Size();
337 width = trueRHS.Size();
362 trueX.GetBlock(i).SyncAliasMemory(trueX);
363 gridfunctions.
Get(trial_var_name)->Distribute(&(trueX.GetBlock(i)));
406 ApplyBoundaryBLFIntegrators<mfem::ParBilinearForm>(
408 ApplyDomainBLFIntegrators<mfem::ParBilinearForm>(
427 auto test_mblfs = std::make_shared<Moose::MFEM::NamedFieldsMap<mfem::ParMixedBilinearForm>>();
437 test_var_name != coupled_var_name)
441 ApplyDomainBLFIntegrators<mfem::ParMixedBilinearForm>(
447 test_mblfs->Register(coupled_var_name, mblf);
466 : _dt_coef(1.0), _time_derivative_map(time_derivative_map)
472 mfem::AssemblyLevel assembly_level)
477 std::make_unique<mfem::ParGridFunction>(gridfunctions.
Get(test_var_name)->ParFESpace()));
483 if (fabs(dt -
_dt_coef.constant) > 1.0e-12 * dt)
488 auto blf =
_blfs.
Get(test_var_name);
512 const auto time_derivative_test_var_name =
516 if (time_derivative_test_var_name != coupled_var_name &&
528 const auto & trial_var_name = kernel->getTrialVariableName();
529 const auto & test_var_name = kernel->getTestVariableName();
539 auto kernel_field_map =
540 std::make_shared<Moose::MFEM::NamedFieldsMap<std::vector<std::shared_ptr<MFEMKernel>>>>();
545 auto kernels = std::make_shared<std::vector<std::shared_ptr<MFEMKernel>>>();
572 ApplyBoundaryBLFIntegrators<mfem::ParBilinearForm>(
574 ApplyDomainBLFIntegrators<mfem::ParBilinearForm>(
601 std::make_shared<Moose::MFEM::NamedFieldsMap<mfem::ParMixedBilinearForm>>();
605 auto td_mblf = std::make_shared<mfem::ParMixedBilinearForm>(
_test_pfespaces.at(j),
614 ApplyDomainBLFIntegrators<mfem::ParMixedBilinearForm>(
620 const auto & trial_var_time_integral_name =
622 if (
_mblfs.
Has(test_var_name) &&
_mblfs.
Get(test_var_name)->Has(trial_var_time_integral_name))
626 auto mblf =
_mblfs.
Get(test_var_name)->GetShared(trial_var_time_integral_name);
630 if (td_mblf->GetDBFI()->Size() || td_mblf->GetBBFI()->Size())
637 test_td_mblfs->Register(trial_var_name, td_mblf);
652 const auto time_derivative_test_var_name =
656 mfem::Array<int> global_ess_markers(trial_gf.ParFESpace()->GetParMesh()->bdr_attributes.Max());
657 global_ess_markers = 0;
667 time_derivative_test_var_name, trial_gf_time_derivative, global_ess_markers);
668 trial_gf.ParFESpace()->GetEssentialTrueDofs(global_ess_markers,
_ess_tdof_lists.at(i));
679 auto blf =
_blfs.
Get(test_var_name);
680 auto lf =
_lfs.
Get(test_var_name);
683 mfem::Vector lf_prev(lf->Size());
693 mfem::BlockVector & truedXdt,
694 mfem::BlockVector & trueRHS)
703 mfem::BlockVector & truedXdt,
704 mfem::BlockVector & trueRHS)
708 auto lf =
_lfs.
Get(test_var_name);
711 mfem::OperatorPtr aux_a;
712 mfem::Vector aux_x, aux_rhs;
713 td_blf->FormLinearSystem(
716 truedXdt.GetBlock(0) = aux_x;
717 trueRHS.GetBlock(0) = aux_rhs;
718 truedXdt.SyncFromBlocks();
719 trueRHS.SyncFromBlocks();
722 op.Reset(aux_a.Ptr());
723 aux_a.SetOperatorOwner(
false);
std::string name(const ElemQuality q)
mfem::ConstantCoefficient _dt_coef
Coefficient for timestep scaling.
virtual void EliminateCoupledVariables()
Perform trivial eliminations of coupled variables lacking corresponding test variables.
virtual void AddKernel(std::shared_ptr< MFEMKernel > kernel) override
Add kernels.
KOKKOS_INLINE_FUNCTION const T * find(const T &target, const T *const begin, const T *const end)
Find a value in an array.
virtual void AddTestVariableNameIfMissing(const std::string &test_var_name)
Add test variable to EquationSystem.
virtual void AddKernel(std::shared_ptr< MFEMKernel > kernel)
Add kernels.
virtual void RecoverFEMSolution(mfem::BlockVector &trueX, Moose::MFEM::GridFunctions &gridfunctions)
Update variable from solution vector after solve.
virtual void BuildBilinearForms()
Build bilinear forms (diagonal Jacobian contributions)
bool Has(const std::string &field_name) const
Predicate to check if a field is registered with name field_name.
void AssembleJacobian(Moose::MFEM::NamedFieldsMap< mfem::ParBilinearForm > &jac_blfs, Moose::MFEM::NamedFieldsMap< Moose::MFEM::NamedFieldsMap< mfem::ParMixedBilinearForm >> &jac_mblfs, Moose::MFEM::NamedFieldsMap< mfem::ParLinearForm > &rhs_lfs, std::vector< mfem::Array< int >> &ess_tdof_lists, std::vector< std::unique_ptr< mfem::ParGridFunction >> &var_ess_constraints, mfem::OperatorHandle &op, mfem::BlockVector &trueX, mfem::BlockVector &trueRHS)
Form Jacobian operator based on on- and off-diagonal bilinear form contributions, populate solution a...
std::vector< mfem::ParFiniteElementSpace * > _coupled_pfespaces
Pointers to finite element spaces associated with coupled variables.
Moose::MFEM::NamedFieldsMap< Moose::MFEM::NamedFieldsMap< std::vector< std::shared_ptr< MFEMKernel > > > > _td_kernels_map
bool isTimeDerivative(const std::string &time_derivative_var_name) const
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
virtual void FormSystem(mfem::OperatorHandle &op, mfem::BlockVector &truedXdt, mfem::BlockVector &trueRHS) override
void ApplyBoundaryLFIntegrators(const std::string &test_var_name, std::shared_ptr< mfem::ParLinearForm > form, Moose::MFEM::NamedFieldsMap< Moose::MFEM::NamedFieldsMap< std::vector< std::shared_ptr< MFEMIntegratedBC >>>> &integrated_bc_map)
bool VectorContainsName(const std::vector< std::string > &the_vector, const std::string &name) const
std::vector< std::string > _eliminated_var_names
Names of all coupled variables without a corresponding test variable.
virtual void UpdateEquationSystem()
~EquationSystem() override
Moose::MFEM::NamedFieldsMap< Moose::MFEM::NamedFieldsMap< mfem::ParMixedBilinearForm > > _mblfs
Moose::MFEM::GridFunctions _eliminated_variables
Pointers to coupled variables not part of the reduced EquationSystem.
virtual void AddEssentialBC(std::shared_ptr< MFEMEssentialBC > bc)
Add BC associated with essentially constrained DoFs on boundaries.
Lightweight adaptor over a std::map relating names of GridFunctions with the name of their time deriv...
const std::string & getTimeIntegralName(const std::string &time_derivative_var_name) const
std::vector< mfem::Array< int > > _ess_tdof_lists
Moose::MFEM::NamedFieldsMap< Moose::MFEM::NamedFieldsMap< mfem::ParMixedBilinearForm > > _td_mblfs
Lightweight adaptor over an std::map from strings to pointer to T.
mfem::AssemblyLevel _assembly_level
auto max(const L &left, const R &right)
Moose::MFEM::NamedFieldsMap< std::vector< std::shared_ptr< MFEMEssentialBC > > > _essential_bc_map
Arrays to store essential BCs to act on each component of weak form.
std::vector< mfem::ParFiniteElementSpace * > _test_pfespaces
Pointers to finite element spaces associated with test variables.
virtual void Init(Moose::MFEM::GridFunctions &gridfunctions, mfem::AssemblyLevel assembly_level) override
Initialise.
virtual void SetTimeStep(mfem::real_t dt)
void Mult(const mfem::Vector &u, mfem::Vector &residual) const override
Compute residual y = Mu.
std::vector< std::string > _trial_var_names
Subset of _coupled_var_names of all variables corresponding to gridfunctions with degrees of freedom ...
std::vector< std::unique_ptr< mfem::ParGridFunction > > _td_var_ess_constraints
Gridfunctions holding essential constraints from Dirichlet BCs.
virtual void BuildMixedBilinearForms() override
Build mixed bilinear forms (off-diagonal Jacobian contributions)
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...
virtual void EliminateCoupledVariables() override
Perform trivial eliminations of coupled variables lacking corresponding test variables.
virtual void FormLegacySystem(mfem::OperatorHandle &op, mfem::BlockVector &trueX, mfem::BlockVector &trueRHS)
std::shared_ptr< T > GetShared(const std::string &field_name) const
Returns a shared pointer to the field. This is guaranteed to return a non-null shared pointer...
virtual void SetTrialVariableNames() override
Set trial variable names from subset of coupled variables that have an associated test variable...
mfem::OperatorHandle _jacobian
virtual void Init(Moose::MFEM::GridFunctions &gridfunctions, mfem::AssemblyLevel assembly_level)
Initialise.
void ScaleAndAddBLFIntegrators(std::shared_ptr< FormType > source_blf, std::shared_ptr< FormType > target_blf, mfem::real_t scale_factor)
Fetch all integrators on a source bilinear form, scale them by a real factor, and add to a second tar...
TimeDependentEquationSystem(const Moose::MFEM::TimeDerivativeMap &time_derivative_map)
std::vector< std::string > _test_var_names
Names of all test variables corresponding to linear forms in this equation system.
virtual void BuildEquationSystem()
Build all forms comprising this EquationSystem.
std::vector< std::unique_ptr< mfem::ParGridFunction > > _var_ess_constraints
Gridfunctions holding essential constraints from Dirichlet BCs.
virtual void FormLegacySystem(mfem::OperatorHandle &op, mfem::BlockVector &truedXdt, mfem::BlockVector &trueRHS) override
virtual void BuildMixedBilinearForms()
Build mixed bilinear forms (off-diagonal Jacobian contributions)
mfem::Array2D< const mfem::HypreParMatrix * > _h_blocks
virtual void ApplyEssentialBCs() override
Update all essentially constrained true DoF markers and values on boundaries.
virtual void SetTrialVariableNames()
Set trial variable names from subset of coupled variables that have an associated test variable...
virtual void AddCoupledVariableNameIfMissing(const std::string &coupled_var_name)
Add coupled variable to EquationSystem.
virtual void FormLinearSystem(mfem::OperatorHandle &op, mfem::BlockVector &trueX, mfem::BlockVector &trueRHS)
Form linear system, with essential boundary conditions accounted for.
std::vector< std::string > _coupled_var_names
Names of all trial variables of kernels and boundary conditions added to this EquationSystem.
void Register(const std::string &field_name, FieldArgs &&... args)
Construct new field with name field_name and register.
Moose::MFEM::NamedFieldsMap< Moose::MFEM::NamedFieldsMap< std::vector< std::shared_ptr< MFEMIntegratedBC > > > > _integrated_bc_map
Arrays to store integrated BCs to act on each component of weak form.
void DeleteAllBlocks()
Deletes the HypreParMatrix associated with any pointer stored in _h_blocks, and then proceeds to dele...
Moose::MFEM::NamedFieldsMap< mfem::ParBilinearForm > _td_blfs
Containers to store contributions to weak form of the form (F du/dt, v)
virtual void BuildLinearForms()
Build linear forms and eliminate constrained DoFs.
IntRange< T > make_range(T beg, T end)
const Moose::MFEM::TimeDerivativeMap & _time_derivative_map
Map between variable names and their time derivatives.
virtual void BuildJacobian(mfem::BlockVector &trueX, mfem::BlockVector &trueRHS)
Build linear system, with essential boundary conditions accounted for.
void ApplyDomainLFIntegrators(const std::string &test_var_name, std::shared_ptr< mfem::ParLinearForm > form, Moose::MFEM::NamedFieldsMap< Moose::MFEM::NamedFieldsMap< std::vector< std::shared_ptr< MFEMKernel >>>> &kernels_map)
virtual void ApplyEssentialBCs()
Update all essentially constrained true DoF markers and values on boundaries.
virtual void ApplyEssentialBC(const std::string &test_var_name, mfem::ParGridFunction &trial_gf, mfem::Array< int > &global_ess_markers)
Apply essential BC(s) associated with test_var_name to set true DoFs of trial_gf and update markers o...
Moose::MFEM::NamedFieldsMap< mfem::ParLinearForm > _lfs
virtual void BuildBilinearForms() override
Build bilinear forms (diagonal Jacobian contributions)
Moose::MFEM::NamedFieldsMap< Moose::MFEM::NamedFieldsMap< std::vector< std::shared_ptr< MFEMKernel > > > > _kernels_map
Arrays to store kernels to act on each component of weak form.
T & GetRef(const std::string &field_name) const
Returns a reference to a field.
mfem::Operator & GetGradient(const mfem::Vector &u) const override
Compute J = M + grad_H(u)
virtual void FormSystem(mfem::OperatorHandle &op, mfem::BlockVector &trueX, mfem::BlockVector &trueRHS)
Moose::MFEM::NamedFieldsMap< mfem::ParBilinearForm > _blfs
virtual void AddIntegratedBC(std::shared_ptr< MFEMIntegratedBC > kernel)
auto index_range(const T &sizable)
const std::string & getTimeDerivativeName(const std::string &var_name) const