sandbox/larswd/particle_classic.h
Particles can be removed based on their position or another condition
int remove_particle (particle p, Particles Plist) {
long unsigned int * ind = malloc (sizeof(long int));
int i = 0, a = 1;
(Plist) {
foreach_particle_inforeach_dimension()
if (p().x != p.x)
continue;
if (i + 1 >= a) {
= realloc (ind, a*2*sizeof(long int));
ind *= 2;
a }
[i++] = _j_particle;
ind}
(Plist, i, ind);
remove_particles_index free (ind); ind = NULL;
return i;
}
Utility functions
boundary conditions
peridoc box and _MPI
boundaries.
Periodicity in vertical does not make sense in the multilayer solver, and hence this function remains currently unchanged.
void particle_boundary (Particles P) {
= {X0, Y0, Z0};
coord mind (P) {
foreach_particle_inforeach_dimension() {
if (p().x < mind.x)
().x += L0;
pelse if (p().x > (mind.x + L0))
().x -= L0;
p}
}
#if _MPI
(P);
update_mpi #endif
}
Place particle
s
For already allocated particle
s referenced by
Particles P
:
The foreach() and foreach_dimension()-iterators do not see z-axis in multilayer, and hence the support for this axis must be added manually where relevant.
void place_in_cells (Particles P) {
= pl[P];
particles pp long unsigned int np = 0;
foreach(serial, reduction(+:np)) {
= {x, y,z};
coord loc foreach_dimension()
[np].x = loc.x;
pp++;
np}
}
Simple particles statistics
The function computes, Average location, min, max and standard
deviation vectors. The correct statistics are only available for
pid() == 0
.
(Particles P) {
pstats statsp = {0 ,0, 0}, min = {0,0,0},
coord avg = {0, 0, 0}, stddev = {0, 0, 0};
max foreach_dimension(3) {
.x = stddev.x = 0;
avg.x = HUGE;
min.x = -HUGE;
max}
long unsigned int np = pn[P];
#if _MPI
(MPI_IN_PLACE, &np, 1, MPI_UNSIGNED_LONG,
MPI_Allreduce , MPI_COMM_WORLD);
MPI_SUM#endif
if (np) {
foreach_dimension() { //reduction of coord members does not work
double avgx = 0;
double minx = HUGE;
double maxx = -HUGE;
(P, reduction(+:avgx) reduction(max:maxx)
foreach_particle_inreduction (min:minx)) {
+= p().x;
avgx if (p().x < minx)
= p().x;
minx if (p().x > maxx)
= p().x;
maxx }
.x = avgx/(double)np;
avg.x = minx;
min.x = maxx;
max}
foreach_dimension() {
double stddevx = 0;
(P, reduction(+:stddevx)) {
foreach_particle_in+= sq(avg.x - p().x);
stddevx }
.x = sqrt(stddevx/(double)np);
stddev}
}
;
pstats s.max = max, s.min = min, s.avg = avg, s.stddev = stddev;
sreturn s;
}
Propability density function
Obtain a scalar PDF from particle locations
void particle_pdf (Particles P, scalar s) {
foreach()
[] = 0;
sparticle_boundary (P);
(P) {
foreach_particle_in= locate (x,y,z);
Point point if (point.level > 0)
[]++;
s}
foreach()
[] /= (pn[P]*dv());
sboundary ({s});
}
Random step
Particles displace a certain distance (step
) in a random
direction
void random_step (Particles P, double step) {
(P) {
foreach_particle_indouble theta = noise()*pi;
#if (dimension == 1)
= {sign(theta)};
coord d #elif (dimension < 3)
= {sin(theta), cos(theta)};
coord d #else
double phi = acos(noise());
= {sin(phi)*cos(theta), sin(phi)*sin(theta), cos(phi)};
coord d #endif
foreach_dimension()
().x += d.x*step;
p}
}
Length of particle loop
A function that computes the line length of particles places in a loop (mind the ordering). Special care is taken to obtain 4th order accuracy.
double plength (Particles P) {
double lr = 0;
int np = pn[P];
= pl[P];
particles pli (P) {
foreach_particle_inint il = _j_particle - 1 < 0 ? np - 1: _j_particle - 1;
int ir = _j_particle + 1 >= np ? 0 : _j_particle + 1;
= (coord){pli[il].x, pli[il].y, pli[il].z};
coord pl = (coord){pli[_j_particle].x, pli[_j_particle].y, pli[_j_particle].z};
coord pm = (coord){pli[ir].x, pli[ir].y, pli[ir].z};
coord pr = {0, 0, 0}, a1 = {0,0,0};
coord bv = {0,0,0};
coord a2 double bl = 0, ka = 0;
foreach_dimension() {
.x = pm.x - pl.x;
a1.x = pr.x - pl.x;
bv+= sq(bv.x);
bl }
= sqrt(bl);
bl foreach_dimension()
+= a1.x*bv.x/bl;
ka
foreach_dimension()
.x = a1.x - bv.x*ka/bl;
a2
(&a2);
normalize double al = 0, am = 0, ar = 0;
foreach_dimension() {
-= a2.x*pl.x;
al -= a2.x*pm.x;
am -= a2.x*pr.x;
ar }
double C = fabs(am - al);
double xt = 0;
double b = 0;
foreach_dimension() {
+= sq(pl.x - pm.x);
xt += sq(pl.x - pr.x);
b }
= sqrt (xt - sq(C));
xt = sqrt(b);
b double A = C/((xt*(b - xt)));
double xp1 = 0.5*b*(1 - 1/sqrt(3));
double xp2 = 0.5*b*(1 + 1/sqrt(3));
double l1 = b*sqrt(1. + sq(-2*A*xp1 + A*b));
double l2 = b*sqrt(1. + sq(-2*A*xp2 + A*b));
+= (l1 + l2)/4;
lr }
return lr;
}