OpenFPM  5.2.0
Project that contain the implementation of distributed structures
main.cpp
Go to the documentation of this file.
1 /* Benchmark: Redistance a sphere which is only known as indicator function (using OpenFPM + Algoim)
2  * Date : 21 June 2021
3  * Author : sachin
4  */
25 #include <cmath>
26 #include <iostream>
27 #include "Grid/grid_dist_id.hpp"
28 #include "data_type/aggregate.hpp"
29 #include "VCluster/VCluster.hpp"
30 #include "Vector/Vector.hpp"
31 #include "FiniteDifference/util/common.hpp"
32 #include "FiniteDifference/eq.hpp"
33 #include "FiniteDifference/FD_op.hpp"
35 
36 constexpr int SIM_DIM = 3;
37 constexpr int POLY_ORDER = 5;
38 constexpr int SIM_GRID_SIZE = 64;
39 constexpr double PI = 3.141592653589793;
40 
41 // Fields - phi, cp
43 
44 // Grid size on each dimension
45 const long int sz[SIM_DIM] = {SIM_GRID_SIZE, SIM_GRID_SIZE, SIM_GRID_SIZE};
46 const size_t szu[SIM_DIM] = {(size_t) sz[0], (size_t) sz[1], (size_t) sz[2]};
47 
48 // 2D physical domain
49 Box<SIM_DIM,double> domain({-1.5,-1.5,-1.5},{1.5,1.5,1.5});
50 
51 constexpr int x = 0;
52 constexpr int y = 1;
53 constexpr int z = 2;
54 
55 // Alias for properties on the grid
56 constexpr int phi = 0;
57 constexpr int cp = 1;
58 
59 double nb_gamma = 0.0;
60 
61 
62 constexpr int narrow_band_half_width = 8;
63 
64 typedef struct EllipseParameters{
65  double origin[3];
66  double radiusA;
67  double radiusB;
68  double radiusC;
69  double eccentricity;
71 
72 // Generate the initial +1, -1 field for a sphere/ellipsoid
73 template<const unsigned int phi_field, typename grid_type>
74 void initializeIndicatorFunc(grid_type &gd, const EllipseParams &params)
75 {
76  // Note: Since we use a Non-periodic boundary, ghost_get does not update ghost layers of sim box.
77  // Therefore we are initializing the ghost layer with non-zero values.
78  auto it = gd.getDomainGhostIterator();
79  while(it.isNext())
80  {
81  auto key = it.get();
82  Point<grid_type::dims, double> coords = gd.getPos(key);
83  double posx = coords.get(x);
84  double posy = coords.get(y);
85  double posz = coords.get(z);
86 
87  double phi_val = 1.0 - sqrt(((posx - params.origin[0])/params.radiusA)*((posx - params.origin[0])/params.radiusA) + ((posy - params.origin[1])/params.radiusB)*((posy - params.origin[1])/params.radiusB) + ((posz - params.origin[2])/params.radiusC)*((posz - params.origin[2])/params.radiusC));
88  gd.template get<phi_field>(key) = (phi_val<0)?-1.0:1.0;
89  ++it;
90  }
91 }
92 
93 // Computes the error in redistancing for a unit sphere
94 void estimateErrorInReinit(GridDist &gd, EllipseParams &params)
95 {
96  double max_phi_err = -1.0;
97  // Update the ls_phi field in ghosts
98  gd.template ghost_get<phi>(KEEP_PROPERTIES);
99 
100  auto it = gd.getDomainIterator();
101  while(it.isNext())
102  {
103  auto key = it.get();
104  Point<GridDist::dims, double> coords = gd.getPos(key);
105  double posx = coords.get(0);
106  double posy = coords.get(1);
107  double posz = coords.get(2);
108 
109  double exact_phi_val = 1.0 - sqrt(((posx - params.origin[0])/params.radiusA)*((posx - params.origin[0])/params.radiusA) + ((posy - params.origin[1])/params.radiusB)*((posy - params.origin[1])/params.radiusB) + ((posz - params.origin[2])/params.radiusC)*((posz - params.origin[2])/params.radiusC));
110 
111  double phi_err = std::abs(exact_phi_val - gd.template get<phi>(key)); // / std::abs(exact_phi);
112 
113  if(phi_err > max_phi_err)
114  max_phi_err = phi_err;
115  ++it;
116  }
117 
118  std::cout<<"Error in redistancing = "<<max_phi_err<<"\n";
119 
120  return;
121 }
122 
123 int main(int argc, char* argv[])
124 {
125  // Initialize the library
126  openfpm_init(&argc, &argv);
127  // Create VCluster
128  Vcluster<> &v_cl = create_vcluster();
129 
130  periodicity<SIM_DIM> grid_bc = {NON_PERIODIC, NON_PERIODIC, NON_PERIODIC};
131  // Ghost in grid units
132  Ghost <SIM_DIM, long int> grid_ghost(2*narrow_band_half_width);
133  GridDist gdist(szu, domain, grid_ghost, grid_bc);
134 
135  // Set property names
137  prop_names.add("ls_phi");
138  prop_names.add("closest_point");
139  gdist.setPropNames(prop_names);
140 
141  EllipseParams params;
142  params.origin[x] = 0.0;
143  params.origin[y] = 0.0;
144  params.origin[z] = 0.0;
145  params.radiusA = 1.0;
146  params.radiusB = 1.0;
147  params.radiusC = 1.0;
148 
149  initializeIndicatorFunc<phi>(gdist, params);
150  nb_gamma = narrow_band_half_width * gdist.spacing(0);
151 
152  std::cout<<"Grid spacing = "<<gdist.spacing(x)<<"\n";
153 
154  // gdist.write_frame("output", 0);
155 
156  // Estimates the closest point assuming that the local polynomial approximation
157  // of the level set phi field has the correct zero even if it is not the right SDF.
158  estimateClosestPoint<phi, cp, POLY_ORDER>(gdist, 3.0);
159 
160  // Redistance Levelset - This would try to get the SDF based on CP estimate.
161  reinitializeLS<phi, cp>(gdist, 3.0);
162 
163  // Compute the errors
164  estimateErrorInReinit(gdist, params);
165 
166  // gdist.write_frame("output", 1);
167 
168  openfpm_finalize();
169 }
170 
This class represent an N-dimensional box.
Definition: Box.hpp:60
Definition: Ghost.hpp:40
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:28
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
Definition: Point.hpp:172
Implementation of VCluster class.
Definition: VCluster.hpp:59
This is a distributed grid.
Point< dim, St > getPos(const grid_dist_key_dx< dim, bg_key > &v1)
Get the reference of the selected element.
grid_dist_iterator< dim, device_grid, decltype(device_grid::type_of_iterator()), FIXED > getDomainGhostIterator() const
It return an iterator that span the grid domain + ghost part.
grid_dist_iterator< dim, device_grid, decltype(device_grid::type_of_subiterator()), FREE > getDomainIterator() const
It return an iterator that span the full grid domain (each processor span its local domain)
Functions for level set reinitialization and extension on OpenFPM grids based on closest point method...
Boundary conditions.
Definition: common.hpp:22