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

Verifies HDivFETransformation::map_dphi (the physical-space gradients of H(div)-conforming Raviart-Thomas shape functions) by comparing fe->get_dphi() against a central-difference approximation built from map_phi's own output (fe->get_phi()), evaluated at physical points perturbed via FEMap::inverse_map. More...

Inheritance diagram for HDivGradTest:
[legend]

Public Member Functions

 LIBMESH_CPPUNIT_TEST_SUITE (HDivGradTest)
 
 CPPUNIT_TEST (testQuad8Affine)
 
 CPPUNIT_TEST (testTri6Affine)
 
 CPPUNIT_TEST (testQuad8NonAffine)
 
 CPPUNIT_TEST (testTri6NonAffine)
 
 CPPUNIT_TEST (testHex27Affine)
 
 CPPUNIT_TEST (testTet14Affine)
 
 CPPUNIT_TEST (testHex27NonAffine)
 
 CPPUNIT_TEST (testTet14NonAffine)
 
 CPPUNIT_TEST_SUITE_END ()
 
void setUp ()
 
void tearDown ()
 
void testQuad8Affine ()
 
void testQuad8NonAffine ()
 
void testTri6Affine ()
 
void testTri6NonAffine ()
 
void testHex27Affine ()
 
void testHex27NonAffine ()
 
void testTet14Affine ()
 
void testTet14NonAffine ()
 

Private Member Functions

void testGradByFiniteDifference (const ElemType elem_type, const bool distort)
 

Detailed Description

Verifies HDivFETransformation::map_dphi (the physical-space gradients of H(div)-conforming Raviart-Thomas shape functions) by comparing fe->get_dphi() against a central-difference approximation built from map_phi's own output (fe->get_phi()), evaluated at physical points perturbed via FEMap::inverse_map.

Definition at line 25 of file fe_hdiv_grad_test.C.

Member Function Documentation

◆ CPPUNIT_TEST() [1/8]

HDivGradTest::CPPUNIT_TEST ( testHex27Affine  )

◆ CPPUNIT_TEST() [2/8]

HDivGradTest::CPPUNIT_TEST ( testHex27NonAffine  )

◆ CPPUNIT_TEST() [3/8]

HDivGradTest::CPPUNIT_TEST ( testQuad8Affine  )

◆ CPPUNIT_TEST() [4/8]

HDivGradTest::CPPUNIT_TEST ( testQuad8NonAffine  )

◆ CPPUNIT_TEST() [5/8]

HDivGradTest::CPPUNIT_TEST ( testTet14Affine  )

◆ CPPUNIT_TEST() [6/8]

HDivGradTest::CPPUNIT_TEST ( testTet14NonAffine  )

◆ CPPUNIT_TEST() [7/8]

HDivGradTest::CPPUNIT_TEST ( testTri6Affine  )

◆ CPPUNIT_TEST() [8/8]

HDivGradTest::CPPUNIT_TEST ( testTri6NonAffine  )

◆ CPPUNIT_TEST_SUITE_END()

HDivGradTest::CPPUNIT_TEST_SUITE_END ( )

◆ LIBMESH_CPPUNIT_TEST_SUITE()

HDivGradTest::LIBMESH_CPPUNIT_TEST_SUITE ( HDivGradTest  )

◆ setUp()

void HDivGradTest::setUp ( )
inline

Definition at line 50 of file fe_hdiv_grad_test.C.

50{}

◆ tearDown()

void HDivGradTest::tearDown ( )
inline

Definition at line 51 of file fe_hdiv_grad_test.C.

51{}

◆ testGradByFiniteDifference()

void HDivGradTest::testGradByFiniteDifference ( const ElemType  elem_type,
const bool  distort 
)
inlineprivate

Definition at line 76 of file fe_hdiv_grad_test.C.

77 {
78 LOG_UNIT_TEST;
79
80 Mesh mesh(*TestCommWorld);
81 unsigned int dim = 0;
82
83 switch (elem_type)
84 {
85 case QUAD8:
86 case TRI6:
87 dim = 2;
89 (mesh, 1, 1, 0., 1., 0., 1., elem_type);
90 break;
91 case HEX27:
92 case TET14:
93 dim = 3;
95 (mesh, 1, 1, 1, 0., 1., 0., 1., 0., 1., elem_type);
96 break;
97 default:
98 libmesh_error_msg("Unsupported element type " << elem_type);
99 }
100
101 auto elem_range = mesh.active_local_element_ptr_range();
102 if (elem_range.begin() == elem_range.end())
103 return;
104 const Elem * elem = *(elem_range.begin());
105
106 if (distort)
107 {
108 // Move one of this element's own vertices partway toward the
109 // element's own vertex average, without touching the associated
110 // edge/face nodes -- this turns the element's boundary curved and
111 // gives the map nonzero second derivatives, exercising the terms
112 // in map_dphi (A and B in the derivation) that vanish identically
113 // on an affine element. For a straight-sided simplex, the signed
114 // volume is an affine function of any single vertex's position,
115 // and moving that vertex to the vertex average reduces the signed
116 // volume to a positive fraction (1/n_vertices) of the original;
117 // moving only partway there is therefore guaranteed to keep the
118 // element non-degenerate, regardless of the element's own size or
119 // shape, unlike a fixed or size-scaled absolute displacement.
120 Node & node = mesh.node_ref(elem->node_id(0));
121 const Point target = elem->vertex_average();
122 for (auto d : make_range(dim))
123 node(d) += Real(0.3) * (target(d) - node(d));
124 }
125
126 const FEType fe_type(FIRST, RAVIART_THOMAS);
127 std::unique_ptr<FEVectorBase> fe(FEVectorBase::build(dim, fe_type));
128
129 const std::vector<std::vector<RealTensor>> & dphi = fe->get_dphi();
130 const std::vector<std::vector<RealGradient>> & phi = fe->get_phi();
131 const std::vector<Point> & xyz = fe->get_xyz();
132
133 QGauss qrule(dim, fe_type.default_quadrature_order());
134 fe->attach_quadrature_rule(&qrule);
135
136 fe->reinit(elem);
137
138 // Copy out what we need before the perturbed reinit() calls below
139 // overwrite fe's internal state.
140 const std::vector<std::vector<RealTensor>> dphi_base = dphi;
141 const std::vector<Point> qpoints = xyz;
142
143 const Real h = 1e-6;
144 const Real tol = 5e-4;
145
146 for (auto qp : index_range(qpoints))
147 {
148 const Point x0 = qpoints[qp];
149
150 for (auto l : make_range(dim))
151 {
152 Point x_plus = x0;
153 x_plus(l) += h;
154 Point x_minus = x0;
155 x_minus(l) -= h;
156
157 std::vector<Point> pts_plus
158 (1, FEMap::inverse_map(dim, elem, x_plus));
159 fe->reinit(elem, &pts_plus);
160 const std::vector<std::vector<RealGradient>> phi_plus = phi;
161
162 std::vector<Point> pts_minus
163 (1, FEMap::inverse_map(dim, elem, x_minus));
164 fe->reinit(elem, &pts_minus);
165 const std::vector<std::vector<RealGradient>> phi_minus = phi;
166
167 for (auto i : index_range(dphi_base))
168 for (auto k : make_range(LIBMESH_DIM))
169 {
170 const Real fd =
171 (phi_plus[i][0](k) - phi_minus[i][0](k)) / (2*h);
172
173 LIBMESH_ASSERT_FP_EQUAL(fd, dphi_base[i][qp](k, l), tol);
174 }
175 }
176 }
177 }
unsigned int dim
This is the base class from which all geometric element types are derived.
Definition elem.h:96
dof_id_type node_id(const unsigned int i) const
Definition elem.h:2605
Point vertex_average() const
Definition elem.C:609
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
static Point inverse_map(const unsigned int dim, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true, const bool extra_checks=true)
Definition fe_map.C:1512
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition fe_type.h:197
virtual const Node & node_ref(const dof_id_type i) const
Definition mesh_base.h:742
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
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:41
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.
void build_cube(UnstructuredMesh &mesh, const unsigned int nx=0, const unsigned int ny=0, const unsigned int nz=0, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const Real zmin=0., const Real zmax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
Builds a (elements) cube.
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
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

References libMesh::FEGenericBase< OutputType >::build(), libMesh::MeshTools::Generation::build_cube(), libMesh::MeshTools::Generation::build_square(), libMesh::FEType::default_quadrature_order(), dim, libMesh::FIRST, libMesh::HEX27, libMesh::index_range(), libMesh::FEMap::inverse_map(), libMesh::make_range(), mesh, libMesh::Elem::node_id(), libMesh::MeshBase::node_ref(), libMesh::QUAD8, libMesh::RAVIART_THOMAS, libMesh::Real, TestCommWorld, libMesh::TET14, libMesh::TRI6, and libMesh::Elem::vertex_average().

Referenced by testHex27Affine(), testHex27NonAffine(), testQuad8Affine(), testQuad8NonAffine(), testTet14Affine(), testTet14NonAffine(), testTri6Affine(), and testTri6NonAffine().

◆ testHex27Affine()

void HDivGradTest::testHex27Affine ( )
inline

Definition at line 65 of file fe_hdiv_grad_test.C.

void testGradByFiniteDifference(const ElemType elem_type, const bool distort)

References libMesh::HEX27, and testGradByFiniteDifference().

◆ testHex27NonAffine()

void HDivGradTest::testHex27NonAffine ( )
inline

Definition at line 66 of file fe_hdiv_grad_test.C.

References libMesh::HEX27, and testGradByFiniteDifference().

◆ testQuad8Affine()

void HDivGradTest::testQuad8Affine ( )
inline

Definition at line 58 of file fe_hdiv_grad_test.C.

References libMesh::QUAD8, and testGradByFiniteDifference().

◆ testQuad8NonAffine()

void HDivGradTest::testQuad8NonAffine ( )
inline

Definition at line 59 of file fe_hdiv_grad_test.C.

References libMesh::QUAD8, and testGradByFiniteDifference().

◆ testTet14Affine()

void HDivGradTest::testTet14Affine ( )
inline

Definition at line 67 of file fe_hdiv_grad_test.C.

References testGradByFiniteDifference(), and libMesh::TET14.

◆ testTet14NonAffine()

void HDivGradTest::testTet14NonAffine ( )
inline

Definition at line 68 of file fe_hdiv_grad_test.C.

References testGradByFiniteDifference(), and libMesh::TET14.

◆ testTri6Affine()

void HDivGradTest::testTri6Affine ( )
inline

Definition at line 60 of file fe_hdiv_grad_test.C.

References testGradByFiniteDifference(), and libMesh::TRI6.

◆ testTri6NonAffine()

void HDivGradTest::testTri6NonAffine ( )
inline

Definition at line 61 of file fe_hdiv_grad_test.C.

References testGradByFiniteDifference(), and libMesh::TRI6.


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