Exemplo n.º 1
0
def test_correct_at_value2D():
    comm = spyro.utils.mpi_init(model)
    model["opts"]["degree"] = 3
    mesh, V = spyro.io.read_mesh(model, comm)
    pz = -0.1
    px = 0.3
    recvs = spyro.create_transect((pz, px), (pz, px), 3)
    # recvs = spyro.create_transect(
    #    (-0.00935421,  3.25160664), (-0.00935421,  3.25160664), 3
    # )
    model["acquisition"]["receiver_locations"] = recvs
    model["acquisition"]["num_receivers"] = 3

    receivers = spyro.Receivers(model, mesh, V, comm)
    V = receivers.space
    z, x = SpatialCoordinate(mesh)

    u1 = Function(V).interpolate(x + z)
    test1 = math.isclose((pz + px),
                         receivers._Receivers__new_at(u1.dat.data[:], 0),
                         rel_tol=1e-09)

    u1 = Function(V).interpolate(sin(x) * z * 2)
    test2 = math.isclose(
        sin(px) * pz * 2,
        receivers._Receivers__new_at(u1.dat.data[:], 0),
        rel_tol=1e-05,
    )

    assert all([test1, test2])
Exemplo n.º 2
0
def test_correct_at_value3D():
    test_model2 = deepcopy(model3D)
    test_model2["acquisition"]["num_receivers"] = 3
    test_model2["opts"]["degree"] = 3
    comm = spyro.utils.mpi_init(test_model2)
    mesh, V = spyro.io.read_mesh(test_model2, comm)
    x_start = 0.09153949331982138
    x_end = 0.09153949331982138
    z_start = 0.0
    z_end = 0.0
    y_start = 0.47342699605572036
    y_end = 0.47342699605572036

    x_real, y_real, z_real = x_start, y_start, z_start

    recvs = spyro.create_transect((z_start, x_start, y_start),
                                  (z_end, x_end, y_end), 3)
    test_model2["acquisition"]["receiver_locations"] = recvs
    receivers = spyro.Receivers(test_model2, mesh, V, comm)
    V = receivers.space
    z, x, y = SpatialCoordinate(mesh)

    u1 = Function(V).interpolate(x + z + y)
    realvalue = x_real + y_real + z_real
    test1 = math.isclose(realvalue,
                         receivers._Receivers__new_at(u1.dat.data[:], 0),
                         rel_tol=1e-09)

    u1 = Function(V).interpolate(sin(x) * (z + 1)**2 * cos(y))
    realvalue = sin(x_real) * (z_real + 1)**2 * cos(y_real)
    test2 = math.isclose(realvalue,
                         receivers._Receivers__new_at(u1.dat.data[:], 0),
                         rel_tol=1e-05)

    assert all([test1, test2])
Exemplo n.º 3
0
def test_parallel_source():

    comm = spyro.utils.mpi_init(options)

    mesh, V = spyro.io.read_mesh(options, comm)

    vp = Function(V).assign(1.0)

    sources = spyro.Sources(options, mesh, V, comm)

    receivers = spyro.Receivers(options, mesh, V, comm)

    wavelet = spyro.full_ricker_wavelet(
        options["timeaxis"]["dt"],
        options["timeaxis"]["tf"],
        options["acquisition"]["frequency"],
    )

    f, r = forward(
        options,
        mesh,
        comm,
        vp,
        sources,
        wavelet,
        receivers,
    )

    #print(np.amax(np.abs(r)))
    #spyro.io.save_shots('serial_shot.dat', r)
    r_s = spyro.io.load_shots(os.getcwd() + '/test/serial_shot.dat')
    assert np.amax(np.abs(r - r_s)) < 1e-16
Exemplo n.º 4
0
def run_solve(timestep_method, method, model, mesh, expr):
    testmodel = deepcopy(model)
    if method == "KMV":
        variant = "KMV"
        testmodel["opts"]["quadrature"] = "KMV"
    else:
        variant = "equispaced"

    comm = spyro.utils.mpi_init(testmodel)

    element = FiniteElement(method, mesh.ufl_cell(), degree=1, variant=variant)
    V = FunctionSpace(mesh, element)

    excitation = spyro.Sources(testmodel, mesh, V, comm)

    wavelet = spyro.full_ricker_wavelet(dt=0.001, tf=1.0, freq=2.0)

    receivers = spyro.Receivers(testmodel, mesh, V, comm)

    if timestep_method == "central":
        p, _ = spyro.solvers.forward(testmodel, mesh, comm, Constant(1.0),
                                     excitation, wavelet, receivers)
    elif timestep_method == "ssprk":
        p, _ = spyro.solvers.SSPRK3(testmodel, mesh, comm, Constant(1.0),
                                    excitation, receivers)
    expr = expr(*SpatialCoordinate(mesh))
    return errornorm(interpolate(expr, V), p[-1])
Exemplo n.º 5
0
def wave_solver(model, mesh, comm, output=False):
    method = model["opts"]["method"]
    degree = model['opts']['degree']

    element = fire.FiniteElement(method,
                                 mesh.ufl_cell(),
                                 degree=degree,
                                 variant="KMV")
    V = fire.FunctionSpace(mesh, element)
    vp = fire.Constant(1.429)

    if comm.ensemble_comm.rank == 0 and comm.comm.rank == 0:
        print("Finding sources and receivers", flush=True)
    sources = spyro.Sources(model, mesh, V, comm)
    receivers = spyro.Receivers(model, mesh, V, comm)

    if comm.ensemble_comm.rank == 0 and comm.comm.rank == 0:
        print("Starting simulation", flush=True)

    wavelet = spyro.full_ricker_wavelet(
        dt=model["timeaxis"]["dt"],
        tf=model["timeaxis"]["tf"],
        freq=model["acquisition"]["frequency"],
    )
    p, p_r = spyro.solvers.forward(model,
                                   mesh,
                                   comm,
                                   vp,
                                   sources,
                                   wavelet,
                                   receivers,
                                   output=output)
    return p_r
Exemplo n.º 6
0
def wave_solver(model, G, comm=False):
    minimum_mesh_velocity = model['testing_parameters'][
        'minimum_mesh_velocity']
    model["mesh"]["meshfile"] = "meshes/2Dhomogeneous" + str(G) + ".msh"
    try:
        mesh, V = spyro.io.read_mesh(model, comm)
    except:
        model = generate_mesh(model, G, comm)
        mesh, V = spyro.io.read_mesh(model, comm)

    if model['testing_parameters']['experiment_type'] == 'homogeneous':
        vp_exact = fire.Constant(minimum_mesh_velocity)
    elif model['testing_parameters']['experiment_type'] == 'heterogeneous':
        vp_exact = spyro.io.interpolate(model, mesh, V, guess=False)

    if model["opts"]["method"] == 'KMV':
        estimate_max_eigenvalue = True
    else:
        estimate_max_eigenvalue = False
    new_dt = 0.2 * spyro.estimate_timestep(
        mesh, V, vp_exact, estimate_max_eigenvalue=estimate_max_eigenvalue)

    model['timeaxis']['dt'] = comm.comm.allreduce(new_dt, op=MPI.MIN)
    if comm.comm.rank == 0:
        print(
            f"Maximum stable timestep is: {model['timeaxis']['dt']} seconds",
            flush=True,
        )
    if model['timeaxis']['dt'] > 0.001:
        model['timeaxis']['dt'] = 0.001
    if comm.comm.rank == 0:
        print(
            f"Timestep used is: {model['timeaxis']['dt']} seconds",
            flush=True,
        )

    sources = spyro.Sources(model, mesh, V, comm)
    receivers = spyro.Receivers(model, mesh, V, comm)
    wavelet = spyro.full_ricker_wavelet(
        dt=model["timeaxis"]["dt"],
        tf=model["timeaxis"]["tf"],
        freq=model["acquisition"]["frequency"],
    )

    for sn in range(model["acquisition"]["num_sources"]):
        if spyro.io.is_owner(comm, sn):
            t1 = time.time()
            p_field, p_recv = spyro.solvers.forward(model,
                                                    mesh,
                                                    comm,
                                                    vp_exact,
                                                    sources,
                                                    wavelet,
                                                    receivers,
                                                    source_num=sn,
                                                    output=False)
            print(time.time() - t1)

    return p_recv
Exemplo n.º 7
0
def test_correct_receiver_to_cell_location2D():
    """Tests if the receivers where located in the correct cell"""
    comm = spyro.utils.mpi_init(model)
    model["opts"]["degree"] = 3
    mesh, V = spyro.io.read_mesh(model, comm)

    model["acquisition"]["num_receivers"] = 3
    recvs = spyro.create_transect((-0.1, 0.3), (-0.1, 0.9), 3)
    recvs = model["acquisition"]["receiver_locations"] = recvs

    receivers = spyro.Receivers(model, mesh, V, comm)

    # test 1
    cell_vertex1 = receivers.cellVertices[0][0]
    cell_vertex2 = receivers.cellVertices[0][1]
    cell_vertex3 = receivers.cellVertices[0][2]
    x = receivers.receiver_locations[0, 0]
    y = receivers.receiver_locations[0, 1]
    p = (x, y)

    areaT = triangle_area(cell_vertex1, cell_vertex2, cell_vertex3)
    area1 = triangle_area(p, cell_vertex2, cell_vertex3)
    area2 = triangle_area(cell_vertex1, p, cell_vertex3)
    area3 = triangle_area(cell_vertex1, cell_vertex2, p)

    test1 = math.isclose((area1 + area2 + area3), areaT, rel_tol=1e-09)

    # test 2
    cell_vertex1 = receivers.cellVertices[1][0]
    cell_vertex2 = receivers.cellVertices[1][1]
    cell_vertex3 = receivers.cellVertices[1][2]
    x = receivers.receiver_locations[1, 0]
    y = receivers.receiver_locations[1, 1]
    p = (x, y)

    areaT = triangle_area(cell_vertex1, cell_vertex2, cell_vertex3)
    area1 = triangle_area(p, cell_vertex2, cell_vertex3)
    area2 = triangle_area(cell_vertex1, p, cell_vertex3)
    area3 = triangle_area(cell_vertex1, cell_vertex2, p)

    test2 = math.isclose((area1 + area2 + area3), areaT, rel_tol=1e-09)

    # test 3
    cell_vertex1 = receivers.cellVertices[2][0]
    cell_vertex2 = receivers.cellVertices[2][1]
    cell_vertex3 = receivers.cellVertices[2][2]
    x = receivers.receiver_locations[2, 0]
    y = receivers.receiver_locations[2, 1]
    p = (x, y)

    areaT = triangle_area(cell_vertex1, cell_vertex2, cell_vertex3)
    area1 = triangle_area(p, cell_vertex2, cell_vertex3)
    area2 = triangle_area(cell_vertex1, p, cell_vertex3)
    area3 = triangle_area(cell_vertex1, cell_vertex2, p)

    test3 = math.isclose((area1 + area2 + area3), areaT, rel_tol=1e-09)

    assert all([test1, test2, test3])
Exemplo n.º 8
0
def test_correct_receiver_location_generation3D():
    """Tests if receiver locations where generated correctly"""

    test_model = deepcopy(model3D)
    comm = spyro.utils.mpi_init(test_model)
    mesh, V = spyro.io.read_mesh(test_model, comm)
    test_model["acquisition"]["num_receivers"] = 3
    receivers = spyro.create_transect((-0.05, 0.3, 0.5), (-0.05, 0.9, 0.5), 3)
    test_model["acquisition"]["receiver_locations"] = receivers
    receivers = spyro.Receivers(test_model, mesh, V, comm)
    answer = np.array([[-0.05, 0.3, 0.5], [-0.05, 0.6, 0.5], [-0.05, 0.9, 0.5]])

    assert np.allclose(receivers.receiver_locations, answer)
Exemplo n.º 9
0
    "tf": 5.00,  # Final time for event
    "dt": 0.001,
    "amplitude": 1,  # the Ricker has an amplitude of 1.
    "nspool": 1000,  # how frequently to output solution to pvds
    "fspool": 10,  # how frequently to save solution to RAM
    "skip": 4,
}
comm = spyro.utils.mpi_init(model)
mesh, V = spyro.io.read_mesh(model, comm)
if COMM_WORLD.rank == 0:
    print(f"The mesh has {V.dim()} degrees of freedom")
vp = spyro.io.interpolate(model, mesh, V, guess=True)
if comm.ensemble_comm.rank == 0:
    File("guess_velocity.pvd", comm=comm.comm).write(vp)
sources = spyro.Sources(model, mesh, V, comm)
receivers = spyro.Receivers(model, mesh, V, comm)
wavelet = spyro.full_ricker_wavelet(
    dt=model["timeaxis"]["dt"],
    tf=model["timeaxis"]["tf"],
    freq=model["acquisition"]["frequency"],
)
if comm.ensemble_comm.rank == 0:
    control_file = File(outdir + "control.pvd", comm=comm.comm)
    grad_file = File(outdir + "grad.pvd", comm=comm.comm)
quad_rule = finat.quadrature.make_quadrature(
    V.finat_element.cell, V.ufl_element().degree(), "KMV"
)
dxlump = dx(rule=quad_rule)

water = np.where(vp.dat.data[:] < 1.51)
Exemplo n.º 10
0
def test_gradient_talyor_remainder_v2():
    from ROL.firedrake_vector import FiredrakeVector as FeVector
    import ROL

    comm = spyro.utils.mpi_init(model)

    mesh, V = spyro.io.read_mesh(model, comm)

    vp_guess = _make_vp_guess(V, mesh)

    sources = spyro.Sources(model, mesh, V, comm)

    receivers = spyro.Receivers(model, mesh, V, comm)

    vp_exact = _make_vp_exact(V, mesh)

    _, p_exact_recv = spyro.solvers.forward(model, mesh, comm, vp_exact,
                                            sources, wavelet, receivers)

    qr_x, _, _ = spyro.domains.quadrature.quadrature_rules(V)

    class L2Inner(object):
        def __init__(self):
            self.A = assemble(TrialFunction(V) * TestFunction(V) *
                              dx(rule=qr_x),
                              mat_type="matfree")
            self.Ap = as_backend_type(self.A).mat()

        def eval(self, _u, _v):
            upet = as_backend_type(_u).vec()
            vpet = as_backend_type(_v).vec()
            A_u = self.Ap.createVecLeft()
            self.Ap.mult(upet, A_u)
            return vpet.dot(A_u)

    class Objective(ROL.Objective):
        def __init__(self, inner_product):
            ROL.Objective.__init__(self)
            self.inner_product = inner_product
            self.p_guess = None
            self.misfit = None

        def value(self, x, tol):
            """Compute the functional"""
            self.p_guess, p_guess_recv = spyro.solvers.forward(
                model,
                mesh,
                comm,
                vp_guess,
                sources,
                wavelet,
                receivers,
                output=False,
            )
            self.misfit = spyro.utils.evaluate_misfit(model, p_guess_recv,
                                                      p_exact_recv)
            J = spyro.utils.compute_functional(model, self.misfit)
            return J

        def gradient(self, g, x, tol):
            dJ = spyro.solvers.gradient(
                model,
                mesh,
                comm,
                vp_guess,
                receivers,
                self.p_guess,
                self.misfit,
            )
            g.scale(0)
            g.vec += dJ

        def update(self, x, flag, iteration):
            vp_guess.assign(Function(V, x.vec, name="velocity"))

    paramsDict = {
        "Step": {
            "Line Search": {
                "Descent Method": {
                    "Type": "Quasi-Newton Method"
                }
            },
            "Type": "Line Search",
        },
        "Status Test": {
            "Gradient Tolerance": 1e-12,
            "Iteration Limit": 20
        },
    }
    params = ROL.ParameterList(paramsDict, "Parameters")

    inner_product = L2Inner()
    obj = Objective(inner_product)
    u = Function(V).assign(vp_guess)
    opt = FeVector(u.vector(), inner_product)
    d = Function(V)

    x, y = SpatialCoordinate(mesh)
    # d.interpolate(sin(x * pi) * sin(y * pi))
    d.vector()[:] = np.random.rand(V.dim())
    # d.assign(0.1)
    d = FeVector(d.vector(), inner_product)
    # check the gradient using d model pertubation 4 iterations and 2nd order test
    obj.checkGradient(opt, d, 4, 2)
Exemplo n.º 11
0
def _test_gradient(options, pml=False):

    comm = spyro.utils.mpi_init(options)

    mesh, V = spyro.io.read_mesh(options, comm)

    if pml:
        vp_exact = _make_vp_exact_pml(V, mesh)
        z, x = SpatialCoordinate(mesh)
        Lx = model_pml["mesh"]["Lx"]
        Lz = model_pml["mesh"]["Lz"]
        x1 = 0.0
        x2 = Lx
        z1 = 0.0
        z2 = -Lz
        boxx1 = Function(V).interpolate(conditional(x > x1, 1.0, 0.0))
        boxx2 = Function(V).interpolate(conditional(x < Lx, 1.0, 0.0))
        boxz1 = Function(V).interpolate(conditional(z > z2, 1.0, 0.0))
        mask = Function(V).interpolate(boxx1 * boxx2 * boxz1)
        File("mask.pvd").write(mask)
    else:
        vp_exact = _make_vp_exact(V, mesh)

        mask = Function(V).assign(1.0)

    vp_guess = _make_vp_guess(V, mesh)

    sources = spyro.Sources(options, mesh, V, comm)

    receivers = spyro.Receivers(options, mesh, V, comm)

    wavelet = spyro.full_ricker_wavelet(
        options["timeaxis"]["dt"],
        options["timeaxis"]["tf"],
        options["acquisition"]["frequency"],
    )

    # simulate the exact model
    p_exact, p_exact_recv = forward(
        options,
        mesh,
        comm,
        vp_exact,
        sources,
        wavelet,
        receivers,
    )

    # simulate the guess model
    p_guess, p_guess_recv = forward(
        options,
        mesh,
        comm,
        vp_guess,
        sources,
        wavelet,
        receivers,
    )

    misfit = p_exact_recv - p_guess_recv

    qr_x, _, _ = quadrature.quadrature_rules(V)

    Jm = functional(options, misfit)
    print("\n Cost functional at fixed point : " + str(Jm) + " \n ")

    # compute the gradient of the control (to be verified)
    dJ = gradient(options, mesh, comm, vp_guess, receivers, p_guess, misfit)
    dJ *= mask
    File("gradient.pvd").write(dJ)

    steps = [1e-3, 1e-4, 1e-5]  # , 1e-6]  # step length

    delta_m = Function(V)  # model direction (random)
    delta_m.assign(dJ)

    # this deepcopy is important otherwise pertubations accumulate
    vp_original = vp_guess.copy(deepcopy=True)

    errors = []
    for step in steps:  # range(3):
        # steps.append(step)
        # perturb the model and calculate the functional (again)
        # J(m + delta_m*h)
        vp_guess = vp_original + step * delta_m
        _, p_guess_recv = forward(
            options,
            mesh,
            comm,
            vp_guess,
            sources,
            wavelet,
            receivers,
        )

        Jp = functional(options, p_exact_recv - p_guess_recv)
        projnorm = assemble(mask * dJ * delta_m * dx(rule=qr_x))
        fd_grad = (Jp - Jm) / step
        print(
            "\n Cost functional for step " + str(step) + " : " + str(Jp) +
            ", fd approx.: " + str(fd_grad) + ", grad'*dir : " +
            str(projnorm) + " \n ", )

        errors.append(100 * ((fd_grad - projnorm) / projnorm))
        # step /= 2

    # all errors less than 1 %
    errors = np.array(errors)
    assert (np.abs(errors) < 5.0).all()
Exemplo n.º 12
0
def test_forward_5shots():
    model = {}

    model["opts"] = {
        "method": "KMV",  # either CG or KMV
        "quadrature": "KMV",  # Equi or KMV
        "degree": 4,  # p order
        "dimension": 2,  # dimension
    }
    model["parallelism"] = {
        "type": "automatic",
    }
    model["mesh"] = {
        "Lz": 3.5,  # depth in km - always positive
        "Lx": 17.0,  # width in km - always positive
        "Ly": 0.0,  # thickness in km - always positive
        "meshfile": "meshes/marmousi_5Hz.msh",
        "initmodel": None,
        "truemodel": "velocity_models/vp_marmousi-ii.hdf5",
    }
    model["BCs"] = {
        "status": True,  # True or false
        "outer_bc": "non-reflective",  #  None or non-reflective (outer boundary condition)
        "damping_type": "polynomial",  # polynomial, hyperbolic, shifted_hyperbolic
        "exponent": 2,  # damping layer has a exponent variation
        "cmax": 4.5,  # maximum acoustic wave velocity in PML - km/s
        "R": 1e-6,  # theoretical reflection coefficient
        "lz": 0.9,  # thickness of the PML in the z-direction (km) - always positive
        "lx": 0.9,  # thickness of the PML in the x-direction (km) - always positive
        "ly": 0.0,  # thickness of the PML in the y-direction (km) - always positive
    }
    model["acquisition"] = {
        "source_type": "Ricker",
        "source_pos": spyro.create_transect((-0.1, 1.0), (-0.1, 15.0), 5),
        "frequency": 5.0,
        "delay": 1.0,
        "receiver_locations": spyro.create_transect((-0.1, 1.0), (-0.1, 15.0),13),
    }
    model["timeaxis"] = {
        "t0": 0.0,  #  Initial time for event
        "tf": 3.00,  # Final time for event
        "dt": 0.001,
        "amplitude": 1,  # the Ricker has an amplitude of 1.
        "nspool": 100,  # how frequently to output solution to pvds
        "fspool": 99999,  # how frequently to save solution to RAM
    }

    dt=model["timeaxis"]["dt"]
    final_time=model["timeaxis"]["tf"]

    comm = spyro.utils.mpi_init(model)

    mesh, V = spyro.io.read_mesh(model, comm)
    vp = spyro.io.interpolate(model, mesh, V, guess=False)

    if comm.ensemble_comm.rank == 0:
        File("true_velocity.pvd", comm=comm.comm).write(vp)
    sources = spyro.Sources(model, mesh, V, comm)
    receivers = spyro.Receivers(model, mesh, V, comm)
    wavelet = spyro.full_ricker_wavelet(
        dt=model["timeaxis"]["dt"],
        tf=model["timeaxis"]["tf"],
        freq=model["acquisition"]["frequency"],
    )
    p, p_r = spyro.solvers.forward(model, mesh, comm, vp, sources, wavelet, receivers)

    pass_error_test = False
    for source_id in range(len(model["acquisition"]["source_pos"])):
        if comm.ensemble_comm.rank == (source_id % comm.ensemble_comm.size):
            receiver_in_source_index= get_receiver_in_source_location(source_id, model)
            if source_id != len(model["acquisition"]["source_pos"])-1 or source_id == 0:
                receiver_comparison_index = receiver_in_source_index + 1
            else:
                receiver_comparison_index = receiver_in_source_index - 1
            error_percent = compare_velocity(p_r, receiver_in_source_index, receiver_comparison_index, model,dt)
            if error_percent < 5:
                pass_error_test = True
            print(f"For source = {source_id}: test = {pass_error_test}", flush = True)

    spyro.plots.plot_shots(model, comm, p_r, vmin=-1e-3, vmax=1e-3)
    spyro.io.save_shots(model, comm, p_r)
    assert pass_error_test
Exemplo n.º 13
0
def gradient_test_acoustic(model,
                           mesh,
                           V,
                           comm,
                           vp_exact,
                           vp_guess,
                           mask=None):  #{{{
    import firedrake_adjoint as fire_adj
    with fire_adj.stop_annotating():
        if comm.comm.rank == 0:
            print('######## Starting gradient test ########', flush=True)

        sources = spyro.Sources(model, mesh, V, comm)
        receivers = spyro.Receivers(model, mesh, V, comm)

        wavelet = spyro.full_ricker_wavelet(
            model["timeaxis"]["dt"],
            model["timeaxis"]["tf"],
            model["acquisition"]["frequency"],
        )
        point_cloud = receivers.set_point_cloud(comm)
        # simulate the exact model
        if comm.comm.rank == 0:
            print('######## Running the exact model ########', flush=True)
        p_exact_recv = forward(model, mesh, comm, vp_exact, sources, wavelet,
                               point_cloud)

    # simulate the guess model
    if comm.comm.rank == 0:
        print('######## Running the guess model ########', flush=True)
    p_guess_recv, Jm = forward(model,
                               mesh,
                               comm,
                               vp_guess,
                               sources,
                               wavelet,
                               point_cloud,
                               fwi=True,
                               true_rec=p_exact_recv)
    if comm.comm.rank == 0:
        print("\n Cost functional at fixed point : " + str(Jm) + " \n ",
              flush=True)

    # compute the gradient of the control (to be verified)
    if comm.comm.rank == 0:
        print(
            '######## Computing the gradient by automatic differentiation ########',
            flush=True)
    control = fire_adj.Control(vp_guess)
    dJ = fire_adj.compute_gradient(Jm, control)
    if mask:
        dJ *= mask

    # File("gradient.pvd").write(dJ)

    #steps = [1e-3, 1e-4, 1e-5, 1e-6, 1e-7]  # step length
    #steps = [1e-4, 1e-5, 1e-6, 1e-7]  # step length
    steps = [1e-5, 1e-6, 1e-7, 1e-8]  # step length
    with fire_adj.stop_annotating():
        delta_m = Function(V)  # model direction (random)
        delta_m.assign(dJ)
        Jhat = fire_adj.ReducedFunctional(Jm, control)
        derivative = enlisting.Enlist(Jhat.derivative())
        hs = enlisting.Enlist(delta_m)

        projnorm = sum(hi._ad_dot(di) for hi, di in zip(hs, derivative))

        # this deepcopy is important otherwise pertubations accumulate
        vp_original = vp_guess.copy(deepcopy=True)

        if comm.comm.rank == 0:
            print(
                '######## Computing the gradient by finite diferences ########',
                flush=True)
        errors = []
        for step in steps:  # range(3):
            # steps.append(step)
            # perturb the model and calculate the functional (again)
            # J(m + delta_m*h)
            vp_guess = vp_original + step * delta_m
            p_guess_recv, Jp = forward(model,
                                       mesh,
                                       comm,
                                       vp_guess,
                                       sources,
                                       wavelet,
                                       point_cloud,
                                       fwi=True,
                                       true_rec=p_exact_recv)

            fd_grad = (Jp - Jm) / step
            if comm.comm.rank == 0:
                print("\n Cost functional for step " + str(step) + " : " +
                      str(Jp) + ", fd approx.: " + str(fd_grad) +
                      ", grad'*dir : " + str(projnorm) + " \n ",
                      flush=True)

            errors.append(100 * ((fd_grad - projnorm) / projnorm))

    fire_adj.get_working_tape().clear_tape()

    # all errors less than 1 %
    errors = np.array(errors)
    assert (np.abs(errors) < 5.0).all()
Exemplo n.º 14
0
def test_correct_receiver_to_cell_location3D():
    """Tests if the receivers where located in the correct cell"""

    test_model1 = deepcopy(model3D)
    comm = spyro.utils.mpi_init(test_model1)
    mesh, V = spyro.io.read_mesh(test_model1, comm)
    rec = spyro.create_transect((-0.05, 0.1, 0.5), (-0.05, 0.9, 0.5), 3)
    test_model1["acquisition"]["receiver_locations"] = rec
    test_model1["acquisition"]["num_receivers"] = 3
    receivers = spyro.Receivers(test_model1, mesh, V, comm)

    # test 1
    cell_vertex1 = receivers.cellVertices[0][0]
    cell_vertex2 = receivers.cellVertices[0][1]
    cell_vertex3 = receivers.cellVertices[0][2]
    cell_vertex4 = receivers.cellVertices[0][3]
    x = receivers.receiver_locations[0, 0]
    y = receivers.receiver_locations[0, 1]
    z = receivers.receiver_locations[0, 2]
    p = (x, y, z)

    volumeT = tetrahedral_volume(cell_vertex1, cell_vertex2, cell_vertex3,
                                 cell_vertex4)
    volume1 = tetrahedral_volume(p, cell_vertex2, cell_vertex3, cell_vertex4)
    volume2 = tetrahedral_volume(cell_vertex1, p, cell_vertex3, cell_vertex4)
    volume3 = tetrahedral_volume(cell_vertex1, cell_vertex2, p, cell_vertex4)
    volume4 = tetrahedral_volume(cell_vertex1, cell_vertex2, cell_vertex3, p)

    test1 = math.isclose((volume1 + volume2 + volume3 + volume4),
                         volumeT,
                         rel_tol=1e-09)

    # test 2
    cell_vertex1 = receivers.cellVertices[1][0]
    cell_vertex2 = receivers.cellVertices[1][1]
    cell_vertex3 = receivers.cellVertices[1][2]
    cell_vertex4 = receivers.cellVertices[1][3]
    x = receivers.receiver_locations[1, 0]
    y = receivers.receiver_locations[1, 1]
    z = receivers.receiver_locations[1, 2]
    p = (x, y, z)

    volumeT = tetrahedral_volume(cell_vertex1, cell_vertex2, cell_vertex3,
                                 cell_vertex4)
    volume1 = tetrahedral_volume(p, cell_vertex2, cell_vertex3, cell_vertex4)
    volume2 = tetrahedral_volume(cell_vertex1, p, cell_vertex3, cell_vertex4)
    volume3 = tetrahedral_volume(cell_vertex1, cell_vertex2, p, cell_vertex4)
    volume4 = tetrahedral_volume(cell_vertex1, cell_vertex2, cell_vertex3, p)

    test2 = math.isclose((volume1 + volume2 + volume3 + volume4),
                         volumeT,
                         rel_tol=1e-09)

    # test 3
    cell_vertex1 = receivers.cellVertices[2][0]
    cell_vertex2 = receivers.cellVertices[2][1]
    cell_vertex3 = receivers.cellVertices[2][2]
    cell_vertex4 = receivers.cellVertices[2][3]
    x = receivers.receiver_locations[2, 0]
    y = receivers.receiver_locations[2, 1]
    z = receivers.receiver_locations[2, 2]
    p = (x, y, z)

    volumeT = tetrahedral_volume(cell_vertex1, cell_vertex2, cell_vertex3,
                                 cell_vertex4)
    volume1 = tetrahedral_volume(p, cell_vertex2, cell_vertex3, cell_vertex4)
    volume2 = tetrahedral_volume(cell_vertex1, p, cell_vertex3, cell_vertex4)
    volume3 = tetrahedral_volume(cell_vertex1, cell_vertex2, p, cell_vertex4)
    volume4 = tetrahedral_volume(cell_vertex1, cell_vertex2, cell_vertex3, p)

    test3 = math.isclose((volume1 + volume2 + volume3 + volume4),
                         volumeT,
                         rel_tol=1e-09)

    assert all([test1, test2, test3])
Exemplo n.º 15
0
def test_forward_3d(tf=0.6):
    model = {}

    model["opts"] = {
        "method": "KMV",  # either CG or KMV
        "quadrature": "KMV",  # Equi or KMV
        "degree": 3,  # p order
        "dimension": 3,  # dimension
    }
    model["parallelism"] = {"type": "automatic"}  # automatic",
    model["mesh"] = {
        "Lz": 5.175,  # depth in km - always positive
        "Lx": 7.50,  # width in km - always positive
        "Ly": 7.50,  # thickness in km - always positive
        "meshfile": "meshes/overthrust_3D_true_model.msh",
        "initmodel": "velocity_models/overthrust_3D_guess_model.hdf5",
        "truemodel": "velocity_models/overthrust_3D_true_model.hdf5",
    }
    model["BCs"] = {
        "status": True,  # True or false
        "outer_bc":
        "non-reflective",  #  None or non-reflective (outer boundary condition)
        "damping_type":
        "polynomial",  # polynomial, hyperbolic, shifted_hyperbolic
        "exponent": 2,  # damping layer has a exponent variation
        "cmax": 6.0,  # maximum acoustic wave velocity in PML - km/s
        "R": 1e-6,  # theoretical reflection coefficient
        "lz":
        0.75,  # thickness of the PML in the z-direction (km) - always positive
        "lx":
        0.75,  # thickness of the PML in the x-direction (km) - always positive
        "ly":
        0.75,  # thickness of the PML in the y-direction (km) - always positive
    }
    model["acquisition"] = {
        "source_type":
        "Ricker",
        "source_pos": [(-0.15, 0.25, 0.25)],
        "frequency":
        5.0,
        "delay":
        1.0,
        "receiver_locations": [(-0.15, 0.25, 0.25), (-0.15, 0.3, 0.25),
                               (-0.15, 0.35, 0.25), (-0.15, 0.4, 0.25),
                               (-0.15, 0.45, 0.25), (-0.15, 0.5, 0.25),
                               (-0.15, 0.55, 0.25), (-0.15, 0.6, 0.25)],
    }
    model["aut_dif"] = {"status": False}
    model["timeaxis"] = {
        "t0": 0.0,  #  Initial time for event
        "tf": tf,  # Final time for event
        "dt": 0.00075,
        "amplitude": 1,  # the Ricker has an amplitude of 1.
        "nspool": 100,  # how frequently to output solution to pvds
        "fspool": 99999,  # how frequently to save solution to RAM
    }

    comm = spyro.utils.mpi_init(model)
    mesh, V = spyro.io.read_mesh(model, comm)
    vp = spyro.io.interpolate(model, mesh, V, guess=False)

    if comm.ensemble_comm.rank == 0:
        File("true_velocity.pvd", comm=comm.comm).write(vp)

    sources = spyro.Sources(model, mesh, V, comm)
    receivers = spyro.Receivers(model, mesh, V, comm)
    wavelet = spyro.full_ricker_wavelet(
        dt=model["timeaxis"]["dt"],
        tf=model["timeaxis"]["tf"],
        freq=model["acquisition"]["frequency"],
    )

    p, p_r = spyro.solvers.forward(model,
                                   mesh,
                                   comm,
                                   vp,
                                   sources,
                                   wavelet,
                                   receivers,
                                   output=False)

    dt = model["timeaxis"]["dt"]
    final_time = model["timeaxis"]["tf"]

    pass_error_test = True

    if comm.comm.rank == 0:
        error_percent = compare_velocity(p_r, 0, 7, model, dt)
        if error_percent < 5:
            pass_error_test = True
        else:
            pass_error_test = False

    assert pass_error_test