tavoid division by zero - sphere - GPU-based 3D discrete element method algorit… | |
git clone git://src.adamsgaard.dk/sphere | |
Log | |
Files | |
Refs | |
LICENSE | |
--- | |
commit 87896b646b81db3467f045a34fdcd4818f3b2107 | |
parent fc014aaa276e3bdc4eb3727500b52c8b076f4d7a | |
Author: Anders Damsgaard <[email protected]> | |
Date: Thu, 19 Mar 2015 19:49:38 +0100 | |
avoid division by zero | |
Diffstat: | |
M src/darcy.cuh | 141 ++++++++++-------------------… | |
1 file changed, 44 insertions(+), 97 deletions(-) | |
--- | |
diff --git a/src/darcy.cuh b/src/darcy.cuh | |
t@@ -266,14 +266,9 @@ __global__ void findDarcyParticleVelocities( | |
*/ | |
// Return the volume of a sphere with radius r | |
-__device__ Float sphereVolume(const Float r) | |
+__forceinline__ __device__ Float sphereVolume(const Float r) | |
{ | |
- if (r > 0.0) | |
- return 4.0/3.0*M_PI*pow(r, 3); | |
- else { | |
- printf("Error: Negative radius\n"); | |
- return NAN; | |
- } | |
+ return 4.0/3.0*M_PI*pow(r, 3); | |
} | |
__device__ Float3 abs(const Float3 v) | |
t@@ -291,10 +286,10 @@ __device__ Float weight( | |
const Float dy, // in: Cell spacing, y | |
const Float dz) // in: Cell spacing, z | |
{ | |
- const Float3 dist = abs(x_p - x_f); | |
+ /*const Float3 dist = abs(x_p - x_f); | |
if (dist.x < dx && dist.y < dy && dist.z < dz) | |
return (1.0 - dist.x/dx)*(1.0 - dist.y/dy)*(1.0 - dist.z/dz); | |
- else | |
+ else*/ | |
return 0.0; | |
} | |
t@@ -345,11 +340,7 @@ __global__ void findDarcyPorositiesLinear( | |
const Float dy = devC_grid.L[1]/ny; | |
const Float dz = devC_grid.L[2]/nz; | |
- // Cell volume | |
- const Float cell_volume = dx*dy*dz; | |
- | |
- Float void_volume = cell_volume; // current void volume | |
- Float void_volume_new = cell_volume; // projected new void volume | |
+ Float void_volume = dx*dy*dz; // current void volume | |
Float4 xr; // particle pos. and radius | |
// check that we are not outside the fluid grid | |
t@@ -364,11 +355,10 @@ __global__ void findDarcyPorositiesLinear( | |
z*dz + 0.5*dz); | |
//Float d, r; | |
- Float r, s, vol_p; | |
+ Float s, vol_p; | |
Float phi = 1.00; | |
Float4 v; | |
Float3 x3, v3; | |
- Float div_v_p = 0.0; | |
//unsigned int n = 0; | |
// Average particle velocities along principal axes around the | |
t@@ -380,17 +370,8 @@ __global__ void findDarcyPorositiesLinear( | |
Float v_p_zn = 0.0; | |
Float v_p_zp = 0.0; | |
- // Coordinates of cell-face nodes relative to cell center | |
- const Float3 n_xn = MAKE_FLOAT3( -0.5*dx, 0.0, 0.0); | |
- const Float3 n_xp = MAKE_FLOAT3( 0.5*dx, 0.0, 0.0); | |
- const Float3 n_yn = MAKE_FLOAT3( 0.0, -0.5*dy, 0.0); | |
- const Float3 n_yp = MAKE_FLOAT3( 0.0, 0.5*dy, 0.0); | |
- const Float3 n_zn = MAKE_FLOAT3( 0.0, 0.0, -0.5*dz); | |
- const Float3 n_zp = MAKE_FLOAT3( 0.0, 0.0, 0.5*dz); | |
- | |
// Read old porosity | |
__syncthreads(); | |
- Float phi_0 = dev_darcy_phi[d_idx(x,y,z)]; | |
// The cell 3d index | |
const int3 gridPos = make_int3((int)x,(int)y,(int)z); | |
t@@ -442,7 +423,6 @@ __global__ void findDarcyPorositiesLinear( | |
v = dev_vel_sorted[i]; | |
x3 = MAKE_FLOAT3(xr.x, xr.y, xr.z); | |
v3 = MAKE_FLOAT3(v.x, v.y, v.z); | |
- r = xr.w; | |
// Find center distance | |
dist = MAKE_FLOAT3( | |
t@@ -451,45 +431,43 @@ __global__ void findDarcyPorositiesLinear( | |
X.z - xr.z); | |
dist += distmod; | |
s = weightDist(dist, dx, dy, dz); | |
- vol_p = sphereVolume(r); | |
+ vol_p = sphereVolume(xr.w); | |
// Subtract particle volume times weight | |
void_volume -= s*vol_p; | |
- //// Find projected new void volume | |
- // Eulerian update of positions | |
- xr += v*devC_dt; | |
- | |
- // Find center distance | |
- dist = MAKE_FLOAT3( | |
- X.x - xr.x, | |
- X.y - xr.y, | |
- X.z - xr.z); | |
- dist += distmod; | |
- s = weightDist(dist, dx, dy, dz); | |
- void_volume_new -= s*vol_p; | |
- | |
// Add particle contribution to cell face | |
// nodes of component-wise velocity | |
x3 += distmod; | |
- s = weight(x3, X + n_xn, dx, dy, dz); | |
- v_p_xn += s*vol_p*v3.x / (s*vol_p); | |
- | |
- s = weight(x3, X + n_xp, dx, dy, dz); | |
- v_p_xp += s*vol_p*v3.x / (s*vol_p); | |
- | |
- s = weight(x3, X + n_yn, dx, dy, dz); | |
- v_p_yn += s*vol_p*v3.y / (s*vol_p); | |
- | |
- s = weight(x3, X + n_yp, dx, dy, dz); | |
- v_p_yp += s*vol_p*v3.y / (s*vol_p); | |
- | |
- s = weight(x3, X + n_zn, dx, dy, dz); | |
- v_p_zn += s*vol_p*v3.z / (s*vol_p); | |
- | |
- s = weight(x3, X + n_zp, dx, dy, dz); | |
- v_p_zp += s*vol_p*v3.z / (s*vol_p); | |
- | |
+ s = weight(x3, | |
+ X + MAKE_FLOAT3(-0.5*dx, 0.0, 0.0), | |
+ dx, dy, dz); | |
+ v_p_xn += s*vol_p*v3.x / (s*vol_p + 1.0e-8… | |
+ | |
+ s = weight(x3, | |
+ X + MAKE_FLOAT3( 0.5*dx, 0.0, 0.0), | |
+ dx, dy, dz); | |
+ v_p_xp += s*vol_p*v3.x / (s*vol_p + 1.0e-8… | |
+ | |
+ s = weight(x3, | |
+ X + MAKE_FLOAT3( 0.0, -0.5*dy, 0.0… | |
+ dx, dy, dz); | |
+ v_p_yn += s*vol_p*v3.y / (s*vol_p + 1.0e-8… | |
+ | |
+ s = weight(x3, | |
+ X + MAKE_FLOAT3( 0.0, 0.5*dy, 0.0), | |
+ dx, dy, dz); | |
+ v_p_yp += s*vol_p*v3.y / (s*vol_p + 1.0e-8… | |
+ | |
+ s = weight(x3, | |
+ X + MAKE_FLOAT3( 0.0, 0.0, -0.5*dz… | |
+ dx, dy, dz); | |
+ v_p_zn += s*vol_p*v3.z / (s*vol_p + 1.0e-8… | |
+ | |
+ s = weight(x3, | |
+ X + MAKE_FLOAT3( 0.0, 0.0, 0.5*dz), | |
+ dx, dy, dz); | |
+ v_p_zp += s*vol_p*v3.z / (s*vol_p + 1.0e-8… | |
} | |
} | |
} | |
t@@ -498,66 +476,35 @@ __global__ void findDarcyPorositiesLinear( | |
} | |
// Make sure that the porosity is in the interval [0.0;1.0] | |
- phi = fmin(0.9, fmax(0.1, void_volume/cell_volume)); | |
- Float phi_new = fmin(0.9, fmax(0.1, void_volume_new/cell_volume)); | |
- //phi = fmin(0.99, fmax(0.01, void_volume/cell_volume)); | |
- //phi = void_volume/cell_volume; | |
- | |
- // Backwards Euler | |
- //Float dphi = phi - phi_0; | |
- | |
- // Forwards Euler | |
- //Float dphi = phi_new - phi; | |
- | |
- // Central difference after first iteration | |
- Float dphi; | |
- if (iteration == 0) | |
- dphi = phi_new - phi; | |
- else | |
- dphi = 0.5*(phi_new - phi_0); | |
+ phi = fmin(0.9, fmax(0.1, void_volume/(dx*dy*dz))); | |
// Determine particle velocity divergence | |
- div_v_p = | |
+ const Float div_v_p = | |
(v_p_xp - v_p_xn)/dx + | |
(v_p_yp - v_p_yn)/dy + | |
(v_p_zp - v_p_zn)/dz; | |
- // report values to stdout for debugging | |
- //printf("%d,%d,%d\tphi = %f dphi = %f\n", x,y,z, phi, dphi); | |
- //printf("%d,%d,%d\tphi = %f dphi = %f v_avg = %f,%f,%f d_avg = %f… | |
- // x,y,z, phi, dphi, v_avg.x, v_avg.y, v_avg.z, d_avg); | |
- | |
// Save porosity and porosity change | |
__syncthreads(); | |
- //phi = 0.5; dphi = 0.0; // disable porosity effects | |
const unsigned int cellidx = d_idx(x,y,z); | |
- dev_darcy_phi[cellidx] = phi*c_phi; | |
- //dev_darcy_dphi[cellidx] += dphi*c_phi; | |
- dev_darcy_dphi[cellidx] += dphi*c_phi; | |
- //dev_darcy_vp_avg[cellidx] = v_avg; | |
- //dev_darcy_d_avg[cellidx] = d_avg; | |
- //dev_darcy_div_v_p[cellidx] = dot_epsilon_kk*c_phi; | |
+ dev_darcy_phi[cellidx] = phi*c_phi; | |
dev_darcy_div_v_p[cellidx] = div_v_p; | |
- /*printf("\n%d,%d,%d: findDarcyPorosities\n" | |
+ printf("\n%d,%d,%d: findDarcyPorosities\n" | |
"\tphi = %f\n" | |
- "\tdphi = %e\n" | |
- "\tdphi_eps= %e\n" | |
"\tX = %e, %e, %e\n" | |
"\txr = %e, %e, %e\n" | |
- "\tq = %e\n" | |
"\tdiv_v_p = %e\n" | |
, x,y,z, | |
- phi, dphi, | |
- dot_epsilon_kk*(1.0 - phi)*devC_dt, | |
+ phi, | |
X.x, X.y, X.z, | |
xr.x, xr.y, xr.z, | |
- q, | |
- dot_epsilon_kk);*/ | |
+ div_v_p); | |
#ifdef CHECK_FLUID_FINITE | |
(void)checkFiniteFloat("phi", x, y, z, phi); | |
- (void)checkFiniteFloat("dphi", x, y, z, dphi); | |
+ //(void)checkFiniteFloat("dphi", x, y, z, dphi); | |
+ (void)checkFiniteFloat("div_v_p", x, y, z, div_v_p); | |
//(void)checkFiniteFloat("dot_epsilon_kk", x, y, z, dot_epsilon_kk… | |
//(void)checkFiniteFloat3("v_avg", x, y, z, v_avg); | |
//(void)checkFiniteFloat("d_avg", x, y, z, d_avg); |