Example #1
0
def test_success():
    # should fail because z is positive
    success, u, grad_u = dc3d0wrapper(1.0, [0.0, 0.0, 1.0], 1.0, 90,
                                      [1.0, 0.0, 0.0, 0.0])
    assert (success == 2)

    success, u, grad_u = dc3dwrapper(1.0, [0.0, 0.0, 1.0], 0.0, 90,
                                     [-0.7, 0.7], [-0.7, 0.7], [1.0, 0.0, 0.0])
    assert (success == 2)
Example #2
0
def test_success():
    # should fail because z is positive
    success, u, grad_u = dc3d0wrapper(1.0, [0.0, 0.0, 1.0],
                                       1.0, 90,
                                       [1.0, 0.0, 0.0, 0.0]);
    assert(success == 2)

    success, u, grad_u = dc3dwrapper(1.0, [0.0, 0.0, 1.0],
                                   0.0, 90, [-0.7, 0.7], [-0.7, 0.7],
                                   [1.0, 0.0, 0.0])
    assert(success == 2)
Example #3
0
def compute_surface_disp_point(params, inputs, x, y):
    # A major compute loop for each source object at an x/y point.
    # x/y in the same coordinate system as the fault object.
    u_disp = 0
    v_disp = 0
    w_disp = 0
    for fault in inputs.source_object:

        # Fault parameters
        L = conversion_math.get_strike_length(fault.xstart, fault.xfinish,
                                              fault.ystart, fault.yfinish)
        W = conversion_math.get_downdip_width(fault.top, fault.bottom,
                                              fault.dipangle)
        depth = fault.top
        dip = fault.dipangle
        strike_slip = fault.rtlat * -1
        # The dc3d coordinate system has left-lateral positive.
        dip_slip = fault.reverse

        # Preparing to rotate to a fault-oriented coordinate system.
        theta = fault.strike - 90
        theta = np.deg2rad(theta)
        R = np.array([[np.cos(theta), -np.sin(theta)],
                      [np.sin(theta), np.cos(theta)]])
        R2 = np.array([[np.cos(-theta), -np.sin(-theta)],
                       [np.sin(-theta), np.cos(-theta)]])

        # Compute the position relative to the translated, rotated fault.
        translated_pos = np.array([[x - fault.xstart], [y - fault.ystart]])
        xy = R.dot(translated_pos)
        # Solve for displacements at the surface
        if fault.potency != []:
            success, u, grad_u = dc3d0wrapper(
                params.alpha, [xy[0], xy[1], 0.0], depth, dip, [
                    fault.potency[0], fault.potency[1], fault.potency[2],
                    fault.potency[3]
                ])
            u = u * 1e-6
            # Unit correction: potency from N-m results in displacements in microns.
        else:
            success, u, grad_u = dc3dwrapper(params.alpha, [xy[0], xy[1], 0.0],
                                             depth, dip, [0, L], [-W, 0],
                                             [strike_slip, dip_slip, 0.0])
        urot = R2.dot(np.array([[u[0]], [u[1]]]))

        # Update the displacements from all sources
        u_disp = u_disp + urot[0]
        v_disp = v_disp + urot[1]
        w_disp = w_disp + u[2]
        # vertical

    return u_disp, v_disp, w_disp
Example #4
0
def compute_strains_stresses_from_one_fault(source, x, y, z, alpha):
    """
    The main math of DC3D
    Operates on a source object (e.g., fault),
    and an xyz position in the same cartesian reference frame.
    """
    L = fault_vector_functions.get_strike_length(source.xstart, source.xfinish,
                                                 source.ystart, source.yfinish)
    W = fault_vector_functions.get_downdip_width(source.top, source.bottom,
                                                 source.dipangle)
    depth = source.top
    dip = source.dipangle
    strike_slip = source.rtlat * -1
    # The dc3d coordinate system has left-lateral positive.
    dip_slip = source.reverse

    # Preparing to rotate to a fault-oriented coordinate system.
    theta = source.strike - 90
    theta = np.deg2rad(theta)
    R = np.array([[np.cos(theta), -np.sin(theta), 0],
                  [np.sin(theta), np.cos(theta), 0], [0, 0, 1]])
    # horizontal rotation into strike-aligned coordinates.
    R2 = np.array([[np.cos(-theta), -np.sin(-theta), 0],
                   [np.sin(-theta), np.cos(-theta), 0], [0, 0, 1]])

    # Compute the position relative to the translated, rotated fault.
    translated_pos = np.array([[x - source.xstart], [y - source.ystart], [-z]])
    xyz = R.dot(translated_pos)
    if source.potency:
        success, u, grad_u = dc3d0wrapper(
            alpha, [xyz[0], xyz[1], xyz[2]], depth, dip, [
                source.potency[0], source.potency[1], source.potency[2],
                source.potency[3]
            ])
        grad_u = grad_u * 1e-9
        # DC3D0 Unit correction: potency from N-m results in strain in nanostrain
        u = u * 1e-6
        # Unit correction: potency from N-m results in displacements in microns.
    else:
        success, u, grad_u = dc3dwrapper(
            alpha, [xyz[0], xyz[1], xyz[2]], depth, dip, [0, L], [-W, 0],
            [strike_slip, dip_slip, source.tensile])
        grad_u = grad_u * 1e-3
        # DC3D Unit correction.
    # Solve for displacement gradients at certain xyz position

    # Rotate grad_u back into the unprimed coordinates.
    desired_coords_grad_u = np.dot(R2, np.dot(grad_u, R2.T))
    desired_coords_u = R2.dot(np.array([[u[0]], [u[1]], [u[2]]]))

    return desired_coords_grad_u, desired_coords_u
Example #5
0
def test_dc3d0():
    source_depth, obs_depth, poisson_ratio, mu, dip, alpha = get_params()
    n = (100, 100)
    x = linspace(-1, 1, n[0])
    y = linspace(-1, 1, n[1])
    ux = zeros((n[0], n[1]))
    for i in range(100):
        for j in range(100):
            success, u, grad_u = dc3d0wrapper(alpha, [x[i], y[j], -obs_depth],
                                              source_depth, dip,
                                              [1.0, 0.0, 0.0, 0.0])
            assert (success == 0)
            ux[i, j] = u[0]

    cntrf = contourf(x, y, log(abs(ux.T)))
    contour(x, y, log(abs(ux.T)), colors='k', linestyles='solid')
    xlabel('x')
    ylabel('y')
    cbar = colorbar(cntrf)
    cbar.set_label('$\log(u_{\\textrm{x}})$')
    show()
Example #6
0
def test_dc3d0():
    source_depth, obs_depth, poisson_ratio, mu, dip, alpha = get_params()
    n = (100, 100)
    x = linspace(-1, 1, n[0])
    y = linspace(-1, 1, n[1])
    ux = zeros((n[0], n[1]))
    for i in range(100):
        for j in range(100):
            success, u, grad_u = dc3d0wrapper(alpha,
                                               [x[i], y[j], -obs_depth],
                                               source_depth, dip,
                                               [1.0, 0.0, 0.0, 0.0]);
            assert(success == 0)
            ux[i, j] = u[0]

    cntrf = contourf(x, y, log(abs(ux.T)))
    contour(x, y, log(abs(ux.T)), colors = 'k', linestyles = 'solid')
    xlabel('x')
    ylabel('y')
    cbar = colorbar(cntrf)
    cbar.set_label('$\log(u_{\\textrm{x}})$')
    show()
Example #7
0
def compute_strains_stresses(params, inputs):

    # Pseudocode:
    # For each receiver, at the center point, sum up the strain and stress for each source.
    # Return : source object, receiver object, shear stress, normal stress, and coulomb stress on each receiver.

    # The values we're actually going to output.
    receiver_shear = []
    receiver_normal = []
    receiver_coulomb = []

    for receiver in inputs.receiver_object:
        centercoords = conversion_math.get_fault_center(receiver)
        normal_sum = 0
        shear_sum = 0
        coulomb_sum = 0

        for source in inputs.source_object:
            # A major compute loop for each source object.

            L = conversion_math.get_strike_length(source.xstart,
                                                  source.xfinish,
                                                  source.ystart,
                                                  source.yfinish)
            W = conversion_math.get_downdip_width(source.top, source.bottom,
                                                  source.dipangle)
            depth = source.top
            dip = source.dipangle
            strike_slip = source.rtlat * -1
            # The dc3d coordinate system has left-lateral positive.
            dip_slip = source.reverse

            # Preparing to rotate to a fault-oriented coordinate system.
            theta = source.strike - 90
            theta = np.deg2rad(theta)
            R = np.array([[np.cos(theta), -np.sin(theta), 0],
                          [np.sin(theta), np.cos(theta), 0], [0, 0, 1]])
            # horizontal rotation into strike-aligned coordinates.
            R2 = np.array([[np.cos(-theta), -np.sin(-theta), 0],
                           [np.sin(-theta), np.cos(-theta), 0], [0, 0, 1]])

            # Compute the position relative to the translated, rotated fault.
            translated_pos = np.array([[centercoords[0] - source.xstart],
                                       [centercoords[1] - source.ystart],
                                       [-centercoords[2]]])
            xyz = R.dot(translated_pos)
            if source.potency != []:
                success, u, grad_u = dc3d0wrapper(
                    params.alpha, [xyz[0], xyz[1], xyz[2]], depth, dip, [
                        source.potency[0], source.potency[1],
                        source.potency[2], source.potency[3]
                    ])
                grad_u = grad_u * 1e-9
                # DC3D0 Unit correction: potency from N-m results in displacements in nanostrain
            else:
                success, u, grad_u = dc3dwrapper(params.alpha,
                                                 [xyz[0], xyz[1], xyz[2]],
                                                 depth, dip, [0, L], [-W, 0],
                                                 [strike_slip, dip_slip, 0.0])
                grad_u = grad_u * 1e-3
                # DC3D Unit correction.
            # Solve for displacement gradients at center of receiver fault

            # Rotate grad_u back into the unprimed coordinates.  Divide by 1000 because coordinate units (km) and slip units (m) are different by 1000.
            desired_coords_grad_u = np.dot(R2, np.dot(grad_u, R2.T))

            # Then rotate again into receiver coordinates.
            strain_tensor = conversion_math.get_strain_tensor(
                desired_coords_grad_u)
            stress_tensor = conversion_math.get_stress_tensor(
                strain_tensor, params.lame1, params.mu)

            # Then compute shear, normal, and coulomb stresses.
            [normal, shear, coulomb] = conversion_math.get_coulomb_stresses(
                stress_tensor, receiver.strike, receiver.rake,
                receiver.dipangle, inputs.FRIC)
            normal_sum = normal_sum + normal
            shear_sum = shear_sum + shear
            coulomb_sum = coulomb_sum + coulomb

        receiver_normal.append(normal_sum)
        receiver_shear.append(shear_sum)
        receiver_coulomb.append(coulomb_sum)

        # return lists of normal, shear, coulomb values for each receiver.
    return [receiver_normal, receiver_shear, receiver_coulomb]