def test_shift_scalar(self): #shift c = Talbot(f=f3, n=24, shift=1.0, vectorized=False) assert_allclose(c(1), np.exp(1))
def test_shift2_scalar(self): #shift d = Talbot(f=f4, n=24, shift=1.2, vectorized=False) assert_allclose(d(1.2,args=(2,)), 1.2*np.sin(2*1.2), atol=1e-6)
def test_two_t_scalar(self): a = Talbot(f=f1, n=24, shift=0.0, vectorized=False) #single value of t: assert_allclose(a([1,2]), np.exp(np.array([-1,-2])))
def test_args_scalar(self): #args b = Talbot(f=f2, n=24, shift=0.0, vectorized=False) assert_allclose(b(1, args=(1,)), np.exp(-2))
def test_shift2(self): #shift d = Talbot(f=f4, n=24, shift=1.2) assert_allclose(d(1.2,args=(2,)), 1.2*np.sin(2*1.2), atol=1e-6)
def test_single_t_scalar(self): a = Talbot(f=f1, n=24, shift=0.0, vectorized=False) #single value of t: assert_allclose(a(1), np.exp(-1))
def test_args(self): #args b = Talbot(f=f2, n=24, shift=0.0) assert_allclose(b(1, args=(1,)), np.exp(-2))
def test_shift(self): #shift c = Talbot(f=f3, n=24, shift=1.0) assert_allclose(c(1), np.exp(1))
def test_two_t(self): a = Talbot(f=f1, n=24, shift=0.0) #single value of t: assert_allclose(a([1,2]), np.exp(np.array([-1,-2])))
def test_single_t(self): a = Talbot(f=f1, n=24, shift=0.0) #single value of t: assert_allclose(a(1), np.exp(-1))
def test_t_is_zero_error(self): a = Talbot(f=f1, n=24, shift=0.0) #t=0 raise error: assert_raises(ValueError, a, 0)
def laplace_inverse(self, f, tvar, args, **opt): ilt = Talbot(f, **opt) val = ilt(tvar, args) return val, 0.0
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