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)
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";
321 #endif // LIBMESH_ENABLE_INFINITE_ELEMENTS 322 #endif // LIBMESH_HAVE_SLEPC 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++)
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;
614 Real tol=0.01*elem->hmin();
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];
672 #endif // LIBMESH_ENABLE_INFINITE_ELEMENTS && LIBMESH_HAVE_SLEPC 675 #ifdef LIBMESH_HAVE_SLEPC 684 PetscErrorCode ierr = EPSGetST(_slepc_solver.eps(), &st);
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);
719 #endif // LIBMESH_HAVE_SLEPC 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);
788 #endif //LIBMESH_ENABLE_INFINITE_ELEMENTS SlepcSolverConfiguration(libMesh::SlepcEigenSolver< libMesh::Number > &slepc_eigen_solver)
Constructor: get a reference to the SlepcEigenSolver variable to be able to manipulate it...
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
virtual std::pair< Real, Real > get_eigenpair(dof_id_type i)
This is the EquationSystems class.
static unsigned int n_dofs(const unsigned int dim, const FEType &fe_t, const ElemType t)
virtual const std::vector< Real > & get_Sobolev_weightxR_sq() const
Gradient point_gradient(unsigned int var, const Point &p, const bool insist_on_success=true, const NumericVector< Number > *sol=nullptr) const
boost::multiprecision::float128 real(const boost::multiprecision::float128 in)
A class that interfaces the SolverConfiguration to add the SLEPC option SetST.
const SparseMatrix< Number > & get_matrix_A() const
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
static constexpr Real TOLERANCE
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
const SparseMatrix< Number > & get_matrix_B() const
const FEType & variable_type(const unsigned int c) const
This is the base class from which all geometric element types are derived.
Number point_value(unsigned int var, const Point &p, const bool insist_on_success=true, const NumericVector< Number > *sol=nullptr) const
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.
const EigenSolver< Number > & get_eigen_solver() const
void assemble_SchroedingerEquation(EquationSystems &, const std::string &)
In this function, we assemble the actual system matrices.
const T_sys & get_system(std::string_view name) const
void line_print(EquationSystems &es, std::string output, std::string SysName)
This is the MeshBase class.
const std::vector< OutputGradient > & get_dphase() const
unsigned int variable_number(std::string_view var) const
int main(int argc, char **argv)
libMesh::SlepcEigenSolver< libMesh::Number > & _slepc_solver
The linear solver object that we are configuring.
FEType get_fe_type() const
This class handles the numbering of degrees of freedom on a mesh.
void libmesh_ignore(const Args &...)
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.
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true)=0
Locate element face (edge in 2D) neighbors.
const T & get(std::string_view) const
void SetST(SpectralTransform st)
This is the main functionality of this little class.
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 const std::vector< Real > & get_JxWxdecay_sq() const
This function is the variant of get_JxW() for InfFE.
virtual unsigned int n_quadrature_points() const
Manages consistently variables, degrees of freedom, and coefficient vectors.
virtual const std::vector< std::vector< OutputShape > > & get_phi_over_decayxR() const
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.
SpectralTransform
Defines an enum for spectral tronsformations applied before solving the (generalised) eigenproblem...
This class stores solver configuration data, e.g.
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.
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_for_inffe const std::vector< Point > & get_xyz() 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.
virtual void solve() override
Assembles & solves the eigen system.
This class is used to build infinite elements on top of an existing mesh.
std::complex< Real > Complex
const Elem * neighbor_ptr(unsigned int i) const
virtual bool close_to_point(const Point &p, Real tol) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual SimpleRange< element_iterator > active_local_subdomain_elements_ptr_range(subdomain_id_type sid)=0
const Point build_inf_elem(const bool be_verbose=false)
Build infinite elements atop a volume-based mesh, determine origin automatically. ...
~SlepcSolverConfiguration()
empty destructor
T & set(const std::string &)
const MeshBase & get_mesh() const
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
This class implements specific orders of Gauss quadrature.
unsigned int mesh_dimension() const
Parameters parameters
Data structure holding arbitrary parameters.
void set_eigenproblem_type(EigenProblemType ept)
Sets the type of the current eigen problem.
static std::unique_ptr< FEGenericBase > build_InfFE(const unsigned int dim, const FEType &type)
Builds a specific infinite element type.
virtual const std::vector< RealGradient > & get_Sobolev_dweightxR_sq() const
boost::multiprecision::float128 imag(const boost::multiprecision::float128)
unsigned int get_n_converged() const
virtual void init()
Initialize all the systems.
void set_solver_configuration(SolverConfiguration &solver_configuration)
Set the solver configuration object.
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.
Manages consistently variables, degrees of freedom, and coefficient vectors for eigenvalue problems...
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
virtual void configure_solver() override
Apply solver options to a particular solver.
const DofMap & get_dof_map() const
A Point defines a location in LIBMESH_DIM dimensional Real space.
This class forms the foundation from which generic finite elements may be derived.
virtual const std::vector< std::vector< OutputGradient > > & get_dphi_over_decayxR() 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.