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" 17 BOOST_AUTO_TEST_SUITE( FD_Solver_test )
20 BOOST_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>();
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>());
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);
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");
874 BOOST_AUTO_TEST_SUITE_END()
void setPreconditioner(PCType type)
Set the preconditioner of the linear solver.
Specify the general characteristic of system to solve.
Position of the element of dimension d in the hyper-cube of dimension dim.
Sparse Matrix implementation stub object when OpenFPM is compiled with no linear algebra support.
Specify the general characteristic of system to solve.
Class that contain Padding information on each direction positive and Negative direction.
This class implement the point shape in an N-dimensional space.
St spacing(size_t i) const
Get the spacing of the grid in direction i.
stub when library compiled without eigen
Implementation of VCluster class.
This class decompose a space into sub-sub-domains and distribute them across processors.
Sparse Matrix implementation.
This is a distributed grid.
Implementation of the staggered grid.
This class is able to do Matrix inversion in parallel with PETSC solvers.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
size_t getProcessingUnits()
Get the total number of processors.
Laplacian second order on h (spacing)
This class represent an N-dimensional box.
Test structure used for several test.
Implementation of 1-D std::vector like structure.
void load(const std::string &filename)
Reload the grid from HDF5 file.