Introduction
Introduction Statistics Contact Development Disclaimer Help
tuse upwind differences for pressure and a larger S_min - granular-channel-hydr…
git clone git://src.adamsgaard.dk/granular-channel-hydro
Log
Files
Refs
README
LICENSE
---
commit b927f7b0194424fbefffb922391b0d999459702a
parent 3a8080534dbb60ccc47435d15ed6ce9fd909fc59
Author: Anders Damsgaard Christensen <[email protected]>
Date: Wed, 1 Feb 2017 16:05:32 -0800
use upwind differences for pressure and a larger S_min
Diffstat:
M 1d-test.py | 89 +++++++++++++++--------------…
1 file changed, 42 insertions(+), 47 deletions(-)
---
diff --git a/1d-test.py b/1d-test.py
t@@ -19,7 +19,7 @@ import sys
## Model parameters
Ns = 25 # Number of nodes [-]
Ls = 100e3 # Model length [m]
-t_end = 24.*60.*60.*1.9 # Total simulation time [s]
+t_end = 24.*60.*60.*2 # Total simulation time [s]
tol_Q = 1e-3 # Tolerance criteria for the normalized max. residual for Q
tol_P_c = 1e-3 # Tolerance criteria for the normalized max. residual for P_c
max_iter = 1e2*Ns # Maximum number of solver iterations before failure
t@@ -44,8 +44,8 @@ K_d = 0.0 # Deposition constant [-], disabled when 0.0
#D50 = 1e-3 # Median grain size [m]
#tau_c = 0.5*g*(rho_s - rho_i)*D50 # Critical shear stress for transport
d15 = 1e-3 # Characteristic grain size [m]
-#tau_c = 0.025*d15*g*(rho_s - rho_i) # Critical shear stress (Carter 2016)
-tau_c = 0.
+tau_c = 0.025*d15*g*(rho_s - rho_i) # Critical shear stress (Carter 2016)
+#tau_c = 0.
mu_w = 1.787e-3 # Water viscosity [Pa*s]
froude = 0.1 # Friction factor [-]
v_s = d15**2.*g*2.*(rho_s - rho_i)/(9.*mu_w) # Settling velocity (Carter 2016)
t@@ -59,7 +59,7 @@ c_1 = -0.118 # [m/kPa]
c_2 = 4.60 # [m]
# Minimum channel size [m^2], must be bigger than 0
-S_min = 1e-2
+S_min = 1e-1
t@@ -151,69 +151,61 @@ def update_channel_size_with_limit(S, dSdt, dt, N):
def flux_solver(m_dot, ds):
# Iteratively find new fluxes
- it_Q = 0
- max_res_Q = 1e9 # arbitrary large value
+ it = 0
+ max_res = 1e9 # arbitrary large value
# Iteratively find solution, do not settle for less iterations than the
# number of nodes
- while max_res_Q > tol_Q and it_Q < Ns:
+ while max_res > tol_Q or it < Ns:
Q_old = Q.copy()
# dQ/ds = m_dot -> Q_out = m*delta(s) + Q_in
# Upwind information propagation (upwind)
- #Q[1:] = m_dot*ds[1:] - Q[:-1]
- #Q[0] = 0.
Q[0] = 1e-2 # Ng 2000
Q[1:] = m_dot*ds[1:] + Q[:-1]
- max_res_Q = numpy.max(numpy.abs((Q - Q_old)/(Q + 1e-16)))
+ max_res = numpy.max(numpy.abs((Q - Q_old)/(Q + 1e-16)))
if output_convergence:
- print('it_Q = {}: max_res_Q = {}'.format(it_Q, max_res_Q))
+ print('it = {}: max_res = {}'.format(it, max_res))
#import ipdb; ipdb.set_trace()
- if it_Q >= max_iter:
- raise Exception('t = {}, step = {}:'.format(t, step) +
+ if it >= max_iter:
+ raise Exception('t = {}, step = {}:'.format(time, step) +
'Iterative solution not found for Q')
- it_Q += 1
+ it += 1
return Q
def pressure_solver(psi, F, Q, S):
# Iteratively find new water pressures
+ # dP_c/ds = psi - FQ^2/S^{8/3}
- it_P_c = 0
- max_res_P_c = 1e9 # arbitrary large value
- while max_res_P_c > tol_P_c and it_P_c < Ns:
+ it = 0
+ max_res = 1e9 # arbitrary large value
+ while max_res > tol_P_c or it < Ns*40:
P_c_old = P_c.copy()
- # dP_c/ds = psi - FQ^2/S^{8/3}
- #if it_P_c % 2 == 0: # Alternate direction between iterations
- #P_c[1:] = psi[1:]*ds[1:] \
- #- F*Q[1:]**2./(S[1:]**(8./3.))*ds[1:] \
- #+ P_c[:-1] # Downstream
- #else:
-
- #P_c[:-1] = -psi[:-1]*ds[:-1] \
- #+ F*Q[:-1]**2./(S[:-1]**(8./3.))*ds[:-1] \
- #+ P_c[1:] # Upstream
-
- P_c[:-1] = -avg_midpoint(psi)*ds[:-1] \
- + F*avg_midpoint(Q)**2./(S[:-1]**(8./3.))*ds[:-1] \
- + P_c[1:] # Upstream
-
- # Dirichlet BC at terminus
+
+ # Upwind finite differences
+ P_c[:-1] = -psi[:-1]*ds[:-1] \
+ + F*Q[:-1]**2./(S[:-1]**(8./3.))*ds[:-1] \
+ + P_c[1:] # Upstream
+
+ # Dirichlet BC (fixed pressure) at terminus
P_c[-1] = 0.
- max_res_P_c = numpy.max(numpy.abs((P_c - P_c_old)/(P_c + 1e-16)))
+ # von Neumann BC (no gradient = no flux) at s=0
+ P_c[0] = P_c[1]
+
+ max_res = numpy.max(numpy.abs((P_c - P_c_old)/(P_c + 1e-16)))
if output_convergence:
- print('it_P_c = {}: max_res_P_c = {}'.format(it_P_c,
- max_res_P_c))
+ print('it = {}: max_res = {}'.format(it, max_res))
- if it_P_c >= max_iter:
- raise Exception('t = {}, step = {}:'.format(t, step) +
+ if it >= max_iter:
+ raise Exception('t = {}, step = {}:'.format(time, step) +
'Iterative solution not found for P_c')
- it_P_c += 1
+ it += 1
#import ipdb; ipdb.set_trace()
#import ipdb; ipdb.set_trace()
t@@ -250,7 +242,6 @@ def plot_state(step, time):
ax_m.set_ylabel('[m]')
ax_ms.set_ylabel('[m/s]')
-
plt.setp(ax_Pa.get_xticklabels(), visible=False)
plt.tight_layout()
if step == -1:
t@@ -261,14 +252,18 @@ def plot_state(step, time):
def find_new_timestep(ds, Q, S):
# Determine the timestep using the Courant-Friedrichs-Lewy condition
- safety = 0.8
- return safety*numpy.minimum(60.*60.*24., numpy.min(numpy.abs(ds/(Q*S))))
+ safety = 0.2
+ dt = safety*numpy.minimum(60.*60.*24., numpy.min(numpy.abs(ds/(Q*S))))
+
+ if dt < 1.0:
+ raise Exception('Error: Time step less than 1 second at time '
+ + '{:.3} s/{:.3} d'.format(time, time/(60.*60.*24.)))
+
+ return dt
def print_status_to_stdout(time, dt):
- sys.stdout.write('\rt = {:.2} s or {:.4} d, dt = {:.2} s'.format(\
- time,
- time/(60.*6…
- dt))
+ sys.stdout.write('\rt = {:.2} s or {:.4} d, dt = {:.2} s '\
+ .format(time, time/(60.*60.*24.), dt))
sys.stdout.flush()
s_c = avg_midpoint(s) # Channel section midpoint coordinates [m]
t@@ -298,7 +293,7 @@ plot_state(-1, 0.0)
## Time loop
time = 0.; step = 0
-while time < t_end:
+while time <= t_end:
dt = find_new_timestep(ds, Q, S)
You are viewing proxied material from mx1.adamsgaard.dk. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.