5#define BOOST_TEST_DYN_LINK
6#include <boost/test/unit_test.hpp>
8#include "FD_Solver.hpp"
9#include "Solvers/petsc_solver.hpp"
10#include "Solvers/umfpack_solver.hpp"
11#include "FD_expressions.hpp"
13#include "Grid/staggered_dist_grid.hpp"
14#include "util/EqnsStructFD.hpp"
17BOOST_AUTO_TEST_SUITE( FD_Solver_test )
20BOOST_AUTO_TEST_CASE(solver_check_diagonal)
22 const size_t sz[2] = {81,81};
30 auto it = domain.getDomainIterator();
34 auto gkey = it.getGKey(key);
35 double x = gkey.get(0) * domain.spacing(0);
36 double y = gkey.get(1) * domain.spacing(1);
37 domain.get<1>(key) = x+y;
42 domain.ghost_get<0>();
44 pet_sol.setPreconditioner(PCNONE);
46 auto v = FD::getV<0>(domain);
47 auto RHS= FD::getV<1>(domain);
48 auto sol= FD::getV<2>(domain);
51 Solver.impose(5.0*v,{0,0},{80,80},
prop_id<1>());
52 Solver.solve_with_solver(pet_sol,sol);
54 auto linferror = LInfError(v, sol);
58 BOOST_REQUIRE(linferror < 1e-5);
66 BOOST_AUTO_TEST_CASE(solver_Lap)
68 const size_t sz[2] = {82,82};
76 auto it = domain.getDomainIterator();
80 auto gkey = it.getGKey(key);
81 double x = gkey.get(0) * domain.spacing(0);
82 double y = gkey.get(1) * domain.spacing(1);
83 domain.get<0>(key) = sin(M_PI*x)*sin(M_PI*y);
84 domain.get<1>(key) = -2*M_PI*M_PI*sin(M_PI*x)*sin(M_PI*y);
88 domain.ghost_get<0>();
91 auto v = FD::getV<0>(domain);
92 auto RHS= FD::getV<1>(domain);
93 auto sol= FD::getV<2>(domain);
110 Solver.impose(v,{0,81},{81,81},
prop_id<0>());
111 Solver.impose(v,{81,1},{81,80},
prop_id<0>());
115 pet_sol.setPreconditioner(PCNONE);
116 Solver.solve_with_solver(pet_sol,sol);
118 auto linferror = LInfError(v, sol);
119 BOOST_REQUIRE(linferror < 1e-3);
125 BOOST_AUTO_TEST_CASE(solver_Lap_stag)
127 const size_t sz[2] = {82,82};
135 auto it = domain.getDomainIterator();
139 auto gkey = it.getGKey(key);
140 double x = gkey.get(0) * domain.spacing(0);
141 double y = gkey.get(1) * domain.spacing(1);
142 domain.get<0>(key) = sin(M_PI*x)*sin(M_PI*y);
143 domain.get<1>(key) = -2*M_PI*M_PI*sin(M_PI*x)*sin(M_PI*y);
147 domain.ghost_get<0>();
150 auto v = FD::getV<0>(domain);
151 auto RHS= FD::getV<1>(domain);
152 auto sol= FD::getV<2>(domain);
168 Solver.impose(v,{0,81},{81,81},
prop_id<0>());
169 Solver.impose(v,{81,1},{81,80},
prop_id<0>());
175 auto it2 = domain.getDomainIterator();
177 while (it2.isNext()) {
180 if (fabs(domain.getProp<0>(p) - domain.getProp<2>(p)) > worst) {
181 worst = fabs(domain.getProp<0>(p) - domain.getProp<2>(p));
186 BOOST_REQUIRE(worst < 1e-3);
393 static const unsigned int dims = 2;
396 static const unsigned int nvar = 3;
399 static const bool boundary[];
419 const bool lid_nn_stag::boundary[] = {NON_PERIODIC,NON_PERIODIC};
421 BOOST_AUTO_TEST_CASE(solver_Lid_driven_cavity_stag)
431 constexpr int velocity = 0;
432 constexpr int pressure = 1;
444 long int sz[] = {256,64};
446 szu[0] = (size_t)sz[0];
447 szu[1] = (size_t)sz[1];
463 g_dist.setDefaultStagPosition();
464 g_dist.setStagPosition<0>(cmb_v);
470 FD_scheme<lid_nn_stag,
decltype(g_dist)> fd(pd,stencil_max,g_dist);
472 auto P = FD::getV_stag<1>(g_dist);
473 auto v = FD::getV_stag<0>(g_dist);
474 auto RHS = FD::getV_stag<2>(g_dist);
487 auto Stokes_vx = nu *
Lap(v[x]) - Dx(
P);
488 auto Stokes_vy = nu *
Lap(v[y]) - Dy(
P);
490 auto incompressibility = Dx(v[x]) + Dy(v[y]);
505 auto it = g_dist.getDomainIterator();
509 auto gkey = it.getGKey(key);
510 double xg = gkey.get(0) * g_dist.spacing(0);
511 double yg = gkey.get(1) * g_dist.spacing(1);
514 g_dist.getProp<2>(key)[1] = 1.0;
515 g_dist.getProp<3>(key) = 1.0;
527 fd.impose(incompressibility, {0,0},{sz[0]-2,sz[1]-2}, 0.0,ic,
true);
528 fd.impose(
P, {0,0},{0,0},0.0,ic);
531 fd.impose(Stokes_vx, {1,0},{sz[0]-2,sz[1]-2},0.0,
vx,left_cell);
532 fd.impose(Stokes_vy, {0,1},{sz[0]-2,sz[1]-2},0.0,vy,bottom_cell);
543 fd.impose(v[x], {0,0},{0,sz[1]-2},0.0,
vx,left_cell);
554 fd.impose(v[y], {-1,0},{-1,sz[1]-1},0.0,vy,corner_right);
558 fd.impose(v[x],{sz[0]-1,0},{sz[0]-1,sz[1]-2},0.0,
vx,left_cell);
559 fd.impose(v[y],{sz[0]-1,0},{sz[0]-1,sz[1]-1},
prop_id<3>(),vy,corner_dw);
563 fd.impose(v[x], {0,-1},{sz[0]-1,-1},0.0,
vx,corner_up);
564 fd.impose(v[y], {0,0},{sz[0]-2,0},0.0,vy,bottom_cell);
567 fd.impose(v[x],{0,sz[1]-1},{sz[0]-1,sz[1]-1},0.0,
vx,corner_dw);
568 fd.impose(v[y],{0,sz[1]-1},{sz[0]-2,sz[1]-1},0.0,vy,bottom_cell);
577 fd.impose(
P, {-1,-1},{sz[0]-1,-1},0.0,ic);
578 fd.impose(
P, {-1,sz[1]-1},{sz[0]-1,sz[1]-1},0.0,ic);
579 fd.impose(
P, {-1,0},{-1,sz[1]-2},0.0,ic);
580 fd.impose(
P, {sz[0]-1,0},{sz[0]-1,sz[1]-2},0.0,ic);
583 fd.impose(v[x], {-1,-1},{-1,sz[1]-1},0.0,
vx,left_cell);
584 fd.impose(v[y], {-1,-1},{sz[0]-1,-1},0.0,vy,bottom_cell);
586 fd.solve(v[x],v[y],
P);
599 g_dist.template ghost_get<0,1>();
603 auto it3 = g_dist_normal.getSubDomainIterator({1,1},{(
int)g_dist_normal.size(0)-1,(
int)g_dist_normal.size(1)-1});
604 auto it4 = g_dist.getSubDomainIterator({1,1},{(
int)g_dist.size(0)-1,(
int)g_dist.size(1)-1});
608 auto key = it3.get();
609 auto key2 = it4.get();
611 g_dist_normal.template getProp<0>(key)[0] = v[x].value(key2,corner_dw);
612 g_dist_normal.template getProp<0>(key)[1] = v[y].value(key2,corner_dw);;
614 g_dist_normal.template getProp<1>(key) =
P.value(key2,corner_dw);
615 g_dist_normal.template getProp<2>(key)[x] = RHS[x].value(key2,corner_dw);
616 g_dist_normal.template getProp<2>(key)[y] = RHS[y].value(key2,corner_dw);
623#if !(defined(SE_CLASS3) || defined(TEST_COVERAGE_MODE))
627 g_dist2.load(
"test/lid_driven_cavity_reference.hdf5");
629 auto it2 = g_dist2.getSubDomainIterator({1,1},{(
int)g_dist2.size(0)-1,(
int)g_dist2.size(1)-1});
636 test &= fabs(g_dist2.template getProp<velocity>(p)[0] - g_dist_normal.template getProp<velocity>(p)[0]) < 3.5e-3;
637 test &= fabs(g_dist2.template getProp<velocity>(p)[1] - g_dist_normal.template getProp<velocity>(p)[1]) < 3.5e-3;
639 test &= fabs(g_dist2.template getProp<pressure>(p) - g_dist_normal.template getProp<pressure>(p)) < 3.0;
643 std::cout << g_dist2.template getProp<velocity>(p)[0] <<
" " << g_dist_normal.template getProp<velocity>(p)[0] << std::endl;
644 std::cout << g_dist2.template getProp<velocity>(p)[1] <<
" " << g_dist_normal.template getProp<velocity>(p)[1] << std::endl;
646 std::cout << g_dist2.template getProp<pressure>(p) <<
" " << g_dist_normal.template getProp<pressure>(p) << std::endl;
650 g_dist_normal.template getProp<1>(p) =
P.value(p,corner_dw);
658 BOOST_REQUIRE_EQUAL(test,
true);
667 static const unsigned int dims = 2;
670 static const unsigned int nvar = 3;
673 static const bool boundary[];
703 const bool ana_nn_stag::boundary[] = {NON_PERIODIC,NON_PERIODIC};
721 BOOST_AUTO_TEST_CASE(solver_ana_stag)
729 constexpr int velocity = 0;
730 constexpr int pressure = 1;
739 long int sz[] = {256,256};
744 szu[0] = (size_t)sz[0];
745 szu[1] = (size_t)sz[1];
750 staggered_grid_dist<2,float,aggregate<Point<2,float>,float,
Point<2,float>,float,float,
float>> g_dist(szu,domain,g);
751 grid_dist_id<2,float,aggregate<Point<2,float>,float,
Point<2,float>,float,float,
float>> g_dist_normal(g_dist.getDecomposition(),szu,g);
753 double hx = g_dist.spacing(0);
754 double hy = g_dist.spacing(1);
760 g_dist.setDefaultStagPosition();
761 g_dist.setStagPosition<0>(cmb_v);
767 FD_scheme<lid_nn_stag,
decltype(g_dist)> fd(pd,stencil_max,g_dist);
769 auto P = FD::getV_stag<1>(g_dist);
770 auto v = FD::getV_stag<0>(g_dist);
771 auto Ana_v = FD::getV_stag<2>(g_dist);
772 auto Ana_P = FD::getV_stag<3>(g_dist);
781 auto Stokes_vx =
Lap(v[x]) - Dx(
P);
782 auto Stokes_vy =
Lap(v[y]) - Dy(
P);
784 auto incompressibility = Dx(v[x]) + Dy(v[y]);
799 auto fu = [](
double x,
double y) {
return x*x + y*y; };
800 auto fv = [](
double x,
double y) {
return 2.0*x*x - 2.0*x*y; };
810 fd.impose(incompressibility, {0,0},{sz[0]-2,sz[1]-2}, 0.0,ic,
true);
811 fd.impose(
P, {0,0},{0,0},(hx+hy)/2-1.0,ic);
813 fd.impose(Stokes_vx, {1,0},{sz[0]-2,sz[1]-2},3.0,
vx,left_cell);
814 fd.impose(Stokes_vy, {0,1},{sz[0]-2,sz[1]-2},3.0,vy,bottom_cell);
817 fd.impose(v[x], {0,0},{0,sz[1]-2},fu,
vx,left_cell);
818 fd.impose(v[y], {-1,0},{-1,sz[1]-1},fv,vy,corner_right);
821 fd.impose(v[x],{sz[0]-1,0},{sz[0]-1,sz[1]-2},fu,
vx,left_cell);
822 fd.impose(v[y],{sz[0]-1,0},{sz[0]-1,sz[1]-1},fv,vy,corner_dw);
825 fd.impose(v[x],{0,-1},{sz[0]-1,-1},fu,
vx,corner_up);
826 fd.impose(v[y], {0,0},{sz[0]-2,0},fv,vy,bottom_cell);
829 fd.impose(v[x],{0,sz[1]-1},{sz[0]-1,sz[1]-1},fu,
vx,corner_dw);
830 fd.impose(v[y],{0,sz[1]-1},{sz[0]-2,sz[1]-1},fv,vy,bottom_cell);
833 fd.impose(
P, {-1,-1},{sz[0]-1,-1},0.0,ic);
834 fd.impose(
P, {-1,sz[1]-1},{sz[0]-1,sz[1]-1},0.0,ic);
835 fd.impose(
P, {-1,0},{-1,sz[1]-2},0.0,ic);
836 fd.impose(
P, {sz[0]-1,0},{sz[0]-1,sz[1]-2},0.0,ic);
839 fd.impose(v[x], {-1,-1},{-1,sz[1]-1},0.0,
vx,left_cell);
840 fd.impose(v[y], {-1,-1},{sz[0]-1,-1},0.0,vy,bottom_cell);
842 fd.solve(v[x],v[y],
P);
844 auto it2 = g_dist_normal.getDomainIterator();
848 auto key = it2.get();
849 auto gkey = it2.getGKey(key);
850 double x = gkey.get(0) * g_dist_normal.spacing(0);
851 double y = gkey.get(1) * g_dist_normal.spacing(1);
853 g_dist_normal.template getProp<0>(key)[0] = v[0].value(key,left_cell);
854 g_dist_normal.template getProp<0>(key)[1] = v[1].value(key,bottom_cell);
856 g_dist_normal.template getProp<1>(key) =
P.value(key,center_cell);
858 g_dist_normal.template getProp<2>(key)[0] = x*x + y*y;
859 g_dist_normal.template getProp<2>(key)[1] = 2*x*x - 2*x*y;
860 g_dist_normal.template getProp<3>(key) = x + y - 1;
864 g_dist_normal.write(
"ana_stokes");
874BOOST_AUTO_TEST_SUITE_END()
This class represent an N-dimensional box.
This class decompose a space into sub-sub-domains and distribute them across processors.
Laplacian second order on h (spacing)
Class that contain Padding information on each direction positive and Negative direction.
Test structure used for several test.
This class implement the point shape in an N-dimensional space.
Sparse Matrix implementation.
size_t getProcessingUnits()
Get the total number of processors.
Implementation of VCluster class.
Sparse Matrix implementation stub object when OpenFPM is compiled with no linear algebra support.
This is a distributed grid.
Implementation of 1-D std::vector like structure.
In case T does not match the PETSC precision compilation create a stub structure.
Implementation of the staggered grid.
stub when library compiled without eigen
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
Position of the element of dimension d in the hyper-cube of dimension dim.
Specify the general characteristic of system to solve.
Specify the general characteristic of system to solve.