14#define BOOST_TEST_DYN_LINK
16#include "util/util_debug.hpp"
17#include <boost/test/unit_test.hpp>
19#include "../DCPSE_op.hpp"
20#include "../DCPSE_Solver.hpp"
21#include "Operators/Vector/vector_dist_operators.hpp"
22#include "Vector/vector_dist_subset.hpp"
23#include "../EqnsStruct.hpp"
24#include "util/SphericalHarmonics.hpp"
32BOOST_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 Advection Adv(domain, 2, rCut, 1.9,support_options::RADIUS);
101 auto v = getV<1>(domain);
102 auto P = getV<0>(domain);
103 auto dv = getV<3>(domain);
104 auto dP = getV<6>(domain);
110 domain.ghost_get<1>();
112 auto it2 = domain.getDomainIterator();
116 while (it2.isNext()) {
119 if (fabs(domain.getProp<3>(p)[1] - domain.getProp<4>(p)[1]) > worst1) {
120 worst1 = fabs(domain.getProp<3>(p)[1] - domain.getProp<4>(p)[1]);
127 BOOST_REQUIRE(worst1 < 0.03);
135 auto it3 = domain.getDomainIterator();
139 while (it3.isNext()) {
141 if (fabs(domain.getProp<6>(p) - domain.getProp<5>(p)) > worst2) {
142 worst2 = fabs(domain.getProp<6>(p) - domain.getProp<5>(p));
148 domain.deleteGhost();
149 BOOST_REQUIRE(worst2 < 0.03);
154 BOOST_AUTO_TEST_CASE(dcpse_poisson_dirichlet_anal3d) {
158 const size_t sz[3] = {grd_sz,grd_sz,grd_sz};
160 size_t bc[3] = {NON_PERIODIC, NON_PERIODIC,NON_PERIODIC};
161 double spacing = box.getHigh(0) / (sz[0] - 1);
163 double rCut = 3.1 * spacing;
164 BOOST_TEST_MESSAGE(
"Init vector_dist...");
166 vector_dist<3, double, aggregate<double,double,double,double,double,double>> domain(0, box, bc, ghost);
170 BOOST_TEST_MESSAGE(
"Init domain...");
172 auto it = domain.getGridIterator(sz);
173 while (it.isNext()) {
176 double x = key.get(0) * it.getSpacing(0);
177 domain.getLastPos()[0] = x;
178 double y = key.get(1) * it.getSpacing(1);
179 domain.getLastPos()[1] = y;
180 double z = key.get(2) * it.getSpacing(2);
181 domain.getLastPos()[2] = z;
185 BOOST_TEST_MESSAGE(
"Sync domain across processors...");
188 domain.ghost_get<0>();
190 Derivative_x Dx(domain, 2, rCut,1.9,support_options::RADIUS);
191 Derivative_y Dy(domain, 2, rCut,1.9,support_options::RADIUS);
192 Laplacian
Lap(domain, 2, rCut,1.3,support_options::RADIUS);
202 auto v = getV<0>(domain);
203 auto RHS=getV<1>(domain);
204 auto sol = getV<2>(domain);
205 auto anasol = getV<3>(domain);
206 auto err = getV<4>(domain);
207 auto DCPSE_sol=getV<5>(domain);
210 {box.getLow(0) - spacing / 2.0, box.getHigh(1) - spacing / 2.0, box.getLow(2) - spacing / 2.0},
211 {box.getHigh(0) + spacing / 2.0, box.getHigh(1) + spacing / 2.0, box.getHigh(2) + spacing / 2.0});
214 {box.getLow(0) - spacing / 2.0, box.getLow(1) - spacing / 2.0, box.getLow(2) - spacing / 2.0},
215 {box.getHigh(0) + spacing / 2.0, box.getLow(1) + spacing / 2.0, box.getHigh(2) + spacing / 2.0});
218 {box.getLow(0) - spacing / 2.0, box.getLow(1) - spacing / 2.0, box.getLow(2) - spacing / 2.0},
219 {box.getLow(0) + spacing / 2.0, box.getHigh(1) + spacing / 2.0, box.getHigh(2) + spacing / 2.0});
222 {box.getHigh(0) - spacing / 2.0, box.getLow(1) - spacing / 2.0, box.getLow(2) - spacing / 2.0},
223 {box.getHigh(0) + spacing / 2.0, box.getHigh(1) + spacing / 2.0, box.getHigh(2) + spacing / 2.0});
226 {box.getLow(0) - spacing / 2.0, box.getLow(1) - spacing / 2.0, box.getLow(2) - spacing / 2.0},
227 {box.getHigh(0) + spacing / 2.0, box.getHigh(1) + spacing / 2.0, box.getLow(2) + spacing / 2.0});
230 {box.getLow(0) - spacing / 2.0, box.getLow(1) - spacing / 2.0, box.getHigh(2) - spacing / 2.0},
231 {box.getHigh(0) + spacing / 2.0, box.getHigh(1) + spacing / 2.0, box.getHigh(2) + spacing / 2.0});
243 auto Particles=domain;
244 auto it2 = Particles.getDomainIterator();
246 while (it2.isNext()) {
249 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));
250 domain.getProp<3>(p) = sin(M_PI*xp.
get(0))*sin(M_PI*xp.
get(1))*sin(M_PI*xp.
get(2));
251 if (front.isInside(xp) ==
true) {
253 front_p.last().get<0>() = p.getKey();
254 }
else if (back.isInside(xp) ==
true) {
256 back_p.last().get<0>() = p.getKey();
257 }
else if (left.isInside(xp) ==
true) {
259 left_p.last().get<0>() = p.getKey();
260 }
else if (right.isInside(xp) ==
true) {
262 right_p.last().get<0>() = p.getKey();
263 }
else if (up.isInside(xp) ==
true) {
265 up_p.last().get<0>() = p.getKey();
266 }
else if (down.isInside(xp) ==
true) {
268 down_p.last().get<0>() = p.getKey();
271 bulk.last().get<0>() = p.getKey();
277 DCPSE_scheme<
equations3d1,
decltype(domain)> Solver( domain);
278 auto Poisson =
Lap(v);
293 v=abs(DCPSE_sol-RHS);
295 for(
int j=0;j<bulk.
size();j++)
296 {
auto p=bulk.get<0>(j);
297 if (fabs(domain.getProp<3>(p) - domain.getProp<2>(p)) >= worst1) {
298 worst1 = fabs(domain.getProp<3>(p) - domain.getProp<2>(p));
300 domain.getProp<4>(p) = fabs(domain.getProp<3>(p) - domain.getProp<2>(p));
306 BOOST_REQUIRE(worst1 < 0.031);
310 BOOST_AUTO_TEST_CASE(Sph_harm) {
311 BOOST_REQUIRE(openfpm::math::Y(2,1,0.5,0)+0.459674<0.00001);
317 const size_t sz[3] = {grd_sz,grd_sz,grd_sz};
319 size_t bc[3] = {NON_PERIODIC, NON_PERIODIC, NON_PERIODIC};
320 double spacing = 2.0 / (sz[0] - 1);
321 double rCut = 3.9*spacing;
325 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);
328 auto &v_cl = create_vcluster();
333 auto it = Particles.getGridIterator(sz);
334 while (it.isNext()) {
336 double x = -1.0+key.get(0) * it.getSpacing(0);
337 double y = -1.0+key.get(1) * it.getSpacing(1);
338 double z = -1.0+key.get(2) * it.getSpacing(2);
339 double r=sqrt(x*x+y*y+z*z);
340 if (r<R-spacing/2.0) {
342 Particles.getLastPos()[0] = x;
343 Particles.getLastPos()[1] = y;
344 Particles.getLastPos()[2] = z;
345 Particles.getLastProp<8>()[0] = r;
347 Particles.getLastProp<8>()[1] = 0.0;
350 Particles.getLastProp<8>()[1] = std::atan2(sqrt(x*x+y*y),z);
352 Particles.getLastProp<8>()[2] = std::atan2(y,x);
357 int n_sp=
int(grd_sz)*
int(grd_sz)*3;
359 double Golden_angle=M_PI * (3.0 - sqrt(5.0));
361 for(
int i=1;i<=n_sp;i++)
363 double y = 1.0 - (i /double(n_sp - 1.0)) * 2.0;
364 double radius = sqrt(1 - y * y);
365 double Golden_theta = Golden_angle * i;
366 double x = cos(Golden_theta) * radius;
367 double z = sin(Golden_theta) * radius;
369 if (acos(z)==0 || acos(z)==M_PI){
370 std::cout<<
"Theta 0/Pi "<<std::endl;
375 Particles.getLastPos()[0] = x;
376 Particles.getLastPos()[1] = y;
377 Particles.getLastPos()[2] = z;
378 Particles.getLastProp<8>()[0] = 1.0 ;
379 Particles.getLastProp<8>()[1] = std::atan2(sqrt(x*x+y*y),z);
380 Particles.getLastProp<8>()[2] = std::atan2(y,x);
383 Particles.ghost_get<0>();
386 std::unordered_map<const lm,double,key_hash,key_equal> Vr;
387 std::unordered_map<const lm,double,key_hash,key_equal> V1;
388 std::unordered_map<const lm,double,key_hash,key_equal> V2;
392 for(
int l=0;l<=K;l++){
393 for(
int m=-l;m<=l;m++){
394 Vr[std::make_tuple(l,m)]=0.0;
395 V1[std::make_tuple(l,m)]=0.0;
396 V2[std::make_tuple(l,m)]=0.0;
402 V1[std::make_tuple(1,0)]=1.0;
404 auto it2 = Particles.getDomainIterator();
405 while (it2.isNext()) {
409 Particles.getProp<0>(p) =0;
413 Particles.getProp<0>(p) = 0;
414 std::vector<double> SVel;
415 SVel=openfpm::math::sumY<K>(xP[0],xP[1],xP[2],Vr,V1,V2);
416 double SP=openfpm::math::sumY_Scalar<K>(xP[0],xP[1],xP[2],Vr);
417 Particles.getProp<2>(p)[0] = SVel[0];
418 Particles.getProp<2>(p)[1] = SVel[1];
419 Particles.getProp<2>(p)[2] = SVel[2];
420 Particles.getProp<9>(p)[0] = SVel[0];
421 Particles.getProp<9>(p)[1] = SVel[1];
422 Particles.getProp<9>(p)[2] = SVel[2];
423 Particles.getProp<5>(p) = SP;
424 Particles.setSubset(p,1);
430 Particles.setSubset(p,0);
431 Particles.getProp<0>(p) = 0;
432 Particles.getProp<1>(p)[0] = 0;
433 Particles.getProp<1>(p)[1] = 0;
434 Particles.getProp<1>(p)[2] = 0;
439 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);
440 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);
442 auto & bulk = Particles_bulk.getIds();
443 auto & Surface = Particles_surface.getIds();
445 for (
int j = 0; j < bulk.
size(); j++) {
446 auto p = bulk.get<0>(j);
450 std::unordered_map<const lm,double,key_hash,key_equal> Ur;
451 std::unordered_map<const lm,double,key_hash,key_equal> U2;
452 std::unordered_map<const lm,double,key_hash,key_equal> U1;
453 std::unordered_map<const lm,double,key_hash,key_equal> Plm;
455 for (
int l = 0; l <= K; l++) {
456 for (
int m = -l; m <= l; m++) {
457 auto Er= Vr.find(std::make_tuple(l,m));
458 auto E1= V1.find(std::make_tuple(l,m));
459 auto E2= V2.find(std::make_tuple(l,m));
460 std::vector<double> Sol=openfpm::math::sph_anasol_u(nu,l,m,Er->second,E1->second,E2->second,xP[0]);
461 Ur[std::make_tuple(l,m)]=Sol[0];
462 U1[std::make_tuple(l,m)]=Sol[1];
463 U2[std::make_tuple(l,m)]=Sol[2];
464 Plm[std::make_tuple(l,m)]=Sol[3];
469 if(fabs(xP[0])>=1e-5 && xP[1]>1e-5 && (M_PI-xP[1])>=1e-5)
471 std::vector<double> SVel = openfpm::math::sumY<K>(xP[0], xP[1], xP[2], Ur, U1, U2);
472 Particles.getProp<9>(p)[0] = SVel[0];
473 Particles.getProp<9>(p)[1] = SVel[1];
474 Particles.getProp<9>(p)[2] = SVel[2];
475 Particles.getProp<5>(p) = openfpm::math::sumY_Scalar<K>(xP[0], xP[1], xP[2], Plm);
479 auto P = getV<0>(Particles);
480 auto V = getV<1>(Particles);
481 auto V_B = getV<2>(Particles);
483 auto DIV = getV<3>(Particles);
484 auto V_t = getV<4>(Particles);
485 auto P_anal = getV<5>(Particles);
486 auto temp=getV<6>(Particles);
487 auto RHS = getV<7>(Particles);
488 auto P_bulk = getV<0>(Particles_bulk);
489 auto RHS_bulk = getV<7>(Particles_bulk);
490 auto V_anal = getV<9>(Particles);
502 double sampling2=1.9;
503 double rCut2=3.9*spacing;
505 Derivative_x Dx(Particles, 2, rCut,sampling, support_options::RADIUS),B_Dx(Particles_bulk, 2, rCut,sampling, support_options::RADIUS);
506 Derivative_y Dy(Particles, 2, rCut,sampling, support_options::RADIUS),B_Dy(Particles_bulk, 2, rCut,sampling, support_options::RADIUS);
507 Derivative_z Dz(Particles, 2, rCut,sampling, support_options::RADIUS),B_Dz(Particles_bulk, 2, rCut,sampling, support_options::RADIUS);
508 Derivative_xx Dxx(Particles, 2, rCut2,sampling2,support_options::RADIUS);
509 Derivative_yy Dyy(Particles, 2, rCut2,sampling2,support_options::RADIUS);
510 Derivative_zz Dzz(Particles, 2, rCut2,sampling2,support_options::RADIUS);
514 solverPetsc.setPreconditioner(PCNONE);
518 double V_err_eps = 1e-5;
520 double V_err = 1, V_err_old;
523 int ctr = 0, errctr, Vreset = 0;
527 while (V_err >= V_err_eps && n <= nmax) {
529 Particles.ghost_get<0>(SKIP_LABELLING);
530 RHS_bulk[0] = B_Dx(
P);
531 RHS_bulk[1] = B_Dy(
P);
532 RHS_bulk[2] = B_Dz(
P);
533 DCPSE_scheme<
equations3d3,
decltype(Particles)> Solver(Particles);
534 auto Stokes1 = nu * (Dxx(V[0])+Dyy(V[0])+Dzz(V[0]));
535 auto Stokes2 = nu * (Dxx(V[1])+Dyy(V[1])+Dzz(V[1]));
536 auto Stokes3 = nu * (Dxx(V[2])+Dyy(V[2])+Dzz(V[2]));
537 Solver.impose(Stokes1, bulk, RHS[0],
vx);
538 Solver.impose(Stokes2, bulk, RHS[1], vy);
539 Solver.impose(Stokes3, bulk, RHS[2], vz);
540 Solver.impose(V[0], Surface, V_B[0],
vx);
541 Solver.impose(V[1], Surface, V_B[1], vy);
542 Solver.impose(V[2], Surface, V_B[2], vz);
544 Solver.solve_with_solver(solverPetsc, V[0], V[1], V[2]);
549 Particles.ghost_get<1>();
550 DIV = -(Dx(V[0])+Dy(V[1])+Dz(V[2]));
554 for (
int j = 0; j < bulk.
size(); j++) {
555 auto p = bulk.get<0>(j);
556 sum += (Particles.getProp<4>(p)[0] - Particles.getProp<1>(p)[0]) *
557 (Particles.getProp<4>(p)[0] - Particles.getProp<1>(p)[0]) +
558 (Particles.getProp<4>(p)[1] - Particles.getProp<1>(p)[1]) *
559 (Particles.getProp<4>(p)[1] - Particles.getProp<1>(p)[1]) +
560 (Particles.getProp<4>(p)[2] - Particles.getProp<1>(p)[2]) *
561 (Particles.getProp<4>(p)[2] - Particles.getProp<1>(p)[2]);
562 sum1 += Particles.getProp<1>(p)[0] * Particles.getProp<1>(p)[0] +
563 Particles.getProp<1>(p)[1] * Particles.getProp<1>(p)[1] +
564 Particles.getProp<1>(p)[2] * Particles.getProp<1>(p)[2];
572 Particles.ghost_get<1>(SKIP_LABELLING);
575 if (V_err > V_err_old || abs(V_err_old - V_err) < 1e-14) {
582 std::cout <<
"CONVERGENCE LOOP BROKEN DUE TO INCREASE/VERY SLOW DECREASE IN ERROR" << std::endl;
597 for (
int j = 0; j < bulk.
size(); j++) {
598 auto p = bulk.get<0>(j);
600 if(xP[0]>=1e-5 && xP[1]>1e-5 && (M_PI-xP[1])>=1e-5)
602 double dx=Particles.getProp<9>(p)[0] - Particles.getProp<1>(p)[0];
603 double dy=Particles.getProp<9>(p)[1] - Particles.getProp<1>(p)[1];
604 double dz=Particles.getProp<9>(p)[2] - Particles.getProp<1>(p)[2];
605 Particles.getProp<4>(p)[0]=fabs(dx);
606 Particles.getProp<4>(p)[1]=fabs(dy);
607 Particles.getProp<4>(p)[2]=fabs(dz);
608 L2 += dx*dx+dy*dy+dz*dz;
609 if (std::max({fabs(dx),fabs(dy),fabs(dz)}) > worst) {
610 worst = std::max({fabs(dx),fabs(dy),fabs(dz)});
629 BOOST_REQUIRE(worst<1e-3);
634 BOOST_AUTO_TEST_CASE(Sph_harm_ig) {
635 BOOST_REQUIRE(openfpm::math::Y(2,1,0.5,0)+0.459674<0.00001);
641 const size_t sz[3] = {grd_sz,grd_sz,grd_sz};
643 size_t bc[3] = {NON_PERIODIC, NON_PERIODIC, NON_PERIODIC};
644 double spacing = 2.0 / (sz[0] - 1);
645 double rCut = 3.9*spacing;
649 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);
652 auto &v_cl = create_vcluster();
657 auto it = Particles.getGridIterator(sz);
658 while (it.isNext()) {
660 double x = -1.0+key.get(0) * it.getSpacing(0);
661 double y = -1.0+key.get(1) * it.getSpacing(1);
662 double z = -1.0+key.get(2) * it.getSpacing(2);
663 double r=sqrt(x*x+y*y+z*z);
664 if (r<R-spacing/2.0) {
666 Particles.getLastPos()[0] = x;
667 Particles.getLastPos()[1] = y;
668 Particles.getLastPos()[2] = z;
669 Particles.getLastProp<8>()[0] = r;
671 Particles.getLastProp<8>()[1] = 0.0;
674 Particles.getLastProp<8>()[1] = std::atan2(sqrt(x*x+y*y),z);
676 Particles.getLastProp<8>()[2] = std::atan2(y,x);
681 int n_sp=
int(grd_sz)*
int(grd_sz)*3;
683 double Golden_angle=M_PI * (3.0 - sqrt(5.0));
685 for(
int i=1;i<=n_sp;i++)
687 double y = 1.0 - (i /double(n_sp - 1.0)) * 2.0;
688 double radius = sqrt(1 - y * y);
689 double Golden_theta = Golden_angle * i;
690 double x = cos(Golden_theta) * radius;
691 double z = sin(Golden_theta) * radius;
693 if (acos(z)==0 || acos(z)==M_PI){
694 std::cout<<
"Theta 0/Pi "<<std::endl;
699 Particles.getLastPos()[0] = x;
700 Particles.getLastPos()[1] = y;
701 Particles.getLastPos()[2] = z;
702 Particles.getLastProp<8>()[0] = 1.0 ;
703 Particles.getLastProp<8>()[1] = std::atan2(sqrt(x*x+y*y),z);
704 Particles.getLastProp<8>()[2] = std::atan2(y,x);
707 Particles.ghost_get<0>();
710 std::unordered_map<const lm,double,key_hash,key_equal> Vr;
711 std::unordered_map<const lm,double,key_hash,key_equal> V1;
712 std::unordered_map<const lm,double,key_hash,key_equal> V2;
716 for(
int l=0;l<=K;l++){
717 for(
int m=-l;m<=l;m++){
718 Vr[std::make_tuple(l,m)]=0.0;
719 V1[std::make_tuple(l,m)]=0.0;
720 V2[std::make_tuple(l,m)]=0.0;
726 V1[std::make_tuple(1,0)]=1.0;
728 auto it2 = Particles.getDomainIterator();
729 while (it2.isNext()) {
733 Particles.getProp<0>(p) =0;
737 Particles.getProp<0>(p) = 0;
738 std::vector<double> SVel;
739 SVel=openfpm::math::sumY<K>(xP[0],xP[1],xP[2],Vr,V1,V2);
740 double SP=openfpm::math::sumY_Scalar<K>(xP[0],xP[1],xP[2],Vr);
741 Particles.getProp<2>(p)[0] = SVel[0];
742 Particles.getProp<2>(p)[1] = SVel[1];
743 Particles.getProp<2>(p)[2] = SVel[2];
744 Particles.getProp<9>(p)[0] = SVel[0];
745 Particles.getProp<9>(p)[1] = SVel[1];
746 Particles.getProp<9>(p)[2] = SVel[2];
747 Particles.getProp<5>(p) = SP;
748 Particles.setSubset(p,1);
754 Particles.setSubset(p,0);
755 Particles.getProp<0>(p) = 0;
756 Particles.getProp<1>(p)[0] = 0;
757 Particles.getProp<1>(p)[1] = 0;
758 Particles.getProp<1>(p)[2] = 0;
763 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);
764 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);
766 auto & bulk = Particles_bulk.getIds();
767 auto & Surface = Particles_surface.getIds();
769 for (
int j = 0; j < bulk.
size(); j++) {
770 auto p = bulk.get<0>(j);
774 std::unordered_map<const lm,double,key_hash,key_equal> Ur;
775 std::unordered_map<const lm,double,key_hash,key_equal> U2;
776 std::unordered_map<const lm,double,key_hash,key_equal> U1;
777 std::unordered_map<const lm,double,key_hash,key_equal> Plm;
779 for (
int l = 0; l <= K; l++) {
780 for (
int m = -l; m <= l; m++) {
781 auto Er= Vr.find(std::make_tuple(l,m));
782 auto E1= V1.find(std::make_tuple(l,m));
783 auto E2= V2.find(std::make_tuple(l,m));
784 std::vector<double> Sol=openfpm::math::sph_anasol_u(nu,l,m,Er->second,E1->second,E2->second,xP[0]);
785 Ur[std::make_tuple(l,m)]=Sol[0];
786 U1[std::make_tuple(l,m)]=Sol[1];
787 U2[std::make_tuple(l,m)]=Sol[2];
788 Plm[std::make_tuple(l,m)]=Sol[3];
793 if(fabs(xP[0])>=1e-5 && xP[1]>1e-5 && (M_PI-xP[1])>=1e-5)
795 std::vector<double> SVel = openfpm::math::sumY<K>(xP[0], xP[1], xP[2], Ur, U1, U2);
796 Particles.getProp<9>(p)[0] = SVel[0];
797 Particles.getProp<9>(p)[1] = SVel[1];
798 Particles.getProp<9>(p)[2] = SVel[2];
799 Particles.getProp<5>(p) = openfpm::math::sumY_Scalar<K>(xP[0], xP[1], xP[2], Plm);
803 auto P = getV<0>(Particles);
804 auto V = getV<1>(Particles);
805 auto V_B = getV<2>(Particles);
807 auto DIV = getV<3>(Particles);
808 auto V_t = getV<4>(Particles);
809 auto P_anal = getV<5>(Particles);
810 auto temp=getV<6>(Particles);
811 auto RHS = getV<7>(Particles);
812 auto P_bulk = getV<0>(Particles_bulk);
813 auto RHS_bulk = getV<7>(Particles_bulk);
814 auto V_anal = getV<9>(Particles);
826 double sampling2=1.9;
827 double rCut2=3.9*spacing;
829 Derivative_x Dx(Particles, 2, rCut,sampling, support_options::RADIUS),B_Dx(Particles_bulk, 2, rCut,sampling, support_options::RADIUS);
830 Derivative_y Dy(Particles, 2, rCut,sampling, support_options::RADIUS),B_Dy(Particles_bulk, 2, rCut,sampling, support_options::RADIUS);
831 Derivative_z Dz(Particles, 2, rCut,sampling, support_options::RADIUS),B_Dz(Particles_bulk, 2, rCut,sampling, support_options::RADIUS);
832 Derivative_xx Dxx(Particles, 2, rCut2,sampling2,support_options::RADIUS);
833 Derivative_yy Dyy(Particles, 2, rCut2,sampling2,support_options::RADIUS);
834 Derivative_zz Dzz(Particles, 2, rCut2,sampling2,support_options::RADIUS);
838 solverPetsc.setPreconditioner(PCNONE);
842 double V_err_eps = 1e-5;
844 double V_err = 1, V_err_old;
847 int ctr = 0, errctr, Vreset = 0;
851 while (V_err >= V_err_eps && n <= nmax) {
853 Particles.ghost_get<0>(SKIP_LABELLING);
854 RHS_bulk[0] = B_Dx(
P);
855 RHS_bulk[1] = B_Dy(
P);
856 RHS_bulk[2] = B_Dz(
P);
857 DCPSE_scheme<
equations3d3,
decltype(Particles)> Solver(Particles);
858 auto Stokes1 = nu * (Dxx(V[0])+Dyy(V[0])+Dzz(V[0]));
859 auto Stokes2 = nu * (Dxx(V[1])+Dyy(V[1])+Dzz(V[1]));
860 auto Stokes3 = nu * (Dxx(V[2])+Dyy(V[2])+Dzz(V[2]));
861 Solver.impose(Stokes1, bulk, RHS[0],
vx);
862 Solver.impose(Stokes2, bulk, RHS[1], vy);
863 Solver.impose(Stokes3, bulk, RHS[2], vz);
864 Solver.impose(V[0], Surface, V_B[0],
vx);
865 Solver.impose(V[1], Surface, V_B[1], vy);
866 Solver.impose(V[2], Surface, V_B[2], vz);
867 Solver.impose_x_ig(bulk, V[0],
vx);
868 Solver.impose_x_ig(bulk, V[1], vy);
869 Solver.impose_x_ig(bulk, V[2], vz);
870 Solver.impose_x_ig(Surface, V[0],
vx);
871 Solver.impose_x_ig(Surface, V[1], vy);
872 Solver.impose_x_ig(Surface, V[2], vz);
874 Solver.solve_with_solver_ig(solverPetsc, V[0], V[1], V[2]);
879 Particles.ghost_get<1>();
880 DIV = -(Dx(V[0])+Dy(V[1])+Dz(V[2]));
884 for (
int j = 0; j < bulk.
size(); j++) {
885 auto p = bulk.get<0>(j);
886 sum += (Particles.getProp<4>(p)[0] - Particles.getProp<1>(p)[0]) *
887 (Particles.getProp<4>(p)[0] - Particles.getProp<1>(p)[0]) +
888 (Particles.getProp<4>(p)[1] - Particles.getProp<1>(p)[1]) *
889 (Particles.getProp<4>(p)[1] - Particles.getProp<1>(p)[1]) +
890 (Particles.getProp<4>(p)[2] - Particles.getProp<1>(p)[2]) *
891 (Particles.getProp<4>(p)[2] - Particles.getProp<1>(p)[2]);
892 sum1 += Particles.getProp<1>(p)[0] * Particles.getProp<1>(p)[0] +
893 Particles.getProp<1>(p)[1] * Particles.getProp<1>(p)[1] +
894 Particles.getProp<1>(p)[2] * Particles.getProp<1>(p)[2];
902 Particles.ghost_get<1>(SKIP_LABELLING);
905 if (V_err > V_err_old || abs(V_err_old - V_err) < 1e-14) {
912 std::cout <<
"CONVERGENCE LOOP BROKEN DUE TO INCREASE/VERY SLOW DECREASE IN ERROR" << std::endl;
928 for (
int j = 0; j < bulk.
size(); j++) {
929 auto p = bulk.get<0>(j);
931 if(xP[0]>=1e-5 && xP[1]>1e-5 && (M_PI-xP[1])>=1e-5)
933 double dx=Particles.getProp<9>(p)[0] - Particles.getProp<1>(p)[0];
934 double dy=Particles.getProp<9>(p)[1] - Particles.getProp<1>(p)[1];
935 double dz=Particles.getProp<9>(p)[2] - Particles.getProp<1>(p)[2];
936 Particles.getProp<4>(p)[0]=fabs(dx);
937 Particles.getProp<4>(p)[1]=fabs(dy);
938 Particles.getProp<4>(p)[2]=fabs(dz);
939 L2 += dx*dx+dy*dy+dz*dz;
940 if (std::max({fabs(dx),fabs(dy),fabs(dz)}) > worst) {
941 worst = std::max({fabs(dx),fabs(dy),fabs(dz)});
960 BOOST_REQUIRE(worst<1e-3);
963BOOST_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.
In case T does not match the PETSC precision compilation create a stub structure.
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.