Vector expressions
This example show how to use expressions to do complex calculation on particles
Initialization
He define some useful constants
constexpr int A = 0;
constexpr int B = 1;
constexpr int C = 2;
Derivative second order on h (spacing)
Kernel function
We define a kernel function. In general a kernel is a function like \( K(x_p,x_q,A_p,A_q) \). Where \( x_p \) and \( x_q \) are positions of the 2 particles p and q. \( A_p \) and \( A_q \) are the properties on p and q.
A second version more General is
\( K(p,q,A_p,A_q,particles) \)
Where \( p \) in the index of the particle and \( q \) are the index of the particles produced by the cell-List. and particles is the vector containing the particle p and q (In multi-phase SPH this can also be not true)
- Note
- On multi-phase this is not true
In this case we are defining an exponential-like function \( A_q e^{\frac{|x_p-x_q|^2}{\sigma}} \)
{
float sigma;
:sigma(sigma)
{}
{
float dist = norm(p-q);
return Pq * exp(- dist * dist / sigma);
}
inline Point<3,double> value(
size_t p,
size_t q,
Point<3,double> & Pp,
Point<3,double> & Pq,
const vector_dist<3,
double,
aggregate<
double,
double,
Point<3,double>,
Point<3,double>> > & v)
{
float dist = norm(p-q);
return Pq * exp(- dist * dist / sigma);
}
};
This class implement the point shape in an N-dimensional space.
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
exp_kernel(float var)
Exponential kernel giving variance.
__device__ __host__ float value(const Point< 3, float > &p, const Point< 3, float > &q, float pA, float pB)
Result of the exponential kernel.
Initialization
Here we Initialize the library, we create a Box that define our domain, boundary conditions, and ghost
- See also
- Initialization
openfpm_init(&argc,&argv);
size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
double dt = 0.01;
This class represent an N-dimensional box.
%Vector create
We create 2 vectors one with 4 properties 2 scalar and 2 vectors. and one with one scalar
- See also
- Vector instantiation
vector_dist<3,double, aggregate<double,double,Point<3,double>,
Point<3,double>> > vd(4096,domain,bc,g);
Loop over particles
We assign random position to particles for both vectors
- See also
- Assign position
auto it = vd.getDomainIterator();
while (it.isNext())
{
auto p = it.get();
vd.getPos(p)[0] = (double)rand() / RAND_MAX;
vd.getPos(p)[1] = (double)rand() / RAND_MAX;
vd.getPos(p)[2] = (double)rand() / RAND_MAX;
vd2.getPos(p)[0] = (double)rand() / RAND_MAX;
vd2.getPos(p)[1] = (double)rand() / RAND_MAX;
vd2.getPos(p)[2] = (double)rand() / RAND_MAX;
++it;
}
Mapping particles
Redistribute the particles according to the decomposition
- See also
- Mapping particles
Getting expression properties
Before using expression we have to get alias for each properties we want to use for the expression
auto vA = getV<A>(vd);
auto vB = getV<B>(vd);
auto vC = getV<C>(vd);
auto vD = getV<D>(vd);
auto vPOS = getV<POS_PROP>(vd);
auto v2A = getV<0>(vd);
auto v2POS = getV<POS_PROP>(vd);
Expressions
Once we have the expression properties we can use them to compose expressions
vA = 1;
vB = vA;
vC = 4;
vD = vPOS;
All these expression are applied point wise for each particles
- Note
- the * is a scalar product in case of vectors simple multiplication in case of scalar
vA = norm(vPOS);
vA = vA + sin(2.0 * vD) * exp(1.2 * vD);
vC = pmul(vD,vD) * dt;
vD = vD / sqrt( vD * vD );
Visualization, write VTK files
With this function we output the particles in VTK format.
- See also
- Visualization, write VTK files
Lazy expression and convert object into expressions
If we want to use an object like Point into an expression we have to first convert into an expression with the function getVExpr. Every expression does not produce any code execution until we do not assin this expression to some property
auto p0_e = getVExpr(p0);
auto expr1 = 1.0/2.0/sqrt(M_PI)*exp(-(v2POS-p0_e)*(v2POS-p0_e)/2.0);
v2A = expr1;
Each operator= produce an iteration across particles. It is possible to use the function assign to execute multiple assignment in one cycle. Assign support a variable number of expression
assign(vA,1.0,
vB,expr1,
vC,vD/norm(vD),
vD,2.0*vC);
Apply kernel
we shown the simple usage of simple point-wise function like sin and exp. Here we show the function applyKernel that encapsulate the operation
\(\sum_{q = Neighborhood(p)} Kernel(x_p,x_q,A_p,A_q) \)
where \( x_p \) is the position of the particle p, \( x_q \) is the position of the particle q, \( A_p \) is the value of the property carried by the particle p, \( A_q \) is the value of the property carried by the particle q
- Note
- On particle method we saw the following formulas
-
\( \sum_{q = Neighborhood(p)} A_q [D^{\beta}ker](x_p,x_q) V_q \) in SPH
-
\( \sum_{q = Neighborhood(p)} (A_p-A_q)ker(x_p,x_q) V_q \) in PSE
-
These 2 formulas and others can be embedded into the previous one where
-
\( Kernel(x_p,x_q,A_p,A_q) = A_q [D^{\beta}ker](x_p,x_q) V_q \)
-
\( Kernel(x_p,x_q,A_p,A_q) = (A_p-A_q)*ker(x_p,x_q) V_q \)
We create some useful object to use apply kernel plus we synchronize the ghost for the property 3 because apply kernel require to read the ghost part
auto cl = vd.getCellList(0.1);
vd.ghost_get<3>();
Than we construct an expression with applyKernel
vC = applyKernel_in( vD / norm(vD) ,vd,cl,ker) + vD;
A renormalizaion of the vector vD is calculated on fly for each particle q neighborhood of p. The the following expression is calculated for each particle p
\( (\sum_{q = Neighborhood p} Ker(x_p,x_q,(\frac{vD}{norm(vD)})_p,(\frac{vD}{norm(vD)})_q)) + vD \)
- Note
- Cerefull here ApplyKernel is a special function if it act on property vD we cannot write on property vD ( vD = ... is an error and produce unpredictable result )
Exist also a second version suitable for more General cases
vC = applyKernel_in_gen( vD / norm(vD) ,vd,cl,ker) + vD;
In the case of General-Finite-Differences, DC-PSE and Multi-Phase SPH. \( K(x_p,x_q,A_p,A_q)\) is limitative and we have to use the following \( K(p,q,A_p,A_q,particles) \). In this case the position \( x_p \) and \( x_q \) are substituted by the id of p and id of q comming from the cell list + the vector on which we are operating.
- Note
- in case of Multi-Phase multiple vectors are needed. But such vector can passed in the Kernel structure
vC = applyKernel_in_gen( vD / norm(vD) ,vd,cl,ker) + vD;
If the expression is point-wise the rule the propety on the right cannot appear on the left does not apply
VTK and visualization
Write a VTK file and visualize. Before write the particles also delete Ghost (VTK writer in general output also the ghost particles)
- See also
- Visualization, write VTK files
Finalize
At the very end of the program we have always de-initialize the library