1#ifdef MOOSE_MFEM_ENABLED
5#include "libmesh/int_range.h"
13 mfem::AssemblyLevel assembly_level)
17 if (gridfunctions.
size())
18 mooseError(
"Mixing real and complex variables is currently not supported.");
22 if (!cmplx_gridfunctions.
Has(test_var_name))
26 " requested by equation system during initialization was "
27 "not found in gridfunctions");
33 cmplx_gridfunctions.
Get(test_var_name)->ParFESpace()));
47 cmplx_gridfunctions.
GetShared(eliminated_var_name));
94 ApplyBoundaryBLFIntegrators<mfem::ParSesquilinearForm>(
96 ApplyDomainBLFIntegrators<mfem::ParSesquilinearForm>(
116 std::make_shared<Moose::MFEM::NamedFieldsMap<mfem::ParMixedSesquilinearForm>>();
120 auto mslf = std::make_shared<mfem::ParMixedSesquilinearForm>(
_coupled_pfespaces.at(j),
126 test_var_name != coupled_var_name)
130 ApplyDomainBLFIntegrators<mfem::ParMixedSesquilinearForm>(
136 test_mslfs->Register(coupled_var_name, mslf);
141 _mslfs.Register(test_var_name, test_mslfs);
147 mfem::ParComplexGridFunction & trial_gf,
148 mfem::Array<int> & global_ess_markers)
154 bc->ApplyBC(trial_gf);
156 mfem::Array<int> ess_bdrs(bc->getBoundaryMarkers());
158 for (
const auto i : make_range(ess_bdrs.Size()))
159 global_ess_markers[i] |= ess_bdrs[i];
179 _ess_markers.at(i).SetSize(trial_gf.ParFESpace()->GetParMesh()->bdr_attributes.Max(), 0);
190 const auto & trial_var_name = kernel->getTrialVariableName();
191 const auto & test_var_name = kernel->getTestVariableName();
197 auto kernel_field_map =
198 std::make_shared<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexKernel>>>>();
204 auto kernels = std::make_shared<std::vector<std::shared_ptr<MFEMComplexKernel>>>();
207 _cmplx_kernels_map.GetRef(test_var_name).Get(trial_var_name)->push_back(std::move(kernel));
213 const auto & trial_var_name = bc->getTrialVariableName();
214 const auto & test_var_name = bc->getTestVariableName();
220 auto integrated_bc_field_map =
221 std::make_shared<NamedFieldsMap<std::vector<std::shared_ptr<MFEMComplexIntegratedBC>>>>();
227 auto bcs = std::make_shared<std::vector<std::shared_ptr<MFEMComplexIntegratedBC>>>();
236 const auto & test_var_name = bc->getTestVariableName();
241 auto bcs = std::make_shared<std::vector<std::shared_ptr<MFEMComplexEssentialBC>>>();
252 if (
_mslfs.Has(test_var_name) &&
_mslfs.Get(test_var_name)->Has(eliminated_var_name) &&
255 auto & mslf = *
_mslfs.Get(test_var_name)->Get(eliminated_var_name);
256 auto & clf = *
_clfs.
Get(test_var_name);
257 const mfem::real_t
scale = -1.0;
258 const mfem::real_t conv =
259 (mslf.GetConvention() == mfem::ComplexOperator::HERMITIAN) ? 1.0 : -1.0;
277 mfem::BlockVector & trueX,
278 mfem::BlockVector & trueRHS)
281 mfem::Vector aux_x, aux_rhs;
282 mfem::OperatorPtr aux_a;
284 auto slf =
_slfs.
Get(test_var_name);
293 trueX.GetBlock(0) = aux_x;
294 trueRHS.GetBlock(0) = aux_rhs;
295 trueX.SyncFromBlocks();
296 trueRHS.SyncFromBlocks();
298 op.Reset(aux_a.Ptr());
299 aux_a.SetOperatorOwner(
false);
304 mfem::BlockVector & trueX,
305 mfem::BlockVector & trueRHS)
314 trueRHS.SyncToBlocks();
323 mfem::Vector aux_x, aux_rhs;
325 std::unique_ptr<mfem::OperatorHandle> aux_a = std::make_unique<mfem::OperatorHandle>();
327 if (test_var_name == trial_var_name)
329 mooseAssert(i == j,
"Trial and test variables must have the same ordering.");
330 auto slf =
_slfs.
Get(test_var_name);
331 auto clf =
_clfs.
Get(test_var_name);
339 trueX.GetBlock(i) = aux_x;
341 else if (
_mslfs.Has(test_var_name) &&
_mslfs.Get(test_var_name)->Has(trial_var_name))
343 auto mslf =
_mslfs.Get(test_var_name)->Get(trial_var_name);
355 trueRHS.GetBlock(i) += aux_rhs;
356 _h_blocks(i, j) = aux_a->As<mfem::ComplexHypreParMatrix>()->GetSystemMatrix();
361 trueX.SyncFromBlocks();
362 trueRHS.SyncFromBlocks();
365 op.Reset(mfem::HypreParMatrixFromBlocks(
_h_blocks));
383 trueX.GetBlock(i).SyncMemory(trueX);
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
void markSolutionChanged()
Notify quadrature function coefficients that solution variables have changed, marking the stored valu...
void EliminateCoupledVariables() override
Perform trivial eliminations of coupled variables lacking corresponding test variables.
virtual void BuildLinearForms() override
Build linear forms and eliminate constrained DoFs.
std::vector< std::unique_ptr< mfem::ParComplexGridFunction > > _cmplx_var_ess_constraints
Complex Gridfunctions holding essential constraints from Dirichlet BCs.
Moose::MFEM::ComplexGridFunctions * _complex_gfuncs
NamedFieldsMap< NamedFieldsMap< std::vector< std::shared_ptr< MFEMComplexKernel > > > > _cmplx_kernels_map
virtual void Mult(const mfem::Vector &x, mfem::Vector &y) const override
Nonlinear Mult (Used by Newton-solver not necessarily nonlinear)
virtual void FormSystemOperator(mfem::OperatorHandle &op, mfem::BlockVector &trueX, mfem::BlockVector &trueRHS) override
Form matrix-free representation of system operator.
virtual void BuildMixedBilinearForms() override
Build mixed bilinear forms (off-diagonal Jacobian contributions)
virtual void SetTrialVariablesFromTrueVectors(const mfem::BlockVector &trueX) const override
Update variable from solution vector after solve.
NamedFieldsMap< std::vector< std::shared_ptr< MFEMComplexEssentialBC > > > _cmplx_essential_bc_map
NamedFieldsMap< mfem::ParSesquilinearForm > _slfs
virtual void BuildBilinearForms() override
Build bilinear forms (diagonal Jacobian contributions)
virtual void Init(GridFunctions &gridfunctions, ComplexGridFunctions &cmplx_gridfunctions, mfem::AssemblyLevel assembly_level) override
Initialise.
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.
void AddComplexKernel(std::shared_ptr< MFEMComplexKernel > kernel)
Add complex kernels.
virtual void ApplyComplexEssentialBC(const std::string &var_name, mfem::ParComplexGridFunction &trial_gf, mfem::Array< int > &global_ess_markers)
Applies complex BCs to a single trial variable.
NamedFieldsMap< NamedFieldsMap< std::vector< std::shared_ptr< MFEMComplexIntegratedBC > > > > _cmplx_integrated_bc_map
virtual void ApplyEssentialBCs() override
Update all essentially constrained true DoF markers and values on boundaries.
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.
NamedFieldsMap< mfem::ParComplexLinearForm > _clfs
NamedFieldsMap< NamedFieldsMap< mfem::ParMixedSesquilinearForm > > _mslfs
virtual void FormSystemMatrix(mfem::OperatorHandle &op, mfem::BlockVector &trueX, mfem::BlockVector &trueRHS) override
Form matrix representation of system operator as a HypreParMatrix.
void AddComplexIntegratedBC(std::shared_ptr< MFEMComplexIntegratedBC > bc)
Add complex integrated BCs.
ComplexGridFunctions _cmplx_eliminated_variables
Pointers to coupled variables not part of the reduced ComplexEquationSystem.
void AddComplexEssentialBCs(std::shared_ptr< MFEMComplexEssentialBC > bc)
Add complex essential BCs.
virtual void AddTestVariableNameIfMissing(const std::string &test_var_name)
Add test variable to EquationSystem.
std::vector< std::string > _coupled_var_names
Names of all trial variables of kernels and boundary conditions added to this EquationSystem.
std::vector< mfem::ParFiniteElementSpace * > _test_pfespaces
Pointers to finite element spaces associated with test variables.
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
mfem::Array2D< const mfem::HypreParMatrix * > _h_blocks
std::vector< std::string > _test_var_names
Names of all test variables corresponding to linear forms in this equation system.
mfem::OperatorHandle _linear_operator
mfem::AssemblyLevel _assembly_level
virtual void SetTrialVariableNames()
Set trial variable names from subset of coupled variables that have an associated test variable.
std::vector< mfem::Array< int > > _ess_tdof_lists
CoefficientManager * _coefficient_manager
void DeleteHBlocks()
Deletes the HypreParMatrix associated with any pointer stored in _h_blocks, and then proceeds to dele...
std::vector< std::string > _trial_var_names
Subset of _coupled_var_names of all variables corresponding to gridfunctions with degrees of freedom ...
std::vector< mfem::Array< int > > _ess_markers
std::vector< std::string > _eliminated_var_names
Names of all coupled variables without a corresponding test variable.
virtual void AddCoupledVariableNameIfMissing(const std::string &coupled_var_name)
Add coupled variable to EquationSystem.
void Register(const std::string &field_name, FieldArgs &&... args)
Construct new field with name field_name and register.
bool Has(const std::string &field_name) const
Predicate to check if a field is registered with name field_name.
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.
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.
int size()
Returns the number of elements in the map.
T & GetRef(const std::string &field_name) const
Returns a reference to a field.
Utilities for converting between vector(s) of libMesh Points and MFEM Vector(s).