9 #include <Compadre_Config.h> 
   16 #ifdef COMPADRE_USE_MPI 
   20 #include <Kokkos_Timer.hpp> 
   21 #include <Kokkos_Core.hpp> 
   23 using namespace Compadre;
 
   28 int main (
int argc, 
char* args[]) {
 
   31 #ifdef COMPADRE_USE_MPI 
   32 MPI_Init(&argc, &args);
 
   36 Kokkos::initialize(argc, args);
 
   45     int constraint_type = 0; 
 
   47         int arg8toi = atoi(args[7]);
 
   49             constraint_type = arg8toi;
 
   59         int arg7toi = atoi(args[6]);
 
   61             problem_type = arg7toi;
 
   72         int arg6toi = atoi(args[5]);
 
   74             solver_type = arg6toi;
 
   80     int N_pts_on_sphere = 1000; 
 
   82         int arg5toi = atoi(args[4]);
 
   84             N_pts_on_sphere = arg5toi;
 
   92         int arg4toi = atoi(args[3]);
 
  100     int number_target_coords = 200; 
 
  102         int arg3toi = atoi(args[2]);
 
  104             number_target_coords = arg3toi;
 
  112         int arg2toi = atoi(args[1]);
 
  124     Kokkos::Profiling::pushRegion(
"Setup Point Data");
 
  129     Kokkos::View<double**, Kokkos::DefaultExecutionSpace> source_coords_device(
"source coordinates", 
 
  130             1.25*N_pts_on_sphere, 3);
 
  131     Kokkos::View<double**>::HostMirror source_coords = Kokkos::create_mirror_view(source_coords_device);
 
  136     int number_source_coords;
 
  142         double a = 4*
PI*r*r/N_pts_on_sphere;
 
  143         double d = std::sqrt(a);
 
  144         int M_theta = std::round(
PI/d);
 
  145         double d_theta = 
PI/M_theta;
 
  146         double d_phi = a/d_theta;
 
  147         for (
int i=0; i<M_theta; ++i) {
 
  148             double theta = 
PI*(i + 0.5)/M_theta;
 
  149             int M_phi = std::round(2*
PI*std::sin(theta)/d_phi);
 
  150             for (
int j=0; j<M_phi; ++j) {
 
  151                 double phi = 2*
PI*j/M_phi;
 
  152                 source_coords(N_count, 0) = theta;
 
  153                 source_coords(N_count, 1) = phi;
 
  158         for (
int i=0; i<N_count; ++i) {
 
  159             double theta = source_coords(i,0);
 
  160             double phi = source_coords(i,1);
 
  161             source_coords(i,0) = r*std::sin(theta)*std::cos(phi);
 
  162             source_coords(i,1) = r*std::sin(theta)*std::sin(phi);
 
  163             source_coords(i,2) = r*cos(theta);
 
  166         number_source_coords = N_count;
 
  170     Kokkos::resize(source_coords, number_source_coords, 3);
 
  171     Kokkos::resize(source_coords_device, number_source_coords, 3);
 
  174     Kokkos::View<double**, Kokkos::DefaultExecutionSpace> target_coords_device (
"target coordinates", 
 
  175             number_target_coords, 3);
 
  176     Kokkos::View<double**>::HostMirror target_coords = Kokkos::create_mirror_view(target_coords_device);
 
  179         bool enough_pts_found = 
false;
 
  183         double a = 4.0*
PI*r*r/((double)(5.0*number_target_coords)); 
 
  184         double d = std::sqrt(a);
 
  185         int M_theta = std::round(
PI/d);
 
  186         double d_theta = 
PI/((double)M_theta);
 
  187         double d_phi = a/d_theta;
 
  188         for (
int i=0; i<M_theta; ++i) {
 
  189             double theta = 
PI*(i + 0.5)/M_theta;
 
  190             int M_phi = std::round(2*
PI*std::sin(theta)/d_phi);
 
  191             for (
int j=0; j<M_phi; ++j) {
 
  192                 double phi = 2*
PI*j/M_phi;
 
  193                 target_coords(N_count, 0) = theta;
 
  194                 target_coords(N_count, 1) = phi;
 
  196                 if (N_count == number_target_coords) {
 
  197                     enough_pts_found = 
true;
 
  201             if (enough_pts_found) 
break;
 
  204         for (
int i=0; i<N_count; ++i) {
 
  205             double theta = target_coords(i,0);
 
  206             double phi = target_coords(i,1);
 
  207             target_coords(i,0) = r*std::sin(theta)*std::cos(phi);
 
  208             target_coords(i,1) = r*std::sin(theta)*std::sin(phi);
 
  209             target_coords(i,2) = r*cos(theta);
 
  217     Kokkos::Profiling::popRegion();
 
  219     Kokkos::Profiling::pushRegion(
"Creating Data");
 
  225     Kokkos::deep_copy(source_coords_device, source_coords);
 
  228     Kokkos::deep_copy(target_coords_device, target_coords);
 
  235     Kokkos::View<double*, Kokkos::DefaultExecutionSpace> sampling_data_device(
"samples of true solution", 
 
  236             source_coords_device.extent(0));
 
  238     Kokkos::View<double*, Kokkos::DefaultExecutionSpace> ones_data_device(
"samples of ones", 
 
  239             source_coords_device.extent(0));
 
  240     Kokkos::deep_copy(ones_data_device, 1.0);
 
  243     Kokkos::View<double**, Kokkos::DefaultExecutionSpace> sampling_vector_data_device(
"samples of vector true solution", 
 
  244             source_coords_device.extent(0), 3);
 
  246     Kokkos::parallel_for(
"Sampling Manufactured Solutions", Kokkos::RangePolicy<Kokkos::DefaultExecutionSpace>
 
  247             (0,source_coords.extent(0)), KOKKOS_LAMBDA(
const int i) {
 
  250         double xval = source_coords_device(i,0);
 
  251         double yval = (dimension>1) ? source_coords_device(i,1) : 0;
 
  252         double zval = (dimension>2) ? source_coords_device(i,2) : 0;
 
  257         for (
int j=0; j<3; ++j) {
 
  258             double gradient[3] = {0,0,0};
 
  260             sampling_vector_data_device(i,j) = gradient[j];
 
  267     Kokkos::Profiling::popRegion();
 
  268     Kokkos::Profiling::pushRegion(
"Neighbor Search");
 
  279     double epsilon_multiplier = 1.9;
 
  280     int estimated_upper_bound_number_neighbors = 
 
  281         point_cloud_search.getEstimatedNumberNeighborsUpperBound(min_neighbors, dimension, epsilon_multiplier);
 
  283     Kokkos::View<int**, Kokkos::DefaultExecutionSpace> neighbor_lists_device(
"neighbor lists", 
 
  284             number_target_coords, estimated_upper_bound_number_neighbors); 
 
  285     Kokkos::View<int**>::HostMirror neighbor_lists = Kokkos::create_mirror_view(neighbor_lists_device);
 
  288     Kokkos::View<double*, Kokkos::DefaultExecutionSpace> epsilon_device(
"h supports", number_target_coords);
 
  289     Kokkos::View<double*>::HostMirror epsilon = Kokkos::create_mirror_view(epsilon_device);
 
  294     point_cloud_search.generate2DNeighborListsFromKNNSearch(
false , target_coords, neighbor_lists, 
 
  295             epsilon, min_neighbors, epsilon_multiplier);
 
  299     Kokkos::Profiling::popRegion();
 
  310     Kokkos::deep_copy(neighbor_lists_device, neighbor_lists);
 
  311     Kokkos::deep_copy(epsilon_device, epsilon);
 
  314     std::string solver_name;
 
  315     if (solver_type == 0) { 
 
  317     } 
else if (solver_type == 1) { 
 
  319     } 
else if (solver_type == 2) { 
 
  324     std::string problem_name;
 
  325     if (problem_type == 0) { 
 
  326         problem_name = 
"STANDARD";
 
  327     } 
else if (problem_type == 1) { 
 
  328         problem_name = 
"MANIFOLD";
 
  332     std::string constraint_name;
 
  333     if (constraint_type == 0) { 
 
  334         constraint_name = 
"NO_CONSTRAINT";
 
  335     } 
else if (constraint_type == 1) { 
 
  336         constraint_name = 
"NEUMANN_GRAD_SCALAR";
 
  341     GMLS my_GMLS_scalar(order, dimension,
 
  342                         solver_name.c_str(), problem_name.c_str(), constraint_name.c_str(),
 
  359     my_GMLS_scalar.
setProblemData(neighbor_lists_device, source_coords_device, target_coords_device, epsilon_device);
 
  364     my_GMLS_scalar.setReferenceOutwardNormalDirection(target_coords_device, 
true );
 
  367     std::vector<TargetOperation> lro_scalar(4);
 
  374     my_GMLS_scalar.addTargets(lro_scalar);
 
  380     my_GMLS_scalar.setCurvatureWeightingPower(2);
 
  386     my_GMLS_scalar.setWeightingPower(2);
 
  389     my_GMLS_scalar.generateAlphas();
 
  391     Kokkos::Profiling::pushRegion(
"Full Polynomial Basis GMLS Solution");
 
  398                         solver_name.c_str(), problem_name.c_str(), constraint_name.c_str(),
 
  401     my_GMLS_vector.
setProblemData(neighbor_lists_device, source_coords_device, target_coords_device, epsilon_device);
 
  402     std::vector<TargetOperation> lro_vector(2);
 
  405     my_GMLS_vector.addTargets(lro_vector);
 
  407     my_GMLS_vector.setCurvatureWeightingPower(2);
 
  409     my_GMLS_vector.setWeightingPower(2);
 
  410     my_GMLS_vector.generateAlphas();
 
  411     Kokkos::Profiling::popRegion();
 
  413     Kokkos::Profiling::pushRegion(
"Scalar Polynomial Basis Repeated to Form a Vector GMLS Solution");
 
  438                                          solver_name.c_str(), problem_name.c_str(), constraint_name.c_str(),
 
  441     my_GMLS_vector_of_scalar_clones.
setProblemData(neighbor_lists_device, source_coords_device, target_coords_device, epsilon_device);
 
  442     std::vector<TargetOperation> lro_vector_of_scalar_clones(2);
 
  445     my_GMLS_vector_of_scalar_clones.addTargets(lro_vector_of_scalar_clones);
 
  447     my_GMLS_vector_of_scalar_clones.setCurvatureWeightingPower(2);
 
  449     my_GMLS_vector_of_scalar_clones.setWeightingPower(2);
 
  450     my_GMLS_vector_of_scalar_clones.generateAlphas();
 
  451     Kokkos::Profiling::popRegion();
 
  456     double instantiation_time = timer.seconds();
 
  457     std::cout << 
"Took " << instantiation_time << 
"s to complete alphas generation." << std::endl;
 
  459     Kokkos::Profiling::pushRegion(
"Apply Alphas to Data");
 
  474     Evaluator scalar_gmls_evaluator(&my_GMLS_scalar);
 
  475     Evaluator vector_gmls_evaluator(&my_GMLS_vector);
 
  476     Evaluator vector_gmls_evaluator_of_scalar_clones(&my_GMLS_vector_of_scalar_clones);
 
  496     auto output_vector_of_scalar_clones = 
 
  500     auto output_divergence_of_scalar_clones = 
 
  534     Kokkos::Profiling::popRegion();
 
  536     Kokkos::Profiling::pushRegion(
"Comparison");
 
  540     double tangent_bundle_error = 0;
 
  541     double tangent_bundle_norm = 0;
 
  542     double values_error = 0;
 
  543     double values_norm = 0;
 
  544     double laplacian_error = 0;
 
  545     double laplacian_norm = 0;
 
  546     double gradient_ambient_error = 0;
 
  547     double gradient_ambient_norm = 0;
 
  550     double vector_ambient_error = 0;
 
  551     double vector_ambient_norm = 0;
 
  552     double divergence_ambient_error = 0;
 
  553     double divergence_ambient_norm = 0;
 
  554     double vector_of_scalar_clones_ambient_error = 0;
 
  555     double vector_of_scalar_clones_ambient_norm = 0;
 
  556     double divergence_of_scalar_clones_ambient_error = 0;
 
  557     double divergence_of_scalar_clones_ambient_norm = 0;
 
  560     for (
int i=0; i<number_target_coords; i++) {
 
  563         double GMLS_value = output_value(i);
 
  564         double GMLS_gc = output_gc(i);
 
  567         double GMLS_Laplacian = output_laplacian(i);
 
  570         double xval = target_coords(i,0);
 
  571         double yval = (dimension>1) ? target_coords(i,1) : 0;
 
  572         double zval = (dimension>2) ? target_coords(i,2) : 0;
 
  573         double coord[3] = {xval, yval, zval};
 
  576         for (
int j=0; j<dimension-1; ++j) {
 
  577             double tangent_inner_prod = 0;
 
  578             for (
int k=0; k<dimension; ++k) {
 
  579                 tangent_inner_prod += coord[k] * my_GMLS_scalar.getTangentBundle(i, j, k);
 
  581             tangent_bundle_error += tangent_inner_prod * tangent_inner_prod;
 
  583         double normal_inner_prod = 0;
 
  584         for (
int k=0; k<dimension; ++k) {
 
  585             normal_inner_prod += coord[k] * my_GMLS_scalar.getTangentBundle(i, dimension-1, k);
 
  588         double normal_error_to_sum = (normal_inner_prod > 0) ? normal_inner_prod - 1 : normal_inner_prod + 1;
 
  589         tangent_bundle_error += normal_error_to_sum * normal_error_to_sum;
 
  590         tangent_bundle_norm += 1;
 
  595         double actual_Gradient_ambient[3] = {0,0,0}; 
 
  599         values_error += (GMLS_value - actual_value)*(GMLS_value - actual_value);
 
  600         values_norm  += actual_value*actual_value;
 
  602         laplacian_error += (GMLS_Laplacian - actual_Laplacian)*(GMLS_Laplacian - actual_Laplacian);
 
  603         laplacian_norm += actual_Laplacian*actual_Laplacian;
 
  605         double actual_gc = 1.0;
 
  606         gc_error += (GMLS_gc - actual_gc)*(GMLS_gc - actual_gc);
 
  607         gc_norm += actual_gc*actual_gc;
 
  609         for (
int j=0; j<dimension; ++j) {
 
  610             gradient_ambient_error += (output_gradient(i,j) - actual_Gradient_ambient[j])*(output_gradient(i,j) - actual_Gradient_ambient[j]);
 
  611             gradient_ambient_norm += actual_Gradient_ambient[j]*actual_Gradient_ambient[j];
 
  614         for (
int j=0; j<dimension; ++j) {
 
  615             vector_ambient_error += (output_vector(i,j) - actual_Gradient_ambient[j])*(output_vector(i,j) - actual_Gradient_ambient[j]);
 
  616             vector_ambient_norm += actual_Gradient_ambient[j]*actual_Gradient_ambient[j];
 
  619         divergence_ambient_error += (output_divergence(i) - actual_Laplacian)*(output_divergence(i) - actual_Laplacian);
 
  620         divergence_ambient_norm += actual_Laplacian*actual_Laplacian;
 
  622         for (
int j=0; j<dimension; ++j) {
 
  623             vector_of_scalar_clones_ambient_error += (output_vector_of_scalar_clones(i,j) - actual_Gradient_ambient[j])*(output_vector_of_scalar_clones(i,j) - actual_Gradient_ambient[j]);
 
  624             vector_of_scalar_clones_ambient_norm += actual_Gradient_ambient[j]*actual_Gradient_ambient[j];
 
  627         divergence_of_scalar_clones_ambient_error += (output_divergence_of_scalar_clones(i) - actual_Laplacian)*(output_divergence_of_scalar_clones(i) - actual_Laplacian);
 
  628         divergence_of_scalar_clones_ambient_norm += actual_Laplacian*actual_Laplacian;
 
  632     tangent_bundle_error /= number_target_coords;
 
  633     tangent_bundle_error = std::sqrt(tangent_bundle_error);
 
  634     tangent_bundle_norm /= number_target_coords;
 
  635     tangent_bundle_norm = std::sqrt(tangent_bundle_norm);
 
  637     values_error /= number_target_coords;
 
  638     values_error = std::sqrt(values_error);
 
  639     values_norm /= number_target_coords;
 
  640     values_norm = std::sqrt(values_norm);
 
  642     laplacian_error /= number_target_coords;
 
  643     laplacian_error = std::sqrt(laplacian_error);
 
  644     laplacian_norm /= number_target_coords;
 
  645     laplacian_norm = std::sqrt(laplacian_norm);
 
  647     gradient_ambient_error /= number_target_coords;
 
  648     gradient_ambient_error = std::sqrt(gradient_ambient_error);
 
  649     gradient_ambient_norm /= number_target_coords;
 
  650     gradient_ambient_norm = std::sqrt(gradient_ambient_norm);
 
  652     gc_error /= number_target_coords;
 
  653     gc_error = std::sqrt(gc_error);
 
  654     gc_norm /= number_target_coords;
 
  655     gc_norm = std::sqrt(gc_norm);
 
  657     vector_ambient_error /= number_target_coords;
 
  658     vector_ambient_error = std::sqrt(vector_ambient_error);
 
  659     vector_ambient_norm /= number_target_coords;
 
  660     vector_ambient_norm = std::sqrt(vector_ambient_norm);
 
  662     divergence_ambient_error /= number_target_coords;
 
  663     divergence_ambient_error = std::sqrt(divergence_ambient_error);
 
  664     divergence_ambient_norm /= number_target_coords;
 
  665     divergence_ambient_norm = std::sqrt(divergence_ambient_norm);
 
  667     vector_of_scalar_clones_ambient_error /= number_target_coords;
 
  668     vector_of_scalar_clones_ambient_error = std::sqrt(vector_of_scalar_clones_ambient_error);
 
  669     vector_of_scalar_clones_ambient_norm /= number_target_coords;
 
  670     vector_of_scalar_clones_ambient_norm = std::sqrt(vector_of_scalar_clones_ambient_norm);
 
  672     divergence_of_scalar_clones_ambient_error /= number_target_coords;
 
  673     divergence_of_scalar_clones_ambient_error = std::sqrt(divergence_of_scalar_clones_ambient_error);
 
  674     divergence_of_scalar_clones_ambient_norm /= number_target_coords;
 
  675     divergence_of_scalar_clones_ambient_norm = std::sqrt(divergence_of_scalar_clones_ambient_norm);
 
  677     printf(
"Tangent Bundle Error: %g\n", tangent_bundle_error / tangent_bundle_norm);  
 
  678     printf(
"Point Value Error: %g\n", values_error / values_norm);  
 
  679     printf(
"Laplace-Beltrami Error: %g\n", laplacian_error / laplacian_norm);  
 
  680     printf(
"Gaussian Curvature Error: %g\n", gc_error / gc_norm);  
 
  681     printf(
"Surface Gradient (Ambient) Error: %g\n", gradient_ambient_error / gradient_ambient_norm);  
 
  682     printf(
"Surface Vector (VectorBasis) Error: %g\n", vector_ambient_error / vector_ambient_norm);  
 
  683     printf(
"Surface Divergence (VectorBasis) Error: %g\n", divergence_ambient_error / divergence_ambient_norm);  
 
  684     printf(
"Surface Vector (ScalarClones) Error: %g\n", 
 
  685             vector_of_scalar_clones_ambient_error / vector_of_scalar_clones_ambient_norm);  
 
  686     printf(
"Surface Divergence (ScalarClones) Error: %g\n", 
 
  687             divergence_of_scalar_clones_ambient_error / divergence_of_scalar_clones_ambient_norm);  
 
  691     Kokkos::Profiling::popRegion();
 
  700 #ifdef COMPADRE_USE_MPI 
KOKKOS_INLINE_FUNCTION double sphere_harmonic54(double x, double y, double z)
 
Lightweight Evaluator Helper This class is a lightweight wrapper for extracting and applying all rele...
 
constexpr SamplingFunctional ManifoldVectorPointSample
Point evaluations of the entire vector source function (but on a manifold, so it includes a transform...
 
Point evaluation of a vector (reconstructs entire vector at once, requiring a ReconstructionSpace hav...
 
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...
 
Point evaluation of Gaussian curvature. 
 
int main(int argc, char *args[])
[Parse Command Line Arguments] 
 
Point evaluation of a scalar. 
 
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...
 
Scalar basis reused as many times as there are components in the vector resulting in a much cheaper p...
 
Point evaluation of the laplacian of a scalar (could be on a manifold or not) 
 
Point evaluation of the divergence of a vector (results in a scalar) 
 
KOKKOS_INLINE_FUNCTION void gradient_sphereHarmonic54_ambient(double *gradient, double x, double y, double z)
 
Point evaluation of the gradient of a scalar. 
 
Generalized Moving Least Squares (GMLS) 
 
import subprocess import os import re import math import sys import argparse d d d(20 *num_target_sites *pow(4, grid_num))
 
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 laplace_beltrami_sphere_harmonic54(double x, double y, double z)
 
Vector polynomial basis having # of components _dimensions, or (_dimensions-1) in the case of manifol...