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
58PetscErrorCode
form_matrixA(SNES snes, Vec x, Mat jac, Mat pc,
void *
ctx);
63main(
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
206 libMesh::out <<
"WARNING: Solver did not converge!\n" << nconv << std::endl;
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);
245std::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());
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);
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);
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);
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);
This class extends EigenSystem to allow a simple way of solving (standard or generalized) eigenvalue ...
void copy_sub_to_super(const NumericVector< Number > &sub, NumericVector< Number > &super)
Copy a logically sub-vector into a super-vector.
virtual void reinit() override
Reinitializes the member data fields associated with the system, so that, e.g., assemble() may be use...
Defines a dense matrix for use in Finite Element-type computations.
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
Defines a dense vector for use in Finite Element-type computations.
void resize(const unsigned int n)
Resize the vector.
This is the EquationSystems class.
void print_info(std::ostream &os=libMesh::out) const
Prints information about the equation systems, by default to libMesh::out.
Parameters parameters
Data structure holding arbitrary parameters.
virtual void init()
Initialize all the systems.
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.
const T_sys & get_system(std::string_view name) const
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
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.
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Order default_quadrature_order() const
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
This is the MeshBase class.
unsigned int mesh_dimension() const
void print_info(std::ostream &os=libMesh::out, const unsigned int verbosity=0, const bool global=true) const
Prints relevant information about the mesh.
Implements (adaptive) mesh refinement algorithms for a MeshBase.
bool refine_elements()
Only refines the user-requested elements.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
virtual void close()=0
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
const Parallel::Communicator & comm() const
T & set(const std::string &)
static PetscMatrixBase< T > * get_context(Mat mat, const TIMPI::Communicator &comm)
This class provides a nice interface to the PETSc C-based AIJ data structures for parallel,...
This class allows to use a PETSc shell matrix.
Mat mat()
Returns a pointer to the underlying PETSc Mat object.
This class provides a nice interface to PETSc's Vec object.
virtual void close() override
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
virtual void swap(NumericVector< T > &v) override
Swaps the contents of this with v.
virtual void add(const numeric_index_type i, const T value) override
Adds value to the vector entry specified by i.
unsigned int n_points() const
This class implements specific orders of Gauss quadrature.
virtual void close()=0
Calls the SparseMatrix's internal assembly routines, ensuring that the values are consistent across p...
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 FEType & variable_type(const unsigned int i) const
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.
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.
dof_id_type n_constrained_dofs() const
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
virtual void update()
Update the local values to reflect the solution on neighboring processors.
const DofMap & get_dof_map() const
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
void update_current_local_solution(CondensedEigenSystem &sys, Vec x)
PetscErrorCode form_matrixA(SNES snes, Vec x, Mat jac, Mat pc, void *ctx)
std::unique_ptr< NumericVector< Number > > create_wrapped_function(CondensedEigenSystem &sys, Vec f)
PetscErrorCode form_functionA(SNES snes, Vec x, Vec Ax, void *ctx)
PetscErrorCode form_functionB(SNES snes, Vec x, Vec Bx, void *ctx)
The libMesh namespace provides an interface to certain functionality in the library.
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
T command_line_next(std::string name, T default_value)
Use GetPot's search()/next() functions to get following arguments from the command line.
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
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...