PeriDEM 0.3.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
fe::TetElem Class Reference

A class for mapping and quadrature related operations for linear tetrahedron element. More...

#include <tetElem.h>

Inheritance diagram for fe::TetElem:
Collaboration diagram for fe::TetElem:

Public Member Functions

 TetElem (size_t order)
 Constructor.
 
double elemSize (const std::vector< util::Point > &nodes) override
 Returns the volume of element.
 
std::vector< double > getShapes (const util::Point &p, const std::vector< util::Point > &nodes) override
 Returns the values of shape function at point p.
 
std::vector< std::vector< double > > getDerShapes (const util::Point &p, const std::vector< util::Point > &nodes) override
 Returns the values of derivative of shape function at point p.
 
- Public Member Functions inherited from fe::BaseElem
 BaseElem (size_t order, size_t element_type)
 Constructor.
 
size_t getElemType ()
 Get element type.
 
size_t getQuadOrder ()
 Get order of quadrature approximation.
 
size_t getNumQuadPoints ()
 Get number of quadrature points in the data.
 
std::vector< fe::QuadDatagetQuadDatas (const std::vector< util::Point > &nodes)
 Get quadrature data mapped to the physical element (N, dN/dx, x, w, J). Shared isoparametric map; types only fill reference N, dN/dξ, and w.
 
std::vector< fe::QuadDatagetQuadPoints (const std::vector< util::Point > &nodes)
 Same as getQuadDatas without transforming dN/dξ to dN/dx.
 

Private Member Functions

std::vector< double > getShapes (const util::Point &p) override
 Returns the values of shape function at point p on reference element.
 
std::vector< std::vector< double > > getDerShapes (const util::Point &p) override
 Returns the values of derivative of shape function at point p on reference element.
 
util::Point mapPointToRefElem (const util::Point &p, const std::vector< util::Point > &nodes) override
 Maps point p in a given element to the reference element.
 
double getJacobian (const util::Point &p, const std::vector< util::Point > &nodes, std::vector< std::vector< double > > *J) override
 Computes the Jacobian of map \( \Phi: T^0 \to T \).
 
void init () override
 Compute the quadrature points for triangle element.
 

Additional Inherited Members

- Protected Attributes inherited from fe::BaseElem
size_t d_quadOrder
 Order of quadrature point integration approximation.
 
size_t d_elemType
 Element type.
 
std::vector< fe::QuadDatad_quads
 Quadrature data collection.
 

Detailed Description

A class for mapping and quadrature related operations for linear tetrahedron element.

The reference tetrahedron element \( T^0 \) is given by vertices \( (0,0,0), \, (1,0,0), \, (0,1,0), \, (0,0,1) \).

  1. The shape functions at point \( (\xi, \eta, \zeta) \in T^0 \) are

    \[N^0_1(\xi, \eta, \zeta) = 1- \xi - \eta - \zeta, \quad N^0_2(\xi, \eta, \zeta) = \xi, \quad N^0_3(\xi, \eta, \zeta) = \eta, \quad N^0_4(\xi, \eta, \zeta) = \zeta. \]

  2. For linear tetrahedron element, derivative of shape functions are constant and are as follows

    \[\frac{d N^0_1(\xi, \eta, \zeta)}{d\xi} = -1, \, \frac{d N^0_1(\xi, \eta, \zeta) }{d\eta} = -1, \, \frac{d N^0_1(\xi, \eta, \zeta) }{d\zeta} = -1, \]

    \[\frac{d N^0_2(\xi, \eta, \zeta)}{d\xi} = 1, \, \frac{d N^0_2(\xi, \eta, \zeta)}{d\eta} = 0, \, \frac{d N^0_2(\xi, \eta, \zeta)}{d\zeta} = 0, \]

    \[\frac{d N^0_2(\xi, \eta, \zeta)}{d\xi} = 0, \, \frac{d N^0_2(\xi, \eta, \zeta)}{d\eta} = 1, \, \frac{d N^0_2(\xi, \eta, \zeta)}{d\zeta} = 0, \]

    \[\frac{d N^0_2(\xi, \eta, \zeta)}{d\xi} = 0, \, \frac{d N^0_2(\xi, \eta, \zeta)}{d\eta} = 0, \, \frac{d N^0_2(\xi, \eta, \zeta)}{d\zeta} = 1. \]

  3. Map \( \Phi: T^0 \to T\) is given by

    \[ x(\xi, \eta, \zeta) = \sum_{i=1}^4 N^0_i(\xi, \eta, \zeta) v^i_x, \quad y (\xi, \eta, \zeta) = \sum_{i=1}^4 N^0_i(\xi, \eta, \zeta) v^i_y, \quad z (\xi, \eta, \zeta) = \sum_{i=1}^4 N^0_i(\xi, \eta, \zeta) v^i_z \]

    where \( v^1, v^2, v^3, v^4\) are vertices of element \( T \).
  4. The Jacobian of the map \( \Phi: T^0 \to T\) is given by

    \[ J = \left[ { \begin{array}{ccc} \frac{dx}{d\xi} &\frac{dy}{d\xi} &\frac{dz}{d\xi} \\ \frac{dx}{d\eta} & \frac{dy}{d\eta} &\frac{dz}{d\eta} \\ \frac{dx}{d\zeta} & \frac{dy}{d\zeta} &\frac{dz}{d\zeta} \\ \end{array} } \right] \]

    and determinant of Jacobian is

    \[ det(J) = \frac{dx}{d\xi} (\frac{dy}{d\eta} \times \frac{dz}{d\zeta} - \frac{dy}{d\zeta}\times \frac{dz}{d\eta}) - \frac{dy}{d\xi} (\frac{dx}{d\eta} \times \frac{dz}{d\zeta} - \frac{dx}{d\zeta}\times \frac{dz}{d\eta}) + \frac{dz}{d\xi} (\frac{dx}{d\eta} \times \frac{dy}{d\zeta} - \frac{dx}{d\zeta}\times \frac{dy}{d\eta}). \]

    For linear triangle element, Jacobian (and so \( det(J) \)) is constant. For linear tetrahedron elements,

    \[ \frac{dx}{d\xi} = v^2_x - v^1_x, \quad \frac{dx}{d\eta} = v^3_x - v^1_x, \quad \frac{dx}{d\zeta} = v^4_x - v^1_x, \]

    \[ \frac{dy}{d\xi} = v^2_y - v^1_y, \quad \frac{dy}{d\eta} = v^3_y - v^1_y, \quad \frac{dy}{d\zeta} = v^4_y - v^1_y, \]

    \[ \frac{dz}{d\xi} = v^2_z - v^1_z, \quad \frac{dz}{d\eta} = v^3_z - v^1_z, \quad \frac{dz}{d\zeta} = v^4_z - v^1_z \]

    and \( det(J) = \frac{volume(T)}{volume(T^0)} = 6\times volume(T) \).
  5. Inverse map \( \Phi^{-1} : T \to T^0 \) for linear tetrahedron element can be derived as follows:

From map \( (\xi, \eta, \zeta)\in T^0 \to (x,y,z) \in T \) we have

\[ x = \sum_{i=1}^4 N^0_i(\xi, \eta, \zeta) v^i_x, \quad y = \sum_{i=1}^4 N^0_i(\xi, \eta, \zeta) v^i_y, \quad z = \sum_{i=1}^4 N^0_i(\xi, \eta, \zeta) v^i_z. \]

Substituting formula for \( N^0_i \) in above to get

\[ x = (1 - \xi - \eta - \zeta) v^1_x + \xi v^2_x + \eta v^3_x + \zeta v^4_x, \quad y = (1 - \xi - \eta - \zeta) v^1_y + \xi v^2_y + \eta v^3_y + \zeta v^4_y, \quad z = (1 - \xi - \eta - \zeta) v^1_z + \xi v^2_z + \eta v^3_z + \zeta v^4_z \]

or

\[ x - v^1_x = \xi (v^2_x - v^1_x) + \eta (v^3_x - v^1_x) + \zeta (v^4_x - v^1_x), \quad y - v^1_y = \xi (v^2_y - v^1_y) + \eta (v^3_y - v^1_y) + \zeta (v^4_y - v^1_y), \quad z - v^1_z = \xi (v^2_z - v^1_z) + \eta (v^3_z - v^1_z) + \zeta (v^4_z - v^1_z). \]

Writing above in matrix form, we have

\[ \left[ {\begin{array}{c} x - v^1_x \\ y - v^1_y \\ z - v^1_z \end{array}}\right] = \left[ {\begin{array}{ccc} v^2_x - v^1_x & v^3_x - v^1_x & v^4_x - v^1_x\\ v^2_y - v^1_y & v^3_y - v^1_y & v^3_y - v^1_y \\ v^2_z - v^1_z & v^3_z - v^1_z & v^3_z - v^1_z \end{array}}\right] \, \left[ {\begin{array}{c} \xi \\ \eta \\ \zeta \end{array}}\right]. \]

Denoting the matrix as \( B \)

\[ B = \left[ {\begin{array}{ccc} v^2_x - v^1_x & v^3_x - v^1_x & v^4_x - v^1_x\\ v^2_y - v^1_y & v^3_y - v^1_y & v^4_y - v^1_y \\ v^2_z - v^1_z & v^3_z - v^1_z & v^4_z - v^1_z \end{array}}\right] \]

. Note that \( B \) is transpose of jacobian of map \(\Phi\) therefore \( det(B) = det(J)\). Inverse of \( B\) is

\[ C := B^{-1} = \frac{1}{det(B)} \left[ {\begin{array}{ccc} B_{22}B_{33} - B_{32}B_{23} & B_{13}B_{32} - B_{33}B_{12} & B_{12}B_{23} - B_{22}B_{13} \\ B_{23}B_{31} - B_{33}B_{21} & B_{11}B_{33} - B_{31}B_{13} & B_{13}B_{21} - B_{23}B_{11} \\ B_{21}B_{32} - B_{31}B_{22} & B_{12}B_{31} - B_{32}B_{11} & B_{11}B_{22} - B_{21}B_{12} \\ \end{array}}\right]. \]

With \( C \) we have inverse map given by

\[ \xi(x,y,z) = C_{11} (x - v^1_x) + C_{12} (y - v^1_y) + C_{13} (z - v^1_z), \quad \eta(x,y,z) = C_{21} (x - v^1_x) + C_{22} (y - v^1_y) + C_{23} (z - v^1_z), \quad \zeta (x,y,z) = C_{31} (x - v^1_x) + C_{32} (y - v^1_y) + C_{33} (z - v^1_z). \]

Definition at line 141 of file tetElem.h.

Constructor & Destructor Documentation

◆ TetElem()

fe::TetElem::TetElem ( size_t  order)
explicit

Constructor.

Parameters
orderOrder of quadrature point approximation

Definition at line 70 of file tetElem.cpp.

72
73 if (d_quadOrder > 3) {
74 throw std::runtime_error(
76 << "Error: For linear tet element, we only support upto 3 quad "
77 "order approximation.\n");
78 }
79
80 // compute quad data
81 this->init();
82}
A base class which provides methods to map points to/from reference element and to compute quadrature...
Definition baseElem.h:84
size_t d_quadOrder
Order of quadrature point integration approximation.
Definition baseElem.h:218
void init() override
Compute the quadrature points for triangle element.
Definition tetElem.cpp:209
Collects a message with stream syntax for use in an exception.
Definition io.h:52
static const int vtk_type_tetra
Integer flag for tetrahedron element.

References fe::BaseElem::d_quadOrder, and init().

Here is the call graph for this function:

Member Function Documentation

◆ elemSize()

double fe::TetElem::elemSize ( const std::vector< util::Point > &  nodes)
overridevirtual

Returns the volume of element.

If tetrahedron \( T \) is given by points \( v^1, v^2, v^3, v^4 \) then the volume is

\[ volume(T) =\frac{1}{3!} \left\vert \left[ {\begin{array}{cccc} v^1_x & v^1_y & v^1_z & 1 \\ v^2_x & v^2_y & v^2_z & 1 \\ v^3_x & v^3_y & v^3_z & 1 \\ v^4_x & v^4_y & v^4_z & 1 \\ \end{array}}\right] \right\vert \]

where \( v^i_x, v^i_y, v^i_z \) are the x, y, z component of point \( v^i \).

Note that volume and Jacobian of map \( \Phi: T^0 \to T \) are related as

\[ volume(T) = volume(T^0) \times det(J). \]

Here, \( volume(T^0) = 1/6 \).

Parameters
nodesVertices of element
Returns
vector Vector of shape functions at point p

Implements fe::BaseElem.

Definition at line 84 of file tetElem.cpp.

84 {
85 // volume of tet element is (1/6) a * (b x c),
86 // where a = v2 - v1, b = v3 - v1, c = v4 - v1
87 auto a = nodes[1] - nodes[0];
88 auto b = nodes[2] - nodes[0];
89 auto c = nodes[3] - nodes[0];
90 return (1. / 6.) * a * (b.cross(c));
91}

◆ getDerShapes() [1/2]

std::vector< std::vector< double > > fe::TetElem::getDerShapes ( const util::Point p)
overrideprivatevirtual

Returns the values of derivative of shape function at point p on reference element.

Parameters
pLocation of point
Returns
vector Vector of derivative of shape functions

Implements fe::BaseElem.

Definition at line 125 of file tetElem.cpp.

126 {
127
128 // d N1/d xi = -1, d N1/d eta = -1, d N1/d zeta = -1,
129 // d N2/ d xi = 1, d N2/d eta = 0, d N2/d zeta = 0,
130 // d N3/ d xi = 0, d N3/d eta = 1, d N3/d zeta = 0,
131 // d N4/ d xi = 0, d N4/d eta = 0, d N4/d zeta = 1,
132 std::vector<std::vector<double>> r;
133 r.push_back(std::vector<double>{-1., -1., -1.});
134 r.push_back(std::vector<double>{1., 0., 0.});
135 r.push_back(std::vector<double>{0., 1., 0.});
136 r.push_back(std::vector<double>{0., 0., 1.});
137
138 return r;
139}

◆ getDerShapes() [2/2]

std::vector< std::vector< double > > fe::TetElem::getDerShapes ( const util::Point p,
const std::vector< util::Point > &  nodes 
)
overridevirtual

Returns the values of derivative of shape function at point p.

Below, we present the derivation of the formula:

We are interested in \( \frac{\partial N_i(x_p, y_p, z_p)}{\partial x}\), \( \frac{\partial N_i(x_p, y_p, z_p)}{\partial y}\) and \( \frac{\partial N_i(x_p, y_p, z_p)}{\partial z}\). By using the map \( \Phi : T^0 \to T\) we have

\[ N^0_i(\xi, \eta, \zeta) = N_i(x(\xi,\eta,\zeta), y(\xi, \eta,\eta), z(\xi, \eta,\eta)) \]

and therefore we can write

\[ \frac{\partial N^0_i(\xi, \eta, \zeta)}{\partial \xi} = \frac{\partial N_i}{\partial x} \frac{\partial x}{\partial \xi} + \frac{\partial N_i}{\partial y} \frac{\partial y}{\partial \xi} + \frac{\partial N_i}{\partial z} \frac{\partial z}{\partial \xi}, \]

\[ \frac{\partial N^0_i(\xi, \eta, \zeta)}{\partial \eta} = \frac{\partial N_i}{\partial x} \frac{\partial x}{\partial \eta} + \frac{\partial N_i}{\partial y} \frac{\partial y}{\partial \eta} + \frac{\partial N_i}{\partial z} \frac{\partial z}{\partial \eta} \]

and

\[ \frac{\partial N^0_i(\xi, \eta, \zeta)}{\partial \zeta} = \frac{\partial N_i}{\partial x} \frac{\partial x}{\partial \zeta} + \frac{\partial N_i}{\partial y} \frac{\partial y}{\partial \zeta} + \frac{\partial N_i}{\partial z} \frac{\partial z}{\partial \zeta} \]

which can be written in the matrix form as

\[ \left[ {\begin{array}{c} \frac{\partial N^0_i}{\partial \xi} \\ \frac{\partial N^0_i}{\partial \eta} \\ \frac{\partial N^0_i}{\partial \zeta} \end{array}}\right] = \left[ { \begin{array}{ccc} \frac{dx}{d\xi} &\frac{dy}{d\xi} &\frac{dz}{d\xi} \\ \frac{dx}{d\eta} & \frac{dy}{d\eta} &\frac{dz}{d\eta} \\ \frac{dx}{d\zeta} & \frac{dy}{d\zeta} &\frac{dz}{d\zeta} \\ \end{array} } \right] \, \left[ {\begin{array}{c} \frac{\partial N_i}{\partial x} \\ \frac{\partial N_i}{\partial y} \\ \frac{\partial N_i}{\partial z}\end{array}}\right]. \]

The matrix is the Jacobian matrix \( J \) and follows if vertices of elements are known. Using \( J^{-1} \) we have following formula for derivatives of the shape function

\[ \left[ {\begin{array}{c} \frac{\partial N_i}{\partial x} \\ \frac{\partial N_i}{\partial y} \\ \frac{\partial N_i}{\partial z}\end{array}}\right] = J^{-1} \left[ {\begin{array}{c} \frac{\partial N^0_i}{\partial \xi} \\ \frac{\partial N^0_i}{\partial \eta} \\ \frac{\partial N^0_i}{\partial \zeta}\end{array}}\right]. \]

Here, derivatives \( \frac{\partial N^0_i}{ \partial \xi} \), \( \frac{\partial N^0_i} {\partial \eta } \) and \( \frac{\partial N^0_i} {\partial \zeta } \) correspond to reference element and are easy to compute.

Parameters
pLocation of point
nodesVertices of element
Returns
vector Vector of derivative of shape functions

Reimplemented from fe::BaseElem.

Definition at line 98 of file tetElem.cpp.

99 {
100
101 // get derivatives of shape function in reference tet element
102 auto ders_ref = getDerShapes(mapPointToRefElem(p, nodes));
103
104 // get Jacobian and its determinant
105 std::vector<std::vector<double>> J;
106 auto detJ = getJacobian(p, nodes, &J);
107
108 auto J_inv = util::inv(J);
109
110 // to hold derivatives
111 std::vector<std::vector<double>> ders(ders_ref.size(),
112 std::vector<double>(3, 0.));
113
114 // grad N_i = J_inv * grad N_i^ref
115 for (size_t i = 0; i < 4; i++)
116 ders[i] = util::dot(J_inv, ders_ref[i]);
117
118 return ders;
119}
std::vector< std::vector< double > > getDerShapes(const util::Point &p, const std::vector< util::Point > &nodes) override
Returns the values of derivative of shape function at point p.
Definition tetElem.cpp:98
double getJacobian(const util::Point &p, const std::vector< util::Point > &nodes, std::vector< std::vector< double > > *J) override
Computes the Jacobian of map .
Definition tetElem.cpp:176
util::Point mapPointToRefElem(const util::Point &p, const std::vector< util::Point > &nodes) override
Maps point p in a given element to the reference element.
Definition tetElem.cpp:142
std::vector< std::vector< double > > inv(const std::vector< std::vector< double > > &m)
Computes the determinant of matrix.
Definition matrix.cpp:93
std::vector< double > dot(const std::vector< std::vector< double > > &m, const std::vector< double > &v)
Computes the dot product between matrix and vector.
Definition matrix.cpp:38

References util::dot(), and util::inv().

Here is the call graph for this function:

◆ getJacobian()

double fe::TetElem::getJacobian ( const util::Point p,
const std::vector< util::Point > &  nodes,
std::vector< std::vector< double > > *  J 
)
overrideprivatevirtual

Computes the Jacobian of map \( \Phi: T^0 \to T \).

Parameters
pLocation of point in reference element
nodesVertices of element
JMatrix to store the Jacobian (if not nullptr)
Returns
det(J) Determinant of the Jacobain

Implements fe::BaseElem.

Definition at line 176 of file tetElem.cpp.

178 {
179 if (J != nullptr) {
180 J->resize(3);
181 (*J)[0] = std::vector<double>{nodes[1].d_x - nodes[0].d_x,
182 nodes[1].d_y - nodes[0].d_y,
183 nodes[1].d_z - nodes[0].d_z};
184 (*J)[1] = std::vector<double>{nodes[2].d_x - nodes[0].d_x,
185 nodes[2].d_y - nodes[0].d_y,
186 nodes[2].d_z - nodes[0].d_z};
187 (*J)[2] = std::vector<double>{nodes[3].d_x - nodes[0].d_x,
188 nodes[3].d_y - nodes[0].d_y,
189 nodes[3].d_z - nodes[0].d_z};
190
191 return util::det(*J);
192 } else {
193 std::vector<std::vector<double>> J_local;
194 J_local.resize(3);
195 J_local[0] = std::vector<double>{nodes[1].d_x - nodes[0].d_x,
196 nodes[1].d_y - nodes[0].d_y,
197 nodes[1].d_z - nodes[0].d_z};
198 J_local[1] = std::vector<double>{nodes[2].d_x - nodes[0].d_x,
199 nodes[2].d_y - nodes[0].d_y,
200 nodes[2].d_z - nodes[0].d_z};
201 J_local[2] = std::vector<double>{nodes[3].d_x - nodes[0].d_x,
202 nodes[3].d_y - nodes[0].d_y,
203 nodes[3].d_z - nodes[0].d_z};
204
205 return util::det(J_local);
206 }
207}
double det(const std::vector< std::vector< double > > &m)
Computes the determinant of matrix.
Definition matrix.cpp:75

References util::det().

Here is the call graph for this function:

◆ getShapes() [1/2]

std::vector< double > fe::TetElem::getShapes ( const util::Point p)
overrideprivatevirtual

Returns the values of shape function at point p on reference element.

Parameters
pLocation of point
Returns
vector Vector of shape functions at point p

Implements fe::BaseElem.

Definition at line 120 of file tetElem.cpp.

120 {
121 // N1 = 1 - xi - eta - zeta, N2 = xi, N3 = eta, N4 = zeta
122 return std::vector<double>{1. - p.d_x - p.d_y - p.d_z, p.d_x, p.d_y, p.d_z};
123}
double d_y
the y coordinate
Definition point.h:36
double d_z
the z coordinate
Definition point.h:39
double d_x
the x coordinate
Definition point.h:33

References util::Point::d_x, util::Point::d_y, and util::Point::d_z.

◆ getShapes() [2/2]

std::vector< double > fe::TetElem::getShapes ( const util::Point p,
const std::vector< util::Point > &  nodes 
)
overridevirtual

Returns the values of shape function at point p.

We first map the point p in \( T \) to reference tetrahedron \( T^0 \) using fe::TetElem::mapPointToRefElem and then compute shape functions at the mapped point using fe::TetElem::getShapes(const util::Point &).

Parameters
pLocation of point
nodesVertices of element
Returns
vector Vector of shape functions at point p

Reimplemented from fe::BaseElem.

Definition at line 93 of file tetElem.cpp.

94 {
95 return getShapes(mapPointToRefElem(p, nodes));
96}
std::vector< double > getShapes(const util::Point &p, const std::vector< util::Point > &nodes) override
Returns the values of shape function at point p.
Definition tetElem.cpp:93

◆ init()

void fe::TetElem::init ( )
overrideprivatevirtual

Compute the quadrature points for triangle element.

Implements fe::BaseElem.

Definition at line 209 of file tetElem.cpp.

209 {
210 //
211 // compute quad data for reference triangle with vertex at
212 // (0,0), (1,0), (0,1)
213 //
214
215 if (!d_quads.empty()) return;
216
217 // no point in zeroth order
218 if (d_quadOrder == 0) {
219 d_quads.resize(0);
220 }
221
222 // 3x3 identity matrix
223 std::vector<std::vector<double>> ident_mat;
224 ident_mat.push_back(std::vector<double>{1., 0., 0.});
225 ident_mat.push_back(std::vector<double>{0., 1., 0.});
226 ident_mat.push_back(std::vector<double>{0., 0., 1.});
227
228 //
229 // These datas are from LibMesh code
230 // See: https://libmesh.github.io/doxygen/quadrature__gauss__3D_8C_source.html
231
232 //
233 // first order quad points for triangle
234 //
235 if (d_quadOrder == 1) {
236 d_quads.clear();
237 fe::QuadData qd;
238 qd.d_w = 1. / 6.;
239 qd.d_p = util::Point(1. / 4., 1. / 4., 1. / 4.);
240 // N1 = 1 - xi - eta, N2 = xi, N3 = eta
241 qd.d_shapes = getShapes(qd.d_p);
242 // d N1/d xi = -1, d N1/d eta = -1, d N2/ d xi = 1, d N2/d eta = 0,
243 // d N3/ d xi = 0, d N3/d eta = 1
245 qd.d_J = ident_mat;
246 qd.d_detJ = 1.;
247 d_quads.push_back(qd);
248 }
249
250 //
251 // second order quad points for triangle
252 //
253 if (d_quadOrder == 2) {
254 d_quads.clear();
255 fe::QuadData qd;
256
257 double w = 1. / 24.;
258 double a = 0.585410196624969;
259 double b = 0.138196601125011;
260 // point 1
261 qd.d_w = w;
262 qd.d_p = util::Point(a, b, b);
263 qd.d_shapes = getShapes(qd.d_p);
265 qd.d_J = ident_mat;
266 qd.d_detJ = 1.;
267 d_quads.push_back(qd);
268 // point 2
269 qd.d_w = w;
270 qd.d_p = util::Point(b, a, b);
271 qd.d_shapes = getShapes(qd.d_p);
273 qd.d_J = ident_mat;
274 qd.d_detJ = 1.;
275 d_quads.push_back(qd);
276 // point 3
277 qd.d_w = w;
278 qd.d_p = util::Point(b, b, a);
279 qd.d_shapes = getShapes(qd.d_p);
281 qd.d_J = ident_mat;
282 qd.d_detJ = 1.;
283 d_quads.push_back(qd);
284 // point 4
285 qd.d_w = w;
286 qd.d_p = util::Point(b, b, b);
287 qd.d_shapes = getShapes(qd.d_p);
289 qd.d_J = ident_mat;
290 qd.d_detJ = 1.;
291 d_quads.push_back(qd);
292 }
293
294 //
295 // third order quad points for triangle
296 //
297 if (d_quadOrder == 3) {
298 d_quads.clear();
299 fe::QuadData qd;
300
301 double w1 = -2. / 15.;
302 double w2 = 0.075;
303
304 double a = 0.25;
305 double b = 0.5;
306 double c = 1. / 6.;
307
308 // point 1
309 qd.d_w = w1;
310 qd.d_p = util::Point(a, a, a);
311 qd.d_shapes = getShapes(qd.d_p);
313 qd.d_J = ident_mat;
314 qd.d_detJ = 1.;
315 d_quads.push_back(qd);
316 // point 2
317 qd.d_w = w2;
318 qd.d_p = util::Point(b, c, c);
319 qd.d_shapes = getShapes(qd.d_p);
321 qd.d_J = ident_mat;
322 qd.d_detJ = 1.;
323 d_quads.push_back(qd);
324 // point 3
325 qd.d_w = w2;
326 qd.d_p = util::Point(c, b, c);
327 qd.d_shapes = getShapes(qd.d_p);
329 qd.d_J = ident_mat;
330 qd.d_detJ = 1.;
331 d_quads.push_back(qd);
332 // point 4
333 qd.d_w = w2;
334 qd.d_p = util::Point(c, c, b);
335 qd.d_shapes = getShapes(qd.d_p);
337 qd.d_J = ident_mat;
338 qd.d_detJ = 1.;
339 d_quads.push_back(qd);
340 // point 5
341 qd.d_w = w2;
342 qd.d_p = util::Point(c, c, c);
343 qd.d_shapes = getShapes(qd.d_p);
345 qd.d_J = ident_mat;
346 qd.d_detJ = 1.;
347 d_quads.push_back(qd);
348 }
349}
std::vector< fe::QuadData > d_quads
Quadrature data collection.
Definition baseElem.h:224
A struct to store the quadrature data. List of data are.
Definition quadData.h:23
std::vector< double > d_shapes
Value of shape functions at quad point p.
Definition quadData.h:37
std::vector< std::vector< double > > d_derShapes
Derivatives of shape functions at the quad point.
Definition quadData.h:46
double d_w
Quadrature weight.
Definition quadData.h:26
util::Point d_p
Quadrature point in 1-d, 2-d or 3-d.
Definition quadData.h:29
std::vector< std::vector< double > > d_J
Jacobian of the map from reference element to the element.
Definition quadData.h:54
double d_detJ
Determinant of the Jacobian of the map from reference element to the element.
Definition quadData.h:60
A structure to represent 3d vectors.
Definition point.h:30

References fe::QuadData::d_derShapes, fe::QuadData::d_detJ, fe::QuadData::d_J, fe::QuadData::d_p, fe::QuadData::d_shapes, and fe::QuadData::d_w.

Referenced by TetElem().

Here is the caller graph for this function:

◆ mapPointToRefElem()

util::Point fe::TetElem::mapPointToRefElem ( const util::Point p,
const std::vector< util::Point > &  nodes 
)
overrideprivatevirtual

Maps point p in a given element to the reference element.

Let \( v^1, v^2, v^3\) are three vertices of triangle \( T\) and let \(T^0 \) is the reference triangle. Following the introduction to fe::TriElem, the map \( (x,y) \in T \) to \( (\xi, \eta) \in T^0 \) is given by

\[ \xi = C_{11} (x - v^1_x) + C_{12} (y - v^1_y), \quad \eta = C_{21} (x - v^1_x) + C_{22} (y - v^1_y). \]

\( C\) is the inverse of matrix

\[ B = \left[ {\begin{array}{cc} v^2_x - v^1_x & v^3_x - v^1_x \\ v^2_y - v^1_y & v^3_y - v^1_y \end{array}}\right], \]

i.e.

\[ C := B^{-1} = \frac{1}{(v^2_x - v^1_x)(v^3_y - v^1_y) - (v^3_x - v^1_x) (v^2_y - v^1_y)} \left[ {\begin{array}{cc} v^3_y - v^1_y & -(v^3_x - v^1_x) \\ -(v^2_y - v^1_y) & v^2_x - v^1_x \end{array}}\right]. \]

If mapped point \( (\xi, \eta)\) does not satisfy following conditions

  • \[ 0\leq \xi, \eta \]

  • \[ \xi \leq 1 - \eta \quad (or\, equivalently) \quad \eta \leq 1 - \xi \]

    then the point \( (\xi,\eta) \) does not belong to the reference triangle or equivalently point \((x,y) \) does not belong to the triangle \( T \) and the method issues error. Otherwise the method returns point \( (\xi, \eta)\).
Parameters
pLocation of point
nodesVertices of element
Returns
vector Vector of shape functions at point p

Reimplemented from fe::BaseElem.

Definition at line 142 of file tetElem.cpp.

143 {
144
145 // get Jacobian matrix and compute its transpose
146 std::vector<std::vector<double>> J(3, std::vector<double>(3, 0.));
147 auto detJ = getJacobian(p, nodes, &J);
148
149 // get transpose of Jacobian
150 auto B = util::transpose(J);
151 auto detB = detJ;
152
153 // get inverse of B
154 auto B_inv = util::inv(B);
155
156 // get vector from first vertex to point p
157 std::vector<double> vec_p = {p.d_x - nodes[0].d_x,
158 p.d_y - nodes[0].d_y,
159 p.d_z - nodes[0].d_z};
160 // multiply B_inv to vector to transform point
161 auto p_ref = util::dot(B_inv, vec_p);
162
163 // check point
164 checkPoint(p_ref, nodes);
165
166 if (util::isLess(p_ref[0], 0.)) p_ref[0] = 0.;
167 if (util::isLess(p_ref[1], 0.)) p_ref[1] = 0.;
168 if (util::isLess(p_ref[2], 0.)) p_ref[2] = 0.;
169 if (util::isGreater(p_ref[0], 1.)) p_ref[0] = 1.;
170 if (util::isGreater(p_ref[1], 1.)) p_ref[1] = 1.;
171 if (util::isGreater(p_ref[2], 1.)) p_ref[2] = 1.;
172
173 return util::Point(p_ref);
174}
void checkPoint(const std::vector< double > &p, const std::vector< util::Point > &nodes)
Definition tetElem.cpp:22
bool isGreater(const double &a, const double &b)
Returns true if a > b.
Definition function.cpp:17
bool isLess(const double &a, const double &b)
Returns true if a < b.
Definition function.cpp:22
std::vector< std::vector< double > > transpose(const std::vector< std::vector< double > > &m)
Computes the tranpose of matrix.
Definition matrix.cpp:56

References util::Point::d_x, util::Point::d_y, util::Point::d_z, util::dot(), util::inv(), util::isGreater(), util::isLess(), and util::transpose().

Here is the call graph for this function:

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