103 #include "interpolation/interpolation.hpp" 104 #include "Grid/grid_dist_id.hpp" 105 #include "Vector/vector_dist.hpp" 106 #include "Matrix/SparseMatrix.hpp" 107 #include "Vector/Vector.hpp" 108 #include "FiniteDifference/FDScheme.hpp" 109 #include "Solvers/petsc_solver.hpp" 110 #include "interpolation/mp4_kernel.hpp" 111 #include "Solvers/petsc_solver_AMG_report.hpp" 126 double sigma = 1.0/3.523;
128 double tgtre = 7500.0;
130 double ringnz = 0.01;
133 double nu = 1.0/tgtre;
139 constexpr
unsigned int vorticity = 0;
140 constexpr
unsigned int velocity = 0;
141 constexpr
unsigned int p_vel = 1;
142 constexpr
int rhs_part = 2;
143 constexpr
unsigned int old_vort = 3;
144 constexpr
unsigned int old_pos = 4;
148 template<
typename gr
id>
void calc_and_print_max_div_and_int(
grid & g_vort)
152 g_vort.template ghost_get<vorticity>();
153 auto it5 = g_vort.getDomainIterator();
155 double max_vort = 0.0;
157 double int_vort[3] = {0.0,0.0,0.0};
161 auto key = it5.get();
165 tmp = 1.0f/g_vort.spacing(x)/2.0f*(g_vort.template get<vorticity>(key.move(x,1))[x] - g_vort.template get<vorticity>(key.move(x,-1))[x] ) +
166 1.0f/g_vort.spacing(y)/2.0f*(g_vort.template get<vorticity>(key.move(y,1))[y] - g_vort.template get<vorticity>(key.move(y,-1))[y] ) +
167 1.0f/g_vort.spacing(z)/2.0f*(g_vort.template get<vorticity>(key.move(z,1))[z] - g_vort.template get<vorticity>(key.move(z,-1))[z] );
169 int_vort[x] += g_vort.template get<vorticity>(key)[x];
170 int_vort[y] += g_vort.template get<vorticity>(key)[y];
171 int_vort[z] += g_vort.template get<vorticity>(key)[z];
179 Vcluster & v_cl = create_vcluster();
181 v_cl.
sum(int_vort[0]);
182 v_cl.
sum(int_vort[1]);
183 v_cl.
sum(int_vort[2]);
187 {std::cout <<
"Max div for vorticity " << max_vort <<
" Integral: " << int_vort[0] <<
" " << int_vort[1] <<
" " << int_vort[2] << std::endl;}
226 constexpr
int nk = 32;
231 for (
size_t i = 0 ; i < nk ; i++)
233 ak[i] = rand()/RAND_MAX;
234 bk[i] = rand()/RAND_MAX;
238 double gamma = nu * tgtre;
239 double rinv2 = 1.0f/(sigma*sigma);
240 double max_vorticity = gamma*rinv2/M_PI;
247 auto key_d = it.get();
248 auto key = it.getGKey(key_d);
253 double theta1 = atan2((ty-2.5f),(tz-2.5f));
261 double rad1r = sqrt((ty-2.5f)*(ty-2.5f) + (tz-2.5f)*(tz-2.5f)) - ringr1*(1.0f + ringnz * noise);
262 double rad1t = tx - 1.0f;
263 double rad1sq = rad1r*rad1r + rad1t*rad1t;
264 double radstr = -exp(-rad1sq*rinv2)*rinv2*gamma/M_PI;
265 gr.template get<vorticity>(key_d)[x] = 0.0f;
266 gr.template get<vorticity>(key_d)[y] = -radstr * cos(theta1);
267 gr.template get<vorticity>(key_d)[z] = radstr * sin(theta1);
286 static const unsigned int dims = 3;
287 static const unsigned int nvar = 1;
289 typedef double stype;
293 static const int grid_type = NORMAL_GRID;
421 constexpr
unsigned int phi = 0;
437 gr.template ghost_get<vorticity>();
452 psi.template get<phi>(key) = 1.0f/gr.
spacing(x)/2.0f*(gr.template get<vorticity>(key.move(x,1))[x] - gr.template get<vorticity>(key.move(x,-1))[x] ) +
453 1.0f/gr.
spacing(y)/2.0f*(gr.template get<vorticity>(key.move(y,1))[y] - gr.template get<vorticity>(key.move(y,-1))[y] ) +
454 1.0f/gr.
spacing(z)/2.0f*(gr.template get<vorticity>(key.move(z,1))[z] - gr.template get<vorticity>(key.move(z,-1))[z] );
462 calc_and_print_max_div_and_int(gr);
478 fd.template impose_dit<0>(poisson(),psi,psi.getDomainIterator());
507 solver.
solve(fd.getA(),x_,fd.getB());
514 solver.
solve(x_,fd.getB());
519 fd.template copy<phi>(x_,psi);
525 psi.template ghost_get<phi>();
533 auto key = it2.get();
535 gr.template get<vorticity>(key)[x] -= 1.0f/2.0f/psi.
spacing(x)*(psi.template get<phi>(key.move(x,1))-psi.template get<phi>(key.move(x,-1)));
536 gr.template get<vorticity>(key)[y] -= 1.0f/2.0f/psi.
spacing(y)*(psi.template get<phi>(key.move(y,1))-psi.template get<phi>(key.move(y,-1)));
537 gr.template get<vorticity>(key)[z] -= 1.0f/2.0f/psi.
spacing(z)*(psi.template get<phi>(key.move(z,1))-psi.template get<phi>(key.move(z,-1)));
544 calc_and_print_max_div_and_int(gr);
578 auto key = git.get_dist();
589 vd.template getLastProp<vorticity>()[x] = gr.template get<vorticity>(key)[x];
590 vd.template getLastProp<vorticity>()[y] = gr.template get<vorticity>(key)[y];
591 vd.template getLastProp<vorticity>()[z] = gr.template get<vorticity>(key)[z];
661 constexpr
unsigned int phi = 0;
683 calc_and_print_max_div_and_int(g_vort);
686 for (
size_t i = 0 ; i < 3 ; i++)
691 auto it2 = gr_ps.getDomainIterator();
696 auto key = it2.get();
699 gr_ps.get<vorticity>(key) = g_vort.template get<vorticity>(key)[i];
711 fd.template impose_dit<phi>(poisson(),gr_ps,gr_ps.getDomainIterator());
724 solver.
solve(phi_s[i],b);
733 Vcluster & v_cl = create_vcluster();
735 {std::cout <<
"Solved component " << i <<
" Error: " << serr.
err_inf << std::endl;}
738 fd.template copy<phi>(phi_s[i],gr_ps);
744 auto it3 = gr_ps.getDomainIterator();
749 auto key = it3.get();
751 phi_v.get<velocity>(key)[i] = gr_ps.get<phi>(key);
761 phi_v.ghost_get<phi>();
763 double inv_dx = 0.5f / g_vort.
spacing(0);
764 double inv_dy = 0.5f / g_vort.
spacing(1);
765 double inv_dz = 0.5f / g_vort.
spacing(2);
767 auto it3 = phi_v.getDomainIterator();
772 auto key = it3.get();
774 double phi_xy = (phi_v.get<phi>(key.move(y,1))[x] - phi_v.get<phi>(key.move(y,-1))[x])*inv_dy;
775 double phi_xz = (phi_v.get<phi>(key.move(z,1))[x] - phi_v.get<phi>(key.move(z,-1))[x])*inv_dz;
776 double phi_yx = (phi_v.get<phi>(key.move(x,1))[y] - phi_v.get<phi>(key.move(x,-1))[y])*inv_dx;
777 double phi_yz = (phi_v.get<phi>(key.move(z,1))[y] - phi_v.get<phi>(key.move(z,-1))[y])*inv_dz;
778 double phi_zx = (phi_v.get<phi>(key.move(x,1))[z] - phi_v.get<phi>(key.move(x,-1))[z])*inv_dx;
779 double phi_zy = (phi_v.get<phi>(key.move(y,1))[z] - phi_v.get<phi>(key.move(y,-1))[z])*inv_dy;
781 g_vel.template get<velocity>(key)[x] = phi_zy - phi_yz;
782 g_vel.template get<velocity>(key)[y] = phi_xz - phi_zx;
783 g_vel.template get<velocity>(key)[z] = phi_yx - phi_xy;
801 gr.template get<prp>(key)[0] = 0.0;
802 gr.template get<prp>(key)[1] = 0.0;
803 gr.template get<prp>(key)[2] = 0.0;
819 vd.template getProp<prp>(key)[0] = 0.0;
820 vd.template getProp<prp>(key)[1] = 0.0;
821 vd.template getProp<prp>(key)[2] = 0.0;
843 template<
typename gr
id>
void calc_rhs(
grid & g_vort,
grid & g_vel,
grid & g_dwp)
846 constexpr
int rhs = 0;
850 double fac1 = 2.0f*nu/(g_vort.spacing(0));
851 double fac2 = 2.0f*nu/(g_vort.spacing(1));
852 double fac3 = 2.0f*nu/(g_vort.spacing(2));
854 double fac4 = 0.5f/(g_vort.spacing(0));
855 double fac5 = 0.5f/(g_vort.spacing(1));
856 double fac6 = 0.5f/(g_vort.spacing(2));
858 auto it = g_dwp.getDomainIterator();
860 g_vort.template ghost_get<vorticity>();
866 g_dwp.template get<rhs>(key)[x] =
870 fac4*g_vort.template get<vorticity>(key)[x]*
871 (g_vel.template get<velocity>(key.move(x,1))[x] - g_vel.template get<velocity>(key.move(x,-1))[x])+
872 fac5*g_vort.template get<vorticity>(key)[y]*
873 (g_vel.template get<velocity>(key.move(y,1))[x] - g_vel.template get<velocity>(key.move(y,-1))[x])+
874 fac6*g_vort.template get<vorticity>(key)[z]*
875 (g_vel.template get<velocity>(key.move(z,1))[x] - g_vel.template get<velocity>(key.move(z,-1))[x]);
877 g_dwp.template get<rhs>(key)[y] =
881 fac4*g_vort.template get<vorticity>(key)[x]*
882 (g_vel.template get<velocity>(key.move(x,1))[y] - g_vel.template get<velocity>(key.move(x,-1))[y])+
883 fac5*g_vort.template get<vorticity>(key)[y]*
884 (g_vel.template get<velocity>(key.move(y,1))[y] - g_vel.template get<velocity>(key.move(y,-1))[y])+
885 fac6*g_vort.template get<vorticity>(key)[z]*
886 (g_vel.template get<velocity>(key.move(z,1))[y] - g_vel.template get<velocity>(key.move(z,-1))[y]);
889 g_dwp.template get<rhs>(key)[z] =
893 fac4*g_vort.template get<vorticity>(key)[x]*
894 (g_vel.template get<velocity>(key.move(x,1))[z] - g_vel.template get<velocity>(key.move(x,-1))[z])+
895 fac5*g_vort.template get<vorticity>(key)[y]*
896 (g_vel.template get<velocity>(key.move(y,1))[z] - g_vel.template get<velocity>(key.move(y,-1))[z])+
897 fac6*g_vort.template get<vorticity>(key)[z]*
898 (g_vel.template get<velocity>(key.move(z,1))[z] - g_vel.template get<velocity>(key.move(z,-1))[z]);
950 auto key = it2.
get();
1006 while (it2.isNext())
1008 auto key = it2.
get();
1044 template<
typename gr
id,
typename vector>
void do_step(vector &
particles,
1053 constexpr
int rhs = 0;
1058 inte.template p2m<vorticity,vorticity>(
particles,g_vort);
1060 g_vort.template ghost_put<add_,vorticity>();
1067 comp_vel(domain,g_vort,g_vel,phi_s,solver);
1068 calc_rhs(g_vort,g_vel,g_dvort);
1074 g_dvort.template ghost_get<rhs>();
1075 g_vel.template ghost_get<velocity>();
1078 inte.template m2p<rhs,rhs_part>(g_dvort,
particles);
1079 inte.template m2p<velocity,p_vel>(g_vel,
particles);
1084 template<
typename vector,
typename gr
id>
void check_point_and_save(vector &
particles,
1090 Vcluster & v_cl = create_vcluster();
1094 particles.
write(
"part_out_" + std::to_string(i),VTK_WRITER | FORMAT_BINARY);
1095 g_vort.template ghost_get<vorticity>();
1096 g_vel.template ghost_get<velocity>();
1097 g_vel.write(
"grid_velocity_" + std::to_string(i), VTK_WRITER | FORMAT_BINARY);
1098 g_vort.write(
"grid_vorticity_" + std::to_string(i), VTK_WRITER | FORMAT_BINARY);
1107 while (it_s.isNext())
1109 auto p = it_s.get();
1111 double vort_magn = sqrt(
particles.template getProp<vorticity>(p)[0] *
particles.template getProp<vorticity>(p)[0] +
1112 particles.template getProp<vorticity>(p)[1] *
particles.template getProp<vorticity>(p)[1] +
1113 particles.template getProp<vorticity>(p)[2] *
particles.template getProp<vorticity>(p)[2]);
1115 if (vort_magn < 0.1)
1127 part_save.template getLastProp<0>() = vort_magn;
1156 int main(
int argc,
char* argv[])
1159 openfpm_init(&argc,&argv);
1168 long int sz[] = {512,64,64};
1169 size_t szu[] = {(size_t)sz[0],(
size_t)sz[1],(size_t)sz[2]};
1174 grid_type g_vel(g_vort.getDecomposition(),szu,g);
1175 grid_type g_dvort(g_vort.getDecomposition(),szu,g);
1184 Vcluster & v_cl = create_vcluster();
1188 {std::cout <<
"SPACING " << g_vort.spacing(0) <<
" " << g_vort.spacing(1) <<
" " << g_vort.spacing(2) << std::endl;}
1191 init_ring(g_vort,domain);
1193 x_.
resize(g_vort.size(),g_vort.getLocalDomainSize());
1200 helmotz_hodge_projection(g_vort,domain,solver,x_,
true);
1211 phi_s[0].resize(g_vort.size(),g_vort.getLocalDomainSize());
1212 phi_s[1].resize(g_vort.size(),g_vort.getLocalDomainSize());
1213 phi_s[2].resize(g_vort.size(),g_vort.getLocalDomainSize());
1229 {g_vort.write(
"grid_vorticity_init", VTK_WRITER | FORMAT_BINARY);}
1240 std::string restart(argv[1]);
1243 i = std::stoi(restart);
1251 {std::cout <<
"Restarting from " << i << std::endl;}
1255 for ( ; i < 10001 ; i++)
1258 do_step(
particles,g_vort,g_vel,g_dvort,domain,inte,phi_s,solver);
1264 do_step(
particles,g_vort,g_vel,g_dvort,domain,inte,phi_s,solver);
1271 inte.template p2m<vorticity,vorticity>(
particles,g_vort);
1272 g_vort.template ghost_put<add_,vorticity>();
1275 helmotz_hodge_projection(g_vort,domain,solver,x_,
false);
1281 {std::cout <<
"Step " << i << std::endl;}
1284 if (i % 100 == 0) {check_point_and_save(
particles,g_vort,g_vel,g_dvort,i);}
1295 int main(
int argc,
char* argv[])
void setPreconditioner(PCType type)
Set the preconditioner of the linear solver.
Decomposition & getDecomposition()
Get the decomposition.
size_t getProcessUnitID()
Get the process unit id.
Sparse Matrix implementation stub object when OpenFPM is compiled with no linear algebra support.
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
static const unsigned int dims
Number of dimansions of the problem.
void setMaxIter(PetscInt n)
Set the maximum number of iteration for Krylov solvers.
In case T does not match the PETSC precision compilation create a stub structure.
auto getPos(vect_dist_key_dx vec_key) -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
SparseMatrix< double, int, PETSC_BASE > SparseMatrix_type
type of sparse grid that store the Matrix A
Meta-function to return a compatible zero-element.
auto getProp(vect_dist_key_dx vec_key) -> decltype(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
It contain statistic of the error of the calculated solution.
auto get(const grid_dist_key_dx< dim, bg_key > &v1) const -> typename std::add_lvalue_reference< decltype(loc_grid.get(v1.getSub()).template get< p >(v1.getKey()))>::type
Get the reference of the selected element.
void setPreconditionerAMG_cycleType(const std::string &cycle_type, int sweep_up=-1, int sweep_dw=-1, int sweep_crs=-1)
It set the type of cycle and optionally the number of sweep.
float stype
type of the space
void setAbsTol(PetscReal abstol_)
Set the absolute tolerance as stop criteria.
St spacing(size_t i) const
Get the spacing of the grid in direction i.
Vector< double, PETSC_BASE > solve(SparseMatrix< double, int, PETSC_BASE > &A, const Vector< double, PETSC_BASE > &b, bool initial_guess=false)
Here we invert the matrix and solve the system.
void save(const std::string &filename) const
Save the distributed vector on HDF5 file.
Vector< double, PETSC_BASE > Vector_type
type of vector that store the solution
Implementation of VCluster class.
void setPreconditionerAMG_maxit(int nit)
Set the maximum number of V or W cycle for algebraic-multi-grid.
void execute()
Execute all the requests.
grid_dist_iterator< dim, device_grid, decltype(device_grid::type_of_iterator()), FIXED > getDomainGhostIterator() const
It return an iterator that span the grid domain + ghost part.
auto getLastPos() -> decltype(v_pos.template get< 0 >(0))
Get the position of the last element.
void map(size_t opt=NONE)
It move all the particles that does not belong to the local processor to the respective processor.
Sparse Matrix implementation.
This is a distributed grid.
void resize(size_t row, size_t row_n)
stub resize
grid_dist_id_iterator_dec< Decomposition > getGridIterator(const size_t(&sz)[dim])
size_t size_local() const
return the local size of the vector
static const unsigned int nvar
We have only one scalar unknown.
const size_t(& getSize() const)[N]
Return the size of the grid as an array.
void setPreconditionerAMG_nl(int nl)
Set the number of levels for the algebraic-multigrid preconditioner.
This class is able to do Matrix inversion in parallel with PETSC solvers.
void setSolver(KSPType type)
Set the Petsc solver.
void start()
Start the timer.
bool write(std::string out, int opt=VTK_WRITER)
Output particle position and properties.
size_t getProcessingUnits()
Get the total number of processors.
Laplacian second order on h (spacing)
void add()
Add local particle.
grid_dist_iterator< dim, device_grid, decltype(device_grid::type_of_subiterator()), FREE > getDomainIterator() const
It return an iterator that span the full grid domain (each processor span its local domain)
This class represent an N-dimensional box.
void sum(T &num)
Sum the numbers across all processors and get the result.
grid_dist_id< 3, float, aggregate< float > > b_grid
Grid that store the solution.
const grid_sm< dim, T > & getGridInfo() const
Get an object containing the grid informations.
void setPreconditionerAMG_coarsen(const std::string &type)
Set the coarsening method for the algebraic-multi-grid preconditioner.
void setPreconditionerAMG_relax(const std::string &type, int k=REL_ALL)
Set the relaxation method for the algebraic-multi-grid preconditioner.
void max(T &num)
Get the maximum number across all processors (or reduction with infinity norm)
vect_dist_key_dx get()
Get the actual key.
static const bool boundary[]
specify the boundary conditions
OutputIteratorT OffsetT ReductionOpT OuputT init
< [in] The initial value of the reduction
solError get_residual_error(SparseMatrix< double, int, PETSC_BASE > &A, const Vector< double, PETSC_BASE > &x, const Vector< double, PETSC_BASE > &b)
It return the resiual error.
vector_dist_iterator getDomainIterator() const
Get an iterator that traverse the particles in the domain.
void clear()
remove all the elements
Decomposition & getDecomposition()
Get the object that store the information about the decomposition.
void load(const std::string &filename)
Load the distributed vector from an HDF5 file.
Class for cpu time benchmarking.
void setPreconditionerAMG_coarsenNodalType(int norm)
Set the block coarsening norm type.
grid_key_dx< Decomposition::dims > get()
Get the actual global key of the grid.
Main class for interpolation Particle to mest p2m and Mesh to particle m2p.
void stop()
Stop the timer.
PetscReal err_inf
infinity norm of the error