Compadre  1.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
GMLS_Staggered.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <string>
3 #include <vector>
4 #include <map>
5 #include <stdlib.h>
6 #include <cstdio>
7 #include <random>
8 
9 #include <Compadre_Config.h>
10 #include <Compadre_GMLS.hpp>
11 #include <Compadre_Evaluator.hpp>
13 
14 #include "GMLS_Tutorial.hpp"
15 
16 #ifdef COMPADRE_USE_MPI
17 #include <mpi.h>
18 #endif
19 
20 #include <Kokkos_Timer.hpp>
21 #include <Kokkos_Core.hpp>
22 
23 using namespace Compadre;
24 
25 //! [Parse Command Line Arguments]
26 
27 // called from command line
28 int main (int argc, char* args[]) {
29 
30 // initializes MPI (if available) with command line arguments given
31 #ifdef COMPADRE_USE_MPI
32 MPI_Init(&argc, &args);
33 #endif
34 
35 // initializes Kokkos with command line arguments given
36 Kokkos::initialize(argc, args);
37 
38 // becomes false if the computed solution not within the failure_threshold of the actual solution
39 bool all_passed = true;
40 
41 // code block to reduce scope for all Kokkos View allocations
42 // otherwise, Views may be deallocating when we call Kokkos::finalize() later
43 {
44  // check if 7 arguments are given from the command line, the first being the program name
45  // constraint_type used in solving each GMLS problem:
46  // 0 - No constraints used in solving each GMLS problem
47  // 1 - Neumann Gradient Scalar used in solving each GMLS problem
48  int constraint_type = 0; // No constraints by default
49  if (argc >= 7) {
50  int arg7toi = atoi(args[6]);
51  if (arg7toi > 0) {
52  constraint_type = arg7toi;
53  }
54  }
55 
56  // check if 6 arguments are given from the command line, the first being the program name
57  // problem_type used in solving each GMLS problem:
58  // 0 - Standard GMLS problem
59  // 1 - Manifold GMLS problem
60  int problem_type = 0; // Standard by default
61  if (argc >= 6) {
62  int arg6toi = atoi(args[5]);
63  if (arg6toi > 0) {
64  problem_type = arg6toi;
65  }
66  }
67 
68  // check if 5 arguments are given from the command line, the first being the program name
69  // solver_type used for factorization in solving each GMLS problem:
70  // 0 - SVD used for factorization in solving each GMLS problem
71  // 1 - QR used for factorization in solving each GMLS problem
72  // 2 - LU used for factorization in solving each GMLS problem
73  int solver_type = 1; // QR by default
74  if (argc >= 5) {
75  int arg5toi = atoi(args[4]);
76  if (arg5toi >= 0) {
77  solver_type = arg5toi;
78  }
79  }
80 
81  // check if 4 arguments are given from the command line
82  // dimension for the coordinates and the solution
83  int dimension = 3; // dimension 3 by default
84  if (argc >= 4) {
85  int arg4toi = atoi(args[3]);
86  if (arg4toi > 0) {
87  dimension = arg4toi;
88  }
89  }
90 
91  // check if 3 arguments are given from the command line
92  // set the number of target sites where we will reconstruct the target functionals at
93  int number_target_coords = 200; // 200 target sites by default
94  if (argc >= 3) {
95  int arg3toi = atoi(args[2]);
96  if (arg3toi > 0) {
97  number_target_coords = arg3toi;
98  }
99  }
100 
101  // check if 2 arguments are given from the command line
102  // set the number of target sites where we will reconstruct the target functionals at
103  int order = 3; // 3rd degree polynomial basis by default
104  if (argc >= 2) {
105  int arg2toi = atoi(args[1]);
106  if (arg2toi > 0) {
107  order = arg2toi;
108  }
109  }
110 
111  // the functions we will be seeking to reconstruct are in the span of the basis
112  // of the reconstruction space we choose for GMLS, so the error should be very small
113  const double failure_tolerance = 9e-8;
114 
115  // minimum neighbors for unisolvency is the same as the size of the polynomial basis
116  const int min_neighbors = Compadre::GMLS::getNP(order+1, dimension);
117 
118  //! [Parse Command Line Arguments]
119  Kokkos::Timer timer;
120  Kokkos::Profiling::pushRegion("Setup Point Data");
121  //! [Setting Up The Point Cloud]
122 
123  // approximate spacing of source sites
124  double h_spacing = 0.05;
125  int n_neg1_to_1 = 2*(1/h_spacing) + 1; // always odd
126 
127  // number of source coordinate sites that will fill a box of [-1,1]x[-1,1]x[-1,1] with a spacing approximately h
128  const int number_source_coords = std::pow(n_neg1_to_1, dimension);
129 
130  // coordinates of source sites
131  Kokkos::View<double**, Kokkos::DefaultExecutionSpace> source_coords_device("source coordinates",
132  number_source_coords, 3);
133  Kokkos::View<double**>::HostMirror source_coords = Kokkos::create_mirror_view(source_coords_device);
134 
135  // coordinates of target sites
136  Kokkos::View<double**, Kokkos::DefaultExecutionSpace> target_coords_device ("target coordinates", number_target_coords, 3);
137  Kokkos::View<double**>::HostMirror target_coords = Kokkos::create_mirror_view(target_coords_device);
138 
139  // tangent bundle for each target sites
140  Kokkos::View<double***, Kokkos::DefaultExecutionSpace> tangent_bundles_device ("tangent bundles", number_target_coords, 3, 3);
141  Kokkos::View<double***>::HostMirror tangent_bundles = Kokkos::create_mirror_view(tangent_bundles_device);
142 
143  // fill source coordinates with a uniform grid
144  int source_index = 0;
145  double this_coord[3] = {0,0,0};
146  for (int i=-n_neg1_to_1/2; i<n_neg1_to_1/2+1; ++i) {
147  this_coord[0] = i*h_spacing;
148  for (int j=-n_neg1_to_1/2; j<n_neg1_to_1/2+1; ++j) {
149  this_coord[1] = j*h_spacing;
150  for (int k=-n_neg1_to_1/2; k<n_neg1_to_1/2+1; ++k) {
151  this_coord[2] = k*h_spacing;
152  if (dimension==3) {
153  source_coords(source_index,0) = this_coord[0];
154  source_coords(source_index,1) = this_coord[1];
155  source_coords(source_index,2) = this_coord[2];
156  source_index++;
157  }
158  }
159  if (dimension==2) {
160  source_coords(source_index,0) = this_coord[0];
161  source_coords(source_index,1) = this_coord[1];
162  source_coords(source_index,2) = 0;
163  source_index++;
164  }
165  }
166  if (dimension==1) {
167  source_coords(source_index,0) = this_coord[0];
168  source_coords(source_index,1) = 0;
169  source_coords(source_index,2) = 0;
170  source_index++;
171  }
172  }
173 
174  // Generate target points - these are random permutation from available source points
175  // Note that this is assuming that the number of targets in this test will not exceed
176  // the number of source coords, which is 41^3 = 68921
177  // seed random number generator
178  std::mt19937 rng(50);
179  // generate random integers in [0..number_source_coords-1] (used to pick target sites)
180  std::uniform_int_distribution<int> gen_num_neighbours(0, source_index);
181  // fill target sites with random selections from source sites
182  for (int i=0; i<number_target_coords; ++i) {
183  const int source_site_to_copy = gen_num_neighbours(rng);
184  for (int j=0; j<3; j++) {
185  target_coords(i, j) = source_coords(source_site_to_copy, j);
186  }
187  if (constraint_type == 1) { // create bundles of normal vectors
188  if (dimension == 3) {
189  tangent_bundles(i, 0, 0) = 0.0;
190  tangent_bundles(i, 0, 1) = 0.0;
191  tangent_bundles(i, 0, 2) = 0.0;
192  tangent_bundles(i, 1, 0) = 0.0;
193  tangent_bundles(i, 1, 1) = 0.0;
194  tangent_bundles(i, 1, 2) = 0.0;
195  tangent_bundles(i, 2, 0) = 1.0/(sqrt(3.0));
196  tangent_bundles(i, 2, 1) = 1.0/(sqrt(3.0));
197  tangent_bundles(i, 2, 2) = 1.0/(sqrt(3.0));
198  }
199  if (dimension == 2) {
200  tangent_bundles(i, 0, 0) = 0.0;
201  tangent_bundles(i, 0, 1) = 0.0;
202  tangent_bundles(i, 1, 0) = 1.0/(sqrt(2.0));
203  tangent_bundles(i, 1, 1) = 1.0/(sqrt(2.0));
204  }
205  }
206  }
207 
208  //! [Setting Up The Point Cloud]
209 
210  Kokkos::Profiling::popRegion();
211  Kokkos::Profiling::pushRegion("Creating Data");
212 
213  //! [Creating The Data]
214 
215 
216  // source coordinates need copied to device before using to construct sampling data
217  Kokkos::deep_copy(source_coords_device, source_coords);
218 
219  // target coordinates copied next, because it is a convenient time to send them to device
220  Kokkos::deep_copy(target_coords_device, target_coords);
221 
222  // need Kokkos View storing true solution
223  Kokkos::View<double*, Kokkos::DefaultExecutionSpace> sampling_data_device("samples of true solution",
224  source_coords_device.extent(0));
225 
226  Kokkos::parallel_for("Sampling Manufactured Solutions", Kokkos::RangePolicy<Kokkos::DefaultExecutionSpace>
227  (0,source_coords.extent(0)), KOKKOS_LAMBDA(const int i) {
228  // coordinates of source site i
229  double xval = source_coords_device(i,0);
230  double yval = (dimension>1) ? source_coords_device(i,1) : 0;
231  double zval = (dimension>2) ? source_coords_device(i,2) : 0;
232 
233  // data for targets with scalar input
234  sampling_data_device(i) = trueSolution(xval, yval, zval, order, dimension);
235  });
236 
237 
238  //! [Creating The Data]
239 
240  Kokkos::Profiling::popRegion();
241  Kokkos::Profiling::pushRegion("Neighbor Search");
242 
243  //! [Performing Neighbor Search]
244 
245 
246  // Point cloud construction for neighbor search
247  // CreatePointCloudSearch constructs an object of type PointCloudSearch, but deduces the templates for you
248  auto point_cloud_search(CreatePointCloudSearch(source_coords, dimension));
249 
250  // each row is a neighbor list for a target site, with the first column of each row containing
251  // the number of neighbors for that rows corresponding target site
252  // for the default values in this test, the multiplier is suggested to be 2.2
253  double epsilon_multiplier = 2.2;
254  int estimated_upper_bound_number_neighbors =
255  point_cloud_search.getEstimatedNumberNeighborsUpperBound(min_neighbors, dimension, epsilon_multiplier);
256 
257  Kokkos::View<int**, Kokkos::DefaultExecutionSpace> neighbor_lists_device("neighbor lists",
258  number_target_coords, estimated_upper_bound_number_neighbors); // first column is # of neighbors
259  Kokkos::View<int**>::HostMirror neighbor_lists = Kokkos::create_mirror_view(neighbor_lists_device);
260 
261  // each target site has a window size
262  Kokkos::View<double*, Kokkos::DefaultExecutionSpace> epsilon_device("h supports", number_target_coords);
263  Kokkos::View<double*>::HostMirror epsilon = Kokkos::create_mirror_view(epsilon_device);
264 
265  // query the point cloud to generate the neighbor lists using a kdtree to produce the n nearest neighbor
266  // to each target site, adding (epsilon_multiplier-1)*100% to whatever the distance away the further neighbor used is from
267  // each target to the view for epsilon
268  point_cloud_search.generate2DNeighborListsFromKNNSearch(false /*not dry run*/, target_coords, neighbor_lists,
269  epsilon, min_neighbors, epsilon_multiplier);
270 
271  //! [Performing Neighbor Search]
272 
273  Kokkos::Profiling::popRegion();
274  Kokkos::fence(); // let call to build neighbor lists complete before copying back to device
275  timer.reset();
276 
277  //! [Setting Up The GMLS Object]
278 
279 
280  // Copy data back to device (they were filled on the host)
281  // We could have filled Kokkos Views with memory space on the host
282  // and used these instead, and then the copying of data to the device
283  // would be performed in the GMLS class
284  Kokkos::deep_copy(neighbor_lists_device, neighbor_lists);
285  Kokkos::deep_copy(epsilon_device, epsilon);
286 
287  // solver name for passing into the GMLS class
288  std::string solver_name;
289  if (solver_type == 0) { // SVD
290  solver_name = "SVD";
291  } else if (solver_type == 1) { // QR
292  solver_name = "QR";
293  } else if (solver_type == 2) { // LU
294  solver_name = "LU";
295  }
296 
297  // problem name for passing into the GMLS class
298  std::string problem_name;
299  if (problem_type == 0) { // Standard
300  problem_name = "STANDARD";
301  } else if (problem_type == 1) { // Manifold
302  problem_name = "MANIFOLD";
303  }
304 
305  // boundary name for passing into the GMLS class
306  std::string constraint_name;
307  if (constraint_type == 0) { // No constraints
308  constraint_name = "NO_CONSTRAINT";
309  } else if (constraint_type == 1) { // Neumann Gradient Scalar
310  constraint_name = "NEUMANN_GRAD_SCALAR";
311  }
312 
313  // initialize an instance of the GMLS class
314  // NULL in manifold order indicates non-manifold case
315  // First, analytica gradient on scalar polynomial basis
316  GMLS scalar_basis_gmls(ScalarTaylorPolynomial,
318  order, dimension,
319  solver_name.c_str(), problem_name.c_str(), constraint_name.c_str(),
320  0 /*manifold order*/);
321 
322  // Another class performing Gaussian quadrature integration on vector polynomial basis
323  GMLS vector_basis_gmls(VectorTaylorPolynomial,
326  order, dimension,
327  solver_name.c_str(), problem_name.c_str(), constraint_name.c_str(),
328  0 /*manifold order*/);
329 
330  // pass in neighbor lists, source coordinates, target coordinates, and window sizes
331  //
332  // neighbor lists have the format:
333  // dimensions: (# number of target sites) X (# maximum number of neighbors for any given target + 1)
334  // the first column contains the number of neighbors for that rows corresponding target index
335  //
336  // source coordinates have the format:
337  // dimensions: (# number of source sites) X (dimension)
338  // entries in the neighbor lists (integers) correspond to rows of this 2D array
339  //
340  // target coordinates have the format:
341  // dimensions: (# number of target sites) X (dimension)
342  // # of target sites is same as # of rows of neighbor lists
343  //
344  scalar_basis_gmls.setProblemData(neighbor_lists_device, source_coords_device, target_coords_device, epsilon_device);
345  vector_basis_gmls.setProblemData(neighbor_lists_device, source_coords_device, target_coords_device, epsilon_device);
346  if (constraint_name == "NEUMANN_GRAD_SCALAR") {
347  scalar_basis_gmls.setTangentBundle(tangent_bundles_device);
348  vector_basis_gmls.setTangentBundle(tangent_bundles_device);
349  }
350 
351  // create a vector of target operations
352  std::vector<TargetOperation> lro(2);
355 
356  // and then pass them to the GMLS class
357  scalar_basis_gmls.addTargets(lro);
358  vector_basis_gmls.addTargets(lro);
359 
360  // sets the weighting kernel function from WeightingFunctionType
361  scalar_basis_gmls.setWeightingType(WeightingFunctionType::Power);
362  vector_basis_gmls.setWeightingType(WeightingFunctionType::Power);
363 
364  // power to use in that weighting kernel function
365  scalar_basis_gmls.setWeightingPower(2);
366  vector_basis_gmls.setWeightingPower(2);
367 
368  // setup quadrature for StaggeredEdgeIntegralSample
369  vector_basis_gmls.setOrderOfQuadraturePoints(order);
370  vector_basis_gmls.setDimensionOfQuadraturePoints(1);
371  vector_basis_gmls.setQuadratureType("LINE");
372 
373  // generate the alphas that to be combined with data for each target operation requested in lro
374  scalar_basis_gmls.generateAlphas();
375  vector_basis_gmls.generateAlphas();
376 
377  //! [Setting Up The GMLS Object]
378 
379  double instantiation_time = timer.seconds();
380  std::cout << "Took " << instantiation_time << "s to complete alphas generation." << std::endl;
381  Kokkos::fence(); // let generateAlphas finish up before using alphas
382  Kokkos::Profiling::pushRegion("Apply Alphas to Data");
383 
384  //! [Apply GMLS Alphas To Data]
385 
386  // it is important to note that if you expect to use the data as a 1D view, then you should use double*
387  // however, if you know that the target operation will result in a 2D view (vector or matrix output),
388  // then you should template with double** as this is something that can not be infered from the input data
389  // or the target operator at compile time. Additionally, a template argument is required indicating either
390  // Kokkos::HostSpace or Kokkos::DefaultExecutionSpace::memory_space()
391 
392  // The Evaluator class takes care of handling input data views as well as the output data views.
393  // It uses information from the GMLS class to determine how many components are in the input
394  // as well as output for any choice of target functionals and then performs the contactions
395  // on the data using the alpha coefficients generated by the GMLS class, all on the device.
396  Evaluator gmls_evaluator_scalar(&scalar_basis_gmls);
397  Evaluator gmls_evaluator_vector(&vector_basis_gmls);
398 
399  auto output_divergence_scalar = gmls_evaluator_scalar.applyAlphasToDataAllComponentsAllTargetSites<double*, Kokkos::HostSpace>
401 
402  auto output_divergence_vector = gmls_evaluator_vector.applyAlphasToDataAllComponentsAllTargetSites<double*, Kokkos::HostSpace>
404 
405  // evaluating the gradient
406  auto output_gradient_scalar = gmls_evaluator_scalar.applyAlphasToDataAllComponentsAllTargetSites<double**, Kokkos::HostSpace>
408 
409  auto output_gradient_vector = gmls_evaluator_vector.applyAlphasToDataAllComponentsAllTargetSites<double**, Kokkos::HostSpace>
411 
412  //! [Apply GMLS Alphas To Data]
413 
414  Kokkos::fence(); // let application of alphas to data finish before using results
415  Kokkos::Profiling::popRegion();
416  // times the Comparison in Kokkos
417  Kokkos::Profiling::pushRegion("Comparison");
418 
419  //! [Check That Solutions Are Correct]
420 
421  // loop through the target sites
422  for (int i=0; i<number_target_coords; i++) {
423 
424  // target site i's coordinate
425  double xval = target_coords(i,0);
426  double yval = (dimension>1) ? target_coords(i,1) : 0;
427  double zval = (dimension>2) ? target_coords(i,2) : 0;
428 
429  // evaluation of various exact solutions
430  double actual_Divergence;
431  actual_Divergence = trueLaplacian(xval, yval, zval, order, dimension);
432  double actual_Gradient[3] = {0,0,0}; // initialized for 3, but only filled up to dimension
433  trueGradient(actual_Gradient, xval, yval, zval, order, dimension);
434 
435  // calculate correction factor
436  double g = (dimension == 3) ? (1.0/sqrt(3.0))*(actual_Gradient[0] + actual_Gradient[1] + actual_Gradient[2])
437  : (1.0/sqrt(2.0))*(actual_Gradient[0] + actual_Gradient[1]);
438  // obtain number of neighbor for each target
439  // in order to exploit the index where the value for the Lagrange multiplier is stored
440  int num_neigh_i = neighbor_lists(i, 0);
441 
442  // load divergence from output
443  double GMLS_Divergence_Scalar = output_divergence_scalar(i);
444  double GMLS_Divergence_Vector = output_divergence_vector(i);
445 
446  // obtain adjusted value for divergence
447  if (constraint_name == "NEUMANN_GRAD_SCALAR") {
448  double b_i_scalar = scalar_basis_gmls.getAlpha0TensorTo0Tensor(DivergenceOfVectorPointEvaluation, i, num_neigh_i);
449  GMLS_Divergence_Scalar = GMLS_Divergence_Scalar + b_i_scalar*g;
450 
451  double b_i_vector = vector_basis_gmls.getAlpha0TensorTo0Tensor(DivergenceOfVectorPointEvaluation, i, num_neigh_i);
452  GMLS_Divergence_Vector = GMLS_Divergence_Vector + b_i_vector*g;
453  }
454 
455  // check divergence - scalar basis
456  if(std::abs(actual_Divergence - GMLS_Divergence_Scalar) > failure_tolerance) {
457  all_passed = false;
458  std::cout << i << " Failed Divergence on SCALAR basis by: " << std::abs(actual_Divergence - GMLS_Divergence_Scalar) << std::endl;
459  std::cout << i << " GMLS " << GMLS_Divergence_Scalar << " adjusted " << GMLS_Divergence_Scalar << " actual " << actual_Divergence << std::endl;
460  }
461 
462  // check divergence - vector basis
463  if(std::abs(actual_Divergence - GMLS_Divergence_Vector) > failure_tolerance) {
464  all_passed = false;
465  std::cout << i << " Failed Divergence on VECTOR basis by: " << std::abs(actual_Divergence - GMLS_Divergence_Vector) << std::endl;
466  std::cout << i << " GMLS " << GMLS_Divergence_Vector << " adjusted " << GMLS_Divergence_Vector << " actual " << actual_Divergence << std::endl;
467  }
468 
469  // load gradient from output
470  double Scalar_GMLS_GradX = (dimension>1) ? output_gradient_scalar(i,0) : 0;
471  double Scalar_GMLS_GradY = (dimension>1) ? output_gradient_scalar(i,1) : 0;
472  double Scalar_GMLS_GradZ = (dimension>2) ? output_gradient_scalar(i,2) : 0;
473 
474  double Vector_GMLS_GradX = (dimension>1) ? output_gradient_vector(i,0) : 0;
475  double Vector_GMLS_GradY = (dimension>1) ? output_gradient_vector(i,1) : 0;
476  double Vector_GMLS_GradZ = (dimension>2) ? output_gradient_vector(i,2) : 0;
477 
478  // Obtain adjusted value
479  if (constraint_name == "NEUMANN_GRAD_SCALAR") {
480  double bx_i_scalar = scalar_basis_gmls.getAlpha0TensorTo1Tensor(GradientOfScalarPointEvaluation, i, 0, num_neigh_i);
481  double by_i_scalar = scalar_basis_gmls.getAlpha0TensorTo1Tensor(GradientOfScalarPointEvaluation, i, 1, num_neigh_i);
482  double bz_i_scalar = scalar_basis_gmls.getAlpha0TensorTo1Tensor(GradientOfScalarPointEvaluation, i, 2, num_neigh_i);
483  Scalar_GMLS_GradX = Scalar_GMLS_GradX + bx_i_scalar*g;
484  Scalar_GMLS_GradY = Scalar_GMLS_GradY + by_i_scalar*g;
485  Scalar_GMLS_GradZ = Scalar_GMLS_GradZ + bz_i_scalar*g;
486 
487  double bx_i_vector = vector_basis_gmls.getAlpha0TensorTo1Tensor(GradientOfScalarPointEvaluation, i, 0, num_neigh_i);
488  double by_i_vector = vector_basis_gmls.getAlpha0TensorTo1Tensor(GradientOfScalarPointEvaluation, i, 1, num_neigh_i);
489  double bz_i_vector = vector_basis_gmls.getAlpha0TensorTo1Tensor(GradientOfScalarPointEvaluation, i, 2, num_neigh_i);
490  Vector_GMLS_GradX = Vector_GMLS_GradX + bx_i_vector*g;
491  Vector_GMLS_GradY = Vector_GMLS_GradY + by_i_vector*g;
492  Vector_GMLS_GradZ = Vector_GMLS_GradZ + bz_i_vector*g;
493  }
494 
495  // check gradient - scalar gmls
496  if(std::abs(actual_Gradient[0] - Scalar_GMLS_GradX) > failure_tolerance) {
497  all_passed = false;
498  std::cout << i << " Failed Scalar GradX by: " << std::abs(actual_Gradient[0] - Scalar_GMLS_GradX) << std::endl;
499  if (dimension>1) {
500  if(std::abs(actual_Gradient[1] - Scalar_GMLS_GradY) > failure_tolerance) {
501  all_passed = false;
502  std::cout << i << " Failed Scalar GradY by: " << std::abs(actual_Gradient[1] - Scalar_GMLS_GradY) << std::endl;
503  }
504  }
505  if (dimension>2) {
506  if(std::abs(actual_Gradient[2] - Scalar_GMLS_GradZ) > failure_tolerance) {
507  all_passed = false;
508  std::cout << i << " Failed Scalar GradZ by: " << std::abs(actual_Gradient[2] - Scalar_GMLS_GradZ) << std::endl;
509  }
510  }
511  }
512 
513  // check gradient - vector gmls
514  if(std::abs(actual_Gradient[0] - Vector_GMLS_GradX) > failure_tolerance) {
515  all_passed = false;
516  std::cout << i << " Failed Vector GradX by: " << std::abs(actual_Gradient[0] - Vector_GMLS_GradX) << std::endl;
517  if (dimension>1) {
518  if(std::abs(actual_Gradient[1] - Vector_GMLS_GradY) > failure_tolerance) {
519  all_passed = false;
520  std::cout << i << " Failed Vector GradY by: " << std::abs(actual_Gradient[1] - Vector_GMLS_GradY) << std::endl;
521  }
522  }
523  if (dimension>2) {
524  if(std::abs(actual_Gradient[2] - Vector_GMLS_GradZ) > failure_tolerance) {
525  all_passed = false;
526  std::cout << i << " Failed Vector GradZ by: " << std::abs(actual_Gradient[2] - Vector_GMLS_GradZ) << std::endl;
527  }
528  }
529  }
530  }
531 
532 
533  //! [Check That Solutions Are Correct]
534  // popRegion hidden from tutorial
535  // stop timing comparison loop
536  Kokkos::Profiling::popRegion();
537  //! [Finalize Program]
538 
539 } // end of code block to reduce scope, causing Kokkos View de-allocations
540 // otherwise, Views may be deallocating when we call Kokkos::finalize() later
541 
542 // finalize Kokkos and MPI (if available)
543 Kokkos::finalize();
544 #ifdef COMPADRE_USE_MPI
545 MPI_Finalize();
546 #endif
547 
548 // output to user that test passed or failed
549 if(all_passed) {
550  fprintf(stdout, "Passed test \n");
551  return 0;
552 } else {
553  fprintf(stdout, "Failed test \n");
554  return -1;
555 }
556 
557 } // main
558 
559 
560 //! [Finalize Program]
Lightweight Evaluator Helper This class is a lightweight wrapper for extracting and applying all rele...
PointCloudSearch< view_type > CreatePointCloudSearch(view_type src_view, const local_index_type dimensions=-1, const local_index_type max_leaf=-1)
CreatePointCloudSearch allows for the construction of an object of type PointCloudSearch with templat...
constexpr SamplingFunctional StaggeredEdgeAnalyticGradientIntegralSample
Analytical integral of a gradient source vector is just a difference of the scalar source at neighbor...
Scalar polynomial basis centered at the target site and scaled by sum of basis powers e...
int main(int argc, char *args[])
[Parse Command Line Arguments]
Definition: GMLS_Device.cpp:29
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)
constexpr SamplingFunctional StaggeredEdgeIntegralSample
Samples consist of the result of integrals of a vector dotted with the tangent along edges between ne...
Point evaluation of the divergence of a vector (results in a scalar)
Point evaluation of the gradient of a scalar.
KOKKOS_INLINE_FUNCTION double trueLaplacian(double x, double y, double z, int order, int dimension)
Generalized Moving Least Squares (GMLS)
Kokkos::View< output_data_type, output_array_layout, output_memory_space > applyAlphasToDataAllComponentsAllTargetSites(view_type_input_data sampling_data, TargetOperation lro, const SamplingFunctional sro_in=PointSample, bool scalar_as_vector_if_needed=true, const int evaluation_site_local_index=0) const
Transformation of data under GMLS.
void setProblemData(view_type_1 neighbor_lists, view_type_2 source_coordinates, view_type_3 target_coordinates, view_type_4 epsilons)
Sets basic problem data (neighbor lists, source coordinates, and target coordinates) ...
KOKKOS_INLINE_FUNCTION double trueSolution(double x, double y, double z, int order, int dimension)
Vector polynomial basis having # of components _dimensions, or (_dimensions-1) in the case of manifol...