43#include "DCPSE/DCPSE_OP/DCPSE_op.hpp"
44#include "DCPSE/DCPSE_OP/DCPSE_Solver.hpp"
45#include "Operators/Vector/vector_dist_operators.hpp"
46#include "Vector/vector_dist_subset.hpp"
47#include "util/SphericalHarmonics.hpp"
50int main(
int argc,
char* argv[])
70 openfpm_init(&argc,&argv);
74 double V_err_eps = 5e-4;
77 const size_t sz[3] = {grd_sz,grd_sz,grd_sz};
79 size_t bc[3] = {NON_PERIODIC, NON_PERIODIC, NON_PERIODIC};
80 double spacing = 2.0 / (sz[0] - 1);
81 double rCut = 3.9*spacing;
85 vector_dist_ws<3, double, aggregate<double,VectorS<3, double>,
VectorS<3, double>,double,
VectorS<3, double>,double,double,
VectorS<3, double>,
VectorS<3, double>,
VectorS<3, double>>> Particles(0, box, bc, ghost);
86 Particles.setPropNames({
"Pressure",
"Velocity",
"Velocity_Boundary",
"Divergence",
"V_T",
"P_analytical",
"TEMP" ,
"RHS",
"PolarCoord",
"V_analytical"});
101 auto &v_cl = create_vcluster();
103 auto it = Particles.getGridIterator(sz);
104 while (it.isNext()) {
106 double x = -1.0+key.get(0) * it.getSpacing(0);
107 double y = -1.0+key.get(1) * it.getSpacing(1);
108 double z = -1.0+key.get(2) * it.getSpacing(2);
109 double r=sqrt(x*x+y*y+z*z);
110 if (r<R-spacing/2.0) {
112 Particles.getLastPos()[0] = x;
113 Particles.getLastPos()[1] = y;
114 Particles.getLastPos()[2] = z;
115 Particles.getLastProp<8>()[0] = r;
117 Particles.getLastProp<8>()[1] = 0.0;
120 Particles.getLastProp<8>()[1] = std::atan2(sqrt(x*x+y*y),z);
122 Particles.getLastProp<8>()[2] = std::atan2(y,x);
127 int n_sp=
int(grd_sz)*
int(grd_sz)*3;
129 double Golden_angle=M_PI * (3.0 - sqrt(5.0));
131 for(
int i=1;i<=n_sp;i++)
133 double y = 1.0 - (i /double(n_sp - 1.0)) * 2.0;
134 double radius = sqrt(1 - y * y);
135 double Golden_theta = Golden_angle * i;
136 double x = cos(Golden_theta) * radius;
137 double z = sin(Golden_theta) * radius;
139 if (acos(z)==0 || acos(z)==M_PI){
140 std::cout<<
"Theta 0/Pi "<<std::endl;
145 Particles.getLastPos()[0] = x;
146 Particles.getLastPos()[1] = y;
147 Particles.getLastPos()[2] = z;
148 Particles.getLastProp<8>()[0] = 1.0 ;
149 Particles.getLastProp<8>()[1] = std::atan2(sqrt(x*x+y*y),z);
150 Particles.getLastProp<8>()[2] = std::atan2(y,x);
153 Particles.ghost_get<0>();
168 std::unordered_map<const lm,double,key_hash,key_equal> Vr;
169 std::unordered_map<const lm,double,key_hash,key_equal> V1;
170 std::unordered_map<const lm,double,key_hash,key_equal> V2;
174 for(
int l=0;l<=K;l++){
175 for(
int m=-l;m<=l;m++){
176 Vr[std::make_tuple(l,m)]=0.0;
177 V1[std::make_tuple(l,m)]=0.0;
178 V2[std::make_tuple(l,m)]=0.0;
184 V1[std::make_tuple(2,0)]=1.0;
186 auto it2 = Particles.getDomainIterator();
187 while (it2.isNext()) {
191 Particles.getProp<0>(p) =0;
193 Particles.getProp<0>(p) = 0;
194 std::vector<double> SVel;
195 SVel=openfpm::math::sumY<K>(xP[0],xP[1],xP[2],Vr,V1,V2);
196 double SP=openfpm::math::sumY_Scalar<K>(xP[0],xP[1],xP[2],Vr);
197 Particles.getProp<2>(p)[0] = SVel[0];
198 Particles.getProp<2>(p)[1] = SVel[1];
199 Particles.getProp<2>(p)[2] = SVel[2];
200 Particles.getProp<9>(p)[0] = SVel[0];
201 Particles.getProp<9>(p)[1] = SVel[1];
202 Particles.getProp<9>(p)[2] = SVel[2];
203 Particles.getProp<5>(p) = SP;
204 Particles.setSubset(p,1);
208 Particles.setSubset(p,0);
209 Particles.getProp<0>(p) = 0;
210 Particles.getProp<1>(p)[0] = 0;
211 Particles.getProp<1>(p)[1] = 0;
212 Particles.getProp<1>(p)[2] = 0;
229 vector_dist_subset<3, double, aggregate<double,VectorS<3, double>,
VectorS<3, double>,double,
VectorS<3, double>,double,double,
VectorS<3, double>,
VectorS<3, double>,
VectorS<3, double>>> Particles_bulk(Particles,0);
230 vector_dist_subset<3, double, aggregate<double,VectorS<3, double>,
VectorS<3, double>,double,
VectorS<3, double>,double,double,
VectorS<3, double>,
VectorS<3, double>,
VectorS<3, double>>> Particles_surface(Particles,1);
232 auto & bulk = Particles_bulk.getIds();
233 auto & Surface = Particles_surface.getIds();
235 for (
int j = 0; j < bulk.size(); j++) {
236 auto p = bulk.get<0>(j);
241 std::unordered_map<const lm,double,key_hash,key_equal> Ur, U1, U2, Plm;
244 for (
int l = 0; l <= K; l++) {
245 for (
int m = -l; m <= l; m++) {
246 auto Er= Vr.find(std::make_tuple(l,m));
247 auto E1= V1.find(std::make_tuple(l,m));
248 auto E2= V2.find(std::make_tuple(l,m));
249 std::vector<double> Sol=openfpm::math::sph_anasol_u(nu,l,m,Er->second,E1->second,E2->second,xP[0]);
250 Ur[std::make_tuple(l,m)]=Sol[0];
251 U1[std::make_tuple(l,m)]=Sol[1];
252 U2[std::make_tuple(l,m)]=Sol[2];
253 Plm[std::make_tuple(l,m)]=Sol[3];
259 if(fabs(xP[0])>=1e-5 && xP[1]>1e-5 && (M_PI-xP[1])>=1e-5)
261 std::vector<double> SVel = openfpm::math::sumY<K>(xP[0], xP[1], xP[2], Ur, U1, U2);
262 Particles.getProp<9>(p)[0] = SVel[0];
263 Particles.getProp<9>(p)[1] = SVel[1];
264 Particles.getProp<9>(p)[2] = SVel[2];
265 Particles.getProp<5>(p) = openfpm::math::sumY_Scalar<K>(xP[0], xP[1], xP[2], Plm);
280 auto P = getV<0>(Particles);
281 auto V = getV<1>(Particles);
282 auto V_B = getV<2>(Particles);
284 auto DIV = getV<3>(Particles);
285 auto V_t = getV<4>(Particles);
286 auto P_anal = getV<5>(Particles);
287 auto temp=getV<6>(Particles);
288 auto RHS = getV<7>(Particles);
289 auto P_bulk = getV<0>(Particles_bulk);
290 auto RHS_bulk = getV<7>(Particles_bulk);
291 auto V_anal = getV<9>(Particles);
297 double sampling2=1.9;
298 double rCut2=3.9*spacing;
300 Derivative_x Dx(Particles, 2, rCut,sampling, support_options::RADIUS),B_Dx(Particles_bulk, 2, rCut,sampling, support_options::RADIUS);
301 Derivative_y Dy(Particles, 2, rCut,sampling, support_options::RADIUS),B_Dy(Particles_bulk, 2, rCut,sampling, support_options::RADIUS);
302 Derivative_z Dz(Particles, 2, rCut,sampling, support_options::RADIUS),B_Dz(Particles_bulk, 2, rCut,sampling, support_options::RADIUS);
303 Derivative_xx Dxx(Particles, 2, rCut2,sampling2,support_options::RADIUS);
304 Derivative_yy Dyy(Particles, 2, rCut2,sampling2,support_options::RADIUS);
305 Derivative_zz Dzz(Particles, 2, rCut2,sampling2,support_options::RADIUS);
327 solverPetsc.setPreconditioner(PCNONE);
331 double V_err = 1, V_err_old;
332 int n = 0, nmax = 30, ctr = 0, errctr, Vreset = 0;
336 while (V_err >= V_err_eps && n <= nmax) {
337 Particles.ghost_get<0>(SKIP_LABELLING);
338 RHS_bulk[0] = B_Dx(
P);
339 RHS_bulk[1] = B_Dy(
P);
340 RHS_bulk[2] = B_Dz(
P);
341 DCPSE_scheme<
equations3d3,
decltype(Particles)> Solver(Particles);
342 auto Stokes1 = nu * (Dxx(V[0])+Dyy(V[0])+Dzz(V[0]));
343 auto Stokes2 = nu * (Dxx(V[1])+Dyy(V[1])+Dzz(V[1]));
344 auto Stokes3 = nu * (Dxx(V[2])+Dyy(V[2])+Dzz(V[2]));
345 Solver.impose(Stokes1, bulk, RHS[0],
vx);
346 Solver.impose(Stokes2, bulk, RHS[1], vy);
347 Solver.impose(Stokes3, bulk, RHS[2], vz);
348 Solver.impose(V[0], Surface, V_B[0],
vx);
349 Solver.impose(V[1], Surface, V_B[1], vy);
350 Solver.impose(V[2], Surface, V_B[2], vz);
351 Solver.solve_with_solver(solverPetsc, V[0], V[1], V[2]);
352 Particles.ghost_get<1>();
353 DIV = -(Dx(V[0])+Dy(V[1])+Dz(V[2]));
357 for (
int j = 0; j < bulk.size(); j++) {
358 auto p = bulk.get<0>(j);
359 sum += (Particles.getProp<4>(p)[0] - Particles.getProp<1>(p)[0]) *
360 (Particles.getProp<4>(p)[0] - Particles.getProp<1>(p)[0]) +
361 (Particles.getProp<4>(p)[1] - Particles.getProp<1>(p)[1]) *
362 (Particles.getProp<4>(p)[1] - Particles.getProp<1>(p)[1]) +
363 (Particles.getProp<4>(p)[2] - Particles.getProp<1>(p)[2]) *
364 (Particles.getProp<4>(p)[2] - Particles.getProp<1>(p)[2]);
365 sum1 += Particles.getProp<1>(p)[0] * Particles.getProp<1>(p)[0] +
366 Particles.getProp<1>(p)[1] * Particles.getProp<1>(p)[1] +
367 Particles.getProp<1>(p)[2] * Particles.getProp<1>(p)[2];
375 Particles.ghost_get<1>(SKIP_LABELLING);
378 if (V_err > V_err_old || abs(V_err_old - V_err) < 1e-14) {
385 std::cout <<
"CONVERGENCE LOOP BROKEN DUE TO INCREASE/VERY SLOW DECREASE IN Divergence" << std::endl;
397 Particles.write(
"StokesSphere");
This class represent an N-dimensional box.
Test structure used for several test.
This class implement the point shape in an N-dimensional space.
In case T does not match the PETSC precision compilation create a stub structure.
Class for cpu time benchmarking.
void start()
Start the timer.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
It model an expression expr1 + ... exprn.