Example #1
0
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
Example #2
0
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
Example #3
0
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
Example #4
0
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
Example #5
0
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
Example #6
0
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
Example #7
0
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