MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
lor_util.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#ifndef MFEM_LOR_UTIL
13#define MFEM_LOR_UTIL
14
19
20namespace mfem
21{
22
23MFEM_HOST_DEVICE inline real_t Det2D(DeviceMatrix &J)
24{
25 return J(0,0)*J(1,1) - J(1,0)*J(0,1);
26}
27
28MFEM_HOST_DEVICE inline real_t Det3D(DeviceMatrix &J)
29{
30 return J(0,0) * (J(1,1) * J(2,2) - J(2,1) * J(1,2)) -
31 J(1,0) * (J(0,1) * J(2,2) - J(2,1) * J(0,2)) +
32 J(2,0) * (J(0,1) * J(1,2) - J(1,1) * J(0,2));
33}
34
35template <int ORDER, int SDIM=2>
36MFEM_HOST_DEVICE inline void LORVertexCoordinates2D(
37 const real_t *X, int iel_ho, int kx, int ky, real_t **v)
38{
39 const int nd1d = ORDER + 1;
40 const int nvert_per_el = nd1d*nd1d;
41
42 const int v0 = kx + nd1d*ky;
43 const int v1 = kx + 1 + nd1d*ky;
44 const int v2 = kx + 1 + nd1d*(ky + 1);
45 const int v3 = kx + nd1d*(ky + 1);
46
47 const int e0 = SDIM*(v0 + nvert_per_el*iel_ho);
48 const int e1 = SDIM*(v1 + nvert_per_el*iel_ho);
49 const int e2 = SDIM*(v2 + nvert_per_el*iel_ho);
50 const int e3 = SDIM*(v3 + nvert_per_el*iel_ho);
51
52 // Vertex coordinates
53 v[0][0] = X[e0 + 0];
54 v[1][0] = X[e0 + 1];
55
56 v[0][1] = X[e1 + 0];
57 v[1][1] = X[e1 + 1];
58
59 v[0][2] = X[e2 + 0];
60 v[1][2] = X[e2 + 1];
61
62 v[0][3] = X[e3 + 0];
63 v[1][3] = X[e3 + 1];
64
65 if (SDIM == 3)
66 {
67 v[2][0] = X[e0 + 2];
68 v[2][1] = X[e1 + 2];
69 v[2][2] = X[e2 + 2];
70 v[2][3] = X[e3 + 2];
71 }
72}
73
74template <int ORDER>
75MFEM_HOST_DEVICE inline void LORVertexCoordinates3D(
76 const real_t *X, int iel_ho, int kx, int ky, int kz,
77 real_t vx[8], real_t vy[8], real_t vz[8])
78{
79 const int dim = 3;
80 const int nd1d = ORDER + 1;
81 const int nvert_per_el = nd1d*nd1d*nd1d;
82
83 const int v0 = kx + nd1d*(ky + nd1d*kz);
84 const int v1 = kx + 1 + nd1d*(ky + nd1d*kz);
85 const int v2 = kx + 1 + nd1d*(ky + 1 + nd1d*kz);
86 const int v3 = kx + nd1d*(ky + 1 + nd1d*kz);
87 const int v4 = kx + nd1d*(ky + nd1d*(kz + 1));
88 const int v5 = kx + 1 + nd1d*(ky + nd1d*(kz + 1));
89 const int v6 = kx + 1 + nd1d*(ky + 1 + nd1d*(kz + 1));
90 const int v7 = kx + nd1d*(ky + 1 + nd1d*(kz + 1));
91
92 const int e0 = dim*(v0 + nvert_per_el*iel_ho);
93 const int e1 = dim*(v1 + nvert_per_el*iel_ho);
94 const int e2 = dim*(v2 + nvert_per_el*iel_ho);
95 const int e3 = dim*(v3 + nvert_per_el*iel_ho);
96 const int e4 = dim*(v4 + nvert_per_el*iel_ho);
97 const int e5 = dim*(v5 + nvert_per_el*iel_ho);
98 const int e6 = dim*(v6 + nvert_per_el*iel_ho);
99 const int e7 = dim*(v7 + nvert_per_el*iel_ho);
100
101 vx[0] = X[e0 + 0];
102 vy[0] = X[e0 + 1];
103 vz[0] = X[e0 + 2];
104
105 vx[1] = X[e1 + 0];
106 vy[1] = X[e1 + 1];
107 vz[1] = X[e1 + 2];
108
109 vx[2] = X[e2 + 0];
110 vy[2] = X[e2 + 1];
111 vz[2] = X[e2 + 2];
112
113 vx[3] = X[e3 + 0];
114 vy[3] = X[e3 + 1];
115 vz[3] = X[e3 + 2];
116
117 vx[4] = X[e4 + 0];
118 vy[4] = X[e4 + 1];
119 vz[4] = X[e4 + 2];
120
121 vx[5] = X[e5 + 0];
122 vy[5] = X[e5 + 1];
123 vz[5] = X[e5 + 2];
124
125 vx[6] = X[e6 + 0];
126 vy[6] = X[e6 + 1];
127 vz[6] = X[e6 + 2];
128
129 vx[7] = X[e7 + 0];
130 vy[7] = X[e7 + 1];
131 vz[7] = X[e7 + 2];
132}
133
134template <int SDIM=2>
135MFEM_HOST_DEVICE inline void Jacobian2D(
136 const real_t x, const real_t y, real_t **v, DeviceMatrix &J);
137
138template <> MFEM_HOST_DEVICE inline void Jacobian2D<2>(
139 const real_t x, const real_t y, real_t **v, DeviceMatrix &J)
140{
141 J(0,0) = -(1-y)*v[0][0] + (1-y)*v[0][1] + y*v[0][2] - y*v[0][3];
142 J(0,1) = -(1-x)*v[0][0] - x*v[0][1] + x*v[0][2] + (1-x)*v[0][3];
143
144 J(1,0) = -(1-y)*v[1][0] + (1-y)*v[1][1] + y*v[1][2] - y*v[1][3];
145 J(1,1) = -(1-x)*v[1][0] - x*v[1][1] + x*v[1][2] + (1-x)*v[1][3];
146}
147
148template <> MFEM_HOST_DEVICE inline void Jacobian2D<3>(
149 const real_t x, const real_t y, real_t **v, DeviceMatrix &J)
150{
151 J(0,0) = -(1-y)*v[0][0] + (1-y)*v[0][1] + y*v[0][2] - y*v[0][3];
152 J(0,1) = -(1-x)*v[0][0] - x*v[0][1] + x*v[0][2] + (1-x)*v[0][3];
153
154 J(1,0) = -(1-y)*v[1][0] + (1-y)*v[1][1] + y*v[1][2] - y*v[1][3];
155 J(1,1) = -(1-x)*v[1][0] - x*v[1][1] + x*v[1][2] + (1-x)*v[1][3];
156
157 J(2,0) = -(1-y)*v[2][0] + (1-y)*v[2][1] + y*v[2][2] - y*v[2][3];
158 J(2,1) = -(1-x)*v[2][0] - x*v[2][1] + x*v[2][2] + (1-x)*v[2][3];
159}
160
161template <int ORDER, int SDIM, bool RT, bool ND>
162MFEM_HOST_DEVICE inline void SetupLORQuadData2D(
163 const real_t *X, int iel_ho, int kx, int ky, DeviceTensor<3> &Q, bool piola)
164{
165 real_t vx[4], vy[4], vz[4];
166 real_t *v[] = {vx, vy, vz};
167 LORVertexCoordinates2D<ORDER,SDIM>(X, iel_ho, kx, ky, v);
168
169 for (int iqy=0; iqy<2; ++iqy)
170 {
171 for (int iqx=0; iqx<2; ++iqx)
172 {
173 const real_t x = iqx;
174 const real_t y = iqy;
175 const real_t w = 1.0/4.0;
176
177 real_t J_[SDIM*2];
178 DeviceTensor<2> J(J_, SDIM, 2);
179
180 Jacobian2D<SDIM>(x, y, v, J);
181
182 if (SDIM == 2)
183 {
184 const real_t detJ = Det2D(J);
185 const real_t w_detJ = w/detJ;
186 const real_t E = J(0,0)*J(0,0) + J(1,0)*J(1,0);
187 const real_t F = J(0,0)*J(0,1) + J(1,0)*J(1,1);
188 const real_t G = J(0,1)*J(0,1) + J(1,1)*J(1,1);
189 Q(0,iqy,iqx) = w_detJ * (RT ? E : G); // 1,1
190 Q(1,iqy,iqx) = w_detJ * (RT ? F : -F); // 1,2
191 Q(2,iqy,iqx) = w_detJ * (RT ? G : E); // 2,2
192 Q(3,iqy,iqx) = (ND || RT) ? w_detJ : w*detJ;
193 }
194 else
195 {
196 const real_t E = J(0,0)*J(0,0) + J(1,0)*J(1,0) + J(2,0)*J(2,0);
197 const real_t F = J(0,0)*J(0,1) + J(1,0)*J(1,1) + J(2,0)*J(2,1);
198 const real_t G = J(0,1)*J(0,1) + J(1,1)*J(1,1) + J(2,1)*J(2,1);
199 const real_t detJ = sqrt(E*G - F*F);
200 const real_t w_detJ = w/detJ;
201 Q(0,iqy,iqx) = w_detJ * (RT ? E : G); // 1,1
202 Q(1,iqy,iqx) = w_detJ * (RT ? F : -F); // 1,2
203 Q(2,iqy,iqx) = w_detJ * (RT ? G : E); // 2,2
204 Q(3,iqy,iqx) = (ND || RT) ? w_detJ : w*detJ;
205 }
206 }
207 }
208}
209
210MFEM_HOST_DEVICE inline void Jacobian3D(
211 const real_t x, const real_t y, const real_t z,
212 const real_t vx[8], const real_t vy[8], const real_t vz[8],
213 DeviceMatrix &J)
214{
215 // c: (1-x)(1-y)(1-z)v0[c] + x (1-y)(1-z)v1[c] + x y (1-z)v2[c] + (1-x) y (1-z)v3[c]
216 // + (1-x)(1-y) z v4[c] + x (1-y) z v5[c] + x y z v6[c] + (1-x) y z v7[c]
217 J(0,0) = -(1-y)*(1-z)*vx[0]
218 + (1-y)*(1-z)*vx[1] + y*(1-z)*vx[2] - y*(1-z)*vx[3]
219 - (1-y)*z*vx[4] + (1-y)*z*vx[5] + y*z*vx[6] - y*z*vx[7];
220
221 J(0,1) = -(1-x)*(1-z)*vx[0]
222 - x*(1-z)*vx[1] + x*(1-z)*vx[2] + (1-x)*(1-z)*vx[3]
223 - (1-x)*z*vx[4] - x*z*vx[5] + x*z*vx[6] + (1-x)*z*vx[7];
224
225 J(0,2) = -(1-x)*(1-y)*vx[0] - x*(1-y)*vx[1]
226 - x*y*vx[2] - (1-x)*y*vx[3] + (1-x)*(1-y)*vx[4]
227 + x*(1-y)*vx[5] + x*y*vx[6] + (1-x)*y*vx[7];
228
229 J(1,0) = -(1-y)*(1-z)*vy[0] + (1-y)*(1-z)*vy[1]
230 + y*(1-z)*vy[2] - y*(1-z)*vy[3] - (1-y)*z*vy[4]
231 + (1-y)*z*vy[5] + y*z*vy[6] - y*z*vy[7];
232
233 J(1,1) = -(1-x)*(1-z)*vy[0] - x*(1-z)*vy[1]
234 + x*(1-z)*vy[2] + (1-x)*(1-z)*vy[3]- (1-x)*z*vy[4] -
235 x*z*vy[5] + x*z*vy[6] + (1-x)*z*vy[7];
236
237 J(1,2) = -(1-x)*(1-y)*vy[0] - x*(1-y)*vy[1]
238 - x*y*vy[2] - (1-x)*y*vy[3] + (1-x)*(1-y)*vy[4]
239 + x*(1-y)*vy[5] + x*y*vy[6] + (1-x)*y*vy[7];
240
241 J(2,0) = -(1-y)*(1-z)*vz[0] + (1-y)*(1-z)*vz[1]
242 + y*(1-z)*vz[2] - y*(1-z)*vz[3]- (1-y)*z*vz[4] +
243 (1-y)*z*vz[5] + y*z*vz[6] - y*z*vz[7];
244
245 J(2,1) = -(1-x)*(1-z)*vz[0] - x*(1-z)*vz[1]
246 + x*(1-z)*vz[2] + (1-x)*(1-z)*vz[3] - (1-x)*z*vz[4]
247 - x*z*vz[5] + x*z*vz[6] + (1-x)*z*vz[7];
248
249 J(2,2) = -(1-x)*(1-y)*vz[0] - x*(1-y)*vz[1]
250 - x*y*vz[2] - (1-x)*y*vz[3] + (1-x)*(1-y)*vz[4]
251 + x*(1-y)*vz[5] + x*y*vz[6] + (1-x)*y*vz[7];
252}
253
254MFEM_HOST_DEVICE inline void Adjugate3D(const DeviceMatrix &J, DeviceMatrix &A)
255{
256 A(0,0) = (J(1,1) * J(2,2)) - (J(1,2) * J(2,1));
257 A(0,1) = (J(2,1) * J(0,2)) - (J(0,1) * J(2,2));
258 A(0,2) = (J(0,1) * J(1,2)) - (J(1,1) * J(0,2));
259 A(1,0) = (J(2,0) * J(1,2)) - (J(1,0) * J(2,2));
260 A(1,1) = (J(0,0) * J(2,2)) - (J(0,2) * J(2,0));
261 A(1,2) = (J(1,0) * J(0,2)) - (J(0,0) * J(1,2));
262 A(2,0) = (J(1,0) * J(2,1)) - (J(2,0) * J(1,1));
263 A(2,1) = (J(2,0) * J(0,1)) - (J(0,0) * J(2,1));
264 A(2,2) = (J(0,0) * J(1,1)) - (J(0,1) * J(1,0));
265}
266
267}
268
269#endif
A basic generic Tensor class, appropriate for use on the GPU.
Definition dtensor.hpp:82
int dim
Definition ex24.cpp:53
constexpr int SDIM
MFEM_HOST_DEVICE void Jacobian2D< 2 >(const real_t x, const real_t y, real_t **v, DeviceMatrix &J)
Definition lor_util.hpp:138
MFEM_HOST_DEVICE void SetupLORQuadData2D(const real_t *X, int iel_ho, int kx, int ky, DeviceTensor< 3 > &Q, bool piola)
Definition lor_util.hpp:162
MFEM_HOST_DEVICE void Jacobian3D(const real_t x, const real_t y, const real_t z, const real_t vx[8], const real_t vy[8], const real_t vz[8], DeviceMatrix &J)
Definition lor_util.hpp:210
MFEM_HOST_DEVICE void Jacobian2D(const real_t x, const real_t y, real_t **v, DeviceMatrix &J)
MFEM_HOST_DEVICE real_t Det3D(DeviceMatrix &J)
Definition lor_util.hpp:28
MFEM_HOST_DEVICE void Adjugate3D(const DeviceMatrix &J, DeviceMatrix &A)
Definition lor_util.hpp:254
float real_t
Definition config.hpp:43
MFEM_HOST_DEVICE void LORVertexCoordinates2D(const real_t *X, int iel_ho, int kx, int ky, real_t **v)
Definition lor_util.hpp:36
MFEM_HOST_DEVICE void Jacobian2D< 3 >(const real_t x, const real_t y, real_t **v, DeviceMatrix &J)
Definition lor_util.hpp:148
MFEM_HOST_DEVICE void LORVertexCoordinates3D(const real_t *X, int iel_ho, int kx, int ky, int kz, real_t vx[8], real_t vy[8], real_t vz[8])
Definition lor_util.hpp:75
MFEM_HOST_DEVICE real_t Det2D(DeviceMatrix &J)
Definition lor_util.hpp:23