31 #include "libmesh/libmesh.h"    32 #include "libmesh/mesh.h"    33 #include "libmesh/mesh_generation.h"    34 #include "libmesh/exodusII_io.h"    35 #include "libmesh/condensed_eigen_system.h"    36 #include "libmesh/equation_systems.h"    37 #include "libmesh/fe.h"    38 #include "libmesh/quadrature_gauss.h"    39 #include "libmesh/dense_matrix.h"    40 #include "libmesh/petsc_matrix.h"    41 #include "libmesh/petsc_vector.h"    42 #include "libmesh/dof_map.h"    43 #include "libmesh/getpot.h"    44 #include "libmesh/eigen_solver.h"    45 #include "libmesh/enum_eigen_solver_type.h"    46 #include "libmesh/petsc_shell_matrix.h"    47 #include "libmesh/elem.h"    48 #include "libmesh/mesh_refinement.h"    49 #include "libmesh/slepc_macro.h"    54 #ifdef LIBMESH_HAVE_SLEPC    55 #include <petscsnes.h>    58 PetscErrorCode 
form_matrixA(SNES snes, Vec x, Mat jac, Mat pc, 
void * 
ctx);
    63 main(
int argc, 
char ** argv)
    68 #ifdef LIBMESH_DEFAULT_SINGLE_PRECISION    70   libmesh_example_requires(
false, 
"--disable-singleprecision");
    73 #ifndef LIBMESH_HAVE_SLEPC    74   libmesh_example_requires(
false, 
"--enable-slepc with a slepc version >=3.13");
    76 #if SLEPC_VERSION_LESS_THAN(3, 13, 0)    77   libmesh_example_requires(
false, 
"--enable-slepc with a slepc version >=3.13");
    82   for (
int i = 1; i < argc; i++)
    88   constexpr 
int nev = 1;
    94   libmesh_example_requires(2 <= LIBMESH_DIM, 
"2D support");
   104 #ifdef LIBMESH_ENABLE_AMR   105   for (
auto * elem : 
mesh.active_element_ptr_range())
   106     if (elem->vertex_average()(0) < 0)
   132   equation_systems.
parameters.
set<
unsigned int>(
"eigenpairs") = nev;
   133   equation_systems.
parameters.
set<
unsigned int>(
"basis vectors") = nev * 3;
   135   eigen_system.set_eigenproblem_type(
GNHEP);
   136   eigen_system.use_shell_matrices(
true);
   139   equation_systems.
init();
   144   LibmeshPetscCallQ(PetscOptionsSetValue(LIBMESH_PETSC_NULLPTR, 
"-eps_type", 
"power"));
   145   LibmeshPetscCallQ(PetscOptionsSetValue(LIBMESH_PETSC_NULLPTR, 
"-eps_power_update", 
"1"));
   146   LibmeshPetscCallQ(PetscOptionsSetValue(LIBMESH_PETSC_NULLPTR, 
"-eps_power_nonlinear", 
"1"));
   147   LibmeshPetscCallQ(PetscOptionsSetValue(LIBMESH_PETSC_NULLPTR, 
"-eps_max_it", 
"1"));
   148   LibmeshPetscCallQ(PetscOptionsSetValue(LIBMESH_PETSC_NULLPTR, 
"-eps_power_snes_mf_operator", 
"1"));
   149   LibmeshPetscCallQ(PetscOptionsSetValue(LIBMESH_PETSC_NULLPTR, 
"-eps_power_pc_type", 
"lu"));
   168   PetscContainer container;
   171   LibmeshPetscCallQ(PetscObjectCompose((PetscObject)Amat, 
"formFunctionCtx", (PetscObject)container));
   172   LibmeshPetscCallQ(PetscObjectCompose((PetscObject)Amat, 
"formJacobianCtx", (PetscObject)container));
   173   LibmeshPetscCallQ(PetscObjectCompose((PetscObject)Bmat, 
"formFunctionCtx", (PetscObject)container));
   180   wrapped_initial_space.
add(1);
   181   wrapped_initial_space.close();
   182   eigen_system.get_eigen_solver().set_initial_space(wrapped_initial_space);
   185   eigen_system.initialize_condensed_matrices();
   186   eigen_system.dont_create_submatrices_in_solve();
   187   eigen_system.assemble_before_solve = 
false;
   188   eigen_system.get_eigen_solver().set_close_matrix_before_solve(
false);
   189   eigen_system.solve();
   192   unsigned int nconv = eigen_system.get_n_converged();
   197     auto [re, im] = eigen_system.get_eigenpair(0);
   198     libMesh::out << 
"The converged eigenvalue is " << re << 
" + " << im << 
"i" << std::endl;
   200 #ifdef LIBMESH_HAVE_EXODUS_API   203 #endif // #ifdef LIBMESH_HAVE_EXODUS_API   206     libMesh::out << 
"WARNING: Solver did not converge!\n" << nconv << std::endl;
   212 #endif // SLEPC version >= 3.13.0   213 #endif // LIBMESH_HAVE_SLEPC   216 #ifdef LIBMESH_HAVE_SLEPC   224   if (dof_map.n_constrained_dofs())
   228     dof_map.enforce_constraints_exactly(sys);
   239     X_global.
swap(X_sys);
   241     X_global.swap(X_sys);
   245 std::unique_ptr<NumericVector<Number>>
   250   if (dof_map.n_constrained_dofs())
   254     auto F = std::make_unique<PetscVector<Number>>(f, sys.
comm());
   301   fe->attach_quadrature_rule(&qrule);
   306   fe_face->attach_quadrature_rule(&qrule_face);
   309   const std::vector<Real> & JxW = fe->get_JxW();
   312   const auto & dphi = fe->get_dphi();
   315   std::vector<Number> Ue;
   323   std::vector<dof_id_type> dof_indices;
   331   for (
const auto & elem : 
mesh.active_local_element_ptr_range())
   337     dof_map.dof_indices(elem, dof_indices);
   346     eigen_system.current_local_solution->get(dof_indices, Ue);
   354     const unsigned int n_dofs = cast_int<unsigned int>(dof_indices.size());
   361     for (
const auto qp : 
make_range(qrule.n_points()))
   366         grad_u_qp += dphi[i][qp] * Ue[i];
   369         Ke(i) += JxW[qp] * dphi[i][qp] * grad_u_qp;
   372     for (
const auto s : elem->side_index_range())
   373       if (!elem->neighbor_ptr(s))
   375         const auto & phi_face = fe_face->get_phi();
   376         const auto & JxW_face = fe_face->get_JxW();
   378         fe_face->reinit(elem, s);
   379         for (
const auto qp : 
make_range(qrule_face.n_points()))
   383             u_qp += phi_face[i][qp] * Ue[i];
   385             Ke(i) += JxW_face[qp] * phi_face[i][qp] * u_qp;
   393     dof_map.constrain_element_vector(Ke, dof_indices);
   405     eigen_system.copy_super_to_sub(*AX, wrapped_Ax);
   452   fe->attach_quadrature_rule(&qrule);
   455   const std::vector<Real> & JxW = fe->get_JxW();
   458   const std::vector<std::vector<Real>> & phi = fe->get_phi();
   461   std::vector<Number> Ue;
   469   std::vector<dof_id_type> dof_indices;
   477   for (
const auto & elem : 
mesh.active_local_element_ptr_range())
   483     dof_map.dof_indices(elem, dof_indices);
   492     eigen_system.current_local_solution->get(dof_indices, Ue);
   500     const unsigned int n_dofs = cast_int<unsigned int>(dof_indices.size());
   507     for (
unsigned int qp = 0; qp < qrule.n_points(); qp++)
   512         Uqp += phi[i][qp] * Ue[i];
   514       for (
unsigned int i = 0; i != n_dofs; i++)
   515         Me(i) += JxW[qp] * phi[i][qp] * Uqp;
   522     dof_map.constrain_element_vector(Me, dof_indices);
   534     eigen_system.copy_super_to_sub(*BX, wrapped_Bx);
   562   PetscBool pisshell, jismffd;
   566     libmesh_error_msg(
"Generic preconditioning requires that an explicit matrix representation of "   567                       "the preconditioner be formed");
   570     libmesh_error_msg(
"The operator should be formed matrix free");
   572   auto & pc_super = eigen_system.get_precond_matrix();
   595   fe->attach_quadrature_rule(&qrule);
   600   fe_face->attach_quadrature_rule(&qrule_face);
   603   const std::vector<Real> & JxW = fe->get_JxW();
   606   const auto & dphi = fe->get_dphi();
   614   std::vector<dof_id_type> dof_indices;
   622   for (
const auto & elem : 
mesh.active_local_element_ptr_range())
   628     dof_map.dof_indices(elem, dof_indices);
   642     const unsigned int n_dofs = cast_int<unsigned int>(dof_indices.size());
   643     Ke.
resize(n_dofs, n_dofs);
   649     for (
const auto qp : 
make_range(qrule.n_points()))
   653           Ke(i, j) += JxW[qp] * dphi[i][qp] * dphi[j][qp];
   655     for (
const auto s : elem->side_index_range())
   656       if (!elem->neighbor_ptr(s))
   658         const auto & phi_face = fe_face->get_phi();
   659         const auto & JxW_face = fe_face->get_JxW();
   661         fe_face->reinit(elem, s);
   662         for (
const auto qp : 
make_range(qrule_face.n_points()))
   666               Ke(i, j) += JxW_face[qp] * phi_face[i][qp] * phi_face[j][qp];
   674     dof_map.constrain_element_matrix(Ke, dof_indices);
   678     pc_super.
add_matrix(Ke, dof_indices, dof_indices);
   687 #if SLEPC_VERSION_LESS_THAN(3,21,0)   689     eigen_system.copy_super_to_sub(pc_super, sub);
   693     eigen_system.copy_super_to_sub(pc_super, *sub);
 class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
T command_line_next(std::string name, T default_value)
Use GetPot's search()/next() functions to get following arguments from the command line...
This is the EquationSystems class. 
This class provides a nice interface to PETSc's Vec object. 
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
bool refine_elements()
Only refines the user-requested elements. 
Mat mat()
Returns a pointer to the underlying PETSc Mat object. 
void resize(const unsigned int n)
Resize the vector. 
virtual void add(const numeric_index_type i, const T value) override
Adds value to the vector entry specified by i. 
This class allows to use a PETSc shell matrix. 
void print_info(std::ostream &os=libMesh::out) const
Prints information about the equation systems, by default to libMesh::out. 
const Parallel::Communicator & comm() const
Order default_quadrature_order() const
NumericVector< Number > & add_vector(std::string_view vec_name, const bool projections=true, const ParallelType type=PARALLEL)
Adds the additional vector vec_name to this system. 
static PetscMatrixBase< T > * get_context(Mat mat, const TIMPI::Communicator &comm)
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space. 
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g. 
The libMesh namespace provides an interface to certain functionality in the library. 
PetscErrorCode form_functionB(SNES snes, Vec x, Vec Bx, void *ctx)
const T_sys & get_system(std::string_view name) const
This is the MeshBase class. 
virtual void swap(NumericVector< T > &v) override
Swaps the contents of this with v. 
Implements (adaptive) mesh refinement algorithms for a MeshBase. 
void copy_sub_to_super(const NumericVector< Number > &sub, NumericVector< Number > &super)
Copy a logically sub-vector into a super-vector. 
virtual void write_equation_systems(const std::string &fname, const EquationSystems &es, const std::set< std::string > *system_names=nullptr) override
Writes out the solution for no specific time or timestep. 
void print_info(std::ostream &os=libMesh::out, const unsigned int verbosity=0, const bool global=true) const
Prints relevant information about the mesh. 
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values. 
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary. 
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type. 
unsigned int add_variable(std::string_view var, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
Adds the variable var to the list of variables for this system. 
virtual void close()=0
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
This class extends EigenSystem to allow a simple way of solving (standard or generalized) eigenvalue ...
int main(int argc, char **argv)
PetscErrorCode form_matrixA(SNES snes, Vec x, Mat jac, Mat pc, void *ctx)
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
virtual void update()
Update the local values to reflect the solution on neighboring processors. 
virtual void close()=0
Calls the SparseMatrix's internal assembly routines, ensuring that the values are consistent across p...
const FEType & variable_type(const unsigned int i) const
std::unique_ptr< NumericVector< Number > > create_wrapped_function(CondensedEigenSystem &sys, Vec f)
T & set(const std::string &)
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero(). 
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
This class implements specific orders of Gauss quadrature. 
unsigned int mesh_dimension() const
Parameters parameters
Data structure holding arbitrary parameters. 
This class provides a nice interface to the PETSc C-based AIJ data structures for parallel...
virtual void reinit() override
Reinitializes the member data fields associated with the system, so that, e.g., assemble() may be use...
virtual void init()
Initialize all the systems. 
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
virtual System & add_system(std::string_view system_type, std::string_view name)
Add the system of type system_type named name to the systems array. 
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default. 
PetscErrorCode form_functionA(SNES snes, Vec x, Vec Ax, void *ctx)
SparseMatrix< Number > & add_matrix(std::string_view mat_name, ParallelType type=PARALLEL, MatrixBuildType mat_build_type=MatrixBuildType::AUTOMATIC)
Adds the additional matrix mat_name to this system. 
const DofMap & get_dof_map() const
dof_id_type n_constrained_dofs() const
void update_current_local_solution(CondensedEigenSystem &sys, Vec x)