10 #define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
11 #define BOOST_MPL_LIMIT_VECTOR_SIZE 40
13 #define BOOST_TEST_DYN_LINK
15 #include "util/util_debug.hpp"
16 #include <boost/test/unit_test.hpp>
18 #include "../DCPSE_surface_op.hpp"
19 #include "../DCPSE_Solver.hpp"
20 #include "../../DcpseInterpolation.hpp"
21 #include "Operators/Vector/vector_dist_operators.hpp"
24 #include "util/SphericalHarmonics.hpp"
25 #include "Vector/vector_dist_multiphase_functions.hpp"
27 BOOST_AUTO_TEST_SUITE(dcpse_op_suite_tests)
28 BOOST_AUTO_TEST_CASE(dcpse_surface_simple) {
29 double boxP1{-1.5}, boxP2{1.5};
30 double boxSize{boxP2 - boxP1};
33 double grid_spacing{boxSize/(sz[0]-1)};
34 double rCut{3.9 * grid_spacing};
37 size_t bc[2] = {NON_PERIODIC,NON_PERIODIC};
39 auto &v_cl=create_vcluster();
43 BOOST_TEST_MESSAGE(
"Init domain...");
46 if (v_cl.rank() == 0) {
47 for (
int i = 0; i < n; ++i) {
48 double xp = -1.5+i*grid_spacing;
50 Sparticles.getLastPos()[0] = xp;
51 Sparticles.getLastPos()[1] = 0;
52 Sparticles.getLastProp<3>() = std::sin(xp);
53 Sparticles.getLastProp<2>()[0] = 0;
54 Sparticles.getLastProp<2>()[1] = 1.0;
55 Sparticles.getLastProp<1>() = -std::sin(xp);
56 Sparticles.getLastSubset(0);
61 BOOST_TEST_MESSAGE(
"Sync domain across processors...");
63 Sparticles.ghost_get<0,3>();
66 auto verletList = Sparticles.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
68 SurfaceDerivative_xx<2,decltype(verletList)> SDxx(Sparticles, verletList, 2, rCut, grid_spacing,
static_cast<unsigned int>(rCut/grid_spacing));
69 SurfaceDerivative_yy<2,decltype(verletList)> SDyy(Sparticles, verletList, 2, rCut, grid_spacing,
static_cast<unsigned int>(rCut/grid_spacing));
72 auto INICONC = getV<3>(Sparticles);
73 auto CONC = getV<0>(Sparticles);
74 auto TEMP = getV<4>(Sparticles);
75 auto normal = getV<2>(Sparticles);
77 CONC=SDxx(INICONC)+SDyy(INICONC);
82 auto it2 = Sparticles.getDomainIterator();
84 while (it2.isNext()) {
86 if (fabs(Sparticles.getProp<1>(p) - Sparticles.getProp<0>(p)) > worst) {
87 worst = fabs(Sparticles.getProp<1>(p) - Sparticles.getProp<0>(p));
92 Sparticles.deleteGhost();
95 BOOST_REQUIRE(worst < 0.03);
97 BOOST_AUTO_TEST_CASE(dcpse_surface_circle) {
99 double boxP1{-1.5}, boxP2{1.5};
100 double boxSize{boxP2 - boxP1};
102 auto &v_cl=create_vcluster();
105 size_t sz[2] = {n,n};
106 double grid_spacing{boxSize/(sz[0]-1)};
107 double rCut{5.1 * grid_spacing};
110 size_t bc[2] = {NON_PERIODIC,NON_PERIODIC};
112 vector_dist_ws<2, double, aggregate<double,double,double[2],double,double[2],double>> Sparticles(0, domain,bc,ghost);
114 BOOST_TEST_MESSAGE(
"Init domain...");
117 const double radius{1.0};
118 std::array<double,2> center{0.0,0.0};
120 const double pi{3.14159265358979323846};
124 double dtheta{2*pi/double(n)};
125 if (v_cl.rank() == 0) {
126 for (
int i = 0; i < n; ++i) {
127 coord[0] = center[0] + radius * std::cos(theta);
128 coord[1] = center[1] + radius * std::sin(theta);
130 Sparticles.getLastPos()[0] = coord[0];
131 Sparticles.getLastPos()[1] = coord[1];
132 Sparticles.getLastProp<3>() = std::sin(theta);
133 Sparticles.getLastProp<2>()[0] = std::cos(theta);
134 Sparticles.getLastProp<2>()[1] = std::sin(theta);
135 Sparticles.getLastProp<1>() = -std::sin(theta);;
136 Sparticles.getLastSubset(0);
142 BOOST_TEST_MESSAGE(
"Sync domain across processors...");
144 Sparticles.ghost_get<0,3>();
145 Sparticles.ghost_get_subset();
148 auto verletList = Sparticles.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
150 SurfaceDerivative_xx<2,decltype(verletList)> SDxx(Sparticles, verletList, 2, rCut, grid_spacing,
static_cast<unsigned int>(rCut/grid_spacing));
151 SurfaceDerivative_yy<2,decltype(verletList)> SDyy(Sparticles, verletList, 2, rCut, grid_spacing,
static_cast<unsigned int>(rCut/grid_spacing));
155 auto INICONC = getV<3>(Sparticles);
156 auto CONC = getV<0>(Sparticles);
157 auto TEMP = getV<4>(Sparticles);
158 auto normal = getV<2>(Sparticles);
160 CONC=SDxx(INICONC)+SDyy(INICONC);
169 auto it2 = Sparticles.getDomainIterator();
171 while (it2.isNext()) {
173 Sparticles.getProp<5>(p) = fabs(Sparticles.getProp<1>(p) - Sparticles.getProp<0>(p));
174 if (fabs(Sparticles.getProp<1>(p) - Sparticles.getProp<0>(p)) > worst) {
175 worst = fabs(Sparticles.getProp<1>(p) - Sparticles.getProp<0>(p));
179 Sparticles.deleteGhost();
182 BOOST_REQUIRE(worst < 0.03);
184 BOOST_AUTO_TEST_CASE(dcpse_surface_solver_circle) {
185 double boxP1{-1.5}, boxP2{1.5};
186 double boxSize{boxP2 - boxP1};
188 auto &v_cl=create_vcluster();
195 size_t sz[2] = {n,n};
196 double grid_spacing{boxSize/(sz[0]-1)};
197 double rCut{3.9 * grid_spacing};
200 size_t bc[2] = {NON_PERIODIC,NON_PERIODIC};
202 vector_dist_ws<2, double, aggregate<double,double,double[2],double,double[2],double>> Sparticles(0, domain,bc,ghost);
204 BOOST_TEST_MESSAGE(
"Init domain...");
207 const double radius{1.0};
208 std::array<double,2> center{0.0,0.0};
210 const double pi{3.14159265358979323846};
214 double dtheta{2*pi/double(n)};
215 if (v_cl.rank() == 0) {
216 for (
int i = 0; i < n; ++i) {
217 coord[0] = center[0] + radius * std::cos(theta);
218 coord[1] = center[1] + radius * std::sin(theta);
220 Sparticles.getLastPos()[0] = coord[0];
221 Sparticles.getLastPos()[1] = coord[1];
222 Sparticles.getLastProp<3>() = -openfpm::math::intpowlog(k,2)*std::sin(k*theta);
223 Sparticles.getLastProp<2>()[0] = std::cos(theta);
224 Sparticles.getLastProp<2>()[1] = std::sin(theta);
225 Sparticles.getLastProp<1>() = std::sin(k*theta);;
226 Sparticles.getLastSubset(0);
227 if(coord[0]==1. && coord[1]==0.)
228 {Sparticles.getLastSubset(1);}
234 BOOST_TEST_MESSAGE(
"Sync domain across processors...");
236 Sparticles.ghost_get<0>();
240 auto & bulk=Sparticles_bulk.getIds();
241 auto & boundary=Sparticles_boundary.getIds();
243 auto verletList = Sparticles.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
245 SurfaceDerivative_xx<2,decltype(verletList)> SDxx(Sparticles, verletList, 2, rCut, grid_spacing,
static_cast<unsigned int>(rCut/grid_spacing));
246 SurfaceDerivative_yy<2,decltype(verletList)> SDyy(Sparticles, verletList, 2, rCut, grid_spacing,
static_cast<unsigned int>(rCut/grid_spacing));
247 auto INICONC = getV<3>(Sparticles);
248 auto CONC = getV<0>(Sparticles);
249 auto TEMP = getV<4>(Sparticles);
250 auto normal = getV<2>(Sparticles);
251 auto ANASOL = getV<1>(Sparticles);
252 DCPSE_scheme<
equations2d1,decltype(Sparticles)> Solver(Sparticles);
253 Solver.impose(SDxx(CONC)+SDyy(CONC), bulk, INICONC);
254 Solver.impose(CONC, boundary, ANASOL);
256 auto it2 = Sparticles.getDomainIterator();
258 while (it2.isNext()) {
260 Sparticles.getProp<5>(p) = fabs(Sparticles.getProp<1>(p) - Sparticles.getProp<0>(p));
261 if (fabs(Sparticles.getProp<1>(p) - Sparticles.getProp<0>(p)) > worst) {
262 worst = fabs(Sparticles.getProp<1>(p) - Sparticles.getProp<0>(p));
266 Sparticles.deleteGhost();
269 BOOST_REQUIRE(worst < 0.03);
272 BOOST_AUTO_TEST_CASE(dcpse_surface_sphere_copy) {
273 auto & v_cl = create_vcluster();
279 double boxP1{-1.5}, boxP2{1.5};
280 double boxSize{boxP2 - boxP1};
281 size_t sz[3] = {n,n,n};
282 double grid_spacing{boxSize/(sz[0]-1)};
283 double grid_spacing_surf=std::sqrt(4.0*M_PI/n);
284 double rCut{2.5 * grid_spacing_surf};
286 Box<3,double> domain{{boxP1,boxP1,boxP1},{boxP2,boxP2,boxP2}};
287 size_t bc[3] = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
292 vector_dist_ws<3, double, aggregate<double,double,double[3],double,double[3],double>> Sparticles(0, domain,bc,ghost);
294 double Golden_angle=M_PI * (3.0 - sqrt(5.0));
295 if (v_cl.rank() == 0) {
298 for(
int i=1;i<n_sp;i++)
300 double y = 1.0 - (i /double(n_sp - 1.0)) * 2.0;
301 double radius = sqrt(1 - y * y);
302 double Golden_theta = Golden_angle * i;
303 double x = cos(Golden_theta) * radius;
304 double z = sin(Golden_theta) * radius;
306 Sparticles.getLastPos()[0] = x;
307 Sparticles.getLastPos()[1] = y;
308 Sparticles.getLastPos()[2] = z;
309 double rm=sqrt(x*x+y*y+z*z);
310 Sparticles.getLastProp<2>()[0] = x/rm;
311 Sparticles.getLastProp<2>()[1] = y/rm;
312 Sparticles.getLastProp<2>()[2] = z/rm;
313 Sparticles.getLastProp<4>()[0] = 1.0 ;
314 Sparticles.getLastProp<4>()[1] = std::atan2(sqrt(x*x+y*y),z);
315 Sparticles.getLastProp<4>()[2] = std::atan2(y,x);
317 {Sparticles.getLastSubset(1);}
319 {Sparticles.getLastSubset(0);}
325 Sparticles.ghost_get<3>();
329 auto &bulkIds=Sparticles_bulk.getIds();
330 auto &bdrIds=Sparticles_boundary.getIds();
331 std::unordered_map<const lm,double,key_hash,key_equal> Alm;
334 for(
int l=0;l<=K;l++){
335 for(
int m=-l;m<=l;m++){
336 Alm[std::make_tuple(l,m)]=0;
339 Alm[std::make_tuple(1,0)]=1;
340 auto it2 = Sparticles.getDomainIterator();
341 while (it2.isNext()) {
350 Sparticles.getProp<3>(p)=openfpm::math::sumY_Scalar<K>(xP[0],xP[1],xP[2],Alm);
351 Sparticles.getProp<1>(p)=2.0;
354 auto f=getV<2>(Sparticles);
355 auto Df=getV<0>(Sparticles);
357 auto verletList = Sparticles.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
359 SurfaceDerivative_x<2,decltype(verletList)> Sdx{Sparticles,verletList,2,rCut,grid_spacing_surf,
static_cast<unsigned int>(rCut/grid_spacing_surf)};
360 SurfaceDerivative_y<2,decltype(verletList)> Sdy{Sparticles,verletList,2,rCut,grid_spacing_surf,
static_cast<unsigned int>(rCut/grid_spacing_surf)};
361 SurfaceDerivative_z<2,decltype(verletList)> Sdz{Sparticles,verletList,2,rCut,grid_spacing_surf,
static_cast<unsigned int>(rCut/grid_spacing_surf)};
372 Sparticles.ghost_get<3>();
373 Df=(Sdx(f[0])+Sdy(f[1])+Sdz(f[2]));
375 auto it3 = Sparticles.getDomainIterator();
377 while (it3.isNext()) {
380 if (fabs(Sparticles.getProp<1>(p) - Sparticles.getProp<0>(p)) > worst) {
381 worst = fabs(Sparticles.getProp<1>(p) - Sparticles.getProp<0>(p));
385 Sparticles.deleteGhost();
388 BOOST_REQUIRE(worst < 0.03);
390 BOOST_AUTO_TEST_CASE(dcpse_surface_sphere) {
391 auto & v_cl = create_vcluster();
397 double boxP1{-1.5}, boxP2{1.5};
398 double boxSize{boxP2 - boxP1};
399 size_t sz[3] = {n,n,n};
400 double grid_spacing{boxSize/(sz[0]-1)};
401 double grid_spacing_surf=std::sqrt(4.0*M_PI/n);
402 double rCut{2.5 * grid_spacing_surf};
404 Box<3,double> domain{{boxP1,boxP1,boxP1},{boxP2,boxP2,boxP2}};
405 size_t bc[3] = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
410 vector_dist_ws<3, double, aggregate<double,double,double[3],double,double[3],double>> Sparticles(0, domain,bc,ghost);
412 double Golden_angle=M_PI * (3.0 - sqrt(5.0));
413 if (v_cl.rank() == 0) {
416 for(
int i=1;i<n_sp;i++)
418 double y = 1.0 - (i /double(n_sp - 1.0)) * 2.0;
419 double radius = sqrt(1 - y * y);
420 double Golden_theta = Golden_angle * i;
421 double x = cos(Golden_theta) * radius;
422 double z = sin(Golden_theta) * radius;
424 Sparticles.getLastPos()[0] = x;
425 Sparticles.getLastPos()[1] = y;
426 Sparticles.getLastPos()[2] = z;
427 double rm=sqrt(x*x+y*y+z*z);
428 Sparticles.getLastProp<2>()[0] = x/rm;
429 Sparticles.getLastProp<2>()[1] = y/rm;
430 Sparticles.getLastProp<2>()[2] = z/rm;
431 Sparticles.getLastProp<4>()[0] = 1.0 ;
432 Sparticles.getLastProp<4>()[1] = std::atan2(sqrt(x*x+y*y),z);
433 Sparticles.getLastProp<4>()[2] = std::atan2(y,x);
435 {Sparticles.getLastSubset(1);}
437 {Sparticles.getLastSubset(0);}
443 Sparticles.ghost_get<3>();
447 auto &bulkIds=Sparticles_bulk.getIds();
448 auto &bdrIds=Sparticles_boundary.getIds();
449 std::unordered_map<const lm,double,key_hash,key_equal> Alm;
452 for(
int l=0;l<=K;l++){
453 for(
int m=-l;m<=l;m++){
454 Alm[std::make_tuple(l,m)]=0;
457 Alm[std::make_tuple(1,0)]=1;
458 auto it2 = Sparticles.getDomainIterator();
459 while (it2.isNext()) {
468 Sparticles.getProp<3>(p)=openfpm::math::sumY_Scalar<K>(xP[0],xP[1],xP[2],Alm);
469 Sparticles.getProp<1>(p)=-(K)*(K+1)*openfpm::math::sumY_Scalar<K>(xP[0],xP[1],xP[2],Alm);
472 auto f=getV<3>(Sparticles);
473 auto Df=getV<0>(Sparticles);
475 auto verletList = Sparticles.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
477 SurfaceDerivative_xx<2,decltype(verletList)> Sdxx{Sparticles,verletList,2,rCut,grid_spacing_surf,
static_cast<unsigned int>(rCut/grid_spacing_surf)};
478 SurfaceDerivative_yy<2,decltype(verletList)> Sdyy{Sparticles,verletList,2,rCut,grid_spacing_surf,
static_cast<unsigned int>(rCut/grid_spacing_surf)};
479 SurfaceDerivative_zz<2,decltype(verletList)> Sdzz{Sparticles,verletList,2,rCut,grid_spacing_surf,
static_cast<unsigned int>(rCut/grid_spacing_surf)};
490 Sparticles.ghost_get<3>();
491 Df=(Sdxx(f)+Sdyy(f)+Sdzz(f));
493 auto it3 = Sparticles.getDomainIterator();
495 while (it3.isNext()) {
498 if (fabs(Sparticles.getProp<1>(p) - Sparticles.getProp<0>(p)) > worst) {
499 worst = fabs(Sparticles.getProp<1>(p) - Sparticles.getProp<0>(p));
503 Sparticles.deleteGhost();
506 BOOST_REQUIRE(worst < 0.03);
510 BOOST_AUTO_TEST_CASE(dcpse_surface_sphere_old) {
511 auto & v_cl = create_vcluster();
517 double boxP1{-1.5}, boxP2{1.5};
518 double boxSize{boxP2 - boxP1};
519 size_t sz[3] = {n,n,n};
520 double grid_spacing{boxSize/(sz[0]-1)};
521 double grid_spacing_surf=grid_spacing*30;
522 double rCut{2.5 * grid_spacing_surf};
524 Box<3,double> domain{{boxP1,boxP1,boxP1},{boxP2,boxP2,boxP2}};
525 size_t bc[3] = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
530 vector_dist_ws<3, double, aggregate<double,double,double[3],double,double[3],double>> Sparticles(0, domain,bc,ghost);
532 double Golden_angle=M_PI * (3.0 - sqrt(5.0));
533 if (v_cl.rank() == 0) {
536 std::unordered_map<const lm,double,key_hash,key_equal> Alm;
539 for(
int l=0;l<=K;l++){
540 for(
int m=-l;m<=l;m++){
541 Alm[std::make_tuple(l,m)]=0;
544 Alm[std::make_tuple(1,0)]=1;
545 for(
int i=1;i<n_sp;i++)
547 double y = 1.0 - (i /double(n_sp - 1.0)) * 2.0;
548 double radius = sqrt(1 - y * y);
549 double Golden_theta = Golden_angle * i;
550 double x = cos(Golden_theta) * radius;
551 double z = sin(Golden_theta) * radius;
553 Sparticles.getLastPos()[0] = x;
554 Sparticles.getLastPos()[1] = y;
555 Sparticles.getLastPos()[2] = z;
556 double rm=sqrt(x*x+y*y+z*z);
557 Sparticles.getLastProp<2>()[0] = x/rm;
558 Sparticles.getLastProp<2>()[1] = y/rm;
559 Sparticles.getLastProp<2>()[2] = z/rm;
560 Sparticles.getLastProp<4>()[0] = 1.0 ;
561 Sparticles.getLastProp<4>()[1] = std::atan2(sqrt(x*x+y*y),z);
562 Sparticles.getLastProp<4>()[2] = std::atan2(y,x);
563 double m1=openfpm::math::sumY_Scalar<K>(1.0,std::atan2(sqrt(x*x+y*y),z),std::atan2(y,x),Alm);
564 double m2=-(K)*(K+1)*openfpm::math::sumY_Scalar<K>(1.0,std::atan2(sqrt(x*x+y*y),z),std::atan2(y,x),Alm);
565 Sparticles.getLastProp<3>()=m1;
566 Sparticles.getLastProp<1>()=m2;
567 Sparticles.getLastSubset(0);
568 for(
int j=1;j<=2;++j){
570 Sparticles.getLastPos()[0] = x+j*grid_spacing_surf*x/rm;
571 Sparticles.getLastPos()[1] = y+j*grid_spacing_surf*y/rm;
572 Sparticles.getLastPos()[2] = z+j*grid_spacing_surf*z/rm;
573 Sparticles.getLastProp<3>()=m1;
574 Sparticles.getLastSubset(1);
577 Sparticles.getLastPos()[0] = x-j*grid_spacing_surf*x/rm;
578 Sparticles.getLastPos()[1] = y-j*grid_spacing_surf*y/rm;
579 Sparticles.getLastPos()[2] = z-j*grid_spacing_surf*z/rm;
580 Sparticles.getLastProp<3>()=m1;
581 Sparticles.getLastSubset(1);
589 Sparticles.ghost_get<3>();
594 auto &bulkIds=Sparticles_bulk.getIds();
595 auto &bdrIds=Sparticles_boundary.getIds();
610 auto f=getV<3>(Sparticles);
611 auto Df=getV<0>(Sparticles);
616 auto verletList = Sparticles.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
618 Derivative_xx<decltype(verletList)> Sdxx{Sparticles,verletList,2,rCut};
620 Derivative_yy<decltype(verletList)> Sdyy{Sparticles,verletList,2,rCut};
622 Derivative_zz<decltype(verletList)> Sdzz{Sparticles,verletList,2,rCut};
637 Sparticles.ghost_get<3>();
638 Df=(Sdxx(f)+Sdyy(f)+Sdzz(f));
642 for (
int j = 0; j < bulkIds.size(); j++) {
643 auto p = bulkIds.get<0>(j);
645 if (fabs(Sparticles.getProp<1>(p) - Sparticles.getProp<0>(p)) > worst) {
646 worst = fabs(Sparticles.getProp<1>(p) - Sparticles.getProp<0>(p));
649 Sparticles.deleteGhost();
652 BOOST_REQUIRE(worst < 0.03);
655 BOOST_AUTO_TEST_CASE(dcpse_surface_adaptive_planeCart) {
656 auto & v_cl = create_vcluster();
663 size_t sz[3] = {n,n,n};
664 double spacing{0.02};
668 size_t bc[3] = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
671 part.setPropNames(propNames);
673 if (v_cl.rank() == 0) {
675 for (
int i = 0; i < n; ++i) {
676 for (
int j = 0; j < n; ++j) {
679 part.getLastPos()[0] = spacing*i;
680 part.getLastPos()[1] = spacing*j;
681 part.getLastPos()[2] = 0.0;
683 part.getLastProp<1>()[0] = 0;
684 part.getLastProp<1>()[1] = 0;
685 part.getLastProp<1>()[2] = 1.0;
687 part.getLastProp<2>() = std::sin(M_PI * part.getLastPos()[1]);
688 part.getLastProp<3>() = 0;
689 part.getLastProp<4>() = M_PI * std::cos(M_PI * part.getLastPos()[1]);
691 part.getLastProp<0>() = 2*spacing;
695 part.addComputationCosts();
696 part.getDecomposition().decompose();
698 part.ghost_get<0,1,2,3>();
700 size_t total_n{part.size_local()};
705 std::cerr <<
"size local " << part.size_local() << std::endl;
707 auto verletList = part.template getVerletAdaptRCut<>();
709 SurfaceDerivative_y<1,decltype(verletList)> Sdy{part,verletList,2,0,0,2,support_options::ADAPTIVE};
710 auto f = getV<2>(part);
711 auto Df = getV<3>(part);
717 double maxErr{0}, l2err{0}, maxRel_err{0}, l2rel_err{0};
719 auto pit{part.getDomainIterator()};
720 while (pit.isNext()) {
723 err = std::abs(part.getProp<4>(key) - part.getProp<3>(key));
724 rel_err = err/std::abs(part.getProp<4>(key));
725 part.getProp<5>(key) = err;
727 maxErr = std::max(maxErr,err);
728 maxRel_err = std::max(maxRel_err,rel_err);
730 l2rel_err += rel_err*rel_err;
735 v_cl.max(maxRel_err);
741 double linf_norm{maxErr};
742 double l2_norm{std::sqrt(l2err/
double(total_n))};
744 double linf_rel_norm{maxRel_err};
745 double l2_rel_norm{std::sqrt(l2rel_err/
double(total_n))};
749 BOOST_REQUIRE_CLOSE(l2_norm,8.657329e-02,0.1);
750 BOOST_REQUIRE_CLOSE(linf_norm,7.108664e-01,0.1);
754 BOOST_AUTO_TEST_CASE(dcpse_surface_adaptive_unitSphere) {
756 auto & v_cl = create_vcluster();
762 double part_spacing{std::sqrt(4*3.14159265358979323846/n)};
765 size_t bc[3] = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
766 std::array<double,3> center{0,0,0};
769 part.setPropNames(propNames);
771 if (v_cl.rank() == 0) {
775 const double golden_ang = M_PI*(3.0 - std::sqrt(5.0));
776 const double prefactor{std::sqrt(0.75/M_PI)};
777 double rad, theta, arg, thetaB, phi, phi_norm;
778 std::array<double,3> coord;
780 for (
int i = 0; i < n; ++i) {
782 coord[1] = 1.0 - 2.0*(i/double(n-1));
783 rad = std::sqrt(1.0 - (coord[1]-center[1])*(coord[1]-center[1]));
784 theta = golden_ang * i;
785 coord[0] = std::cos(theta) * rad;
786 coord[2] = std::sin(theta) * rad;
788 arg = (coord[0]-center[0]) * (coord[0]-center[0]) + (coord[1]-center[1]) * (coord[1]-center[1]);
789 thetaB = std::atan2(std::sqrt(arg),(coord[2]-center[2]));
790 phi = std::atan2((coord[1]-center[1]),(coord[0]-center[0]));
793 part.getLastPos()[0] = coord[0];
794 part.getLastPos()[1] = coord[1];
795 part.getLastPos()[2] = coord[2];
798 part.getLastProp<1>()[0] = std::sin(thetaB)*std::cos(phi);
799 part.getLastProp<1>()[1] = std::sin(thetaB)*std::sin(phi);
800 part.getLastProp<1>()[2] = std::cos(thetaB);
802 part.getLastProp<0>() = 2*part_spacing;
804 part.getLastProp<2>() = 0.25*std::sqrt(5/M_PI) * (3 * std::cos(thetaB) * std::cos(thetaB) - 1);
805 part.getLastProp<3>() = 0.0;
806 part.getLastProp<4>() = 0.0;
807 part.getLastProp<5>() = -6 * part.getLastProp<2>();
812 part.ghost_get<0,1,2>();
814 size_t total_n{part.size_local()};
819 auto verletList_reg = part.template getVerlet<>(2*part_spacing);
822 auto verletList_adapt = part.template getVerletAdaptRCut<>();
825 SurfaceDerivative_xx<1,decltype(verletList_reg)> Sdxx_reg{part,verletList_reg,2,0,part_spacing,2};
826 SurfaceDerivative_yy<1,decltype(verletList_reg)> Sdyy_reg{part,verletList_reg,2,0,part_spacing,2};
827 SurfaceDerivative_zz<1,decltype(verletList_reg)> Sdzz_reg{part,verletList_reg,2,0,part_spacing,2};
830 SurfaceDerivative_xx<1,decltype(verletList_adapt)> Sdxx_adapt{part,verletList_adapt,2,0,0,2,support_options::ADAPTIVE};
831 SurfaceDerivative_yy<1,decltype(verletList_adapt)> Sdyy_adapt{part,verletList_adapt,2,0,0,2,support_options::ADAPTIVE};
832 SurfaceDerivative_zz<1,decltype(verletList_adapt)> Sdzz_adapt{part,verletList_adapt,2,0,0,2,support_options::ADAPTIVE};
834 auto f{getV<2>(part)};
835 auto lap_reg{getV<4>(part)};
836 auto lap_adapt{getV<3>(part)};
837 lap_reg = Sdxx_reg(f) + Sdyy_reg(f)+ Sdzz_reg(f);
838 lap_adapt = Sdxx_adapt(f) + Sdyy_adapt(f)+ Sdzz_adapt(f);
842 double maxErr_reg{0}, l2err_reg{0}, maxRel_err_reg{0}, l2rel_err_reg{0};
843 double err_reg, rel_err_reg;
844 double maxErr_adapt{0}, l2err_adapt{0}, maxRel_err_adapt{0}, l2rel_err_adapt{0};
845 double err_adapt, rel_err_adapt;
846 auto pit{part.getDomainIterator()};
847 while (pit.isNext()) {
850 err_reg = std::abs(part.getProp<4>(key) - part.getProp<5>(key));
851 rel_err_reg = err_reg/std::abs(part.getProp<5>(key));
852 part.getProp<7>(key) = err_reg;
854 maxErr_reg = std::max(maxErr_reg,err_reg);
855 maxRel_err_reg = std::max(maxRel_err_reg,rel_err_reg);
856 l2err_reg += err_reg*err_reg;
857 l2rel_err_reg += rel_err_reg*rel_err_reg;
859 err_adapt = std::abs(part.getProp<3>(key) - part.getProp<5>(key));
860 rel_err_adapt = err_adapt/std::abs(part.getProp<5>(key));
861 part.getProp<6>(key) = err_adapt;
863 maxErr_adapt = std::max(maxErr_adapt,err_adapt);
864 maxRel_err_adapt = std::max(maxRel_err_adapt,rel_err_adapt);
865 l2err_adapt += err_adapt*err_adapt;
866 l2rel_err_adapt += rel_err_adapt*rel_err_adapt;
870 v_cl.max(maxErr_reg);
871 v_cl.max(maxRel_err_reg);
873 v_cl.sum(l2rel_err_reg);
874 v_cl.max(maxErr_adapt);
875 v_cl.max(maxRel_err_adapt);
876 v_cl.sum(l2err_adapt);
877 v_cl.sum(l2rel_err_adapt);
881 double linf_norm_reg{maxErr_reg};
882 double l2_norm_reg{std::sqrt(l2err_reg/
double(total_n))};
884 double linf_rel_norm_reg{maxRel_err_reg};
885 double l2_rel_norm_reg{std::sqrt(l2rel_err_reg/
double(total_n))};
887 double linf_norm_adapt{maxErr_adapt};
888 double l2_norm_adapt{std::sqrt(l2err_adapt/
double(total_n))};
890 double linf_rel_norm_adapt{maxRel_err_adapt};
891 double l2_rel_norm_adapt{std::sqrt(l2rel_err_adapt/
double(total_n))};
899 BOOST_REQUIRE_CLOSE(l2_norm_reg,l2_norm_adapt,0.001);
900 BOOST_REQUIRE_CLOSE(linf_norm_reg,linf_norm_adapt,0.001);
901 BOOST_REQUIRE_CLOSE(l2_rel_norm_reg,l2_rel_norm_adapt,0.001);
902 BOOST_REQUIRE_CLOSE(linf_rel_norm_reg,linf_rel_norm_adapt,0.001);
1140 BOOST_AUTO_TEST_CASE(dcpse_surface_tensor_gradient) {
1144 constexpr
int VEC{0};
1145 constexpr
int NORMAL{1};
1146 constexpr
int PROJMAT{2};
1147 constexpr
int EUCGRAD{3};
1148 constexpr
int SGRAD{4};
1149 constexpr
int DSGRAD{5};
1150 constexpr
int LAP{6};
1151 constexpr
int ANALYTLAP{7};
1159 size_t part_set_size[3] = {4000, 8000, 16000};
1160 double L2norms_conv[3] = {0,0,0};
1161 double Linfnorms_conv[3] = {0,0,0};
1164 for (
int ll = 0; ll < 3; ++ll) {
1166 size_t n_part{part_set_size[ll]};
1169 size_t sz[3] = {n_part,n_part,n_part};
1170 double grid_spacing{0.8/((std::pow(sz[0],1/3.0)-1))};
1171 double grid_spacing_surf{grid_spacing};
1175 size_t bc[3] = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
1178 part.setPropNames(propNames);
1180 std::array<double,3> center{0,0,0};
1181 std::array<double,3> coord;
1183 if (v_cl.
rank() == 0) {
1186 const double pi{3.14159265358979323846};
1187 const double golden_ang = pi*(3.0 - std::sqrt(5.0));
1188 const double prefactor{std::sqrt(0.75/pi)};
1189 double rad, theta, arg, thetaB, phi, phi_norm;
1191 for (
int i = 0; i < n_part; ++i) {
1193 coord[1] = 1.0 - 2.0*(i/double(n_part-1));
1194 rad = std::sqrt(1.0 - (coord[1]-center[1])*(coord[1]-center[1]));
1195 theta = golden_ang * i;
1196 coord[0] = std::cos(theta) * rad;
1197 coord[2] = std::sin(theta) * rad;
1199 arg = (coord[0]-center[0]) * (coord[0]-center[0]) + (coord[1]-center[1]) * (coord[1]-center[1]);
1200 thetaB = std::atan2(std::sqrt(arg),(coord[2]-center[2]));
1201 phi = std::atan2((coord[1]-center[1]),(coord[0]-center[0]));
1204 part.getLastPos()[0] = coord[0];
1205 part.getLastPos()[1] = coord[1];
1206 part.getLastPos()[2] = coord[2];
1211 part.getLastProp<VEC>()[0] = - 3.0/4.0 * std::sqrt(7.0/pi) * (1.0 - 5.0 * std::cos(thetaB) * std::cos(thetaB)) * std::sin(thetaB) * std::sin(phi);
1212 part.getLastProp<VEC>()[1] = 3.0/4.0 * std::sqrt(7.0/pi) * (1.0 - 5.0 * std::cos(thetaB) * std::cos(thetaB)) * std::sin(thetaB) * std::cos(phi);
1213 part.getLastProp<VEC>()[2] = 0.0;
1222 part.getLastProp<ANALYTLAP>()[0] = 11.0 * 3.0/4.0 * std::sqrt(7.0/pi) * (1.0 - 5.0 * std::cos(thetaB) * std::cos(thetaB)) * std::sin(thetaB) * std::sin(phi);
1223 part.getLastProp<ANALYTLAP>()[1] = - 11.0 * 3.0/4.0 * std::sqrt(7.0/pi) * (1.0 - 5.0 * std::cos(thetaB) * std::cos(thetaB)) * std::sin(thetaB) * std::cos(phi);
1224 part.getLastProp<ANALYTLAP>()[2] = 0.0;
1231 part.getLastProp<NORMAL>()[0] = std::sin(thetaB)*std::cos(phi);
1232 part.getLastProp<NORMAL>()[1] = std::sin(thetaB)*std::sin(phi);
1233 part.getLastProp<NORMAL>()[2] = std::cos(thetaB);
1237 for (
int i = 0; i < 3; ++i) {
1238 ni = part.getLastProp<NORMAL>()[i];
1239 for (
int j = 0; j < 3; ++j) {
1240 nj = part.getLastProp<NORMAL>()[j];
1241 part.getLastProp<PROJMAT>()[i][j] = (i==j)*(1-ni*nj) - !(i==j)*(ni*nj);
1248 part.ghost_get<VEC,PROJMAT,NORMAL>();
1251 auto verletList = part.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut*grid_spacing);
1252 SurfaceDerivative_x<NORMAL,decltype(verletList)> Sdx{part,verletList,3,rCut*grid_spacing,grid_spacing_surf,
static_cast<unsigned int>(rCut*grid_spacing/grid_spacing_surf)};
1253 SurfaceDerivative_y<NORMAL,decltype(verletList)> Sdy{part,verletList,3,rCut*grid_spacing,grid_spacing_surf,
static_cast<unsigned int>(rCut*grid_spacing/grid_spacing_surf)};
1254 SurfaceDerivative_z<NORMAL,decltype(verletList)> Sdz{part,verletList,3,rCut*grid_spacing,grid_spacing_surf,
static_cast<unsigned int>(rCut*grid_spacing/grid_spacing_surf)};
1257 auto vec{getV<VEC>(part)};
1258 auto projMat{getV<PROJMAT>(part)};
1259 auto eucGrad{getV<EUCGRAD>(part)};
1260 auto SGrad{getV<SGRAD>(part)};
1261 auto dSGrad{getV<DSGRAD>(part)};
1262 auto lap{getV<LAP>(part)};
1280 part.template ghost_get<SGRAD,LAP>();
1283 eucGrad[0][0] = Sdx(vec[0]);
1284 eucGrad[0][1] = Sdy(vec[0]);
1285 eucGrad[0][2] = Sdz(vec[0]);
1287 eucGrad[1][0] = Sdx(vec[1]);
1288 eucGrad[1][1] = Sdy(vec[1]);
1289 eucGrad[1][2] = Sdz(vec[1]);
1291 eucGrad[2][0] = Sdx(vec[2]);
1292 eucGrad[2][1] = Sdy(vec[2]);
1293 eucGrad[2][2] = Sdz(vec[2]);
1294 part.template ghost_get<EUCGRAD>();
1296 for (
int l = 0; l < 3; ++l)
1297 for (
int k = 0; k < 3; ++k)
1298 for (
int t = 0; t < 3; ++t)
1299 for (
int h = 0; h < 3; ++h)
1300 SGrad[l][k] = projMat[l][t] * projMat[k][h] * eucGrad[t][h] + SGrad[l][k];
1301 part.template ghost_get<SGRAD>();
1306 auto it1{part.getDomainIterator()};
1307 while (it1.isNext()) {
1308 auto key{it1.get()};
1310 for (
int d1 = 0; d1 < 3; ++d1) {
1312 for (
int d2 = 0; d2 < 3; ++d2)
1313 dot_prod[d1] += part.template getProp<SGRAD>(key)[d1][d2] * part.template getProp<NORMAL>(key)[d2];
1315 if (std::fabs(dot_prod[d1]) > 1e-14)
1316 std::cout << key.to_string() <<
" not tangent\n";
1326 auto it1{part.getDomainIterator()};
1327 while (it1.isNext()) {
1328 auto key{it1.get()};
1330 for (
int d1 = 0; d1 < 3; ++d1) {
1332 for (
int d2 = 0; d2 < 3; ++d2)
1333 dot_prod[d1] += part.template getProp<SGRAD>(key)[d2][d1] * part.template getProp<NORMAL>(key)[d2];
1335 if (std::fabs(dot_prod[d1]) > 1e-14)
1336 std::cout << key.to_string() <<
" not tangent\n";
1344 for (
int d1 = 0; d1 < 3; ++d1)
1345 for (
int d2 = 0; d2 < 3; ++d2) {
1346 dSGrad[d1][d2][0] = Sdx(SGrad[d1][d2]);
1347 dSGrad[d1][d2][1] = Sdy(SGrad[d1][d2]);
1348 dSGrad[d1][d2][2] = Sdz(SGrad[d1][d2]);
1388 part.template ghost_get<DSGRAD>();
1390 for (
int i = 0; i < 3; ++i)
1391 for (
int l = 0; l < 3; ++l)
1392 for (
int k = 0; k < 3; ++k)
1393 for (
int m = 0; m < 3; ++m) {
1394 lap[i] = projMat[i][l] * projMat[k][m] * dSGrad[l][k][m] + lap[i];
1396 part.template ghost_get<LAP>();
1400 auto it1{part.getDomainIterator()};
1401 while (it1.isNext()) {
1403 auto key{it1.get()};
1404 for (
int d1 = 0; d1 < 3; ++d1)
1405 dot_prod += part.template getProp<LAP>(key)[d1] * part.template getProp<NORMAL>(key)[d1];
1407 if (std::fabs(dot_prod) > 1e-14)
1408 std::cout << key.to_string() <<
" not tangent\n";
1416 double maxErr{0}, l2err{0};
1417 double err, abs_lap;
1418 auto pit{part.getDomainIterator()};
1419 while (pit.isNext()) {
1420 auto key{pit.get()};
1424 for (
int d = 0; d < 3; ++d) {
1425 err += (part.getProp<ANALYTLAP>(key)[d] - part.getProp<LAP>(key)[d]) * (part.getProp<ANALYTLAP>(key)[d] - part.getProp<LAP>(key)[d]);
1426 abs_lap += part.getProp<LAP>(key)[d] * part.getProp<LAP>(key)[d];
1429 err = std::sqrt(err);
1430 maxErr = std::max(maxErr,err);
1439 double linf_normLap{maxErr};
1440 double l2_normLap{std::sqrt(l2err/
double(n_part))};
1442 L2norms_conv[ll] = l2_normLap;
1443 Linfnorms_conv[ll] = linf_normLap;
1445 if (v_cl.
rank() == 0)
1446 std::cout << n_part <<
" " << std::setprecision(6) << std::scientific << grid_spacing <<
" " << l2_normLap <<
" " << linf_normLap << std::endl;
1450 part.write(
"tensor_surface_derivative_N" + std::to_string(n_part),VTK_WRITER);
1453 BOOST_TEST_MESSAGE(
"Test convergence of surface vector Laplacian");
1454 BOOST_TEST_MESSAGE(
"L2 error for N=4000 / L2 error for N=8000 = " + std::to_string(L2norms_conv[0]/L2norms_conv[1]));
1455 BOOST_TEST_MESSAGE(
"L2 error for N=8000 / L2 error for N=16000 = " + std::to_string(L2norms_conv[1]/L2norms_conv[2]));
1456 BOOST_REQUIRE(L2norms_conv[0]/L2norms_conv[1] > 2);
1457 BOOST_REQUIRE(L2norms_conv[1]/L2norms_conv[2] > 1.8);
1461 BOOST_AUTO_TEST_CASE(dcpse_surface_p2p_interpolation_sphere_scalar) {
1462 auto & v_cl = create_vcluster();
1465 size_t n_from1=4096;
1466 size_t n_from2=8192;
1469 double boxP1{-1.5}, boxP2{1.5};
1470 double boxSize{boxP2 - boxP1};
1471 size_t sz1[3] = {n_from1,n_from1,n_from1};
1472 size_t sz2[3] = {n_from2,n_from2,n_from2};
1473 size_t szTo[3] = {n_to,n_to,n_to};
1474 double grid_spacing1 = std::sqrt(4.0*M_PI/n_from1);
1475 double grid_spacing2 = std::sqrt(4.0*M_PI/n_from2);
1476 double grid_spacingTo = std::sqrt(4.0*M_PI/n_to);
1477 double grid_spacing_surf2=grid_spacing2;
1478 double grid_spacing_surf1=grid_spacing1;
1479 double grid_spacing_surfTo=grid_spacingTo;
1480 double cutoff_factor = 3.5;
1481 double rCut2{cutoff_factor * grid_spacing_surf2};
1482 double rCut1{cutoff_factor * grid_spacing_surf1};
1483 double rCutTo{cutoff_factor * grid_spacing_surfTo};
1485 Box<3,double> domain{{boxP1,boxP1,boxP1},{boxP2,boxP2,boxP2}};
1486 size_t bc[3] = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
1499 double Golden_angle=M_PI * (3.0 - sqrt(5.0));
1500 if (v_cl.
rank() == 0) {
1502 for(
int i=0;i<n_from1;i++)
1504 double y = 1.0 - (i /double(n_from1 - 1.0)) * 2.0;
1505 double radius = sqrt(1 - y * y);
1506 double Golden_theta = Golden_angle * i;
1507 double x = cos(Golden_theta) * radius;
1508 double z = sin(Golden_theta) * radius;
1509 SparticlesFrom1.add();
1510 SparticlesFrom1.getLastPos()[0] = x;
1511 SparticlesFrom1.getLastPos()[1] = y;
1512 SparticlesFrom1.getLastPos()[2] = z;
1513 double rm=sqrt(x*x+y*y+z*z);
1515 SparticlesFrom1.getLastProp<1>()[0] = x/rm;
1516 SparticlesFrom1.getLastProp<1>()[1] = y/rm;
1517 SparticlesFrom1.getLastProp<1>()[2] = z/rm;
1525 SparticlesFrom1.getLastProp<0>() = 0.25*std::sqrt(105.0/M_PI)*(x*x - y*y)*z;
1530 for(
int i=0;i<n_from2;i++)
1532 double y = 1.0 - (i /double(n_from2 - 1.0)) * 2.0;
1533 double radius = sqrt(1 - y * y);
1534 double Golden_theta = Golden_angle * i;
1535 double x = cos(Golden_theta) * radius;
1536 double z = sin(Golden_theta) * radius;
1537 SparticlesFrom2.add();
1538 SparticlesFrom2.getLastPos()[0] = x;
1539 SparticlesFrom2.getLastPos()[1] = y;
1540 SparticlesFrom2.getLastPos()[2] = z;
1541 double rm=sqrt(x*x+y*y+z*z);
1543 SparticlesFrom2.getLastProp<1>()[0] = x/rm;
1544 SparticlesFrom2.getLastProp<1>()[1] = y/rm;
1545 SparticlesFrom2.getLastProp<1>()[2] = z/rm;
1553 SparticlesFrom2.getLastProp<0>() = 0.25*std::sqrt(105.0/M_PI)*(x*x - y*y)*z;
1558 for(
int i=0;i<((
int)(n_to-1));i++)
1560 double y = 1.0 - (i /double(n_to - 1.0)) * 2.0;
1561 double radius = sqrt(1 - y * y);
1562 double Golden_theta = Golden_angle * i;
1563 double x = cos(Golden_theta) * radius;
1564 double z = sin(Golden_theta) * radius;
1566 SparticlesTo.getLastPos()[0] = x;
1567 SparticlesTo.getLastPos()[1] = y;
1568 SparticlesTo.getLastPos()[2] = z;
1569 double rm=sqrt(x*x+y*y+z*z);
1571 SparticlesTo.getLastProp<0>() = 0.0;
1572 SparticlesTo.getLastProp<1>() = 0.0;
1576 SparticlesFrom1.write(
"from1_before");
1577 SparticlesFrom2.write(
"from2_before");
1578 SparticlesTo.write(
"to_before");
1580 SparticlesFrom1.map();
1581 SparticlesFrom1.ghost_get<0,1>();
1582 SparticlesFrom2.map();
1583 SparticlesFrom2.ghost_get<0,1>();
1585 SparticlesTo.ghost_get<0>();
1587 const size_t oporder = 5;
1589 auto cellListSparticlesFrom1 = SparticlesFrom1.getCellList(rCut1);
1590 auto verletListSparticlesTo1 = createVerletTwoPhase(SparticlesTo,SparticlesFrom1,cellListSparticlesFrom1,rCut1);
1592 auto cellListSparticlesFrom2 = SparticlesFrom2.getCellList(rCut2);
1593 auto verletListSparticlesTo2 = createVerletTwoPhase(SparticlesTo,SparticlesFrom2,cellListSparticlesFrom2,rCut2);
1595 PPInterpolation<decltype(SparticlesFrom1),decltype(SparticlesTo), decltype(verletListSparticlesTo1), 1> ppSurface(SparticlesFrom1,SparticlesTo, verletListSparticlesTo1, oporder,rCut1,grid_spacing1,
true,support_options::RADIUS);
1596 ppSurface.p2p<0,0>();
1597 PPInterpolation<decltype(SparticlesFrom2),decltype(SparticlesTo), decltype(verletListSparticlesTo2), 1> ppSurface2(SparticlesFrom2,SparticlesTo, verletListSparticlesTo2, oporder,rCut2,grid_spacing2,
true,support_options::RADIUS);
1598 ppSurface2.p2p<0,1>();
1600 auto it = SparticlesTo.getDomainIterator();
1602 double worst2 = 0.0;
1603 while (it.isNext()) {
1606 double x = SparticlesTo.getPos(p)[0];
1607 double y = SparticlesTo.getPos(p)[1];
1608 double z = SparticlesTo.getPos(p)[2];
1616 double sphericalHarmonic = 0.25*std::sqrt(105.0/M_PI)*(x*x - y*y)*z;
1619 SparticlesTo.getProp<2>(p) = fabs(SparticlesTo.getProp<0>(p) - sphericalHarmonic);
1620 SparticlesTo.getProp<3>(p) = fabs(SparticlesTo.getProp<1>(p) - sphericalHarmonic);
1622 if (fabs(SparticlesTo.getProp<0>(p) - sphericalHarmonic) > worst) {
1623 worst = fabs(SparticlesTo.getProp<0>(p) - sphericalHarmonic);
1625 if (fabs(SparticlesTo.getProp<1>(p) - sphericalHarmonic) > worst2) {
1626 worst2 = fabs(SparticlesTo.getProp<1>(p) - sphericalHarmonic);
1634 std::cout<<
"Linf interpolation error with h_from1=1/"<<n_from1<<
" to h_to=1/"<<n_to<<
" is: "<<worst<<std::endl;
1635 std::cout<<
"Linf interpolation error with h_from2=1/"<<n_from2<<
" to h_to=1/"<<n_to<<
" is: "<<worst2<<std::endl;
1638 std::cout<<
"Convergence order is "<<std::log10(worst2/worst)/std::log10(std::sqrt((
float)n_from1/(
float)n_from2))<<std::endl;
1639 std::cout<<
"Operator order = "<<oporder<<std::endl;
1640 SparticlesTo.deleteGhost();
1641 SparticlesFrom1.deleteGhost();
1642 SparticlesTo.write(
"SparticlesTo_after");
1643 SparticlesFrom1.write(
"SparticlesFrom1_after");
1644 BOOST_REQUIRE(worst < 0.03);
1645 BOOST_REQUIRE(worst2 < 0.03);
1648 BOOST_AUTO_TEST_CASE(dcpse_surface_p2p_interpolation_plane_scalar) {
1650 auto & v_cl = create_vcluster();
1658 double grid_spacing_from{2.0/(n_from-1)};
1659 double grid_spacing_to{2.0/(n_to-1)};
1660 size_t bc[3] = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
1667 if (v_cl.
rank() == 0) {
1669 for (
int i = 0; i < n_from; ++i)
1670 for (
int j = 0; j < n_from; ++j) {
1674 part_from.getLastPos()[0] = -1 + i*grid_spacing_from;
1675 part_from.getLastPos()[1] = -1 + j*grid_spacing_from;
1676 part_from.getLastPos()[2] = 0;
1678 part_from.getLastProp<0>() = std::fabs(part_from.getLastPos()[0]);
1679 part_from.getLastProp<1>()[0] = 0;
1680 part_from.getLastProp<1>()[1] = 0;
1681 part_from.getLastProp<1>()[2] = 1;
1685 part_from.ghost_get<0,1>();
1688 std::random_device rd;
1689 std::mt19937 gen(rd());
1690 std::uniform_real_distribution<> dist_threshold{-1.0,1.0};
1692 if (v_cl.
rank() == 0) {
1694 for (
int i = 0; i < n_to; ++i)
1695 for (
int j = 0; j < n_to; ++j) {
1699 part_to.getLastPos()[0] = -1 + i*grid_spacing_to;
1700 part_to.getLastPos()[1] = -1 + j*grid_spacing_to;
1703 part_to.getLastPos()[2] = 0;
1705 part_to.getLastProp<0>() = 0;
1706 part_to.getLastProp<1>()[0] = 0;
1707 part_to.getLastProp<1>()[1] = 0;
1708 part_to.getLastProp<1>()[2] = 1;
1709 part_to.getLastProp<2>() = 0;
1713 part_to.ghost_get<0,1>();
1716 auto cellList = part_from.getCellList(rCut);
1717 auto verletList = createVerletTwoPhase(part_to,part_from,cellList,rCut);
1719 PPInterpolation<decltype(part_from),decltype(part_to),decltype(verletList),1> ppSurface(part_from,part_to,verletList,2,rCut,grid_spacing_from,
true);
1720 ppSurface.p2p<0,0>();
1723 auto it = part_to.getDomainIterator();
1725 while (it.isNext()) {
1728 part_to.getProp<2>(key) = std::fabs(part_to.getProp<0>(key) - std::fabs(part_to.getPos(key)[0]));
1730 if (part_to.getProp<2>(key) > worst)
1731 worst = part_to.getProp<2>(key);
1739 part_from.deleteGhost();
1740 part_from.write(
"surface_p2p_interp_plane_part_from");
1741 part_to.deleteGhost();
1742 part_to.write(
"surface_p2p_interp_plane_part_to");
1744 std::cout <<
"worst: " << worst << std::endl;
1748 BOOST_AUTO_TEST_CASE(dcpse_surface_p2p_interpolation_sphere_vector) {
1750 auto & v_cl = create_vcluster();
1755 size_t ni_from[3] = {2000,8000,16000};
1756 size_t ni_to[3] = {2000,4000,32000};
1759 double boxP1{-1.2}, boxP2{1.2};
1760 double boxSize{boxP2 - boxP1};
1761 Box<3,double> domain{{boxP1,boxP1,boxP1},{boxP2,boxP2,boxP2}};
1762 size_t bc[3] = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
1764 double cutoff_factor = 3.5;
1765 const size_t oporder = 5;
1767 double Linf[3][3] = {{0,0,0},{0,0,0},{0,0,0}};
1769 for (
int ni = 0; ni < 3; ++ni)
1772 double grid_spacing_from{std::sqrt(4.0*M_PI/ni_from[ni])};
1773 double rCut_from{cutoff_factor * grid_spacing_from};
1777 if (v_cl.
rank() == 0) {
1779 double Golden_angle{M_PI * (3.0 - sqrt(5.0))};
1780 double thetaB, phi, arg;
1782 for(
int i = 0; i < ni_from[ni]; ++i)
1784 double y = 1.0 - (i /double(ni_from[ni] - 1.0)) * 2.0;
1785 double radius = sqrt(1 - y * y);
1786 double Golden_theta = Golden_angle * i;
1787 double x = cos(Golden_theta) * radius;
1788 double z = sin(Golden_theta) * radius;
1791 thetaB = std::atan2(std::sqrt(arg),z);
1792 phi = std::atan2(y,x);
1794 Sparticles_from.add();
1795 Sparticles_from.getLastPos()[0] = x;
1796 Sparticles_from.getLastPos()[1] = y;
1797 Sparticles_from.getLastPos()[2] = z;
1799 double rm = sqrt(x*x+y*y+z*z);
1802 Sparticles_from.getLastProp<0>()[0] = x/rm;
1803 Sparticles_from.getLastProp<0>()[1] = y/rm;
1804 Sparticles_from.getLastProp<0>()[2] = z/rm;
1807 Sparticles_from.getLastProp<1>()[0] = - 3.0/4.0 * std::sqrt(7.0/M_PI) * (1.0 - 5.0 * std::cos(thetaB) * std::cos(thetaB)) * std::sin(thetaB) * std::sin(phi);
1808 Sparticles_from.getLastProp<1>()[1] = 3.0/4.0 * std::sqrt(7.0/M_PI) * (1.0 - 5.0 * std::cos(thetaB) * std::cos(thetaB)) * std::sin(thetaB) * std::cos(phi);
1809 Sparticles_from.getLastProp<1>()[2] = 0.0;
1812 Sparticles_from.map();
1813 Sparticles_from.ghost_get<0,1>();
1814 Sparticles_from.write(
"from_N" + std::to_string(ni_from[ni]) +
"_before");
1817 for (
int nj = 0; nj < 3; ++nj)
1819 double grid_spacing_to{std::sqrt(4.0*M_PI/ni_to[nj])};
1820 double rCut_to{cutoff_factor * grid_spacing_to};
1824 if (v_cl.
rank() == 0) {
1826 double Golden_angle{M_PI * (3.0 - sqrt(5.0))};
1827 double thetaB, phi, arg;
1829 for(
int i = 0; i < ni_to[nj]; ++i)
1831 double y = 1.0 - (i /double(ni_to[nj] - 1.0)) * 2.0;
1832 double radius = sqrt(1 - y * y);
1833 double Golden_theta = Golden_angle * i;
1834 double x = cos(Golden_theta) * radius;
1835 double z = sin(Golden_theta) * radius;
1838 thetaB = std::atan2(std::sqrt(arg),z);
1839 phi = std::atan2(y,x);
1841 Sparticles_to.add();
1842 Sparticles_to.getLastPos()[0] = x;
1843 Sparticles_to.getLastPos()[1] = y;
1844 Sparticles_to.getLastPos()[2] = z;
1846 double rm=sqrt(x*x+y*y+z*z);
1848 for (
int d = 0; d < 3; ++d)
1849 Sparticles_to.getLastProp<0>()[d] = 0.0;
1852 Sparticles_to.getLastProp<1>()[0] = - 3.0/4.0 * std::sqrt(7.0/M_PI) * (1.0 - 5.0 * std::cos(thetaB) * std::cos(thetaB)) * std::sin(thetaB) * std::sin(phi);
1853 Sparticles_to.getLastProp<1>()[1] = 3.0/4.0 * std::sqrt(7.0/M_PI) * (1.0 - 5.0 * std::cos(thetaB) * std::cos(thetaB)) * std::sin(thetaB) * std::cos(phi);
1854 Sparticles_to.getLastProp<1>()[2] = 0.0;
1856 Sparticles_to.getLastProp<2>() = 0.0;
1859 Sparticles_to.map();
1860 Sparticles_to.ghost_get<0,1>();
1861 Sparticles_to.write(
"to_N" + std::to_string(ni_to[nj]) +
"_before");
1865 auto cellList = Sparticles_from.getCellList(rCut_from);
1866 auto verletList = createVerletTwoPhase(Sparticles_to,Sparticles_from,cellList,rCut_from);
1868 PPInterpolation<decltype(Sparticles_from),decltype(Sparticles_to), decltype(verletList),0> ppSurface(Sparticles_from,Sparticles_to,verletList,oporder,rCut_from,grid_spacing_from,
true);
1869 ppSurface.p2p<1,0,3>();
1872 auto it = Sparticles_to.getDomainIterator();
1874 while (it.isNext()) {
1877 double x = Sparticles_to.getPos(p)[0];
1878 double y = Sparticles_to.getPos(p)[1];
1879 double z = Sparticles_to.getPos(p)[2];
1882 for (
int d = 0; d < 3; ++d)
1883 err += (Sparticles_to.getProp<0>(p)[d] - Sparticles_to.getProp<1>(p)[d]) * (Sparticles_to.getProp<0>(p)[d] - Sparticles_to.getProp<1>(p)[d]);
1885 worst = std::max(worst,std::sqrt(err));
1891 Linf[ni][nj] = worst;
1893 if (v_cl.
rank() == 0)
1894 std::cout<<
"Linf interpolation error with N_from: " << ni_from[ni] <<
" to N_to: " << ni_to[nj] <<
" is: " << worst << std::endl;
1896 Sparticles_from.deleteGhost();
1897 Sparticles_to.deleteGhost();
1899 Sparticles_from.write(
"from_N" + std::to_string(ni_to[nj]) +
"_after");
1900 Sparticles_to.write(
"to_N" + std::to_string(ni_to[nj]) +
"_after");
1902 BOOST_REQUIRE(worst < 0.03);
1906 if (v_cl.
rank() == 0) {
1907 std::cout <<
"Operator order = " << oporder << std::endl;
1911 std::cout <<
"Convergence order is " << std::log10(Linf[2][0]/Linf[1][0]) / std::log10(std::sqrt((
float)ni_from[1]/(
float)ni_from[2]))<<std::endl;
1912 std::cout <<
"Convergence order is " << std::log10(Linf[1][0]/Linf[0][0]) / std::log10(std::sqrt((
float)ni_from[0]/(
float)ni_from[1]))<<std::endl;
1914 std::cout <<
"Convergence order is " << std::log10(Linf[2][1]/Linf[1][1]) / std::log10(std::sqrt((
float)ni_from[1]/(
float)ni_from[2]))<<std::endl;
1915 std::cout <<
"Convergence order is " << std::log10(Linf[1][1]/Linf[0][1]) / std::log10(std::sqrt((
float)ni_from[0]/(
float)ni_from[1]))<<std::endl;
1917 std::cout <<
"Convergence order is " << std::log10(Linf[2][2]/Linf[1][2]) / std::log10(std::sqrt((
float)ni_from[1]/(
float)ni_from[2]))<<std::endl;
1918 std::cout <<
"Convergence order is " << std::log10(Linf[1][2]/Linf[0][2]) / std::log10(std::sqrt((
float)ni_from[0]/(
float)ni_from[1]))<<std::endl;
1922 BOOST_AUTO_TEST_SUITE_END()
This class represent an N-dimensional box.
Class to perform particle to particle interpolation using DC-PSE kernels.
void execute()
Execute all the requests.
size_t rank()
Get the process unit id.
void sum(T &num)
Sum the numbers across all processors and get the result.
void max(T &num)
Get the maximum number across all processors (or reduction with infinity norm)
Implementation of VCluster class.
Class for cpu time benchmarking.
void start()
Start the timer.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
Specify the general characteristic of system to solve.