14 #define BOOST_TEST_DYN_LINK
16 #include "util/util_debug.hpp"
17 #include <boost/test/unit_test.hpp>
19 #include "DCPSE/DCPSE_op/DCPSE_op.hpp"
20 #include "DCPSE/DCPSE_op/DCPSE_Solver.hpp"
21 #include "Operators/Vector/vector_dist_operators.hpp"
22 #include "Vector/vector_dist_subset.hpp"
23 #include "DCPSE/DCPSE_op/EqnsStruct.hpp"
24 #include "util/SphericalHarmonics.hpp"
32 BOOST_AUTO_TEST_SUITE(dcpse_op_suite_tests3)
33 BOOST_AUTO_TEST_CASE(dcpse_op_vec3d) {
36 size_t edgeSemiSize = 21;
37 const size_t sz[3] = {edgeSemiSize, edgeSemiSize,edgeSemiSize};
39 size_t bc[3] = {NON_PERIODIC, NON_PERIODIC, NON_PERIODIC};
40 double spacing = box.getHigh(0) / (sz[0] - 1);
41 double rCut = 3.1 * spacing;
43 BOOST_TEST_MESSAGE(
"Init vector_dist...");
44 double sigma2 = spacing * spacing/ (2 * 4);
46 vector_dist<3, double, aggregate<double, VectorS<3, double>,
VectorS<3, double>,
VectorS<3, double>,
VectorS<3, double>,double,
double>> domain(
50 BOOST_TEST_MESSAGE(
"Init domain...");
52 auto it = domain.getGridIterator(sz);
55 double minNormOne = 999;
59 mem_id k0 = key.get(0);
60 double x = k0 * spacing;
61 domain.getLastPos()[0] = x;
62 mem_id k1 = key.get(1);
63 double y = k1 * spacing;
64 domain.getLastPos()[1] = y;
65 mem_id k2 = key.get(2);
66 double z = k2 * spacing;
67 domain.getLastPos()[2] = z;
69 domain.template getLastProp<0>() = sin(domain.getLastPos()[0]) + sin(domain.getLastPos()[1]) + sin(domain.getLastPos()[2]) ;
70 domain.template getLastProp<1>()[0] = cos(domain.getLastPos()[0]);
71 domain.template getLastProp<1>()[1] = cos(domain.getLastPos()[1]) ;
72 domain.template getLastProp<1>()[2] = cos(domain.getLastPos()[2]);
74 domain.template getLastProp<2>()[0] = 0;
75 domain.template getLastProp<2>()[1] = 0;
76 domain.template getLastProp<3>()[0] = 0;
77 domain.template getLastProp<3>()[1] = 0;
78 domain.template getLastProp<3>()[2] = 0;
80 domain.template getLastProp<4>()[0] = -cos(domain.getLastPos()[0]) * sin(domain.getLastPos()[0]);
81 domain.template getLastProp<4>()[1] = -cos(domain.getLastPos()[1]) * sin(domain.getLastPos()[1]);
82 domain.template getLastProp<4>()[2] = -cos(domain.getLastPos()[2]) * sin(domain.getLastPos()[2]);
91 domain.template getLastProp<5>() = cos(domain.getLastPos()[0]) * cos(domain.getLastPos()[0])+cos(domain.getLastPos()[1]) * cos(domain.getLastPos()[1])+cos(domain.getLastPos()[2]) * cos(domain.getLastPos()[2]) ;
95 BOOST_TEST_MESSAGE(
"Sync domain across processors...");
98 domain.ghost_get<0>();
100 auto verletList = domain.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
101 Advection<decltype(verletList)> Adv(domain, verletList, 2, rCut, support_options::RADIUS);
102 auto v = getV<1>(domain);
103 auto P = getV<0>(domain);
104 auto dv = getV<3>(domain);
105 auto dP = getV<6>(domain);
111 domain.ghost_get<1>();
113 auto it2 = domain.getDomainIterator();
117 while (it2.isNext()) {
120 if (fabs(domain.getProp<3>(p)[1] - domain.getProp<4>(p)[1]) > worst1) {
121 worst1 = fabs(domain.getProp<3>(p)[1] - domain.getProp<4>(p)[1]);
128 BOOST_REQUIRE(worst1 < 0.03);
136 auto it3 = domain.getDomainIterator();
140 while (it3.isNext()) {
142 if (fabs(domain.getProp<6>(p) - domain.getProp<5>(p)) > worst2) {
143 worst2 = fabs(domain.getProp<6>(p) - domain.getProp<5>(p));
149 domain.deleteGhost();
150 BOOST_REQUIRE(worst2 < 0.03);
155 BOOST_AUTO_TEST_CASE(dcpse_poisson_dirichlet_anal3d) {
159 const size_t sz[3] = {grd_sz,grd_sz,grd_sz};
161 size_t bc[3] = {NON_PERIODIC, NON_PERIODIC,NON_PERIODIC};
162 double spacing = box.getHigh(0) / (sz[0] - 1);
164 double rCut = 3.1 * spacing;
165 BOOST_TEST_MESSAGE(
"Init vector_dist...");
167 vector_dist<3, double, aggregate<double,double,double,double,double,double>> domain(0, box, bc, ghost);
171 BOOST_TEST_MESSAGE(
"Init domain...");
173 auto it = domain.getGridIterator(sz);
174 while (it.isNext()) {
177 double x = key.get(0) * it.getSpacing(0);
178 domain.getLastPos()[0] = x;
179 double y = key.get(1) * it.getSpacing(1);
180 domain.getLastPos()[1] = y;
181 double z = key.get(2) * it.getSpacing(2);
182 domain.getLastPos()[2] = z;
186 BOOST_TEST_MESSAGE(
"Sync domain across processors...");
189 domain.ghost_get<0>();
191 auto verletList = domain.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
193 Derivative_x<decltype(verletList)> Dx(domain, verletList, 2, rCut, support_options::RADIUS);
194 Derivative_y<decltype(verletList)> Dy(domain, verletList, 2, rCut, support_options::RADIUS);
195 Laplacian<decltype(verletList)>
Lap(domain, verletList, 2, rCut, support_options::RADIUS);
205 auto v = getV<0>(domain);
206 auto RHS=getV<1>(domain);
207 auto sol = getV<2>(domain);
208 auto anasol = getV<3>(domain);
209 auto err = getV<4>(domain);
210 auto DCPSE_sol=getV<5>(domain);
213 {box.getLow(0) - spacing / 2.0, box.getHigh(1) - spacing / 2.0, box.getLow(2) - spacing / 2.0},
214 {box.getHigh(0) + spacing / 2.0, box.getHigh(1) + spacing / 2.0, box.getHigh(2) + spacing / 2.0});
217 {box.getLow(0) - spacing / 2.0, box.getLow(1) - spacing / 2.0, box.getLow(2) - spacing / 2.0},
218 {box.getHigh(0) + spacing / 2.0, box.getLow(1) + spacing / 2.0, box.getHigh(2) + spacing / 2.0});
221 {box.getLow(0) - spacing / 2.0, box.getLow(1) - spacing / 2.0, box.getLow(2) - spacing / 2.0},
222 {box.getLow(0) + spacing / 2.0, box.getHigh(1) + spacing / 2.0, box.getHigh(2) + spacing / 2.0});
225 {box.getHigh(0) - spacing / 2.0, box.getLow(1) - spacing / 2.0, box.getLow(2) - spacing / 2.0},
226 {box.getHigh(0) + spacing / 2.0, box.getHigh(1) + spacing / 2.0, box.getHigh(2) + spacing / 2.0});
229 {box.getLow(0) - spacing / 2.0, box.getLow(1) - spacing / 2.0, box.getLow(2) - spacing / 2.0},
230 {box.getHigh(0) + spacing / 2.0, box.getHigh(1) + spacing / 2.0, box.getLow(2) + spacing / 2.0});
233 {box.getLow(0) - spacing / 2.0, box.getLow(1) - spacing / 2.0, box.getHigh(2) - spacing / 2.0},
234 {box.getHigh(0) + spacing / 2.0, box.getHigh(1) + spacing / 2.0, box.getHigh(2) + spacing / 2.0});
246 auto Particles=domain;
247 auto it2 = Particles.getDomainIterator();
249 while (it2.isNext()) {
252 domain.getProp<1>(p) = -3.0*M_PI*M_PI*sin(M_PI*xp.
get(0))*sin(M_PI*xp.
get(1))*sin(M_PI*xp.
get(2));
253 domain.getProp<3>(p) = sin(M_PI*xp.
get(0))*sin(M_PI*xp.
get(1))*sin(M_PI*xp.
get(2));
254 if (front.isInside(xp) ==
true) {
256 front_p.last().get<0>() = p.getKey();
257 }
else if (back.isInside(xp) ==
true) {
259 back_p.last().get<0>() = p.getKey();
260 }
else if (left.isInside(xp) ==
true) {
262 left_p.last().get<0>() = p.getKey();
263 }
else if (right.isInside(xp) ==
true) {
265 right_p.last().get<0>() = p.getKey();
266 }
else if (up.isInside(xp) ==
true) {
268 up_p.last().get<0>() = p.getKey();
269 }
else if (down.isInside(xp) ==
true) {
271 down_p.last().get<0>() = p.getKey();
274 bulk.last().get<0>() = p.getKey();
280 DCPSE_scheme<
equations3d1,decltype(domain)> Solver( domain);
281 auto Poisson =
Lap(v);
296 v=abs(DCPSE_sol-RHS);
298 for(
int j=0;j<bulk.
size();j++)
299 {
auto p=bulk.get<0>(j);
300 if (fabs(domain.getProp<3>(p) - domain.getProp<2>(p)) >= worst1) {
301 worst1 = fabs(domain.getProp<3>(p) - domain.getProp<2>(p));
303 domain.getProp<4>(p) = fabs(domain.getProp<3>(p) - domain.getProp<2>(p));
309 BOOST_REQUIRE(worst1 < 0.031);
312 BOOST_AUTO_TEST_CASE(Sph_harm) {
313 BOOST_REQUIRE(openfpm::math::Y(2,1,0.5,0)+0.459674<0.00001);
319 const size_t sz[3] = {grd_sz,grd_sz,grd_sz};
321 size_t bc[3] = {NON_PERIODIC, NON_PERIODIC, NON_PERIODIC};
322 double spacing = 2.0 / (sz[0] - 1);
323 double rCut = 3.9*spacing;
327 vector_dist_ws<3, double, aggregate<double,VectorS<3, double>,
VectorS<3, double>,double,
VectorS<3, double>,double,double,
VectorS<3, double>,
VectorS<3, double>,
VectorS<3, double>>> Particles(0, box, bc, ghost);
330 auto &v_cl = create_vcluster();
335 auto it = Particles.getGridIterator(sz);
336 while (it.isNext()) {
338 double x = -1.0+key.get(0) * it.getSpacing(0);
339 double y = -1.0+key.get(1) * it.getSpacing(1);
340 double z = -1.0+key.get(2) * it.getSpacing(2);
341 double r=sqrt(x*x+y*y+z*z);
342 if (r<R-spacing/2.0) {
344 Particles.getLastPos()[0] = x;
345 Particles.getLastPos()[1] = y;
346 Particles.getLastPos()[2] = z;
347 Particles.getLastProp<8>()[0] = r;
349 Particles.getLastProp<8>()[1] = 0.0;
352 Particles.getLastProp<8>()[1] = std::atan2(sqrt(x*x+y*y),z);
354 Particles.getLastProp<8>()[2] = std::atan2(y,x);
359 int n_sp=
int(grd_sz)*
int(grd_sz)*3;
361 double Golden_angle=M_PI * (3.0 - sqrt(5.0));
363 for(
int i=1;i<=n_sp;i++)
365 double y = 1.0 - (i /double(n_sp - 1.0)) * 2.0;
366 double radius = sqrt(1 - y * y);
367 double Golden_theta = Golden_angle * i;
368 double x = cos(Golden_theta) * radius;
369 double z = sin(Golden_theta) * radius;
371 if (acos(z)==0 || acos(z)==M_PI){
372 std::cout<<
"Theta 0/Pi "<<std::endl;
377 Particles.getLastPos()[0] = x;
378 Particles.getLastPos()[1] = y;
379 Particles.getLastPos()[2] = z;
380 Particles.getLastProp<8>()[0] = 1.0 ;
381 Particles.getLastProp<8>()[1] = std::atan2(sqrt(x*x+y*y),z);
382 Particles.getLastProp<8>()[2] = std::atan2(y,x);
385 Particles.ghost_get<0>();
388 std::unordered_map<const lm,double,key_hash,key_equal> Vr;
389 std::unordered_map<const lm,double,key_hash,key_equal> V1;
390 std::unordered_map<const lm,double,key_hash,key_equal> V2;
394 for(
int l=0;l<=K;l++){
395 for(
int m=-l;m<=l;m++){
396 Vr[std::make_tuple(l,m)]=0.0;
397 V1[std::make_tuple(l,m)]=0.0;
398 V2[std::make_tuple(l,m)]=0.0;
404 V1[std::make_tuple(1,0)]=1.0;
406 auto it2 = Particles.getDomainIterator();
407 while (it2.isNext()) {
411 Particles.getProp<0>(p) =0;
415 Particles.getProp<0>(p) = 0;
416 std::vector<double> SVel;
417 SVel=openfpm::math::sumY<K>(xP[0],xP[1],xP[2],Vr,V1,V2);
418 double SP=openfpm::math::sumY_Scalar<K>(xP[0],xP[1],xP[2],Vr);
419 Particles.getProp<2>(p)[0] = SVel[0];
420 Particles.getProp<2>(p)[1] = SVel[1];
421 Particles.getProp<2>(p)[2] = SVel[2];
422 Particles.getProp<9>(p)[0] = SVel[0];
423 Particles.getProp<9>(p)[1] = SVel[1];
424 Particles.getProp<9>(p)[2] = SVel[2];
425 Particles.getProp<5>(p) = SP;
426 Particles.setSubset(p,1);
432 Particles.setSubset(p,0);
433 Particles.getProp<0>(p) = 0;
434 Particles.getProp<1>(p)[0] = 0;
435 Particles.getProp<1>(p)[1] = 0;
436 Particles.getProp<1>(p)[2] = 0;
441 vector_dist_subset<3, double, aggregate<double,VectorS<3, double>,
VectorS<3, double>,double,
VectorS<3, double>,double,double,
VectorS<3, double>,
VectorS<3, double>,
VectorS<3, double>>> Particles_bulk(Particles,0);
442 vector_dist_subset<3, double, aggregate<double,VectorS<3, double>,
VectorS<3, double>,double,
VectorS<3, double>,double,double,
VectorS<3, double>,
VectorS<3, double>,
VectorS<3, double>>> Particles_surface(Particles,1);
444 auto & bulk = Particles_bulk.getIds();
445 auto & Surface = Particles_surface.getIds();
447 for (
int j = 0; j < bulk.
size(); j++) {
448 auto p = bulk.get<0>(j);
452 std::unordered_map<const lm,double,key_hash,key_equal> Ur;
453 std::unordered_map<const lm,double,key_hash,key_equal> U2;
454 std::unordered_map<const lm,double,key_hash,key_equal> U1;
455 std::unordered_map<const lm,double,key_hash,key_equal> Plm;
457 for (
int l = 0; l <= K; l++) {
458 for (
int m = -l; m <= l; m++) {
459 auto Er= Vr.find(std::make_tuple(l,m));
460 auto E1= V1.find(std::make_tuple(l,m));
461 auto E2= V2.find(std::make_tuple(l,m));
462 std::vector<double> Sol=openfpm::math::sph_anasol_u(nu,l,m,Er->second,E1->second,E2->second,xP[0]);
463 Ur[std::make_tuple(l,m)]=Sol[0];
464 U1[std::make_tuple(l,m)]=Sol[1];
465 U2[std::make_tuple(l,m)]=Sol[2];
466 Plm[std::make_tuple(l,m)]=Sol[3];
471 if(fabs(xP[0])>=1e-5 && xP[1]>1e-5 && (M_PI-xP[1])>=1e-5)
473 std::vector<double> SVel = openfpm::math::sumY<K>(xP[0], xP[1], xP[2], Ur, U1, U2);
474 Particles.getProp<9>(p)[0] = SVel[0];
475 Particles.getProp<9>(p)[1] = SVel[1];
476 Particles.getProp<9>(p)[2] = SVel[2];
477 Particles.getProp<5>(p) = openfpm::math::sumY_Scalar<K>(xP[0], xP[1], xP[2], Plm);
481 auto P = getV<0>(Particles);
482 auto V = getV<1>(Particles);
483 auto V_B = getV<2>(Particles);
485 auto DIV = getV<3>(Particles);
486 auto V_t = getV<4>(Particles);
487 auto P_anal = getV<5>(Particles);
488 auto temp=getV<6>(Particles);
489 auto RHS = getV<7>(Particles);
490 auto P_bulk = getV<0>(Particles_bulk);
491 auto RHS_bulk = getV<7>(Particles_bulk);
492 auto V_anal = getV<9>(Particles);
504 double sampling2=1.9;
505 double rCut2=3.9*spacing;
507 Particles.ghost_get_subset();
508 auto verletList = Particles.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
509 auto verletList2 = Particles.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut2);
510 auto verletList_bulk = Particles_bulk.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
512 Derivative_x<decltype(verletList)> Dx(Particles, verletList, 2, rCut, support_options::RADIUS);
513 Derivative_y<decltype(verletList)> Dy(Particles, verletList, 2, rCut, support_options::RADIUS);
514 Derivative_z<decltype(verletList)> Dz(Particles, verletList, 2, rCut, support_options::RADIUS);
516 Derivative_x<decltype(verletList_bulk)> B_Dx(Particles_bulk, verletList_bulk, 2, rCut, support_options::RADIUS);
517 Derivative_y<decltype(verletList_bulk)> B_Dy(Particles_bulk, verletList_bulk, 2, rCut, support_options::RADIUS);
518 Derivative_z<decltype(verletList_bulk)> B_Dz(Particles_bulk, verletList_bulk, 2, rCut, support_options::RADIUS);
520 Derivative_xx<decltype(verletList2)> Dxx(Particles, verletList2, 2, rCut2, support_options::RADIUS);
521 Derivative_yy<decltype(verletList2)> Dyy(Particles, verletList2, 2, rCut2, support_options::RADIUS);
522 Derivative_zz<decltype(verletList2)> Dzz(Particles, verletList2, 2, rCut2, support_options::RADIUS);
530 double V_err_eps = 1e-5;
532 double V_err = 1, V_err_old;
535 int ctr = 0, errctr, Vreset = 0;
539 while (V_err >= V_err_eps && n <= nmax) {
541 Particles.ghost_get<0>(SKIP_LABELLING);
542 RHS_bulk[0] = B_Dx(
P);
543 RHS_bulk[1] = B_Dy(
P);
544 RHS_bulk[2] = B_Dz(
P);
545 DCPSE_scheme<
equations3d3, decltype(Particles)> Solver(Particles);
546 auto Stokes1 = nu * (Dxx(V[0])+Dyy(V[0])+Dzz(V[0]));
547 auto Stokes2 = nu * (Dxx(V[1])+Dyy(V[1])+Dzz(V[1]));
548 auto Stokes3 = nu * (Dxx(V[2])+Dyy(V[2])+Dzz(V[2]));
549 Solver.impose(Stokes1, bulk, RHS[0],
vx);
550 Solver.impose(Stokes2, bulk, RHS[1], vy);
551 Solver.impose(Stokes3, bulk, RHS[2], vz);
552 Solver.impose(V[0], Surface, V_B[0],
vx);
553 Solver.impose(V[1], Surface, V_B[1], vy);
554 Solver.impose(V[2], Surface, V_B[2], vz);
556 Solver.solve_with_solver(solverPetsc, V[0], V[1], V[2]);
561 Particles.ghost_get<1>();
562 DIV = -(Dx(V[0])+Dy(V[1])+Dz(V[2]));
566 for (
int j = 0; j < bulk.
size(); j++) {
567 auto p = bulk.get<0>(j);
568 sum += (Particles.getProp<4>(p)[0] - Particles.getProp<1>(p)[0]) *
569 (Particles.getProp<4>(p)[0] - Particles.getProp<1>(p)[0]) +
570 (Particles.getProp<4>(p)[1] - Particles.getProp<1>(p)[1]) *
571 (Particles.getProp<4>(p)[1] - Particles.getProp<1>(p)[1]) +
572 (Particles.getProp<4>(p)[2] - Particles.getProp<1>(p)[2]) *
573 (Particles.getProp<4>(p)[2] - Particles.getProp<1>(p)[2]);
574 sum1 += Particles.getProp<1>(p)[0] * Particles.getProp<1>(p)[0] +
575 Particles.getProp<1>(p)[1] * Particles.getProp<1>(p)[1] +
576 Particles.getProp<1>(p)[2] * Particles.getProp<1>(p)[2];
584 Particles.ghost_get<1>(SKIP_LABELLING);
587 if (V_err > V_err_old || abs(V_err_old - V_err) < 1e-14) {
594 std::cout <<
"CONVERGENCE LOOP BROKEN DUE TO INCREASE/VERY SLOW DECREASE IN ERROR" << std::endl;
609 for (
int j = 0; j < bulk.
size(); j++) {
610 auto p = bulk.get<0>(j);
612 if(xP[0]>=1e-5 && xP[1]>1e-5 && (M_PI-xP[1])>=1e-5)
614 double dx=Particles.getProp<9>(p)[0] - Particles.getProp<1>(p)[0];
615 double dy=Particles.getProp<9>(p)[1] - Particles.getProp<1>(p)[1];
616 double dz=Particles.getProp<9>(p)[2] - Particles.getProp<1>(p)[2];
617 Particles.getProp<4>(p)[0]=fabs(dx);
618 Particles.getProp<4>(p)[1]=fabs(dy);
619 Particles.getProp<4>(p)[2]=fabs(dz);
620 L2 += dx*dx+dy*dy+dz*dz;
621 if (std::max({fabs(dx),fabs(dy),fabs(dz)}) > worst) {
622 worst = std::max({fabs(dx),fabs(dy),fabs(dz)});
641 BOOST_REQUIRE(worst<1e-3);
646 BOOST_AUTO_TEST_CASE(Sph_harm_ig) {
647 BOOST_REQUIRE(openfpm::math::Y(2,1,0.5,0)+0.459674<0.00001);
653 const size_t sz[3] = {grd_sz,grd_sz,grd_sz};
655 size_t bc[3] = {NON_PERIODIC, NON_PERIODIC, NON_PERIODIC};
656 double spacing = 2.0 / (sz[0] - 1);
657 double rCut = 3.9*spacing;
661 vector_dist_ws<3, double, aggregate<double,VectorS<3, double>,
VectorS<3, double>,double,
VectorS<3, double>,double,double,
VectorS<3, double>,
VectorS<3, double>,
VectorS<3, double>>> Particles(0, box, bc, ghost);
664 auto &v_cl = create_vcluster();
669 auto it = Particles.getGridIterator(sz);
670 while (it.isNext()) {
672 double x = -1.0+key.get(0) * it.getSpacing(0);
673 double y = -1.0+key.get(1) * it.getSpacing(1);
674 double z = -1.0+key.get(2) * it.getSpacing(2);
675 double r=sqrt(x*x+y*y+z*z);
676 if (r<R-spacing/2.0) {
678 Particles.getLastPos()[0] = x;
679 Particles.getLastPos()[1] = y;
680 Particles.getLastPos()[2] = z;
681 Particles.getLastProp<8>()[0] = r;
683 Particles.getLastProp<8>()[1] = 0.0;
686 Particles.getLastProp<8>()[1] = std::atan2(sqrt(x*x+y*y),z);
688 Particles.getLastProp<8>()[2] = std::atan2(y,x);
693 int n_sp=
int(grd_sz)*
int(grd_sz)*3;
695 double Golden_angle=M_PI * (3.0 - sqrt(5.0));
697 for(
int i=1;i<=n_sp;i++)
699 double y = 1.0 - (i /double(n_sp - 1.0)) * 2.0;
700 double radius = sqrt(1 - y * y);
701 double Golden_theta = Golden_angle * i;
702 double x = cos(Golden_theta) * radius;
703 double z = sin(Golden_theta) * radius;
705 if (acos(z)==0 || acos(z)==M_PI){
706 std::cout<<
"Theta 0/Pi "<<std::endl;
711 Particles.getLastPos()[0] = x;
712 Particles.getLastPos()[1] = y;
713 Particles.getLastPos()[2] = z;
714 Particles.getLastProp<8>()[0] = 1.0 ;
715 Particles.getLastProp<8>()[1] = std::atan2(sqrt(x*x+y*y),z);
716 Particles.getLastProp<8>()[2] = std::atan2(y,x);
719 Particles.ghost_get<0>();
722 std::unordered_map<const lm,double,key_hash,key_equal> Vr;
723 std::unordered_map<const lm,double,key_hash,key_equal> V1;
724 std::unordered_map<const lm,double,key_hash,key_equal> V2;
728 for(
int l=0;l<=K;l++){
729 for(
int m=-l;m<=l;m++){
730 Vr[std::make_tuple(l,m)]=0.0;
731 V1[std::make_tuple(l,m)]=0.0;
732 V2[std::make_tuple(l,m)]=0.0;
738 V1[std::make_tuple(1,0)]=1.0;
740 auto it2 = Particles.getDomainIterator();
741 while (it2.isNext()) {
745 Particles.getProp<0>(p) =0;
749 Particles.getProp<0>(p) = 0;
750 std::vector<double> SVel;
751 SVel=openfpm::math::sumY<K>(xP[0],xP[1],xP[2],Vr,V1,V2);
752 double SP=openfpm::math::sumY_Scalar<K>(xP[0],xP[1],xP[2],Vr);
753 Particles.getProp<2>(p)[0] = SVel[0];
754 Particles.getProp<2>(p)[1] = SVel[1];
755 Particles.getProp<2>(p)[2] = SVel[2];
756 Particles.getProp<9>(p)[0] = SVel[0];
757 Particles.getProp<9>(p)[1] = SVel[1];
758 Particles.getProp<9>(p)[2] = SVel[2];
759 Particles.getProp<5>(p) = SP;
760 Particles.setSubset(p,1);
766 Particles.setSubset(p,0);
767 Particles.getProp<0>(p) = 0;
768 Particles.getProp<1>(p)[0] = 0;
769 Particles.getProp<1>(p)[1] = 0;
770 Particles.getProp<1>(p)[2] = 0;
775 vector_dist_subset<3, double, aggregate<double,VectorS<3, double>,
VectorS<3, double>,double,
VectorS<3, double>,double,double,
VectorS<3, double>,
VectorS<3, double>,
VectorS<3, double>>> Particles_bulk(Particles,0);
776 vector_dist_subset<3, double, aggregate<double,VectorS<3, double>,
VectorS<3, double>,double,
VectorS<3, double>,double,double,
VectorS<3, double>,
VectorS<3, double>,
VectorS<3, double>>> Particles_surface(Particles,1);
778 auto & bulk = Particles_bulk.getIds();
779 auto & Surface = Particles_surface.getIds();
781 for (
int j = 0; j < bulk.
size(); j++) {
782 auto p = bulk.get<0>(j);
786 std::unordered_map<const lm,double,key_hash,key_equal> Ur;
787 std::unordered_map<const lm,double,key_hash,key_equal> U2;
788 std::unordered_map<const lm,double,key_hash,key_equal> U1;
789 std::unordered_map<const lm,double,key_hash,key_equal> Plm;
791 for (
int l = 0; l <= K; l++) {
792 for (
int m = -l; m <= l; m++) {
793 auto Er= Vr.find(std::make_tuple(l,m));
794 auto E1= V1.find(std::make_tuple(l,m));
795 auto E2= V2.find(std::make_tuple(l,m));
796 std::vector<double> Sol=openfpm::math::sph_anasol_u(nu,l,m,Er->second,E1->second,E2->second,xP[0]);
797 Ur[std::make_tuple(l,m)]=Sol[0];
798 U1[std::make_tuple(l,m)]=Sol[1];
799 U2[std::make_tuple(l,m)]=Sol[2];
800 Plm[std::make_tuple(l,m)]=Sol[3];
805 if(fabs(xP[0])>=1e-5 && xP[1]>1e-5 && (M_PI-xP[1])>=1e-5)
807 std::vector<double> SVel = openfpm::math::sumY<K>(xP[0], xP[1], xP[2], Ur, U1, U2);
808 Particles.getProp<9>(p)[0] = SVel[0];
809 Particles.getProp<9>(p)[1] = SVel[1];
810 Particles.getProp<9>(p)[2] = SVel[2];
811 Particles.getProp<5>(p) = openfpm::math::sumY_Scalar<K>(xP[0], xP[1], xP[2], Plm);
815 auto P = getV<0>(Particles);
816 auto V = getV<1>(Particles);
817 auto V_B = getV<2>(Particles);
819 auto DIV = getV<3>(Particles);
820 auto V_t = getV<4>(Particles);
821 auto P_anal = getV<5>(Particles);
822 auto temp=getV<6>(Particles);
823 auto RHS = getV<7>(Particles);
824 auto P_bulk = getV<0>(Particles_bulk);
825 auto RHS_bulk = getV<7>(Particles_bulk);
826 auto V_anal = getV<9>(Particles);
838 double sampling2=1.9;
839 double rCut2=3.9*spacing;
841 Particles.ghost_get_subset();
842 auto verletList = Particles.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
843 auto verletList2 = Particles.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut2);
844 auto verletList_bulk = Particles_bulk.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut2);
846 Derivative_x<decltype(verletList)> Dx(Particles, verletList, 2, rCut, support_options::RADIUS);
847 Derivative_y<decltype(verletList)> Dy(Particles, verletList, 2, rCut, support_options::RADIUS);
848 Derivative_z<decltype(verletList)> Dz(Particles, verletList, 2, rCut, support_options::RADIUS);
850 Derivative_x<decltype(verletList_bulk)> B_Dx(Particles_bulk, verletList_bulk, 2, rCut, support_options::RADIUS);
851 Derivative_y<decltype(verletList_bulk)> B_Dy(Particles_bulk, verletList_bulk, 2, rCut, support_options::RADIUS);
852 Derivative_z<decltype(verletList_bulk)> B_Dz(Particles_bulk, verletList_bulk, 2, rCut, support_options::RADIUS);
854 Derivative_xx<decltype(verletList2)> Dxx(Particles, verletList2, 2, rCut2, support_options::RADIUS);
855 Derivative_yy<decltype(verletList2)> Dyy(Particles, verletList2, 2, rCut2, support_options::RADIUS);
856 Derivative_zz<decltype(verletList2)> Dzz(Particles, verletList2, 2, rCut2, support_options::RADIUS);
864 double V_err_eps = 1e-5;
866 double V_err = 1, V_err_old;
869 int ctr = 0, errctr, Vreset = 0;
873 while (V_err >= V_err_eps && n <= nmax) {
875 Particles.ghost_get<0>(SKIP_LABELLING);
876 RHS_bulk[0] = B_Dx(
P);
877 RHS_bulk[1] = B_Dy(
P);
878 RHS_bulk[2] = B_Dz(
P);
879 DCPSE_scheme<
equations3d3, decltype(Particles)> Solver(Particles);
880 auto Stokes1 = nu * (Dxx(V[0])+Dyy(V[0])+Dzz(V[0]));
881 auto Stokes2 = nu * (Dxx(V[1])+Dyy(V[1])+Dzz(V[1]));
882 auto Stokes3 = nu * (Dxx(V[2])+Dyy(V[2])+Dzz(V[2]));
883 Solver.impose(Stokes1, bulk, RHS[0],
vx);
884 Solver.impose(Stokes2, bulk, RHS[1], vy);
885 Solver.impose(Stokes3, bulk, RHS[2], vz);
886 Solver.impose(V[0], Surface, V_B[0],
vx);
887 Solver.impose(V[1], Surface, V_B[1], vy);
888 Solver.impose(V[2], Surface, V_B[2], vz);
889 Solver.impose_x_ig(bulk, V[0],
vx);
890 Solver.impose_x_ig(bulk, V[1], vy);
891 Solver.impose_x_ig(bulk, V[2], vz);
892 Solver.impose_x_ig(Surface, V[0],
vx);
893 Solver.impose_x_ig(Surface, V[1], vy);
894 Solver.impose_x_ig(Surface, V[2], vz);
896 Solver.solve_with_solver_ig(solverPetsc, V[0], V[1], V[2]);
901 Particles.ghost_get<1>();
902 DIV = -(Dx(V[0])+Dy(V[1])+Dz(V[2]));
906 for (
int j = 0; j < bulk.
size(); j++) {
907 auto p = bulk.get<0>(j);
908 sum += (Particles.getProp<4>(p)[0] - Particles.getProp<1>(p)[0]) *
909 (Particles.getProp<4>(p)[0] - Particles.getProp<1>(p)[0]) +
910 (Particles.getProp<4>(p)[1] - Particles.getProp<1>(p)[1]) *
911 (Particles.getProp<4>(p)[1] - Particles.getProp<1>(p)[1]) +
912 (Particles.getProp<4>(p)[2] - Particles.getProp<1>(p)[2]) *
913 (Particles.getProp<4>(p)[2] - Particles.getProp<1>(p)[2]);
914 sum1 += Particles.getProp<1>(p)[0] * Particles.getProp<1>(p)[0] +
915 Particles.getProp<1>(p)[1] * Particles.getProp<1>(p)[1] +
916 Particles.getProp<1>(p)[2] * Particles.getProp<1>(p)[2];
924 Particles.ghost_get<1>(SKIP_LABELLING);
927 if (V_err > V_err_old || abs(V_err_old - V_err) < 1e-14) {
934 std::cout <<
"CONVERGENCE LOOP BROKEN DUE TO INCREASE/VERY SLOW DECREASE IN ERROR" << std::endl;
950 for (
int j = 0; j < bulk.
size(); j++) {
951 auto p = bulk.get<0>(j);
953 if(xP[0]>=1e-5 && xP[1]>1e-5 && (M_PI-xP[1])>=1e-5)
955 double dx=Particles.getProp<9>(p)[0] - Particles.getProp<1>(p)[0];
956 double dy=Particles.getProp<9>(p)[1] - Particles.getProp<1>(p)[1];
957 double dz=Particles.getProp<9>(p)[2] - Particles.getProp<1>(p)[2];
958 Particles.getProp<4>(p)[0]=fabs(dx);
959 Particles.getProp<4>(p)[1]=fabs(dy);
960 Particles.getProp<4>(p)[2]=fabs(dz);
961 L2 += dx*dx+dy*dy+dz*dz;
962 if (std::max({fabs(dx),fabs(dy),fabs(dz)}) > worst) {
963 worst = std::max({fabs(dx),fabs(dy),fabs(dz)});
982 BOOST_REQUIRE(worst<1e-3);
985 BOOST_AUTO_TEST_SUITE_END()
This class represent an N-dimensional box.
Laplacian second order on h (spacing)
Test structure used for several test.
This class implement the point shape in an N-dimensional space.
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
Implementation of 1-D std::vector like structure.
This class is able to do Matrix inversion in parallel with PETSC solvers.
void setPreconditioner(PCType type)
Set the preconditioner of the linear solver.
Class for cpu time benchmarking.
void stop()
Stop the timer.
void start()
Start the timer.
double getwct()
Return the elapsed real time.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
It model an expression expr1 + ... exprn.