114 #include "interpolation/interpolation.hpp"
115 #include "Grid/grid_dist_id.hpp"
116 #include "Vector/vector_dist.hpp"
117 #include "Matrix/SparseMatrix.hpp"
118 #include "Vector/Vector.hpp"
119 #include "FiniteDifference/FDScheme.hpp"
120 #include "Solvers/petsc_solver.hpp"
121 #include "interpolation/mp4_kernel.hpp"
122 #include "Solvers/petsc_solver_AMG_report.hpp"
137 float sigma = 1.0/3.523;
140 float tgtre = 3000.0;
143 float nu = 1.0/tgtre;
150 const unsigned int nsteps = 10;
152 const unsigned int nsteps = 10001;
156 constexpr
unsigned int vorticity = 0;
157 constexpr
unsigned int velocity = 0;
158 constexpr
unsigned int p_vel = 1;
159 constexpr
int rhs_part = 2;
160 constexpr
unsigned int old_vort = 3;
161 constexpr
unsigned int old_pos = 4;
165 template<
typename gr
id>
void calc_and_print_max_div_and_int(
grid & g_vort)
169 g_vort.template ghost_get<vorticity>();
170 auto it5 = g_vort.getDomainIterator();
172 double max_vort = 0.0;
174 double int_vort[3] = {0.0,0.0,0.0};
178 auto key = it5.get();
182 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] ) +
183 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] ) +
184 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] );
186 int_vort[x] += g_vort.template get<vorticity>(key)[x];
187 int_vort[y] += g_vort.template get<vorticity>(key)[y];
188 int_vort[z] += g_vort.template get<vorticity>(key)[z];
198 v_cl.
sum(int_vort[0]);
199 v_cl.
sum(int_vort[1]);
200 v_cl.
sum(int_vort[2]);
204 {std::cout <<
"Max div for vorticity " << max_vort <<
" Integral: " << int_vort[0] <<
" " << int_vort[1] <<
" " << int_vort[2] << std::endl;}
243 constexpr
int nk = 32;
248 for (
size_t i = 0 ; i < nk ; i++)
250 ak[i] = rand()/RAND_MAX;
251 bk[i] = rand()/RAND_MAX;
255 float gamma = nu * tgtre;
256 float rinv2 = 1.0f/(sigma*sigma);
257 float max_vorticity = gamma*rinv2/M_PI;
264 auto key_d = it.get();
265 auto key = it.getGKey(key_d);
267 float tx = (key.get(x)-2)*gr.
spacing(x) + domain.getLow(x);
268 float ty = (key.get(y)-2)*gr.
spacing(y) + domain.getLow(y);
269 float tz = (key.get(z)-2)*gr.
spacing(z) + domain.getLow(z);
270 float theta1 = atan2((ty-domain.getHigh(1)/2.0f),(tz-domain.getHigh(2)/2.0f));
273 float rad1r = sqrt((ty-domain.getHigh(1)/2.0f)*(ty-domain.getHigh(1)/2.0f) + (tz-domain.getHigh(2)/2.0f)*(tz-domain.getHigh(2)/2.0f)) - ringr1;
274 float rad1t = tx - 1.0f;
275 float rad1sq = rad1r*rad1r + rad1t*rad1t;
276 float radstr = -exp(-rad1sq*rinv2)*rinv2*gamma/M_PI;
277 gr.template get<vorticity>(key_d)[x] = 0.0f;
278 gr.template get<vorticity>(key_d)[y] = -radstr * cos(theta1);
279 gr.template get<vorticity>(key_d)[z] = radstr * sin(theta1);
283 float rad1r_ = sqrt((ty-domain.getHigh(1)/2.0f)*(ty-domain.getHigh(1)/2.0f) + (tz-domain.getHigh(2)/2.0f)*(tz-domain.getHigh(2)/2.0f)) + ringr1;
284 float rad1sqTILDA = rad1sq*rinv2;
285 radstr = exp(-rad1sq*rinv2)*rinv2*gamma/M_PI;
286 gr.template get<vorticity>(key_d)[x] = 0.0f;
287 gr.template get<vorticity>(key_d)[y] = -radstr * cos(theta1);
288 gr.template get<vorticity>(key_d)[z] = radstr * sin(theta1);
307 static const unsigned int dims = 3;
309 static const unsigned int nvar = 1;
321 static const int grid_type = NORMAL_GRID;
450 constexpr
unsigned int phi = 0;
466 gr.template ghost_get<vorticity>();
481 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] ) +
482 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] ) +
483 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] );
491 calc_and_print_max_div_and_int(gr);
507 fd.template impose_dit<0>(poisson(),psi,psi.getDomainIterator());
541 solver.
solve(fd.getA(),x_,fd.getB());
548 solver.
solve(x_,fd.getB());
553 fd.template copy<phi>(x_,psi);
559 psi.template ghost_get<phi>();
567 auto key = it2.get();
569 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)));
570 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)));
571 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)));
578 calc_and_print_max_div_and_int(gr);
612 auto key = git.get_dist();
623 vd.template getLastProp<vorticity>()[x] = gr.template get<vorticity>(key)[x];
624 vd.template getLastProp<vorticity>()[y] = gr.template get<vorticity>(key)[y];
625 vd.template getLastProp<vorticity>()[z] = gr.template get<vorticity>(key)[z];
695 constexpr
unsigned int phi = 0;
717 calc_and_print_max_div_and_int(g_vort);
720 for (
size_t i = 0 ; i < 3 ; i++)
725 auto it2 = gr_ps.getDomainIterator();
730 auto key = it2.get();
733 gr_ps.get<vorticity>(key) = g_vort.template get<vorticity>(key)[i];
745 fd.template impose_dit<phi>(poisson(),gr_ps,gr_ps.getDomainIterator());
758 solver.
solve(phi_s[i],b);
769 {std::cout <<
"Solved component " << i <<
" Error: " << serr.
err_inf << std::endl;}
772 fd.template copy<phi>(phi_s[i],gr_ps);
778 auto it3 = gr_ps.getDomainIterator();
783 auto key = it3.get();
785 phi_v.get<velocity>(key)[i] = gr_ps.get<phi>(key);
795 phi_v.ghost_get<phi>();
797 float inv_dx = 0.5f / g_vort.
spacing(0);
798 float inv_dy = 0.5f / g_vort.
spacing(1);
799 float inv_dz = 0.5f / g_vort.
spacing(2);
801 auto it3 = phi_v.getDomainIterator();
806 auto key = it3.get();
808 float phi_xy = (phi_v.get<phi>(key.move(y,1))[x] - phi_v.get<phi>(key.move(y,-1))[x])*inv_dy;
809 float phi_xz = (phi_v.get<phi>(key.move(z,1))[x] - phi_v.get<phi>(key.move(z,-1))[x])*inv_dz;
810 float phi_yx = (phi_v.get<phi>(key.move(x,1))[y] - phi_v.get<phi>(key.move(x,-1))[y])*inv_dx;
811 float phi_yz = (phi_v.get<phi>(key.move(z,1))[y] - phi_v.get<phi>(key.move(z,-1))[y])*inv_dz;
812 float phi_zx = (phi_v.get<phi>(key.move(x,1))[z] - phi_v.get<phi>(key.move(x,-1))[z])*inv_dx;
813 float phi_zy = (phi_v.get<phi>(key.move(y,1))[z] - phi_v.get<phi>(key.move(y,-1))[z])*inv_dy;
815 g_vel.template get<velocity>(key)[x] = phi_zy - phi_yz;
816 g_vel.template get<velocity>(key)[y] = phi_xz - phi_zx;
817 g_vel.template get<velocity>(key)[z] = phi_yx - phi_xy;
835 gr.template get<prp>(key)[0] = 0.0;
836 gr.template get<prp>(key)[1] = 0.0;
837 gr.template get<prp>(key)[2] = 0.0;
853 vd.template getProp<prp>(key)[0] = 0.0;
854 vd.template getProp<prp>(key)[1] = 0.0;
855 vd.template getProp<prp>(key)[2] = 0.0;
877 template<
typename gr
id>
void calc_rhs(
grid & g_vort,
grid & g_vel,
grid & g_dwp)
880 constexpr
int rhs = 0;
884 float fac1 = 2.0f*nu/(g_vort.spacing(0)*g_vort.spacing(0));
885 float fac2 = 2.0f*nu/(g_vort.spacing(1)*g_vort.spacing(1));
886 float fac3 = 2.0f*nu/(g_vort.spacing(2)*g_vort.spacing(2));
888 float fac4 = 0.5f/(g_vort.spacing(0));
889 float fac5 = 0.5f/(g_vort.spacing(1));
890 float fac6 = 0.5f/(g_vort.spacing(2));
892 auto it = g_dwp.getDomainIterator();
894 g_vort.template ghost_get<vorticity>();
900 g_dwp.template get<rhs>(key)[x] = fac1*(g_vort.template get<vorticity>(key.move(x,1))[x]+g_vort.template get<vorticity>(key.move(x,-1))[x])+
901 fac2*(g_vort.template get<vorticity>(key.move(y,1))[x]+g_vort.template get<vorticity>(key.move(y,-1))[x])+
902 fac3*(g_vort.template get<vorticity>(key.move(z,1))[x]+g_vort.template get<vorticity>(key.move(z,-1))[x])-
903 2.0f*(fac1+fac2+fac3)*g_vort.template get<vorticity>(key)[x]+
904 fac4*g_vort.template get<vorticity>(key)[x]*
905 (g_vel.template get<velocity>(key.move(x,1))[x] - g_vel.template get<velocity>(key.move(x,-1))[x])+
906 fac5*g_vort.template get<vorticity>(key)[y]*
907 (g_vel.template get<velocity>(key.move(y,1))[x] - g_vel.template get<velocity>(key.move(y,-1))[x])+
908 fac6*g_vort.template get<vorticity>(key)[z]*
909 (g_vel.template get<velocity>(key.move(z,1))[x] - g_vel.template get<velocity>(key.move(z,-1))[x]);
911 g_dwp.template get<rhs>(key)[y] = fac1*(g_vort.template get<vorticity>(key.move(x,1))[y]+g_vort.template get<vorticity>(key.move(x,-1))[y])+
912 fac2*(g_vort.template get<vorticity>(key.move(y,1))[y]+g_vort.template get<vorticity>(key.move(y,-1))[y])+
913 fac3*(g_vort.template get<vorticity>(key.move(z,1))[y]+g_vort.template get<vorticity>(key.move(z,-1))[y])-
914 2.0f*(fac1+fac2+fac3)*g_vort.template get<vorticity>(key)[y]+
915 fac4*g_vort.template get<vorticity>(key)[x]*
916 (g_vel.template get<velocity>(key.move(x,1))[y] - g_vel.template get<velocity>(key.move(x,-1))[y])+
917 fac5*g_vort.template get<vorticity>(key)[y]*
918 (g_vel.template get<velocity>(key.move(y,1))[y] - g_vel.template get<velocity>(key.move(y,-1))[y])+
919 fac6*g_vort.template get<vorticity>(key)[z]*
920 (g_vel.template get<velocity>(key.move(z,1))[y] - g_vel.template get<velocity>(key.move(z,-1))[y]);
923 g_dwp.template get<rhs>(key)[z] = fac1*(g_vort.template get<vorticity>(key.move(x,1))[z]+g_vort.template get<vorticity>(key.move(x,-1))[z])+
924 fac2*(g_vort.template get<vorticity>(key.move(y,1))[z]+g_vort.template get<vorticity>(key.move(y,-1))[z])+
925 fac3*(g_vort.template get<vorticity>(key.move(z,1))[z]+g_vort.template get<vorticity>(key.move(z,-1))[z])-
926 2.0f*(fac1+fac2+fac3)*g_vort.template get<vorticity>(key)[z]+
927 fac4*g_vort.template get<vorticity>(key)[x]*
928 (g_vel.template get<velocity>(key.move(x,1))[z] - g_vel.template get<velocity>(key.move(x,-1))[z])+
929 fac5*g_vort.template get<vorticity>(key)[y]*
930 (g_vel.template get<velocity>(key.move(y,1))[z] - g_vel.template get<velocity>(key.move(y,-1))[z])+
931 fac6*g_vort.template get<vorticity>(key)[z]*
932 (g_vel.template get<velocity>(key.move(z,1))[z] - g_vel.template get<velocity>(key.move(z,-1))[z]);
984 auto key = it2.
get();
1029 auto key = it.
get();
1040 while (it2.isNext())
1042 auto key = it2.
get();
1078 template<
typename gr
id,
typename vector>
void do_step(vector &
particles,
1087 constexpr
int rhs = 0;
1092 inte.template p2m<vorticity,vorticity>(
particles,g_vort);
1094 g_vort.template ghost_put<add_,vorticity>();
1101 comp_vel(domain,g_vort,g_vel,phi_s,solver);
1102 calc_rhs(g_vort,g_vel,g_dvort);
1108 g_dvort.template ghost_get<rhs>();
1109 g_vel.template ghost_get<velocity>();
1112 inte.template m2p<rhs,rhs_part>(g_dvort,
particles);
1113 inte.template m2p<velocity,p_vel>(g_vel,
particles);
1118 template<
typename vector,
typename gr
id>
void check_point_and_save(vector &
particles,
1128 particles.
write(
"part_out_" + std::to_string(i),VTK_WRITER | FORMAT_BINARY);
1129 g_vort.template ghost_get<vorticity>();
1130 g_vel.template ghost_get<velocity>();
1131 g_vel.write_frame(
"grid_velocity",i, VTK_WRITER | FORMAT_BINARY);
1132 g_vort.write_frame(
"grid_vorticity",i, VTK_WRITER | FORMAT_BINARY);
1141 while (it_s.isNext())
1143 auto p = it_s.get();
1145 float vort_magn = sqrt(
particles.template getProp<vorticity>(p)[0] *
particles.template getProp<vorticity>(p)[0] +
1146 particles.template getProp<vorticity>(p)[1] *
particles.template getProp<vorticity>(p)[1] +
1147 particles.template getProp<vorticity>(p)[2] *
particles.template getProp<vorticity>(p)[2]);
1149 if (vort_magn < 0.1)
1161 part_save.template getLastProp<0>() = vort_magn;
1190 int main(
int argc,
char* argv[])
1193 openfpm_init(&argc,&argv);
1206 long int sz[] = {96,96,96};
1207 size_t szu[] = {(size_t)sz[0],(
size_t)sz[1],(size_t)sz[2]};
1212 grid_type g_vel(g_vort.getDecomposition(),szu,g);
1213 grid_type g_dvort(g_vort.getDecomposition(),szu,g);
1226 {std::cout <<
"SPACING " << g_vort.spacing(0) <<
" " << g_vort.spacing(1) <<
" " << g_vort.spacing(2) << std::endl;}
1229 init_ring(g_vort,domain);
1231 x_.
resize(g_vort.size(),g_vort.getLocalDomainSize());
1238 helmotz_hodge_projection(g_vort,domain,solver,x_,
true);
1249 phi_s[0].
resize(g_vort.size(),g_vort.getLocalDomainSize());
1250 phi_s[1].
resize(g_vort.size(),g_vort.getLocalDomainSize());
1251 phi_s[2].
resize(g_vort.size(),g_vort.getLocalDomainSize());
1267 {g_vort.write(
"grid_vorticity_init", VTK_WRITER | FORMAT_BINARY);}
1278 std::string restart(argv[1]);
1281 i = std::stoi(restart);
1289 {std::cout <<
"Restarting from " << i << std::endl;}
1293 for ( ; i < nsteps ; i++)
1296 do_step(
particles,g_vort,g_vel,g_dvort,domain,inte,phi_s,solver);
1302 do_step(
particles,g_vort,g_vel,g_dvort,domain,inte,phi_s,solver);
1309 inte.template p2m<vorticity,vorticity>(
particles,g_vort);
1310 g_vort.template ghost_put<add_,vorticity>();
1313 helmotz_hodge_projection(g_vort,domain,solver,x_,
false);
1319 {std::cout <<
"Step " << i << std::endl;}
1322 if (i % 100 == 0) {check_point_and_save(
particles,g_vort,g_vel,g_dvort,i);}
1332 int main(
int argc,
char* argv[])