13 #define BOOST_TEST_DYN_LINK
15 #include "util/util_debug.hpp"
16 #include <boost/test/unit_test.hpp>
18 #include "DCPSE/DCPSE_op/DCPSE_op.hpp"
19 #include "DCPSE/DCPSE_op/DCPSE_Solver.hpp"
20 #include "Operators/Vector/vector_dist_operators.hpp"
21 #include "Vector/vector_dist_subset.hpp"
22 #include "DCPSE/DCPSE_op/EqnsStruct.hpp"
29 BOOST_AUTO_TEST_SUITE(dcpse_op_subset_suite_tests)
31 BOOST_AUTO_TEST_CASE(dcpse_op_subset_tests) {
34 size_t edgeSemiSize = 40;
35 const size_t sz[2] = {2 * edgeSemiSize, 2 * edgeSemiSize};
37 size_t bc[2] = {NON_PERIODIC, NON_PERIODIC};
39 spacing[0] = 1.0 / (sz[0] - 1);
40 spacing[1] = 1.0 / (sz[1] - 1);
41 double rCut = 3.9 * spacing[0];
43 double sampling_factor = 4.0;
45 BOOST_TEST_MESSAGE(
"Init vector_dist...");
46 double sigma2 = spacing[0] * spacing[1] / (2 * 4);
48 vector_dist_ws<2, double, aggregate<double, double, double, VectorS<2, double>,
VectorS<2, double>,
VectorS<2, double>,
double>> Particles(0, box,
51 Particles.setPropNames({
"0",
"1",
"2",
"3",
"4",
"5",
"6"});
53 BOOST_TEST_MESSAGE(
"Init Particles...");
54 std::mt19937 rng{6666666};
56 std::normal_distribution<> gaussian{0, sigma2};
61 auto it = Particles.getGridIterator(sz);
64 double minNormOne = 999;
69 mem_id k0 = key.get(0);
70 double x = k0 * spacing[0];
71 Particles.getLastPos()[0] = x;
72 mem_id k1 = key.get(1);
73 double y = k1 * spacing[1];
74 Particles.getLastPos()[1] = y;
76 Particles.template getLastProp<0>() = sin(Particles.getLastPos()[0]) + sin(Particles.getLastPos()[1]);
78 if (k0 != 0 && k1 != 0 && k0 != sz[0] -1 && k1 != sz[1] - 1)
83 Particles.getLastSubset(0);
89 Particles.getLastSubset(1);
96 BOOST_TEST_MESSAGE(
"Sync Particles across processors...");
99 Particles.ghost_get<0>();
100 Particles.ghost_get_subset();
102 auto git = Particles.getGhostIterator();
108 Particles.template getProp<0>(p) = std::numeric_limits<double>::quiet_NaN();
113 vector_dist_subset<2, double, aggregate<double, double, double, VectorS<2, double>,
VectorS<2, double>,
VectorS<2, double>,
double>> Particles_bulk(Particles,0);
114 vector_dist_subset<2, double, aggregate<double, double, double, VectorS<2, double>,
VectorS<2, double>,
VectorS<2, double>,
double>> Particles_boundary(Particles,1);
115 auto & boundary = Particles_boundary.getIds();
118 auto P = getV<0>(Particles);
119 auto Out = getV<1>(Particles);
120 auto Pb = getV<2>(Particles);
121 auto Out_V = getV<3>(Particles);
124 auto P_bulk = getV<2>(Particles_bulk);
125 auto Out_bulk = getV<1>(Particles_bulk);
126 auto Out_V_bulk = getV<3>(Particles_bulk);
139 auto verletList_bulk = Particles_bulk.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
141 Derivative_x<decltype(verletList_bulk)> Dx_bulk(Particles, Particles_bulk, verletList_bulk, 2, rCut, support_options::RADIUS);
142 Derivative_y<decltype(verletList_bulk)> Dy_bulk(Particles, Particles_bulk, verletList_bulk, 2, rCut, support_options::RADIUS);
144 Out_bulk = Dx_bulk(
P);
145 Out_V_bulk[0] =
P + Dx_bulk(
P);
146 Out_V_bulk[1] = Out_V[0] +Dy_bulk(
P);
151 auto & v_cl = create_vcluster();
154 auto it2 = Particles_bulk.getDomainIterator();
164 is_nan |= std::isnan(Particles_bulk.template getProp<1>(p));
171 BOOST_REQUIRE_EQUAL(is_nan,
true);
177 Particles.ghost_get<0>();
178 Particles.write(
"TEST");
180 for (
int i = 0 ; i < boundary.size() ; i++)
182 Particles.template getProp<0>(boundary.template get<0>(i)) = std::numeric_limits<double>::quiet_NaN();
185 Particles.ghost_get<0>();
187 Out_bulk = Dx_bulk(
P);
188 Out_V_bulk[0] =
P + Dx_bulk(
P);
189 Out_V_bulk[1] = Out_V[0] +Dy_bulk(
P);
191 auto it2 = Particles_bulk.getDomainIterator();
196 BOOST_REQUIRE_EQUAL(Particles_bulk.getProp<2>(p),15.0);
197 BOOST_REQUIRE(fabs(Particles_bulk.getProp<1>(p) - cos(Particles_bulk.getPos(p)[0])) < 0.005 );
198 BOOST_REQUIRE(fabs(Particles_bulk.getProp<3>(p)[0] - Particles_bulk.getProp<0>(p) - cos(Particles_bulk.getPos(p)[0])) < 0.001 );
199 BOOST_REQUIRE(fabs(Particles_bulk.getProp<3>(p)[1] - Particles_bulk.getProp<3>(p)[0] - cos(Particles_bulk.getPos(p)[1])) < 0.001 );
207 BOOST_AUTO_TEST_CASE(dcpse_op_subset_PC_lid) {
212 size_t edgeSemiSize = 20;
213 const size_t sz[2] = {2 * edgeSemiSize+1, 2 * edgeSemiSize+1};
215 size_t bc[2] = {NON_PERIODIC, NON_PERIODIC};
217 spacing[0] = 1.0 / (sz[0] - 1);
218 spacing[1] = 1.0 / (sz[1] - 1);
219 double rCut = 3.9 * spacing[0];
221 double sampling_factor = 4.0;
223 BOOST_TEST_MESSAGE(
"Init vector_dist...");
224 double sigma2 = spacing[0] * spacing[1] / (2 * 4);
225 auto &v_cl = create_vcluster();
227 typedef aggregate<double, VectorS<2, double>,
VectorS<2, double>,
VectorS<2, double>,double,
VectorS<2, double>,
VectorS<2, double>,
double> particle_type;
232 BOOST_TEST_MESSAGE(
"Init Particles...");
237 auto it = Particles.getGridIterator(sz);
242 mem_id k0 = key.get(0);
243 double xp0 = k0 * spacing[0];
244 Particles.getLastPos()[0] = xp0;
245 mem_id k1 = key.get(1);
246 double yp0 = k1 * spacing[1];
247 Particles.getLastPos()[1] = yp0;
250 BOOST_TEST_MESSAGE(
"Sync Particles across processors...");
252 Particles.ghost_get<0>();
253 Particles.ghost_get_subset();
255 auto it2 = Particles.getDomainIterator();
256 while (it2.isNext()) {
259 if (xp[0] != 0 && xp[1] != 0 && xp[0] != 1.0 && xp[1] != 1.0) {
262 Particles.setSubset(p,0);
263 Particles.getProp<3>(p)[x] = 3.0;
264 Particles.getProp<3>(p)[y] = 3.0;
268 Particles.setSubset(p,1);
269 Particles.getProp<3>(p)[x] = xp[0]*xp[0]+xp[1]*xp[1];
270 Particles.getProp<3>(p)[y] = xp[0]*xp[0]-2*xp[0]*xp[1];
272 Particles.getProp<6>(p)[x] = xp[0]*xp[0]+xp[1]*xp[1];
273 Particles.getProp<6>(p)[y] = xp[0]*xp[0]-2*xp[0]*xp[1];
274 Particles.getProp<7>(p) = xp[0]+xp[1]-1.0;
281 auto & bulk = Particles_bulk.getIds();
282 auto & boundary = Particles_boundary.getIds();
284 auto P = getV<0>(Particles);
285 auto V = getV<1>(Particles);
286 auto RHS = getV<2>(Particles);
287 auto dV = getV<3>(Particles);
288 auto div = getV<4>(Particles);
289 auto V_star = getV<5>(Particles);
292 auto P_bulk = getV<0>(Particles_bulk);
293 auto RHS_bulk =getV<2>(Particles_bulk);
297 auto verletList = Particles.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
298 auto verletList_bulk = Particles_bulk.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
300 Derivative_x<decltype(verletList)> Dx(Particles, verletList, 2, rCut, support_options::RADIUS);
301 Derivative_xx<decltype(verletList)> Dxx(Particles, verletList, 2, rCut, support_options::RADIUS);
302 Derivative_yy<decltype(verletList)> Dyy(Particles, verletList, 2, rCut, support_options::RADIUS);
303 Derivative_y<decltype(verletList)> Dy(Particles, verletList, 2, rCut, support_options::RADIUS);
304 Derivative_x<decltype(verletList_bulk)> Bulk_Dx(Particles, Particles_bulk, verletList_bulk, 2, rCut, support_options::RADIUS);
305 Derivative_y<decltype(verletList_bulk)> Bulk_Dy(Particles, Particles_bulk, verletList_bulk, 2, rCut, support_options::RADIUS);
307 int n = 0, nmax = 5, ctr = 0, errctr=1, Vreset = 0;
318 double sum, sum1, sum_k,V_err_eps=1e-3,V_err_old;
319 auto Stokes1=Dxx(V[x])+Dyy(V[x]);
320 auto Stokes2=Dxx(V[y])+Dyy(V[y]);
329 while (V_err >= V_err_eps && n <= nmax) {
330 Particles.ghost_get<0>(SKIP_LABELLING);
331 RHS_bulk[x] = dV[x] + Bulk_Dx(
P);
332 RHS_bulk[y] = dV[y] + Bulk_Dy(
P);
333 DCPSE_scheme<
equations2d2, decltype(Particles)> Solver(Particles);
334 Solver.impose(Stokes1, bulk, RHS[0],
vx);
335 Solver.impose(Stokes2, bulk, RHS[1], vy);
336 Solver.impose(V[x], boundary, RHS[0],
vx);
337 Solver.impose(V[y], boundary, RHS[1], vy);
343 Solver.solve_with_solver(solverPetsc, V[x], V[y]);
344 Particles.ghost_get<1>(SKIP_LABELLING);
345 div = -(Dx(V[x]) + Dy(V[y]));
350 for (
int j = 0; j < bulk.size(); j++) {
351 auto p = bulk.get<0>(j);
352 sum += (Particles.getProp<5>(p)[0] - Particles.getProp<1>(p)[0]) *
353 (Particles.getProp<5>(p)[0] - Particles.getProp<1>(p)[0]) +
354 (Particles.getProp<5>(p)[1] - Particles.getProp<1>(p)[1]) *
355 (Particles.getProp<5>(p)[1] - Particles.getProp<1>(p)[1]);
356 sum1 += Particles.getProp<1>(p)[0] * Particles.getProp<1>(p)[0] +
357 Particles.getProp<1>(p)[1] * Particles.getProp<1>(p)[1];
368 if (V_err > V_err_old || abs(V_err_old - V_err) < 1e-8) {
376 std::cout <<
"CONVERGENCE LOOP BROKEN DUE TO INCREASE/VERY SLOW DECREASE IN ERROR" << std::endl;
384 if (v_cl.rank() == 0) {
385 std::cout <<
"Rel l2 cgs err in V = " << V_err <<
" at " << n << std::endl;
391 for(
int j=0;j<bulk.size();j++)
392 {
auto p=bulk.get<0>(j);
393 if (fabs(Particles.getProp<6>(p)[0] - Particles.getProp<1>(p)[0]) >= worst1) {
394 worst1 = fabs(Particles.getProp<6>(p)[0] - Particles.getProp<1>(p)[0]);
397 for(
int j=0;j<bulk.size();j++)
398 {
auto p=bulk.get<0>(j);
399 if (fabs(Particles.getProp<6>(p)[1] - Particles.getProp<1>(p)[1]) >= worst2) {
400 worst2 = fabs(Particles.getProp<6>(p)[1] - Particles.getProp<1>(p)[1]);
405 std::cout <<
"Maximum Analytic Error in Vx: " << worst1 << std::endl;
406 std::cout <<
"Maximum Analytic Error in Vy: " << worst2 << std::endl;
407 BOOST_REQUIRE(worst1 < 0.03);
408 BOOST_REQUIRE(worst2 < 0.03);
413 BOOST_AUTO_TEST_CASE(dcpse_op_subset_PC_lid2) {
418 size_t edgeSemiSize = 20;
419 const size_t sz[2] = {2 * edgeSemiSize+1, 2 * edgeSemiSize+1};
421 size_t bc[2] = {NON_PERIODIC, NON_PERIODIC};
423 spacing[0] = 1.0 / (sz[0] - 1);
424 spacing[1] = 1.0 / (sz[1] - 1);
425 double rCut = 3.9 * spacing[0];
427 double sampling_factor = 4.0;
429 BOOST_TEST_MESSAGE(
"Init vector_dist...");
430 auto &v_cl = create_vcluster();
432 vector_dist<2, double, aggregate<double, VectorS<2, double>,
VectorS<2, double>,
VectorS<2, double>,double,
VectorS<2, double>,
VectorS<2, double>,
double>> Particles(0, box,
435 vector_dist<2, double, aggregate<double, VectorS<2, double>,
VectorS<2, double>,
VectorS<2, double>,double,
VectorS<2, double>,
VectorS<2, double>,
double>> Particles_subset(Particles.getDecomposition(), 0);
439 BOOST_TEST_MESSAGE(
"Init Particles...");
444 auto it = Particles.getGridIterator(sz);
446 double minNormOne = 999;
451 mem_id k0 = key.get(0);
452 double xp0 = k0 * spacing[0];
453 Particles.getLastPos()[0] = xp0;
454 mem_id k1 = key.get(1);
455 double yp0 = k1 * spacing[1];
456 Particles.getLastPos()[1] = yp0;
459 BOOST_TEST_MESSAGE(
"Sync Particles across processors...");
461 Particles.ghost_get<0>();
462 Particles.ghost_get_subset();
463 auto it2 = Particles.getDomainIterator();
464 while (it2.isNext()) {
467 if (xp[0] != 0 && xp[1] != 0 && xp[0] != 1.0 && xp[1] != 1.0) {
469 bulk.last().get<0>() = p.getKey();
470 Particles.getProp<3>(p)[x] = 3.0;
471 Particles.getProp<3>(p)[y] = 3.0;
474 boundary.last().get<0>() = p.getKey();
475 Particles.getProp<3>(p)[x] = xp[0]*xp[0]+xp[1]*xp[1];
476 Particles.getProp<3>(p)[y] = xp[0]*xp[0]-2*xp[0]*xp[1];
478 Particles.getProp<6>(p)[x] = xp[0]*xp[0]+xp[1]*xp[1];
479 Particles.getProp<6>(p)[y] = xp[0]*xp[0]-2*xp[0]*xp[1];
480 Particles.getProp<7>(p) = xp[0]+xp[1]-1.0;
485 for (
int i = 0; i < bulk.
size(); i++) {
486 Particles_subset.add();
487 Particles_subset.getLastPos()[0] = Particles.getPos(bulk.template get<0>(i))[0];
488 Particles_subset.getLastPos()[1] = Particles.getPos(bulk.template get<0>(i))[1];
490 Particles_subset.map();
491 Particles_subset.ghost_get<0>();
495 auto P = getV<0>(Particles);
496 auto V = getV<1>(Particles);
497 auto RHS = getV<2>(Particles);
498 auto dV = getV<3>(Particles);
499 auto div = getV<4>(Particles);
500 auto V_star = getV<5>(Particles);
502 auto P_bulk = getV<0>(Particles_subset);
503 auto Grad_bulk= getV<2>(Particles_subset);
507 auto verletList = Particles.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
508 auto verletList_subset = Particles_subset.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
510 Derivative_x<decltype(verletList)> Dx(Particles, verletList, 2, rCut, support_options::RADIUS);
511 Derivative_xx<decltype(verletList)> Dxx(Particles, verletList, 2, rCut, support_options::RADIUS);
512 Derivative_yy<decltype(verletList)> Dyy(Particles, verletList, 2, rCut, support_options::RADIUS);
513 Derivative_y<decltype(verletList)> Dy(Particles, verletList, 2, rCut, support_options::RADIUS);
515 Derivative_y<decltype(verletList_subset)> Bulk_Dy(Particles_subset, verletList_subset, 2, rCut, support_options::RADIUS);
516 Derivative_x<decltype(verletList_subset)> Bulk_Dx(Particles_subset, verletList_subset, 2, rCut, support_options::RADIUS);
518 int n = 0, nmax = 5, ctr = 0, errctr=0, Vreset = 0;
529 double sum, sum1, sum_k,V_err_eps=1e-3,V_err_old;
530 auto Stokes1=Dxx(V[x])+Dyy(V[x]);
531 auto Stokes2=Dxx(V[y])+Dyy(V[y]);
538 while (V_err >= V_err_eps && n <= nmax) {
541 Particles_subset.ghost_get<0>(SKIP_LABELLING);
543 Grad_bulk[x] = Bulk_Dx(P_bulk);
544 Grad_bulk[y] = Bulk_Dy(P_bulk);
545 for (
int i = 0; i < bulk.
size(); i++) {
546 Particles.template getProp<2>(bulk.template get<0>(i))[x] += Particles_subset.getProp<2>(i)[x];
547 Particles.template getProp<2>(bulk.template get<0>(i))[y] += Particles_subset.getProp<2>(i)[y];
550 DCPSE_scheme<
equations2d2, decltype(Particles)> Solver(Particles);
551 Solver.impose(Stokes1, bulk, RHS[0],
vx);
552 Solver.impose(Stokes2, bulk, RHS[1], vy);
553 Solver.impose(V[x], boundary, RHS[0],
vx);
554 Solver.impose(V[y], boundary, RHS[1], vy);
555 Solver.solve_with_solver(solverPetsc, V[x], V[y]);
556 Particles.ghost_get<1>(SKIP_LABELLING);
557 div = -(Dx(V[x]) + Dy(V[y]));
559 for (
int i = 0; i < bulk.
size(); i++) {
560 Particles_subset.getProp<0>(i) = Particles.template getProp<0>(bulk.template get<0>(i));
565 for (
int j = 0; j < bulk.
size(); j++) {
566 auto p = bulk.get<0>(j);
567 sum += (Particles.getProp<5>(p)[0] - Particles.getProp<1>(p)[0]) *
568 (Particles.getProp<5>(p)[0] - Particles.getProp<1>(p)[0]) +
569 (Particles.getProp<5>(p)[1] - Particles.getProp<1>(p)[1]) *
570 (Particles.getProp<5>(p)[1] - Particles.getProp<1>(p)[1]);
571 sum1 += Particles.getProp<1>(p)[0] * Particles.getProp<1>(p)[0] +
572 Particles.getProp<1>(p)[1] * Particles.getProp<1>(p)[1];
583 if (V_err > V_err_old || abs(V_err_old - V_err) < 1e-8) {
591 std::cout <<
"CONVERGENCE LOOP BROKEN DUE TO INCREASE/VERY SLOW DECREASE IN ERROR" << std::endl;
599 if (v_cl.rank() == 0) {
600 std::cout <<
"Rel l2 cgs err in V = " << V_err <<
" at " << n << std::endl;
607 for(
int j=0;j<bulk.
size();j++)
608 {
auto p=bulk.get<0>(j);
609 if (fabs(Particles.getProp<6>(p)[0] - Particles.getProp<1>(p)[0]) >= worst1) {
610 worst1 = fabs(Particles.getProp<6>(p)[0] - Particles.getProp<1>(p)[0]);
613 for(
int j=0;j<bulk.
size();j++)
614 {
auto p=bulk.get<0>(j);
615 if (fabs(Particles.getProp<6>(p)[1] - Particles.getProp<1>(p)[1]) >= worst2) {
616 worst2 = fabs(Particles.getProp<6>(p)[1] - Particles.getProp<1>(p)[1]);
620 std::cout <<
"Maximum Analytic Error in slice x: " << worst1 << std::endl;
621 std::cout <<
"Maximum Analytic Error in slice y: " << worst2 << std::endl;
622 BOOST_REQUIRE(worst1 < 0.03);
623 BOOST_REQUIRE(worst2 < 0.03);
628 BOOST_AUTO_TEST_SUITE_END()
This class represent an N-dimensional box.
Test structure used for several test.
This class implement the point shape in an N-dimensional space.
Implementation of 1-D std::vector like structure.
This class is able to do Matrix inversion in parallel with PETSC solvers.
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
It model an expression expr1 + ... exprn.