Go to the documentation of this file.
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
65 EXTERN_C_FOR_SLEPC_BEGIN
66 # include <slepceps.h>
67 EXTERN_C_FOR_SLEPC_END
68 #endif // LIBMESH_HAVE_SLEPC
73 #ifdef LIBMESH_HAVE_SLEPC
98 _slepc_solver(slepc_eigen_solver),
107 virtual void configure_solver()
override;
124 #endif // LIBMESH_HAVE_SLEPC
134 int main (
int argc,
char** argv)
141 libmesh_error_msg(
"\nUsage: " << argv[0] <<
" <input-filename>");
146 std::cout <<
"Running " << argv[0];
148 for (
int i=1; i<argc; i++)
149 std::cout <<
" " << argv[i];
150 std::cout << std::endl << std::endl;
154 #ifndef LIBMESH_HAVE_SLEPC
155 libmesh_example_requires(
false,
"--enable-slepc");
157 #ifndef LIBMESH_ENABLE_INFINITE_ELEMENTS
158 libmesh_example_requires(
false,
"--enable-ifem");
161 #ifndef LIBMESH_USE_COMPLEX_NUMBERS
162 libmesh_example_requires(
false,
"--enable-complex");
165 #ifdef LIBMESH_DEFAULT_SINGLE_PRECISION
167 libmesh_example_requires(
false,
"--disable-singleprecision");
175 libmesh_example_requires(3 <= LIBMESH_DIM,
"3D support");
178 const unsigned int nev = cl(
"nev",1);
179 Real E = cl(
"Energy", -.5);
180 Real r=cl(
"radius", 4.);
181 unsigned int maxiter=cl(
"maxiter", 700);
199 if (elem->infinite())
201 elem->subdomain_id() = 1;
203 elem->neighbor_ptr(0)->subdomain_id()=2;
234 eq_sys.
parameters.
set<
unsigned int>(
"basis vectors") = nev*3+4;
238 eq_sys.
parameters.
set<
unsigned int>(
"linear solver maximum iterations") = maxiter;
241 #if SLEPC_VERSION_LESS_THAN(2,3,2)
252 libmesh_cast_ptr<SlepcEigenSolver<Number>* >( &(*eig_sys.
eigen_solver) );
280 out <<
"Number of converged eigenpairs: " << nconv <<
"\n";
283 for(
unsigned int i=0; i<nconv; i++)
288 Complex eigenvalue(eigpair.first, eigpair.second);
289 out<<
" "<<eigenvalue<<std::endl;
295 if (eigpair.first > 0.)
308 #ifdef LIBMESH_HAVE_EXODUS_API
310 std::ostringstream eigenvector_output_name;
311 eigenvector_output_name <<
"U" <<
"-" << i <<
"_inf.e";
318 std::ostringstream file;
319 file <<
"infini_" << i <<
".txt";
325 #endif // LIBMESH_ENABLE_INFINITE_ELEMENTS
326 #endif // LIBMESH_HAVE_SLEPC
338 #if defined(LIBMESH_ENABLE_INFINITE_ELEMENTS) && defined(LIBMESH_HAVE_SLEPC)
341 libmesh_assert_equal_to (system_name,
"EigenSE");
362 QGauss qrule (
dim, fe_type.default_quadrature_order());
372 fe->attach_quadrature_rule (&qrule);
373 inf_fe->attach_quadrature_rule (&qrule);
404 std::vector<dof_id_type> dof_indices;
423 if (elem->infinite())
438 const std::vector<Real>& JxW = cfe->
get_JxW();
441 const std::vector<std::vector<Real> >& phi = cfe->
get_phi();
442 const std::vector<std::vector<RealGradient> >& dphi = cfe->
get_dphi();
443 const std::vector<Point>& q_point = cfe->
get_xyz();
445 const std::vector<RealGradient>& dphase = cfe->
get_dphase();
461 M.
resize (dof_indices.size(), dof_indices.size());
462 H.
resize (dof_indices.size(), dof_indices.size());
468 for (
unsigned int qp=0; qp<max_qp; qp++)
472 potval=-1./(q_point[qp]).
norm();
477 for (
unsigned int i=0; i<n_sf; i++)
479 for (
unsigned int j=0; j<n_sf; j++)
485 temp = (dweight[qp]*phi[i][qp]+
weight[qp]*(dphi[i][qp]-ik*dphase[qp]*phi[i][qp]))
486 *(dphi[j][qp]+ik*dphase[qp]*phi[j][qp]);
489 H(i,j) += JxW[qp]*(0.5*temp + potval*
weight[qp]*phi[i][qp]*phi[j][qp]);
491 M(i,j)+= JxW[qp]*
weight[qp]*phi[i][qp]*phi[j][qp];
521 QGauss qrule2 (
dim-1, fe_type.default_quadrature_order());
523 face_fe->attach_quadrature_rule (&qrule2);
527 for ( ; el != end_el; ++el){
528 const Elem* elem = *el;
534 const std::vector<Real>& JxW = face_fe->get_JxW();
535 const std::vector<Point>& q_point = face_fe->get_xyz();
536 const std::vector<std::vector<RealGradient> >& dphi = face_fe->get_dphi();
537 const std::vector<std::vector<Real> >& phi = face_fe->get_phi();
538 const std::vector<Point>& normal = face_fe->get_normals();
539 const std::vector<RealGradient>& dphase = face_fe->get_dphase();
540 const std::vector<Real>&
weight = face_fe->get_Sobolev_weight();
543 const unsigned int side=0;
544 face_fe->reinit (elem, side);
545 unsigned int n_sf = face_fe->n_shape_functions();
547 H.
resize (dof_indices.size(), dof_indices.size());
549 for (
unsigned int pts=0; pts<q_point.size(); pts++){
550 for (
unsigned int i=0; i<n_sf; i++){
552 for (
unsigned int j=0; j<n_sf; j++){
555 H(i,j)-=.5*JxW[pts]*
weight[pts]*phi[i][pts]*normal[pts]*(dphi[j][pts]+ik*dphase[pts]*phi[j][pts]);
564 QGauss qrule2 (
dim-1, fe_type.default_quadrature_order());
566 face_fe->attach_quadrature_rule (&qrule2);
570 for ( ; el != end_el; ++el){
571 const Elem* elem = *el;
576 unsigned int num_neighbors=0;
578 for (
unsigned int i=0; i<elem->
n_neighbors(); i++){
583 libmesh_assert_greater(num_neighbors,0);
584 libmesh_assert_greater(elem->
n_neighbors(), num_neighbors);
589 for(
unsigned int prev_neighbor=0; prev_neighbor<elem->
n_neighbors(); prev_neighbor++){
592 const std::vector<Real>& JxW =face_fe->get_JxW();
593 const std::vector<Point>& q_point = face_fe->get_xyz();
594 const std::vector<std::vector<RealGradient> >& dphi = face_fe->get_dphi();
595 const std::vector<std::vector<Real> >& phi = face_fe->get_phi();
596 const std::vector<Point>& normal = face_fe->get_normals();
603 for (; prev_neighbor<elem->
n_neighbors(); prev_neighbor++){
616 unsigned int found_s=0;
620 for(
unsigned int n=0; n< elem->
n_sides(); n++){
634 if (tol > 0.2*elem->
hmin()){
635 err<<
"Warning: tolerance reached "<<tol<<
","<<std::endl;
636 err<<
" but element-height is "<<elem->
hmin()<<std::endl;
637 err<<
" (element id: "<<elem->
id()<<
")"<<std::endl;
643 libmesh_assert_equal_to(found_s, 1);
647 face_fe->reinit (elem, side);
648 unsigned int n_sf = face_fe->n_shape_functions();
650 H.
resize (dof_indices.size(), dof_indices.size());
652 for (
unsigned int pts=0; pts<q_point.size(); pts++){
654 for (
unsigned int j=0; j<n_sf; j++){
655 for (
unsigned int i=0; i<n_sf; i++){
657 H(i,j)+=.5*JxW[pts]*normal[pts]*phi[i][pts]*dphi[j][pts];
675 #endif // LIBMESH_ENABLE_INFINITE_ELEMENTS && LIBMESH_HAVE_SLEPC
678 #ifdef LIBMESH_HAVE_SLEPC
687 PetscErrorCode
ierr = EPSGetST(_slepc_solver.eps(), &st);
697 ierr = STSetType(st, STSHIFT);
701 #if SLEPC_VERSION_LESS_THAN(3,1,0)
702 ierr = STSetType(st, STSINV);
704 ierr = STSetType(st, STSINVERT);
708 ierr = STSetType(st, STCAYLEY);
722 #endif // LIBMESH_HAVE_SLEPC
732 #ifndef LIBMESH_ENABLE_INFINITE_ELEMENTS
747 std::ostringstream re_output;
748 re_output<<
"re_"<<output;
749 std::ostringstream im_output;
750 im_output<<
"im_"<<output;
751 std::ostringstream abs_output;
752 abs_output<<
"abs_"<<output;
755 std::ofstream im_out(re_output.str());
756 std::ofstream re_out(im_output.str());
757 std::ofstream abs_out(abs_output.str());
765 for (
int pts=1;pts<=N;pts++)
769 q_point =
Point(start+ 2*pts*r/N, 0., 0.);
775 re_out<<
" "<<std::setw(12)<<q_point(0);
776 im_out<<
" "<<std::setw(12)<<q_point(0);
777 abs_out<<
" "<<std::setw(12)<<q_point(0);
778 re_out<<
" "<<std::setw(12)<<std::scientific<<std::setprecision(6)<<
std::real(soln);
779 im_out<<
" "<<std::setw(12)<<std::scientific<<std::setprecision(6)<<
std::imag(soln);
780 abs_out<<
" "<<std::setw(12)<<std::scientific<<std::setprecision(6)<<
std::abs(soln);
782 re_out<<
" "<<std::setw(12)<<std::scientific<<std::setprecision(6)<<
std::imag(grad(0)*soln)<<std::endl;
783 im_out<<
" "<<std::setw(12)<<std::scientific<<std::setprecision(6)<<
std::imag(grad(0)*soln)<<std::endl;
784 abs_out<<
" "<<std::setw(12)<<std::scientific<<std::setprecision(6)<<
std::abs(
std::imag(grad(0)*soln))<<std::endl;
788 libmesh_assert_less(
std::abs(
std::abs(soln)-0.081*exp(-q_point.norm())), .0011);
791 #endif //LIBMESH_ENABLE_INFINITE_ELEMENTS
virtual element_iterator active_local_subdomain_elements_end(subdomain_id_type subdomain_id)=0
Manages consistently variables, degrees of freedom, and coefficient vectors.
virtual unsigned int n_shape_functions() const =0
const Point build_inf_elem(const bool be_verbose=false)
Build infinite elements atop a volume-based mesh, determine origin automatically.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
std::unique_ptr< SparseMatrix< Number > > matrix_A
The system matrix for standard eigenvalue problems.
const std::vector< Point > & get_xyz() const
virtual System & add_system(const std::string &system_type, const std::string &name)
Add the system of type system_type named name to the systems array.
const MeshBase & get_mesh() const
This class implements specific orders of Gauss quadrature.
virtual bool close_to_point(const Point &p, Real tol) const
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Fills the vector di with the global degree of freedom indices for the element.
const std::vector< OutputGradient > & get_dphase() const
virtual SimpleRange< element_iterator > active_local_element_ptr_range()=0
unsigned int n_neighbors() const
virtual void solve() override
Assembles & solves the eigen system.
The libMesh namespace provides an interface to certain functionality in the library.
This class forms the foundation from which generic finite elements may be derived.
const T_sys & get_system(const std::string &name) const
virtual bool infinite() const =0
const std::vector< Real > & get_JxW() const
MetaPhysicL::DualNumber< T, D > sqrt(const MetaPhysicL::DualNumber< T, D > &in)
static const Real TOLERANCE
std::unique_ptr< EigenSolver< Number > > eigen_solver
The EigenSolver, defining which interface, i.e solver package to use.
void set_eigenproblem_type(EigenProblemType ept)
Sets the type of the current eigen problem.
void assemble_SchroedingerEquation(EquationSystems &, const std::string &)
In this function, we assemble the actual system matrices.
unsigned int mesh_dimension() const
const std::vector< std::vector< OutputGradient > > & get_dphi() const
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
static std::unique_ptr< FEGenericBase > build_InfFE(const unsigned int dim, const FEType &type)
Builds a specific infinite element type.
int main(int argc, char **argv)
void resize(const unsigned int new_m, const unsigned int new_n)
Resize the matrix.
unsigned int get_n_converged() const
std::unique_ptr< SparseMatrix< Number > > matrix_B
A second system matrix for generalized eigenvalue problems.
void line_print(EquationSystems &es, std::string output, std::string SysName)
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
virtual SimpleRange< element_iterator > element_ptr_range()=0
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.
This is the MeshBase class.
MetaPhysicL::DualNumber< T, D > abs(const MetaPhysicL::DualNumber< T, D > &in)
std::unique_ptr< T > UniquePtr
void libmesh_ignore(const Args &...)
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
unsigned int add_variable(const std::string &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 init()
Initialize all the systems.
A Point defines a location in LIBMESH_DIM dimensional Real space.
virtual std::unique_ptr< Elem > side_ptr(unsigned int i)=0
This class is used to build infinite elements on top of an existing mesh.
virtual std::pair< Real, Real > get_eigenpair(dof_id_type i)
void SetST(SpectralTransform st)
This is the main functionality of this little class.
double pow(double a, int b)
const FEType & variable_type(const unsigned int c) const
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
void set_solver_configuration(SolverConfiguration &solver_configuration)
Set the solver configuration object.
virtual unsigned int n_quadrature_points() const =0
SlepcSolverConfiguration(libMesh::SlepcEigenSolver< libMesh::Number > &slepc_eigen_solver)
Constructur: get a reference to the SlepcEigenSolver variable to be able to manipulate it.
The definition of the const_element_iterator struct.
SpectralTransform
Defines an enum for spectral tronsformations applied before solving the (generalised) eigenproblem.
This is the EquationSystems class.
T & set(const std::string &)
std::complex< Real > Complex
virtual void write_equation_systems(const std::string &, const EquationSystems &, const std::set< std::string > *system_names=nullptr)
This method implements writing a mesh with data to a specified file where the data is taken from the ...
const std::vector< RealGradient > & get_Sobolev_dweight() 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.
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.
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Number point_value(unsigned int var, const Point &p, const bool insist_on_success=true, const NumericVector< Number > *sol=nullptr) const
Manages consistently variables, degrees of freedom, and coefficient vectors for eigenvalue problems.
This class handles the numbering of degrees of freedom on a mesh.
virtual Real hmin() const
A class that interfaces the SolverConfiguration to add the SLEPC option SetST.
~SlepcSolverConfiguration()
empty destructor
This is the base class from which all geometric element types are derived.
unsigned short int variable_number(const std::string &var) const
MetaPhysicL::DualNumber< T, D > norm(const MetaPhysicL::DualNumber< T, D > &in)
This class stores solver configuration data, e.g.
const DofMap & get_dof_map() const
const Elem * neighbor_ptr(unsigned int i) const
const std::vector< std::vector< OutputShape > > & get_phi() const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
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.
virtual unsigned int n_sides() const =0
const T & get(const std::string &) const
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true)=0
Locate element face (edge in 2D) neighbors.
boost::multiprecision::float128 imag(const boost::multiprecision::float128)
virtual void configure_solver() override
Apply solver options to a particular solver.
Gradient point_gradient(unsigned int var, const Point &p, const bool insist_on_success=true, const NumericVector< Number > *sol=nullptr) const
libMesh::SlepcEigenSolver< libMesh::Number > & _slepc_solver
The linear solver object that we are configuring.
virtual element_iterator active_local_subdomain_elements_begin(subdomain_id_type subdomain_id)=0
const std::vector< Real > & get_Sobolev_weight() const
boost::multiprecision::float128 real(const boost::multiprecision::float128 in)
Parameters parameters
Data structure holding arbitrary parameters.