7 #include <boost/test/unit_test_log.hpp>
8 #define BOOST_TEST_DYN_LINK
9 #include <boost/test/unit_test.hpp>
12 #include "Vector/vector_dist.hpp"
13 #include "DCPSE/Dcpse.hpp"
14 #include "DCPSE/MonomialBasis.hpp"
15 #include "Draw/DrawParticles.hpp"
17 #include "Operators/Vector/vector_dist_operators.hpp"
19 #include "pcp_unit_test_helpfunctions.h"
30 template<
typename particles_type,
typename iterator_type,
size_t sdf,
size_t surf_flag,
size_t ref_cp>
31 void initializeLSEllipsoid(
particles_type &vd, iterator_type particle_it,
const EllipseParams ¶ms,
double bandwidth,
double perturb_factor,
double H)
33 while(particle_it.isNext())
35 double posx = particle_it.get().get(0);
36 double posy = particle_it.get().get(1);
37 double posz = particle_it.get().get(2);
43 double dist = DistancePointEllipsoid(params.radiusA, params.radiusB, params.radiusC, abs(posx), abs(posy), abs(posz), ref_cpx, ref_cpy, ref_cpz);
44 if (abs(dist) < bandwidth/2.0)
46 posx = posx + perturb_factor*randMinusOneToOne()*H;
47 posy = posy + perturb_factor*randMinusOneToOne()*H;
48 posz = posz + perturb_factor*randMinusOneToOne()*H;
50 dist = DistancePointEllipsoid(params.radiusA, params.radiusB, params.radiusC, abs(posx), abs(posy), abs(posz), ref_cpx, ref_cpy, ref_cpz);
56 double phi_val = 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)) - 1.0;
57 vd.template getLastProp<sdf>() = phi_val;
58 vd.template getLastProp<ref_cp>()[0] = return_sign(posx)*ref_cpx;
59 vd.template getLastProp<ref_cp>()[1] = return_sign(posy)*ref_cpy;
60 vd.template getLastProp<ref_cp>()[2] = return_sign(posz)*ref_cpz;
61 vd.template getLastProp<surf_flag>() = 0;
68 BOOST_AUTO_TEST_SUITE( particle_closest_point_test )
70 BOOST_AUTO_TEST_CASE( ellipsoid )
73 constexpr
int poly_order = 4;
74 const double H = 1.0/64.0;
75 const double perturb_factor = 0.3;
78 const double bandwidth = 12.0*H;
79 const double regression_rcut_factor = 2.4;
80 const double threshold = 1e-13;
84 Box<3, double> domain({-l/2.0, -l/3.0, -l/3.0}, {l/2.0, l/3.0, l/3.0});
85 size_t sz[3] = {(size_t)(l/H + 0.5), (size_t)((2.0/3.0)*l/H + 0.5), (
size_t)((2.0/3.0)*l/H + 0.5)};
86 size_t bc[3] = {NON_PERIODIC, NON_PERIODIC, NON_PERIODIC};
89 constexpr
int sdf = 0;
91 constexpr
int normal = 2;
92 constexpr
int curvature = 3;
93 constexpr
int surf_flag = 4;
94 constexpr
int ref_cp = 5;
95 typedef vector_dist<3, double, aggregate<double, Point<3, double>,
Point<3, double>, double,
int,
Point<3, double>>>
particles;
100 particles vd(0, domain, bc, g, DEC_GRAN(512));
104 for (
int k = 0; k < 3; k++) params.origin[k] = 0.0;
105 params.radiusA = 0.75;
106 params.radiusB = 0.5;
107 params.radiusC = 0.5;
112 initializeLSEllipsoid<particles, decltype(particle_it), sdf, surf_flag, ref_cp>(vd, particle_it, params, bandwidth, perturb_factor, H);
117 rdistoptions.minter_poly_degree = poly_order;
119 rdistoptions.r_cutoff_factor = regression_rcut_factor;
120 rdistoptions.sampling_radius = 0.75*bandwidth;
121 rdistoptions.tolerance = threshold;
122 rdistoptions.write_cp = 1;
123 rdistoptions.compute_normals = 1;
124 rdistoptions.compute_curvatures = 1;
125 rdistoptions.only_narrowband = 0;
127 static constexpr
unsigned int num_coeffs = minter_lp_degree_one_num_coeffs(3, poly_order);
130 std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
131 pcprdist.run_redistancing();
132 std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
133 std::cout <<
"Time difference for pcp redistancing = " << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() <<
"[ms]" << std::endl;
139 double sdfmaxerr = 0.0;
140 double sdfmeanerr = 0.0;
142 double cpmaxerr = 0.0;
143 double normalerr = 0.0;
144 double normalmaxerr = 0.0;
145 double curvatureerr = 0.0;
146 double curvaturemaxerr = 0.0;
147 int particlecount = 0;
153 double reference_sdf = return_sign(sqrt(((pos[0] - params.origin[0])/params.radiusA)*((pos[0] - params.origin[0])/params.radiusA) + ((pos[1] - params.origin[1])/params.radiusB)*((pos[1] - params.origin[1])/params.radiusB) + ((pos[2] - params.origin[2])/params.radiusC)*((pos[2] - params.origin[2])/params.radiusC)) - 1.0)*norm(vd.
getProp<ref_cp>(a) - pos);
155 double reference_curvature;
158 sdferr = abs(vd.
getProp<sdf>(a) - reference_sdf);
159 if (sdferr > sdfmaxerr) sdfmaxerr = sdferr;
160 sdfmeanerr += sdferr;
165 if (cperr > cpmaxerr) cpmaxerr = cperr;
168 reference_normal[0] = 2*vd.
getProp<ref_cp>(a)[0]/(params.radiusA*params.radiusA);
169 reference_normal[1] = 2*vd.
getProp<ref_cp>(a)[1]/(params.radiusB*params.radiusB);
170 reference_normal[2] = 2*vd.
getProp<ref_cp>(a)[2]/(params.radiusC*params.radiusC);
171 reference_normal = return_sign(reference_sdf)*reference_normal/norm(reference_normal);
172 normalerr = norm(reference_normal - vd.
getProp<normal>(a));
173 if (normalerr > normalmaxerr) normalmaxerr = normalerr;
176 reference_curvature = (std::abs(vd.
getProp<ref_cp>(a)[0]*vd.
getProp<ref_cp>(a)[0] + vd.
getProp<ref_cp>(a)[1]*vd.
getProp<ref_cp>(a)[1] + vd.
getProp<ref_cp>(a)[2]*vd.
getProp<ref_cp>(a)[2] - params.radiusA*params.radiusA - params.radiusB*params.radiusB - params.radiusC*params.radiusC))/(params.radiusA*params.radiusA*params.radiusB*params.radiusB*params.radiusC*params.radiusC*std::pow(vd.
getProp<ref_cp>(a)[0]*vd.
getProp<ref_cp>(a)[0]/std::pow(params.radiusA, 4) + vd.
getProp<ref_cp>(a)[1]*vd.
getProp<ref_cp>(a)[1]/std::pow(params.radiusB, 4) + vd.
getProp<ref_cp>(a)[2]*vd.
getProp<ref_cp>(a)[2]/std::pow(params.radiusC, 4), 1.5));
177 curvatureerr = abs(reference_curvature - vd.
getProp<curvature>(a));
178 if (curvatureerr > curvaturemaxerr) curvaturemaxerr = curvatureerr;
182 sdfmeanerr = sdfmeanerr/particlecount;
183 std::cout<<
"Mean error for sdf is: "<<sdfmeanerr<<std::endl;
184 std::cout<<
"Maximum error for sdf is: "<<sdfmaxerr<<std::endl;
185 std::cout<<
"Maximum error for the closest point is: "<<cpmaxerr<<std::endl;
186 std::cout<<
"Maximum error for surface normal is: "<<normalmaxerr<<std::endl;
187 std::cout<<
"Maximum error for curvature is: "<<curvaturemaxerr<<std::endl;
189 double tolerance = 1e-7;
191 if (std::abs(sdfmaxerr) < tolerance)
200 BOOST_AUTO_TEST_SUITE_END()
This class represent an N-dimensional box.
static PointIterator< dim, T, typename vd_type::Decomposition_type > DrawBox(vd_type &vd, size_t(&sz)[dim], Box< dim, T > &domain, Box< dim, T > &sub)
Draw particles in a box.
This class implement the point shape in an N-dimensional space.
Class for reinitializing a level-set function into a signed distance function using the Closest-Point...
auto getProp(vect_dist_key_dx vec_key) -> decltype(vPrp.template get< id >(vec_key.getKey()))
Get the property of an element.
void setPropNames(const openfpm::vector< std::string > &names)
Set the properties names.
auto getPos(vect_dist_key_dx vec_key) -> decltype(vPos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
vector_dist_iterator getDomainIterator() const
Get an iterator that traverse the particles in the domain.
void add()
Add local particle.
auto getLastPos() -> decltype(vPos.template get< 0 >(0))
Get the position of the last element.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
Structure to bundle options for redistancing.