Compadre  1.6.0
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]
int main(int argc, char *args[])
[Parse Command Line Arguments]
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 curlcurldivfreeTestSolution_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)
Lightweight Evaluator Helper This class is a lightweight wrapper for extracting and applying all rele...
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)
Generalized Moving Least Squares (GMLS)
void addTargets(TargetOperation lro)
Adds a target to the vector of target functional to be applied to the reconstruction.
void setWeightingParameter(int wp, int index=0)
Parameter for weighting kernel for GMLS problem index = 0 sets p paramater for weighting kernel index...
void generateAlphas(const int number_of_batches=1, const bool keep_coefficients=false, const bool clear_cache=true)
Meant to calculate target operations and apply the evaluations to the previously constructed polynomi...
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)
void setWeightingType(const std::string &wt)
Type for weighting kernel for GMLS problem.
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....
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...
@ DivergenceFreeVectorTaylorPolynomial
Divergence-free vector polynomial basis.
constexpr SamplingFunctional VectorPointSample
Point evaluations of the entire vector source function.
@ CurlOfVectorPointEvaluation
Point evaluation of the curl of a vector (results in a vector)
@ CurlCurlOfVectorPointEvaluation
Point evaluation of the curl of a curl of a vector (results in a vector)
@ GradientOfVectorPointEvaluation
Point evaluation of the gradient of a vector (results in a matrix, NOT CURRENTLY IMPLEMENTED)
@ VectorPointEvaluation
Point evaluation of a vector (reconstructs entire vector at once, requiring a ReconstructionSpace hav...