def dispersion_psv(xml_input): """ Compute dispersion curves and displacement functions for PSV propagation. periods, phase_velocities = dispersion_psv(xml_input) Dispersion curves and displacement functions are written to files. """ #- read input --------------------------------------------------------------------------------- inp = rxml.read_xml(xml_input) inp = inp[1] verbose = int(inp["verbose"]) plot_dispersion = int(inp["plot_dispersion"]) plot_amplitudes = int(inp["plot_amplitudes"]) model = inp["model"] write_output = inp["output"]["write_output"] output_directory = inp["output"]["directory"] tag = inp["output"]["tag"] r_min = float(inp["integration"]["starting_radius"]) dr = float(inp["integration"]["radius_sampling"]) T_min = float(inp["T_c_sampling"]["T_min"]) T_max = float(inp["T_c_sampling"]["T_max"]) dT = float(inp["T_c_sampling"]["dT"]) c_min = float(inp["T_c_sampling"]["c_min"]) c_max = float(inp["T_c_sampling"]["c_max"]) dc = float(inp["T_c_sampling"]["dc"]) #- initialisations ---------------------------------------------------------------------------- T = np.arange(T_min, T_max + dT, dT, dtype=float) c = np.arange(c_min, c_max + dc, dc, dtype=float) omega = 2 * np.pi / T mode = [] periods = [] phase_velocities = [] group_velocities = [] r = np.arange(r_min, 6371000.0 + dr, dr, dtype=float) rho = np.zeros(len(r)) A = np.zeros(len(r)) C = np.zeros(len(r)) F = np.zeros(len(r)) L = np.zeros(len(r)) N = np.zeros(len(r)) for n in np.arange(len(r)): rho[n], A[n], C[n], F[n], L[n], N[n] = m.models(r[n], model) #- root-finding algorithm --------------------------------------------------------------------- #- loop over angular frequencies for _omega in omega: mode_count = 0.0 k = _omega / c #- loop over trial wavenumbers r_left = 0.0 for n in np.arange(len(k)): #- compute vertical wave functions using alternative system r1, r2, r3, r4, r5, r = ipsv_alt.integrate_psv_alt( r_min, dr, _omega, k[n], model) r_right = r2[len(r2) - 1] #- check if there is a zero ----------------------------------------------------------- if r_left * r_right < 0.0: mode_count += 1.0 mode.append(mode_count) #- start bisection algorithm rr_left = r_left rr_right = r_right k_left = k[n - 1] k_right = k[n] for i in np.arange(5): k_new = (k_left * np.abs(rr_right) + k_right * np.abs(rr_left)) / (np.abs(rr_left) + np.abs(rr_right)) r1, r2, r3, r4, r5, r = ipsv_alt.integrate_psv_alt( r_min, dr, _omega, k_new, model) rr = r2[len(r2) - 1] if rr * rr_left < 0.0: k_right = k_new rr_right = rr elif rr * rr_right < 0.0: k_left = k_new rr_left = rr else: continue #================================================================================== #- compute final vertical wave functions and corresponding velocities and kernels - #================================================================================== #- compute final vertical wave functions using the original first-order system #- two independent solutions r11, r21, r31, r41, r = ipsv.integrate_psv( r_min, dr, _omega, k_new, model, 1) r12, r22, r32, r42, r = ipsv.integrate_psv( r_min, dr, _omega, k_new, model, 2) #- determine their weights via boundary condition (weight q1 is set to 1) nr = len(r) - 1 q2 = -r21[nr] / r22[nr] #- final solution with boundary condition r1 = r11 + q2 * r12 r2 = r21 + q2 * r22 r3 = r31 + q2 * r32 r4 = r41 + q2 * r42 #- normalise to vertical displacement at the surface mm = r1[nr] r1 = r1 / mm r2 = r2 / mm r3 = r3 / mm r4 = r4 / mm #- phase velocity periods.append(2 * np.pi / _omega) phase_velocities.append(_omega / k_new) #- group velocity U, I1, I3 = vg.group_velocity_psv(r1, r2, r3, r4, r, k_new, _omega / k_new, rho, A, C, F, L, N) group_velocities.append(U) #- kernels kpsv.kernels_psv(r, r1, r2, r3, r4, _omega, k_new, I3, rho, A, C, F, L, N, write_output, output_directory, tag) #================================================================================== #- screen output and displacement function files ---------------------------------- #================================================================================== #- plot and print to screen if verbose: print "T=" + str(2 * np.pi / _omega) + " s, c=" + str( _omega / k_new) + " m/s, U=" + str(U) + " m/s" if plot_amplitudes: f = plt.figure() f.text(0.5, 0.95, "T=" + str(2 * np.pi / _omega) + " s, c=" + str(_omega / k_new) + " m/s", horizontalalignment="center", verticalalignment="top") plt.subplot(2, 2, 1) plt.plot(r, r1) plt.xlabel("radius [m]") plt.title("vertical displacement") plt.subplot(2, 2, 2) plt.plot(r, r2) plt.xlabel("radius [m]") plt.title("vertical stress") plt.subplot(2, 2, 3) plt.plot(r, r3) plt.xlabel("radius [m]") plt.title("horizontal displacement") plt.subplot(2, 2, 4) plt.plot(r, r4) plt.xlabel("radius [m]") plt.title("horizontal stress") plt.show() #- write output if write_output: identifier = "T=" + str(2 * np.pi / _omega) + ".c=" + str( _omega / k_new) fid = open( output_directory + "displacement_psv." + tag + "." + identifier, "w") fid.write("number of vertical sampling points\n") fid.write(str(len(r)) + "\n") fid.write( "radius, vertical displacement, horizontal displacement \n" ) for idx in np.arange(len(r)): fid.write( str(r[idx]) + " " + str(r1[idx]) + " " + str(r3[idx]) + "\n") fid.close() r_left = r_right #============================================================================================== #- output ------------------------------------------------------------------------------------- #============================================================================================== #- dispersion curve --------------------------------------------------------------------------- if write_output: #- write dispersion curve fid = open(output_directory + "dispersion_psv." + tag, "w") for k in np.arange(len(periods)): fid.write( str(periods[k]) + " " + str(phase_velocities[k]) + " " + str(group_velocities[k]) + "\n") fid.close() #- plot --------------------------------------------------------------------------------------- if plot_dispersion: for n in np.arange(len(periods)): plt.plot(periods[n], phase_velocities[n], 'ko') #if mode[n]==1.0: plt.plot(periods[n], group_velocities[n], 'ro') plt.margins(0.2) plt.xlabel("period [s]") plt.ylabel("phase velocity (black), group velocity (red) [m/s]") plt.title("PSV dispersion") plt.show() #- return ------------------------------------------------------------------------------------- return periods, phase_velocities
def dispersion_psv(xml_input): """ Compute dispersion curves and displacement functions for PSV propagation. periods, phase_velocities = dispersion_psv(xml_input) Dispersion curves and displacement functions are written to files. """ #- read input --------------------------------------------------------------------------------- inp = rxml.read_xml(xml_input) inp = inp[1] verbose = int(inp["verbose"]) plot_dispersion = int(inp["plot_dispersion"]) plot_amplitudes = int(inp["plot_amplitudes"]) model = inp["model"] write_output = inp["output"]["write_output"] output_directory = inp["output"]["directory"] tag = inp["output"]["tag"] r_min = float(inp["integration"]["starting_radius"]) dr = float(inp["integration"]["radius_sampling"]) T_min = float(inp["T_c_sampling"]["T_min"]) T_max = float(inp["T_c_sampling"]["T_max"]) dT = float(inp["T_c_sampling"]["dT"]) c_min = float(inp["T_c_sampling"]["c_min"]) c_max = float(inp["T_c_sampling"]["c_max"]) dc = float(inp["T_c_sampling"]["dc"]) #- initialisations ---------------------------------------------------------------------------- T = np.arange(T_min,T_max + dT,dT,dtype=float) c = np.arange(c_min,c_max + dc,dc,dtype=float) omega = 2 * np.pi / T mode = [] periods = [] phase_velocities = [] group_velocities = [] r = np.arange(r_min, 6371000.0 + dr, dr, dtype=float) rho = np.zeros(len(r)) A = np.zeros(len(r)) C = np.zeros(len(r)) F = np.zeros(len(r)) L = np.zeros(len(r)) N = np.zeros(len(r)) for n in np.arange(len(r)): rho[n], A[n], C[n], F[n], L[n], N[n] = m.models(r[n], model) #- root-finding algorithm --------------------------------------------------------------------- #- loop over angular frequencies for _omega in omega: mode_count = 0.0 k = _omega / c #- loop over trial wavenumbers r_left = 0.0 for n in np.arange(len(k)): #- compute vertical wave functions using alternative system r1, r2, r3, r4, r5, r = ipsv_alt.integrate_psv_alt(r_min, dr, _omega, k[n], model) r_right = r2[len(r2)-1] #- check if there is a zero ----------------------------------------------------------- if r_left * r_right < 0.0: mode_count += 1.0 mode.append(mode_count) #- start bisection algorithm rr_left = r_left rr_right = r_right k_left = k[n-1] k_right = k[n] for i in np.arange(5): k_new = (k_left * np.abs(rr_right) + k_right * np.abs(rr_left)) / (np.abs(rr_left) + np.abs(rr_right)) r1, r2, r3, r4, r5, r = ipsv_alt.integrate_psv_alt(r_min, dr, _omega, k_new, model) rr = r2[len(r2)-1] if rr * rr_left < 0.0: k_right = k_new rr_right = rr elif rr * rr_right < 0.0: k_left = k_new rr_left = rr else: continue #================================================================================== #- compute final vertical wave functions and corresponding velocities and kernels - #================================================================================== #- compute final vertical wave functions using the original first-order system #- two independent solutions r11, r21, r31, r41, r = ipsv.integrate_psv(r_min, dr, _omega, k_new, model, 1) r12, r22, r32, r42, r = ipsv.integrate_psv(r_min, dr, _omega, k_new, model, 2) #- determine their weights via boundary condition (weight q1 is set to 1) nr = len(r) - 1 q2 = -r21[nr] / r22[nr] #- final solution with boundary condition r1 = r11 + q2 * r12 r2 = r21 + q2 * r22 r3 = r31 + q2 * r32 r4 = r41 + q2 * r42 #- normalise to vertical displacement at the surface mm = r1[nr] r1 = r1 / mm r2 = r2 / mm r3 = r3 / mm r4 = r4 / mm #- phase velocity periods.append(2*np.pi/_omega) phase_velocities.append(_omega / k_new) #- group velocity U, I1, I3 = vg.group_velocity_psv(r1, r2, r3, r4, r, k_new, _omega/k_new, rho, A, C, F, L, N) group_velocities.append(U) #- kernels kpsv.kernels_psv(r, r1, r2, r3, r4, _omega, k_new, I3, rho, A, C, F, L, N, write_output, output_directory, tag) #================================================================================== #- screen output and displacement function files ---------------------------------- #================================================================================== #- plot and print to screen if verbose: print "T="+str(2*np.pi/_omega)+" s, c="+str(_omega / k_new)+" m/s, U="+str(U)+" m/s" if plot_amplitudes: f=plt.figure() f.text(0.5,0.95,"T="+str(2*np.pi/_omega)+" s, c="+str(_omega / k_new)+" m/s",horizontalalignment="center",verticalalignment="top") plt.subplot(2,2,1) plt.plot(r, r1) plt.xlabel("radius [m]") plt.title("vertical displacement") plt.subplot(2,2,2) plt.plot(r, r2) plt.xlabel("radius [m]") plt.title("vertical stress") plt.subplot(2,2,3) plt.plot(r, r3) plt.xlabel("radius [m]") plt.title("horizontal displacement") plt.subplot(2,2,4) plt.plot(r, r4) plt.xlabel("radius [m]") plt.title("horizontal stress") plt.show() #- write output if write_output: identifier = "T="+str(2*np.pi/_omega)+".c="+str(_omega / k_new) fid = open(output_directory+"displacement_psv."+tag+"."+identifier,"w") fid.write("number of vertical sampling points\n") fid.write(str(len(r))+"\n") fid.write("radius, vertical displacement, horizontal displacement \n") for idx in np.arange(len(r)): fid.write(str(r[idx])+" "+str(r1[idx])+" "+str(r3[idx])+"\n") fid.close() r_left = r_right #============================================================================================== #- output ------------------------------------------------------------------------------------- #============================================================================================== #- dispersion curve --------------------------------------------------------------------------- if write_output: #- write dispersion curve fid = open(output_directory+"dispersion_psv."+tag,"w") for k in np.arange(len(periods)): fid.write(str(periods[k])+" "+str(phase_velocities[k])+" "+str(group_velocities[k])+"\n") fid.close() #- plot --------------------------------------------------------------------------------------- if plot_dispersion: for n in np.arange(len(periods)): plt.plot(periods[n],phase_velocities[n],'ko') #if mode[n]==1.0: plt.plot(periods[n],group_velocities[n],'ro') plt.margins(0.2) plt.xlabel("period [s]") plt.ylabel("phase velocity (black), group velocity (red) [m/s]") plt.title("PSV dispersion") plt.show() #- return ------------------------------------------------------------------------------------- return periods, phase_velocities
def integrate_psv_alt(r_min, dr, omega, k, model): """ Integrate first-order system for a fixed circular frequency omega and a fixed wavenumber k. r1, r2, r3, r4, r5, r = integrate_psv_alt(r_min, dr, omega, k, model) r_min: minimum radius in m dr: radius increment in m omega: circular frequency in Hz k: wave number in 1/m model: Earth model, e.g. "PREM", "GUTENBERG", ... . r1, ...: variables of the alternative Rayleigh wave system r: radius vector in m """ import numpy as np import MODELS.models as m import matplotlib.pyplot as plt #- initialisation ----------------------------------------------------------------------------- r = np.arange(r_min, 6371000.0 + dr, dr, dtype=float) r1 = np.zeros(len(r)) r2 = np.zeros(len(r)) r3 = np.zeros(len(r)) r4 = np.zeros(len(r)) r5 = np.zeros(len(r)) rho, A, C, F, L, N = m.models(r[0], model) #- check if phase velocity is below S velocity ------------------------------------------------ if (k**2 - (omega**2 * rho / L)) > 0.0: #- set initial values r1[0] = 0.0 r2[0] = 1.0 r3[0] = 0.0 r4[0] = 0.0 r5[0] = 0.0 #- integrate upwards with 4th-order Runge-Kutta-------------------------------------------- for n in np.arange(len(r)-1): #- compute Runge-Kutta coeficients for l1 and l2 rho, A, C, F, L, N = m.models(r[n], model) K1_1 = f1(C,L,r4[n],r5[n]) K2_1 = f2(rho,A,C,F,omega,k,r4[n],r5[n]) K3_1 = f3(C,F,k,r4[n],r5[n]) K4_1 = f4(rho,A,C,F,omega,k,r1[n],r2[n],r3[n]) K5_1 = f5(rho,L,omega,k,r1[n],r2[n],r3[n]) rho, A, C, F, L, N = m.models(r[n] + dr / 2.0, model) K1_2 = f1(C,L,r4[n]+0.5*K4_1*dr,r5[n]+0.5*K5_1*dr) K2_2 = f2(rho,A,C,F,omega,k,r4[n]+0.5*K4_1*dr,r5[n]+0.5*K5_1*dr) K3_2 = f3(C,F,k,r4[n]+0.5*K4_1*dr,r5[n]+0.5*K5_1*dr) K4_2 = f4(rho,A,C,F,omega,k,r1[n]+0.5*K1_1*dr,r2[n]+0.5*K2_1*dr,r3[n]+0.5*K3_1*dr) K5_2 = f5(rho,L,omega,k,r1[n]+0.5*K1_1*dr,r2[n]+0.5*K2_1*dr,r3[n]+0.5*K3_1*dr) K1_3 = f1(C,L,r4[n]+0.5*K4_2*dr,r5[n]+0.5*K5_2*dr) K2_3 = f2(rho,A,C,F,omega,k,r4[n]+0.5*K4_2*dr,r5[n]+0.5*K5_2*dr) K3_3 = f3(C,F,k,r4[n]+0.5*K4_2*dr,r5[n]+0.5*K5_2*dr) K4_3 = f4(rho,A,C,F,omega,k,r1[n]+0.5*K1_2*dr,r2[n]+0.5*K2_2*dr,r3[n]+0.5*K3_2*dr) K5_3 = f5(rho,L,omega,k,r1[n]+0.5*K1_2*dr,r2[n]+0.5*K2_2*dr,r3[n]+0.5*K3_2*dr) rho, A, C, F, L, N = m.models(r[n] + dr, model) K1_4 = f1(C,L,r4[n]+K4_3*dr,r5[n]+K5_3*dr) K2_4 = f2(rho,A,C,F,omega,k,r4[n]+K4_3*dr,r5[n]+K5_3*dr) K3_4 = f3(C,F,k,r4[n]+K4_3*dr,r5[n]+K5_3*dr) K4_4 = f4(rho,A,C,F,omega,k,r1[n]+K1_3*dr,r2[n]+K2_3*dr,r3[n]+K3_3*dr) K5_4 = f5(rho,L,omega,k,r1[n]+K1_3*dr,r2[n]+K2_3*dr,r3[n]+K3_3*dr) #- update r1[n + 1] = r1[n] + dr * (K1_1 + 2 * K1_2 + 2 * K1_3 + K1_4) / 6.0 r2[n + 1] = r2[n] + dr * (K2_1 + 2 * K2_2 + 2 * K2_3 + K2_4) / 6.0 r3[n + 1] = r3[n] + dr * (K3_1 + 2 * K3_2 + 2 * K3_3 + K3_4) / 6.0 r4[n + 1] = r4[n] + dr * (K4_1 + 2 * K4_2 + 2 * K4_3 + K4_4) / 6.0 r5[n + 1] = r5[n] + dr * (K5_1 + 2 * K5_2 + 2 * K5_3 + K5_4) / 6.0 #- rescale to maximum to prevent overflow mm = np.max(np.abs(r2)) r1 = r1 / mm r2 = r2 / mm r3 = r3 / mm r4 = r4 / mm r5 = r5 / mm #- return ------------------------------------------------------------------------------------- return r1, r2, r3, r4, r5, r
def integrate_sh(r_min, dr, omega, k, model): """ Integrate first-order system for a fixed circular frequency omega and a fixed wavenumber k. l1, l2, r = integrate_sh(r_min, dr, omega, k, model) r_min: minimum radius in m dr: radius increment in m omega: circular frequency in Hz k: wave number in 1/m model: Earth model, e.g. "PREM", "GUTENBERG", ... . l1, l2: variables of the Love wave system r: radius vector in m """ import numpy as np import MODELS.models as m import matplotlib.pyplot as plt #- initialisation ----------------------------------------------------------------------------- r = np.arange(r_min, 6371000.0 + dr, dr, dtype=float) l1 = np.zeros(len(r)) l2 = np.zeros(len(r)) rho, A, C, F, L, N = m.models(r[0], model) #- check if phase velocity is below S velocity ------------------------------------------------ if (1==1): #(k**2 - (omega**2 * rho / L)) > 0.0: #- set initial values l2[0] = 1.0 l1[0] = 0.0 #- integrate upwards with 4th-order Runge-Kutta-------------------------------------------- for n in np.arange(len(r)-1): #- compute Runge-Kutta coeficients for l1 and l2 rho, A, C, F, L, N = m.models(r[n], model) K1_1 = f1(L, l2[n]) K2_1 = f2(N, rho, k, omega, l1[n]) rho, A, C, F, L, N = m.models(r[n] + dr / 2.0, model) K1_2 = f1(L, l2[n] + K2_1 * dr / 2.0) K2_2 = f2(N, rho, k, omega, l1[n] + K1_1 * dr / 2.0) K1_3 = f1(L, l2[n] + K2_2 * dr / 2.0) K2_3 = f2(N, rho, k, omega, l1[n] + K1_2 * dr / 2.0) rho, A, C, F, L, N = m.models(r[n] + dr, model) K1_4 = f1(L, l2[n] + K2_3 * dr) K2_4 = f2(N, rho, k, omega, l1[n] + K1_3 * dr) #- update l1[n + 1] = l1[n] + dr * (K1_1 + 2 * K1_2 + 2 * K1_3 + K1_4) / 6.0 l2[n + 1] = l2[n] + dr * (K2_1 + 2 * K2_2 + 2 * K2_3 + K2_4) / 6.0 #- rescale to maximum to prevent overflow l1 = l1 / np.max(np.abs(l2)) l2 = l2 / np.max(np.abs(l2)) #- return ------------------------------------------------------------------------------------- return l1, l2, r
def integrate_sh(r_min, dr, omega, k, model): """ Integrate first-order system for a fixed circular frequency omega and a fixed wavenumber k. l1, l2, r = integrate_sh(r_min, dr, omega, k, model) r_min: minimum radius in m dr: radius increment in m omega: circular frequency in Hz k: wave number in 1/m model: Earth model, e.g. "PREM", "GUTENBERG", ... . l1, l2: variables of the Love wave system r: radius vector in m """ import numpy as np import MODELS.models as m import matplotlib.pyplot as plt #- initialisation ----------------------------------------------------------------------------- r = np.arange(r_min, 6371000.0 + dr, dr, dtype=float) l1 = np.zeros(len(r)) l2 = np.zeros(len(r)) rho, A, C, F, L, N = m.models(r[0], model) #- check if phase velocity is below S velocity ------------------------------------------------ if (1 == 1): #(k**2 - (omega**2 * rho / L)) > 0.0: #- set initial values l2[0] = 1.0 l1[0] = 0.0 #- integrate upwards with 4th-order Runge-Kutta-------------------------------------------- for n in np.arange(len(r) - 1): #- compute Runge-Kutta coeficients for l1 and l2 rho, A, C, F, L, N = m.models(r[n], model) K1_1 = f1(L, l2[n]) K2_1 = f2(N, rho, k, omega, l1[n]) rho, A, C, F, L, N = m.models(r[n] + dr / 2.0, model) K1_2 = f1(L, l2[n] + K2_1 * dr / 2.0) K2_2 = f2(N, rho, k, omega, l1[n] + K1_1 * dr / 2.0) K1_3 = f1(L, l2[n] + K2_2 * dr / 2.0) K2_3 = f2(N, rho, k, omega, l1[n] + K1_2 * dr / 2.0) rho, A, C, F, L, N = m.models(r[n] + dr, model) K1_4 = f1(L, l2[n] + K2_3 * dr) K2_4 = f2(N, rho, k, omega, l1[n] + K1_3 * dr) #- update l1[n + 1] = l1[n] + dr * (K1_1 + 2 * K1_2 + 2 * K1_3 + K1_4) / 6.0 l2[n + 1] = l2[n] + dr * (K2_1 + 2 * K2_2 + 2 * K2_3 + K2_4) / 6.0 #- rescale to maximum to prevent overflow l1 = l1 / np.max(np.abs(l2)) l2 = l2 / np.max(np.abs(l2)) #- return ------------------------------------------------------------------------------------- return l1, l2, r
def dispersion_sh(xml_input): """ Compute dispersion curves, displacement functions and kernels for SH propagation. periods, phase_velocities = dispersion_sh(xml_input) Dispersion curves and displacement functions are written to files. """ #- read input --------------------------------------------------------------------------------- inp = rxml.read_xml(xml_input) inp = inp[1] verbose = int(inp["verbose"]) plot_dispersion = int(inp["plot_dispersion"]) plot_amplitudes = int(inp["plot_amplitudes"]) model = inp["model"] write_output = inp["output"]["write_output"] output_directory = inp["output"]["directory"] tag = inp["output"]["tag"] r_min = float(inp["integration"]["starting_radius"]) dr = float(inp["integration"]["radius_sampling"]) T_min = float(inp["T_c_sampling"]["T_min"]) T_max = float(inp["T_c_sampling"]["T_max"]) dT = float(inp["T_c_sampling"]["dT"]) c_min = float(inp["T_c_sampling"]["c_min"]) c_max = float(inp["T_c_sampling"]["c_max"]) dc = float(inp["T_c_sampling"]["dc"]) #- initialisations ---------------------------------------------------------------------------- T = np.arange(T_min,T_max + dT,dT,dtype=float) c = np.arange(c_min,c_max + dc,dc,dtype=float) omega = 2 * np.pi / T mode = [] periods = [] phase_velocities = [] group_velocities = [] r = np.arange(r_min, 6371000.0 + dr, dr, dtype=float) rho = np.zeros(len(r)) A = np.zeros(len(r)) C = np.zeros(len(r)) F = np.zeros(len(r)) L = np.zeros(len(r)) N = np.zeros(len(r)) for n in np.arange(len(r)): rho[n], A[n], C[n], F[n], L[n], N[n] = m.models(r[n], model) #- root-finding algorithm --------------------------------------------------------------------- #- loop over angular frequencies for _omega in omega: k = _omega / c mode_count = 0.0 #- loop over trial wavenumbers l_left = 0.0 for n in np.arange(len(k)): #- compute vertical wave functions l1, l2, r = ish.integrate_sh(r_min, dr, _omega, k[n], model) l_right = l2[len(l2)-1] #- check if there is a zero ----------------------------------------------------------- if l_left * l_right < 0.0: mode_count += 1.0 mode.append(mode_count) #- start bisection algorithm ll_left = l_left ll_right = l_right k_left = k[n-1] k_right = k[n] for i in np.arange(5): k_new = (k_left * np.abs(ll_right) + k_right * np.abs(ll_left)) / (np.abs(ll_left) + np.abs(ll_right)) l1, l2, r = ish.integrate_sh(r_min, dr, _omega, k_new, model) ll = l2[len(l2)-1] if ll * ll_left < 0.0: k_right = k_new ll_right = ll elif ll * ll_right < 0.0: k_left = k_new ll_left = ll else: continue #================================================================================== #- compute final vertical wave functions and corresponding velocities and kernels - #================================================================================== #- stress and displacement functions l1, l2, r = ish.integrate_sh(r_min, dr, _omega, k_new, model) #- phase velocity periods.append(2*np.pi/_omega) phase_velocities.append(_omega/k_new) #- group velocity U, I1, I3 = vg.group_velocity_sh(l1, l2, r, _omega/k_new, rho, N) group_velocities.append(U) #- kernels ksh.kernels_sh(r, l1, l2, _omega, k_new, I3, rho, A, C, F, L, N, write_output, output_directory, tag) #================================================================================== #- screen output and displacement function files ---------------------------------- #================================================================================== #- plot and print to screen if verbose: print "T="+str(2*np.pi/_omega)+" s, c="+str(_omega / k_new)+" m/s, U="+str(U)+" m/s" if plot_amplitudes: plt.plot(r, l1) plt.xlabel("radius [m]") plt.ylabel("stress-normalised displacement amplitude") plt.title("T="+str(2*np.pi/_omega)+" s, c="+str(_omega / k_new)+" m/s") plt.show() #- write output if write_output: identifier = "T="+str(2*np.pi/_omega)+".c="+str(_omega / k_new) fid = open(output_directory+"displacement_sh."+tag+"."+identifier,"w") fid.write("number of vertical sampling points\n") fid.write(str(len(r))+"\n") fid.write("radius displacement stress\n") for idx in np.arange(len(r)): fid.write(str(r[idx])+" "+str(l1[idx])+" "+str(l2[idx])+"\n") fid.close() l_left =l_right #============================================================================================== #- output ------------------------------------------------------------------------------------- #============================================================================================== if write_output: #- write dispersion curve fid = open(output_directory+"dispersion_sh."+tag,"w") for k in np.arange(len(periods)): fid.write(str(periods[k])+" "+str(phase_velocities[k])+" "+str(group_velocities[k])+"\n") fid.close() #- plot --------------------------------------------------------------------------------------- print mode if plot_dispersion: for n in np.arange(len(periods)): plt.plot(periods[n],phase_velocities[n],'ko') if mode[n]==1.0: plt.plot(periods[n],group_velocities[n],'ro') plt.margins(0.2) plt.xlabel("period [s]") plt.ylabel("phase velocity (black), group velocity (red) [m/s]") plt.title("SH dispersion") plt.show() #- return ------------------------------------------------------------------------------------- return periods, phase_velocities
def integrate_psv(r_min, dr, omega, k, model, initial_condition): """ Integrate first-order system for a fixed circular frequency omega and a fixed wavenumber k. r1, r2, r3, r4, r = integrate_psv(r_min, dr, omega, k, model) r_min: minimum radius in m dr: radius increment in m omega: circular frequency in Hz k: wave number in 1/m model: Earth model, e.g. "PREM", "GUTENBERG", ... . r1, ...: variables of the Rayleigh wave system r: radius vector in m """ import numpy as np import MODELS.models as m import matplotlib.pyplot as plt #- initialisation ----------------------------------------------------------------------------- r = np.arange(r_min, 6371000.0 + dr, dr, dtype=float) r1 = np.zeros(len(r)) r2 = np.zeros(len(r)) r3 = np.zeros(len(r)) r4 = np.zeros(len(r)) rho, A, C, F, L, N = m.models(r[0], model) #- check if phase velocity is below S velocity ------------------------------------------------ if (1 == 1): #(k**2 - (omega**2 * rho / L)) > 0.0: #- set initial values if initial_condition == 1: r1[0] = 0.0 r2[0] = 1.0 r3[0] = 0.0 r4[0] = 0.0 else: r1[0] = 0.0 r2[0] = 0.0 r3[0] = 0.0 r4[0] = 1.0 #- integrate upwards with 4th-order Runge-Kutta-------------------------------------------- for n in np.arange(len(r) - 1): #- compute Runge-Kutta coeficients for l1 and l2 rho, A, C, F, L, N = m.models(r[n], model) K1_1 = f1(C, F, k, r2[n], r3[n]) K2_1 = f2(rho, omega, k, r1[n], r4[n]) K3_1 = f3(L, k, r1[n], r4[n]) K4_1 = f4(rho, A, C, F, omega, k, r2[n], r3[n]) rho, A, C, F, L, N = m.models(r[n] + dr / 2.0, model) K1_2 = f1(C, F, k, r2[n] + 0.5 * K2_1 * dr, r3[n] + 0.5 * K3_1 * dr) K2_2 = f2(rho, omega, k, r1[n] + 0.5 * K1_1 * dr, r4[n] + 0.5 * K4_1 * dr) K3_2 = f3(L, k, r1[n] + 0.5 * K1_1 * dr, r4[n] + 0.5 * K4_1 * dr) K4_2 = f4(rho, A, C, F, omega, k, r2[n] + 0.5 * K2_1 * dr, r3[n] + 0.5 * K3_1 * dr) K1_3 = f1(C, F, k, r2[n] + 0.5 * K2_2 * dr, r3[n] + 0.5 * K3_2 * dr) K2_3 = f2(rho, omega, k, r1[n] + 0.5 * K1_2 * dr, r4[n] + 0.5 * K4_2 * dr) K3_3 = f3(L, k, r1[n] + 0.5 * K1_2 * dr, r4[n] + 0.5 * K4_2 * dr) K4_3 = f4(rho, A, C, F, omega, k, r2[n] + 0.5 * K2_2 * dr, r3[n] + 0.5 * K3_2 * dr) rho, A, C, F, L, N = m.models(r[n] + dr, model) K1_4 = f1(C, F, k, r2[n] + K2_3 * dr, r3[n] + K3_3 * dr) K2_4 = f2(rho, omega, k, r1[n] + K1_3 * dr, r4[n] + K4_3 * dr) K3_4 = f3(L, k, r1[n] + K1_3 * dr, r4[n] + K4_3 * dr) K4_4 = f4(rho, A, C, F, omega, k, r2[n] + K2_3 * dr, r3[n] + K3_3 * dr) #- update r1[n + 1] = r1[n] + dr * (K1_1 + 2 * K1_2 + 2 * K1_3 + K1_4) / 6.0 r2[n + 1] = r2[n] + dr * (K2_1 + 2 * K2_2 + 2 * K2_3 + K2_4) / 6.0 r3[n + 1] = r3[n] + dr * (K3_1 + 2 * K3_2 + 2 * K3_3 + K3_4) / 6.0 r4[n + 1] = r4[n] + dr * (K4_1 + 2 * K4_2 + 2 * K4_3 + K4_4) / 6.0 #- rescale to maximum to prevent overflow if initial_condition == 1: mm = np.max(np.abs(r2)) else: mm = np.max(np.abs(r4)) r1 = r1 / mm r2 = r2 / mm r3 = r3 / mm r4 = r4 / mm #- return ------------------------------------------------------------------------------------- return r1, r2, r3, r4, r