10#ifdef MOOSE_MFEM_ENABLED
14#include "libmesh/int_range.h"
27 _ess_markers.at(0).SetSize(trial_gf.ParFESpace()->GetParMesh()->bdr_attributes.Max(), 0);
39 mfem::Vector ess_values;
40 trial_gf.GetTrueDofs(ess_values);
42 mfem::real_t max_ess_value =
43 mfem::GlobalLpNorm(mfem::infinity(), ess_values.Normlinf(), trial_gf.ParFESpace()->GetComm());
45 if (max_ess_value > 10 * std::numeric_limits<mfem::real_t>::epsilon())
46 mooseError(
"Essential boundary conditions on variable '",
48 "' prescribe a nonzero value. "
49 "An eigenproblem is homogeneous so only zero-valued essential boundary conditions "
50 "are meaningful. Set the boundary coefficient to zero.");
68 std::unique_ptr<mfem::ParBilinearForm> m = std::make_unique<mfem::ParBilinearForm>(fespace);
70 if (fespace->GetTypicalFE()->GetRangeType() == mfem::FiniteElement::SCALAR)
72 if (std::holds_alternative<mfem::MatrixCoefficient *>(rhs_coefficient))
73 mooseError(
"A matrix rhs_coefficient cannot be used with a scalar finite element space.");
74 m->AddDomainIntegrator(
75 new mfem::MassIntegrator(*std::get<mfem::Coefficient *>(rhs_coefficient)));
78 m->AddDomainIntegrator(std::visit(
79 [](
auto * coef) {
return new mfem::VectorFEMassIntegrator(*coef); }, rhs_coefficient));
85 m->EliminateEssentialBCDiag(
_ess_markers.at(0), std::numeric_limits<mfem::real_t>::min());
96 "Eigensolve is only supported for single-variable, square systems");
98 height = trueX.Size();
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
virtual void ApplyEssentialBCs() override
Mark external boundaries as essential for eigenproblem BC elimination.
void FormMassMatrix(EigenRHSCoefficient rhs_coefficient)
Form mass matrix for the eigensolver with Dirichlet BC elimination.
virtual void CheckProblemIsHomogeneous()
Verify that the problem is homogeneous (all Dirichlet BCs are zero)
mfem::OperatorHandle _mass_rhs
The mass operator (e.g. the RHS operator for a generalized eigenproblem)
void PrepareEigensolver(EigensolverBase &solver)
Prepare the provided eigensolver.
void BuildEigenproblemJacobian(mfem::BlockVector &trueX, EigenRHSCoefficient rhs_coefficient)
Build eigenproblem system, with essential boundary conditions accounted for.
void FormEigenproblemMatrix()
Form HypreParMatrix matrix operator for the eigensolver with Dirichlet BC elimination.
Base class for eigensolvers.
virtual void SetMassMatrix(mfem::Operator &mass)=0
Sets the mass matrix for the eigensolver in derived classes.
std::vector< mfem::ParFiniteElementSpace * > _test_pfespaces
Pointers to finite element spaces associated with test variables.
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...
std::vector< std::string > _test_var_names
Names of all test variables corresponding to linear forms in this equation system.
std::vector< mfem::Array< int > > _ess_tdof_lists
NamedFieldsMap< mfem::ParBilinearForm > _blfs
mfem::OperatorHandle _jacobian
std::vector< std::string > _trial_var_names
Subset of _coupled_var_names of all variables corresponding to gridfunctions with degrees of freedom ...
std::vector< std::unique_ptr< mfem::ParGridFunction > > _var_ess_constraints
Gridfunctions holding essential constraints from Dirichlet BCs.
std::vector< mfem::Array< int > > _ess_markers
Moose::MFEM::GridFunctions * _gfuncs
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.
T & GetRef(const std::string &field_name) const
Returns a reference to a field.
void SetOperator(mfem::Operator &op)
Updates the solver and any associated weak form context at the operator level.
Utilities for converting between vector(s) of libMesh Points and MFEM Vector(s).
std::variant< mfem::Coefficient *, mfem::MatrixCoefficient * > EigenRHSCoefficient
Scalar or matrix coefficient scaling the eigenproblem right-hand side.