Source code for geotecha.consolidation.cosenzaandkorosak2014

# 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.

"""
Cosenza and Korosak (2014) "Secondary Consolidation of Clay as
an Anomalous Diffusion Process".

"""
from __future__ import print_function, division

import numpy as np
from matplotlib import pyplot as plt
import math
import textwrap

import geotecha.piecewise.piecewise_linear_1d as pwise


#from geotecha.mathematics.mp_laplace import Talbot
from geotecha.mathematics.laplace import Talbot

[docs]def plot_one_dim_consol(z, t, por=None, doc=None, settle=None, uavg=None): """Rough plotting routine""" if not por is None: plt.figure() plt.plot(por,z) plt.ylabel('Depth, z') plt.xlabel('Pore pressure') plt.gca().invert_yaxis() if not doc is None: plt.figure() plt.plot(t, doc) plt.xlabel('Time, t') plt.ylabel('Degree of consolidation') plt.gca().invert_yaxis() plt.semilogx() if not settle is None: plt.figure() plt.plot(t, settle) plt.xlabel('Time, t') plt.ylabel('settlement') plt.gca().invert_yaxis() plt.semilogx() if not uavg is None: plt.figure() plt.plot(t, uavg) plt.xlabel('Time, t') plt.ylabel('Average pore pressure') # plt.gca().invert_yaxis() plt.semilogx() return
[docs]def cosenzaandkorosak2014(z, t, theta, v, tpor=None, L = 1, kv = 1, mv = 0.1, gamw = 10, ui = 1, nterms = 100): """Secondary consolidation of Clay as an anomalous diffusion process An implementation of [1]_. Features: - Single layer, soil properties constant over time. - Instant load uniform with depth. - Vertical flow. - Similar to Terzaghi 1d consolidation equation but with additional fractional time derivative that retards pore pressure dissipation as a possible creep mechanism. - Uses Laplace transform in solution. Parameters ---------- z : float or 1d array/list of float Depth. t : float or 1d array/list of float Time. theta : float or array/list of float Parameter in [1]_. v : float or array/list of float Parameter in [1]_. tpor : float or 1d array/list of float Time values for pore pressure vs depth calcs. L : float, optional Drainage path length. Default H = 1. kv : float, optional Vertical coefficient of permeability. Default kv = 1. mv : float, optional Volume compressibility. Default mv = 0.1. gamw : float, optional Unit weight of water. defaule gamw = 10. ui : float, optional Initial uniform pore water pressure. Default ui = 1. nterms : int, optional Maximum number of series terms. Default nterms= 100. 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 between depth H and depth Z. settlement : 1d array of float Surface settlement at depth z. Notes ----- The article [1]_ only has single values of `theta` and `v`. Here I've simply added more. References ---------- Code developed based on [1]_ .. [1] Cosenza, Philippe, and Dean Korosak. 2014. 'Secondary Consolidation of Clay as an Anomalous Diffusion Process'. International Journal for Numerical and Analytical Methods in Geomechanics: doi:10.1002/nag.2256. """ # def F(s, v, theta, lam): # return (1+theta*s**(v-1))/(s + theta*s**v+lam) def F(s, v, theta, lam): numer = np.ones_like(s) denom = s+lam for v_, the_ in zip(v,theta): numer += the_*s**(v_-1) denom += the_*s**v_ return (numer/denom) # def Bn(r, lam, the, v, t): # numer = lam * the*r**(v-1)*cmath.sin(np.pi*v) # denom = (lam - r + the*r**v*cmath.exp(1j*np.pi*v))**2 # # return math.exp(-r * t)*numer/denom z = np.atleast_1d(z) t = np.atleast_1d(t) theta = np.atleast_1d(theta) v = np.atleast_1d(v) if tpor is None: tpor=t else: tpor = np.atleast_1d(t) M = ((2 * np.arange(nterms) + 1) * np.pi) # an = 2 / M dTv = kv / L**2 / mv / gamw lamda_n = M**2*dTv Z = (z / L) # por = np.zeros((len(z), len(tpor))) # doc = np.zeros(len(t)) a = Talbot(F, n=24, shift=0.0) Bn = np.zeros((len(tpor), nterms), dtype=float) for j, lam in enumerate(M): Bn[:, j] = np.array(a(tpor, args=(v, theta, M[j])), dtype=float) if np.allclose(tpor, t): #reuse Bn for Doc Bn_ = Bn.copy() Bn = Bn[np.newaxis, :, :] An = 2/M[np.newaxis, :] * np.sin(M[np.newaxis, :] * Z[:, np.newaxis]) An = An[:, np.newaxis, :] por = np.sum(An*Bn, axis=2)*ui #degree of consolidation An = 2*2**2/M[np.newaxis, :]**2 if np.allclose(tpor, t): Bn = Bn_ else: Bn = np.zeros((len(t), nterms), dtype=float) for j, lam in enumerate(M): Bn[:, j] = np.array(a(t, args=(v, theta, M[j])), dtype=float) doc = 1 - np.sum(An*Bn, axis = 1) return por, doc
if __name__ == '__main__': z = np.linspace(0,1,20) # t = np.linspace(0.1,3,5) t = np.logspace(-3,6,80) tpor = np.array([0.01, 1]) theta = [0.2, 0.2] v = [0.1, 0.01] # theta = 1.5 # v = 0.5 por, doc = cosenzaandkorosak2014(z, t, theta, v, nterms=20) plot_one_dim_consol(z, t, por, doc) plt.show()