10 #ifdef MOOSE_MFEM_ENABLED 13 #include "libmesh/int_range.h" 31 const std::string & name)
const 34 auto iter = std::find(the_vector.begin(), the_vector.end(),
name);
36 return (iter != the_vector.end());
72 auto trial_var_name = kernel->getTrialVariableName();
73 auto test_var_name = kernel->getTestVariableName();
76 auto kernel_field_map =
77 std::make_shared<Moose::MFEM::NamedFieldsMap<std::vector<std::shared_ptr<MFEMKernel>>>>();
84 auto kernels = std::make_shared<std::vector<std::shared_ptr<MFEMKernel>>>();
85 _kernels_map.
Get(test_var_name)->Register(trial_var_name, std::move(kernels));
95 auto trial_var_name = bc->getTrialVariableName();
96 auto test_var_name = bc->getTestVariableName();
99 auto integrated_bc_field_map = std::make_shared<
107 auto bcs = std::make_shared<std::vector<std::shared_ptr<MFEMIntegratedBC>>>();
117 auto test_var_name = bc->getTestVariableName();
120 auto bcs = std::make_shared<std::vector<std::shared_ptr<MFEMEssentialBC>>>();
129 mfem::AssemblyLevel assembly_level)
135 if (!gridfunctions.
Has(test_var_name))
139 " requested by equation system during initialisation was " 140 "not found in gridfunctions");
146 std::make_unique<mfem::ParGridFunction>(gridfunctions.
Get(test_var_name)->ParFESpace()));
160 gridfunctions.
GetShared(eliminated_var_name));
177 mooseAssert(pmesh,
"parallel mesh is null");
180 mfem::Array<int> global_ess_markers(pmesh->bdr_attributes.Max());
181 global_ess_markers = 0;
182 for (
auto & bc : bcs)
184 bc->ApplyBC(trial_gf);
186 mfem::Array<int> ess_bdrs(bc->getBoundaryMarkers());
187 for (
auto it = 0; it != pmesh->bdr_attributes.Max(); ++it)
189 global_ess_markers[it] =
std::max(global_ess_markers[it], ess_bdrs[it]);
192 trial_gf.FESpace()->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);
215 mfem::BlockVector & trueX,
216 mfem::BlockVector & trueRHS)
221 case mfem::AssemblyLevel::LEGACY:
226 "Non-legacy assembly is only supported for single-variable systems");
229 "Non-legacy assembly is only supported for single test and trial variable systems");
236 mfem::BlockVector & trueX,
237 mfem::BlockVector & trueRHS)
240 auto blf =
_blfs.
Get(test_var_name);
241 auto lf =
_lfs.
Get(test_var_name);
242 mfem::BlockVector aux_x, aux_rhs;
243 mfem::OperatorPtr aux_a;
245 blf->FormLinearSystem(
248 trueX.GetBlock(0) = aux_x;
249 trueRHS.GetBlock(0) = aux_rhs;
250 trueX.SyncFromBlocks();
251 trueRHS.SyncFromBlocks();
253 op.Reset(aux_a.Ptr());
254 aux_a.SetOperatorOwner(
false);
259 mfem::BlockVector & trueX,
260 mfem::BlockVector & trueRHS)
270 auto blf =
_blfs.
Get(test_var_name);
271 auto lf =
_lfs.
Get(test_var_name);
272 mfem::Vector aux_x, aux_rhs;
273 mfem::HypreParMatrix * aux_a =
new mfem::HypreParMatrix;
274 blf->FormLinearSystem(
277 trueX.GetBlock(i) = aux_x;
278 trueRHS.GetBlock(i) = aux_rhs;
289 mfem::Vector aux_x, aux_rhs;
294 auto mblf =
_mblfs.
Get(test_var_name)->Get(trial_var_name);
295 mfem::HypreParMatrix * aux_a =
new mfem::HypreParMatrix;
304 trueRHS.GetBlock(i) += aux_rhs;
311 trueX.GetBlock(i).SyncAliasMemory(trueX);
312 trueRHS.GetBlock(i).SyncAliasMemory(trueRHS);
316 op.Reset(mfem::HypreParMatrixFromBlocks(
_h_blocks));
322 height = trueX.Size();
323 width = trueRHS.Size();
348 trueX.GetBlock(i).SyncAliasMemory(trueX);
349 gridfunctions.
Get(trial_var_name)->Distribute(&(trueX.GetBlock(i)));
392 ApplyBoundaryBLFIntegrators<mfem::ParBilinearForm>(
394 ApplyDomainBLFIntegrators<mfem::ParBilinearForm>(
411 auto test_mblfs = std::make_shared<Moose::MFEM::NamedFieldsMap<mfem::ParMixedBilinearForm>>();
421 test_var_name != coupled_var_name)
425 ApplyDomainBLFIntegrators<mfem::ParMixedBilinearForm>(
431 test_mblfs->Register(coupled_var_name, mblf);
464 if (fabs(dt -
_dt_coef.constant) > 1.0e-12 * dt)
469 auto blf =
_blfs.
Get(test_var_name);
486 if (time_derivative_test_var_name == coupled_var_name)
505 auto trial_var_name = kernel->getTrialVariableName();
506 auto test_var_name = kernel->getTestVariableName();
512 auto kernel_field_map =
513 std::make_shared<Moose::MFEM::NamedFieldsMap<std::vector<std::shared_ptr<MFEMKernel>>>>();
519 auto kernels = std::make_shared<std::vector<std::shared_ptr<MFEMKernel>>>();
546 ApplyBoundaryBLFIntegrators<mfem::ParBilinearForm>(
548 ApplyDomainBLFIntegrators<mfem::ParBilinearForm>(
553 auto blf =
_blfs.
Get(test_var_name);
554 auto integs = blf->GetDBFI();
555 auto b_integs = blf->GetBBFI();
556 auto markers = blf->GetBBFI_Marker();
559 if (integs->Size() || b_integs->Size())
561 mfem::SumIntegrator * sum =
new mfem::SumIntegrator(
false);
564 for (
int i = 0; i < integs->Size(); ++i)
565 sum->AddIntegrator(*integs[i]);
567 for (
int i = 0; i < b_integs->Size(); ++i)
572 td_blf->AddDomainIntegrator(scaled_sum);
582 mfem::BlockVector & truedXdt,
583 mfem::BlockVector & trueRHS)
594 auto blf =
_blfs.
Get(test_var_name);
595 auto lf =
_lfs.
Get(test_var_name);
600 mfem::Vector aux_x, aux_rhs;
607 mfem::HypreParMatrix * aux_a =
new mfem::HypreParMatrix;
608 td_blf->FormLinearSystem(
_ess_tdof_lists.at(i), bc_x, *lf, *aux_a, aux_x, aux_rhs);
610 truedXdt.GetBlock(i) = aux_x;
611 trueRHS.GetBlock(i) = aux_rhs;
614 truedXdt.SyncFromBlocks();
615 trueRHS.SyncFromBlocks();
618 op.Reset(mfem::HypreParMatrixFromBlocks(
_h_blocks));
623 mfem::BlockVector & truedXdt,
624 mfem::BlockVector & trueRHS)
628 auto blf =
_blfs.
Get(test_var_name);
629 auto lf =
_lfs.
Get(test_var_name);
634 mfem::Vector lf_prev(lf->Size());
638 mfem::Vector aux_x, aux_rhs;
645 mfem::OperatorPtr aux_a;
646 td_blf->FormLinearSystem(
_ess_tdof_lists.at(0), bc_x, *lf, aux_a, aux_x, aux_rhs);
648 truedXdt.GetBlock(0) = aux_x;
649 trueRHS.GetBlock(0) = aux_rhs;
650 truedXdt.SyncFromBlocks();
651 trueRHS.SyncFromBlocks();
654 op.Reset(aux_a.Ptr());
655 aux_a.SetOperatorOwner(
false);
std::string name(const ElemQuality q)
mfem::ConstantCoefficient _dt_coef
Coefficient for timestep scaling.
virtual void EliminateCoupledVariables()
virtual void AddKernel(std::shared_ptr< MFEMKernel > kernel) override
Add kernels.
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.
bool Has(const std::string &field_name) const
Predicate to check if a field is registered with name field_name.
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
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
TimeDependentEquationSystem()
Moose::MFEM::GridFunctions _eliminated_variables
Pointers to coupled variables not part of the reduced EquationSystem.
virtual void AddEssentialBC(std::shared_ptr< MFEMEssentialBC > bc)
void AddCoupledVariableNameIfMissing(const std::string &coupled_var_name) override
Add coupled variable to EquationSystem.
std::vector< mfem::Array< int > > _ess_tdof_lists
Lightweight adaptor over an std::map from strings to pointer to T.
mfem::AssemblyLevel _assembly_level
std::string GetTimeDerivativeName(std::string name)
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.
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 ...
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 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
std::vector< std::string > _test_var_names
Names of all test variables corresponding to linear forms in this equation system.
virtual void BuildEquationSystem()
std::vector< std::unique_ptr< mfem::ParGridFunction > > _var_ess_constraints
Gridfunctions holding essential constraints from Dirichlet BCs.
virtual void Init(Moose::MFEM::GridFunctions &gridfunctions, const Moose::MFEM::FESpaces &fespaces, mfem::AssemblyLevel assembly_level)
Initialise.
virtual void FormLegacySystem(mfem::OperatorHandle &op, mfem::BlockVector &truedXdt, mfem::BlockVector &trueRHS) override
virtual void BuildMixedBilinearForms()
Integrator which scales its results by a constant value.
mfem::Array2D< const mfem::HypreParMatrix * > _h_blocks
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
Container 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)
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()
Moose::MFEM::NamedFieldsMap< mfem::ParLinearForm > _lfs
virtual void BuildBilinearForms() override
Build bilinear forms.
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.
virtual void SetTimeStep(double dt)
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)