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 
22 public:
23  ComplexEquationSystem() = default;
24  ~ComplexEquationSystem() = default;
25 
26  // Build forms
27  virtual void Init(GridFunctions & gridfunctions,
28  ComplexGridFunctions & cmplx_gridfunctions,
29  mfem::AssemblyLevel assembly_level) override;
30 
32  virtual void Mult(const mfem::Vector & x, mfem::Vector & y) const override;
33 
35  virtual void BuildEquationSystem() override;
36 
38  virtual void BuildLinearForms() override;
39 
41  virtual void BuildBilinearForms() override;
42 
45  virtual void ApplyComplexEssentialBC(const std::string & var_name,
46  mfem::ParComplexGridFunction & trial_gf,
47  mfem::Array<int> & global_ess_markers);
49  virtual void ApplyEssentialBCs() override;
50 
52  void AddComplexKernel(std::shared_ptr<MFEMComplexKernel> kernel);
53 
55  void AddComplexIntegratedBC(std::shared_ptr<MFEMComplexIntegratedBC> bc);
56 
58  void AddComplexEssentialBCs(std::shared_ptr<MFEMComplexEssentialBC> bc);
59 
62  virtual void FormSystemOperator(mfem::OperatorHandle & op,
63  mfem::BlockVector & trueX,
64  mfem::BlockVector & trueRHS) override;
65 
68  virtual void FormSystemMatrix(mfem::OperatorHandle & op,
69  mfem::BlockVector & trueX,
70  mfem::BlockVector & trueRHS) override;
71 
73  virtual void SetTrialVariablesFromTrueVectors(const mfem::BlockVector & trueX) const override;
74 
76  template <class FormType>
78  const std::string & trial_var_name,
79  const std::string & test_var_name,
80  std::shared_ptr<FormType> form,
81  NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexKernel>>>> &
82  kernels_map);
83 
85  inline void ApplyDomainLFIntegrators(
86  const std::string & test_var_name,
87  std::shared_ptr<mfem::ParComplexLinearForm> form,
88  NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexKernel>>>> &
89  kernels_map);
90 
92  template <class FormType>
94  const std::string & trial_var_name,
95  const std::string & test_var_name,
96  std::shared_ptr<FormType> form,
97  NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexIntegratedBC>>>> &
98  integrated_bc_map);
99 
101  inline void ApplyBoundaryLFIntegrators(
102  const std::string & test_var_name,
103  std::shared_ptr<mfem::ParComplexLinearForm> form,
104  NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexIntegratedBC>>>> &
105  integrated_bc_map);
106 
107  virtual bool Complex() const override { return true; }
108 
109 protected:
110  // Complex Linear and Bilinear Forms
113 
114  // Complex kernels and integrated BCs
119 
120  // Complex essential BCs
122 
125 
127  std::vector<std::unique_ptr<mfem::ParComplexGridFunction>> _cmplx_var_ess_constraints;
128 
129  // Pointer to complex GridFunctions to enable updates during nonlinear iterations
131 };
132 
133 template <class FormType>
134 void
136  const std::string & trial_var_name,
137  const std::string & test_var_name,
138  std::shared_ptr<FormType> form,
139  NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexKernel>>>> & kernels_map)
140 {
141  if (kernels_map.Has(test_var_name) && kernels_map.Get(test_var_name)->Has(trial_var_name))
142  {
143  auto kernels = kernels_map.GetRef(test_var_name).GetRef(trial_var_name);
144  for (auto & kernel : kernels)
145  {
146  mfem::BilinearFormIntegrator * integ_real = kernel->getRealBFIntegrator();
147  mfem::BilinearFormIntegrator * integ_imag = kernel->getImagBFIntegrator();
148 
149  if (integ_real || integ_imag)
150  {
151  kernel->isSubdomainRestricted()
152  ? form->AddDomainIntegrator(
153  std::move(integ_real), std::move(integ_imag), kernel->getSubdomainMarkers())
154  : form->AddDomainIntegrator(std::move(integ_real), std::move(integ_imag));
155  }
156  }
157  }
158 }
159 
160 inline void
162  const std::string & test_var_name,
163  std::shared_ptr<mfem::ParComplexLinearForm> form,
164  NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexKernel>>>> & kernels_map)
165 {
166  if (kernels_map.Has(test_var_name))
167  {
168  auto kernels = kernels_map.GetRef(test_var_name).GetRef(test_var_name);
169  for (auto & kernel : kernels)
170  {
171  mfem::LinearFormIntegrator * integ_real = kernel->getRealLFIntegrator();
172  mfem::LinearFormIntegrator * integ_imag = kernel->getImagLFIntegrator();
173 
174  if (integ_real || integ_imag)
175  {
176  kernel->isSubdomainRestricted()
177  ? form->AddDomainIntegrator(
178  std::move(integ_real), std::move(integ_imag), kernel->getSubdomainMarkers())
179  : form->AddDomainIntegrator(std::move(integ_real), std::move(integ_imag));
180  }
181  }
182  }
183 }
184 
185 template <class FormType>
186 void
188  const std::string & trial_var_name,
189  const std::string & test_var_name,
190  std::shared_ptr<FormType> form,
191  NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexIntegratedBC>>>> &
192  integrated_bc_map)
193 {
194  if (integrated_bc_map.Has(test_var_name) &&
195  integrated_bc_map.Get(test_var_name)->Has(trial_var_name))
196  {
197  auto bcs = integrated_bc_map.GetRef(test_var_name).GetRef(trial_var_name);
198  for (auto & bc : bcs)
199  {
200  mfem::BilinearFormIntegrator * integ_real = bc->getRealBFIntegrator();
201  mfem::BilinearFormIntegrator * integ_imag = bc->getImagBFIntegrator();
202 
203  if (integ_real || integ_imag)
204  {
205  bc->isBoundaryRestricted()
206  ? form->AddBoundaryIntegrator(
207  std::move(integ_real), std::move(integ_imag), bc->getBoundaryMarkers())
208  : form->AddBoundaryIntegrator(std::move(integ_real), std::move(integ_imag));
209  }
210  }
211  }
212 }
213 
214 inline void
216  const std::string & test_var_name,
217  std::shared_ptr<mfem::ParComplexLinearForm> form,
218  NamedFieldsMap<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexIntegratedBC>>>> &
219  integrated_bc_map)
220 {
221  if (integrated_bc_map.Has(test_var_name))
222  {
223  auto bcs = integrated_bc_map.GetRef(test_var_name).GetRef(test_var_name);
224  for (auto & bc : bcs)
225  {
226  mfem::LinearFormIntegrator * integ_real = bc->getRealLFIntegrator();
227  mfem::LinearFormIntegrator * integ_imag = bc->getImagLFIntegrator();
228 
229  if (integ_real || integ_imag)
230  {
231  bc->isBoundaryRestricted()
232  ? form->AddBoundaryIntegrator(
233  std::move(integ_real), std::move(integ_imag), bc->getBoundaryMarkers())
234  : form->AddBoundaryIntegrator(std::move(integ_real), std::move(integ_imag));
235  }
236  }
237  }
238 }
239 
240 }
241 
242 #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.
Class to store weak form components (bilinear and linear forms, and optionally mixed and nonlinear fo...
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...
virtual bool Complex() const override
Whether this a complex equation system.
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.