22#include "libmesh/libmesh.h"
23#include "libmesh/mesh.h"
24#include "libmesh/mesh_generation.h"
25#include "libmesh/linear_implicit_system.h"
26#include "libmesh/equation_systems.h"
29#include "libmesh/fe.h"
32#include "libmesh/quadrature_gauss.h"
36#include "libmesh/numeric_vector.h"
37#include "libmesh/sparse_matrix.h"
38#include "libmesh/dense_matrix.h"
39#include "libmesh/dense_vector.h"
40#include "libmesh/elem.h"
41#include "libmesh/enum_solver_package.h"
45#include "libmesh/dof_map.h"
47#ifdef LIBMESH_HAVE_PETSC
49#include "libmesh/petsc_matrix.h"
50#include "libmesh/petsc_vector.h"
60 const std::string & system_name);
67int main (
int argc,
char ** argv)
76 for (
int i=1; i<argc; i++)
82 libmesh_example_requires(2 <= LIBMESH_DIM,
"2D support");
121 system.add_matrix(
"preconditioner");
122#ifdef LIBMESH_HAVE_PETSC
123#if PETSC_RELEASE_GREATER_EQUALS(3, 19, 0)
124 system.get_matrix(
"preconditioner").use_hash_table(
true);
129 equation_systems.
init();
137#ifdef LIBMESH_HAVE_PETSC
138 auto & sys_matrix = cast_ref<PetscMatrix<Number> &>(system.get_system_matrix());
139 auto & pre_matrix = cast_ref<PetscMatrix<Number> &>(system.get_matrix(
"preconditioner"));
140 LibmeshPetscCall2(system.comm(), PetscOptionsSetValue(NULL,
"-ksp_monitor", NULL));
142 auto solve = [&sys_matrix, &pre_matrix, &system]() {
148 LibmeshPetscCall2(system.comm(), KSPCreate(system.comm().get(), &ksp));
149 LibmeshPetscCall2(system.comm(), KSPSetOperators(ksp, sys_matrix.mat(), pre_matrix.mat()));
150 LibmeshPetscCall2(system.comm(), KSPSetFromOptions(ksp));
151 LibmeshPetscCall2(system.comm(),
161#if !PETSC_VERSION_LESS_THAN(3, 23, 0)
164 pre_matrix.restore_original_nonzero_pattern();
169 system.solution->zero();
190 const std::string & libmesh_dbg_var(system_name))
195 libmesh_assert_equal_to (system_name,
"Poisson");
214 FEType fe_type = dof_map.variable_type(0);
228 fe->attach_quadrature_rule (&qrule);
241 fe_face->attach_quadrature_rule (&qface);
247 const std::vector<Real> & JxW = fe->get_JxW();
252 const std::vector<Point> & q_point = fe->get_xyz();
255 const std::vector<std::vector<Real>> & phi = fe->get_phi();
259 const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
273 std::vector<dof_id_type> dof_indices;
278 auto & pre_matrix = system.
get_matrix(
"preconditioner");
293 for (
const auto & elem :
mesh.active_local_element_ptr_range())
299 dof_map.dof_indices (elem, dof_indices);
306 const unsigned int n_dofs =
307 cast_int<unsigned int>(dof_indices.size());
317 libmesh_assert_equal_to (n_dofs, phi.size());
328 Ke.
resize (n_dofs, n_dofs);
334 for (
unsigned int qp=0; qp<qrule.
n_points(); qp++)
340 for (
unsigned int i=0; i != n_dofs; i++)
341 for (
unsigned int j=0; j != n_dofs; j++)
343 Ke(i,j) += JxW[qp]*(dphi[i][qp]*dphi[j][qp]);
351 const Real x = q_point[qp](0);
352 const Real y = q_point[qp](1);
353 const Real eps = 1.e-3;
376 for (
unsigned int i=0; i != n_dofs; i++)
377 Fe(i) += JxW[qp]*fxy*phi[i][qp];
416 for (
auto side : elem->side_index_range())
417 if (elem->neighbor_ptr(side) ==
nullptr)
421 const std::vector<std::vector<Real>> & phi_face = fe_face->get_phi();
425 const std::vector<Real> & JxW_face = fe_face->get_JxW();
430 const std::vector<Point> & qface_point = fe_face->get_xyz();
434 fe_face->reinit(elem, side);
439 libmesh_assert_equal_to (n_dofs, phi_face.size());
442 for (
unsigned int qp=0; qp<qface.
n_points(); qp++)
446 const Real xf = qface_point[qp](0);
447 const Real yf = qface_point[qp](1);
451 const Real penalty = 1.e10;
457 for (
unsigned int i=0; i != n_dofs; i++)
458 for (
unsigned int j=0; j != n_dofs; j++)
459 Ke(i,j) += JxW_face[qp]*penalty*phi_face[i][qp]*phi_face[j][qp];
463 for (
unsigned int i=0; i != n_dofs; i++)
464 Fe(i) += JxW_face[qp]*penalty*
value*phi_face[i][qp];
474 dof_map.constrain_element_matrix_and_vector (Ke, Fe, dof_indices);
481 pre_matrix.add_matrix(Ke, dof_indices);
Number(* exact_solution)(const Point &p, const Parameters &, const std::string &, const std::string &)
Defines a dense matrix for use in Finite Element-type computations.
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
Defines a dense vector for use in Finite Element-type computations.
void resize(const unsigned int n)
Resize the vector.
This class handles the numbering of degrees of freedom on a mesh.
This is the EquationSystems class.
void print_info(std::ostream &os=libMesh::out) const
Prints information about the equation systems, by default to libMesh::out.
const MeshBase & get_mesh() const
virtual void init()
Initialize all the systems.
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.
const T_sys & get_system(std::string_view name) const
NumericVector< Number > * rhs
The system matrix.
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
const SparseMatrix< Number > & get_system_matrix() const
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and linear solvers ...
This is the MeshBase class.
unsigned int mesh_dimension() const
void print_info(std::ostream &os=libMesh::out, const unsigned int verbosity=0, const bool global=true) const
Prints relevant information about the mesh.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
virtual void add_vector(const T *v, const std::vector< numeric_index_type > &dof_indices)
Computes , where v is a pointer and each dof_indices[i] specifies where to add value v[i].
This class provides a nice interface to PETSc's Vec object.
unsigned int n_points() const
This class implements specific orders of Gauss quadrature.
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.
const SparseMatrix< Number > & get_matrix(std::string_view mat_name) const
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.
const DofMap & get_dof_map() const
void assemble_poisson(EquationSystems &es, const std::string &system_name)
The libMesh namespace provides an interface to certain functionality in the library.
SolverPackage default_solver_package()
Tnew cast_ptr(Told *oldvar)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real