Compadre  1.5.9
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 
16 KOKKOS_INLINE_FUNCTION
17 double device_max(double d1, double d2) {
18  return (d1 > d2) ? d1 : d2;
19 }
20 
21 KOKKOS_INLINE_FUNCTION
22 double 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 
36 KOKKOS_INLINE_FUNCTION
37 double 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 
76 KOKKOS_INLINE_FUNCTION
77 void 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 
115 KOKKOS_INLINE_FUNCTION
116 double 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 
155 KOKKOS_INLINE_FUNCTION
156 void 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 
195 KOKKOS_INLINE_FUNCTION
196 double 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 
208 KOKKOS_INLINE_FUNCTION
209 double 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 
221 KOKKOS_INLINE_FUNCTION
222 double 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 
250 KOKKOS_INLINE_FUNCTION
251 double 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 
274 KOKKOS_INLINE_FUNCTION
275 double 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 
292 KOKKOS_INLINE_FUNCTION
293 double 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 
309 KOKKOS_INLINE_FUNCTION
310 double 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 
348 KOKKOS_INLINE_FUNCTION
349 double 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 
372 KOKKOS_INLINE_FUNCTION
373 double 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 
411 KOKKOS_INLINE_FUNCTION
412 double 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) {
417  Compadre::XYZ basis_i = Compadre::DivergenceFreePolynomialBasis::evaluatePartialDerivative(i, output_component, 1.0, x, y, z);
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  */
433 int 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 divfreeTestSolution_span_basis(double x, double y, double z, int component, int dimension, int exact_order)
KOKKOS_INLINE_FUNCTION double gradientdivfreeTestSolution_single_polynomial(double x, double y, double z, int component, int dimension)
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 trueHessian(double *ans, double x, double y, double z, int order, int dimension)
KOKKOS_INLINE_FUNCTION double curldivfreeTestSolution_span_basis(double x, double y, double z, int component, int dimension, int exact_order)
int main(int argc, char **argv)
KOKKOS_INLINE_FUNCTION double curlcurldivfreeTestSolution_single_polynomial(double x, double y, double z, int component, int dimension)
KOKKOS_INLINE_FUNCTION double device_max(double d1, double d2)
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 trueGradient(double *ans, double x, double y, double z, int order, int dimension)
KOKKOS_INLINE_FUNCTION double divfreeTestSolution_single_polynomial(double x, double y, double z, int component, int dimension)
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_...
KOKKOS_INLINE_FUNCTION double divergenceTestSolution(double x, double y, double z, int dimension)
KOKKOS_INLINE_FUNCTION double trueLaplacian(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 double divergenceTestSamples(double x, double y, double z, int component, int dimension)
Divergence-free vector polynomial basis.
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_single_polynomial(double x, double y, double z, int component, int dimension)
KOKKOS_INLINE_FUNCTION double trueSolution(double x, double y, double z, int order, int dimension)
KOKKOS_INLINE_FUNCTION double trueDivergence(double x, double y, double z, int order, int dimension)