示例#1
0
def test_tesseroid_vs_spherical_shell():
    "gravmag.tesseroid equal analytical solution of spherical shell to 0.1%"
    density = 1000.
    top = 1000
    bottom = 0
    model = TesseroidMesh((0, 360, -90, 90, top, bottom), (1, 6, 12))
    model.addprop('density', density*np.ones(model.size))
    h = 10000
    lon, lat, height = gridder.regular((0, model.dims[0], 0, model.dims[1]),
                                       (10, 10), z=h)
    funcs = ['potential', 'gx', 'gy', 'gz', 'gxx', 'gxy', 'gxz', 'gyy', 'gyz',
             'gzz']
    shellvalues = calc_shell_effect(h, top, bottom, density)
    for f in funcs:
        shell = shellvalues[f]
        tess = getattr(tesseroid, f)(lon, lat, height, model)
        diff = np.abs(shell - tess)
        # gz gy and the off-diagonal gradients should be zero so I can't
        # calculate a relative error (in %).
        # To do that, I'll use the gz and gzz shell values to calculate the
        # percentage.
        if f in 'gx gy'.split():
            shell = shellvalues['gz']
        elif f in 'gxy gxz gyz'.split():
            shell = shellvalues['gzz']
        diff = 100*diff/np.abs(shell)
        assert diff.max() < 0.1, "diff > 0.1% for {}: {}".format(
            f, diff.max())
示例#2
0
def test_tesseroid_vs_spherical_shell():
    "gravmag.tesseroid equal analytical solution of spherical shell to 0.1%"
    density = 1000.
    top = 1000
    bottom = 0
    model = TesseroidMesh((0, 360, -90, 90, top, bottom), (1, 6, 12))
    model.addprop('density', density * np.ones(model.size))
    h = 10000
    lon, lat, height = gridder.regular((0, model.dims[0], 0, model.dims[1]),
                                       (10, 10),
                                       z=h)
    funcs = [
        'potential', 'gx', 'gy', 'gz', 'gxx', 'gxy', 'gxz', 'gyy', 'gyz', 'gzz'
    ]
    shellvalues = calc_shell_effect(h, top, bottom, density)
    for f in funcs:
        shell = shellvalues[f]
        tess = getattr(tesseroid, f)(lon, lat, height, model)
        diff = np.abs(shell - tess)
        # gz gy and the off-diagonal gradients should be zero so I can't
        # calculate a relative error (in %).
        # To do that, I'll use the gz and gzz shell values to calculate the
        # percentage.
        if f in 'gx gy'.split():
            shell = shellvalues['gz']
        elif f in 'gxy gxz gyz'.split():
            shell = shellvalues['gzz']
        diff = 100 * diff / np.abs(shell)
        assert diff.max() < 0.1, "diff > 0.1% for {}: {}".format(f, diff.max())
示例#3
0
def test_numba_vs_python():
    "gravmag.tesseroid numba and pure python implementations give same result"
    model = TesseroidMesh((0, 1, 0, 2, 1000, 0), (2, 2, 1))
    model.addprop('density', -200*np.ones(model.size))
    lon, lat, height = gridder.regular((0, 1, 0, 2), (20, 20), z=250e3)
    for f in 'potential gx gy gz gxx gxy gxz gyy gyz gzz'.split():
        func = getattr(tesseroid, f)
        py = func(lon, lat, height, model, engine='numpy')
        nb = func(lon, lat, height, model, engine='numba')
        assert_allclose(nb, py, err_msg="Mismatch for {}".format(f))
示例#4
0
def test_numba_vs_python():
    "gravmag.tesseroid numba and pure python implementations give same result"
    model = TesseroidMesh((0, 1, 0, 2, 1000, 0), (2, 2, 1))
    model.addprop('density', -200 * np.ones(model.size))
    lon, lat, height = gridder.regular((0, 1, 0, 2), (20, 20), z=250e3)
    for f in 'potential gx gy gz gxx gxy gxz gyy gyz gzz'.split():
        func = getattr(tesseroid, f)
        py = func(lon, lat, height, model, engine='numpy')
        nb = func(lon, lat, height, model, engine='numba')
        assert_allclose(nb, py, err_msg="Mismatch for {}".format(f))
示例#5
0
def test_serial_vs_parallel():
    "gravmag.tesseroid serial and parallel execution give same result"
    model = TesseroidMesh((-1, 1.5, -2, 2, 0, -10e3), (3, 2, 1))
    model.addprop('density', 500*np.ones(model.size))
    lon, lat, height = gridder.regular((-1, 1.5, -2, 2), (15, 21), z=150e3)
    njobs = 3
    for f in 'potential gx gy gz gxx gxy gxz gyy gyz gzz'.split():
        func = getattr(tesseroid, f)
        serial = func(lon, lat, height, model, njobs=1)
        parallel = func(lon, lat, height, model, njobs=njobs)
        assert_allclose(serial, parallel, err_msg="Mismatch for {}".format(f))
def test_thick_shell():
    def density_linear(height):
        r = height + MEAN_EARTH_RADIUS
        return a * r + b

    # Spherical shell model with a Tesseroid Mesh
    top, bottom = 0, -35000
    density_1, density_2 = 2670, 3300
    a = -(density_2 - density_1) / abs(bottom)
    b = (density_2 - density_1) / abs(bottom) * MEAN_EARTH_RADIUS + 2670
    model = TesseroidMesh((0, 360, -90, 90, top, bottom), (1, 6, 12))
    model.addprop("density", [density_linear for i in range(model.size)])

    # Computation grids
    shape = (10, 10)
    grids = {
        "pole": gridder.regular((89, 90, 0, 1), shape, z=2e3),
        "equator": gridder.regular((0, 1, 0, 1), shape, z=2e3),
        "260km": gridder.regular((89, 90, 0, 1), shape, z=260e3),
        "30deg": gridder.regular((60, 90, 0, 30), shape, z=2e3)
    }
    fields = 'potential gx gy gz gxx gxy gxz gyy gyz gzz'.split()
    for field in fields:
        for grid in grids.keys():
            msg = "Failed linear density test for thick shell while \
                   computing {} on {} grid".format(field, grid)
            lats, lons, heights = grids[grid]
            analytical = shell_linear_density(heights[0], top, bottom, a, b)
            result = getattr(tesseroid, field)(lons, lats, heights, model)
            diff = np.abs(result - analytical[field])
            # gz gy and the off-diagonal gradients should be zero so I can't
            # calculate a relative error (in %).
            # To do that, I'll use the gz and gzz shell values to calculate the
            # percentage.
            if field in 'potential gz gxx gyy gzz'.split():
                diff /= np.abs(analytical[field])
            elif field in 'gx gy'.split():
                diff /= np.abs(analytical['gz'])
            elif field in "gxy gxz gyz".split():
                diff /= np.abs(analytical['gzz'])
            diff = 100 * np.max(diff)
            assert diff < 1e-1, msg
def test_thick_shell():
    def density_exponential(height):
        r = height + MEAN_EARTH_RADIUS
        return a * np.exp(-(r - deltah) / b) + c

    # Spherical shell model with a Tesseroid Mesh
    top, bottom = 0, -35000
    density_1, density_2 = 2670, 3300
    b = 850.
    a = (density_2 - density_1) / (np.exp((abs(top - bottom)) / b) - 1)
    c = density_1 - a
    deltah = MEAN_EARTH_RADIUS
    model = TesseroidMesh((0, 360, -90, 90, top, bottom), (1, 6, 12))
    model.addprop("density", [density_exponential for i in range(model.size)])

    # Computation grids
    shape = (10, 10)
    grid = gridder.regular((60, 90, 0, 30), shape, z=2e3)
    fields = 'potential gx gy gz gxx gxy gxz gyy gyz gzz'.split()
    for field in fields:
        msg = "Failed linear density test for thin shell while \
               computing {} on {} grid".format(field, grid)
        lats, lons, heights = grid[:]
        analytical = shell_exponential_density(heights[0], top, bottom, a, b,
                                               c, deltah)
        result = getattr(tesseroid, field)(lons, lats, heights, model)
        diff = np.abs(result - analytical[field])
        # gz gy and the off-diagonal gradients should be zero so I can't
        # calculate a relative error (in %).
        # To do that, I'll use the gz and gzz shell values to calculate the
        # percentage.
        if field in 'potential gz gxx gyy gzz'.split():
            diff /= np.abs(analytical[field])
        elif field in 'gx gy'.split():
            diff /= np.abs(analytical['gz'])
        elif field in "gxy gxz gyz".split():
            diff /= np.abs(analytical['gzz'])
        diff = 100 * np.max(diff)
        assert diff < 1e-1, msg
    return data


# Create results dir if it does not exist
# ---------------------------------------
script_path = os.path.dirname(os.path.abspath(__file__))
result_dir = os.path.join(script_path, 'results/sine')
if not os.path.isdir(result_dir):
    os.makedirs(result_dir)

# Define Tesseroids models
# ------------------------
thicknesses = [100, 1e3, 1e4, 1e5, 1e6]
shape = (1, 6, 12)
models = [
    TesseroidMesh((0, 360, -90, 90, 0, -thickness), shape)
    for thickness in thicknesses
]

# Define computation grids
# ------------------------
grids = {
    "pole": gridder.regular((89, 90, 0, 1), (11, 11), z=0),
    "equator": gridder.regular((0, 1, 0, 1), (11, 11), z=0),
    "global": gridder.regular((-90, 90, 0, 360), (19, 13), z=0),
    "260km": gridder.regular((-90, 90, 0, 360), (19, 13), z=260e3),
}

# Configure comparisons
# ---------------------
fields = 'potential gz'.split()