libMesh
Loading...
Searching...
No Matches
heterogeneous_nonlinear_constraint_test.C
Go to the documentation of this file.
1#include <libmesh/const_function.h>
2#include <libmesh/dense_matrix.h>
3#include <libmesh/dense_vector.h>
4#include <libmesh/dirichlet_boundaries.h>
5#include <libmesh/dof_map.h>
6#include <libmesh/elem.h>
7#include <libmesh/equation_systems.h>
8#include <libmesh/fe.h>
9#include <libmesh/mesh.h>
10#include <libmesh/mesh_generation.h>
11#include <libmesh/nonlinear_implicit_system.h>
12#include <libmesh/nonlinear_solver.h>
13#include <libmesh/numeric_vector.h>
14#include <libmesh/quadrature_gauss.h>
15#include <libmesh/sparse_matrix.h>
16
17#include "test_comm.h"
18#include "libmesh_cppunit.h"
19
20using namespace libMesh;
21
22namespace
23{
30class LaplaceResidualAndJacobian : public NonlinearImplicitSystem::ComputeResidualandJacobian
31{
32public:
33 virtual void residual_and_jacobian(const NumericVector<Number> & soln,
34 NumericVector<Number> * residual,
35 SparseMatrix<Number> * jacobian,
36 NonlinearImplicitSystem & sys) override
37 {
38 const MeshBase & mesh = sys.get_mesh();
39 DofMap & dof_map = sys.get_dof_map();
40 const FEType fe_type = dof_map.variable_type(0);
41
42 std::unique_ptr<FEBase> fe(FEBase::build(1, fe_type));
43 QGauss qrule(1, fe_type.default_quadrature_order());
44 fe->attach_quadrature_rule(&qrule);
45 const auto & JxW = fe->get_JxW();
46 const auto & dphi = fe->get_dphi();
47
48 if (residual)
49 residual->zero();
50 if (jacobian)
51 jacobian->zero();
52
53 std::vector<dof_id_type> dof_indices;
56
57 for (const Elem * elem : mesh.active_local_element_ptr_range())
58 {
59 dof_map.dof_indices(elem, dof_indices);
60 fe->reinit(elem);
61
62 const auto n = dof_indices.size();
63 Re.resize(n);
64 Ke.resize(n, n);
65
66 for (auto qp : index_range(JxW))
67 for (auto i : make_range(n))
68 for (auto j : make_range(n))
69 {
70 const Number k = JxW[qp] * dphi[i][qp] * dphi[j][qp];
71 Ke(i, j) += k;
72 Re(i) += k * soln(dof_indices[j]);
73 }
74
75 dof_map.constrain_element_matrix_and_vector(Ke, Re, dof_indices, false);
76
77 if (residual)
78 residual->add_vector(Re, dof_indices);
79 if (jacobian)
80 jacobian->add_matrix(Ke, dof_indices);
81 }
82 }
83};
84}
85
86class HeterogeneousNonlinearConstraintTest : public CppUnit::TestCase
87{
88public:
90
91#if defined(LIBMESH_ENABLE_DIRICHLET) && defined(LIBMESH_HAVE_PETSC)
93#endif
94
96
97private:
105 {
106 LOG_UNIT_TEST;
107
110
112 auto & sys = es.add_system<NonlinearImplicitSystem>("sys");
113 const auto u = sys.add_variable("u", FIRST, LAGRANGE);
114
115 // build_line's boundary ids
116 const boundary_id_type left_id = 0, right_id = 1;
117 const Real left_value = 2, right_value = 5;
119 DirichletBoundary({left_id}, {u}, ConstFunction<Number>(left_value)));
121 DirichletBoundary({right_id}, {u}, ConstFunction<Number>(right_value)));
122
123 LaplaceResidualAndJacobian assembly;
124 sys.nonlinear_solver->residual_and_jacobian_object = &assembly;
125
126 es.init();
127
128 // Start from an iterate that satisfies neither boundary value, so
129 // the constrained rows have to pull it to them
130 sys.solution->zero();
131 sys.solution->close();
132 sys.update();
133
134 sys.solve();
135
136 CPPUNIT_ASSERT(sys.nonlinear_solver->converged);
137
138 for (const Node * node : mesh.local_node_ptr_range())
139 {
140 const Real x = (*node)(0);
141 const Number exact = left_value + (right_value - left_value) * x;
142 LIBMESH_ASSERT_NUMBERS_EQUAL(
143 exact, (*sys.solution)(node->dof_number(sys.number(), u, 0)), TOLERANCE * TOLERANCE);
144 }
145 }
146};
147
CPPUNIT_TEST(testNonzeroDirichletValues)
LIBMESH_CPPUNIT_TEST_SUITE(HeterogeneousNonlinearConstraintTest)
void testNonzeroDirichletValues()
PetscNonlinearSolver enforces a constraint in each residual it hands PETSc.
Function that returns a single value that never changes.
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 allows one to associate Dirichlet boundary values with a given set of mesh boundary ids an...
This class handles the numbering of degrees of freedom on a mesh.
Definition dof_map.h:181
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition dof_map.C:2203
void add_dirichlet_boundary(const DirichletBoundary &dirichlet_boundary)
Adds a copy of the specified Dirichlet boundary to the system.
const FEType & variable_type(const unsigned int i) const
Definition dof_map.h:2401
void constrain_element_matrix_and_vector(DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true) const
Constrains the element matrix and vector.
Definition dof_map.h:2511
This is the base class from which all geometric element types are derived.
Definition elem.h:96
This is the EquationSystems class.
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.
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...
Definition fe_type.h:197
Order default_quadrature_order() const
Definition fe_type.h:415
This is the MeshBase class.
Definition mesh_base.h:81
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition mesh.h:51
A Node is like a Point, but with more information.
Definition node.h:55
Abstract base class to be used to calculate the residual and Jacobian simultaneously of a nonlinear s...
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and non-linear solv...
virtual void solve() override
Assembles & solves the nonlinear system R(x) = 0.
std::unique_ptr< NonlinearSolver< Number > > nonlinear_solver
The NonlinearSolver defines the default interface used to solve the nonlinear_implicit system.
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
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].
virtual void zero()=0
Set all entries to zero.
This class implements specific orders of Gauss quadrature.
Generic sparse 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.
virtual void zero()=0
Set all entries to 0.
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.
Definition system.C:1344
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition system.h:1655
virtual void update()
Update the local values to reflect the solution on neighboring processors.
Definition system.C:498
const DofMap & get_dof_map() const
Definition system.h:2417
unsigned int number() const
Definition system.h:2393
const MeshBase & get_mesh() const
Definition system.h:2401
static const boundary_id_type left_id
static const boundary_id_type right_id
Communicator * TestCommWorld
CPPUNIT_TEST_SUITE_REGISTRATION(HeterogeneousNonlinearConstraintTest)
MeshBase & mesh
void build_line(UnstructuredMesh &mesh, const unsigned int nx, const Real xmin=0., const Real xmax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
A specialized build_cube() for 1D meshes.
The libMesh namespace provides an interface to certain functionality in the library.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition int_range.h:153
int8_t boundary_id_type
Definition id_types.h:51
static constexpr Real TOLERANCE
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition int_range.h:176