7#include <boost/test/unit_test_log.hpp>
9#define BOOST_TEST_DYN_LINK
10#include <boost/test/unit_test.hpp>
12#include "Grid/grid_dist_id.hpp"
13#include "data_type/aggregate.hpp"
14#include "VCluster/VCluster.hpp"
15#include "Vector/Vector.hpp"
16#include "FiniteDifference/util/common.hpp"
17#include "FiniteDifference/eq.hpp"
18#include "FiniteDifference/FD_op.hpp"
21constexpr int narrow_band_half_width = 5;
32template<
size_t phi_field,
typename gr
id_type>
40 double posx = coords.
get(0);
41 double posy = coords.
get(1);
42 double posz = coords.
get(2);
45 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));
46 gd.template get<phi_field>(key) = phi_val;
52template<const
unsigned int phi, const
unsigned int field,
typename gr
id_type>
53void initializeScalarField3D(
grid_type &gd,
double init_width)
58 double prefactor_l1 = std::sqrt(2.0/(4.0*M_PI));
64 if(gd.template get<phi>(key) < init_width)
66 auto coords = gd.
getPos(key);
67 double posx = coords.
get(0);
68 double posy = coords.
get(1);
69 double posz = coords.
get(2);
71 double theta = std::atan2(std::sqrt(posx*posx + posy*posy), posz);
73 gd.template get<field>(key) = prefactor_l1 * std::cos(theta);
81BOOST_AUTO_TEST_SUITE( closest_point_test )
84BOOST_AUTO_TEST_CASE( closest_point_unit_sphere )
87 constexpr int SIM_DIM = 3;
88 constexpr int POLY_ORDER = 5;
89 constexpr int SIM_GRID_SIZE = 128;
96 const long int sz[SIM_DIM] = {SIM_GRID_SIZE, SIM_GRID_SIZE, SIM_GRID_SIZE};
97 const size_t szu[SIM_DIM] = {(size_t) sz[0], (
size_t) sz[1], (size_t) sz[2]};
107 constexpr int phi = 0;
108 constexpr int cp = 1;
110 double nb_gamma = 0.0;
114 Ghost <SIM_DIM, long int> grid_ghost(2*narrow_band_half_width);
115 GridDist gdist(szu, domain, grid_ghost, grid_bc);
119 params.origin[x] = 0.0;
120 params.origin[y] = 0.0;
121 params.origin[z] = 0.0;
122 params.radiusA = 1.0;
123 params.radiusB = 1.0;
124 params.radiusC = 1.0;
127 nb_gamma = narrow_band_half_width * gdist.spacing(0);
130 initializeLSEllipsoid<phi>(gdist, params);
133 estimateClosestPoint<phi, cp, POLY_ORDER>(gdist, nb_gamma);
136 auto &patches = gdist.getLocalGridsInfo();
137 double max_error_cp = -1.0;
138 for(
int i = 0; i < patches.size();i++)
141 auto p_xlo = patches.get(i).Dbox.getLow(0) + patches.get(i).origin[0];
142 auto p_xhi = patches.get(i).Dbox.getHigh(0) + patches.get(i).origin[0];
143 auto p_ylo = patches.get(i).Dbox.getLow(1) + patches.get(i).origin[1];
144 auto p_yhi = patches.get(i).Dbox.getHigh(1) + patches.get(i).origin[1];
145 auto p_zlo = patches.get(i).Dbox.getLow(2) + patches.get(i).origin[2];
146 auto p_zhi = patches.get(i).Dbox.getHigh(2) + patches.get(i).origin[2];
148 auto it = gdist.getSubDomainIterator({p_xlo, p_ylo, p_zlo}, {p_xhi, p_yhi, p_zhi});
153 if(std::abs(gdist.template get<phi>(key)) < nb_gamma)
157 double cpx = gdist.template get<cp>(key)[x];
158 double cpy = gdist.template get<cp>(key)[y];
159 double cpz = gdist.template get<cp>(key)[z];
161 if(cpx == -100.0 && cpy == -100.0 && cpz == -100.0)
162 std::cout<<
"ERROR: Requesting closest point where it was not computed."<<std::endl;
165 double estim_px = domain.getLow(x) + (p_xlo - algoim_padding)*gdist.spacing(x) + cpx;
166 double estim_py = domain.getLow(y) + (p_ylo - algoim_padding)*gdist.spacing(y) + cpy;
167 double estim_pz = domain.getLow(z) + (p_zlo - algoim_padding)*gdist.spacing(z) + cpz;
171 double posx = coords.
get(0);
172 double posy = coords.
get(1);
173 double posz = coords.
get(2);
175 double norm = sqrt(posx*posx + posy*posy + posz*posz);
177 double exact_px = posx / norm;
178 double exact_py = posy / norm;
179 double exact_pz = posz / norm;
181 max_error_cp = std::max({std::abs(estim_px - exact_px), std::abs(estim_py - exact_py), std::abs(estim_pz - exact_pz), max_error_cp});
186 std::cout<<
"Unit sphere closest_point error : "<<max_error_cp<<std::endl;
187 double tolerance = 1e-5;
189 if (std::abs(max_error_cp) < tolerance)
198BOOST_AUTO_TEST_CASE( reinitialization_unit_sphere )
201 constexpr int SIM_DIM = 3;
202 constexpr int POLY_ORDER = 5;
203 constexpr int SIM_GRID_SIZE = 128;
210 const long int sz[SIM_DIM] = {SIM_GRID_SIZE, SIM_GRID_SIZE, SIM_GRID_SIZE};
211 const size_t szu[SIM_DIM] = {(size_t) sz[0], (
size_t) sz[1], (size_t) sz[2]};
221 constexpr int phi = 0;
222 constexpr int cp = 1;
224 double nb_gamma = 0.0;
228 Ghost <SIM_DIM, long int> grid_ghost(2*narrow_band_half_width);
229 GridDist gdist(szu, domain, grid_ghost, grid_bc);
232 params.origin[x] = 0.0;
233 params.origin[y] = 0.0;
234 params.origin[z] = 0.0;
235 params.radiusA = 1.0;
236 params.radiusB = 1.0;
237 params.radiusC = 1.0;
239 nb_gamma = narrow_band_half_width * gdist.spacing(0);
241 initializeLSEllipsoid<phi>(gdist, params);
243 estimateClosestPoint<phi, cp, POLY_ORDER>(gdist, nb_gamma);
246 reinitializeLS<phi, cp>(gdist, nb_gamma);
249 auto &patches = gdist.getLocalGridsInfo();
250 double max_error = -1.0;
251 for(
int i = 0; i < patches.size();i++)
253 auto p_xlo = patches.get(i).Dbox.getLow(0) + patches.get(i).origin[0];
254 auto p_xhi = patches.get(i).Dbox.getHigh(0) + patches.get(i).origin[0];
255 auto p_ylo = patches.get(i).Dbox.getLow(1) + patches.get(i).origin[1];
256 auto p_yhi = patches.get(i).Dbox.getHigh(1) + patches.get(i).origin[1];
257 auto p_zlo = patches.get(i).Dbox.getLow(2) + patches.get(i).origin[2];
258 auto p_zhi = patches.get(i).Dbox.getHigh(2) + patches.get(i).origin[2];
260 auto it = gdist.getSubDomainIterator({p_xlo, p_ylo, p_zlo}, {p_xhi, p_yhi, p_zhi});
265 if(std::abs(gdist.template get<phi>(key)) < nb_gamma)
269 double posx = coords.
get(0);
270 double posy = coords.
get(1);
271 double posz = coords.
get(2);
275 double distance = 1.0 - sqrt(posx*posx + posy*posy + posz*posz);
277 max_error = std::max({std::abs(distance - gdist.template get<phi>(key)), max_error});
282 std::cout<<
"Reinitialization error : "<<max_error<<std::endl;
283 double tolerance = 1e-5;
285 if (std::abs(max_error) < tolerance)
295BOOST_AUTO_TEST_CASE( extension_unit_sphere )
298 constexpr int SIM_DIM = 3;
299 constexpr int POLY_ORDER = 5;
300 constexpr int SIM_GRID_SIZE = 128;
307 const long int sz[SIM_DIM] = {SIM_GRID_SIZE, SIM_GRID_SIZE, SIM_GRID_SIZE};
308 const size_t szu[SIM_DIM] = {(size_t) sz[0], (
size_t) sz[1], (size_t) sz[2]};
318 constexpr int phi = 0;
319 constexpr int cp = 1;
320 constexpr int scalar_field = 2;
321 constexpr int scalar_field_temp = 3;
323 double nb_gamma = 0.0;
327 Ghost <SIM_DIM, long int> grid_ghost(2*narrow_band_half_width);
328 GridDist gdist(szu, domain, grid_ghost, grid_bc);
331 params.origin[x] = 0.0;
332 params.origin[y] = 0.0;
333 params.origin[z] = 0.0;
334 params.radiusA = 1.0;
335 params.radiusB = 1.0;
336 params.radiusC = 1.0;
338 nb_gamma = narrow_band_half_width * gdist.spacing(0);
340 initializeLSEllipsoid<phi>(gdist, params);
342 estimateClosestPoint<phi, cp, POLY_ORDER>(gdist, nb_gamma);
345 reinitializeLS<phi, cp>(gdist, nb_gamma);
348 initializeScalarField3D<phi,scalar_field>(gdist, 4*gdist.spacing(0));
351 extendLSField<phi, cp, scalar_field, scalar_field_temp, -1>(gdist, nb_gamma);
352 double prefactor_l1 = std::sqrt(2.0/(4.0*M_PI));
355 auto &patches = gdist.getLocalGridsInfo();
356 double max_error = -1.0;
357 for(
int i = 0; i < patches.size();i++)
359 auto p_xlo = patches.get(i).Dbox.getLow(0) + patches.get(i).origin[0];
360 auto p_xhi = patches.get(i).Dbox.getHigh(0) + patches.get(i).origin[0];
361 auto p_ylo = patches.get(i).Dbox.getLow(1) + patches.get(i).origin[1];
362 auto p_yhi = patches.get(i).Dbox.getHigh(1) + patches.get(i).origin[1];
363 auto p_zlo = patches.get(i).Dbox.getLow(2) + patches.get(i).origin[2];
364 auto p_zhi = patches.get(i).Dbox.getHigh(2) + patches.get(i).origin[2];
366 auto it = gdist.getSubDomainIterator({p_xlo, p_ylo, p_zlo}, {p_xhi, p_yhi, p_zhi});
371 if(std::abs(gdist.template get<phi>(key)) < nb_gamma)
374 auto coords = gdist.getPos(key);
375 double posx = coords.
get(0);
376 double posy = coords.
get(1);
377 double posz = coords.
get(2);
379 double theta = std::atan2(std::sqrt(posx*posx + posy*posy), posz);
382 double exact_val = prefactor_l1 * std::cos(theta);
384 max_error = std::max({std::abs(exact_val - gdist.template get<scalar_field>(key)), max_error});
389 std::cout<<
"Extension error : "<<max_error<<std::endl;
390 double tolerance = 1e-5;
392 if (std::abs(max_error) < tolerance)
401BOOST_AUTO_TEST_SUITE_END()
This class represent an N-dimensional box.
This class implement the point shape in an N-dimensional space.
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
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_subiterator()), FREE > getDomainIterator() const
It return an iterator that span the full grid domain (each processor span its local domain)
Grid key for a distributed grid.
Functions for level set reinitialization and extension on OpenFPM grids based on closest point method...
void extendLSField(grid_type &gd, const double nb_gamma)
Extends a (scalar) field to within nb_gamma from interface. The grid should have level set SDF and cl...