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.