25 #include <queso/Defines.h>
27 #ifdef QUESO_HAVE_LIBMESH
32 #include <queso/FunctionOperatorBuilder.h>
33 #include <queso/LibMeshFunction.h>
34 #include <queso/LibMeshOperatorBase.h>
36 #include <libmesh/libmesh.h>
37 #include <libmesh/mesh.h>
38 #include <libmesh/mesh_generation.h>
39 #include <libmesh/equation_systems.h>
40 #include <libmesh/explicit_system.h>
41 #include <libmesh/condensed_eigen_system.h>
42 #include <libmesh/numeric_vector.h>
43 #include <libmesh/exodusII_io.h>
44 #include <libmesh/parallel.h>
45 #include <libmesh/parallel_implementation.h>
49 LibMeshOperatorBase::LibMeshOperatorBase(
50 const FunctionOperatorBuilder & builder, libMesh::MeshBase & m)
52 equation_systems(new libMesh::EquationSystems(m)),
55 #ifndef LIBMESH_HAVE_SLEPC
56 if (m.processor_id() == 0)
57 std::cerr <<
"ERROR: This example requires libMesh to be\n"
58 <<
"compiled with SLEPc eigen solvers support!"
62 #ifdef LIBMESH_DEFAULT_SINGLE_PRECISION
64 libmesh_example_assert(
false,
"--disable-singleprecision");
67 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
70 libmesh_example_assert(
false,
"--disable-complex");
75 this->equation_systems->add_system<libMesh::CondensedEigenSystem>(
"Eigensystem");
77 #endif // LIBMESH_HAVE_SLEPC
80 LibMeshOperatorBase::~LibMeshOperatorBase()
84 void LibMeshOperatorBase::save_converged_evals(
const std::string & filename)
const
87 std::ofstream evals_file(filename.c_str());
89 std::pair<libMesh::Real, libMesh::Real> eval;
90 for (i = 0; i < this->nconv; i++) {
91 eval = this->equation_systems
92 ->get_system<libMesh::EigenSystem>(
"Eigensystem").get_eigenpair(i);
93 if (equation_systems->processor_id() == 0) {
94 evals_file << eval.first <<
" " << eval.second << std::endl;
97 if (this->equation_systems->processor_id() == 0) {
102 void LibMeshOperatorBase::save_converged_evec(
const std::string & filename,
103 unsigned int i)
const
105 if (i < this->nconv) {
106 boost::shared_ptr<libMesh::EquationSystems> es(this->equation_systems);
107 es->get_system<libMesh::EigenSystem>(
"Eigensystem").get_eigenpair(i);
108 libMesh::ExodusII_IO(es->get_mesh()).write_equation_systems(filename, *es);
111 std::cerr <<
"Warning: eigenpair " << i
112 <<
" did not converge. Not saving."
117 unsigned int LibMeshOperatorBase::get_num_converged()
const {
121 double LibMeshOperatorBase::get_eigenvalue(
unsigned int i)
const
123 if (i < this->nconv) {
124 std::pair<libMesh::Real, libMesh::Real> eval;
125 boost::shared_ptr<libMesh::EquationSystems> es(this->equation_systems);
126 eval = es->get_system<libMesh::EigenSystem>(
"Eigensystem").get_eigenpair(i);
134 double LibMeshOperatorBase::get_inverted_eigenvalue(
unsigned int i)
const
136 return 1.0 / this->get_eigenvalue(i);
139 libMesh::EquationSystems & LibMeshOperatorBase::get_equation_systems()
const
141 return *this->equation_systems;
144 boost::shared_ptr<FunctionBase>
145 LibMeshOperatorBase::inverse_kl_transform(std::vector<double> & xi,
149 boost::shared_ptr<libMesh::EquationSystems> es(this->equation_systems);
150 LibMeshFunction *kl =
new LibMeshFunction(this->builder, es->get_mesh());
155 this->equation_systems->comm().broadcast(xi);
157 boost::shared_ptr<libMesh::EquationSystems> kl_eq_sys(kl->get_equation_systems());
159 std::pair<libMesh::Real, libMesh::Real> eval;
160 for (i = 0; i < this->get_num_converged(); i++) {
161 eval = es->get_system<libMesh::EigenSystem>(
"Eigensystem").get_eigenpair(i);
162 kl_eq_sys->get_system<libMesh::ExplicitSystem>(
"Function").solution->add(
163 xi[i] / pow(eval.first, alpha / 2.0),
164 *es->get_system<libMesh::EigenSystem>(
"Eigensystem").solution);
167 boost::shared_ptr<FunctionBase> ap(kl);
173 #endif // QUESO_HAVE_LIBMESH