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());
62 auto trial_var_name = kernel->getTrialVariableName();
63 auto test_var_name = kernel->getTestVariableName();
66 auto kernel_field_map =
67 std::make_shared<Moose::MFEM::NamedFieldsMap<std::vector<std::shared_ptr<MFEMKernel>>>>();
74 auto kernels = std::make_shared<std::vector<std::shared_ptr<MFEMKernel>>>();
75 _kernels_map.
Get(test_var_name)->Register(trial_var_name, std::move(kernels));
85 auto trial_var_name = bc->getTrialVariableName();
86 auto test_var_name = bc->getTestVariableName();
89 auto integrated_bc_field_map = std::make_shared<
97 auto bcs = std::make_shared<std::vector<std::shared_ptr<MFEMIntegratedBC>>>();
107 auto test_var_name = bc->getTestVariableName();
110 auto bcs = std::make_shared<std::vector<std::shared_ptr<MFEMEssentialBC>>>();
128 mfem::ParGridFunction & trial_gf(*(
_xs.at(i)));
130 mooseAssert(pmesh,
"parallel mesh is null");
133 mfem::Array<int> global_ess_markers(pmesh->bdr_attributes.Max());
134 global_ess_markers = 0;
135 for (
auto & bc : bcs)
137 bc->ApplyBC(trial_gf);
139 mfem::Array<int> ess_bdrs(bc->getBoundaryMarkers());
140 for (
auto it = 0; it != pmesh->bdr_attributes.Max(); ++it)
142 global_ess_markers[it] =
std::max(global_ess_markers[it], ess_bdrs[it]);
145 trial_gf.FESpace()->GetEssentialTrueDofs(global_ess_markers,
_ess_tdof_lists.at(i));
151 mfem::BlockVector & trueX,
152 mfem::BlockVector & trueRHS)
157 case mfem::AssemblyLevel::LEGACY:
162 "Non-legacy assembly is only supported for single-variable systems");
165 "Non-legacy assembly is only supported for single test and trial variable systems");
172 mfem::BlockVector & trueX,
173 mfem::BlockVector & trueRHS)
176 auto blf =
_blfs.
Get(test_var_name);
177 auto lf =
_lfs.
Get(test_var_name);
178 mfem::BlockVector aux_x, aux_rhs;
179 mfem::OperatorPtr aux_a;
181 blf->FormLinearSystem(
_ess_tdof_lists.at(0), *(
_xs.at(0)), *lf, aux_a, aux_x, aux_rhs);
183 trueX.GetBlock(0) = aux_x;
184 trueRHS.GetBlock(0) = aux_rhs;
185 trueX.SyncFromBlocks();
186 trueRHS.SyncFromBlocks();
188 op.Reset(aux_a.Ptr());
189 aux_a.SetOperatorOwner(
false);
194 mfem::BlockVector & trueX,
195 mfem::BlockVector & trueRHS)
205 auto blf =
_blfs.
Get(test_var_name);
206 auto lf =
_lfs.
Get(test_var_name);
207 mfem::Vector aux_x, aux_rhs;
208 mfem::HypreParMatrix * aux_a =
new mfem::HypreParMatrix;
209 blf->FormLinearSystem(
_ess_tdof_lists.at(i), *(
_xs.at(i)), *lf, *aux_a, aux_x, aux_rhs);
211 trueX.GetBlock(i) = aux_x;
212 trueRHS.GetBlock(i) = aux_rhs;
223 mfem::Vector aux_x, aux_rhs;
228 auto mblf =
_mblfs.
Get(test_var_name)->Get(trial_var_name);
229 mfem::HypreParMatrix * aux_a =
new mfem::HypreParMatrix;
238 trueRHS.GetBlock(i) += aux_rhs;
245 trueX.GetBlock(i).SyncAliasMemory(trueX);
246 trueRHS.GetBlock(i).SyncAliasMemory(trueRHS);
250 op.Reset(mfem::HypreParMatrixFromBlocks(
_h_blocks));
256 height = trueX.Size();
257 width = trueRHS.Size();
282 trueX.GetBlock(i).SyncAliasMemory(trueX);
283 gridfunctions.
Get(trial_var_name)->Distribute(&(trueX.GetBlock(i)));
290 mfem::AssemblyLevel assembly_level)
296 if (!gridfunctions.
Has(test_var_name))
298 MFEM_ABORT(
"Test variable " << test_var_name
299 <<
" requested by equation system during initialisation was " 300 "not found in gridfunctions");
306 std::make_unique<mfem::ParGridFunction>(gridfunctions.
Get(test_var_name)->ParFESpace()));
308 std::make_unique<mfem::ParGridFunction>(gridfunctions.
Get(test_var_name)->ParFESpace()));
348 ApplyBoundaryBLFIntegrators<mfem::ParBilinearForm>(
350 ApplyDomainBLFIntegrators<mfem::ParBilinearForm>(
367 auto test_mblfs = std::make_shared<Moose::MFEM::NamedFieldsMap<mfem::ParMixedBilinearForm>>();
371 auto mblf = std::make_shared<mfem::ParMixedBilinearForm>(
_test_pfespaces.at(j),
376 test_var_name != trial_var_name)
380 ApplyDomainBLFIntegrators<mfem::ParMixedBilinearForm>(
386 test_mblfs->Register(trial_var_name, mblf);
422 if (fabs(dt -
_dt_coef.constant) > 1.0e-12 * dt)
427 auto blf =
_blfs.
Get(test_var_name);
439 auto trial_var_name = kernel->getTrialVariableName();
440 auto test_var_name = kernel->getTestVariableName();
445 auto kernel_field_map =
446 std::make_shared<Moose::MFEM::NamedFieldsMap<std::vector<std::shared_ptr<MFEMKernel>>>>();
452 auto kernels = std::make_shared<std::vector<std::shared_ptr<MFEMKernel>>>();
479 ApplyBoundaryBLFIntegrators<mfem::ParBilinearForm>(
481 ApplyDomainBLFIntegrators<mfem::ParBilinearForm>(
486 auto blf =
_blfs.
Get(test_var_name);
487 auto integs = blf->GetDBFI();
488 auto b_integs = blf->GetBBFI();
489 auto markers = blf->GetBBFI_Marker();
491 mfem::SumIntegrator * sum =
new mfem::SumIntegrator(
false);
494 for (
int i = 0; i < integs->Size(); ++i)
496 sum->AddIntegrator(*integs[i]);
499 for (
int i = 0; i < b_integs->Size(); ++i)
506 td_blf->AddDomainIntegrator(scaled_sum);
515 mfem::BlockVector & truedXdt,
516 mfem::BlockVector & trueRHS)
527 auto blf =
_blfs.
Get(test_var_name);
528 auto lf =
_lfs.
Get(test_var_name);
533 mfem::Vector aux_x, aux_rhs;
535 mfem::Vector bc_x = *(
_xs.at(i).get());
540 mfem::HypreParMatrix * aux_a =
new mfem::HypreParMatrix;
541 td_blf->FormLinearSystem(
_ess_tdof_lists.at(i), bc_x, *lf, *aux_a, aux_x, aux_rhs);
543 truedXdt.GetBlock(i) = aux_x;
544 trueRHS.GetBlock(i) = aux_rhs;
547 truedXdt.SyncFromBlocks();
548 trueRHS.SyncFromBlocks();
551 op.Reset(mfem::HypreParMatrixFromBlocks(
_h_blocks));
556 mfem::BlockVector & truedXdt,
557 mfem::BlockVector & trueRHS)
561 auto blf =
_blfs.
Get(test_var_name);
562 auto lf =
_lfs.
Get(test_var_name);
567 mfem::Vector lf_prev(lf->Size());
571 mfem::Vector aux_x, aux_rhs;
573 mfem::Vector bc_x = *(
_xs.at(0).get());
578 mfem::OperatorPtr aux_a;
579 td_blf->FormLinearSystem(
_ess_tdof_lists.at(0), bc_x, *lf, aux_a, aux_x, aux_rhs);
581 truedXdt.GetBlock(0) = aux_x;
582 trueRHS.GetBlock(0) = aux_rhs;
583 truedXdt.SyncFromBlocks();
584 trueRHS.SyncFromBlocks();
587 op.Reset(aux_a.Ptr());
588 aux_a.SetOperatorOwner(
false);
std::string name(const ElemQuality q)
mfem::ConstantCoefficient _dt_coef
virtual void AddKernel(std::shared_ptr< MFEMKernel > kernel) override
virtual void AddTestVariableNameIfMissing(const std::string &test_var_name)
virtual void AddKernel(std::shared_ptr< MFEMKernel > kernel)
virtual void RecoverFEMSolution(mfem::BlockVector &trueX, Moose::MFEM::GridFunctions &gridfunctions)
virtual void BuildBilinearForms()
bool Has(const std::string &field_name) const
Predicate to check if a field is registered with name field_name.
Moose::MFEM::NamedFieldsMap< Moose::MFEM::NamedFieldsMap< std::vector< std::shared_ptr< MFEMKernel > > > > _td_kernels_map
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::unique_ptr< mfem::ParGridFunction > > _xs
virtual void UpdateEquationSystem()
~EquationSystem() override
Moose::MFEM::NamedFieldsMap< Moose::MFEM::NamedFieldsMap< mfem::ParMixedBilinearForm > > _mblfs
std::vector< std::unique_ptr< mfem::ParGridFunction > > _dxdts
TimeDependentEquationSystem()
virtual void AddEssentialBC(std::shared_ptr< MFEMEssentialBC > bc)
std::vector< mfem::Array< int > > _ess_tdof_lists
Lightweight adaptor over an std::map from strings to pointer to T.
mfem::AssemblyLevel _assembly_level
void AddTrialVariableNameIfMissing(const std::string &trial_var_name) override
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
std::vector< mfem::ParFiniteElementSpace * > _test_pfespaces
void Mult(const mfem::Vector &u, mfem::Vector &residual) const override
Compute residual y = Mu.
std::vector< std::string > _trial_var_names
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...
mfem::OperatorHandle _jacobian
virtual void AddTrialVariableNameIfMissing(const std::string &trial_var_name)
std::vector< std::string > _test_var_names
virtual void BuildEquationSystem()
virtual void Init(Moose::MFEM::GridFunctions &gridfunctions, const Moose::MFEM::FESpaces &fespaces, mfem::AssemblyLevel assembly_level)
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 FormLinearSystem(mfem::OperatorHandle &op, mfem::BlockVector &trueX, mfem::BlockVector &trueRHS)
void Register(const std::string &field_name, FieldArgs &&... args)
Construct new field with name field_name and register.
std::vector< std::string > _trial_var_time_derivative_names
Moose::MFEM::NamedFieldsMap< Moose::MFEM::NamedFieldsMap< std::vector< std::shared_ptr< MFEMIntegratedBC > > > > _integrated_bc_map
Moose::MFEM::NamedFieldsMap< mfem::ParBilinearForm > _td_blfs
Moose::MFEM::GridFunctions _trial_variables
virtual void BuildLinearForms()
IntRange< T > make_range(T beg, T end)
virtual void BuildJacobian(mfem::BlockVector &trueX, mfem::BlockVector &trueRHS)
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
Moose::MFEM::NamedFieldsMap< Moose::MFEM::NamedFieldsMap< std::vector< std::shared_ptr< MFEMKernel > > > > _kernels_map
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)