Astaroth  2.2
stdderiv.h
Go to the documentation of this file.
1 #pragma once
2 #ifndef STENCIL_ORDER
3 #define STENCIL_ORDER (6)
4 #endif
5 
6 uniform Scalar AC_dsx = 0.04908738521;
7 uniform Scalar AC_dsy = 0.04908738521;
8 uniform Scalar AC_dsz = 0.04908738521;
9 uniform Scalar AC_inv_dsx = 1.0 / AC_dsx;
10 uniform Scalar AC_inv_dsy = 1.0 / AC_dsy;
11 uniform Scalar AC_inv_dsz = 1.0 / AC_dsz;
12 
13 Scalar
14 first_derivative(Scalar pencil[], Scalar inv_ds)
15 {
16 #if STENCIL_ORDER == 2
17  Scalar coefficients[] = {0, 1.0 / 2.0};
18 #elif STENCIL_ORDER == 4
19  Scalar coefficients[] = {0, 2.0 / 3.0, -1.0 / 12.0};
20 #elif STENCIL_ORDER == 6
21  Scalar coefficients[] = {0, 3.0 / 4.0, -3.0 / 20.0, 1.0 / 60.0};
22 #elif STENCIL_ORDER == 8
23  Scalar coefficients[] = {0, 4.0 / 5.0, -1.0 / 5.0, 4.0 / 105.0, -1.0 / 280.0};
24 #endif
25 
26 #define MID (STENCIL_ORDER / 2)
27 
28  Scalar res = 0;
29 
30  for (int i = 1; i <= MID; ++i) {
31  res += coefficients[i] * (pencil[MID + i] - pencil[MID - i]);
32  }
33 
34  return res * inv_ds;
35 }
36 
37 Scalar
38 second_derivative(Scalar pencil[], Scalar inv_ds)
39 {
40 #if STENCIL_ORDER == 2
41  Scalar coefficients[] = {-2.0, 1.0};
42 #elif STENCIL_ORDER == 4
43  Scalar coefficients[] = {-5.0 / 2.0, 4.0 / 3.0, -1.0 / 12.0};
44 #elif STENCIL_ORDER == 6
45  Scalar coefficients[] = {-49.0 / 18.0, 3.0 / 2.0, -3.0 / 20.0, 1.0 / 90.0};
46 #elif STENCIL_ORDER == 8
47  Scalar coefficients[] = {-205.0 / 72.0, 8.0 / 5.0, -1.0 / 5.0, 8.0 / 315.0, -1.0 / 560.0};
48 #endif
49 
50 #define MID (STENCIL_ORDER / 2)
51  Scalar res = coefficients[0] * pencil[MID];
52 
53  for (int i = 1; i <= MID; ++i) {
54  res += coefficients[i] * (pencil[MID + i] + pencil[MID - i]);
55  }
56 
57  return res * inv_ds * inv_ds;
58 }
59 
60 Scalar
61 cross_derivative(Scalar pencil_a[], Scalar pencil_b[], Scalar inv_ds_a, Scalar inv_ds_b)
62 {
63 #if STENCIL_ORDER == 2
64  Scalar coefficients[] = {0, 1.0 / 4.0};
65 #elif STENCIL_ORDER == 4
66  Scalar coefficients[] = {0, 1.0 / 32.0,
67  1.0 / 64.0}; // TODO correct coefficients, these are just placeholders
68 #elif STENCIL_ORDER == 6
69  Scalar fac = 1.0 / 720.0;
70  Scalar coefficients[] = {0.0 * fac, 270.0 * fac, -27.0 * fac, 2.0 * fac};
71 #elif STENCIL_ORDER == 8
72  Scalar fac = (1.0 / 20160.0);
73  Scalar coefficients[] = {0.0 * fac, 8064.0 * fac, -1008.0 * fac, 128.0 * fac, -9.0 * fac};
74 #endif
75 
76 #define MID (STENCIL_ORDER / 2)
77  Scalar res = 0.0;
78 
79  for (int i = 1; i <= MID; ++i) {
80  res += coefficients[i] *
81  (pencil_a[MID + i] + pencil_a[MID - i] - pencil_b[MID + i] - pencil_b[MID - i]);
82  }
83  return res * inv_ds_a * inv_ds_b;
84 }
85 
86 Scalar
87 derx(int3 vertexIdx, in ScalarField arr)
88 {
89  Scalar pencil[STENCIL_ORDER + 1];
90 
91  for (int offset = 0; offset < STENCIL_ORDER + 1; ++offset) {
92  pencil[offset] = arr[vertexIdx.x + offset - STENCIL_ORDER / 2, vertexIdx.y, vertexIdx.z];
93  }
94 
95  return first_derivative(pencil, AC_inv_dsx);
96 }
97 
98 Scalar
99 derxx(int3 vertexIdx, in ScalarField arr)
100 {
101  Scalar pencil[STENCIL_ORDER + 1];
102 
103  for (int offset = 0; offset < STENCIL_ORDER + 1; ++offset) {
104  pencil[offset] = arr[vertexIdx.x + offset - STENCIL_ORDER / 2, vertexIdx.y, vertexIdx.z];
105  }
106 
107  return second_derivative(pencil, AC_inv_dsx);
108 }
109 
110 Scalar
111 derxy(int3 vertexIdx, in ScalarField arr)
112 {
113  Scalar pencil_a[STENCIL_ORDER + 1];
114 
115  for (int offset = 0; offset < STENCIL_ORDER + 1; ++offset) {
116  pencil_a[offset] = arr[vertexIdx.x + offset - STENCIL_ORDER / 2,
117  vertexIdx.y + offset - STENCIL_ORDER / 2, vertexIdx.z];
118  }
119 
120  Scalar pencil_b[STENCIL_ORDER + 1];
121 
122  for (int offset = 0; offset < STENCIL_ORDER + 1; ++offset) {
123  pencil_b[offset] = arr[vertexIdx.x + offset - STENCIL_ORDER / 2,
124  vertexIdx.y + STENCIL_ORDER / 2 - offset, vertexIdx.z];
125  }
126 
127  return cross_derivative(pencil_a, pencil_b, AC_inv_dsx, AC_inv_dsy);
128 }
129 
130 Scalar
131 derxz(int3 vertexIdx, in ScalarField arr)
132 {
133  Scalar pencil_a[STENCIL_ORDER + 1];
134 
135  for (int offset = 0; offset < STENCIL_ORDER + 1; ++offset) {
136  pencil_a[offset] = arr[vertexIdx.x + offset - STENCIL_ORDER / 2, vertexIdx.y,
137  vertexIdx.z + offset - STENCIL_ORDER / 2];
138  }
139 
140  Scalar pencil_b[STENCIL_ORDER + 1];
141  for (int offset = 0; offset < STENCIL_ORDER + 1; ++offset) {
142  pencil_b[offset] = arr[vertexIdx.x + offset - STENCIL_ORDER / 2, vertexIdx.y,
143  vertexIdx.z + STENCIL_ORDER / 2 - offset];
144  }
145 
146  return cross_derivative(pencil_a, pencil_b, AC_inv_dsx, AC_inv_dsz);
147 }
148 
149 Scalar
150 dery(int3 vertexIdx, in ScalarField arr)
151 {
152  Scalar pencil[STENCIL_ORDER + 1];
153 
154  for (int offset = 0; offset < STENCIL_ORDER + 1; ++offset) {
155  pencil[offset] = arr[vertexIdx.x, vertexIdx.y + offset - STENCIL_ORDER / 2, vertexIdx.z];
156  }
157 
158  return first_derivative(pencil, AC_inv_dsy);
159 }
160 
161 Scalar
162 deryy(int3 vertexIdx, in ScalarField arr)
163 {
164  Scalar pencil[STENCIL_ORDER + 1];
165 
166  for (int offset = 0; offset < STENCIL_ORDER + 1; ++offset) {
167  pencil[offset] = arr[vertexIdx.x, vertexIdx.y + offset - STENCIL_ORDER / 2, vertexIdx.z];
168  }
169 
170  return second_derivative(pencil, AC_inv_dsy);
171 }
172 
173 Scalar
174 deryz(int3 vertexIdx, in ScalarField arr)
175 {
176  Scalar pencil_a[STENCIL_ORDER + 1];
177 
178  for (int offset = 0; offset < STENCIL_ORDER + 1; ++offset) {
179  pencil_a[offset] = arr[vertexIdx.x, vertexIdx.y + offset - STENCIL_ORDER / 2,
180  vertexIdx.z + offset - STENCIL_ORDER / 2];
181  }
182 
183  Scalar pencil_b[STENCIL_ORDER + 1];
184 
185  for (int offset = 0; offset < STENCIL_ORDER + 1; ++offset) {
186  pencil_b[offset] = arr[vertexIdx.x, vertexIdx.y + offset - STENCIL_ORDER / 2,
187  vertexIdx.z + STENCIL_ORDER / 2 - offset];
188  }
189 
190  return cross_derivative(pencil_a, pencil_b, AC_inv_dsy, AC_inv_dsz);
191 }
192 
193 Scalar
194 derz(int3 vertexIdx, in ScalarField arr)
195 {
196  Scalar pencil[STENCIL_ORDER + 1];
197 
198  for (int offset = 0; offset < STENCIL_ORDER + 1; ++offset) {
199  pencil[offset] = arr[vertexIdx.x, vertexIdx.y, vertexIdx.z + offset - STENCIL_ORDER / 2];
200  }
201 
202  return first_derivative(pencil, AC_inv_dsz);
203 }
204 
205 Scalar
206 derzz(int3 vertexIdx, in ScalarField arr)
207 {
208  Scalar pencil[STENCIL_ORDER + 1];
209 
210  for (int offset = 0; offset < STENCIL_ORDER + 1; ++offset) {
211  pencil[offset] = arr[vertexIdx.x, vertexIdx.y, vertexIdx.z + offset - STENCIL_ORDER / 2];
212  }
213 
214  return second_derivative(pencil, AC_inv_dsz);
215 }
216 
217 Preprocessed Scalar
218 value(in ScalarField vertex)
219 {
220  return vertex[vertexIdx];
221 }
222 
223 Device Vector
224 value(in VectorField uu)
225 {
226  return (Vector){value(uu.x), value(uu.y), value(uu.z)};
227 }
228 
229 Preprocessed Vector
230 gradient(in ScalarField vertex)
231 {
232  assert(AC_dsx > 0);
233  assert(AC_dsy > 0);
234  assert(AC_dsz > 0);
235 
236  assert(AC_inv_dsx > 0);
237  assert(AC_inv_dsy > 0);
238  assert(AC_inv_dsz > 0);
239 
240  return (Vector){derx(vertexIdx, vertex), dery(vertexIdx, vertex), derz(vertexIdx, vertex)};
241 }
242 
243 Preprocessed Matrix
244 hessian(in ScalarField vertex)
245 {
246  assert(AC_dsx > 0);
247  assert(AC_dsy > 0);
248  assert(AC_dsz > 0);
249 
250  assert(AC_inv_dsx > 0);
251  assert(AC_inv_dsy > 0);
252  assert(AC_inv_dsz > 0);
253 
254  Matrix mat;
255 
256  mat.row[0] = (Vector){derxx(vertexIdx, vertex), derxy(vertexIdx, vertex),
257  derxz(vertexIdx, vertex)};
258  mat.row[1] = (Vector){mat.row[0].y, deryy(vertexIdx, vertex), deryz(vertexIdx, vertex)};
259  mat.row[2] = (Vector){mat.row[0].z, mat.row[1].z, derzz(vertexIdx, vertex)};
260 
261  return mat;
262 }
263 
265 
267 laplace(in ScalarField data)
268 {
269  return hessian(data).row[0].x + hessian(data).row[1].y + hessian(data).row[2].z;
270 }
271 
273 divergence(in VectorField vec)
274 {
275  return gradient(vec.x).x + gradient(vec.y).y + gradient(vec.z).z;
276 }
277 
278 Device Vector
279 laplace_vec(in VectorField vec)
280 {
281  return (Vector){laplace(vec.x), laplace(vec.y), laplace(vec.z)};
282 }
283 
284 Device Vector
285 curl(in VectorField vec)
286 {
287  return (Vector){gradient(vec.z).y - gradient(vec.y).z, gradient(vec.x).z - gradient(vec.z).x,
288  gradient(vec.y).x - gradient(vec.x).y};
289 }
290 
291 Device Vector
292 gradient_of_divergence(in VectorField vec)
293 {
294  return (Vector){hessian(vec.x).row[0].x + hessian(vec.y).row[0].y + hessian(vec.z).row[0].z,
295  hessian(vec.x).row[1].x + hessian(vec.y).row[1].y + hessian(vec.z).row[1].z,
296  hessian(vec.x).row[2].x + hessian(vec.y).row[2].y + hessian(vec.z).row[2].z};
297 }
298 
299 // Takes uu gradients and returns S
301 stress_tensor(in VectorField vec)
302 {
303  Matrix S;
304 
305  S.row[0].x = (2.0 / 3.0) * gradient(vec.x).x -
306  (1.0 / 3.0) * (gradient(vec.y).y + gradient(vec.z).z);
307  S.row[0].y = (1.0 / 2.0) * (gradient(vec.x).y + gradient(vec.y).x);
308  S.row[0].z = (1.0 / 2.0) * (gradient(vec.x).z + gradient(vec.z).x);
309 
310  S.row[1].y = (2.0 / 3.0) * gradient(vec.y).y -
311  (1.0 / 3.0) * (gradient(vec.x).x + gradient(vec.z).z);
312 
313  S.row[1].z = (1.0 / 2.0) * (gradient(vec.y).z + gradient(vec.z).y);
314 
315  S.row[2].z = (2.0 / 3.0) * gradient(vec.z).z -
316  (1.0 / 3.0) * (gradient(vec.x).x + gradient(vec.y).y);
317 
318  S.row[1].x = S.row[0].y;
319  S.row[2].x = S.row[0].z;
320  S.row[2].y = S.row[1].z;
321 
322  return S;
323 }
324 
326 contract(const Matrix mat)
327 {
328  Scalar res = 0;
329 
330  for (int i = 0; i < 3; ++i) {
331  res += dot(mat.row[i], mat.row[i]);
332  }
333 
334  return res;
335 }
336 
338 
340 length(const Vector vec)
341 {
342  return sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);
343 }
344 
346 reciprocal_len(const Vector vec)
347 {
348  return rsqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);
349 }
350 
351 Device Vector
352 normalized(const Vector vec)
353 {
354  const Scalar inv_len = reciprocal_len(vec);
355  return inv_len * vec;
356 }
sqrt
#define sqrt(x)
Definition: math_utils.h:35
normalized
Device Vector normalized(const Vector vec)
Definition: stdderiv.h:352
second_derivative
Scalar second_derivative(Scalar pencil[], Scalar inv_ds)
Definition: stdderiv.h:38
AC_dsz
uniform Scalar AC_dsz
Definition: stdderiv.h:8
dery
Scalar dery(int3 vertexIdx, in ScalarField arr)
Definition: stdderiv.h:150
AC_dsx
uniform Scalar AC_dsx
Definition: stdderiv.h:6
device_s
Definition: kernels.h:16
derxx
Scalar derxx(int3 vertexIdx, in ScalarField arr)
Definition: stdderiv.h:99
gradient_of_divergence
Device Vector gradient_of_divergence(in VectorField vec)
Definition: stdderiv.h:292
hessian
Preprocessed Matrix hessian(in ScalarField vertex)
Definition: stdderiv.h:244
cross_derivative
Scalar cross_derivative(Scalar pencil_a[], Scalar pencil_b[], Scalar inv_ds_a, Scalar inv_ds_b)
Definition: stdderiv.h:61
gradient
Preprocessed Vector gradient(in ScalarField vertex)
Definition: stdderiv.h:230
derxz
Scalar derxz(int3 vertexIdx, in ScalarField arr)
Definition: stdderiv.h:131
Matrix
Definition: modelsolver.c:58
Scalar
AcReal Scalar
Definition: modelsolver.c:44
AC_inv_dsy
uniform Scalar AC_inv_dsy
Definition: stdderiv.h:10
stress_tensor
Device Matrix stress_tensor(in VectorField vec)
Definition: stdderiv.h:301
AC_inv_dsz
uniform Scalar AC_inv_dsz
Definition: stdderiv.h:11
length
Device Scalar length(const Vector vec)
Definition: stdderiv.h:340
laplace_vec
Device Vector laplace_vec(in VectorField vec)
Definition: stdderiv.h:279
reciprocal_len
Device Scalar reciprocal_len(const Vector vec)
Definition: stdderiv.h:346
value
Preprocessed Scalar value(in ScalarField vertex)
Definition: stdderiv.h:218
deryy
Scalar deryy(int3 vertexIdx, in ScalarField arr)
Definition: stdderiv.h:162
MID
#define MID
contract
Device Scalar contract(const Matrix mat)
Definition: stdderiv.h:326
curl
Device Vector curl(in VectorField vec)
Definition: stdderiv.h:285
divergence
Device Scalar divergence(in VectorField vec)
Definition: stdderiv.h:273
derz
Scalar derz(int3 vertexIdx, in ScalarField arr)
Definition: stdderiv.h:194
derxy
Scalar derxy(int3 vertexIdx, in ScalarField arr)
Definition: stdderiv.h:111
STENCIL_ORDER
#define STENCIL_ORDER
Definition: stdderiv.h:3
derzz
Scalar derzz(int3 vertexIdx, in ScalarField arr)
Definition: stdderiv.h:206
AC_inv_dsx
uniform Scalar AC_inv_dsx
Definition: stdderiv.h:9
derx
Scalar derx(int3 vertexIdx, in ScalarField arr)
Definition: stdderiv.h:87
Matrix::row
Vector row[3]
Definition: modelsolver.c:59
laplace
Device Scalar laplace(in ScalarField data)
Definition: stdderiv.h:267
AC_dsy
uniform Scalar AC_dsy
Definition: stdderiv.h:7
first_derivative
Scalar first_derivative(Scalar pencil[], Scalar inv_ds)
Definition: stdderiv.h:14
deryz
Scalar deryz(int3 vertexIdx, in ScalarField arr)
Definition: stdderiv.h:174