based on GMLS_Device.cpp
GMLS Example with Device Views
This tutorial sets up a batch of GMLS problems, solves the minimization problems, and applies the coefficients produced to data.
Parse Command Line Arguments
int main (
int argc,
char* args[]) {
#ifdef COMPADRE_USE_MPI
MPI_Init(&argc, &args);
#endif
Kokkos::initialize(argc, args);
bool all_passed = true;
{
bool keep_coefficients = number_of_batches==1;
const double failure_tolerance = 1e-9;
const double laplacian_failure_tolerance = 1e-9;
Setting Up The Point Cloud
double h_spacing = 0.05;
int n_neg1_to_1 = 2*(1/h_spacing) + 1;
const int number_source_coords = std::pow(n_neg1_to_1, dimension);
Kokkos::View<double**, Kokkos::DefaultExecutionSpace> source_coords_device("source coordinates",
number_source_coords, 3);
Kokkos::View<double**>::HostMirror source_coords = Kokkos::create_mirror_view(source_coords_device);
Kokkos::View<double**, Kokkos::DefaultExecutionSpace> target_coords_device ("target coordinates", number_target_coords, 3);
Kokkos::View<double**>::HostMirror target_coords = Kokkos::create_mirror_view(target_coords_device);
int source_index = 0;
double this_coord[3] = {0,0,0};
for (int i=-n_neg1_to_1/2; i<n_neg1_to_1/2+1; ++i) {
this_coord[0] = i*h_spacing;
for (int j=-n_neg1_to_1/2; j<n_neg1_to_1/2+1; ++j) {
this_coord[1] = j*h_spacing;
for (int k=-n_neg1_to_1/2; k<n_neg1_to_1/2+1; ++k) {
this_coord[2] = k*h_spacing;
if (dimension==3) {
source_coords(source_index,0) = this_coord[0];
source_coords(source_index,1) = this_coord[1];
source_coords(source_index,2) = this_coord[2];
source_index++;
}
}
if (dimension==2) {
source_coords(source_index,0) = this_coord[0];
source_coords(source_index,1) = this_coord[1];
source_coords(source_index,2) = 0;
source_index++;
}
}
if (dimension==1) {
source_coords(source_index,0) = this_coord[0];
source_coords(source_index,1) = 0;
source_coords(source_index,2) = 0;
source_index++;
}
}
for(int i=0; i<number_target_coords; i++){
double rand_dir[3] = {0,0,0};
for (int j=0; j<dimension; ++j) {
rand_dir[j] = ((double)rand() / (double) RAND_MAX) - 0.5;
}
for (int j=0; j<dimension; ++j) {
target_coords(i,j) = rand_dir[j];
}
}
Performing Neighbor Search
double epsilon_multiplier = 1.4;
Kokkos::View<int*> neighbor_lists_device("neighbor lists",
0);
Kokkos::View<int*>::HostMirror neighbor_lists = Kokkos::create_mirror_view(neighbor_lists_device);
Kokkos::View<int*> number_of_neighbors_list_device("number of neighbor lists",
number_target_coords);
Kokkos::View<int*>::HostMirror number_of_neighbors_list = Kokkos::create_mirror_view(number_of_neighbors_list_device);
Kokkos::View<double*, Kokkos::DefaultExecutionSpace> epsilon_device("h supports", number_target_coords);
Kokkos::View<double*>::HostMirror epsilon = Kokkos::create_mirror_view(epsilon_device);
size_t storage_size = point_cloud_search.generateCRNeighborListsFromKNNSearch(true , target_coords, neighbor_lists,
number_of_neighbors_list, epsilon, min_neighbors, epsilon_multiplier);
Kokkos::resize(neighbor_lists_device, storage_size);
neighbor_lists = Kokkos::create_mirror_view(neighbor_lists_device);
point_cloud_search.generateCRNeighborListsFromKNNSearch(false , target_coords, neighbor_lists,
number_of_neighbors_list, epsilon, min_neighbors, epsilon_multiplier);
Creating The Data
Kokkos::deep_copy(source_coords_device, source_coords);
Kokkos::deep_copy(target_coords_device, target_coords);
Kokkos::View<double*, Kokkos::DefaultExecutionSpace> sampling_data_device("samples of true solution",
source_coords_device.extent(0));
Kokkos::View<double**, Kokkos::DefaultExecutionSpace> gradient_sampling_data_device("samples of true gradient",
source_coords_device.extent(0), dimension);
Kokkos::View<double**, Kokkos::DefaultExecutionSpace> divergence_sampling_data_device
("samples of true solution for divergence test", source_coords_device.extent(0), dimension);
Kokkos::parallel_for("Sampling Manufactured Solutions", Kokkos::RangePolicy<Kokkos::DefaultExecutionSpace>
(0,source_coords.extent(0)), KOKKOS_LAMBDA(const int i) {
double xval = source_coords_device(i,0);
double yval = (dimension>1) ? source_coords_device(i,1) : 0;
double zval = (dimension>2) ? source_coords_device(i,2) : 0;
sampling_data_device(i) =
trueSolution(xval, yval, zval, order, dimension);
double true_grad[3] = {0,0,0};
for (int j=0; j<dimension; ++j) {
gradient_sampling_data_device(i,j) = true_grad[j];
}
});
Setting Up The GMLS Object
Kokkos::deep_copy(neighbor_lists_device, neighbor_lists);
Kokkos::deep_copy(number_of_neighbors_list_device, number_of_neighbors_list);
Kokkos::deep_copy(epsilon_device, epsilon);
order, dimension,
solver_name.c_str(), problem_name.c_str(), constraint_name.c_str(),
2 );
my_GMLS.setProblemData(neighbor_lists_device, number_of_neighbors_list_device, source_coords_device, target_coords_device, epsilon_device);
std::vector<TargetOperation> lro(5);
my_GMLS.addTargets(lro);
my_GMLS.setWeightingParameter(2);
my_GMLS.generateAlphas(number_of_batches, keep_coefficients );
Apply GMLS Alphas To Data
Evaluator gmls_evaluator(&my_GMLS);
auto output_value = gmls_evaluator.applyAlphasToDataAllComponentsAllTargetSites<double*, Kokkos::HostSpace>
auto output_laplacian = gmls_evaluator.applyAlphasToDataAllComponentsAllTargetSites<double*, Kokkos::HostSpace>
auto output_gradient = gmls_evaluator.applyAlphasToDataAllComponentsAllTargetSites<double**, Kokkos::HostSpace>
auto output_divergence = gmls_evaluator.applyAlphasToDataAllComponentsAllTargetSites<double*, Kokkos::HostSpace>
auto output_curl = gmls_evaluator.applyAlphasToDataAllComponentsAllTargetSites<double**, Kokkos::HostSpace>
decltype(output_curl) scalar_coefficients;
if (number_of_batches==1)
scalar_coefficients =
gmls_evaluator.applyFullPolynomialCoefficientsBasisToDataAllComponents<double**, Kokkos::HostSpace>
(sampling_data_device);
Check That Solutions Are Correct
for (int i=0; i<number_target_coords; i++) {
double GMLS_value = output_value(i);
double GMLS_Laplacian = output_laplacian(i);
double GMLS_GradX = (number_of_batches==1) ? scalar_coefficients(i,1)*1./epsilon(i) : output_gradient(i,0);
double GMLS_GradY = (dimension>1) ? output_gradient(i,1) : 0;
double GMLS_GradZ = (dimension>2) ? output_gradient(i,2) : 0;
double GMLS_Divergence = output_divergence(i);
double GMLS_CurlX = (dimension>1) ? output_curl(i,0) : 0;
double GMLS_CurlY = (dimension>1) ? output_curl(i,1) : 0;
double GMLS_CurlZ = (dimension>2) ? output_curl(i,2) : 0;
double xval = target_coords(i,0);
double yval = (dimension>1) ? target_coords(i,1) : 0;
double zval = (dimension>2) ? target_coords(i,2) : 0;
double actual_value =
trueSolution(xval, yval, zval, order, dimension);
double actual_Laplacian =
trueLaplacian(xval, yval, zval, order, dimension);
double actual_Gradient[3] = {0,0,0};
trueGradient(actual_Gradient, xval, yval, zval, order, dimension);
double actual_Divergence;
actual_Divergence =
trueLaplacian(xval, yval, zval, order, dimension);
double actual_Curl[3] = {0,0,0};
if (dimension>1) {
if (dimension>2) {
}
}
if(GMLS_value!=GMLS_value || std::abs(actual_value - GMLS_value) > failure_tolerance) {
all_passed = false;
std::cout << i << " Failed Actual by: " << std::abs(actual_value - GMLS_value) << std::endl;
}
if(std::abs(actual_Laplacian - GMLS_Laplacian) > laplacian_failure_tolerance) {
all_passed = false;
std::cout << i <<" Failed Laplacian by: " << std::abs(actual_Laplacian - GMLS_Laplacian) << std::endl;
}
if(std::abs(actual_Gradient[0] - GMLS_GradX) > failure_tolerance) {
all_passed = false;
std::cout << i << " Failed GradX by: " << std::abs(actual_Gradient[0] - GMLS_GradX) << std::endl;
if (dimension>1) {
if(std::abs(actual_Gradient[1] - GMLS_GradY) > failure_tolerance) {
all_passed = false;
std::cout << i << " Failed GradY by: " << std::abs(actual_Gradient[1] - GMLS_GradY) << std::endl;
}
}
if (dimension>2) {
if(std::abs(actual_Gradient[2] - GMLS_GradZ) > failure_tolerance) {
all_passed = false;
std::cout << i << " Failed GradZ by: " << std::abs(actual_Gradient[2] - GMLS_GradZ) << std::endl;
}
}
}
if(std::abs(actual_Divergence - GMLS_Divergence) > failure_tolerance) {
all_passed = false;
std::cout << i << " Failed Divergence by: " << std::abs(actual_Divergence - GMLS_Divergence) << std::endl;
}
if (order > 2) {
double tmp_diff = 0;
if (dimension>1)
tmp_diff += std::abs(actual_Curl[0] - GMLS_CurlX) + std::abs(actual_Curl[1] - GMLS_CurlY);
if (dimension>2)
tmp_diff += std::abs(actual_Curl[2] - GMLS_CurlZ);
if(std::abs(tmp_diff) > failure_tolerance) {
all_passed = false;
std::cout << i << " Failed Curl by: " << std::abs(tmp_diff) << std::endl;
}
}
}
Finalize Program
}
Kokkos::finalize();
#ifdef COMPADRE_USE_MPI
MPI_Finalize();
#endif
if(all_passed) {
fprintf(stdout, "Passed test \n");
return 0;
} else {
fprintf(stdout, "Failed test \n");
return -1;
}
}
Tutorial