8 double GetRoot (
double r0,
double z0,
double z1,
double g)
10 const int maxIter = 100;
13 double s1 = ( g < 0 ? 0 : sqrt(n0*n0+z1*z1) - 1 ) ;
15 for (
int i = 0; i < maxIter; ++i ){
16 if (i == (maxIter - 1)) std::cout<<
"distance point ellipse algorithm did not converge."<<std::endl;
18 if ( s == s0 || s == s1 ) {
break; }
19 double ratio0 = n0 /( s + r0 );
20 double ratio1 = z1 /( s + 1 );
21 g = ratio0*ratio0 + ratio1*ratio1 - 1 ;
22 if (g > 0) {s0 = s;}
else if (g < 0) {s1 = s ;}
else {break ;}
27 double GetRoot(
double r0,
double r1,
double z0,
double z1,
double z2,
double g)
29 const int maxIter = 100;
33 double s1 = (g < 0 ? 0 : sqrt(n0*n0 + n1*n1 + z2*z2) - 1) ;
35 for(
int i = 0 ; i < maxIter ; ++i )
37 if (i == (maxIter - 1)) std::cout<<
"distance point ellipse algorithm did not converge."<<std::endl;
39 if ( s == s0 || s == s1 ) {
break; }
40 double ratio0 = n0 / ( s + r0 );
41 double ratio1 = n1 / ( s + r1 );
42 double ratio2 = z2 / ( s + 1 );
43 g = ratio0*ratio0 + ratio1*ratio1 +ratio2*ratio2 - 1;
44 if ( g > 0 ) { s0 = s ;}
45 else if ( g < 0 ) { s1 = s ; }
51 double DistancePointEllipse(
double e0,
double e1,
double y0,
double y1,
double& x0,
double& x1)
58 double g = z0*z0+z1*z1 - 1;
60 double r0 = (e0/e1)*(e0/e1);
61 double sbar = GetRoot(r0 , z0 , z1 , g);
62 x0 = r0 * y0 /( sbar + r0 );
63 x1 = y1 /( sbar + 1 );
64 distance = sqrt( (x0-y0)*(x0-y0) + (x1-y1)*(x1-y1) );
72 {x0 = 0 ; x1 = e1 ; distance = abs( y1 - e1 );}
74 double numer0 = e0*y0 , denom0 = e0*e0 - e1*e1;
75 if ( numer0 < denom0 ){
76 double xde0 = numer0/denom0;
77 x0 = e0*xde0 ; x1 = e1*sqrt(1 - xde0*xde0 );
78 distance = sqrt( (x0-y0)*(x0-y0) + x1*x1 );
82 distance = abs( y0 - e0 );
88 double DistancePointEllipsoid(
double e0,
double e1,
double e2,
double y0,
double y1,
double y2,
double& x0,
double& x1,
double& x2)
100 double g = z0*z0 + z1*z1 + z2*z2 - 1 ;
103 double r0 = (e0/e2)*(e0/e2);
104 double r1 = (e1/e2)*(e1/e2);
105 double sbar = GetRoot ( r0 , r1 , z0 , z1 , z2 , g );
106 x0 = r0 *y0 / ( sbar + r0 );
107 x1 = r1 *y1 / ( sbar + r1 );
108 x2 = y2 / ( sbar + 1 );
109 distance = sqrt( (x0 - y0)*(x0 - y0) + (x1 - y1)*(x1 - y1) + (x2 - y2)*(x2 - y2));
122 distance = DistancePointEllipse( e1 , e2 , y1 , y2, x1, x2);
130 distance = DistancePointEllipse( e0 , e2 , y0 , y2, x0, x2);
137 distance = abs(y2 - e2);
143 double denom0 = e0*e0 - e2*e2;
144 double denom1 = e1*e1 - e2*e2;
145 double numer0 = e0*y0;
146 double numer1 = e1*y1;
147 bool computed =
false;
148 if((numer0 < denom0) && (numer1 < denom1))
150 double xde0 = numer0/denom0;
151 double xde1 = numer1/denom1 ;
152 double xde0sqr = xde0 *xde0;
153 double xde1sqr = xde1 * xde1 ;
154 double discr = 1 - xde0sqr - xde1sqr;
160 distance = sqrt((x0 - y0)*(x0 - y0) + (x1 - y1)*(x1 - y1) + x2*x2);
167 distance = DistancePointEllipse(e0 , e1 , y0 , y1, x0, x1);
173 constexpr
unsigned int factorial(
unsigned int x)
175 unsigned int fact = 1;
176 for(
int i = 1; i < (x + 1); i++) fact = fact*i;
179 constexpr
unsigned int minter_lp_degree_one_num_coeffs(
unsigned int dims,
unsigned int poly_degree)
181 return(factorial(dims + poly_degree)/(factorial(dims)*factorial(poly_degree)));
184 int return_sign(
double phi)
186 if (phi > 0)
return 1;
187 if (phi < 0)
return -1;
191 double randMinusOneToOne()
193 double temp = rand() / (RAND_MAX + 1.0);
195 return(2.0*temp - 1.0);
198 template <
typename particles_type>
inline void perturb_pos(
particles_type & vd,
double dp,
double factor)
207 for (
int k = 0; k<dim; k++)
209 vd.
getPos(a)[k] += factor*randMinusOneToOne()*dp;
218 template <
typename particles_type,
int sdf,
int sdf_analytical,
int cp_theoretical>
inline void update_sdfs(
particles_type & vd,
double A,
double B,
double C)
222 while (part.isNext())
228 vd.template getProp<sdf>(a) = - 1.0 + sqrt((xa[0]/A)*(xa[0]/A) + (xa[1]/B)*(xa[1]/B));
230 double xcp_analytical;
231 double ycp_analytical;
232 vd.template getProp<sdf_analytical>(a) = return_sign(vd.template getProp<sdf>(a))*DistancePointEllipse(A, B, abs(xa[0]), abs(xa[1]), xcp_analytical, ycp_analytical);
235 vd.template getProp<cp_theoretical>(a)[0] = return_sign(xa[0])*xcp_analytical;
236 vd.template getProp<cp_theoretical>(a)[1] = return_sign(xa[1])*ycp_analytical;
240 vd.template getProp<sdf>(a) = 1.0 - sqrt(pow(xa[0]/A, 2.0) + pow(xa[1]/B, 2.0) + pow(xa[2]/C, 2.0));
241 double xcp_analytical;
242 double ycp_analytical;
243 double zcp_analytical;
244 vd.template getProp<sdf_analytical>(a) = return_sign(vd.template getProp<sdf>(a))*DistancePointEllipsoid(A, B, C, abs(xa[0]), abs(xa[1]), abs(xa[2]), xcp_analytical, ycp_analytical, zcp_analytical);
245 vd.template getProp<cp_theoretical>(a)[0] = return_sign(xa[0])*xcp_analytical;
246 vd.template getProp<cp_theoretical>(a)[1] = return_sign(xa[1])*ycp_analytical;
247 vd.template getProp<cp_theoretical>(a)[2] = return_sign(xa[2])*zcp_analytical;
259 template <
typename discretization_type,
int sdf,
int sdf_analytical>
inline void get_interpol_error(discretization_type & vd,
double narrow_band_half_width,
double A,
double B,
double C)
261 static constexpr
int dim = discretization_type::dims;
262 auto part = vd.getDomainIterator();
265 double cumerror = 0.0;
271 if (abs(vd.template getProp<sdf_analytical>(a)) > narrow_band_half_width)
276 if (dim == 2) err = abs(vd.template getProp<sdf>(a) - (1.0 - sqrt((xa[0]/A)*(xa[0]/A) + (xa[1]/B)*(xa[1]/B))));
277 else if (dim == 3) err = abs(vd.template getProp<sdf>(a) - (1.0 - sqrt((xa[0]/A)*(xa[0]/A) + (xa[1]/B)*(xa[1]/B) + (xa[2]/C)*(xa[2]/C))));
279 if (err > maxerr) maxerr = err;
285 printf(
"%f, ",maxerr);
289 template <
typename discretization_type,
int sdf,
int sdfgrad,
int curvature,
int cp,
int sdf_analytical,
int cp_theoretical>
inline void get_max_error(discretization_type & vd,
double narrow_band_half_width,
double A,
double B,
double C)
291 static constexpr
int dim = discretization_type::dims;
292 auto part = vd.getDomainIterator();
296 double maxerrkappa = 0.0;
298 double maxerrnorm = 0.0;
300 double maxerrcp = 0.0;
302 double maxerrone = 0.0;
304 double avgsdferr = 0.0;
314 if (abs(vd.template getProp<sdf_analytical>(a)) > narrow_band_half_width)
321 for (
int k = 0; k < dim; k++) norm_computed[k] = vd.template getProp<sdfgrad>(a)[k];
324 for (
int k = 0; k < dim; k++)
326 cp_computed[k] = vd.template getProp<cp>(a)[k];
327 cp_theo[k] = vd.template getProp<cp_theoretical>(a)[k];
329 err = abs(vd.template getProp<sdf>(a) - vd.template getProp<sdf_analytical>(a));
330 if (vd.template getProp<4>(a))
335 errcp = norm(cp_computed - cp_theo);
339 norm_analytical[0] = 2*cp_theo[0]/(A*A);
340 norm_analytical[1] = 2*cp_theo[1]/(B*B);
341 double norm_norm_analytical = norm(norm_analytical);
342 for(
int k = 0; k < dim; k++) norm_analytical[k] = return_sign(vd.template getProp<sdf>(a))*norm_analytical[k]/norm_norm_analytical;
343 errnorm = norm(norm_analytical - norm_computed);
345 kappa = A*B/std::pow(B/A*B/A*cp_theo[0]*cp_theo[0] + A/B*A/B*cp_theo[1]*cp_theo[1], 1.5);
349 norm_analytical[0] = -2*cp_theo[0]/(A*A);
350 norm_analytical[1] = -2*cp_theo[1]/(B*B);
351 norm_analytical[2] = -2*cp_theo[2]/(C*C);
352 double norm_norm_analytical = norm(norm_analytical);
353 for(
int k = 0; k < dim; k++) norm_analytical[k] = return_sign(vd.template getProp<sdf>(a))*norm_analytical[k]/norm_norm_analytical;
355 errnorm = norm(norm_analytical - norm_computed);
357 kappa = -(std::abs(cp_theo[0]*cp_theo[0] + cp_theo[1]*cp_theo[1] + cp_theo[2]*cp_theo[2] - A*A - B*B - C*C))/(2*A*A*B*B*C*C*std::pow(cp_theo[0]*cp_theo[0]/std::pow(A, 4) + cp_theo[1]*cp_theo[1]/std::pow(B, 4) + cp_theo[2]*cp_theo[2]/std::pow(C, 4), 1.5));
359 errkappa = abs(vd.template getProp<curvature>(a) - kappa);
360 if (err > maxerr) maxerr = err;
361 if (errkappa > maxerrkappa) maxerrkappa = errkappa;
362 if (errnorm > maxerrnorm) maxerrnorm = errnorm;
363 if (errcp > maxerrcp) maxerrcp = errcp;
366 std::cout<<
"Average error for sdf in narrow band is: "<<avgsdferr/county<<std::endl;
367 std::cout<<
"Maximum error for sdf on processor is: "<<maxerr<<std::endl;
368 std::cout<<
"Maximum error for surface normal on processor is: "<<maxerrnorm<<std::endl;
369 std::cout<<
"Maximum error for curvature on processor is: "<<maxerrkappa<<std::endl;
370 std::cout<<
"Maximum error for cp(xa) is: "<<maxerrcp<<std::endl;
This class implement the point shape in an N-dimensional space.
static const unsigned int dims
template parameters typedefs
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.