Solving a gray scott-system in 3D using Sparse grids
This example show how to solve a Gray-Scott system in 3D using sparse grids. In this example we will construct a complex geometry
In figure is the final solution of the problem
This example follow the gray scott 3d sparse with the addition that the initialization is completely different to create a complex geometry initialization
We recall here the main differences between sparse and dense.
- Get function return now constant values, so cannot be used to get values, a get in write is an insert a get on a point position that has not been inserted yet return the background value
- Insert function create/overwrite the points value
- getDomainIterator return an iterator on the existing points
- getGridIterator return an iterator on the dense version of the grid
Initialization
The initialization involve the creation of 3 sphere and one cylinder channel connecting them in order to do it we create an iterator over the grid (inserted and not inserted) point with getGridIterator
auto it = Old.getGridIterator();
for (int i = 0 ; i < 3 ; i++)
for (int i = 0 ; i < 3 ; i++)
for (int i = 0 ; i < 3 ; i++)
while (it.isNext())
{
auto key = it.get_dist();
auto keyg = it.get();
for (int i = 0 ; i < 3 ; i++)
{pc.
get(i) = keyg.get(i) * it.getSpacing(i);}
vp.
get(0) = pc.
get(1)*u.get(2) - pc.
get(2)*u.get(1);
vp.
get(1) = pc.
get(2)*u.get(0) - pc.
get(0)*u.get(2);
vp.
get(2) = pc.
get(0)*u.get(1) - pc.
get(1)*u.get(0);
double distance = vp.
norm() / sqrt(3);
if (sph1.isInside(pc) || sph2.isInside(pc) || sph3.isInside(pc) || (distance < 0.1 && channel_box.isInside(pc)) )
{
Old.template insert<U>(key) = 1.0;
Old.template insert<V>(key) = 0.0;
New.template insert<U>(key) = 0.0;
New.template insert<V>(key) = 0.0;
}
++it;
}
This class represent an N-dimensional box.
This class implement the point shape in an N-dimensional space.
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
__device__ __host__ T norm() const
norm of the vector
This class implement the Sphere concept in an N-dimensional space.
After creating the domain we make a perturbation in the up sphere
long int x_start = Old.size(0)*1.95f/domain.getHigh(0);
long int y_start = Old.size(1)*1.95f/domain.getHigh(1);
long int z_start = Old.size(1)*1.95f/domain.getHigh(2);
long int x_stop = Old.size(0)*2.05f/domain.getHigh(0);
long int y_stop = Old.size(1)*2.05f/domain.getHigh(1);
long int z_stop = Old.size(1)*2.05f/domain.getHigh(2);
auto it_init = Old.getGridIterator(start,stop);
while (it_init.isNext())
{
auto key = it_init.get_dist();
Old.template insert<U>(key) = 0.5 + (((double)std::rand())/RAND_MAX -0.5)/10.0;
Old.template insert<V>(key) = 0.25 + (((double)std::rand())/RAND_MAX -0.5)/20.0;
++it_init;
}
grid_key_dx is the key to access any element in the grid
Boundary conditions
For this example we use mirror on direction X Y Z If the point is missing. If the point is missing in both direction than the second derivative is considered zero
double LapU = 0.0;
double LapV = 0.0;
if (Old.existPoint(mz) == true)
{
LapU += Old.get<U>(mz);
LapV += Old.get<V>(mz);
}
else if (Old.existPoint(pz) == true)
{
LapU += Old.get<U>(pz);
LapV += Old.get<V>(pz);
}
else
{
LapU += Old.get<U>(Cp);
LapV += Old.get<V>(Cp);
}
if (Old.existPoint(pz) == true)
{
LapU += Old.get<U>(pz);
LapV += Old.get<V>(pz);
}
else if (Old.existPoint(mz) == true)
{
LapU+= Old.get<U>(mz);
LapV += Old.get<V>(mz);
}
else
{
LapU+= Old.get<U>(Cp);
LapV += Old.get<V>(Cp);
}
if (Old.existPoint(my) == true)
{
LapU += Old.get<U>(my);
LapV += Old.get<V>(my);
}
else if (Old.existPoint(py) == true)
{
LapU += Old.get<U>(py);
LapV += Old.get<V>(py);
}
else
{
LapU+= Old.get<U>(Cp);
LapV += Old.get<V>(Cp);
}
if (Old.existPoint(py) == true)
{
LapU += Old.get<U>(py);
LapV += Old.get<V>(py);
}
else if (Old.existPoint(my) == true)
{
LapU+= Old.get<U>(my);
LapV += Old.get<V>(my);
}
else
{
LapU+= Old.get<U>(Cp);
LapV += Old.get<V>(Cp);
}
if (Old.existPoint(mx) == true)
{
LapU += Old.get<U>(mx);
LapV += Old.get<V>(mx);
}
else if (Old.existPoint(px) == true)
{
LapU += Old.get<U>(px);
LapV += Old.get<V>(px);
}
else
{
LapU+= Old.get<U>(Cp);
LapV += Old.get<V>(Cp);
}
if (Old.existPoint(px) == true)
{
LapU += Old.get<U>(px);
LapV += Old.get<V>(px);
}
else if (Old.existPoint(mx) == true)
{
LapU+= Old.get<U>(mx);
LapV += Old.get<V>(mx);
}
else
{
LapU+= Old.get<U>(Cp);
LapV += Old.get<V>(Cp);
}
LapU -= 6.0*Old.get<U>(Cp);
LapV -= 6.0*Old.get<V>(Cp);