OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
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
36constexpr int SIM_DIM = 3;
37constexpr int POLY_ORDER = 5;
38constexpr int SIM_GRID_SIZE = 64;
39constexpr double PI = 3.141592653589793;
40
41// Fields - phi, cp
43
44// Grid size on each dimension
45const long int sz[SIM_DIM] = {SIM_GRID_SIZE, SIM_GRID_SIZE, SIM_GRID_SIZE};
46const size_t szu[SIM_DIM] = {(size_t) sz[0], (size_t) sz[1], (size_t) sz[2]};
47
48// 2D physical domain
49Box<SIM_DIM,double> domain({-1.5,-1.5,-1.5},{1.5,1.5,1.5});
50
51constexpr int x = 0;
52constexpr int y = 1;
53constexpr int z = 2;
54
55// Alias for properties on the grid
56constexpr int phi = 0;
57constexpr int cp = 1;
58
59double nb_gamma = 0.0;
60
61
62constexpr int narrow_band_half_width = 8;
63
64typedef 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
73template<const unsigned int phi_field, typename grid_type>
74void 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();
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
94void 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
123int 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
136 openfpm::vector < std::string > prop_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, POLY_ORDER>(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:61
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.
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.
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_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