https://mooseframework.inl.gov
ComplexEquationSystem.h
Go to the documentation of this file.
1 #ifdef MOOSE_MFEM_ENABLED
2 
3 #pragma once
4 
5 #include "libmesh/ignore_warnings.h"
6 #include "mfem/miniapps/common/pfem_extras.hpp"
7 #include "libmesh/restore_warnings.h"
8 #include "EquationSystem.h"
9 #include "MFEMComplexKernel.h"
11 #include "MFEMComplexEssentialBC.h"
12 
13 namespace Moose::MFEM
14 {
15 /*
16 Class to store weak form components (bilinear and linear forms, and optionally
17 mixed and nonlinear forms) and build methods
18 */
20 {
21 public:
22  ComplexEquationSystem() = default;
23  ~ComplexEquationSystem() = default;
24 
25  // Build forms
26  virtual void Init(GridFunctions & gridfunctions,
27  ComplexGridFunctions & cmplx_gridfunctions,
28  mfem::AssemblyLevel assembly_level) override;
29 
31  virtual void Mult(const mfem::Vector & x, mfem::Vector & y) const override;
32 
34  virtual void BuildEquationSystem() override;
35 
37  virtual void BuildLinearForms() override;
38 
40  virtual void BuildBilinearForms() override;
41 
44  virtual void ApplyComplexEssentialBC(const std::string & var_name,
45  mfem::ParComplexGridFunction & trial_gf,
46  mfem::Array<int> & global_ess_markers);
48  virtual void ApplyEssentialBCs() override;
49 
51  void AddComplexKernel(std::shared_ptr<MFEMComplexKernel> kernel);
52 
54  void AddComplexIntegratedBC(std::shared_ptr<MFEMComplexIntegratedBC> bc);
55 
57  void AddComplexEssentialBCs(std::shared_ptr<MFEMComplexEssentialBC> bc);
58 
61  virtual void FormSystemOperator(mfem::OperatorHandle & op,
62  mfem::BlockVector & trueX,
63  mfem::BlockVector & trueRHS) override;
64 
67  virtual void FormSystemMatrix(mfem::OperatorHandle & op,
68  mfem::BlockVector & trueX,
69  mfem::BlockVector & trueRHS) override;
70 
72  virtual void SetTrialVariablesFromTrueVectors(const mfem::BlockVector & trueX) const override;
73 
75  template <class FormType>
77  const std::string & trial_var_name,
78  const std::string & test_var_name,
79  std::shared_ptr<FormType> form,
80  NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexKernel>>>> &
81  kernels_map);
82 
84  inline void ApplyDomainLFIntegrators(
85  const std::string & test_var_name,
86  std::shared_ptr<mfem::ParComplexLinearForm> form,
87  NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexKernel>>>> &
88  kernels_map);
89 
91  template <class FormType>
93  const std::string & trial_var_name,
94  const std::string & test_var_name,
95  std::shared_ptr<FormType> form,
96  NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexIntegratedBC>>>> &
97  integrated_bc_map);
98 
100  inline void ApplyBoundaryLFIntegrators(
101  const std::string & test_var_name,
102  std::shared_ptr<mfem::ParComplexLinearForm> form,
103  NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexIntegratedBC>>>> &
104  integrated_bc_map);
105 
106  bool IsComplex() const override { return true; }
107 
108 protected:
109  // Complex Linear and Bilinear Forms
112 
113  // Complex kernels and integrated BCs
118 
119  // Complex essential BCs
121 
124 
126  std::vector<std::unique_ptr<mfem::ParComplexGridFunction>> _cmplx_var_ess_constraints;
127 
128  // Pointer to complex GridFunctions to enable updates during nonlinear iterations
130 };
131 
132 template <class FormType>
133 void
135  const std::string & trial_var_name,
136  const std::string & test_var_name,
137  std::shared_ptr<FormType> form,
138  NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexKernel>>>> & kernels_map)
139 {
140  if (kernels_map.Has(test_var_name) && kernels_map.Get(test_var_name)->Has(trial_var_name))
141  {
142  auto kernels = kernels_map.GetRef(test_var_name).GetRef(trial_var_name);
143  for (auto & kernel : kernels)
144  {
145  mfem::BilinearFormIntegrator * integ_real = kernel->getRealBFIntegrator();
146  mfem::BilinearFormIntegrator * integ_imag = kernel->getImagBFIntegrator();
147 
148  if (integ_real || integ_imag)
149  {
150  kernel->isSubdomainRestricted()
151  ? form->AddDomainIntegrator(
152  std::move(integ_real), std::move(integ_imag), kernel->getSubdomainMarkers())
153  : form->AddDomainIntegrator(std::move(integ_real), std::move(integ_imag));
154  }
155  }
156  }
157 }
158 
159 inline void
161  const std::string & test_var_name,
162  std::shared_ptr<mfem::ParComplexLinearForm> form,
163  NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexKernel>>>> & kernels_map)
164 {
165  if (kernels_map.Has(test_var_name))
166  {
167  auto kernels = kernels_map.GetRef(test_var_name).GetRef(test_var_name);
168  for (auto & kernel : kernels)
169  {
170  mfem::LinearFormIntegrator * integ_real = kernel->getRealLFIntegrator();
171  mfem::LinearFormIntegrator * integ_imag = kernel->getImagLFIntegrator();
172 
173  if (integ_real || integ_imag)
174  {
175  kernel->isSubdomainRestricted()
176  ? form->AddDomainIntegrator(
177  std::move(integ_real), std::move(integ_imag), kernel->getSubdomainMarkers())
178  : form->AddDomainIntegrator(std::move(integ_real), std::move(integ_imag));
179  }
180  }
181  }
182 }
183 
184 template <class FormType>
185 void
187  const std::string & trial_var_name,
188  const std::string & test_var_name,
189  std::shared_ptr<FormType> form,
190  NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexIntegratedBC>>>> &
191  integrated_bc_map)
192 {
193  if (integrated_bc_map.Has(test_var_name) &&
194  integrated_bc_map.Get(test_var_name)->Has(trial_var_name))
195  {
196  auto bcs = integrated_bc_map.GetRef(test_var_name).GetRef(trial_var_name);
197  for (auto & bc : bcs)
198  {
199  mfem::BilinearFormIntegrator * integ_real = bc->getRealBFIntegrator();
200  mfem::BilinearFormIntegrator * integ_imag = bc->getImagBFIntegrator();
201 
202  if (integ_real || integ_imag)
203  {
204  bc->isBoundaryRestricted()
205  ? form->AddBoundaryIntegrator(
206  std::move(integ_real), std::move(integ_imag), bc->getBoundaryMarkers())
207  : form->AddBoundaryIntegrator(std::move(integ_real), std::move(integ_imag));
208  }
209  }
210  }
211 }
212 
213 inline void
215  const std::string & test_var_name,
216  std::shared_ptr<mfem::ParComplexLinearForm> form,
217  NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexIntegratedBC>>>> &
218  integrated_bc_map)
219 {
220  if (integrated_bc_map.Has(test_var_name))
221  {
222  auto bcs = integrated_bc_map.GetRef(test_var_name).GetRef(test_var_name);
223  for (auto & bc : bcs)
224  {
225  mfem::LinearFormIntegrator * integ_real = bc->getRealLFIntegrator();
226  mfem::LinearFormIntegrator * integ_imag = bc->getImagLFIntegrator();
227 
228  if (integ_real || integ_imag)
229  {
230  bc->isBoundaryRestricted()
231  ? form->AddBoundaryIntegrator(
232  std::move(integ_real), std::move(integ_imag), bc->getBoundaryMarkers())
233  : form->AddBoundaryIntegrator(std::move(integ_real), std::move(integ_imag));
234  }
235  }
236  }
237 }
238 
239 }
240 
241 #endif
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< MFEMComplexKernel >>>> &kernels_map)
Template method for applying BilinearFormIntegrators on domains from kernels to a SesquilinearForm...
virtual void Mult(const mfem::Vector &x, mfem::Vector &y) const override
Nonlinear Mult (Used by Newton-solver not necessarily nonlinear)
virtual void SetTrialVariablesFromTrueVectors(const mfem::BlockVector &trueX) const override
Update variable from solution vector after solve.
std::vector< std::unique_ptr< mfem::ParComplexGridFunction > > _cmplx_var_ess_constraints
Complex Gridfunctions holding essential constraints from Dirichlet BCs.
virtual void BuildLinearForms() override
Build linear forms and eliminate constrained DoFs.
NamedFieldsMap< mfem::ParComplexLinearForm > _clfs
virtual void FormSystemOperator(mfem::OperatorHandle &op, mfem::BlockVector &trueX, mfem::BlockVector &trueRHS) override
Form matrix-free representation of system operator.
ComplexGridFunctions _cmplx_eliminated_variables
Pointers to coupled variables not part of the reduced EquationSystem.
Owns the weak-form mathematics of a MOOSE MFEM problem.
virtual void ApplyComplexEssentialBC(const std::string &var_name, mfem::ParComplexGridFunction &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...
void AddComplexEssentialBCs(std::shared_ptr< MFEMComplexEssentialBC > bc)
Add complex essential BCs.
virtual void ApplyEssentialBCs() override
Update all essentially constrained true DoF markers and values on boundaries.
NamedFieldsMap< std::vector< std::shared_ptr< MFEMComplexEssentialBC > > > _cmplx_essential_bc_map
virtual void BuildEquationSystem() override
Build all forms comprising this EquationSystem.
virtual void FormSystemMatrix(mfem::OperatorHandle &op, mfem::BlockVector &trueX, mfem::BlockVector &trueRHS) override
Form matrix representation of system operator as a HypreParMatrix.
NamedFieldsMap< NamedFieldsMap< std::vector< std::shared_ptr< MFEMComplexKernel > > > > _cmplx_kernels_map
void ApplyDomainLFIntegrators(const std::string &test_var_name, std::shared_ptr< mfem::ParComplexLinearForm > form, NamedFieldsMap< NamedFieldsMap< std::vector< std::shared_ptr< MFEMComplexKernel >>>> &kernels_map)
Method for applying LinearFormIntegrators on domains from kernels to a ParComplexLinearForm.
virtual void BuildBilinearForms() override
Build bilinear forms (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< MFEMComplexIntegratedBC >>>> &integrated_bc_map)
Template method for applying BilinearFormIntegrators on boudaries from kernels to a SesquilinearForm...
void AddComplexIntegratedBC(std::shared_ptr< MFEMComplexIntegratedBC > bc)
Add complex integrated BCs.
virtual void Init(GridFunctions &gridfunctions, ComplexGridFunctions &cmplx_gridfunctions, mfem::AssemblyLevel assembly_level) override
Initialise.
NamedFieldsMap< mfem::ParSesquilinearForm > _slfs
Moose::MFEM::ComplexGridFunctions * _complex_gfuncs
void ApplyBoundaryLFIntegrators(const std::string &test_var_name, std::shared_ptr< mfem::ParComplexLinearForm > form, NamedFieldsMap< NamedFieldsMap< std::vector< std::shared_ptr< MFEMComplexIntegratedBC >>>> &integrated_bc_map)
Method for applying LinearFormIntegrators on boundaries from kernels to a ParComplexLinearForm.
Utilities for converting between vector(s) of libMesh Points and MFEM Vector(s).
NamedFieldsMap< NamedFieldsMap< std::vector< std::shared_ptr< MFEMComplexIntegratedBC > > > > _cmplx_integrated_bc_map
void AddComplexKernel(std::shared_ptr< MFEMComplexKernel > kernel)
Add complex kernels.