def calc_settle_and_avp(self): """Calculate settlement and average pore pressure at time""" self.set = np.zeros(len(self.t), dtype=float) self.avp = np.zeros(len(self.t), dtype=float) _z2 = self.zlayer _z1 = self.zlayer - self.h # print(_z1,_z2) sin = math.sin cos = math.cos for j, t in enumerate(self.t): settle = 0 avp = 0 q = pwise.pinterp_x_y(self.surcharge_vs_time, t)[0] settle = np.sum(self.mv * self.h) * q for layer in range(self.nlayers): for m in range(self.n): z1 = _z1[layer] z2 = _z2[layer] Am = self._Am[m] mv = self.mv[layer] Bm = self._Bm[m, layer] Cm = self._Cm[m, layer] beta = self._beta[m, layer] cv = self.cv[layer] Zm_integral = -Bm * sin(beta * z1) / beta + Bm * sin( beta * z2) / beta + Cm * cos( beta * z1) / beta - Cm * cos(beta * z2) / beta Tm = self._calc_Tm(cv, beta, t) avp += Zm_integral * Tm * Am settle -= mv * Zm_integral * Tm * Am self.set[j] = settle self.avp[j] = avp / self.zlayer[-1] return
def _calc_avp(self): """calculate the average pore pressure""" sin = cmath.sin cos = cmath.cos h_all = sum(self.h) if self.t is None: return self.avp = np.zeros((1, len(self.t)), dtype=float) self.set = np.zeros((1, len(self.t)), dtype=float) z_in_layer = np.searchsorted(self.zlayer, self.z) self._calc_un() for p, t in enumerate(self.t): for i in range(self.nh): s = self._sn[i] un = self._un[i] for j in range(self.nv): alp = self._alp[i, j] Tm = self._calc_Tm(alp, t) load = pwise.pinterp_x_y(self.surcharge_vs_time, t) for layer, h in enumerate(self.h): # layer = z_in_layer[k] # zlay = z - (self.zlayer[layer] - self.h[layer]) bet = self._betamn[i, j, layer] Cmn = self._Cmn[i, j].real phi_a = self._phia[i, j, layer] phi_a_dot = self._phidota[i, j, layer] phi = (sin(bet * h) / bet * phi_a + (1 - cos(bet * h)) / bet**2 * phi_a_dot) self.avp[0, p] += Cmn * un * phi.real / h_all * Tm self.set[0, p] += self.mv[layer] * ( load * h / self.nh / self.nv - Cmn * un * phi.real * Tm)
def calc_settle_and_avp(self): """Calculate settlement and average pore pressure at time""" self.set = np.zeros(len(self.t), dtype=float) self.avp = np.zeros(len(self.t), dtype=float) _z2 = self.zlayer _z1 = self.zlayer - self.h # print(_z1,_z2) sin = math.sin cos = math.cos for j, t in enumerate(self.t): settle=0 avp = 0 q = pwise.pinterp_x_y(self.surcharge_vs_time, t)[0] settle = np.sum(self.mv * self.h) * q for layer in range(self.nlayers): for m in range(self.n): z1=_z1[layer] z2=_z2[layer] Am = self._Am[m] mv = self.mv[layer] Bm = self._Bm[m, layer] Cm = self._Cm[m, layer] beta = self._beta[m, layer] cv = self.cv[layer] Zm_integral = -Bm*sin(beta * z1)/beta + Bm * sin(beta * z2)/beta + Cm * cos(beta*z1)/beta - Cm*cos(beta*z2)/beta Tm = self._calc_Tm(cv, beta, t) avp += Zm_integral * Tm * Am settle -= mv * Zm_integral * Tm * Am self.set[j] = settle self.avp[j] = avp / self.zlayer[-1] return
def _calc_avp(self): """calculate the average pore pressure""" sin = cmath.sin cos = cmath.cos h_all = sum(self.h) if self.t is None: return self.avp = np.zeros((1, len(self.t)), dtype=float) self.set = np.zeros((1, len(self.t)), dtype=float) z_in_layer = np.searchsorted(self.zlayer, self.z) self._calc_un() for p, t in enumerate(self.t): for i in range(self.nh): s = self._sn[i] un = self._un[i] for j in range(self.nv): alp = self._alp[i, j] Tm = self._calc_Tm(alp, t) load = pwise.pinterp_x_y(self.surcharge_vs_time, t) for layer, h in enumerate(self.h): # layer = z_in_layer[k] # zlay = z - (self.zlayer[layer] - self.h[layer]) bet = self._betamn[i, j, layer] Cmn = self._Cmn[i, j].real phi_a = self._phia[i, j, layer] phi_a_dot = self._phidota[i, j, layer] phi = (sin(bet * h) / bet * phi_a + (1-cos(bet * h))/bet**2*phi_a_dot) self.avp[0, p] += Cmn * un * phi.real / h_all * Tm self.set[0, p] += self.mv[layer] * (load * h /self.nh/self.nv - Cmn * un * phi.real * Tm)
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
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