Chi-Tech
LagrangeHexMapping.cc
Go to the documentation of this file.
2
3#include "mesh/Cell/cell.h"
4
5#include "chi_log.h"
6
8{
9
11 const chi_mesh::Cell& cell,
12 const Quadrature& volume_quadrature,
13 const Quadrature& surface_quadrature)
15 cell,
16 8,
17 MakeFaceNodeMapping(cell),
18 volume_quadrature,
19 surface_quadrature)
20{
21}
22
23double LagrangeHexMapping::RefShape(uint32_t i, const Vec3& qpoint) const
24{
25 ChiLogicalErrorIf(i >= 8, "Invalid shapefunction index " + std::to_string(i));
26
27 double a, b, c;
28 // clang-format off
29 if (i == 0) {a = -1.0; b=-1.0; c=-1.0;}
30 if (i == 1) {a = 1.0; b=-1.0; c=-1.0;}
31 if (i == 2) {a = 1.0; b= 1.0; c=-1.0;}
32 if (i == 3) {a = -1.0; b= 1.0; c=-1.0;}
33
34 if (i == 4) {a = -1.0; b=-1.0; c= 1.0;}
35 if (i == 5) {a = 1.0; b=-1.0; c= 1.0;}
36 if (i == 6) {a = 1.0; b= 1.0; c= 1.0;}
37 if (i == 7) {a = -1.0; b= 1.0; c= 1.0;}
38
39 return 0.125 *
40 (1.0 + a * qpoint.x) * (1.0 + b * qpoint.y) * (1.0 + c * qpoint.z);
41 // clang-format on
42}
43
45 const Vec3& qpoint) const
46{
47 ChiLogicalErrorIf(i >= 8, "Invalid shapefunction index " + std::to_string(i));
48
49 double a, b, c;
50 // clang-format off
51 if (i == 0) {a = -1.0; b=-1.0; c=-1.0;}
52 if (i == 1) {a = 1.0; b=-1.0; c=-1.0;}
53 if (i == 2) {a = 1.0; b= 1.0; c=-1.0;}
54 if (i == 3) {a = -1.0; b= 1.0; c=-1.0;}
55
56 if (i == 4) {a = -1.0; b=-1.0; c= 1.0;}
57 if (i == 5) {a = 1.0; b=-1.0; c= 1.0;}
58 if (i == 6) {a = 1.0; b= 1.0; c= 1.0;}
59 if (i == 7) {a = -1.0; b= 1.0; c= 1.0;}
60 // clang-format on
61
62 const double x = qpoint.x;
63 const double y = qpoint.y;
64 const double z = qpoint.z;
65
66 return Vec3(0.125 * a * (1.0 + b * y) * (1.0 + c * z),
67 0.125 * b * (1.0 + a * x) * (1.0 + c * z),
68 0.125 * c * (1.0 + a * x) * (1.0 + b * y));
69}
70
73{
74 MatDbl J(3, VecDbl(3, 0.0));
75 for (size_t i = 0; i < num_nodes_; ++i)
76 {
77 const Vec3 grad_shape_i = RefGradShape(i, qpoint);
78 const auto& node_i = node_locations_[i];
79 const double x_i = node_i.x;
80 const double y_i = node_i.y;
81 const double z_i = node_i.z;
82
83 // Loops unrolled for performance
84 J[0][0] += grad_shape_i.x * x_i;
85 J[0][1] += grad_shape_i.y * x_i;
86 J[0][2] += grad_shape_i.z * x_i;
87
88 J[1][0] += grad_shape_i.x * y_i;
89 J[1][1] += grad_shape_i.y * y_i;
90 J[1][2] += grad_shape_i.z * y_i;
91
92 J[2][0] += grad_shape_i.x * z_i;
93 J[2][1] += grad_shape_i.y * z_i;
94 J[2][2] += grad_shape_i.z * z_i;
95 }
96
97 return J;
98}
99
100std::pair<double, LagrangeBaseMapping::Vec3>
102 size_t face_index, const Vec3& qpoint_face) const
103{
104 const auto& x0 = node_locations_[face_node_mappings_[face_index][0]];
105 const auto& x1 = node_locations_[face_node_mappings_[face_index][1]];
106 const auto& x2 = node_locations_[face_node_mappings_[face_index][2]];
107 const auto& x3 = node_locations_[face_node_mappings_[face_index][3]];
108
109 const double xbar = qpoint_face.x;
110 const double ybar = qpoint_face.y;
111 Vec3 dx_dxbar;
112 Vec3 dx_dybar;
113 for (size_t i = 0; i < 4; ++i)
114 {
115 double a, b;
116 Vec3 xi;
117 // clang-format off
118 if (i == 0) {a = -1.0; b=-1.0; xi = x0;}
119 if (i == 1) {a = 1.0; b=-1.0; xi = x1;}
120 if (i == 2) {a = 1.0; b= 1.0; xi = x2;}
121 if (i == 3) {a = -1.0; b= 1.0; xi = x3;}
122 // clang-format on
123
124 const double ab = a * b;
125 dx_dxbar += 0.25 * (a + ab * ybar) * xi;
126 dx_dybar += 0.25 * (b + ab * xbar) * xi;
127 }
128
129 const auto cross = dx_dxbar.Cross(dx_dybar);
130 const double detJ = cross.Norm();
131
132 return {detJ, cross / detJ};
133}
134
137 const Vec3& qpoint_face) const
138{
139 const double x = qpoint_face.x + 1.0;
140 const double y = qpoint_face.y + 1.0;
141 // clang-format off
142 if (face_index == 0/*XMAX*/) return Vec3( 1.0, -1.0, -1.0) + Vec3(0.0, x, y);
143 if (face_index == 1/*XMIN*/) return Vec3(-1.0, 1.0, -1.0) + Vec3(0.0, -x, y);
144 if (face_index == 2/*YMAX*/) return Vec3( 1.0, 1.0, -1.0) + Vec3( -x,0.0, y);
145 if (face_index == 3/*YMIN*/) return Vec3(-1.0, -1.0, -1.0) + Vec3( x,0.0, y);
146 if (face_index == 4/*ZMAX*/) return Vec3(-1.0, -1.0, 1.0) + Vec3( x, y,0.0);
147 if (face_index == 5/*ZMIN*/) return Vec3(-1.0, 1.0, -1.0) + Vec3( x, -y,0.0);
148 // clang-format on
149
150 ChiLogicalError("Invalid face index " + std::to_string(face_index));
151}
152
153} // namespace chi_math::cell_mapping
#define ChiLogicalErrorIf(condition, message)
#define ChiLogicalError(message)
const std::vector< std::vector< int > > face_node_mappings_
Definition: CellMapping.h:130
const std::vector< chi_mesh::Vector3 > node_locations_
Definition: CellMapping.h:121
const size_t num_nodes_
Definition: CellMapping.h:120
double RefShape(uint32_t i, const Vec3 &qpoint) const override
std::pair< double, Vec3 > RefFaceJacobianDeterminantAndNormal(size_t face_index, const Vec3 &qpoint_face) const override
MatDbl RefJacobian(const Vec3 &qpoint) const override
Vec3 FaceToElementQPointConversion(size_t face_index, const Vec3 &qpoint_face) const override
Vec3 RefGradShape(uint32_t i, const Vec3 &qpoint) const override
LagrangeHexMapping(const chi_mesh::MeshContinuum &grid, const chi_mesh::Cell &cell, const Quadrature &volume_quadrature, const Quadrature &surface_quadrature)
double x
Element-0.
Vector3 Cross(const Vector3 &that) const
double y
Element-1.
double z
Element-2.
double Norm() const