def hessian_wrap(model_pert_in, model_pert_out):
    """
    @Params
    model_pert_in: input numpy array
    model_pert_out: output numpy array
    """
    model_pert_out *= 0.

    DevitoOperators.td_born_hessian(model_pert_in=model_pert_in,
                                    model_pert_out=model_pert_out,
                                    src_coords=src_coord,
                                    vel=vel,
                                    geometry=geometry,
                                    solver=solver,
                                    params=params)
##################################################################################################
# This part of the code generates the forward data using the two models and computes the residual
##################################################################################################

dt = v.critical_dt

# Allocate numpy arrays to store data
data = np.zeros(shape=(params["Ns"], params["Nt"], params["Nr"]),
                dtype=np.float32)
data1 = data * 0

# Call wave_propagator_forward with appropriate arguments
t_start = time.time()
DevitoOperators.wave_propagator_forward(data=data,
                                        src_coords=src_coord,
                                        vel=v,
                                        geometry=geometry,
                                        solver=solver,
                                        params=params)
t_end = time.time()
print("\n Time to model shots for v took ", t_end - t_start, " sec.")

t_start = time.time()
DevitoOperators.wave_propagator_forward(data=data1,
                                        src_coords=src_coord,
                                        vel=v1,
                                        geometry=geometry,
                                        solver=solver,
                                        params=params)
t_end = time.time()
print("\n Time to model shots for v1 took ", t_end - t_start, " sec.")
                                    model_pert_out=model_pert_out,
                                    src_coords=src_coord,
                                    vel=vel,
                                    geometry=geometry,
                                    solver=solver,
                                    params=params)


# Create rhs for inversion
dm_adjoint_image = np.zeros((params["Nt"], params["Nx"], params["Nz"]),
                            dtype=np.float32)
t_start = time.time()
DevitoOperators.td_born_hessian(model_pert_in=dm,
                                model_pert_out=dm_adjoint_image,
                                src_coords=src_coord,
                                vel=vel,
                                geometry=geometry,
                                solver=solver,
                                params=params)
t_end = time.time()
print("\nCreate adjoint image took ", t_end - t_start, " sec")

# Run the inversion
niter = 100
dm_invert, resid = conjugate_gradient(hessian_wrap,
                                      rhs=dm_adjoint_image,
                                      x0=None,
                                      niter=niter,
                                      printobj=False)

# Save results