Compadre 1.6.4
Loading...
Searching...
No Matches
GMLS_Tutorial.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Compadre: COMpatible PArticle Discretization and REmap Toolkit
4//
5// Copyright 2018 NTESS and the Compadre contributors.
6// SPDX-License-Identifier: BSD-2-Clause
7// *****************************************************************************
8// @HEADER
9#ifndef _GMLS_TUTORIAL_HPP_
10#define _GMLS_TUTORIAL_HPP_
11
12#include <Kokkos_Core.hpp>
14#include <Compadre_GMLS.hpp>
15
16KOKKOS_INLINE_FUNCTION
17double device_max(double d1, double d2) {
18 return (d1 > d2) ? d1 : d2;
19}
20
21KOKKOS_INLINE_FUNCTION
22double trueSolution(double x, double y, double z, int order, int dimension) {
23 double ans = 0;
24 for (int i=0; i<order+1; i++) {
25 for (int j=0; j<order+1; j++) {
26 for (int k=0; k<order+1; k++) {
27 if (i+j+k <= order) {
28 ans += std::pow(x,i)*std::pow(y,j)*std::pow(z,k);
29 }
30 }
31 }
32 }
33 return ans;
34}
35
36KOKKOS_INLINE_FUNCTION
37double trueLaplacian(double x, double y, double z, int order, int dimension) {
38 double ans = 0;
39 for (int i=0; i<order+1; i++) {
40 for (int j=0; j<order+1; j++) {
41 for (int k=0; k<order+1; k++) {
42 if (i+j+k <= order) {
43 ans += device_max(0,i-1)*device_max(0,i)*
44 std::pow(x,device_max(0,i-2))*std::pow(y,j)*std::pow(z,k);
45 }
46 }
47 }
48 }
49 if (dimension>1) {
50 for (int i=0; i<order+1; i++) {
51 for (int j=0; j<order+1; j++) {
52 for (int k=0; k<order+1; k++) {
53 if (i+j+k <= order) {
54 ans += device_max(0,j-1)*device_max(0,j)*
55 std::pow(x,i)*std::pow(y,device_max(0,j-2))*std::pow(z,k);
56 }
57 }
58 }
59 }
60 }
61 if (dimension>2) {
62 for (int i=0; i<order+1; i++) {
63 for (int j=0; j<order+1; j++) {
64 for (int k=0; k<order+1; k++) {
65 if (i+j+k <= order) {
66 ans += device_max(0,k-1)*device_max(0,k)*
67 std::pow(x,i)*std::pow(y,j)*std::pow(z,device_max(0,k-2));
68 }
69 }
70 }
71 }
72 }
73 return ans;
74}
75
76KOKKOS_INLINE_FUNCTION
77void trueGradient(double* ans, double x, double y, double z, int order, int dimension) {
78
79 for (int i=0; i<order+1; i++) {
80 for (int j=0; j<order+1; j++) {
81 for (int k=0; k<order+1; k++) {
82 if (i+j+k <= order) {
83 ans[0] += device_max(0,i)*
84 std::pow(x,device_max(0,i-1))*std::pow(y,j)*std::pow(z,k);
85 }
86 }
87 }
88 }
89 if (dimension>1) {
90 for (int i=0; i<order+1; i++) {
91 for (int j=0; j<order+1; j++) {
92 for (int k=0; k<order+1; k++) {
93 if (i+j+k <= order) {
94 ans[1] += device_max(0,j)*
95 std::pow(x,i)*std::pow(y,device_max(0,j-1))*std::pow(z,k);
96 }
97 }
98 }
99 }
100 }
101 if (dimension>2) {
102 for (int i=0; i<order+1; i++) {
103 for (int j=0; j<order+1; j++) {
104 for (int k=0; k<order+1; k++) {
105 if (i+j+k <= order) {
106 ans[2] += device_max(0,k)*
107 std::pow(x,i)*std::pow(y,j)*std::pow(z,device_max(0,k-1));
108 }
109 }
110 }
111 }
112 }
113}
114
115KOKKOS_INLINE_FUNCTION
116double trueDivergence(double x, double y, double z, int order, int dimension) {
117 double ans = 0;
118 for (int i=0; i<order+1; i++) {
119 for (int j=0; j<order+1; j++) {
120 for (int k=0; k<order+1; k++) {
121 if (i+j+k <= order) {
122 ans += device_max(0,i)*
123 std::pow(x,device_max(0,i-1))*std::pow(y,j)*std::pow(z,k);
124 }
125 }
126 }
127 }
128 if (dimension>1) {
129 for (int i=0; i<order+1; i++) {
130 for (int j=0; j<order+1; j++) {
131 for (int k=0; k<order+1; k++) {
132 if (i+j+k <= order) {
133 ans += device_max(0,j)*
134 std::pow(x,i)*std::pow(y,device_max(0,j-1))*std::pow(z,k);
135 }
136 }
137 }
138 }
139 }
140 if (dimension>2) {
141 for (int i=0; i<order+1; i++) {
142 for (int j=0; j<order+1; j++) {
143 for (int k=0; k<order+1; k++) {
144 if (i+j+k <= order) {
145 ans += device_max(0,k)*
146 std::pow(x,i)*std::pow(y,j)*std::pow(z,device_max(0,k-1));
147 }
148 }
149 }
150 }
151 }
152 return ans;
153}
154
155KOKKOS_INLINE_FUNCTION
156void trueHessian(double* ans, double x, double y, double z, int order, int dimension) {
157 for (int i=0; i<order+1; i++) {
158 for (int j=0; j<order+1; j++) {
159 for (int k=0; k<order+1; k++) {
160 if (i+j+k <= order) {
161 // XX
162 ans[0] += device_max(0,i)*device_max(0,i-1)*
163 std::pow(x,device_max(0,i-2))*std::pow(y,j)*std::pow(z,k);
164 if (dimension>1) {
165 // XY
166 ans[1] += device_max(0,i)*device_max(0,j)*
167 std::pow(x,device_max(0,i-1))*std::pow(y,device_max(0,j-1))*std::pow(z,k);
168 // YX = XY
169 ans[1*dimension+0] = ans[1];
170 // YY
171 ans[1*dimension+1] += device_max(0,j)*device_max(0,j-1)*
172 std::pow(x,i)*std::pow(y,device_max(0,j-2))*std::pow(z,k);
173 }
174 if (dimension>2) {
175 // XZ
176 ans[2] += device_max(0,i)*device_max(0,k)*
177 std::pow(x,device_max(0,i-1))*std::pow(y,j)*std::pow(z,device_max(0,k-1));
178 // YZ
179 ans[1*dimension+2] += device_max(0,j)*device_max(0,k)*
180 std::pow(x,i)*std::pow(y,device_max(0,j-1))*std::pow(z,device_max(0,k-1));
181 // ZX = XZ
182 ans[2*dimension+0] = ans[2];
183 // ZY = YZ
184 ans[2*dimension+1] = ans[1*dimension+2];
185 // ZZ
186 ans[2*dimension+2] += device_max(0,k)*device_max(0,k-1)*
187 std::pow(x,i)*std::pow(y,j)*std::pow(z,device_max(0,k-2));
188 }
189 }
190 }
191 }
192 }
193}
194
195KOKKOS_INLINE_FUNCTION
196double divergenceTestSamples(double x, double y, double z, int component, int dimension) {
197 // solution can be captured exactly by at least 2rd order
198 switch (component) {
199 case 0:
200 return x*x + y*y - z*z;
201 case 1:
202 return 2*x +3*y + 4*z;
203 default:
204 return -21*x*y + 3*z*x*y + 4*z;
205 }
206}
207
208KOKKOS_INLINE_FUNCTION
209double divergenceTestSolution(double x, double y, double z, int dimension) {
210 switch (dimension) {
211 case 1:
212 // returns divergence of divergenceTestSamples
213 return 2*x;
214 case 2:
215 return 2*x + 3;
216 default:
217 return 2*x + 3 + 3*x*y + 4;
218 }
219}
220
221KOKKOS_INLINE_FUNCTION
222double curlTestSolution(double x, double y, double z, int component, int dimension) {
223 if (dimension==3) {
224 // returns curl of divergenceTestSamples
225 switch (component) {
226 case 0:
227 // u3,y- u2,z
228 return (-21*x + 3*z*x) - 4;
229 case 1:
230 // -u3,x + u1,z
231 return (21*y - 3*z*y) - 2*z;
232 default:
233 // u2,x - u1,y
234 return 2 - 2*y;
235 }
236 } else if (dimension==2) {
237 switch (component) {
238 case 0:
239 // u2,y
240 return 3;
241 default:
242 // -u1,x
243 return -2*x;
244 }
245 } else {
246 return 0;
247 }
248}
249
250KOKKOS_INLINE_FUNCTION
251double divfreeTestSolution_single_polynomial(double x, double y, double z, int component, int dimension) {
252 if (dimension==3) {
253 // returns divfreeTestSamples
254 switch (component) {
255 case 0:
256 return 6.0*x*x*y - 9.0*x*y + 7.0*x*z*z + 6.0*y*y*z;
257 case 1:
258 return 10.0*x*x*z - 7.0*y*z*z - 6.0*x*y*y;
259 default:
260 return -2.0*x*x*x + 9.0*x*y*y + 9.0*y*z;
261 }
262 } else if (dimension==2) {
263 switch (component) {
264 case 0:
265 return 6.0*x*x*y;
266 default:
267 return -6.0*x*y*y;
268 }
269 } else {
270 return 0.0;
271 }
272}
273
274KOKKOS_INLINE_FUNCTION
275double divfreeTestSolution_span_basis(double x, double y, double z, int component, int dimension, int exact_order) {
276 double val = 0.0;
278 if (dimension==3) {
279 for (int i=0; i<NP; ++i) {
281 val += basis_i[component];
282 }
283 } else {
284 for (int i=0; i<NP; ++i) {
286 val += basis_i[component];
287 }
288 }
289 return val;
290}
291
292KOKKOS_INLINE_FUNCTION
293double curldivfreeTestSolution_single_polynomial(double x, double y, double z, int component, int dimension) {
294 if (dimension==3) {
295 // returns curl of divergenceTestSamples
296 switch (component) {
297 case 0:
298 return -10.0*x*x + 18.0*x*y + 14.0*y*z + 9.0*z;
299 case 1:
300 return 6.0*x*x + 14.0*x*z - 3.0*y*y;
301 default:
302 return -6.0*x*x + 20.0*x*z + 9.0*x - 6.0*y*y - 12.0*y*z;
303 }
304 } else {
305 return 0;
306 }
307}
308
309KOKKOS_INLINE_FUNCTION
310double curldivfreeTestSolution_span_basis(double x, double y, double z, int component, int dimension, int exact_order) {
311 double val = 0.0;
313 if (dimension==3) {
314 if (component==0) {
315 for (int i=0; i<NP; ++i) {
318 val += grad_y[2] - grad_z[1];
319 }
320 } else if (component==1) {
321 for (int i=0; i<NP; ++i) {
324 val += -grad_x[2] + grad_z[0];
325 }
326 } else if (component==2) {
327 for (int i=0; i<NP; ++i) {
330 val += grad_x[1] - grad_y[0];
331 }
332 }
333 return val;
334 } else if (dimension==2) {
335 if (component==0) {
336 for (int i=0; i<NP; ++i) {
339 val += grad_x[1] - grad_y[0];
340 }
341 return val;
342 } else return 0;
343 } else {
344 return 0;
345 }
346}
347
348KOKKOS_INLINE_FUNCTION
349double curlcurldivfreeTestSolution_single_polynomial(double x, double y, double z, int component, int dimension) {
350 if (dimension==3) {
351 // returns curl of divergenceTestSamples
352 switch (component) {
353 case 0:
354 return -14.0*x - 12.0*y - 12.0*z;
355 case 1:
356 return 12.0*x + 14.0*y - 20.0*z;
357 default:
358 return -6.0*x;
359 }
360 } else if (dimension==2) {
361 switch (component) {
362 case 0:
363 return -12.0*y;
364 default:
365 return 12.0*x;
366 }
367 } else {
368 return 0;
369 }
370}
371
372KOKKOS_INLINE_FUNCTION
373double gradientdivfreeTestSolution_single_polynomial(double x, double y, double z, int component, int dimension) {
374 if (dimension==3) {
375 switch (component) {
376 case 0:
377 return 12.0*x*y - 9.0*y + 7.0*z*z;
378 case 1:
379 return 6.0*x*x - 9.0*x + 12.0*y*z;
380 case 2:
381 return 14.0*x*z + 6.0*y*y;
382 case 3:
383 return 20.0*x*z - 6.0*y*y;
384 case 4:
385 return -7.0*z*z - 12.0*x*y;
386 case 5:
387 return 10.0*x*x - 14.0*y*z;
388 case 6:
389 return -6.0*x*x + 9.0*y*y;
390 case 7:
391 return 18.0*x*y + 9.0*z;
392 case 8:
393 return 9.0*y;
394 }
395 }
396 if (dimension==2) {
397 switch (component) {
398 case 0:
399 return 12.0*x*y ;
400 case 1:
401 return 6.0*x*x;
402 case 2:
403 return -6.0*y*y;
404 case 3:
405 return -12.0*x*y;
406 }
407 }
408 return 0.0;
409}
410
411KOKKOS_INLINE_FUNCTION
412double gradientdivfreeTestSolution_span_basis(double x, double y, double z, int input_component, int output_component, int dimension, int exact_order) {
413 double val = 0.0;
415 if (dimension==3) {
416 for (int i=0; i<NP; ++i) {
418 val += basis_i[input_component];
419 }
420 } else {
421 for (int i=0; i<NP; ++i) {
423 val += basis_i[input_component];
424 }
425 }
426 return val;
427}
428
429/** Standard GMLS Example
430 *
431 * Exercises GMLS operator evaluation with data over various orders and numbers of targets for targets including point evaluation, Laplacian, divergence, curl, and gradient.
432 */
433int main (int argc, char* args[]);
434
435/**
436 * \example "GMLS Tutorial" based on GMLS_Device.cpp
437 * \section ex GMLS Example with Device Views
438 *
439 * This tutorial sets up a batch of GMLS problems, solves the minimization problems, and applies the coefficients produced to data.
440 *
441 * \section ex1a Parse Command Line Arguments
442 * \snippet GMLS_Device.cpp Parse Command Line Arguments
443 *
444 * \section ex1b Setting Up The Point Cloud
445 * \snippet GMLS_Device.cpp Setting Up The Point Cloud
446 *
447 * \section ex1c Performing Neighbor Search
448 * \snippet GMLS_Device.cpp Performing Neighbor Search
449 *
450 * \section ex2 Creating The Data
451 * \snippet GMLS_Device.cpp Creating The Data
452 *
453 * \section ex3 Setting Up The GMLS Object
454 * \snippet GMLS_Device.cpp Setting Up The GMLS Object
455 *
456 * \section ex4 Apply GMLS Alphas To Data
457 * \snippet GMLS_Device.cpp Apply GMLS Alphas To Data
458 *
459 * \section ex5 Check That Solutions Are Correct
460 * \snippet GMLS_Device.cpp Check That Solutions Are Correct
461 *
462 * \section ex6 Finalize Program
463 * \snippet GMLS_Device.cpp Finalize Program
464 */
465
466#endif
KOKKOS_INLINE_FUNCTION double divergenceTestSolution(double x, double y, double z, int dimension)
KOKKOS_INLINE_FUNCTION double divfreeTestSolution_single_polynomial(double x, double y, double z, int component, int dimension)
KOKKOS_INLINE_FUNCTION double gradientdivfreeTestSolution_span_basis(double x, double y, double z, int input_component, int output_component, int dimension, int exact_order)
KOKKOS_INLINE_FUNCTION double curldivfreeTestSolution_span_basis(double x, double y, double z, int component, int dimension, int exact_order)
KOKKOS_INLINE_FUNCTION double trueSolution(double x, double y, double z, int order, int dimension)
KOKKOS_INLINE_FUNCTION void trueGradient(double *ans, double x, double y, double z, int order, int dimension)
int main(int argc, char *args[])
Standard GMLS Example.
KOKKOS_INLINE_FUNCTION double divergenceTestSamples(double x, double y, double z, int component, int dimension)
KOKKOS_INLINE_FUNCTION double curldivfreeTestSolution_single_polynomial(double x, double y, double z, int component, int dimension)
KOKKOS_INLINE_FUNCTION double curlcurldivfreeTestSolution_single_polynomial(double x, double y, double z, int component, int dimension)
KOKKOS_INLINE_FUNCTION double gradientdivfreeTestSolution_single_polynomial(double x, double y, double z, int component, int dimension)
KOKKOS_INLINE_FUNCTION double divfreeTestSolution_span_basis(double x, double y, double z, int component, int dimension, int exact_order)
KOKKOS_INLINE_FUNCTION double trueDivergence(double x, double y, double z, int order, int dimension)
KOKKOS_INLINE_FUNCTION double curlTestSolution(double x, double y, double z, int component, int dimension)
KOKKOS_INLINE_FUNCTION void trueHessian(double *ans, double x, double y, double z, int order, int dimension)
KOKKOS_INLINE_FUNCTION double device_max(double d1, double d2)
KOKKOS_INLINE_FUNCTION double trueLaplacian(double x, double y, double z, int order, int dimension)
static KOKKOS_INLINE_FUNCTION int getNP(const int m, const int dimension=3, const ReconstructionSpace r_space=ReconstructionSpace::ScalarTaylorPolynomial)
Returns size of the basis for a given polynomial order and dimension General to dimension 1....
KOKKOS_INLINE_FUNCTION void evaluate(const member_type &teamMember, double *delta, double *workspace, const int dimension, const int max_degree, const int component, const double h, const double x, const double y, const double z, const int starting_order=0, const double weight_of_original_value=0.0, const double weight_of_new_value=1.0)
Evaluates the divergence-free polynomial basis delta[j] = weight_of_original_value * delta[j] + weigh...
KOKKOS_INLINE_FUNCTION void evaluatePartialDerivative(const member_type &teamMember, double *delta, double *workspace, const int dimension, const int max_degree, const int component, const int partial_direction, const double h, const double x, const double y, const double z, const int starting_order=0, const double weight_of_original_value=0.0, const double weight_of_new_value=1.0)
Evaluates the first partial derivatives of the divergence-free polynomial basis delta[j] = weight_of_...
@ DivergenceFreeVectorTaylorPolynomial
Divergence-free vector polynomial basis.