libMesh
Loading...
Searching...
No Matches
Public Member Functions | Private Attributes | List of all members
DualShapeTest Class Reference

This class is for unit testing dual coefficient and shape function values. More...

Inheritance diagram for DualShapeTest:
[legend]

Public Member Functions

 LIBMESH_CPPUNIT_TEST_SUITE (DualShapeTest)
 
 CPPUNIT_TEST (testEdge2Lagrange)
 
 CPPUNIT_TEST (testQuad8Lagrange)
 
 CPPUNIT_TEST (testTri6Lagrange)
 
 CPPUNIT_TEST (testTri7Lagrange)
 
 CPPUNIT_TEST (testL2Lagrange)
 
 CPPUNIT_TEST_SUITE_END ()
 
void testEdge2Lagrange ()
 
void testTransformedDual (const ElemType elem_type, const unsigned int n, const Real vertex_over_mid, const FEFamily family=LAGRANGE)
 Check what the transformed dual basis on QUAD8/TRI6/TRI7 guarantees, none of which the untransformed construction gives: strictly positive weights, reproduction of constants, and biorthogonality against Ntilde = T N rather than N.
 
void testQuad8Lagrange ()
 
void testTri6Lagrange ()
 
void testTri7Lagrange ()
 
void testL2Lagrange ()
 
void setUp ()
 
void tearDown ()
 

Private Attributes

std::unique_ptr< Mesh > _mesh
 
std::unique_ptr< QGauss > _qrule
 
std::unique_ptr< FEBase > _fe
 
Elem * _elem
 

Detailed Description

This class is for unit testing dual coefficient and shape function values.

Definition at line 20 of file dual_shape_verification_test.C.

Member Function Documentation

◆ CPPUNIT_TEST() [1/5]

DualShapeTest::CPPUNIT_TEST ( testEdge2Lagrange  )

◆ CPPUNIT_TEST() [2/5]

DualShapeTest::CPPUNIT_TEST ( testL2Lagrange  )

◆ CPPUNIT_TEST() [3/5]

DualShapeTest::CPPUNIT_TEST ( testQuad8Lagrange  )

◆ CPPUNIT_TEST() [4/5]

DualShapeTest::CPPUNIT_TEST ( testTri6Lagrange  )

◆ CPPUNIT_TEST() [5/5]

DualShapeTest::CPPUNIT_TEST ( testTri7Lagrange  )

◆ CPPUNIT_TEST_SUITE_END()

DualShapeTest::CPPUNIT_TEST_SUITE_END ( )

◆ LIBMESH_CPPUNIT_TEST_SUITE()

DualShapeTest::LIBMESH_CPPUNIT_TEST_SUITE ( DualShapeTest  )

◆ setUp()

void DualShapeTest::setUp ( )
inline

Definition at line 197 of file dual_shape_verification_test.C.

198 {
199 FEType fe_type(FIRST, LAGRANGE);
200 _fe = FEBase::build(1, fe_type);
201 _fe->get_phi();
202 _fe->get_dual_phi();
203
204 _mesh = std::make_unique<Mesh>(*TestCommWorld);
205
207
208 auto rng = _mesh->active_local_element_ptr_range();
209 _elem = rng.begin() == rng.end() ? nullptr : *(rng.begin());
210
211 _qrule = std::make_unique<QGauss>(1, fe_type.default_quadrature_order());
212 _fe->attach_quadrature_rule(_qrule.get());
213 }
std::unique_ptr< FEBase > _fe
std::unique_ptr< QGauss > _qrule
std::unique_ptr< Mesh > _mesh
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
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.

References _elem, _fe, _mesh, _qrule, libMesh::FEGenericBase< OutputType >::build(), libMesh::MeshTools::Generation::build_line(), libMesh::FEType::default_quadrature_order(), libMesh::EDGE2, libMesh::FIRST, libMesh::LAGRANGE, and TestCommWorld.

◆ tearDown()

void DualShapeTest::tearDown ( )
inline

Definition at line 215 of file dual_shape_verification_test.C.

215{}

◆ testEdge2Lagrange()

void DualShapeTest::testEdge2Lagrange ( )
inline

Definition at line 39 of file dual_shape_verification_test.C.

40 {
41 LOG_UNIT_TEST;
42 if (!_elem)
43 return;
44
45 _fe->reinit(_elem);
46
47 const DenseMatrix<Real> & dual_coeff = _fe->get_dual_coeff();
48
49 CPPUNIT_ASSERT_EQUAL(dual_coeff.m(), unsigned(2));
50 CPPUNIT_ASSERT_EQUAL(dual_coeff.n(), unsigned(2));
51
52 // TOLERANCE*TOLERANCE works with double but not float128
53 Real my_tol = TOLERANCE*std::sqrt(TOLERANCE);
54
55 LIBMESH_ASSERT_FP_EQUAL(2, dual_coeff(0,0), my_tol);
56 LIBMESH_ASSERT_FP_EQUAL(-1, dual_coeff(0,1), my_tol);
57 LIBMESH_ASSERT_FP_EQUAL(-1, dual_coeff(1,0), my_tol);
58 LIBMESH_ASSERT_FP_EQUAL(2, dual_coeff(1,1), my_tol);
59
60 const auto & dual_phi = _fe->get_dual_phi();
61
62 CPPUNIT_ASSERT_EQUAL(std::size_t(2), dual_phi.size());
63
64 const auto & qpoints = _qrule->get_points();
65
66 CPPUNIT_ASSERT_EQUAL(qpoints.size(), dual_phi[0].size());
67
68 for (auto qp : index_range(dual_phi[0]))
69 LIBMESH_ASSERT_FP_EQUAL(1./2. * (1. - 3.*qpoints[qp](0)), dual_phi[0][qp],
70 my_tol);
71
72 CPPUNIT_ASSERT_EQUAL(qpoints.size(), dual_phi[1].size());
73
74 for (auto qp : index_range(dual_phi[1]))
75 LIBMESH_ASSERT_FP_EQUAL(1./2. * (1. + 3.*qpoints[qp](0)), dual_phi[1][qp],
76 my_tol);
77 }
Defines a dense matrix for use in Finite Element-type computations.
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
static constexpr Real TOLERANCE
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

References _elem, _fe, _qrule, libMesh::index_range(), libMesh::DenseMatrixBase< T >::m(), libMesh::DenseMatrixBase< T >::n(), libMesh::Real, and libMesh::TOLERANCE.

◆ testL2Lagrange()

void DualShapeTest::testL2Lagrange ( )
inline

Definition at line 188 of file dual_shape_verification_test.C.

189 {
190 LOG_UNIT_TEST;
191 // L2_LAGRANGE shares the LAGRANGE shape functions
195 }
void testTransformedDual(const ElemType elem_type, const unsigned int n, const Real vertex_over_mid, const FEFamily family=LAGRANGE)
Check what the transformed dual basis on QUAD8/TRI6/TRI7 guarantees, none of which the untransformed ...

References libMesh::L2_LAGRANGE, libMesh::QUAD8, libMesh::Real, testTransformedDual(), libMesh::TRI6, and libMesh::TRI7.

◆ testQuad8Lagrange()

void DualShapeTest::testQuad8Lagrange ( )
inline

Definition at line 167 of file dual_shape_verification_test.C.

168 {
169 LOG_UNIT_TEST;
170 // QUAD8 weights 1/5 (corner) and 4/5 (mid-edge) on the reference element
172 }

References libMesh::QUAD8, libMesh::Real, and testTransformedDual().

◆ testTransformedDual()

void DualShapeTest::testTransformedDual ( const ElemType  elem_type,
const unsigned int  n,
const Real  vertex_over_mid,
const FEFamily  family = LAGRANGE 
)
inline

Check what the transformed dual basis on QUAD8/TRI6/TRI7 guarantees, none of which the untransformed construction gives: strictly positive weights, reproduction of constants, and biorthogonality against Ntilde = T N rather than N.

vertex_over_mid pins down alpha, and n is the number of SECOND order shape functions on elem_type.

Definition at line 85 of file dual_shape_verification_test.C.

87 {
88 Mesh mesh(*TestCommWorld);
89 MeshTools::Generation::build_square(mesh, 1, 1, -1., 1., -1., 1., elem_type);
90
91 auto rng = mesh.active_local_element_ptr_range();
92 if (rng.begin() == rng.end())
93 return;
94 const Elem * elem = *(rng.begin());
95
96 FEType fe_type(SECOND, family);
97 std::unique_ptr<FEBase> fe = FEBase::build(2, fe_type);
98 const auto & JxW = fe->get_JxW();
99 const auto & phi = fe->get_phi();
100 const auto & dual_phi = fe->get_dual_phi();
101 QGauss qrule(2, fe_type.default_quadrature_order());
102 fe->attach_quadrature_rule(&qrule);
103 fe->reinit(elem);
104
105 CPPUNIT_ASSERT_EQUAL(std::size_t(n), phi.size());
106 CPPUNIT_ASSERT_EQUAL(std::size_t(n), dual_phi.size());
107
108 // TOLERANCE*TOLERANCE works with double but not float128
109 const Real my_tol = TOLERANCE*std::sqrt(TOLERANCE);
110
111 // dtilde_j = \int dual_phi_j; these are the weights that must be positive.
112 std::vector<Real> dtilde(n, 0);
113 for (const auto j : make_range(n))
114 for (const auto qp : index_range(JxW))
115 dtilde[j] += JxW[qp]*dual_phi[j][qp];
116
117 Real sum_dtilde = 0, volume = 0;
118 for (const auto j : make_range(n))
119 {
120 CPPUNIT_ASSERT(dtilde[j] > 0);
121 sum_dtilde += dtilde[j];
122 }
123 for (const auto qp : index_range(JxW))
124 volume += JxW[qp];
125
126 // Partition of unity is preserved, so constants are reproduced and the weights sum to the volume.
127 LIBMESH_ASSERT_FP_EQUAL(volume, sum_dtilde, my_tol);
128 for (const auto qp : index_range(JxW))
129 {
130 Real sum = 0;
131 for (const auto j : make_range(n))
132 sum += dual_phi[j][qp];
133 LIBMESH_ASSERT_FP_EQUAL(1., sum, my_tol);
134 }
135
136 // Scale-free signature of alpha.
137 LIBMESH_ASSERT_FP_EQUAL(vertex_over_mid,
138 dtilde[0]/dtilde[elem->n_vertices()], my_tol);
139
140 // T from the element's own adjacency, not an assumed index convention.
141 const Real alpha = Real(1)/5;
142 DenseMatrix<Real> T(n, n);
143 for (const auto i : make_range(n))
144 T(i,i) = 1.;
145 for (const auto m : make_range(elem->n_vertices(), n))
146 {
147 T(m,m) = 1. - 2.*alpha;
148 for (const auto v : make_range(elem->n_second_order_adjacent_vertices(m)))
149 T(elem->second_order_adjacent_vertex(m,v), m) += alpha;
150 }
151
152 for (const auto k : make_range(n))
153 for (const auto j : make_range(n))
154 {
155 Real integral = 0;
156 for (const auto qp : index_range(JxW))
157 {
158 Real ntilde_k = 0;
159 for (const auto l : make_range(n))
160 ntilde_k += T(k,l)*phi[l][qp];
161 integral += JxW[qp]*dual_phi[j][qp]*ntilde_k;
162 }
163 LIBMESH_ASSERT_FP_EQUAL(k == j ? dtilde[j] : 0., integral, my_tol);
164 }
165 }
This is the base class from which all geometric element types are derived.
Definition elem.h:96
virtual unsigned int n_vertices() const =0
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition mesh.h:51
This class implements specific orders of Gauss quadrature.
MeshBase & mesh
void build_square(UnstructuredMesh &mesh, const unsigned int nx, const unsigned int ny, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
A specialized build_cube() for 2D meshes.
Real volume(const MeshBase &mesh, unsigned int dim=libMesh::invalid_uint)
Find the total volume of a mesh (interpreting that as area for dim = 2, or total arc length for dim =...
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

References libMesh::FEGenericBase< OutputType >::build(), libMesh::MeshTools::Generation::build_square(), libMesh::FEType::default_quadrature_order(), libMesh::index_range(), libMesh::make_range(), mesh, libMesh::Elem::n_second_order_adjacent_vertices(), libMesh::Elem::n_vertices(), libMesh::Real, libMesh::SECOND, libMesh::Elem::second_order_adjacent_vertex(), TestCommWorld, and libMesh::TOLERANCE.

Referenced by testL2Lagrange(), testQuad8Lagrange(), testTri6Lagrange(), and testTri7Lagrange().

◆ testTri6Lagrange()

void DualShapeTest::testTri6Lagrange ( )
inline

Definition at line 174 of file dual_shape_verification_test.C.

175 {
176 LOG_UNIT_TEST;
177 // TRI6 weights 1/15 (vertex) and 1/10 (mid-edge) on the reference element
178 testTransformedDual(TRI6, 6, Real(2)/3);
179 }

References libMesh::Real, testTransformedDual(), and libMesh::TRI6.

◆ testTri7Lagrange()

void DualShapeTest::testTri7Lagrange ( )
inline

Definition at line 181 of file dual_shape_verification_test.C.

182 {
183 LOG_UNIT_TEST;
184 // SECOND order on TRI7 is the TRI6 basis, with no degree of freedom at the centroid node
185 testTransformedDual(TRI7, 6, Real(2)/3);
186 }

References libMesh::Real, testTransformedDual(), and libMesh::TRI7.

Member Data Documentation

◆ _elem

Elem* DualShapeTest::_elem
private

Definition at line 35 of file dual_shape_verification_test.C.

Referenced by setUp(), and testEdge2Lagrange().

◆ _fe

std::unique_ptr<FEBase> DualShapeTest::_fe
private

Definition at line 34 of file dual_shape_verification_test.C.

Referenced by setUp(), and testEdge2Lagrange().

◆ _mesh

std::unique_ptr<Mesh> DualShapeTest::_mesh
private

Definition at line 32 of file dual_shape_verification_test.C.

Referenced by setUp().

◆ _qrule

std::unique_ptr<QGauss> DualShapeTest::_qrule
private

Definition at line 33 of file dual_shape_verification_test.C.

Referenced by setUp(), and testEdge2Lagrange().


The documentation for this class was generated from the following file: