33#include "libmesh/getpot.h"
34#include "libmesh/libmesh.h"
35#include "libmesh/mesh.h"
36#include "libmesh/mesh_tetgen_interface.h"
37#include "libmesh/elem.h"
38#include "libmesh/mesh_generation.h"
39#include "libmesh/exodusII_io.h"
40#include "libmesh/eigen_system.h"
41#include "libmesh/equation_systems.h"
42#include "libmesh/fe.h"
43#include "libmesh/quadrature_gauss.h"
44#include "libmesh/dense_matrix.h"
45#include "libmesh/sparse_matrix.h"
46#include "libmesh/numeric_vector.h"
47#include "libmesh/dof_map.h"
48#include "libmesh/fe_interface.h"
49#include "libmesh/explicit_system.h"
51#include "libmesh/inf_fe.h"
52#include "libmesh/inf_elem_builder.h"
53#include "libmesh/fe_interface.h"
54#include "libmesh/fe_compute_data.h"
56#include "libmesh/point_locator_tree.h"
59#include "libmesh/petsc_solver_exception.h"
60#include "libmesh/solver_configuration.h"
61#include "libmesh/slepc_eigen_solver.h"
62#include "libmesh/enum_eigen_solver_type.h"
64#ifdef LIBMESH_HAVE_SLEPC
65EXTERN_C_FOR_SLEPC_BEGIN
73#ifdef LIBMESH_HAVE_SLEPC
134int main (
int argc,
char** argv)
140 libmesh_error_msg_if(argc < 2,
"\nUsage: " << argv[0] <<
" <input-filename>");
143 std::cout <<
"Running " << argv[0];
145 for (
int i=1; i<argc; i++)
146 std::cout <<
" " << argv[i];
147 std::cout << std::endl << std::endl;
150#ifndef LIBMESH_HAVE_SLEPC
151 libmesh_example_requires(
false,
"--enable-slepc");
153#ifndef LIBMESH_ENABLE_INFINITE_ELEMENTS
154 libmesh_example_requires(
false,
"--enable-ifem");
157#ifndef LIBMESH_USE_COMPLEX_NUMBERS
158 libmesh_example_requires(
false,
"--enable-complex");
161#ifdef LIBMESH_DEFAULT_SINGLE_PRECISION
163 libmesh_example_requires(
false,
"--disable-singleprecision");
171 libmesh_example_requires(3 <= LIBMESH_DIM,
"3D support");
174 const unsigned int nev = cl(
"nev",1);
175 Real E = cl(
"Energy", -.5);
176 Real r=cl(
"radius", 4.);
177 unsigned int maxiter=cl(
"maxiter", 700);
194 for (
auto & elem :
mesh.element_ptr_range())
195 if (elem->infinite())
197 elem->subdomain_id() = 1;
199 elem->neighbor_ptr(0)->subdomain_id()=2;
230 eq_sys.
parameters.
set<
unsigned int>(
"basis vectors") = nev*3+4;
234 eq_sys.
parameters.
set<
unsigned int>(
"linear solver maximum iterations") = maxiter;
237#if SLEPC_VERSION_LESS_THAN(2,3,2)
276 out <<
"Number of converged eigenpairs: " << nconv <<
"\n";
279 for(
unsigned int i=0; i<nconv; i++)
284 Complex eigenvalue(eigpair.first, eigpair.second);
285 out<<
" "<<eigenvalue<<std::endl;
291 if (eigpair.first > 0.)
297 Complex k= sqrt(2.*eigenvalue);
304#ifdef LIBMESH_HAVE_EXODUS_API
306 std::ostringstream eigenvector_output_name;
307 eigenvector_output_name <<
"U" <<
"-" << i <<
"_inf.e";
314 std::ostringstream file;
315 file <<
"infini_" << i <<
".txt";
334#if defined(LIBMESH_ENABLE_INFINITE_ELEMENTS) && defined(LIBMESH_HAVE_SLEPC)
337 libmesh_assert_equal_to (system_name,
"EigenSE");
358 QGauss qrule (
dim, fe_type.default_quadrature_order());
368 fe->attach_quadrature_rule (&qrule);
369 inf_fe->attach_quadrature_rule (&qrule);
397 std::vector<dof_id_type> dof_indices;
405 for (
const auto & elem :
mesh.active_local_element_ptr_range())
416 if (elem->infinite())
436 const std::vector<Point>& q_point = cfe->
get_xyz();
438 const std::vector<RealGradient>& dphase = cfe->
get_dphase();
454 M.
resize (dof_indices.size(), dof_indices.size());
455 H.
resize (dof_indices.size(), dof_indices.size());
461 for (
unsigned int qp=0; qp<max_qp; qp++)
465 Number potval=-1./(q_point[qp]).norm();
468 const unsigned int n_sf =
471 for (
unsigned int i=0; i<n_sf; i++)
473 for (
unsigned int j=0; j<n_sf; j++)
479 Number temp = (dweight[qp]*phi[i][qp]+weight[qp]*(dphi[i][qp]-ik*dphase[qp]*phi[i][qp]))
480 *(dphi[j][qp]+ik*dphase[qp]*phi[j][qp]);
483 H(i,j) += JxW[qp]*(0.5*temp + potval*weight[qp]*phi[i][qp]*phi[j][qp]);
486 M(i,j) += JxW[qp]*weight[qp]*phi[i][qp]*phi[j][qp];
516 QGauss qrule2 (
dim-1, fe_type.default_quadrature_order());
518 face_fe->attach_quadrature_rule (&qrule2);
532 const std::vector<Real>& JxW = face_fe->get_JxWxdecay_sq();
533 const std::vector<Point>& q_point = face_fe->get_xyz();
534 const std::vector<std::vector<RealGradient> >& dphi = face_fe->get_dphi();
535 const std::vector<std::vector<Real> >& phi = face_fe->get_phi();
536 const std::vector<Point>& normal = face_fe->get_normals();
537 const std::vector<RealGradient>& dphase = face_fe->get_dphase();
538 const std::vector<Real>& weight = face_fe->get_Sobolev_weight();
541 const unsigned int side=0;
542 face_fe->reinit (elem, side);
543 const unsigned int n_sf =
546 H.
resize (dof_indices.size(), dof_indices.size());
548 for (
unsigned int pts=0; pts<q_point.size(); pts++){
549 for (
unsigned int i=0; i<n_sf; i++){
551 for (
unsigned int j=0; j<n_sf; j++){
554 H(i,j)-=.5*JxW[pts]*weight[pts]*phi[i][pts]*normal[pts]*(dphi[j][pts]+ik*dphase[pts]*phi[j][pts]);
563 QGauss qrule2 (
dim-1, fe_type.default_quadrature_order());
565 face_fe->attach_quadrature_rule (&qrule2);
572 unsigned int num_neighbors=0;
574 for (
unsigned int i=0; i<elem->n_neighbors(); i++){
575 if (elem->neighbor_ptr(i)->infinite()){
579 libmesh_assert_greater(num_neighbors,0);
580 libmesh_assert_greater(elem->n_neighbors(), num_neighbors);
585 for(
unsigned int prev_neighbor=0; prev_neighbor<elem->n_neighbors(); prev_neighbor++){
588 const std::vector<Real>& JxW =face_fe->get_JxW();
589 const std::vector<Point>& q_point = face_fe->get_xyz();
590 const std::vector<std::vector<RealGradient> >& dphi = face_fe->get_dphi();
591 const std::vector<std::vector<Real> >& phi = face_fe->get_phi();
592 const std::vector<Point>& normal = face_fe->get_normals();
599 for (; prev_neighbor<elem->n_neighbors(); prev_neighbor++){
600 if (elem->neighbor_ptr(prev_neighbor)->infinite()){
605 if ( prev_neighbor == elem->n_neighbors()){
612 unsigned int found_s=0;
616 for(
unsigned int n=0; n< elem->n_sides(); n++){
617 if (relevant_neighbor->
close_to_point(elem->side_ptr(n)->vertex_average(), tol)){
630 if (tol > 0.2*elem->hmin()){
631 err<<
"Warning: tolerance reached "<<tol<<
","<<std::endl;
632 err<<
" but element-height is "<<elem->hmin()<<std::endl;
633 err<<
" (element id: "<<elem->id()<<
")"<<std::endl;
639 libmesh_assert_equal_to(found_s, 1);
643 face_fe->reinit (elem, side);
644 const unsigned int n_sf =
647 H.
resize (dof_indices.size(), dof_indices.size());
649 for (
unsigned int pts=0; pts<q_point.size(); pts++){
651 for (
unsigned int j=0; j<n_sf; j++){
652 for (
unsigned int i=0; i<n_sf; i++){
654 H(i,j)+=.5*JxW[pts]*normal[pts]*phi[i][pts]*dphi[j][pts];
675#ifdef LIBMESH_HAVE_SLEPC
694 ierr = STSetType(st, STSHIFT);
698#if SLEPC_VERSION_LESS_THAN(3,1,0)
699 ierr = STSetType(st, STSINV);
701 ierr = STSetType(st, STSINVERT);
705 ierr = STSetType(st, STCAYLEY);
729#ifndef LIBMESH_ENABLE_INFINITE_ELEMENTS
744 std::ostringstream re_output;
745 re_output<<
"re_"<<output;
746 std::ostringstream im_output;
747 im_output<<
"im_"<<output;
748 std::ostringstream abs_output;
749 abs_output<<
"abs_"<<output;
752 std::ofstream im_out(re_output.str());
753 std::ofstream re_out(im_output.str());
754 std::ofstream abs_out(abs_output.str());
762 for (
int pts=1;pts<=N;pts++)
766 q_point =
Point(start+ 2*pts*r/N, 0., 0.);
772 re_out<<
" "<<std::setw(12)<<q_point(0);
773 im_out<<
" "<<std::setw(12)<<q_point(0);
774 abs_out<<
" "<<std::setw(12)<<q_point(0);
775 re_out<<
" "<<std::setw(12)<<std::scientific<<std::setprecision(6)<<
std::real(soln);
776 im_out<<
" "<<std::setw(12)<<std::scientific<<std::setprecision(6)<<
std::imag(soln);
777 abs_out<<
" "<<std::setw(12)<<std::scientific<<std::setprecision(6)<<std::abs(soln);
779 re_out<<
" "<<std::setw(12)<<std::scientific<<std::setprecision(6)<<
std::imag(grad(0)*soln)<<std::endl;
780 im_out<<
" "<<std::setw(12)<<std::scientific<<std::setprecision(6)<<
std::imag(grad(0)*soln)<<std::endl;
781 abs_out<<
" "<<std::setw(12)<<std::scientific<<std::setprecision(6)<<std::abs(
std::imag(grad(0)*soln))<<std::endl;
785 libmesh_assert_less(std::abs(std::abs(soln)-0.08*exp(-q_point.norm())), .002);
A class that interfaces the SolverConfiguration to add the SLEPC option SetST.
libMesh::SlepcEigenSolver< libMesh::Number > & _slepc_solver
The linear solver object that we are configuring.
SlepcSolverConfiguration(libMesh::SlepcEigenSolver< libMesh::Number > &slepc_eigen_solver)
Constructor: get a reference to the SlepcEigenSolver variable to be able to manipulate it.
void SetST(SpectralTransform st)
This is the main functionality of this little class.
virtual void configure_solver() override
Apply solver options to a particular solver.
~SlepcSolverConfiguration()
empty destructor
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().
This class handles the numbering of degrees of freedom on a mesh.
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
void constrain_element_matrix(DenseMatrix< Number > &matrix, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true) const
Constrains the element matrix.
const FEType & variable_type(const unsigned int i) const
void set_solver_configuration(SolverConfiguration &solver_configuration)
Set the solver configuration object.
Manages consistently variables, degrees of freedom, and coefficient vectors for eigenvalue problems.
void set_eigenproblem_type(EigenProblemType ept)
Sets the type of the current eigen problem.
const SparseMatrix< Number > & get_matrix_B() const
virtual void solve() override
Assembles & solves the eigen system.
virtual std::pair< Real, Real > get_eigenpair(dof_id_type i)
unsigned int get_n_converged() const
const SparseMatrix< Number > & get_matrix_A() const
const EigenSolver< Number > & get_eigen_solver() const
This is the base class from which all geometric element types are derived.
virtual Real hmin() const
virtual bool close_to_point(const Point &p, Real tol) const
const Elem * neighbor_ptr(unsigned int i) const
This is the EquationSystems class.
const MeshBase & get_mesh() const
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.
virtual unsigned int n_quadrature_points() const
virtual_for_inffe const std::vector< Point > & get_xyz() const
virtual void reinit(const Elem *elem, const std::vector< Point > *const pts=nullptr, const std::vector< Real > *const weights=nullptr)=0
This is at the core of this class.
FEType get_fe_type() const
virtual const std::vector< Real > & get_JxWxdecay_sq() const
This function is the variant of get_JxW() for InfFE.
This class forms the foundation from which generic finite elements may be derived.
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
static std::unique_ptr< FEGenericBase > build_InfFE(const unsigned int dim, const FEType &type)
Builds a specific infinite element type.
const std::vector< OutputGradient > & get_dphase() const
virtual const std::vector< Real > & get_Sobolev_weightxR_sq() const
virtual const std::vector< std::vector< OutputGradient > > & get_dphi_over_decayxR() const
virtual const std::vector< std::vector< OutputShape > > & get_phi_over_decayxR() const
virtual const std::vector< RealGradient > & get_Sobolev_dweightxR_sq() const
static unsigned int n_dofs(const unsigned int dim, const FEType &fe_t, const ElemType t)
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
This class is used to build infinite elements on top of an existing mesh.
const Point build_inf_elem(const bool be_verbose=false)
Build infinite elements atop a volume-based mesh, determine origin automatically.
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
This is the MeshBase class.
unsigned int mesh_dimension() const
virtual SimpleRange< element_iterator > active_local_subdomain_elements_ptr_range(subdomain_id_type sid)=0
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true, const bool assert_valid=true)=0
Locate element face (edge in 2D) neighbors.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
T & set(const std::string &)
const T & get(std::string_view) const
A Point defines a location in LIBMESH_DIM dimensional Real space.
This class implements specific orders of Gauss quadrature.
This class provides an interface to the SLEPc eigenvalue solver library from http://slepc....
This class stores solver configuration data, e.g.
virtual void add_matrix(const DenseMatrix< T > &dm, const std::vector< numeric_index_type > &rows, const std::vector< numeric_index_type > &cols)=0
Add the full matrix dm to the SparseMatrix.
Manages consistently variables, degrees of freedom, and coefficient vectors.
Number point_value(unsigned int var, const Point &p, const bool insist_on_success=true, const NumericVector< Number > *sol=nullptr) const
void attach_assemble_function(void fptr(EquationSystems &es, const std::string &name))
Register a user function to use in assembling the system matrix and RHS.
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.
unsigned int variable_number(std::string_view var) const
Gradient point_gradient(unsigned int var, const Point &p, const bool insist_on_success=true, const NumericVector< Number > *sol=nullptr) const
const DofMap & get_dof_map() const
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
void line_print(EquationSystems &es, std::string output, std::string SysName)
void assemble_SchroedingerEquation(EquationSystems &, const std::string &)
In this function, we assemble the actual system matrices.
SpectralTransform
Defines an enum for spectral tronsformations applied before solving the (generalised) eigenproblem.
The libMesh namespace provides an interface to certain functionality in the library.
std::complex< Real > Complex
void libmesh_ignore(const Args &...)
static constexpr Real TOLERANCE
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
boost::multiprecision::float128 real(const boost::multiprecision::float128 in)
boost::multiprecision::float128 imag(const boost::multiprecision::float128)