Source code for geotecha.consolidation.tangandonitsuka2000

# geotecha - A software suite for geotechncial engineering
# Copyright (C) 2018  Rohan T. Walker (rtrwalker@gmail.com)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see http://www.gnu.org/licenses/gpl.html.

"""
Tang and Onitsuka (2000) "Consolidation by vertical drains under
time-dependent loading".

"""
from __future__ import print_function, division

import numpy as np
from matplotlib import pyplot as plt

import math
#import textwrap
#import scipy.special
import geotecha.piecewise.piecewise_linear_1d as pwise


[docs]def tangandonitsuka2000(z, t, kv, kh, ks, kw, mv, gamw, rw, rs, re, H, drn, surcharge_vs_time=((0, 0, 100.0), (0, 1.0, 1.0)), tpor=None, nterms=20): """Consolidation by vertical drains under time-dependent loading An implementation of Tang and Onitsuka (2000)[1]_. Features: - Single layer. - Soil and drain properties constant with time. - Vertical and radial drainage - Well resistance. - Load is uniform with depth but piecewise linear with time. - Radially averaged pore pressure at depth. - Average pore pressure of whole layer vs time. - Settlement of whole layer vs time. Parameters ---------- z : float or 1d array/list of float Depth values for output. t : float or 1d array/list of float Time for degree of consolidation calcs. kv, kh, ks, kw: float Vertical, horizontal, smear zone, and drain permeability. mv : float Volume compressibility. gamw : float Unit weight of water. rw, rs, re: float Drain radius, smear radius, radius of influence. H : float Drainage path length. drn : [0,1] Drainage boundary condition. drn=0 is pervious top pervious bottom. drn=1 is perviousbottom, impervious bottom. surcharge_vs_time: 2 element tuple or array/list, optional (time, magnitude). default = ((0,0,100.0), (0,1.0,1.0)), i.e. instant load of magnitude one. tpor : float or 1d array/list of float, optional Time values for pore pressure vs depth calcs. Default tpor=None i.e. time values will be taken from `t`. nterms : int, optional Maximum number of series terms. Default nterms=20 Returns ------- por : 2d array of float Pore pressure at depth and time. ppress is an array of size (len(z), len(t)). avp : 1d array of float Average pore pressure of layer settlement : 1d array of float surface settlement References ---------- .. [1] Tang, Xiao-Wu, and Katsutada Onitsuka. 'Consolidation by vertical drains under Time-Dependent Loading'. Int Journal for Numerical and Analytical Methods in Geomechanics 24, no. 9 (2000): 739-51. doi:10.1002/1096-9853(20000810)24:9<739::AID-NAG94>3.0.CO;2-B. """ def F_func(n, s, kap): term1 = (math.log(n/s) + kap*math.log(s)-0.75) * n**2 / (n**2 - 1) term2 = s**2 / (n**2 - 1) * (1-kap) * (1-s**2/4/n**2) term3 = kap/ (n**2-1) * (1- 1/4/n**2) return term1 + term2 +term3 def _calc_Tm(alp, t, mag_vs_time): """calculate the Tm expression at a given time Parameters ---------- alp : float eigenvalue, note that this will be squared t : float time value mag_vs_time: PolyLine magnitude vs time Returns ------- Tm: float time dependant function """ loadmag = mag_vs_time.y loadtim = mag_vs_time.x (ramps_less_than_t, constants_less_than_t, steps_less_than_t, ramps_containing_t, constants_containing_t) = (pwise.segment_containing_also_segments_less_than_xi(loadtim, loadmag, t, steps_or_equal_to = True)) exp = math.exp Tm=0 cv = 1 # I copied the Tm function from SchiffmanAndStein1970 i=0 #only one time value for k in steps_less_than_t[i]: sig1 = loadmag[k] sig2 = loadmag[k+1] Tm += (sig2-sig1)*exp(-cv * alp**2 * (t-loadtim[k])) for k in ramps_containing_t[i]: sig1 = loadmag[k] sig2 = loadmag[k+1] t1 = loadtim[k] t2 = loadtim[k+1] # Tm += (-sig1 + sig2)/(alp**2*cv*(-t1 + t2)) - (-sig1 + sig2)*exp(-alp**2*cv*t)*exp(alp**2*cv*t1)/(alp**2*cv*(-t1 + t2)) Tm += (-sig1 + sig2)/(alp**2*cv*(-t1 + t2)) - (-sig1 + sig2)*exp(-alp**2*cv*(t-t1))/(alp**2*cv*(-t1 + t2)) for k in ramps_less_than_t[i]: sig1 = loadmag[k] sig2 = loadmag[k+1] t1 = loadtim[k] t2 = loadtim[k+1] # Tm += -(-sig1 + sig2)*exp(-alp**2*cv*t)*exp(alp**2*cv*t1)/(alp**2*cv*(-t1 + t2)) + (-sig1 + sig2)*exp(-alp**2*cv*t)*exp(alp**2*cv*t2)/(alp**2*cv*(-t1 + t2)) Tm += -(-sig1 + sig2)*exp(-alp**2*cv*(t-t1))/(alp**2*cv*(-t1 + t2)) + (-sig1 + sig2)*exp(-alp**2*cv*(t-t2))/(alp**2*cv*(-t1 + t2)) return Tm z= np.asarray(z) t = np.asarray(t) if tpor is None: tpor = t else: tpor = np.asarray(tpor) if drn==0: #'PTPB' H_ = H/2 # z = z / 2 z = z.copy() i, = np.where(z>H_) z[i]= (H - z[i]) else: #'PTIB' H_ = H surcharge_vs_time = pwise.PolyLine(surcharge_vs_time[0], surcharge_vs_time[1]) kap = kh / ks s = rs / rw n = re / rw F = F_func(n, s, kap) G = kh/kw * (H_/2/rw)**2 M = ((2 * np.arange(nterms) + 1) * np.pi/2) Dm = 8 / M**2 * (n**2 - 1) / n**2 * G bzm = kv / mv / gamw * M**2 / H_**2 brm = kh / mv / gamw * 2 / re**2 / (F + Dm) bm = bzm + brm #por Tm = np.zeros((len(tpor), nterms), dtype=float) for j, tj in enumerate(tpor): for k, bk in enumerate(bm): Tm[j, k]= _calc_Tm(math.sqrt(bk), tj, surcharge_vs_time) Tm = Tm[np.newaxis, :, :] M_ = M[np.newaxis, np.newaxis, :] bm_ = bm[np.newaxis, np.newaxis, :] z_ = z[:, np.newaxis, np.newaxis] por = np.sum(2 / M_ * np.sin(M_ * z_ / H_) * Tm, axis=2) #avp Tm = np.zeros((len(t), nterms), dtype=float) for j, tj in enumerate(t): for k, bk in enumerate(bm): Tm[j, k]= _calc_Tm(math.sqrt(bk), tj, surcharge_vs_time) # Tm = Tm[:, :] M_ = M[np.newaxis, :] avp = np.sum(2 / M_**2 * Tm, axis=1) #settle load = pwise.pinterp_x_y(surcharge_vs_time, t) settle = H * mv * (load - avp) return por, avp, settle
if __name__ == '__main__': import geotecha.plotting.one_d from geotecha.plotting.one_d import plot_vs_depth from geotecha.plotting.one_d import plot_vs_time # H = 1 # z = np.linspace(0, H, 10) # t = np.linspace(0,1,100) # kv, kh, ks, kw = (10, 10, 3, 1) # mv=1 # gamw = 10 # rw, rs, re = (0.03, 0.06, 0.5) # drn = 1 # surcharge_vs_time = ((0,0.15, 0.3, 0.45,100.0), (0,50,50.0,100.0,100.0)) # tpor = t[np.array([20,60,90])] # nterms = 20 # # por, avp, settle = tangandonitsuka2000(z=z, t=t, kv=kv, kh=kh, ks=ks, kw=kw, mv=mv, gamw=gamw, rw=rw, rs=rs, re=re, H=H, # drn=drn, surcharge_vs_time=surcharge_vs_time, # tpor=tpor, nterms=nterms) # # # # # fig_por=plot_vs_depth(por, z, line_labels=['{0:.3g}'.format(v) for v in tpor], # prop_dict={'xlabel': 'Pore Pressure'}) # fig_por.get_axes()[0].grid() ## fig_por.get_axes()[0].set_xlim(0,1.3) # # fig_avp=plot_vs_time(t,avp, prop_dict={'ylabel': "average pore pressure"}) # # fig_set=plot_vs_time(t, settle, prop_dict={'ylabel': "Settlement"}) # fig_set.gca().invert_yaxis() # # plt.show() ######################################## t = np.array([ 1.00000000e-03, 2.00000000e-03, 3.00000000e-03, 4.00000000e-03, 5.00000000e-03, 6.00000000e-03, 7.00000000e-03, 8.00000000e-03, 9.00000000e-03, 1.00000000e-02, 2.00000000e-02, 3.00000000e-02, 4.00000000e-02, 5.00000000e-02, 6.00000000e-02, 7.00000000e-02, 8.00000000e-02, 9.00000000e-02, 1.00000000e-01, 1.10000000e-01, 1.20000000e-01, 1.30000000e-01, 1.40000000e-01, 1.50000000e-01, 1.60000000e-01, 1.70000000e-01, 1.80000000e-01, 1.90000000e-01, 2.00000000e-01, 2.10000000e-01, 2.20000000e-01, 2.30000000e-01, 2.40000000e-01, 2.50000000e-01, 2.60000000e-01, 2.70000000e-01, 2.80000000e-01, 2.90000000e-01, 3.00000000e-01, 3.10000000e-01, 3.20000000e-01, 3.30000000e-01, 3.40000000e-01, 3.50000000e-01, 3.60000000e-01, 3.70000000e-01, 3.80000000e-01, 3.90000000e-01, 4.00000000e-01, 4.10000000e-01, 4.20000000e-01, 4.30000000e-01, 4.40000000e-01, 4.50000000e-01, 4.60000000e-01, 4.70000000e-01, 4.80000000e-01, 4.90000000e-01, 5.00000000e-01, 5.10000000e-01, 5.20000000e-01, 5.30000000e-01, 5.40000000e-01, 5.50000000e-01, 5.60000000e-01, 5.70000000e-01, 5.80000000e-01, 5.90000000e-01, 6.00000000e-01, 6.10000000e-01, 6.20000000e-01, 6.30000000e-01, 6.40000000e-01, 6.50000000e-01, 6.60000000e-01, 6.70000000e-01, 6.80000000e-01, 6.90000000e-01, 7.00000000e-01, 7.10000000e-01, 7.20000000e-01, 7.30000000e-01, 7.40000000e-01, 7.50000000e-01, 7.60000000e-01, 7.70000000e-01, 7.80000000e-01, 7.90000000e-01, 8.00000000e-01, 8.10000000e-01, 8.20000000e-01, 8.30000000e-01, 8.40000000e-01, 8.50000000e-01, 8.60000000e-01, 8.70000000e-01, 8.80000000e-01, 8.90000000e-01, 9.00000000e-01, 9.10000000e-01, 9.20000000e-01, 9.30000000e-01, 9.40000000e-01, 9.50000000e-01, 9.60000000e-01, 9.70000000e-01, 9.80000000e-01, 9.90000000e-01, 1.00000000e+00, 1.01000000e+00]) H = 1 z = np.linspace(0, H,10) kv, kh, ks, kw = (10, 10, 10, 1) mv=1 gamw = 10 rw, rs, re = (0.03, 0.03, 0.5) drn = 1 surcharge_vs_time = ((0,0.15, 0.3, 0.45,100.0), (0,50,50.0,100.0,100.0)) tpor = t[np.array([20,60,90])] nterms = 20 por, avp, settle = tangandonitsuka2000(z=z, t=t, kv=kv, kh=kh, ks=ks, kw=kw, mv=mv, gamw=gamw, rw=rw, rs=rs, re=re, H=H, drn=drn, surcharge_vs_time=surcharge_vs_time, tpor=tpor, nterms=nterms) ############################################## print('por', repr(por)) print('avp', repr(avp)) print('settle', repr(settle))