https://mooseframework.inl.gov
Loading...
Searching...
No Matches
EquationSystem.h
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#ifdef MOOSE_MFEM_ENABLED
11
12#pragma once
13
14#include "libmesh/ignore_warnings.h"
15#include "mfem/miniapps/common/pfem_extras.hpp"
16#include "libmesh/restore_warnings.h"
17#include "MFEMIntegratedBC.h"
18#include "MFEMEssentialBC.h"
19#include "MFEMContainers.h"
20#include "MFEMKernel.h"
22#include "ScaleIntegrator.h"
23#include "NLScaleIntegrator.h"
24
25namespace Moose::MFEM
26{
27class CoefficientManager;
28
44class EquationSystem : public mfem::Operator
45{
46
47public:
48 EquationSystem() = default;
49 ~EquationSystem() override;
50
52 virtual void AddKernel(std::shared_ptr<MFEMKernel> kernel);
53 virtual void AddIntegratedBC(std::shared_ptr<MFEMIntegratedBC> kernel);
55 virtual void AddEssentialBC(std::shared_ptr<MFEMEssentialBC> bc);
56
58 virtual void Init(GridFunctions & gridfunctions,
59 ComplexGridFunctions & cmplx_gridfunctions,
60 mfem::AssemblyLevel assembly_level);
72 void FormSystem(mfem::BlockVector & trueX, mfem::BlockVector & trueRHS);
74 void Mult(const mfem::Vector & u, mfem::Vector & residual) const override;
76 virtual void ComputeNonlinearResidual(const mfem::Vector & u, mfem::Vector & residual) const;
78 mfem::Operator & GetGradient(const mfem::Vector & u) const override;
80 mfem::OperatorHandle & GetLinearOperator() const { return _linear_operator; };
81
83 virtual void SetTrialVariablesFromTrueVectors(const mfem::BlockVector & trueX) const;
84
86 void SetGradientRequired(bool requires_gradient) { _gradient_required = requires_gradient; }
87
91 {
92 _coefficient_manager = &coefficients;
93 }
94
95 // Test variables are associated with linear forms,
96 // whereas trial variables are associated with gridfunctions.
97 const std::vector<std::string> & GetTrialVarNames() const { return _trial_var_names; }
98 const std::vector<std::string> & GetTestVarNames() const { return _test_var_names; }
99
101 const mfem::Array<int> & GetBlockOffsets() const { return _block_true_offsets; }
102
106 mfem::ParBilinearForm & GetBilinearForm(const std::string & test_var_name)
107 {
108 return _blfs.GetRef(test_var_name);
109 }
110
114 mfem::ParGridFunction & GetGridFunction(const std::string & trial_var_name)
115 {
116 return _gfuncs->GetRef(trial_var_name);
117 }
118
122 bool Nonlinear() const { return _non_linear; }
123
125 const mfem::Vector & GetLinearizationPoint() const;
126
131 std::shared_ptr<mfem::ParBilinearForm>
132 BuildBilinearFormForFESpace(const std::string & var_name,
133 mfem::ParFiniteElementSpace & fespace,
134 mfem::AssemblyLevel assembly_level);
135
140 std::shared_ptr<mfem::ParNonlinearForm>
141 BuildNonlinearFormForFESpace(const std::string & var_name,
142 mfem::ParFiniteElementSpace & fespace,
143 mfem::AssemblyLevel assembly_level);
144
149 mfem::Array<int> & GetEssentialBoundaryMarkers(const std::string & var_name);
150
152 virtual bool IsComplex() const { return false; }
154 virtual bool IsEigen() const { return false; }
156 virtual bool IsTimeDependent() const { return false; }
158 bool IsMultivariate() const { return _test_var_names.size() > 1; }
160 bool IsNonlinear() const { return _non_linear; }
161
163 virtual void BuildEquationSystem();
164
165protected:
167 virtual void AddCoupledVariableNameIfMissing(const std::string & coupled_var_name);
169 virtual void AddEliminatedVariableNameIfMissing(const std::string & eliminated_var_name);
171 virtual void AddTestVariableNameIfMissing(const std::string & test_var_name);
173 virtual void SetTrialVariableNames();
174
178 void DeleteHBlocks();
179
184
185 bool VectorContainsName(const std::vector<std::string> & the_vector,
186 const std::string & name) const;
187
190 virtual void ApplyEssentialBC(const std::string & var_name,
191 mfem::ParGridFunction & trial_gf,
192 mfem::Array<int> & global_ess_markers);
194 virtual void ApplyEssentialBCs();
196 virtual void EliminateCoupledVariables();
198 virtual void BuildLinearForms();
200 virtual void BuildNonlinearForms();
202 virtual void BuildBilinearForms();
204 virtual void BuildMixedBilinearForms();
205
208 virtual void FormLinearSystem(mfem::OperatorHandle & op,
209 mfem::BlockVector & trueX,
210 mfem::BlockVector & trueRHS);
211 using mfem::Operator::FormSystemOperator;
214 virtual void FormSystemOperator(mfem::OperatorHandle & op,
215 mfem::BlockVector & trueX,
216 mfem::BlockVector & trueRHS);
219 virtual void FormSystemMatrix(mfem::OperatorHandle & op,
220 mfem::BlockVector & trueX,
221 mfem::BlockVector & trueRHS);
223 void FormJacobianMatrix(const mfem::Vector & u);
224
229 template <class FormType>
231 const std::string & trial_var_name,
232 const std::string & test_var_name,
233 std::shared_ptr<FormType> form,
234 NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMKernel>>>> & kernels_map,
235 std::optional<mfem::real_t> scale_factor = std::nullopt);
236
242 const std::string & test_var_name,
243 std::shared_ptr<mfem::ParLinearForm> form,
244 NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMKernel>>>> & kernels_map);
245
251 const std::string & test_var_name,
252 std::shared_ptr<mfem::ParNonlinearForm> form,
253 NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMKernel>>>> & kernels_map,
254 std::optional<mfem::real_t> scale_factor = std::nullopt);
255
260 template <class FormType>
262 const std::string & trial_var_name,
263 const std::string & test_var_name,
264 std::shared_ptr<FormType> form,
265 NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMIntegratedBC>>>> &
266 integrated_bc_map,
267 std::optional<mfem::real_t> scale_factor = std::nullopt);
268
274 const std::string & test_var_name,
275 std::shared_ptr<mfem::ParLinearForm> form,
276 NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMIntegratedBC>>>> &
277 integrated_bc_map);
278
284 const std::string & test_var_name,
285 std::shared_ptr<mfem::ParNonlinearForm> form,
286 NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMIntegratedBC>>>> &
287 integrated_bc_map,
288 std::optional<mfem::real_t> scale_factor = std::nullopt);
289
292 std::vector<std::string> _coupled_var_names;
296 std::vector<std::string> _trial_var_names;
298 std::vector<std::string> _eliminated_var_names;
302 std::vector<std::string> _test_var_names;
304 std::vector<mfem::ParFiniteElementSpace *> _test_pfespaces;
306 std::vector<mfem::ParFiniteElementSpace *> _coupled_pfespaces;
307
308 // Components of weak form, named according to test variable
313
315 std::vector<std::unique_ptr<mfem::ParGridFunction>> _var_ess_constraints;
316 std::vector<mfem::Array<int>> _ess_tdof_lists;
317 std::vector<mfem::Array<int>> _ess_markers;
318
319 mfem::Array2D<const mfem::HypreParMatrix *> _h_blocks, _jacobian_blocks;
329
330 // Operator handle for the jacobian
331 mutable mfem::OperatorHandle _jacobian;
332 // Operator handle for the linear components of the system operator
333 mutable mfem::OperatorHandle _linear_operator;
334 mfem::AssemblyLevel _assembly_level;
335
336 // Pointer to GridFunctions to enable updates during nonlinear iterations
338 // Array storing block offsets of solution and residual vector
339 mfem::Array<int> _block_true_offsets;
340 // Non-owning pointer to the vector passed into the most recent GetGradient() call.
341 mutable const mfem::Vector * _linearization_point = nullptr;
342 // Boolean indicating if EquationSystem contains nonlinear integrators
343 bool _non_linear = false;
344 // Whether an external object (e.g. solver) requires Jacobian/gradient information.
345 bool _gradient_required = false;
346 // Coefficient manager notified when trial variables are updated, so that stored projections
347 // of solution-dependent coefficients are invalidated.
349
350private:
352 using mfem::Operator::RecoverFEMSolution;
353};
354
355template <class FormType>
356void
358 const std::string & trial_var_name,
359 const std::string & test_var_name,
360 std::shared_ptr<FormType> form,
361 NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMKernel>>>> & kernels_map,
362 std::optional<mfem::real_t> scale_factor)
363{
364 if (kernels_map.Has(test_var_name) && kernels_map.Get(test_var_name)->Has(trial_var_name))
365 {
366 auto kernels = kernels_map.GetRef(test_var_name).GetRef(trial_var_name);
367 for (auto & kernel : kernels)
368 {
369 mfem::BilinearFormIntegrator * integ = kernel->createBFIntegrator();
370
371 if (integ)
372 {
373 if (scale_factor.has_value())
374 integ = new ScaleIntegrator(integ, scale_factor.value(), true);
375 kernel->isDGKernel() ? form->AddInteriorFaceIntegrator(std::move(integ))
376 : kernel->isSubdomainRestricted()
377 ? form->AddDomainIntegrator(std::move(integ), kernel->getSubdomainMarkers())
378 : form->AddDomainIntegrator(std::move(integ));
379 }
380 }
381 }
382}
383
384template <class FormType>
385void
387 const std::string & trial_var_name,
388 const std::string & test_var_name,
389 std::shared_ptr<FormType> form,
390 NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMIntegratedBC>>>> &
391 integrated_bc_map,
392 std::optional<mfem::real_t> scale_factor)
393{
394 if (integrated_bc_map.Has(test_var_name) &&
395 integrated_bc_map.Get(test_var_name)->Has(trial_var_name))
396 {
397 auto bcs = integrated_bc_map.GetRef(test_var_name).GetRef(trial_var_name);
398 for (auto & bc : bcs)
399 {
400 mfem::BilinearFormIntegrator * integ = bc->createBFIntegrator();
401
402 if (integ)
403 {
404 if (scale_factor.has_value())
405 integ = new ScaleIntegrator(integ, scale_factor.value(), true);
406 bc->isDGBC() ? bc->isBoundaryRestricted()
407 ? form->AddBdrFaceIntegrator(std::move(integ), bc->getBoundaryMarkers())
408 : form->AddBdrFaceIntegrator(std::move(integ))
409 : bc->isBoundaryRestricted()
410 ? form->AddBoundaryIntegrator(std::move(integ), bc->getBoundaryMarkers())
411 : form->AddBoundaryIntegrator(std::move(integ));
412 }
413 }
414 }
415}
416
417} // namespace Moose::MFEM
418
419#endif
Front-end class for creating and storing MFEM coefficients.
Owns the weak-form mathematics of a MOOSE MFEM problem.
virtual void AddTestVariableNameIfMissing(const std::string &test_var_name)
Add test variable to EquationSystem.
void ApplyDomainBLFIntegrators(const std::string &trial_var_name, const std::string &test_var_name, std::shared_ptr< FormType > form, NamedFieldsMap< NamedFieldsMap< std::vector< std::shared_ptr< MFEMKernel > > > > &kernels_map, std::optional< mfem::real_t > scale_factor=std::nullopt)
Template method for applying BilinearFormIntegrators on domains from kernels to a BilinearForm,...
const std::vector< std::string > & GetTrialVarNames() const
const std::vector< std::string > & GetTestVarNames() const
std::shared_ptr< mfem::ParBilinearForm > BuildBilinearFormForFESpace(const std::string &var_name, mfem::ParFiniteElementSpace &fespace, mfem::AssemblyLevel assembly_level)
Build a fresh ParBilinearForm on the given FESpace using the same kernels as the main system's biline...
virtual void BuildBilinearForms()
Build bilinear forms (diagonal Jacobian contributions)
virtual void BuildNonlinearForms()
Build non-linear action forms.
std::vector< std::string > _coupled_var_names
Names of all trial variables of kernels and boundary conditions added to this EquationSystem.
virtual void ApplyEssentialBCs()
Update all essentially constrained true DoF markers and values on boundaries.
std::vector< mfem::ParFiniteElementSpace * > _test_pfespaces
Pointers to finite element spaces associated with test variables.
mfem::Array< int > _block_true_offsets
void FormSystem(mfem::BlockVector &trueX, mfem::BlockVector &trueRHS)
Build all weak-form components via BuildEquationSystem(), form the constrained linear part of the sys...
void SetCoefficientManager(CoefficientManager &coefficients)
Set the coefficient manager to notify when trial variables are updated, so that stored projections of...
NamedFieldsMap< NamedFieldsMap< std::vector< std::shared_ptr< MFEMKernel > > > > _kernels_map
Arrays to store kernels to act on each component of weak form.
std::vector< mfem::ParFiniteElementSpace * > _coupled_pfespaces
Pointers to finite element spaces associated with coupled variables.
bool VectorContainsName(const std::vector< std::string > &the_vector, const std::string &name) const
const mfem::Array< int > & GetBlockOffsets() const
Getter for block true offsets associated with the EquationSystem operator.
void ApplyDomainNLFIntegrators(const std::string &test_var_name, std::shared_ptr< mfem::ParNonlinearForm > form, NamedFieldsMap< NamedFieldsMap< std::vector< std::shared_ptr< MFEMKernel > > > > &kernels_map, std::optional< mfem::real_t > scale_factor=std::nullopt)
Apply domain NonlinearFormIntegrators from kernels to the nonlinear form associated with the supplied...
virtual void ApplyEssentialBC(const std::string &var_name, mfem::ParGridFunction &trial_gf, mfem::Array< int > &global_ess_markers)
Apply essential BC(s) associated with var_name to set true DoFs of trial_gf and update markers of all...
virtual void EliminateCoupledVariables()
Perform trivial eliminations of coupled variables lacking corresponding test variables.
virtual void BuildEquationSystem()
Build all forms comprising this EquationSystem.
mfem::Operator & GetGradient(const mfem::Vector &u) const override
Get Jacobian at the provided vector of true DoFs of trial variables.
virtual void BuildMixedBilinearForms()
Build mixed bilinear forms (off-diagonal Jacobian contributions)
void ApplyBoundaryBLFIntegrators(const std::string &trial_var_name, const std::string &test_var_name, std::shared_ptr< FormType > form, NamedFieldsMap< NamedFieldsMap< std::vector< std::shared_ptr< MFEMIntegratedBC > > > > &integrated_bc_map, std::optional< mfem::real_t > scale_factor=std::nullopt)
Template method for applying BilinearFormIntegrators on boundaries from integrated boundary condition...
mfem::Array2D< const mfem::HypreParMatrix * > _h_blocks
mfem::OperatorHandle & GetLinearOperator() const
Get operator handle for linear component of system operator.
void ApplyBoundaryLFIntegrators(const std::string &test_var_name, std::shared_ptr< mfem::ParLinearForm > form, NamedFieldsMap< NamedFieldsMap< std::vector< std::shared_ptr< MFEMIntegratedBC > > > > &integrated_bc_map)
Apply boundary LinearFormIntegrators from integrated boundary conditions to the linear form associate...
std::vector< std::string > _test_var_names
Names of all test variables corresponding to linear forms in this equation system.
void FormJacobianMatrix(const mfem::Vector &u)
Compute Jacobian matrix at the provided vector of true DoFs of trial variables.
virtual void FormSystemOperator(mfem::OperatorHandle &op, mfem::BlockVector &trueX, mfem::BlockVector &trueRHS)
Form matrix-free representation of linear components of system operator.
mfem::Array< int > & GetEssentialBoundaryMarkers(const std::string &var_name)
Return the essential boundary attribute marker array for a given trial variable.
void ApplyBoundaryNLFIntegrators(const std::string &test_var_name, std::shared_ptr< mfem::ParNonlinearForm > form, NamedFieldsMap< NamedFieldsMap< std::vector< std::shared_ptr< MFEMIntegratedBC > > > > &integrated_bc_map, std::optional< mfem::real_t > scale_factor=std::nullopt)
Apply boundary NonlinearFormIntegrators from integrated boundary conditions to the nonlinear form ass...
mfem::OperatorHandle _linear_operator
const mfem::Vector * _linearization_point
std::shared_ptr< mfem::ParNonlinearForm > BuildNonlinearFormForFESpace(const std::string &var_name, mfem::ParFiniteElementSpace &fespace, mfem::AssemblyLevel assembly_level)
Build a fresh ParNonlinearForm on the given FESpace using the same kernels as the main system's nonli...
NamedFieldsMap< mfem::ParLinearForm > _lfs
virtual void AddIntegratedBC(std::shared_ptr< MFEMIntegratedBC > kernel)
mfem::AssemblyLevel _assembly_level
virtual void AddKernel(std::shared_ptr< MFEMKernel > kernel)
Add kernels.
virtual void SetTrialVariableNames()
Set trial variable names from subset of coupled variables that have an associated test variable.
mfem::ParGridFunction & GetGridFunction(const std::string &trial_var_name)
mfem::Array2D< const mfem::HypreParMatrix * > _jacobian_blocks
virtual void FormSystemMatrix(mfem::OperatorHandle &op, mfem::BlockVector &trueX, mfem::BlockVector &trueRHS)
Form matrix representation of linear components of system operator as a HypreParMatrix.
std::vector< mfem::Array< int > > _ess_tdof_lists
CoefficientManager * _coefficient_manager
virtual void SetTrialVariablesFromTrueVectors(const mfem::BlockVector &trueX) const
Update variable from solution vector after solve.
virtual void AddEssentialBC(std::shared_ptr< MFEMEssentialBC > bc)
Add BC associated with essentially constrained DoFs on boundaries.
NamedFieldsMap< mfem::ParBilinearForm > _blfs
void DeleteHBlocks()
Deletes the HypreParMatrix associated with any pointer stored in _h_blocks, and then proceeds to dele...
virtual void ComputeNonlinearResidual(const mfem::Vector &u, mfem::Vector &residual) const
Compute the contribution to the residual from nonlinear forms only.
mfem::OperatorHandle _jacobian
virtual void FormLinearSystem(mfem::OperatorHandle &op, mfem::BlockVector &trueX, mfem::BlockVector &trueRHS)
Form linear components of system based on on- and off-diagonal bilinear form contributions,...
mfem::ParBilinearForm & GetBilinearForm(const std::string &test_var_name)
NamedFieldsMap< std::vector< std::shared_ptr< MFEMEssentialBC > > > _essential_bc_map
Arrays to store essential BCs to act on each component of weak form.
virtual void Init(GridFunctions &gridfunctions, ComplexGridFunctions &cmplx_gridfunctions, mfem::AssemblyLevel assembly_level)
Initialise.
std::vector< std::string > _trial_var_names
Subset of _coupled_var_names of all variables corresponding to gridfunctions with degrees of freedom ...
NamedFieldsMap< NamedFieldsMap< mfem::ParMixedBilinearForm > > _mblfs
std::vector< std::unique_ptr< mfem::ParGridFunction > > _var_ess_constraints
Gridfunctions holding essential constraints from Dirichlet BCs.
void DeleteJacobianBlocks()
Deletes the HypreParMatrix associated with any pointer stored in _jacobian_blocks,...
void ApplyDomainLFIntegrators(const std::string &test_var_name, std::shared_ptr< mfem::ParLinearForm > form, NamedFieldsMap< NamedFieldsMap< std::vector< std::shared_ptr< MFEMKernel > > > > &kernels_map)
Apply domain LinearFormIntegrators from kernels to the linear form associated with the supplied test ...
virtual void AddEliminatedVariableNameIfMissing(const std::string &eliminated_var_name)
Add eliminated variable to EquationSystem.
void Mult(const mfem::Vector &u, mfem::Vector &residual) const override
Compute residual y = Mu.
NamedFieldsMap< mfem::ParNonlinearForm > _nlfs
Moose::MFEM::GridFunctions _eliminated_variables
Pointers to coupled variables not part of the reduced EquationSystem.
const mfem::Vector & GetLinearizationPoint() const
The true-DoF vector used for the most recent Jacobian linearization.
std::vector< mfem::Array< int > > _ess_markers
void SetGradientRequired(bool requires_gradient)
Set whether an external object (such as a nonlinear solver) requires Jacobian information for this Eq...
std::vector< std::string > _eliminated_var_names
Names of all coupled variables without a corresponding test variable.
virtual bool IsComplex() const
Moose::MFEM::GridFunctions * _gfuncs
virtual bool IsEigen() const
virtual void BuildLinearForms()
Build linear forms and eliminate constrained DoFs.
virtual void AddCoupledVariableNameIfMissing(const std::string &coupled_var_name)
Add coupled variable to EquationSystem.
virtual bool IsTimeDependent() const
NamedFieldsMap< NamedFieldsMap< std::vector< std::shared_ptr< MFEMIntegratedBC > > > > _integrated_bc_map
Arrays to store integrated BCs to act on each component of weak form.
T & GetRef(const std::string &field_name) const
Returns a reference to a field.
Integrator which scales its results by a constant value.
Utilities for converting between vector(s) of libMesh Points and MFEM Vector(s).