Example #1
0
    def test_superimpose_two_subfaults(self):
        # Here we generate a slip surface with 2 subfaults, and check that
        # their result adds to the sum of the original 2. This uses values from
        # Okada's table 2.

        # Point at which we calculate output
        x = -3. # x = 2 in Okada's coordinates -- rotate anticlockwise by 90 deg for physical space
        y = 2.  # y = 3 in Okada's coordinates

        okada_values = [-2.747E-3, -3.564E-2] # Values of slip for strike, normal fault respectively

        # Compute functions for Okada's subfaults 2 and 3 (from table 2 in the paper)
        # Translate case 3 to origin 2,3. Then, we know the deformation at
        # (2,3) should be the sum of the values provided by Okada.
        for j in range(2,4):
            if(j==2):
                ##-------
                # Case 2:
                ##-------
                okada_x_origin=0.
                okada_y_origin=0
                d = 4.
                strike=0.
                dip = 70.
                L = 3.
                W = 2.
                slip=1.0
                rake=0.0
                # uz for [strike, normal] faults at x,y
            elif(j==3):
                ##-------
                # Case 3:
                ##-------
                okada_x_origin=x
                okada_y_origin=y
                d = 4.
                strike=0.
                dip = 90.
                L = 3.
                W = 2.
                slip=1.0
                rake=0.0

                # uz for [strike, normal] faults
                #okada_values = [0., 0.] # at x,y
            
            #Convert to the notation in tsunami_okada
            #d_cent = d - (W/2.)*numpy.sin(dip/180.*numpy.pi) # Centroid depth of fault plain
            #x_cent=(okada_x_origin+ L/2.)*1000. # Centroid x in m
            #y_cent=(okada_y_origin + (W/2.)*numpy.cos(dip/180.*numpy.pi))*1000. # Centroid y in m
            x_cent, y_cent, d_cent = okada_tsunami.okada_origin_2_slip_centroid([okada_x_origin*1000., okada_y_origin*1000.],\
                                                    d, L, W, strike, dip)
            
            x_wanted=x*1000. # Desired values of x, y in m
            y_wanted=y*1000.

            # Set up earthquakes, and check that the vertical deformation is the same as in okada
            dis1=slip*numpy.cos(rake/180.*numpy.pi)
            dis2=slip*numpy.sin(rake/180.*numpy.pi)
            dis3=0.
            # Set up the 'my_source' array, or append to it
            if(j==2):
                my_source=numpy.array([x_cent, y_cent, d_cent,strike, dip, L, W, dis1, dis2, dis3])
                my_source=my_source.reshape((1,10))
            elif(j==3):
                my_source2=numpy.array([x_cent, y_cent, d_cent,strike, dip, L, W, dis1, dis2, dis3]) 
                my_source2=my_source2.reshape((1,10))

                mysource=numpy.concatenate((my_source, my_source2))
            else:
                raise Exception, 'j is ' + str(j) + ', it should not take this value'
            
        # Tsunami function with     
        tsu_funct = okada_tsunami.earthquake_source(my_source, verbose=False)
        uz = tsu_funct(numpy.array([x_wanted]), numpy.array([y_wanted]))
      
        # Compute both relative and absolute versions of the error
        reltol = abs((uz - okada_values[0])/uz)
        abstol = abs(uz-okada_values[0])
        assert ((reltol<1.0e-03)|(abstol<1.0e-06))
Example #2
0
    def test_reproduce_okadas_table_rotated_and_offset(self):
        # This is like 'reproduce_okadas_table_rotated', except we also loop
        # over a range of earthquake origins and strikes. Hence, we check that
        # the translation/rotation is done correctly
        #
        # Actually this test subsumes the first two. However, it is useful to 
        # have separately, since separate tests will help isolate any problems

        # Define sets of origins for okada function (in physical space)
        okada_origins=numpy.array([[0., 0.], [1., 2.], [2., -1], [-3., -10.]])

        # Loop over all origins
        for k in range(okada_origins.shape[0]):
            okada_x_origin, okada_y_origin=okada_origins[k,:]
            # Loop over a range of rotations
            for rotation in [0., 30., 90., 150., 210., 325.]:
                # Loop over okada's test cases 2 and 3
                for j in range(2,4):
                    #print 'Testing Case ', j, ' Rotation = ', rotation, ' origin = ', [okada_x_origin, okada_y_origin]

                    if(j==2):
                        ##-------
                        # Case 2:
                        ##-------
                        #okada_x_origin=-1.
                        #okada_y_origin=10.
                        d = 4.
                        strike=rotation
                        dip = 70.
                        L = 3.
                        W = 2.
                        slip=1.0

                        # The desired x and y output location must be rotated too
                        x, y = okada_tsunami.rotate_coordinates([-3., 2.], -strike)
                        x = x+okada_x_origin
                        y = y+okada_y_origin

                        # uz for [strike, normal] faults
                        okada_values = [-2.747E-3, -3.564E-2]
                    elif(j==3):
                        ##-------
                        # Case 3:
                        ##-------
                        #okada_x_origin=0.
                        #okada_y_origin=0
                        d = 4.
                        strike=rotation
                        dip = 90.
                        L = 3.
                        W = 2.
                        slip=1.0
                        
                        x = 0. + okada_x_origin
                        y = 0. + okada_y_origin

                        # uz for [strike, normal] faults
                        okada_values = [0., 0.]
                     
                    # Compute new centroid coordinates
                    x_cent, y_cent, d_cent = okada_tsunami.okada_origin_2_slip_centroid([okada_x_origin*1000., okada_y_origin*1000.],\
                                                    d, L, W, strike, dip)
                    #print '##', x_cent, y_cent, d_cent
                    #assert 0==1

                    x_wanted, y_wanted =[x*1000., y*1000.]
                    

                    # Set up earthquakes, and check that the vertical deformation is the same as in okada
                    for i, rake in enumerate([0., 90.]):
                        dis1=slip*numpy.cos(rake/180.*numpy.pi)
                        dis2=slip*numpy.sin(rake/180.*numpy.pi)
                        dis3=0.
                        
                        my_source=numpy.array([x_cent, y_cent, d_cent,strike, dip, L, W, dis1, dis2, dis3])
                        my_source=my_source.reshape((1,10))
                        
                        tsu_funct = okada_tsunami.earthquake_source(my_source, verbose=False)
                        uz = tsu_funct(numpy.array([x_wanted]), numpy.array([y_wanted]))
                      
                        # Compute both relative and absolute versions of the error
                        reltol = abs((uz - okada_values[i])/uz)
                        abstol = abs(uz-okada_values[i])
                        assert ((reltol<1.0e-03)|(abstol<1.0e-06)), 'Okada_tsunami error for eq source: ' + str(my_source)
Example #3
0
    def test_reproduce_okadas_table(self):
        # Here we check that we can compute
        # the answers provided in Okada's Table 2
        # These refer to earthquakes with strike = 0 and origin 0,0
        for j in range(2,3):
            #print 'Testing Case ', j

            if(j==2):
                ##-------
                # Case 2:
                ##-------
                okada_x_origin=0.
                okada_y_origin=0
                # NOTE: In Okada's system, x = 2, y=3. However, 
                # this must be rotated backwards by 90 degrees
                # to convert to physical coordinates as used by
                # the routine. These physical coordinates correspond
                # to standard descriptions of earthquakes where
                # x,y = lon,lat
                x = -3. # =2 in okada's frame
                y = 2.  # =3 in okadas frame
                d = 4.
                strike=0.
                dip = 70.
                L = 3.
                W = 2.
                slip=1.0

                # uz for [strike, normal] faults
                okada_values = [-2.747E-3, -3.564E-2]
            elif(j==3):
                ##-------
                # Case 3:
                ##-------
                okada_x_origin=0.
                okada_y_origin=0
                x = 0.
                y = 0.
                d = 4.
                strike=0.
                dip = 90.
                L = 3.
                W = 2.
                slip=1.0

                # uz for [strike, normal] faults
                okada_values = [0., 0.]
           
            #import pdb
            #pdb.set_trace() 
            #Compute slip surface centroid
            x_cent, y_cent, d_cent = okada_tsunami.okada_origin_2_slip_centroid([okada_x_origin*1000., okada_y_origin*1000.],\
                                                    d, L, W, strike, dip)
            #y_cent = (okada_y_origin + (W/2.)*numpy.cos(dip/180.*numpy.pi))*1000.
            #x_cent = (okada_x_origin + (L/2.))*1000.
            #d_cent = d - (W/2.)*numpy.sin(dip/180.*numpy.pi)

            #print 'x_cent, y_cent, d_cent = ', x_cent, y_cent, d_cent
            
            x_wanted=x*1000. # Desired values of x, y in m
            y_wanted=y*1000.

            # Set up earthquakes, and check that the vertical deformation is the same as in okada
            for i, rake in enumerate([0., 90.]):
                dis1=slip*numpy.cos(rake/180.*numpy.pi)
                dis2=slip*numpy.sin(rake/180.*numpy.pi)
                dis3=0.
                #print 'dis1, dis2, dis3 = ', dis1, dis2, dis3
                
                my_source=numpy.array([x_cent, y_cent, d_cent,strike, dip, L, W, dis1, dis2, dis3])
                my_source=my_source.reshape((1,10))
                
                tsu_funct = okada_tsunami.earthquake_source(my_source, verbose=False)
                uz = tsu_funct(numpy.array([x_wanted]), numpy.array([y_wanted]))
              
                # Compute both relative and absolute versions of the error
                reltol = abs((uz - okada_values[i])/uz)
                abstol = abs(uz-okada_values[i])
                assert ((reltol<1.0e-03)|(abstol<1.0e-06))
Example #4
0
    def test_reproduce_okadas_table_rotated(self):
        # This test is like 'reproduce_okadas_table' except we rotate the
        # earthquake first -- thus checking that rotation is done correctly in
        # the code   

        # Loop over a range of rotations
        for rotation in [0., 30., 90., 150., 210., 325.]:
            # Test cases 2 - 3 in Okada's table
            for j in range(2,4):
                #print 'Testing Case ', j
                if(j==2):
                    ##-------
                    # Case 2: Parameters from table 2
                    ##-------
                    okada_x_origin=0.
                    okada_y_origin=0
                    d = 4.
                    strike=rotation
                    dip = 70.
                    L = 3.
                    W = 2.
                    slip=1.0

                    # The desired x and y output location must be rotated too
                    x, y = okada_tsunami.rotate_coordinates([-3., 2.], -strike)

                    # uz for [strike, normal] faults
                    okada_values = [-2.747E-3, -3.564E-2]
                elif(j==3):
                    ##-------
                    # Case 3: Parameters from table 2
                    ##-------
                    okada_x_origin=0.
                    okada_y_origin=0
                    x = 0.
                    y = 0.
                    d = 4.
                    strike=rotation
                    dip = 90.
                    L = 3.
                    W = 2.
                    slip=1.0

                    # uz for [strike, normal] faults
                    okada_values = [0., 0.]
                 
                #Convert to the notation in tsunami_okada
                x_cent, y_cent, d_cent = okada_tsunami.okada_origin_2_slip_centroid([okada_x_origin*1000., okada_y_origin*1000.],\
                                                    d, L, W, strike, dip)
                
                x_wanted, y_wanted =[x*1000., y*1000.]
                

                # Set up earthquakes, and check that the vertical deformation is the same as in okada
                for i, rake in enumerate([0., 90.]):
                    dis1=slip*numpy.cos(rake/180.*numpy.pi)
                    dis2=slip*numpy.sin(rake/180.*numpy.pi)
                    dis3=0.
                    
                    my_source=numpy.array([x_cent, y_cent, d_cent,strike, dip, L, W, dis1, dis2, dis3])
                    my_source=my_source.reshape((1,10))
                    
                    tsu_funct = okada_tsunami.earthquake_source(my_source, verbose=False)
                    uz = tsu_funct(numpy.array([x_wanted]), numpy.array([y_wanted]))
                  
                    # Compute both relative and absolute versions of the error
                    reltol = abs((uz - okada_values[i])/uz)
                    abstol = abs(uz-okada_values[i])
                    assert ((reltol<1.0e-03)|(abstol<1.0e-06))
    def test_superimpose_two_subfaults(self):
        # Here we generate a slip surface with 2 subfaults, and check that
        # their result adds to the sum of the original 2. This uses values from
        # Okada's table 2.

        # Point at which we calculate output
        x = -3.0  # x = 2 in Okada's coordinates -- rotate anticlockwise by 90 deg for physical space
        y = 2.0  # y = 3 in Okada's coordinates

        okada_values = [-2.747e-3, -3.564e-2]  # Values of slip for strike, normal fault respectively

        # Compute functions for Okada's subfaults 2 and 3 (from table 2 in the paper)
        # Translate case 3 to origin 2,3. Then, we know the deformation at
        # (2,3) should be the sum of the values provided by Okada.
        for j in range(2, 4):
            if j == 2:
                ##-------
                # Case 2:
                ##-------
                okada_x_origin = 0.0
                okada_y_origin = 0
                d = 4.0
                strike = 0.0
                dip = 70.0
                L = 3.0
                W = 2.0
                slip = 1.0
                rake = 0.0
                # uz for [strike, normal] faults at x,y
            elif j == 3:
                ##-------
                # Case 3:
                ##-------
                okada_x_origin = x
                okada_y_origin = y
                d = 4.0
                strike = 0.0
                dip = 90.0
                L = 3.0
                W = 2.0
                slip = 1.0
                rake = 0.0

                # uz for [strike, normal] faults
                # okada_values = [0., 0.] # at x,y

            # Convert to the notation in tsunami_okada
            # d_cent = d - (W/2.)*numpy.sin(dip/180.*numpy.pi) # Centroid depth of fault plain
            # x_cent=(okada_x_origin+ L/2.)*1000. # Centroid x in m
            # y_cent=(okada_y_origin + (W/2.)*numpy.cos(dip/180.*numpy.pi))*1000. # Centroid y in m
            x_cent, y_cent, d_cent = okada_tsunami.okada_origin_2_slip_centroid(
                [okada_x_origin * 1000.0, okada_y_origin * 1000.0], d, L, W, strike, dip
            )

            x_wanted = x * 1000.0  # Desired values of x, y in m
            y_wanted = y * 1000.0

            # Set up earthquakes, and check that the vertical deformation is the same as in okada
            dis1 = slip * numpy.cos(rake / 180.0 * numpy.pi)
            dis2 = slip * numpy.sin(rake / 180.0 * numpy.pi)
            dis3 = 0.0
            # Set up the 'my_source' array, or append to it
            if j == 2:
                my_source = numpy.array([x_cent, y_cent, d_cent, strike, dip, L, W, dis1, dis2, dis3])
                my_source = my_source.reshape((1, 10))
            elif j == 3:
                my_source2 = numpy.array([x_cent, y_cent, d_cent, strike, dip, L, W, dis1, dis2, dis3])
                my_source2 = my_source2.reshape((1, 10))

                mysource = numpy.concatenate((my_source, my_source2))
            else:
                raise Exception, "j is " + str(j) + ", it should not take this value"

        # Tsunami function with
        tsu_funct = okada_tsunami.earthquake_source(my_source, verbose=False)
        uz = tsu_funct(numpy.array([x_wanted]), numpy.array([y_wanted]))

        # Compute both relative and absolute versions of the error
        reltol = abs((uz - okada_values[0]) / uz)
        abstol = abs(uz - okada_values[0])
        assert (reltol < 1.0e-03) | (abstol < 1.0e-06)
    def test_reproduce_okadas_table(self):
        # Here we check that we can compute
        # the answers provided in Okada's Table 2
        # These refer to earthquakes with strike = 0 and origin 0,0
        for j in range(2, 3):
            # print 'Testing Case ', j

            if j == 2:
                ##-------
                # Case 2:
                ##-------
                okada_x_origin = 0.0
                okada_y_origin = 0
                # NOTE: In Okada's system, x = 2, y=3. However,
                # this must be rotated backwards by 90 degrees
                # to convert to physical coordinates as used by
                # the routine. These physical coordinates correspond
                # to standard descriptions of earthquakes where
                # x,y = lon,lat
                x = -3.0  # =2 in okada's frame
                y = 2.0  # =3 in okadas frame
                d = 4.0
                strike = 0.0
                dip = 70.0
                L = 3.0
                W = 2.0
                slip = 1.0

                # uz for [strike, normal] faults
                okada_values = [-2.747e-3, -3.564e-2]
            elif j == 3:
                ##-------
                # Case 3:
                ##-------
                okada_x_origin = 0.0
                okada_y_origin = 0
                x = 0.0
                y = 0.0
                d = 4.0
                strike = 0.0
                dip = 90.0
                L = 3.0
                W = 2.0
                slip = 1.0

                # uz for [strike, normal] faults
                okada_values = [0.0, 0.0]

            # import pdb
            # pdb.set_trace()
            # Compute slip surface centroid
            x_cent, y_cent, d_cent = okada_tsunami.okada_origin_2_slip_centroid(
                [okada_x_origin * 1000.0, okada_y_origin * 1000.0], d, L, W, strike, dip
            )
            # y_cent = (okada_y_origin + (W/2.)*numpy.cos(dip/180.*numpy.pi))*1000.
            # x_cent = (okada_x_origin + (L/2.))*1000.
            # d_cent = d - (W/2.)*numpy.sin(dip/180.*numpy.pi)

            # print 'x_cent, y_cent, d_cent = ', x_cent, y_cent, d_cent

            x_wanted = x * 1000.0  # Desired values of x, y in m
            y_wanted = y * 1000.0

            # Set up earthquakes, and check that the vertical deformation is the same as in okada
            for i, rake in enumerate([0.0, 90.0]):
                dis1 = slip * numpy.cos(rake / 180.0 * numpy.pi)
                dis2 = slip * numpy.sin(rake / 180.0 * numpy.pi)
                dis3 = 0.0
                # print 'dis1, dis2, dis3 = ', dis1, dis2, dis3

                my_source = numpy.array([x_cent, y_cent, d_cent, strike, dip, L, W, dis1, dis2, dis3])
                my_source = my_source.reshape((1, 10))

                tsu_funct = okada_tsunami.earthquake_source(my_source, verbose=False)
                uz = tsu_funct(numpy.array([x_wanted]), numpy.array([y_wanted]))

                # Compute both relative and absolute versions of the error
                reltol = abs((uz - okada_values[i]) / uz)
                abstol = abs(uz - okada_values[i])
                assert (reltol < 1.0e-03) | (abstol < 1.0e-06)
    def test_reproduce_okadas_table_rotated_and_offset(self):
        # This is like 'reproduce_okadas_table_rotated', except we also loop
        # over a range of earthquake origins and strikes. Hence, we check that
        # the translation/rotation is done correctly
        #
        # Actually this test subsumes the first two. However, it is useful to
        # have separately, since separate tests will help isolate any problems

        # Define sets of origins for okada function (in physical space)
        okada_origins = numpy.array([[0.0, 0.0], [1.0, 2.0], [2.0, -1], [-3.0, -10.0]])

        # Loop over all origins
        for k in range(okada_origins.shape[0]):
            okada_x_origin, okada_y_origin = okada_origins[k, :]
            # Loop over a range of rotations
            for rotation in [0.0, 30.0, 90.0, 150.0, 210.0, 325.0]:
                # Loop over okada's test cases 2 and 3
                for j in range(2, 4):
                    # print 'Testing Case ', j, ' Rotation = ', rotation, ' origin = ', [okada_x_origin, okada_y_origin]

                    if j == 2:
                        ##-------
                        # Case 2:
                        ##-------
                        # okada_x_origin=-1.
                        # okada_y_origin=10.
                        d = 4.0
                        strike = rotation
                        dip = 70.0
                        L = 3.0
                        W = 2.0
                        slip = 1.0

                        # The desired x and y output location must be rotated too
                        x, y = okada_tsunami.rotate_coordinates([-3.0, 2.0], -strike)
                        x = x + okada_x_origin
                        y = y + okada_y_origin

                        # uz for [strike, normal] faults
                        okada_values = [-2.747e-3, -3.564e-2]
                    elif j == 3:
                        ##-------
                        # Case 3:
                        ##-------
                        # okada_x_origin=0.
                        # okada_y_origin=0
                        d = 4.0
                        strike = rotation
                        dip = 90.0
                        L = 3.0
                        W = 2.0
                        slip = 1.0

                        x = 0.0 + okada_x_origin
                        y = 0.0 + okada_y_origin

                        # uz for [strike, normal] faults
                        okada_values = [0.0, 0.0]

                    # Compute new centroid coordinates
                    x_cent, y_cent, d_cent = okada_tsunami.okada_origin_2_slip_centroid(
                        [okada_x_origin * 1000.0, okada_y_origin * 1000.0], d, L, W, strike, dip
                    )
                    # print '##', x_cent, y_cent, d_cent
                    # assert 0==1

                    x_wanted, y_wanted = [x * 1000.0, y * 1000.0]

                    # Set up earthquakes, and check that the vertical deformation is the same as in okada
                    for i, rake in enumerate([0.0, 90.0]):
                        dis1 = slip * numpy.cos(rake / 180.0 * numpy.pi)
                        dis2 = slip * numpy.sin(rake / 180.0 * numpy.pi)
                        dis3 = 0.0

                        my_source = numpy.array([x_cent, y_cent, d_cent, strike, dip, L, W, dis1, dis2, dis3])
                        my_source = my_source.reshape((1, 10))

                        tsu_funct = okada_tsunami.earthquake_source(my_source, verbose=False)
                        uz = tsu_funct(numpy.array([x_wanted]), numpy.array([y_wanted]))

                        # Compute both relative and absolute versions of the error
                        reltol = abs((uz - okada_values[i]) / uz)
                        abstol = abs(uz - okada_values[i])
                        assert (reltol < 1.0e-03) | (abstol < 1.0e-06), "Okada_tsunami error for eq source: " + str(
                            my_source
                        )
    def test_reproduce_okadas_table_rotated(self):
        # This test is like 'reproduce_okadas_table' except we rotate the
        # earthquake first -- thus checking that rotation is done correctly in
        # the code

        # Loop over a range of rotations
        for rotation in [0.0, 30.0, 90.0, 150.0, 210.0, 325.0]:
            # Test cases 2 - 3 in Okada's table
            for j in range(2, 4):
                # print 'Testing Case ', j
                if j == 2:
                    ##-------
                    # Case 2: Parameters from table 2
                    ##-------
                    okada_x_origin = 0.0
                    okada_y_origin = 0
                    d = 4.0
                    strike = rotation
                    dip = 70.0
                    L = 3.0
                    W = 2.0
                    slip = 1.0

                    # The desired x and y output location must be rotated too
                    x, y = okada_tsunami.rotate_coordinates([-3.0, 2.0], -strike)

                    # uz for [strike, normal] faults
                    okada_values = [-2.747e-3, -3.564e-2]
                elif j == 3:
                    ##-------
                    # Case 3: Parameters from table 2
                    ##-------
                    okada_x_origin = 0.0
                    okada_y_origin = 0
                    x = 0.0
                    y = 0.0
                    d = 4.0
                    strike = rotation
                    dip = 90.0
                    L = 3.0
                    W = 2.0
                    slip = 1.0

                    # uz for [strike, normal] faults
                    okada_values = [0.0, 0.0]

                # Convert to the notation in tsunami_okada
                x_cent, y_cent, d_cent = okada_tsunami.okada_origin_2_slip_centroid(
                    [okada_x_origin * 1000.0, okada_y_origin * 1000.0], d, L, W, strike, dip
                )

                x_wanted, y_wanted = [x * 1000.0, y * 1000.0]

                # Set up earthquakes, and check that the vertical deformation is the same as in okada
                for i, rake in enumerate([0.0, 90.0]):
                    dis1 = slip * numpy.cos(rake / 180.0 * numpy.pi)
                    dis2 = slip * numpy.sin(rake / 180.0 * numpy.pi)
                    dis3 = 0.0

                    my_source = numpy.array([x_cent, y_cent, d_cent, strike, dip, L, W, dis1, dis2, dis3])
                    my_source = my_source.reshape((1, 10))

                    tsu_funct = okada_tsunami.earthquake_source(my_source, verbose=False)
                    uz = tsu_funct(numpy.array([x_wanted]), numpy.array([y_wanted]))

                    # Compute both relative and absolute versions of the error
                    reltol = abs((uz - okada_values[i]) / uz)
                    abstol = abs(uz - okada_values[i])
                    assert (reltol < 1.0e-03) | (abstol < 1.0e-06)