@@ -108,7 +108,7 @@ def avalanche(s, p):
108108 zb , grad_h = avalanche_loop (
109109 s ['zb' ].copy (), s ['zne' ], s ['ds' ], s ['dn' ], nx , ny , E , max_iter_ava , tan_dyn
110110 )
111-
111+
112112 # Ensure water level is up-to-date with bed level
113113 s ['zb' ] = zb
114114 s ['gradh' ] = grad_h
@@ -136,42 +136,42 @@ def avalanche_loop(zb, zne, ds, dn, nx, ny, E, max_iter_ava, tan_dyn):
136136 # Directions: 0 => +X, 1 => +Y
137137 for i in range (ny ):
138138 for j in range (nx ):
139- center = zb [i , j ]
140-
141- # +X direction
142- g0 = 0.0
143- if 1 :#(j > 0) and (j < nx - 1):
139+ # disable avalanching where zne >= zb
140+ if zne [i , j ] >= zb [i , j ]:
141+ continue
142+ else :
143+ center = zb [i , j ]
144+ # +X direction
145+ g0 = 0.0
144146 right = zb [i , (j + 1 ) % nx ]
145147 left = zb [i , (j - 1 ) % nx ]
146148 if not ((right > center ) and (left > center )):
147149 if right > left :
148150 g0 = left - center
149151 else :
150152 g0 = center - right
153+ grad_h_down [i , j , 0 ] = g0 / ds [i , j ]
151154
152- grad_h_down [i , j , 0 ] = g0
153-
154- # +Y direction
155- g1 = 0.0
156- if 1 :#(i > 0) and (i < ny - 1):
155+ # +Y direction
156+ g1 = 0.0
157157 down = zb [(i + 1 ) % ny , j ]
158158 up = zb [(i - 1 ) % ny , j ]
159159 if not ((down > center ) and (up > center )):
160160 if down > up :
161161 g1 = up - center
162162 else :
163163 g1 = center - down
164- grad_h_down [i , j , 1 ] = g1
164+ grad_h_down [i , j , 1 ] = g1 / dn [ i , j ]
165165
166166 # normalize by grid spacing (assume ds, dn are 2D fields)
167- for i in range (ny ):
168- for j in range (nx ):
169- grad_h_down [i , j , 0 ] = grad_h_down [i , j , 0 ] / ds [i , j ]
170- grad_h_down [i , j , 1 ] = grad_h_down [i , j , 1 ] / dn [i , j ]
167+ # for i in range(ny):
168+ # for j in range(nx):
169+ # grad_h_down[i, j, 0] = grad_h_down[i, j, 0] / ds[i, j]
170+ # grad_h_down[i, j, 1] = grad_h_down[i, j, 1] / dn[i, j]
171171
172172 # gradient magnitude and maximum
173- for i in range (ny ):
174- for j in range (nx ):
173+ # for i in range(ny):
174+ # for j in range(nx):
175175 gh2 = grad_h_down [i , j , 0 ] * grad_h_down [i , j , 0 ] + grad_h_down [i , j , 1 ] * grad_h_down [i , j , 1 ]
176176 # optional suppression near zne disabled
177177 gh = np .sqrt (gh2 )
@@ -186,22 +186,22 @@ def avalanche_loop(zb, zne, ds, dn, nx, ny, E, max_iter_ava, tan_dyn):
186186 if max_grad_h < tan_dyn :
187187 break
188188
189- # if we continue we compute fluxes and update zb
189+ # we continue to compute fluxes and update zb
190190
191191 # compute grad_h_nonerod and slope_diff per cell using explicit loops
192192 for i in range (ny ):
193193 for j in range (nx ):
194- grad_h_nonerod = (zb [i , j ] - zne [i , j ]) / ds [i , j ]
195- if grad_h [i , j ] > tan_dyn and grad_h_nonerod > 0.0 :
194+ # grad_h_nonerod = (zb[i, j] - zne[i, j]) / ( ds[i, j]*dn[i, j])
195+ if grad_h [i , j ] > tan_dyn : # and (zb[i, j] - zne[i, j]) > 0.0:
196196 slope_diff [i , j ] = np .tanh (grad_h [i , j ]) - np .tanh (0.9 * tan_dyn )
197- elif grad_h_nonerod < (grad_h [i , j ] - tan_dyn ):
198- slope_diff [i , j ] = np .tanh (grad_h_nonerod )
197+ # elif grad_h_nonerod < (grad_h[i, j] - tan_dyn):
198+ # slope_diff[i, j] = np.tanh(grad_h_nonerod)
199199
200- for i in range (ny ):
201- for j in range (nx ):
200+ # for i in range(ny):
201+ # for j in range(nx):
202202 if grad_h [i , j ] != 0.0 :
203- flux_down [i , j , 0 ] = slope_diff [i , j ] * grad_h_down [i , j , 0 ] / grad_h [i , j ]
204- flux_down [i , j , 1 ] = slope_diff [i , j ] * grad_h_down [i , j , 1 ] / grad_h [i , j ]
203+ flux_down [i , j , 0 ] = slope_diff [i , j ] * grad_h_down [i , j , 0 ]# / grad_h[i, j]
204+ flux_down [i , j , 1 ] = slope_diff [i , j ] * grad_h_down [i , j , 1 ]# / grad_h[i, j]
205205
206206 # Build q_in and q_out from 2-component flux representation
207207 f_x = flux_down [:, :, 0 ]
@@ -239,6 +239,14 @@ def avalanche_loop(zb, zne, ds, dn, nx, ny, E, max_iter_ava, tan_dyn):
239239
240240 q_in = (inc_west + inc_east + inc_north + inc_south )
241241
242- zb += E * (q_in - q_out )
242+ # # check mass balance in the presence of non-erodible layer
243+ if np .any ((E * (q_in - q_out )) < (zne - zb )):
244+ # update bed level with non-erodible layer limit
245+ # this will effectively shut down further avalanching from the cells concerned
246+ # because zb will equal zne there in the next iteration
247+ zb += (zne - zb )
248+ else :
249+ # update bed level without non-erodible layer
250+ zb += E * (q_in - q_out )
243251
244252 return zb , grad_h
0 commit comments