Nalu
Nalu: a generalized unstructured massively parallel low Mach flow code designed to support a variety of energy applications of interest (most notably Wind ECP) built on the Sierra Toolkit and Trilinos solver Tpetra/Epetra stack. The open source BSD, clause 3 license model has been chosen for the code base. See LICENSE for more information. http://NaluCFD.org
Hex8GeometryFunctions.h
Go to the documentation of this file.
1 /*------------------------------------------------------------------------*/
2 /* Copyright 2014 Sandia Corporation. */
3 /* This software is released under the license detailed */
4 /* in the file, LICENSE, which is located in the top-level Nalu */
5 /* directory structure */
6 /*------------------------------------------------------------------------*/
7 
8 #ifndef Hex8GeometryFunctions_h
9 #define Hex8GeometryFunctions_h
10 
11 #include <AlgTraits.h>
12 
14 
15 #include <SimdInterface.h>
16 #include <Kokkos_Core.hpp>
17 
18 #include <stk_util/environment/ReportHandler.hpp>
19 
20 #include <vector>
21 #include <cstdlib>
22 #include <stdexcept>
23 #include <string>
24 #include <array>
25 #include <type_traits>
26 
27 namespace sierra {
28 namespace nalu {
29 
30  template <typename ViewType>
32  int ics,
33  const typename ViewType::value_type areacoords[4][3],
34  const ViewType& area)
35  {
44  using ftype = typename ViewType::value_type;
45 
46  area(ics,0) = 0.0;
47  area(ics,1) = 0.0;
48  area(ics,2) = 0.0;
49 
50  const ftype xmid[3] = {
51  0.25 * (areacoords[0][0] + areacoords[1][0] + areacoords[2][0] + areacoords[3][0]),
52  0.25 * (areacoords[0][1] + areacoords[1][1] + areacoords[2][1] + areacoords[3][1]),
53  0.25 * (areacoords[0][2] + areacoords[1][2] + areacoords[2][2] + areacoords[3][2])
54  };
55 
56  ftype r1[3] = { areacoords[0][0] - xmid[0], areacoords[0][1] - xmid[1], areacoords[0][2] - xmid[2] };
57  for (int itriangle = 0; itriangle < 4; ++itriangle) {
58  const int t_index = (itriangle + 1) % 4;
59  const ftype r2[3] = {
60  areacoords[t_index][0] - xmid[0],
61  areacoords[t_index][1] - xmid[1],
62  areacoords[t_index][2] - xmid[2]
63  };
64 
65  area(ics, 0) += r1[1] * r2[2] - r2[1] * r1[2];
66  area(ics, 1) += r1[2] * r2[0] - r2[2] * r1[0];
67  area(ics, 2) += r1[0] * r2[1] - r2[0] * r1[1];
68 
69  r1[0] = r2[0];
70  r1[1] = r2[1];
71  r1[2] = r2[2];
72  }
73  area(ics,0) *= 0.5;
74  area(ics,1) *= 0.5;
75  area(ics,2) *= 0.5;
76  }
77 
78  template <typename RealType>
79  RealType hex_volume_grandy(RealType scvcoords[8][3])
80  {
88  constexpr int nTri = 24;
89  constexpr int dim = 3;
90 
91  constexpr int nNodes = 8;
92  constexpr int nFaces = 6;
93  constexpr int npv = nNodes + nFaces;
94 
95  RealType coordv[npv][dim];
96 
97  // copy coordinates
98  for (int n = 0; n < nNodes; ++n) {
99  coordv[n][0] = scvcoords[n][0];
100  coordv[n][1] = scvcoords[n][1];
101  coordv[n][2] = scvcoords[n][2];
102  }
103 
104  constexpr int nodesPerFace = 4;
105  constexpr int face_nodes[nFaces][nodesPerFace] = {
106  { 0, 3, 2, 1 }, { 4, 5, 6, 7 },
107  { 0, 1, 5, 4 }, { 2, 3, 7, 6 },
108  { 1, 2, 6, 5 }, { 0, 4, 3, 7 }
109  };
110 
111  // append face midpoint coordinates
112  for (int k = 0; k < nFaces; ++k) {
113  const int coordIndex = k + nNodes;
114  for (int d = 0; d < dim; ++d) {
115  coordv[coordIndex][d] = 0.25 * (
116  coordv[face_nodes[k][0]][d]
117  + coordv[face_nodes[k][1]][d]
118  + coordv[face_nodes[k][2]][d]
119  + coordv[face_nodes[k][3]][d]
120  );
121  }
122  }
123 
124  constexpr int triangular_facets[nTri][3] = {
125  { 0, 8, 1}, { 8, 2, 1}, { 3, 2, 8},
126  { 3, 8, 0}, { 6, 9, 5}, { 7, 9, 6},
127  { 4, 9, 7}, { 4, 5, 9}, {10, 0, 1},
128  { 5, 10, 1}, { 4, 10, 5}, { 4, 0, 10},
129  { 7, 6, 11}, { 6, 2, 11}, { 2, 3, 11},
130  { 3, 7, 11}, { 6, 12, 2}, { 5, 12, 6},
131  { 5, 1, 12}, { 1, 2, 12}, { 0, 4, 13},
132  { 4, 7, 13}, { 7, 3, 13}, { 3, 0, 13}
133  };
134 
135  RealType volume = 0.0;
136  for (int k = 0; k < nTri; ++k) {
137  const int p = triangular_facets[k][0];
138  const int q = triangular_facets[k][1];
139  const int r = triangular_facets[k][2];
140 
141  const RealType triFaceMid[3] = {
142  coordv[p][0] + coordv[q][0] + coordv[r][0],
143  coordv[p][1] + coordv[q][1] + coordv[r][1],
144  coordv[p][2] + coordv[q][2] + coordv[r][2]
145  };
146 
147  enum {XC = 0, YC = 1, ZC = 2};
148  RealType dxv[3];
149 
150  dxv[0] = ( coordv[q][YC] - coordv[p][YC] ) * ( coordv[r][ZC] - coordv[p][ZC] )
151  - ( coordv[r][YC] - coordv[p][YC] ) * ( coordv[q][ZC] - coordv[p][ZC] );
152 
153  dxv[1] = ( coordv[r][XC] - coordv[p][XC] ) * ( coordv[q][ZC] - coordv[p][ZC] )
154  - ( coordv[q][XC] - coordv[p][XC] ) * ( coordv[r][ZC] - coordv[p][ZC] );
155 
156  dxv[2] = ( coordv[q][XC] - coordv[p][XC] ) * ( coordv[r][YC] - coordv[p][YC] )
157  - ( coordv[r][XC] - coordv[p][XC] ) * ( coordv[q][YC] - coordv[p][YC] );
158 
159  volume += triFaceMid[0] * dxv[0] + triFaceMid[1] * dxv[1] + triFaceMid[2] * dxv[2];
160  }
161  volume /= RealType(18.0);
162  return volume;
163  }
164 
165  template <typename CoordViewType>
166  void subdivide_hex_8(CoordViewType coords, typename CoordViewType::value_type coordv[27][3])
167  {
171  constexpr int numBaseNodes = 8;
172 
173  for (int n = 0; n < numBaseNodes; ++n) {
174  coordv[n][0] = coords(n,0);
175  coordv[n][1] = coords(n,1);
176  coordv[n][2] = coords(n,2);
177  }
178 
179  // Face-by-face ordering for the subdivided hex. This is different than what is done
180  // for a multilinear Hex27 element, which has equivalent nodal locations.
181  for (int d = 0; d < 3; ++d) {
182  // Face 0
183  coordv[8][d] = 0.5 * (coords(0,d) + coords(1,d)); // edge 1
184  coordv[9][d] = 0.5 * (coords(1,d) + coords(2,d)); // edge 2
185  coordv[10][d] = 0.5 * (coords(2,d) + coords(3,d)); // edge 3
186  coordv[11][d] = 0.5 * (coords(3,d) + coords(0,d)); // edge 4
187 
188  coordv[12][d] = 0.25 * (coords(0,d) + coords(1,d) + coords(2,d) + coords(3,d));
189 
190  // Face 1
191  coordv[13][d] = 0.5 * (coords(4,d) + coords(5,d)); // edge 5
192  coordv[14][d] = 0.5 * (coords(5,d) + coords(6,d)); // edge 6
193  coordv[15][d] = 0.5 * (coords(6,d) + coords(7,d)); // edge 7
194  coordv[16][d] = 0.5 * (coords(7,d) + coords(4,d)); // edge 8
195 
196  coordv[17][d] = 0.25 * (coords(4,d) + coords(5,d) + coords(6,d) + coords(7,d));
197 
198  // Face 2
199  coordv[18][d] = 0.5 * (coords(1,d) + coords(5,d)); // edge 9
200  coordv[19][d] = 0.5 * (coords(0,d) + coords(4,d)); // edge 10
201 
202  coordv[20][d] = 0.25 * (coords(0,d) + coords(1,d) + coords(4,d) + coords(5,d));
203 
204  // Face 3
205  coordv[21][d] = 0.5 * (coords(3,d) + coords(7,d)); // edge 11
206  coordv[22][d] = 0.5 * (coords(2,d) + coords(6,d)); // edge 12
207 
208  coordv[23][d] = 0.25 * (coords(2,d) + coords(3,d) + coords(6,d) + coords(7,d));
209 
210  // Face 4
211  coordv[24][d] = 0.25 * (coords(1,d) + coords(2,d) + coords(5,d) + coords(6,d));
212 
213  // Face 5
214  coordv[25][d] = 0.25 * (coords(0,d) + coords(3,d) + coords(4,d) + coords(7,d));
215 
216  // Volume centroid
217  coordv[26][d] = 0.;
218  for (int n = 0; n < 8; ++n) {
219  coordv[26][d] += coords(n,d);
220  }
221  coordv[26][d] *= 0.125;
222  }
223  }
224 
225 } // namespace nalu
226 } // namespace Sierra
227 
228 #endif
Definition: ABLForcingAlgorithm.C:26
STK SIMD Interface.
void subdivide_hex_8(CoordViewType coords, typename CoordViewType::value_type coordv[27][3])
Definition: Hex8GeometryFunctions.h:166
void quad_area_by_triangulation(int ics, const typename ViewType::value_type areacoords[4][3], const ViewType &area)
Definition: Hex8GeometryFunctions.h:31
RealType hex_volume_grandy(RealType scvcoords[8][3])
Definition: Hex8GeometryFunctions.h:79