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) | |