25 #include <queso/Defines.h>
27 #ifdef QUESO_HAVE_LIBMESH
32 #include <boost/shared_ptr.hpp>
34 #include <queso/FunctionOperatorBuilder.h>
35 #include <queso/LibMeshNegativeLaplacianOperator.h>
36 #include <libmesh/libmesh_common.h>
37 #include <libmesh/mesh.h>
38 #include <libmesh/equation_systems.h>
39 #include <libmesh/condensed_eigen_system.h>
40 #include <libmesh/auto_ptr.h>
41 #include <libmesh/fe_base.h>
42 #include <libmesh/quadrature_gauss.h>
43 #include <libmesh/dense_matrix.h>
44 #include <libmesh/sparse_matrix.h>
45 #include <libmesh/dof_map.h>
46 #include <libmesh/id_types.h>
47 #include <libmesh/elem.h>
48 #include <libmesh/zero_function.h>
49 #include <libmesh/dirichlet_boundaries.h>
50 #include <libmesh/utility.h>
51 #include <libmesh/string_to_enum.h>
52 #include <libmesh/enum_order.h>
53 #include <libmesh/enum_fe_family.h>
57 LibMeshNegativeLaplacianOperator::LibMeshNegativeLaplacianOperator(
58 const FunctionOperatorBuilder & builder, libMesh::MeshBase & m)
59 : LibMeshOperatorBase(builder, m)
61 boost::shared_ptr<libMesh::EquationSystems> es(this->equation_systems);
65 libMesh::CondensedEigenSystem & eigen_system =
66 es->get_system<libMesh::CondensedEigenSystem>(
"Eigensystem");
71 unsigned int u_var = eigen_system.add_variable(
"u",
72 libMesh::Utility::string_to_enum<libMeshEnums::Order>(this->builder.order),
73 libMesh::Utility::string_to_enum<libMeshEnums::FEFamily>(this->builder.family));
77 eigen_system.attach_assemble_object(*
this);
81 es->parameters.set<
unsigned int>(
"eigenpairs") =
82 this->builder.num_req_eigenpairs;
83 es->parameters.set<
unsigned int>(
"basis vectors") =
84 this->builder.num_req_eigenpairs * 3;
87 es->parameters.set<libMesh::Real>(
"linear solver tolerance") =
88 pow(libMesh::TOLERANCE, 5./3.);
89 es->parameters.set<
unsigned int>(
"linear solver maximum iterations") = 1000;
93 eigen_system.set_eigenproblem_type(libMeshEnums::GHEP);
97 eigen_system.eigen_solver->set_position_of_spectrum
98 (libMeshEnums::SMALLEST_MAGNITUDE);
102 std::set<libMesh::boundary_id_type> boundary_ids;
103 boundary_ids.insert(0);
104 boundary_ids.insert(1);
105 boundary_ids.insert(2);
106 boundary_ids.insert(3);
109 std::vector<unsigned int> vars;
110 vars.push_back(u_var);
113 libMesh::ZeroFunction<> zf;
114 libMesh::DirichletBoundary dirichlet_bc(boundary_ids, vars, &zf);
115 eigen_system.get_dof_map().add_dirichlet_boundary(dirichlet_bc);
121 std::set<unsigned int> global_dirichlet_dof_ids;
122 libMesh::DofConstraints::const_iterator
it =
123 eigen_system.get_dof_map().constraint_rows_begin();
125 for ( ; it != eigen_system.get_dof_map().constraint_rows_end(); ++
it) {
126 global_dirichlet_dof_ids.insert(it->first);
129 eigen_system.initialize_condensed_dofs(global_dirichlet_dof_ids);
132 eigen_system.solve();
135 this->nconv = eigen_system.get_n_converged();
138 LibMeshNegativeLaplacianOperator::~LibMeshNegativeLaplacianOperator()
142 void LibMeshNegativeLaplacianOperator::assemble()
144 #ifdef LIBMESH_HAVE_SLEPC
146 boost::shared_ptr<libMesh::EquationSystems> es(this->equation_systems);
149 const libMesh::MeshBase& mesh = es->get_mesh();
152 const unsigned int dim = mesh.mesh_dimension();
155 libMesh::EigenSystem & eigen_system = es->get_system<libMesh::EigenSystem>(
"Eigensystem");
159 libMesh::FEType fe_type = eigen_system.get_dof_map().variable_type(0);
162 libMesh::SparseMatrix<libMesh::Number>& matrix_A = *eigen_system.matrix_A;
163 libMesh::SparseMatrix<libMesh::Number>& matrix_B = *eigen_system.matrix_B;
169 libMesh::AutoPtr<libMesh::FEBase> fe (libMesh::FEBase::build(dim, fe_type));
173 libMesh::QGauss qrule(dim, fe_type.default_quadrature_order());
176 fe->attach_quadrature_rule (&qrule);
179 const std::vector<libMesh::Real>& JxW = fe->get_JxW();
182 const std::vector<std::vector<libMesh::Real> >& phi = fe->get_phi();
183 const std::vector<std::vector<libMesh::RealGradient> >& dphi = fe->get_dphi();
188 const libMesh::DofMap& dof_map = eigen_system.get_dof_map();
191 libMesh::DenseMatrix<libMesh::Number> Me;
192 libMesh::DenseMatrix<libMesh::Number> Ke;
197 std::vector<libMesh::dof_id_type> dof_indices;
205 libMesh::MeshBase::const_element_iterator el = mesh.active_local_elements_begin();
206 const libMesh::MeshBase::const_element_iterator end_el =
207 mesh.active_local_elements_end();
209 for ( ; el != end_el; ++el) {
212 const libMesh::Elem* elem = *el;
218 dof_map.dof_indices(elem, dof_indices);
232 Ke.resize(dof_indices.size(), dof_indices.size());
233 Me.resize(dof_indices.size(), dof_indices.size());
241 for (
unsigned int qp=0; qp < qrule.n_points(); qp++)
242 for (
unsigned int i=0; i < phi.size(); i++)
243 for (
unsigned int j=0; j < phi.size(); j++)
245 Me(i, j) += JxW[qp] * phi[i][qp] * phi[j][qp];
246 Ke(i, j) += JxW[qp] * (dphi[i][qp] * dphi[j][qp]);
263 matrix_A.add_matrix (Ke, dof_indices);
264 matrix_B.add_matrix (Me, dof_indices);
268 #endif // LIBMESH_HAVE_SLEPC
271 void LibMeshNegativeLaplacianOperator::print_info()
const
274 this->equation_systems->get_mesh().print_info();
275 this->equation_systems->print_info();
280 #endif // QUESO_HAVE_LIBMESH
that you receive source code or can get it if you want it