Source code for rockphypy.Anisotropy

#!/usr/bin/env python
# -*-coding:utf-8 -*-


import numpy as np

[docs]class Anisotropy: """Effective models, coordinate transform, anisotropic parameters and phase velocities that can be applied to anisotropic media. """
[docs] @staticmethod def Thomsen(C11, C33, C13, C44, C66, den, theta): """Compute thomsen parameters and three phase velocities for weak anisotropic TI media with vertical symmetry axis. Parameters ---------- Cij : float Stiffnesses in GPa den : float density of the effective medium, for backus average, the effective density can be computed using VRH method for Voigt average. theta : float or array-like angle of incidence Returns ------- float or array-like VP, VSV, VSH: wave velocities propagating along given direction """ alpha= np.sqrt(C33/den) *1e3 beta= np.sqrt(C44/den) *1e3 epsilon= 0.5* (C11-C33)/C33 gamma= 0.5 * (C66-C44)/C44 theta= np.deg2rad(theta) # degree to radian delta= ((C13+C44)**2-(C33-C44)**2 )/ (2*C33*(C33-C44)) VP= alpha*(1+delta*np.sin(theta)**2*np.cos(theta)**2+epsilon*np.sin(theta)**4) VSV= beta*(1+alpha**2/beta**2 * (epsilon-delta)*np.sin(theta)**2*np.cos(theta)**2) VSH= beta*(1+gamma*np.sin(theta)**2) return VP, VSV, VSH, epsilon,gamma,delta
[docs] @staticmethod def Thomsen_Tsvankin(C11,C22,C33,C12,C13,C23,C44,C55,C66): """Elastic constants of an orthorhombic elastic medium defined by Tsvankin’s notation for weak elastic anisotropy assuming the vertical symmetry axis is along the x3 direction. Parameters ---------- Cij : float Stiffnesses in GPa Returns ------- floats Thomsen-Tsvankin parameters """ # defined in the symmetry plane with normal in x1 direction); epsilon_1 = (C22-C33)/(2*C33) delta_1 = ((C23+C44)**2-(C33-C44)**2)/(2*C33*(C33-C44)) gamma_1 = (C66-C55)/2/C55 # defined in the symmetry plane with normal in x2 direction); epsilon_2 = (C11-C33)/(2*C33) delta_2 = ((C13+C55)**2-(C33-C55)**2)/(2*C33*(C33-C55)) gamma_2 = (C66-C44)/2/C44 #gamma_= (C44-C55)/(2*C55) # defined in the horizontal plane with normal in x3 direction delta_3 = ((C12+C66)**2-(C11-C66)**2)/2/C11/(C11-C66) return epsilon_1,delta_1, gamma_1, epsilon_2, delta_2,gamma_2, delta_3
[docs] @staticmethod def Backus(V,lamda, G ): """Computes stiffnesses of a layered medium using backus average model. Parameters ---------- V : float or array-like volumetric fractions of N isotropic layering materials lamda : float or array-like Lamé coefficients of N isotropic layering materials G : float or array-like shear moduli of N isotropic layering materials Returns ------- float or array-like C11,C33,C13,C44,C66:Elastic moduli of the anisotropic layered media """ V= np.asanyarray(V) V=V/np.sum(V) # normalize lamda= np.asanyarray(lamda) G= np.asanyarray(G) # if isinstance(V, ( np.ndarray)) is False: # V=np.array(V) # V=V/np.sum(V) # normalize # if isinstance(lamda, ( np.ndarray)) is False: # lamda=np.array(lamda) # if isinstance(G, ( np.ndarray)) is False: # G=np.array(G) C33=np.dot(V, 1/(lamda+2*G)) **-1 C44=np.dot(V, 1/G)**-1 C66=np.dot(V, G) C13=np.dot(V, 1/(lamda+2*G)) **-1 * np.dot(V, lamda/(lamda+2*G)) C11=np.dot(V, 4*G*(lamda+G)/(lamda+2*G))+np.dot(V, 1/(lamda+2*G))**-1 * np.dot(V, lamda/(lamda+2*G))**2 return C11,C33,C13,C44,C66
[docs] @staticmethod def Backus_log(Vp,Vs,Den,Depth): """Computes Backus Average from log data, notice that the Depth is 1d Vector including each top depth of layer and also the bottom of last layer. Parameters ---------- Vp : array P wave velocities of layers [Vp1,Vp2...Vpn], Km/s, size N Vs : array S wave velocities of layers [Vs1,Vs2...Vsn],Km/s size N Den : array Densities of layers, size N Depth : array 1d depth, ATTENTION: each depth point corresponds to the top of thin isotropic layer, the bottom of the sedimentary package is the last depth point. [dep1,dep2,,,,,,depn, depn+1], size N+1 Returns ------- array-like Stiffness coeffs and averaged density """ Vp, Vs, Den, Depth= np.asanyarray(Vp),np.asanyarray(Vs), np.asanyarray(Den),np.asanyarray(Depth) # compute lame constants from log data G = Den*Vs**2 lamda = Den*Vp**2 - 2*G # compute thickness of each layer given depth thickness = np.diff(Depth) # Volume fraction V= thickness/thickness.sum() C11,C33,C13,C44,C66 = Anisotropy.Backus(V,lamda, G ) # Mass balance for density den = np.dot(V, Den) return C11,C33,C13,C44,C66, den
[docs] @staticmethod def vel_azi_HTI(C,Den,azimuth): """Given stiffnesses and density of the HTI medium, compute the azimuth dependent phase velocities. Parameters ---------- C : 2d array stiffness matrix of the HTI medium Den : float density of the fractured medium azimuth : float or array like azimuth angle, degree Returns ------- float or array like VP,VSH, VSV: phase velocities """ azimuth= np.radians(azimuth) C11=C[0,0] C12=C[0,1] C33=C[2,2] C44=C[3,3] C55=C[4,4] R= np.sqrt( ((C33-C55)*np.sin(azimuth)**2- (C11-C55)*np.cos(azimuth)**2)**2 +4*(C12+C55)**2 *np.sin(azimuth)**2*np.cos(azimuth)**2 ) Vp = 0.5/Den *( (C33+C55 )*np.sin(azimuth)**2 +(C11+C55)*np.cos(azimuth)**2 + R) Vsh= 0.5/Den *( (C33+C55 )*np.sin(azimuth)**2 +(C11+C55)*np.cos(azimuth)**2 - R) Vsv= 1/Den * (C55+ (C44-C55)*np.sin(azimuth)**2) VP= np.sqrt(Vp) VSH= np.sqrt(Vsh) VSV= np.sqrt(Vsv) return VP,VSH, VSV
[docs] @staticmethod def vel_azi_VTI(C,Den,azimuth): """Given stiffnesses and density of the VTI medium, compute the azimuth dependent phase velocities. Parameters ---------- C : 2d array stiffness matrix of the VTI medium Den : float density of the fractured medium azimuth : float or array like azimuth angle, degree Returns ------- float or array like VP,VSH, VSV: phase velocities """ azimuth= np.radians(azimuth) C11=C[0,0] C13=C[0,2] C33=C[2,2] C44=C[3,3] C66=C[5,5] R= np.sqrt( ((C11-C44)*np.sin(azimuth)**2- (C33-C44)*np.cos(azimuth)**2)**2 +(C13+C44)**2 *np.sin(2*azimuth)**2 ) Vp = 0.5/Den *( C11*np.sin(azimuth)**2 +C33*np.cos(azimuth)**2 + C44 + R) Vsv= 0.5/Den *( C11*np.sin(azimuth)**2 +C33*np.cos(azimuth)**2 + C44 - R) Vsh= 1/Den * (C66*np.sin(azimuth)**2+C44*np.cos(azimuth)**2 ) VP = np.sqrt(Vp) VSH= np.sqrt(Vsh) VSV= np.sqrt(Vsv) return VP,VSH, VSV
[docs] @staticmethod def Bond_trans(C, theta, axis=3): """Coordinate Transformations for stiffness matrix in 6x6 Voigt notation using Bond transformation matrix. Parameters ---------- C : 2d array original stiffness matrix theta : float rotational angle axis : int, optional axis=1: fix 1-axis, rotate 2 and 3 axis, examples can be a TTI(Tilted TI) resulted from the rotation of VTI with horizontal aligned fracture sets wrt the vertical x3 axis. In this case, the input C should be a VTI matrix axis=3: fix 3-axis, rotate 1 and 2 axis, E.g. seismic measurements of HTI media e.g caused by vertically aligned fractures. The angle theta may be assigned to be the angle between the fracture normal and a seismic line. Returns ------- 2d array C_trans, new stiffness matrix wrt to the original right-hand rectangular Cartesian coordinates References ---------- - Bond, W., Jan. 1943, The mathematics of the physical properties of crystals, The Bell System Technical Journal, 1-72. """ theta = np.deg2rad(theta) # axis 3 is fixed, rotate x1 and x2 axes. if axis==3: b11 = np.cos(theta) b22 = np.cos(theta) b33 = 1 b21 = np.cos(theta + np.pi/2) b12 = np.cos(np.pi/2 - theta) b13 = 0 b31 = 0 b23 = 0 b32 = 0 # axis 1 is fixed, rotate x2 and x3 axes. elif axis==1: b11 = 1 b22 = np.cos(theta) b33 = np.cos(theta) b21 = 0 b12 = 0 b13 = 0 b31 = 0 b23 = np.cos(theta + np.pi/2) b32 = np.cos(np.pi/2 - theta) # Bond matrix M M1 = np.array([b11**2, b12**2, b13**2, b21**2, b22**2, b23**2, b31**2, b32**2, b33**2]).reshape((3,3)) M2 = np.array([b12*b13, b13*b11, b11*b12, b22*b23, b23*b21, b21*b22, b32*b33, b33*b31, b31*b32]).reshape((3,3)) M3 = np.array([b21*b31, b22*b32, b23*b33, b31*b11, b32*b12, b33*b13, b11*b21, b12*b22, b13*b23]).reshape((3,3)) M4 = np.array([b22*b33+b23*b32, b21*b33+b23*b31, b22*b31+b21*b32, b12*b33+b13*b32, b11*b33+b13*b31, b11*b32+b12*b31, b22*b13+b12*b23, b11*b23+b13*b21, b22*b11+b12*b21]).reshape((3,3)) M = np.block([[M1, M2], [M3, M4]]) C_trans= M @ C @ M.T # matrix multiplication return C_trans