tDarcy porous flow (CPU) implemented, awaiting tests - sphere - GPU-based 3D di… | |
git clone git://src.adamsgaard.dk/sphere | |
Log | |
Files | |
Refs | |
LICENSE | |
--- | |
commit 4d546f1656814b970cd95e250c2771a5beee42f5 | |
parent 9f99cdfce0698a251618671dbb964b98bfe813f4 | |
Author: Anders Damsgaard <[email protected]> | |
Date: Sat, 29 Jun 2013 12:11:33 +0200 | |
Darcy porous flow (CPU) implemented, awaiting tests | |
Diffstat: | |
A python/darcy.py | 118 +++++++++++++++++++++++++++++… | |
M src/darcy.cpp | 83 +++++++++++++++++++++++------… | |
M src/sphere.h | 48 ++++++++++++++++++++++++++---… | |
M src/utility.cpp | 59 +++++++++++++++++++++++++++++… | |
M src/utility.h | 6 ++++++ | |
5 files changed, 286 insertions(+), 28 deletions(-) | |
--- | |
diff --git a/python/darcy.py b/python/darcy.py | |
t@@ -0,0 +1,118 @@ | |
+#!/usr/bin/env python | |
+ | |
+# Import sphere functionality | |
+from sphere import * | |
+import sys | |
+ | |
+### EXPERIMENT SETUP ### | |
+initialization = True | |
+consolidation = True | |
+#shearing = True | |
+rendering = False | |
+#plots = False | |
+ | |
+ | |
+ | |
+# Number of particles | |
+#np = 1e2 | |
+np = 1e4 | |
+ | |
+# Common simulation id | |
+sim_id = "darcy" | |
+ | |
+# Deviatoric stress [Pa] | |
+#devs = 10e3 | |
+devslist = [10.0e3] | |
+ | |
+### INITIALIZATION ### | |
+ | |
+# New class | |
+init = Spherebin(np = np, nd = 3, nw = 0, sid = sim_id + "-init") | |
+ | |
+# Save radii | |
+init.generateRadii(radius_mean = 0.05) | |
+ | |
+# Use default params | |
+init.defaultParams(mu_s = 0.4, mu_d = 0.4, nu = 8.9e-4) | |
+ | |
+# Initialize positions in random grid (also sets world size) | |
+#init.initRandomGridPos(gridnum = numpy.array([9, 9, 1000]), periodic = 1, con… | |
+#init.initRandomGridPos(gridnum = numpy.array([32, 32, 1000]), periodic = 1, c… | |
+init.initRandomGridPos(gridnum = numpy.array([32, 32, 1000]), periodic = 1, co… | |
+ | |
+# Bond ~30% of the particles | |
+#init.random2bonds(spacing=0.1) | |
+ | |
+# Set duration of simulation | |
+init.initTemporal(total = 7.0) | |
+init.time_file_dt[0] = 0.05 | |
+#init.time_file_dt[0] = init.time_dt[0]*0.99 | |
+#init.time_total[0] = init.time_dt[0]*2.0 | |
+#init.initTemporal(total = 0.5) | |
+#init.time_file_dt[0] = init.time_total[0]/5.0 | |
+ | |
+#init.f_rho[2,2,4] = 5.0 | |
+#init.f_rho[6,6,10] = 1.1 | |
+#init.f_rho[:,:,-1] = 1.0001 | |
+ | |
+if (initialization == True): | |
+ | |
+ # Write input file for sphere | |
+ init.writebin() | |
+ | |
+ # Run sphere | |
+ init.run(dry=True) | |
+ init.run(darcyflow=True) | |
+ | |
+ | |
+### CONSOLIDATION ### | |
+ | |
+for devs in devslist: | |
+ # New class | |
+ cons = Spherebin(np = init.np, nw = 1, sid = sim_id + "-cons-devs{}".forma… | |
+ | |
+ # Read last output file of initialization step | |
+ lastf = status(sim_id + "-init") | |
+ cons.readbin("../output/" + sim_id + "-init.output{:0=5}.bin".format(lastf… | |
+ | |
+ # Setup consolidation experiment | |
+ cons.consolidate(deviatoric_stress = devs, periodic = init.periodic) | |
+ | |
+ | |
+ # Set duration of simulation | |
+ cons.initTemporal(total = 1.5) | |
+ #cons.initTemporal(total = 0.0019, file_dt = 0.00009) | |
+ #cons.initTemporal(total = 0.0019, file_dt = 1e-6) | |
+ #cons.initTemporal(total = 0.19, file_dt = 0.019) | |
+ | |
+ cons.w_m[0] *= 0.001 | |
+ | |
+ | |
+ | |
+ if (consolidation == True): | |
+ # Write input file for sphere | |
+ cons.writebin() | |
+ | |
+ # Run sphere | |
+ cons.run(dry=True) # show values, don't run | |
+ cons.run(darcyflow=True) # run | |
+ | |
+ if (plots == True): | |
+ # Make a graph of energies | |
+ visualize(cons.sid, "energy", savefig=True, outformat='png') | |
+ visualize(cons.sid, "walls", savefig=True, outformat='png') | |
+ | |
+ if (rendering == True): | |
+ # Render images with raytracer | |
+ cons.render(method = "pres", max_val = 2.0*devs, verbose = False) | |
+ | |
+ project = cons.sid | |
+ lastfile = status(cons.sid) | |
+ sb = Spherebin() | |
+ for i in range(lastfile+1): | |
+ fn = "../output/{0}.output{1:0=5}.bin".format(project, i) | |
+ sb.sid = project + ".output{:0=5}".format(i) | |
+ sb.readbin(fn, verbose = False) | |
+ for y in range(0,sb.num[1]): | |
+ sb.plotFluidDensities(y = y) | |
+ sb.plotFluidVelocities(y = y) | |
diff --git a/src/darcy.cpp b/src/darcy.cpp | |
t@@ -23,7 +23,7 @@ void DEM::initDarcyMem() | |
d_T = new Float3[ncells]; // hydraulic transmissivity matrix | |
d_Ss = new Float[ncells]; // hydraulic storativity matrix | |
d_W = new Float[ncells]; // hydraulic recharge | |
- d_n = new Float[ncells]; // cell porosity | |
+ d_phi = new Float[ncells]; // cell porosity | |
} | |
// Free memory | |
t@@ -37,7 +37,7 @@ void DEM::freeDarcyMem() | |
free(d_T); | |
free(d_Ss); | |
free(d_W); | |
- free(d_n); | |
+ free(d_phi); | |
} | |
// 3D index to 1D index | |
t@@ -57,7 +57,7 @@ void DEM::initDarcyVals() | |
const Float k = 1.0e-10; | |
// Density of the fluid [kg/m^3] | |
- const Float rho = 3600.0; | |
+ const Float rho = 1000.0; | |
unsigned int ix, iy, iz, cellidx; | |
for (ix=0; ix<d_nx; ++ix) { | |
t@@ -95,7 +95,7 @@ void DEM::copyDarcyVals(unsigned int read, unsigned int writ… | |
d_T[write] = MAKE_FLOAT3(d_T[read].x, d_T[read].y, d_T[read].z); | |
d_Ss[write] = d_Ss[read]; | |
d_W[write] = d_W[read]; | |
- d_n[write] = d_n[read]; | |
+ d_phi[write] = d_phi[read]; | |
} | |
// Update ghost nodes from their parent cell values | |
t@@ -156,14 +156,32 @@ void DEM::setDarcyGhostNodes() | |
// Find cell transmissivities from hydraulic conductivities and cell dimensions | |
void DEM::findDarcyTransmissivities() | |
{ | |
+ // Find porosities from cell particle content | |
+ findPorosities(); | |
+ | |
+ // Density of the fluid [kg/m^3] | |
+ const Float rho = 1000.0; | |
+ | |
+ // Kozeny-Carman parameter | |
+ Float a = 1.0e-8; | |
+ | |
unsigned int ix, iy, iz, cellidx; | |
- Float K; | |
+ Float K, k; | |
for (ix=0; ix<d_nx; ++ix) { | |
for (iy=0; iy<d_ny; ++iy) { | |
for (iz=0; iz<d_nz; ++iz) { | |
cellidx = idx(ix,iy,iz); | |
- K = d_K[cellidx]; | |
+ | |
+ // Read cell porosity | |
+ Float phi = d_phi[cellidx]; | |
+ | |
+ // Calculate permeability from the Kozeny-Carman relationship | |
+ k = a*phi*phi*phi/(1.0 - phi*phi); | |
+ | |
+ //K = d_K[cellidx]; | |
+ // Save hydraulic conductivity [m/s] | |
+ d_K[cellidx] = k*rho*-params.g[2]/params.nu; | |
// Hydraulic transmissivity [m2/s] | |
Float3 T = {K*d_dx, K*d_dy, K*d_dz}; | |
t@@ -293,6 +311,12 @@ Float hmean(Float a, Float b) { | |
// Boundary conditions are fixed values (Dirichlet) | |
void DEM::explDarcyStep() | |
{ | |
+ // Find transmissivities from cell particle content | |
+ findDarcyTransmissivities(); | |
+ | |
+ // Check the time step length | |
+ checkDarcyTimestep(); | |
+ | |
// Cell dims squared | |
const Float dx2 = d_dx*d_dx; | |
const Float dy2 = d_dy*d_dy; | |
t@@ -404,14 +428,13 @@ void DEM::explDarcyStep() | |
} | |
} | |
- // Find macroscopic cell fluid velocities | |
- findDarcyVelocities(); | |
- | |
// Swap d_H and d_H_new | |
Float* tmp = d_H; | |
d_H = d_H_new; | |
d_H_new = tmp; | |
+ // Find macroscopic cell fluid velocities | |
+ findDarcyVelocities(); | |
} | |
// Print array values to file stream (stdout, stderr, other file) | |
t@@ -485,7 +508,7 @@ void DEM::findDarcyVelocities() | |
dH = d_dH[cellidx]; | |
// Approximate cell porosity | |
- Float n = cellPorosity(ix, iy, iz); | |
+ Float phi = d_phi[cellidx]; | |
// Calculate flux | |
// The sign might need to be reversed, depending on the | |
t@@ -495,9 +518,9 @@ void DEM::findDarcyVelocities() | |
q.z = -d_K[cellidx]/nu * dH.z; | |
// Calculate velocity | |
- v.x = q.x/n; | |
- v.y = q.y/n; | |
- v.z = q.z/n; | |
+ v.x = q.x/phi; | |
+ v.y = q.y/phi; | |
+ v.z = q.z/phi; | |
d_V[cellidx] = v; | |
} | |
} | |
t@@ -556,9 +579,21 @@ Float DEM::cellPorosity( | |
} | |
// Return the porosity, which should always be between 0.0 and 1.0 | |
- Float n = fmin(1.0, fmax(0.0, (void_volume)/cell_volume)); | |
- d_n[idx(x,y,z)] = n; | |
- return n; | |
+ Float phi = fmin(1.0, fmax(0.0, void_volume/cell_volume)); | |
+ //Float phi = 0.1; | |
+ return phi; | |
+} | |
+ | |
+void DEM::findPorosities() | |
+{ | |
+ unsigned int ix, iy, iz, cellidx; | |
+ for (ix=0; ix<d_nx; ++ix) { | |
+ for (iy=0; iy<d_ny; ++iy) { | |
+ for (iz=0; iz<d_nz; ++iz) { | |
+ d_phi[idx(ix,iy,iz)] = cellPorosity(ix,iy,iz); | |
+ } | |
+ } | |
+ } | |
} | |
// Find particles with centres inside a spatial interval | |
t@@ -619,7 +654,7 @@ Float DEM::getTmax() | |
return max; | |
} | |
// Get maximum value in 1d array with ghost nodes | |
-Float DEM::getSmin() | |
+Float DEM::getSsmin() | |
{ | |
Float min = 1.0e13; // initialize with a small number | |
unsigned int ix,iy,iz; | |
t@@ -704,9 +739,17 @@ void DEM::initDarcy(const Float cellsizemultiplier) | |
// Print final heads and free memory | |
void DEM::endDarcy() | |
{ | |
- //printDarcyArray(stdout, d_H, "d_H"); | |
- //printDarcyArray(stdout, d_V, "d_V"); | |
- //printDarcyArray(stdout, d_n, "d_n"); | |
+ FILE* Kfile; | |
+ if ((Kfile = fopen("d_K.txt","w"))) { | |
+ printDarcyArray(Kfile, d_K); | |
+ fclose(Kfile); | |
+ } else { | |
+ fprintf(stderr, "Error, could not open d_K.txt\n"); | |
+ } | |
+ printDarcyArray(stdout, d_phi, "d_phi"); | |
+ printDarcyArray(stdout, d_H, "d_H"); | |
+ printDarcyArray(stdout, d_K, "d_K"); | |
+ printDarcyArray(stdout, d_V, "d_V"); | |
freeDarcyMem(); | |
} | |
diff --git a/src/sphere.h b/src/sphere.h | |
t@@ -147,7 +147,7 @@ class DEM { | |
//// Darcy-flow | |
int darcy; // 0: no, 1: yes | |
- // Darcy values | |
+ // Darcy values, host | |
int d_nx, d_ny, d_nz; // Number of cells in each dim | |
Float d_dx, d_dy, d_dz; // Cell length in each dim | |
Float* d_H; // Cell hydraulic heads | |
t@@ -155,11 +155,23 @@ class DEM { | |
Float3* d_V; // Cell fluid velocity | |
Float3* d_dH; // Cell spatial gradient in heads | |
Float* d_K; // Cell hydraulic conductivities (anisotropic) | |
- Float* d_S; // Cell hydraulic storativity | |
+ Float3* d_T; // Cell hydraulic transmissivity | |
+ Float* d_Ss; // Cell hydraulic storativity | |
Float* d_W; // Cell hydraulic recharge | |
- Float* d_n; // Cell porosity | |
+ Float* d_phi; // Cell porosity | |
- // Darcy functions | |
+ // Darcy values, device | |
+ Float* dev_d_H; // Cell hydraulic heads | |
+ Float* dev_d_H_new; // Cell hydraulic heads | |
+ Float3* dev_d_V; // Cell fluid velocity | |
+ Float3* dev_d_dH; // Cell spatial gradient in heads | |
+ Float* dev_d_K; // Cell hydraulic conductivities | |
+ Float3* dev_d_T; // Cell hydraulic transmissivity | |
+ Float* dev_d_Ss; // Cell hydraulic storativity | |
+ Float* dev_d_W; // Cell hydraulic recharge | |
+ Float* dev_d_phi; // Cell porosity | |
+ | |
+ //// Darcy functions | |
// Memory allocation | |
void initDarcyMem(); | |
t@@ -168,6 +180,16 @@ class DEM { | |
// Set some values for the Darcy parameters | |
void initDarcyVals(); | |
+ // Copy Darcy values from cell to cell (by index) | |
+ void copyDarcyVals(unsigned int read, unsigned int write); | |
+ | |
+ // Update ghost nodes from their parent cell values | |
+ void setDarcyGhostNodes(); | |
+ | |
+ // Find cell transmissivities from hydraulic conductivities and cell | |
+ // dimensions | |
+ void findDarcyTransmissivities(); | |
+ | |
// Finds central difference gradients | |
void findDarcyGradients(); | |
t@@ -202,6 +224,9 @@ class DEM { | |
const unsigned int y, | |
const unsigned int z); | |
+ // Find and save all cell porosities | |
+ void findPorosities(); | |
+ | |
// Find darcy flow velocities from specific flux (q) | |
void findDarcyVelocities(); | |
t@@ -211,18 +236,27 @@ class DEM { | |
const unsigned int y, | |
const unsigned int z); | |
- // Get minimum value in 1D array | |
- Float minVal3dArr(Float* arr); | |
- | |
// Initialize Darcy values and arrays | |
void initDarcy(const Float cellsizemultiplier = 1.0); | |
// Clean up Darcy arrays | |
void endDarcy(); | |
+ // Check whether the explicit integration is going to meet the | |
+ // stability criteria | |
+ Float getTmax(); | |
+ Float getSsmin(); | |
+ void checkDarcyTimestep(); | |
+ | |
// Perform a single time step, explicit integration | |
void explDarcyStep(); | |
+ //// Darcy functions, device | |
+ void initDarcyMemDev(); | |
+ void freeDarcyMemDev(); | |
+ void transferDarcyToGlobalDeviceMemory(int statusmsg); | |
+ void transferDarcyFromGlobalDeviceMemory(int statusmsg); | |
+ | |
public: | |
// Values and functions accessible from the outside | |
diff --git a/src/utility.cpp b/src/utility.cpp | |
t@@ -4,7 +4,8 @@ | |
//Round a / b to nearest higher integer value | |
-unsigned int iDivUp(unsigned int a, unsigned int b) { | |
+unsigned int iDivUp(unsigned int a, unsigned int b) | |
+{ | |
return (a % b != 0) ? (a / b + 1) : (a / b); | |
} | |
t@@ -15,3 +16,59 @@ void swapFloatArrays(Float* arr1, Float* arr2) | |
arr1 = arr2; | |
arr2 = tmp; | |
} | |
+ | |
+// Get minimum value in 1D array | |
+Float minVal(Float* arr, int length) | |
+{ | |
+ Float min = 1.0e13; // initialize with a large number | |
+ unsigned int i; | |
+ Float val; | |
+ for (i=0; i<length; ++i) { | |
+ val = arr[i]; | |
+ if (val < min) min = val; | |
+ } | |
+ return min; | |
+} | |
+ | |
+// Get maximum value in 1d array | |
+Float maxVal(Float* arr, int length) | |
+{ | |
+ Float max = -1.0e13; // initialize with a small number | |
+ unsigned int i; | |
+ Float val; | |
+ for (i=0; i<length; ++i) { | |
+ val = arr[i]; | |
+ if (val > max) max = val; | |
+ } | |
+ return max; | |
+} | |
+ | |
+// Get minimum value in 3d array | |
+Float minVal(Float3* arr, int length) | |
+{ | |
+ Float min = 1.0e13; // initialize with a large number | |
+ unsigned int i; | |
+ Float3 val; | |
+ for (i=0; i<length; ++i) { | |
+ val = arr[i]; | |
+ if (val.x < min) min = val.x; | |
+ if (val.y < min) min = val.y; | |
+ if (val.z < min) min = val.z; | |
+ } | |
+ return min; | |
+} | |
+ | |
+// Get maximum value in 3d array | |
+Float maxVal(Float3* arr, int length) | |
+{ | |
+ Float max = -1.0e13; // initialize with a small number | |
+ unsigned int i; | |
+ Float3 val; | |
+ for (i=0; i<length; ++i) { | |
+ val = arr[i]; | |
+ if (val.x > max) max = val.x; | |
+ if (val.y > max) max = val.y; | |
+ if (val.z > max) max = val.z; | |
+ } | |
+ return max; | |
+} | |
diff --git a/src/utility.h b/src/utility.h | |
t@@ -10,5 +10,11 @@ unsigned int iDivUp(unsigned int a, unsigned int b); | |
// Swap two arrays pointers | |
void swapFloatArrays(Float* arr1, Float* arr2); | |
+// Get minimum/maximum value in 1D or 3D array | |
+Float minVal(Float* arr, int length); | |
+Float minVal(Float3* arr, int length); | |
+Float maxVal(Float* arr, int length); | |
+Float maxVal(Float3* arr, int length); | |
+ | |
#endif | |
// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 |