Compadre  1.5.9
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GMLS_DivergenceFree.cpp
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 #include <iostream>
10 #include <string>
11 #include <vector>
12 #include <map>
13 #include <stdlib.h>
14 #include <cstdio>
15 #include <random>
16 
17 #include <Compadre_Config.h>
18 #include <Compadre_GMLS.hpp>
19 #include <Compadre_Evaluator.hpp>
21 
22 #include "GMLS_Tutorial.hpp"
23 #include "CommandLineProcessor.hpp"
24 
25 #ifdef COMPADRE_USE_MPI
26 #include <mpi.h>
27 #endif
28 
29 #include <Kokkos_Timer.hpp>
30 #include <Kokkos_Core.hpp>
31 
32 using namespace Compadre;
33 
34 //! [Parse Command Line Arguments]
35 
36 // called from command line
37 int main (int argc, char* args[]) {
38 
39 // initializes MPI (if available) with command line arguments given
40 #ifdef COMPADRE_USE_MPI
41 MPI_Init(&argc, &args);
42 #endif
43 
44 // initializes Kokkos with command line arguments given
45 Kokkos::initialize(argc, args);
46 
47 // becomes false if the computed solution not within the failure_threshold of the actual solution
48 bool all_passed = true;
49 
50 // code block to reduce scope for all Kokkos View allocations
51 // otherwise, Views may be deallocating when we call Kokkos::finalize() later
52 {
53 
54  CommandLineProcessor clp(argc, args);
55  auto order = clp.order;
56  auto dimension = clp.dimension;
57  auto number_target_coords = clp.number_target_coords;
58  auto constraint_name = clp.constraint_name;
59  auto solver_name = clp.solver_name;
60  auto problem_name = clp.problem_name;
61 
62  // the functions we will be seeking to reconstruct are in the span of the basis
63  // of the reconstruction space we choose for GMLS, so the error should be very small
64  const double failure_tolerance = 1e-9;
65 
66  // minimum neighbors for unisolvency is the same as the size of the polynomial basis
67  const int min_neighbors = Compadre::GMLS::getNP(order, dimension, DivergenceFreeVectorTaylorPolynomial);
68 
69  //! [Parse Command Line Arguments]
70  Kokkos::Timer timer;
71  Kokkos::Profiling::pushRegion("Setup Point Data");
72  //! [Setting Up The Point Cloud]
73 
74  // approximate spacing of source sites
75  double h_spacing = 0.05;
76  int n_neg1_to_1 = 2*(1/h_spacing) + 1; // always odd
77 
78  // number of source coordinate sites that will fill a box of [-1,1]x[-1,1]x[-1,1] with a spacing approximately h
79  const int number_source_coords = std::pow(n_neg1_to_1, dimension);
80 
81  // coordinates of source sites
82  Kokkos::View<double**, Kokkos::DefaultExecutionSpace> source_coords_device("source coordinates",
83  number_source_coords, 3);
84  Kokkos::View<double**>::HostMirror source_coords = Kokkos::create_mirror_view(source_coords_device);
85 
86  // coordinates of target sites
87  Kokkos::View<double**, Kokkos::DefaultExecutionSpace> target_coords_device ("target coordinates", number_target_coords, 3);
88  Kokkos::View<double**>::HostMirror target_coords = Kokkos::create_mirror_view(target_coords_device);
89 
90 
91  // fill source coordinates with a uniform grid
92  int source_index = 0;
93  double this_coord[3] = {0,0,0};
94  for (int i=-n_neg1_to_1/2; i<n_neg1_to_1/2+1; ++i) {
95  this_coord[0] = i*h_spacing;
96  for (int j=-n_neg1_to_1/2; j<n_neg1_to_1/2+1; ++j) {
97  this_coord[1] = j*h_spacing;
98  for (int k=-n_neg1_to_1/2; k<n_neg1_to_1/2+1; ++k) {
99  this_coord[2] = k*h_spacing;
100  if (dimension==3) {
101  source_coords(source_index,0) = this_coord[0];
102  source_coords(source_index,1) = this_coord[1];
103  source_coords(source_index,2) = this_coord[2];
104  source_index++;
105  }
106  }
107  if (dimension==2) {
108  source_coords(source_index,0) = this_coord[0];
109  source_coords(source_index,1) = this_coord[1];
110  source_coords(source_index,2) = 0;
111  source_index++;
112  }
113  }
114  if (dimension==1) {
115  source_coords(source_index,0) = this_coord[0];
116  source_coords(source_index,1) = 0;
117  source_coords(source_index,2) = 0;
118  source_index++;
119  }
120  }
121 
122  // Generate target points - these are random permutation from available source points
123  // Note that this is assuming that the number of targets in this test will not exceed
124  // the number of source coords, which is 41^3 = 68921
125  // seed random number generator
126  std::mt19937 rng(50);
127  // generate random integers in [0..number_source_coords-1] (used to pick target sites)
128  std::uniform_int_distribution<int> gen_num_neighbours(0, source_index);
129  // fill target sites with random selections from source sites
130  for (int i=0; i<number_target_coords; ++i) {
131  const int source_site_to_copy = gen_num_neighbours(rng);
132  for (int j=0; j<3; j++) {
133  target_coords(i, j) = source_coords(source_site_to_copy, j);
134  }
135  }
136 
137  //! [Setting Up The Point Cloud]
138 
139  Kokkos::Profiling::popRegion();
140  Kokkos::Profiling::pushRegion("Creating Data");
141 
142  //! [Creating The Data]
143 
144 
145  // source coordinates need copied to device before using to construct sampling data
146  Kokkos::deep_copy(source_coords_device, source_coords);
147 
148  // target coordinates copied next, because it is a convenient time to send them to device
149  Kokkos::deep_copy(target_coords_device, target_coords);
150 
151  // need Kokkos View storing true solution
152  Kokkos::View<double**, Kokkos::DefaultExecutionSpace> vector_sampling_span_basis_data_device("samples of true vector solution",
153  source_coords_device.extent(0), dimension);
154  Kokkos::View<double**, Kokkos::DefaultExecutionSpace> vector_sampling_single_polynomial_data_device("samples of true vector solution",
155  source_coords_device.extent(0), dimension);
156 
157  Kokkos::parallel_for("Sampling Manufactured Solutions", Kokkos::RangePolicy<Kokkos::DefaultExecutionSpace>
158  (0,source_coords.extent(0)), KOKKOS_LAMBDA(const int i) {
159  // coordinates of source site i
160  double xval = source_coords_device(i,0);
161  double yval = (dimension>1) ? source_coords_device(i,1) : 0;
162  double zval = (dimension>2) ? source_coords_device(i,2) : 0;
163 
164  // data for targets with vector input
165  for (int j=0; j<dimension; ++j) {
166  vector_sampling_span_basis_data_device(i, j) = divfreeTestSolution_span_basis(xval, yval, zval, j, dimension, order);
167  vector_sampling_single_polynomial_data_device(i, j) = divfreeTestSolution_single_polynomial(xval, yval, zval, j, dimension);
168  }
169  });
170 
171 
172  //! [Creating The Data]
173 
174  Kokkos::Profiling::popRegion();
175  Kokkos::Profiling::pushRegion("Neighbor Search");
176 
177  //! [Performing Neighbor Search]
178 
179 
180  // Point cloud construction for neighbor search
181  // CreatePointCloudSearch constructs an object of type PointCloudSearch, but deduces the templates for you
182  auto point_cloud_search(CreatePointCloudSearch(source_coords, dimension));
183 
184  // each row is a neighbor list for a target site, with the first column of each row containing
185  // the number of neighbors for that rows corresponding target site
186  // for the default values in this test, the multiplier is suggested to be 2.2
187  double epsilon_multiplier = 2.2;
188  int estimated_upper_bound_number_neighbors =
189  point_cloud_search.getEstimatedNumberNeighborsUpperBound(min_neighbors, dimension, epsilon_multiplier);
190 
191  Kokkos::View<int**, Kokkos::DefaultExecutionSpace> neighbor_lists_device("neighbor lists",
192  number_target_coords, estimated_upper_bound_number_neighbors); // first column is # of neighbors
193  Kokkos::View<int**>::HostMirror neighbor_lists = Kokkos::create_mirror_view(neighbor_lists_device);
194 
195  // each target site has a window size
196  Kokkos::View<double*, Kokkos::DefaultExecutionSpace> epsilon_device("h supports", number_target_coords);
197  Kokkos::View<double*>::HostMirror epsilon = Kokkos::create_mirror_view(epsilon_device);
198 
199  // query the point cloud to generate the neighbor lists using a kdtree to produce the n nearest neighbor
200  // to each target site, adding (epsilon_multiplier-1)*100% to whatever the distance away the further neighbor used is from
201  // each target to the view for epsilon
202  point_cloud_search.generate2DNeighborListsFromKNNSearch(false /*not dry run*/, target_coords, neighbor_lists,
203  epsilon, min_neighbors, epsilon_multiplier);
204 
205  //! [Performing Neighbor Search]
206 
207  Kokkos::Profiling::popRegion();
208  Kokkos::fence(); // let call to build neighbor lists complete before copying back to device
209  timer.reset();
210 
211  //! [Setting Up The GMLS Object]
212 
213 
214  // Copy data back to device (they were filled on the host)
215  // We could have filled Kokkos Views with memory space on the host
216  // and used these instead, and then the copying of data to the device
217  // would be performed in the GMLS class
218  Kokkos::deep_copy(neighbor_lists_device, neighbor_lists);
219  Kokkos::deep_copy(epsilon_device, epsilon);
220 
221  // initialize an instance of the GMLS class
222  // NULL in manifold order indicates non-manifold case
223  // Vector basis to perform GMLS on divergence free basis
224  GMLS vector_divfree_basis_gmls(DivergenceFreeVectorTaylorPolynomial,
226  order, dimension,
227  solver_name.c_str(), problem_name.c_str(), constraint_name.c_str(),
228  0 /*manifold order*/);
229 
230  // pass in neighbor lists, source coordinates, target coordinates, and window sizes
231  //
232  // neighbor lists have the format:
233  // dimensions: (# number of target sites) X (# maximum number of neighbors for any given target + 1)
234  // the first column contains the number of neighbors for that rows corresponding target index
235  //
236  // source coordinates have the format:
237  // dimensions: (# number of source sites) X (dimension)
238  // entries in the neighbor lists (integers) correspond to rows of this 2D array
239  //
240  // target coordinates have the format:
241  // dimensions: (# number of target sites) X (dimension)
242  // # of target sites is same as # of rows of neighbor lists
243  //
244  vector_divfree_basis_gmls.setProblemData(neighbor_lists_device, source_coords_device, target_coords_device, epsilon_device);
245 
246  // create a vector of target operations
247  std::vector<TargetOperation> lro(4);
248  lro[0] = VectorPointEvaluation;
252 
253  // and then pass them to the GMLS class
254  vector_divfree_basis_gmls.addTargets(lro);
255 
256  // sets the weighting kernel function from WeightingFunctionType
257  vector_divfree_basis_gmls.setWeightingType(WeightingFunctionType::Power);
258 
259  // power to use in that weighting kernel function
260  vector_divfree_basis_gmls.setWeightingParameter(2);
261 
262  // generate the alphas that to be combined with data for each target operation requested in lro
263  vector_divfree_basis_gmls.generateAlphas(15 /* # batches */);
264 
265  //! [Setting Up The GMLS Object]
266 
267  double instantiation_time = timer.seconds();
268  std::cout << "Took " << instantiation_time << "s to complete alphas generation." << std::endl;
269  Kokkos::fence(); // let generateAlphas finish up before using alphas
270  Kokkos::Profiling::pushRegion("Apply Alphas to Data");
271 
272  //! [Apply GMLS Alphas To Data]
273 
274  // it is important to note that if you expect to use the data as a 1D view, then you should use double*
275  // however, if you know that the target operation will result in a 2D view (vector or matrix output),
276  // then you should template with double** as this is something that can not be infered from the input data
277  // or the target operator at compile time. Additionally, a template argument is required indicating either
278  // Kokkos::HostSpace or Kokkos::DefaultExecutionSpace::memory_space()
279 
280  // The Evaluator class takes care of handling input data views as well as the output data views.
281  // It uses information from the GMLS class to determine how many components are in the input
282  // as well as output for any choice of target functionals and then performs the contactions
283  // on the data using the alpha coefficients generated by the GMLS class, all on the device.
284  Evaluator gmls_evaluator_vector(&vector_divfree_basis_gmls);
285 
286  auto output_vector_evaluation = gmls_evaluator_vector.applyAlphasToDataAllComponentsAllTargetSites<double**, Kokkos::HostSpace>
287  (vector_sampling_span_basis_data_device, VectorPointEvaluation, VectorPointSample);
288  auto output_curl_vector_evaluation = gmls_evaluator_vector.applyAlphasToDataAllComponentsAllTargetSites<double**, Kokkos::HostSpace>
289  (vector_sampling_span_basis_data_device, CurlOfVectorPointEvaluation, VectorPointSample);
290  auto output_curlcurl_vector_evaluation = gmls_evaluator_vector.applyAlphasToDataAllComponentsAllTargetSites<double**, Kokkos::HostSpace>
291  (vector_sampling_single_polynomial_data_device, CurlCurlOfVectorPointEvaluation, VectorPointSample);
292  auto output_gradient_vector_evaluation = gmls_evaluator_vector.applyAlphasToDataAllComponentsAllTargetSites<double**, Kokkos::HostSpace>
293  (vector_sampling_span_basis_data_device, GradientOfVectorPointEvaluation, VectorPointSample);
294 
295  //! [Apply GMLS Alphas To Data]
296 
297  Kokkos::fence(); // let application of alphas to data finish before using results
298  Kokkos::Profiling::popRegion();
299  // times the Comparison in Kokkos
300  Kokkos::Profiling::pushRegion("Comparison");
301 
302  //! [Check That Solutions Are Correct]
303 
304  // loop through the target sites
305  for (int i=0; i<number_target_coords; i++) {
306  // load vector components from output
307  double GMLS_DivFree_VectorX = output_vector_evaluation(i, 0);
308  double GMLS_DivFree_VectorY = (dimension>1) ? output_vector_evaluation(i, 1) : 0;
309  double GMLS_DivFree_VectorZ = (dimension>2) ? output_vector_evaluation(i, 2) : 0;
310 
311  // load curl of vector components from output
312  double GMLS_Curl_DivFree_VectorX = output_curl_vector_evaluation(i, 0);
313  double GMLS_Curl_DivFree_VectorY = (dimension>2) ? output_curl_vector_evaluation(i, 1) : 0;
314  double GMLS_Curl_DivFree_VectorZ = (dimension>2) ? output_curl_vector_evaluation(i, 2) : 0;
315 
316  // load curl curl of vector components from output
317  double GMLS_CurlCurl_DivFree_VectorX = output_curlcurl_vector_evaluation(i, 0);
318  double GMLS_CurlCurl_DivFree_VectorY = (dimension>1) ? output_curlcurl_vector_evaluation(i, 1) : 0;
319  double GMLS_CurlCurl_DivFree_VectorZ = (dimension>2) ? output_curlcurl_vector_evaluation(i, 2) : 0;
320 
321  // load gradient of vector components from output
322  double GMLS_Gradient_DivFree_VectorXX = output_gradient_vector_evaluation(i, 0);
323  double GMLS_Gradient_DivFree_VectorXY = output_gradient_vector_evaluation(i, 1);
324  double GMLS_Gradient_DivFree_VectorXZ = (dimension==3) ? output_gradient_vector_evaluation(i, 2) : 0.0;
325  double GMLS_Gradient_DivFree_VectorYX = (dimension==3) ? output_gradient_vector_evaluation(i, 3) : output_gradient_vector_evaluation(i, 2);
326  double GMLS_Gradient_DivFree_VectorYY = (dimension==3) ? output_gradient_vector_evaluation(i, 4) : output_gradient_vector_evaluation(i, 3);
327  double GMLS_Gradient_DivFree_VectorYZ = (dimension==3) ? output_gradient_vector_evaluation(i, 5) : 0.0;
328  double GMLS_Gradient_DivFree_VectorZX = (dimension==3) ? output_gradient_vector_evaluation(i, 6) : 0.0;
329  double GMLS_Gradient_DivFree_VectorZY = (dimension==3) ? output_gradient_vector_evaluation(i, 7) : 0.0;
330  double GMLS_Gradient_DivFree_VectorZZ = (dimension==3) ? output_gradient_vector_evaluation(i, 8) : 0.0;
331 
332  // target site i's coordinate
333  double xval = target_coords(i,0);
334  double yval = (dimension>1) ? target_coords(i,1) : 0;
335  double zval = (dimension>2) ? target_coords(i,2) : 0;
336 
337  // evaluation of vector exact solutions
338  double actual_vector[3] = {0, 0, 0};
339  if (dimension>=1) {
340  actual_vector[0] = divfreeTestSolution_span_basis(xval, yval, zval, 0, dimension, order);
341  if (dimension>=2) {
342  actual_vector[1] = divfreeTestSolution_span_basis(xval, yval, zval, 1, dimension, order);
343  if (dimension==3) {
344  actual_vector[2] = divfreeTestSolution_span_basis(xval, yval, zval, 2, dimension, order);
345  }
346  }
347  }
348 
349  // evaluation of curl of vector exact solutions
350  double actual_curl_vector[3] = {0, 0, 0};
351  if (dimension>=1) {
352  actual_curl_vector[0] = curldivfreeTestSolution_span_basis(xval, yval, zval, 0, dimension, order);
353  if (dimension==3) {
354  actual_curl_vector[1] = curldivfreeTestSolution_span_basis(xval, yval, zval, 1, dimension, order);
355  actual_curl_vector[2] = curldivfreeTestSolution_span_basis(xval, yval, zval, 2, dimension, order);
356  }
357  }
358 
359  // evaluation of curl of curl of vector exact solutions
360  double actual_curlcurl_vector[3] = {0, 0, 0};
361  if (dimension>=1) {
362  actual_curlcurl_vector[0] = curlcurldivfreeTestSolution_single_polynomial(xval, yval, zval, 0, dimension);
363  if (dimension>=2) {
364  actual_curlcurl_vector[1] = curlcurldivfreeTestSolution_single_polynomial(xval, yval, zval, 1, dimension);
365  if (dimension==3) {
366  actual_curlcurl_vector[2] = curlcurldivfreeTestSolution_single_polynomial(xval, yval, zval, 2, dimension);
367  }
368  }
369  }
370 
371  double actual_gradient_vector[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
372  if (dimension==3) {
373  for (int axes = 0; axes < 9; ++axes)
374  actual_gradient_vector[axes] = gradientdivfreeTestSolution_span_basis(xval, yval, zval, axes/dimension, axes%dimension, dimension, order);
375  }
376  if (dimension==2) {
377  for (int axes = 0; axes < 4; ++axes)
378  actual_gradient_vector[axes] = gradientdivfreeTestSolution_span_basis(xval, yval, zval, axes/dimension, axes%dimension, dimension, order);
379  }
380 
381  // check vector evaluation
382  if(std::abs(actual_vector[0] - GMLS_DivFree_VectorX) > failure_tolerance) {
383  all_passed = false;
384  std::cout << i << " Failed VectorX by: " << std::abs(actual_vector[0] - GMLS_DivFree_VectorX) << std::endl;
385  if (dimension>1) {
386  if(std::abs(actual_vector[1] - GMLS_DivFree_VectorY) > failure_tolerance) {
387  all_passed = false;
388  std::cout << i << " Failed VectorY by: " << std::abs(actual_vector[1] - GMLS_DivFree_VectorY) << std::endl;
389  }
390  }
391  if (dimension>2) {
392  if(std::abs(actual_vector[2] - GMLS_DivFree_VectorZ) > failure_tolerance) {
393  all_passed = false;
394  std::cout << i << " Failed VectorZ by: " << std::abs(actual_vector[2] - GMLS_DivFree_VectorZ) << std::endl;
395  }
396  }
397  }
398 
399  // check curl of vector evaluation
400  if (dimension==2) {
401  if(std::abs(actual_curl_vector[0] - GMLS_Curl_DivFree_VectorX) > failure_tolerance) {
402  all_passed = false;
403  std::cout << i << " Failed curl VectorX by: " << std::abs(actual_curl_vector[2] - GMLS_Curl_DivFree_VectorX) << std::endl;
404  }
405  } else if (dimension>2) {
406  if(std::abs(actual_curl_vector[0] - GMLS_Curl_DivFree_VectorX) > failure_tolerance) {
407  all_passed = false;
408  std::cout << i << " Failed curl VectorX by: " << std::abs(actual_curl_vector[0] - GMLS_Curl_DivFree_VectorX) << std::endl;
409  }
410  if(std::abs(actual_curl_vector[1] - GMLS_Curl_DivFree_VectorY) > failure_tolerance) {
411  all_passed = false;
412  std::cout << i << " Failed curl VectorY by: " << std::abs(actual_curl_vector[1] - GMLS_Curl_DivFree_VectorY) << std::endl;
413  }
414  if(std::abs(actual_curl_vector[2] - GMLS_Curl_DivFree_VectorZ) > failure_tolerance) {
415  all_passed = false;
416  std::cout << i << " Failed curl VectorZ by: " << std::abs(actual_curl_vector[2] - GMLS_Curl_DivFree_VectorZ) << std::endl;
417  }
418  }
419 
420  // check curlcurl curlcurl of vector evaluation
421  if(std::abs(actual_curlcurl_vector[0] - GMLS_CurlCurl_DivFree_VectorX) > failure_tolerance) {
422  all_passed = false;
423  std::cout << i << " Failed curl curl VectorX by: " << std::abs(actual_curlcurl_vector[0] - GMLS_CurlCurl_DivFree_VectorX) << std::endl;
424  }
425  if (dimension>1) {
426  if(std::abs(actual_curlcurl_vector[1] - GMLS_CurlCurl_DivFree_VectorY) > failure_tolerance) {
427  all_passed = false;
428  std::cout << i << " Failed curl curl VectorY by: " << std::abs(actual_curlcurl_vector[1] - GMLS_CurlCurl_DivFree_VectorY) << std::endl;
429  }
430  }
431  if (dimension>2) {
432  if(std::abs(actual_curlcurl_vector[2] - GMLS_CurlCurl_DivFree_VectorZ) > failure_tolerance) {
433  all_passed = false;
434  std::cout << i << " Failed curl curl VectorZ by: " << std::abs(actual_curlcurl_vector[2] - GMLS_CurlCurl_DivFree_VectorZ) << std::endl;
435  }
436  }
437 
438  // check gradient of vector evaluation
439  if (dimension==3) {
440  if (std::abs(actual_gradient_vector[0] - GMLS_Gradient_DivFree_VectorXX) > failure_tolerance) {
441  all_passed = false;
442  std::cout << i << " Failed gradient_x VectorX by: " << std::abs(actual_gradient_vector[0] - GMLS_Gradient_DivFree_VectorXX) << std::endl;
443  }
444  if (std::abs(actual_gradient_vector[1] - GMLS_Gradient_DivFree_VectorXY) > failure_tolerance) {
445  all_passed = false;
446  std::cout << i << " Failed gradient_y VectorX by: " << std::abs(actual_gradient_vector[1] - GMLS_Gradient_DivFree_VectorXY) << std::endl;
447  }
448  if (std::abs(actual_gradient_vector[2] - GMLS_Gradient_DivFree_VectorXZ) > failure_tolerance) {
449  all_passed = false;
450  std::cout << i << " Failed gradient_z VectorX by: " << std::abs(actual_gradient_vector[2] - GMLS_Gradient_DivFree_VectorXZ) << std::endl;
451  }
452 
453  if (std::abs(actual_gradient_vector[3] - GMLS_Gradient_DivFree_VectorYX) > failure_tolerance) {
454  all_passed = false;
455  std::cout << i << " Failed gradient_x VectorY by: " << std::abs(actual_gradient_vector[3] - GMLS_Gradient_DivFree_VectorYX) << std::endl;
456  }
457  if (std::abs(actual_gradient_vector[4] - GMLS_Gradient_DivFree_VectorYY) > failure_tolerance) {
458  all_passed = false;
459  std::cout << i << " Failed gradient_y VectorY by: " << std::abs(actual_gradient_vector[4] - GMLS_Gradient_DivFree_VectorYY) << std::endl;
460  }
461  if (std::abs(actual_gradient_vector[5] - GMLS_Gradient_DivFree_VectorYZ) > failure_tolerance) {
462  all_passed = false;
463  std::cout << i << " Failed gradient_z VectorY by: " << std::abs(actual_gradient_vector[5] - GMLS_Gradient_DivFree_VectorYZ) << std::endl;
464  }
465 
466  if (std::abs(actual_gradient_vector[6] - GMLS_Gradient_DivFree_VectorZX) > failure_tolerance) {
467  all_passed = false;
468  std::cout << i << " Failed gradient_x VectorZ by: " << std::abs(actual_gradient_vector[6] - GMLS_Gradient_DivFree_VectorZX) << std::endl;
469  }
470  if (std::abs(actual_gradient_vector[7] - GMLS_Gradient_DivFree_VectorZY) > failure_tolerance) {
471  all_passed = false;
472  std::cout << i << " Failed gradient_y VectorZ by: " << std::abs(actual_gradient_vector[7] - GMLS_Gradient_DivFree_VectorZY) << std::endl;
473  }
474  if (std::abs(actual_gradient_vector[8] - GMLS_Gradient_DivFree_VectorZZ) > failure_tolerance) {
475  all_passed = false;
476  std::cout << i << " Failed gradient_z VectorZ by: " << std::abs(actual_gradient_vector[8] - GMLS_Gradient_DivFree_VectorZZ) << std::endl;
477  }
478  }
479 
480  if (dimension==2) {
481  if (std::abs(actual_gradient_vector[0] - GMLS_Gradient_DivFree_VectorXX) > failure_tolerance) {
482  all_passed = false;
483  std::cout << i << " Failed gradient_x VectorX by: " << std::abs(actual_gradient_vector[0] - GMLS_Gradient_DivFree_VectorXX) << std::endl;
484  }
485  if (std::abs(actual_gradient_vector[1] - GMLS_Gradient_DivFree_VectorXY) > failure_tolerance) {
486  all_passed = false;
487  std::cout << i << " Failed gradient_y VectorX by: " << std::abs(actual_gradient_vector[1] - GMLS_Gradient_DivFree_VectorXY) << std::endl;
488  }
489 
490  if (std::abs(actual_gradient_vector[2] - GMLS_Gradient_DivFree_VectorYX) > failure_tolerance) {
491  all_passed = false;
492  std::cout << i << " Failed gradient_x VectorY by: " << std::abs(actual_gradient_vector[2] - GMLS_Gradient_DivFree_VectorYX) << std::endl;
493  }
494  if (std::abs(actual_gradient_vector[3] - GMLS_Gradient_DivFree_VectorYY) > failure_tolerance) {
495  all_passed = false;
496  std::cout << i << " Failed gradient_y VectorY by: " << (std::abs(actual_gradient_vector[3] - GMLS_Gradient_DivFree_VectorYY) > failure_tolerance) << std::endl;
497  }
498  }
499  }
500 
501  //! [Check That Solutions Are Correct]
502  // popRegion hidden from tutorial
503  // stop timing comparison loop
504  Kokkos::Profiling::popRegion();
505  //! [Finalize Program]
506 
507 
508 } // end of code block to reduce scope, causing Kokkos View de-allocations
509 // otherwise, Views may be deallocating when we call Kokkos::finalize() later
510 
511 // finalize Kokkos and MPI (if available)
512 Kokkos::finalize();
513 #ifdef COMPADRE_USE_MPI
514 MPI_Finalize();
515 #endif
516 
517 // output to user that test passed or failed
518 if(all_passed) {
519  fprintf(stdout, "Passed test \n");
520  return 0;
521 } else {
522  fprintf(stdout, "Failed test \n");
523  return -1;
524 }
525 
526 } // main
527 
528 
529 //! [Finalize Program]
KOKKOS_INLINE_FUNCTION double divfreeTestSolution_span_basis(double x, double y, double z, int component, int dimension, int exact_order)
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...
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)
Point evaluation of the curl of a vector (results in a vector)
KOKKOS_INLINE_FUNCTION double curlcurldivfreeTestSolution_single_polynomial(double x, double y, double z, int component, int dimension)
Point evaluation of the curl of a curl of a vector (results in a vector)
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 double divfreeTestSolution_single_polynomial(double x, double y, double z, int component, int dimension)
Generalized Moving Least Squares (GMLS)
Divergence-free vector polynomial basis.
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 (allocates memory for output)
KOKKOS_INLINE_FUNCTION double gradientdivfreeTestSolution_span_basis(double x, double y, double z, int input_component, int output_component, int dimension, int exact_order)
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) ...
constexpr SamplingFunctional VectorPointSample
Point evaluations of the entire vector source function.
Point evaluation of the gradient of a vector (results in a matrix, NOT CURRENTLY IMPLEMENTED) ...
Point evaluation of a vector (reconstructs entire vector at once, requiring a ReconstructionSpace hav...