コード例 #1
0
ファイル: models.py プロジェクト: elma16/SeaIceSim
    def __init__(self, mesh, conditions, timestepping, params, output, solver_params):

        self.timestepping = timestepping
        self.timestep = timestepping.timestep
        self.timescale = timestepping.timescale
        self.params = params
        if output is None:
            raise RuntimeError("You must provide a directory name for dumping results")
        else:
            self.output = output
        self.outfile = File(output.dirname)
        self.dump_count = 0
        self.dump_freq = output.dumpfreq
        self.solver_params = solver_params
        self.mesh = mesh
        self.conditions = conditions

        if conditions.steady_state == True:
            self.ind = 1
        else:
            self.ind = 1
        
        family = conditions.family
        self.x, self.y = SpatialCoordinate(mesh)
        self.n = FacetNormal(mesh)
        self.V = VectorFunctionSpace(mesh, family, conditions.order + 1)
        self.U = FunctionSpace(mesh, family, conditions.order + 1)
        self.U1 = FunctionSpace(mesh, 'DG', conditions.order)
        self.S = TensorFunctionSpace(mesh, 'DG', conditions.order)
        self.D = FunctionSpace(mesh, 'DG', 0)
        self.W1 = MixedFunctionSpace([self.V, self.S])
        self.W2 = MixedFunctionSpace([self.V, self.U1, self.U1])
        self.W3 = MixedFunctionSpace([self.V, self.S, self.U1, self.U1])
コード例 #2
0
ファイル: helpers.py プロジェクト: Ig-dolci/spyro-1
def create_output_file(name, comm, source_num):
    if io.is_owner(comm, source_num):
        outfile = File(
            os.getcwd() + "/results/shots_" + str(source_num) + "_ensemble_" +
            str(comm.ensemble_comm.rank) + name,
            comm=comm.comm,
        )
        return outfile
コード例 #3
0
def export_fun(fname, *funs):
    """
    Export a list of functions to a VTK file (.pvd).

    Arguments
    ---------
    fname : str
        Filename to export to
    *funs : firedrake.Function
        Any number of functions to export
    """
    outfile = File(fname)
    outfile.write(*funs)
コード例 #4
0
ファイル: solver.py プロジェクト: AndrewLister-STFC/TTiP
    def solve(self, file_path='ttip_result/solution.pvd'):
        """
        Setup and solve the nonlinear problem.
        Save value to file given.
        Any additional keyword arguments are passed to the iteration method.

        Args:
            file_path (string, optional):
                The path to save the pvd file to.
                vtk files will be generated in the same directory as the pvd.
                It is recommended that this is a separate drectory per run.
                Defaults to 'TTiP_result/solution.pvd'.
        """
        F = self.problem.a - self.problem.L
        steady_state = self.is_steady_state()

        if isinstance(self.problem, BoundaryMixin):
            var_prob = NonlinearVariationalProblem(F,
                                                   self.u,
                                                   bcs=self.problem.bcs)
        else:
            var_prob = NonlinearVariationalProblem(F, self.u)
        solver = NonlinearVariationalSolver(problem=var_prob,
                                            solver_parameters=self.params)

        outfile = File(file_path)
        outfile.write(self.u, target_degree=1, target_continuity=H1)

        if steady_state:
            solver.solve()
            outfile.write(self.u, target_degree=1, target_continuity=H1)
        else:
            self.problem.T_.assign(self.u)
            last_perc = 0
            for i in range(self.problem.steps):
                solver.solve()

                perc = int(100 * (i + 1) / self.problem.steps)
                if perc > last_perc:
                    print(f'{perc}%')
                    last_perc = perc

                self.problem.T_.assign(self.u)
                outfile.write(self.u, target_degree=1, target_continuity=H1)
コード例 #5
0
def regularization_form(r):
    mesh = UnitSquareMesh(2 ** r, 2 ** r)
    x = SpatialCoordinate(mesh)

    S = VectorFunctionSpace(mesh, "CG", 1)
    beta = 4.0
    reg_solver = RegularizationSolver(S, mesh, beta=beta, gamma=0.0, dx=dx)

    # Exact solution with free Neumann boundary conditions for this domain
    u_exact = Function(S)
    u_exact_component = cos(x[0] * pi * 2) * cos(x[1] * pi * 2)
    u_exact.interpolate(as_vector((u_exact_component, u_exact_component)))
    f = Function(S)
    theta = TestFunction(S)
    f_component = (1 + beta * 8 * pi * pi) * u_exact_component
    f.interpolate(as_vector((f_component, f_component)))
    rhs_form = inner(f, theta) * dx

    velocity = Function(S)
    rhs = assemble(rhs_form)
    reg_solver.solve(velocity, rhs)
    File("solution_vel_unitsquare.pvd").write(velocity)
    return norm(project(u_exact - velocity, S))
コード例 #6
0
# Pressure update
a2 = inner(grad(p), grad(q)) * dx
L2 = -(1 / k) * div(u1) * q * dx

# Velocity update
a3 = inner(u, v) * dx
L3 = inner(u1, v) * dx - k * inner(grad(p1), v) * dx

# Assemble matrices
A1 = assemble(a1)
A2 = assemble(a2)
A3 = assemble(a3)

# Create files for storing solution
ufile = File("results/velocity.pvd")
pfile = File("results/pressure.pvd")

# Time-stepping
t = dt

numSteps = int(T / dt)

for i in range(numSteps):

    # Update pressure boundary condition

    # Compute tentative velocity step
    # begin("Computing tentative velocity")
    b1 = assemble(L1)
    [bc.apply(A1, b1) for bc in bcu]
コード例 #7
0
    def setup_dump(self, t, tmax, pickup=False):
        """
        Setup dump files
        Check for existence of directory so as not to overwrite
        output files
        Setup checkpoint file

        :arg tmax: model stop time
        :arg pickup: recover state from the checkpointing file if true,
        otherwise dump and checkpoint to disk. (default is False).
        """

        if any([
                self.output.dump_vtus, self.output.dumplist_latlon,
                self.output.dump_diagnostics, self.output.point_data,
                self.output.checkpoint and not pickup
        ]):
            # setup output directory and check that it does not already exist
            self.dumpdir = path.join("results", self.output.dirname)
            running_tests = '--running-tests' in sys.argv or "pytest" in self.output.dirname
            if self.mesh.comm.rank == 0:
                if not running_tests and path.exists(
                        self.dumpdir) and not pickup:
                    raise IOError("results directory '%s' already exists" %
                                  self.dumpdir)
                else:
                    if not running_tests:
                        makedirs(self.dumpdir)

        if self.output.dump_vtus:

            # setup pvd output file
            outfile = path.join(self.dumpdir, "field_output.pvd")
            self.dumpfile = File(outfile,
                                 project_output=self.output.project_fields,
                                 comm=self.mesh.comm)

            # make list of fields to dump
            self.to_dump = [
                f for f in self.fields if f.name() in self.fields.to_dump
            ]

            # make dump counter
            self.dumpcount = itertools.count()

        # if there are fields to be dumped in latlon coordinates,
        # setup the latlon coordinate mesh and make output file
        if len(self.output.dumplist_latlon) > 0:
            mesh_ll = get_latlon_mesh(self.mesh)
            outfile_ll = path.join(self.dumpdir, "field_output_latlon.pvd")
            self.dumpfile_ll = File(outfile_ll,
                                    project_output=self.output.project_fields,
                                    comm=self.mesh.comm)

            # make functions on latlon mesh, as specified by dumplist_latlon
            self.to_dump_latlon = []
            for name in self.output.dumplist_latlon:
                f = self.fields(name)
                field = Function(functionspaceimpl.WithGeometry.create(
                    f.function_space(), mesh_ll),
                                 val=f.topological,
                                 name=name + '_ll')
                self.to_dump_latlon.append(field)

        # we create new netcdf files to write to, unless pickup=True, in
        # which case we just need the filenames
        if self.output.dump_diagnostics:
            diagnostics_filename = self.dumpdir + "/diagnostics.nc"
            self.diagnostic_output = DiagnosticsOutput(diagnostics_filename,
                                                       self.diagnostics,
                                                       self.output.dirname,
                                                       self.mesh.comm,
                                                       create=not pickup)

        if len(self.output.point_data) > 0:
            # set up point data output
            pointdata_filename = self.dumpdir + "/point_data.nc"
            ndt = int(tmax / float(self.dt))
            self.pointdata_output = PointDataOutput(pointdata_filename,
                                                    ndt,
                                                    self.output.point_data,
                                                    self.output.dirname,
                                                    self.fields,
                                                    self.mesh.comm,
                                                    self.output.tolerance,
                                                    create=not pickup)

            # make point data dump counter
            self.pddumpcount = itertools.count()

            # set frequency of point data output - defaults to
            # dumpfreq if not set by user
            if self.output.pddumpfreq is None:
                self.output.pddumpfreq = self.output.dumpfreq

        # if we want to checkpoint and are not picking up from a previous
        # checkpoint file, setup the checkpointing
        if self.output.checkpoint:
            if not pickup:
                self.chkpt = DumbCheckpoint(path.join(self.dumpdir, "chkpt"),
                                            mode=FILE_CREATE)
            # make list of fields to pickup (this doesn't include
            # diagnostic fields)
            self.to_pickup = [
                f for f in self.fields if f.name() in self.fields.to_pickup
            ]

        # if we want to checkpoint then make a checkpoint counter
        if self.output.checkpoint:
            self.chkptcount = itertools.count()

        # dump initial fields
        self.dump(t)
コード例 #8
0
    'pc_python_type': 'firedrake.HybridizationPC',
    'hybridization': {
        'ksp_type': 'preonly',
        'pc_type': 'lu',
        'pc_factor_mat_solver_type': 'mumps'
    }
}

uD_problem = LinearVariationalProblem(lhs(eqn), rhs(eqn), xd)
uD_solver = LinearVariationalSolver(uD_problem, solver_parameters=params)

if COMM_WORLD.Get_rank() == 0:
    print("Finished setting up solvers at  ", ctime())

# Setup output
outfile = File('{0}.pvd'.format(fname))
field_output = [un, eta_out, En, vortn, qn, q2Dn]


# Create latlon version of output
def get_latlon_mesh(mesh):
    """Build 2D projected mesh of spherical mesh"""
    crds_orig = mesh.coordinates
    mesh_dg_fs = VectorFunctionSpace(mesh, "DG", 1)
    crds_dg = Function(mesh_dg_fs)
    crds_latlon = Function(mesh_dg_fs)
    par_loop(
        """
for (int i=0; i<3; i++) {
    for (int j=0; j<3; j++) {
        dg[i][j] = cg[i][j];
コード例 #9
0
ファイル: test_forward.py プロジェクト: krober10nd/spyro
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
コード例 #10
0
ファイル: nullspace_shape.py プロジェクト: LLNL/lestofire
def nlspace_solve(problem: InfDimProblem,
                  params=None,
                  results=None,
                  descent_output_dir=None):
    """
    Solve the optimization problem
        min      J(phi)
        phi in V
        under the constraints
        g_i(phi)=0  for all i=0..p-1
        h_i(phi)<=0 for all i=0..q-1

    Usage
    -----
    results=nlspace_solve(problem: InfDimProblem, params: dict, results:dict)

    Inputs
    ------
    problem : an `~InfDimProblem` object corresponding to the optimization
                  problem above.

    params  : (optional) a dictionary containing algorithm parameters
              (see below).

    results : (optional) a previous output of the nlspace_solve` function.
              The optimization will keep going from the last input of
              the dictionary `results['phi'][-1]`.
              Useful to restart an optimization after an interruption.
    descent_output_dir : Plot the descent direction in the given directory

    Output
    ------
    results : dictionary containing
        results['J']       : values of the objective function along the path
                             (J(phi_0),...,J(phi_n))
        results['G']       : equality constraint values
                             (G(phi_0),...,G(phi_n))
        results['H']       : inequality constraints values
                             (H(phi_0),...,H(phi_n))
        results['muls']    : lagrange multiplier values
                             (mu(phi_0),...,mu(phi_n))


    Optional algorithm parameters
    -----------------------------

    params['alphaJ']   : (default 1) scaling coefficient for the null space
        step xiJ decreasing the objective function

    params['alphaC']   : (default 1) scaling coefficient for the Gauss Newton
        step xiC decreasing the violation of the constraints

    params['alphas']   : (optional) vector of dimension
        problem.nconstraints + problem.nineqconstraints containing
        proportionality coefficients scaling the Gauss Newton direction xiC for
        each of the constraints

    params['debug'] : Tune the verbosity of the output (default 0)
                      Set param['debug']=-1 to display only the final result
                      Set param['debug']=-2 to remove any output

    params['dt'] : (default : `1.0`). Pseudo time-step expressed in a time unit.
        Used to modulate the optimization convergence/oscillatory behavior.

    params['hmin'] : (default : `1.0`). Mesh minimum length. TODO Replace this for dt
        in the calculation of the tolerances `eps`

    params['K']: tunes the distance at which inactive inequality constraints
        are felt. Constraints are felt from a distance K*params['dt']

    params['maxit']    : Maximal number of iterations (default : 4000)

    params['maxtrials']: (default 3) number of trials in between time steps
        until the merit function decreases

    params['tol']      : (default 1e-7) Algorithm stops when
            ||phi_{n+1}-phi_n||<params['tol']
        or after params['maxit'] iterations.

    params['tol_merit'] : (default 0) a new iterate phi_{n+1} is accepted if
        merit(phi_{n+1})<(1+sign(merit(phi_n)*params['tol_merit']))*merit(phi_n)

    params['tol_qp'] : (default 1e-20) the tolerance for the qp solver cvxopt

    params['show_progress_qp'] : (default False) If true, then the output of
        cvxopt will be displayed between iterations.

    params['monitor_time'] : (default False) If true, then the output of
        the time taken between optimization iterations.

    """

    params = set_parameters(params)

    alphas = np.asarray(
        params.get(
            "alphas",
            [1] * (len(problem.eqconstraints) + len(problem.ineqconstraints)),
        ))

    if descent_output_dir:
        descent_pvd = File(f"{descent_output_dir}/descent_direction.pvd")

    results = {
        "phi": [],
        "J": [],
        "G": [],
        "H": [],
        "muls": [],
        "merit": [],
    }

    phi = problem.x0()

    (J, G, H) = problem.eval(phi)

    normdx = 1  # current value for x_{n+1}-x_n

    new_phi = Function(phi.function_space())
    orig_phi = Function(phi.function_space())
    while normdx > params["tol"] and len(results["J"]) < params["maxit"]:
        with MPITimer(phi.comm) as timings:

            results["J"].append(J)
            results["G"].append(G)
            results["H"].append(H)

            if problem.accept():
                break

            it = len(results["J"]) - 1
            display("\n", params["debug"], 1)
            display(
                f"{it}. J=" + format(J, ".4g") + " " + "G=[" +
                ",".join(format(phi, ".4g") for phi in G[:10]) + "] " + "H=[" +
                ",".join(format(phi, ".4g") for phi in H[:10]) + "] " +
                " ||dx||_V=" + format(normdx, ".4g"),
                params["debug"],
                0,
            )

            # Returns the gradients (in the primal space). They are
            # firedrake.Function's
            (dJ, dG, dH) = problem.eval_gradients(phi)
            dC = dG + dH

            H = np.asarray(H)
            G = np.asarray(G)
            C = np.concatenate((G, H))

            # Obtain the tolerances for the inequality constraints and the indices
            # for the violated constraints
            eps = getEps(
                dC,
                problem.n_eqconstraints,
                params["dt"],
                params["K"],
                norm_type=params["normalisation_norm"],
            )
            tildeEps = getTilde(C, problem.n_eqconstraints, eps=eps)
            print(f"eps: {eps}")
            # Obtain the violated contraints
            tilde = getTilde(C, problem.n_eqconstraints)

            p_matrix = p_matrix_eval(dC, tildeEps)
            q_vector = q_vector_eval(dJ, dC, tildeEps)
            qp_results = solve_dual_problem(
                p_matrix,
                q_vector,
                tildeEps,
                problem.n_eqconstraints,
                show_progress_qp=params["show_progress_qp"],
                tol_qp=params["tol_qp"],
            )
            muls = np.zeros(len(C))
            oldmuls = np.zeros(len(C))
            hat = np.asarray([False] * len(C))

            if qp_results:
                muls[tildeEps] = np.asarray(qp_results["x"]).flatten()
                oldmuls = muls.copy()
                hat = np.asarray([True] * len(C))
                hat[problem.n_eqconstraints:] = (muls[problem.n_eqconstraints:]
                                                 > 30 * params["tol_qp"])
                if params.get("disable_dual", False):
                    hat = tildeEps

                dCdCT = dCdCT_eval(dC, hat)
                dCdCTinv = invert_dCdCT(dCdCT, params["debug"])
                muls = np.zeros(len(C))

                dCdJ = dCdJ_eval(dJ, dC, hat)
                muls[hat] = -dCdCTinv.dot(dCdJ[hat])

                if not np.all(muls[problem.n_eqconstraints:] >= 0):
                    display(
                        "Warning, the active set has not been predicted " +
                        "correctly Using old lagrange multipliers",
                        params["debug"],
                        level=1,
                        color="orange_4a",
                    )
                    hat = np.asarray([True] * len(C))
                    muls = oldmuls.copy()

            results["muls"].append(muls)
            display(f"Lagrange multipliers: {muls[:10]}",
                    params["debug"],
                    level=5)
            xiJ = xiJ_eval(dJ, dC, muls, hat)

            # Set of constraints union of active and new violated constraints.
            indicesEps = np.logical_or(tilde, hat)
            dCdCT = dCdCT_eval(dC, indicesEps)
            dCtdCtTinv = invert_dCdCT(dCdCT, params["debug"])

            xiC = xiC_eval(C, dC, dCtdCtTinv, alphas, indicesEps)

            # TODO Consider this? AC = min(0.9, alphaC * dt / max(compute_norm(xiC), 1e-9))
            AJ = params["alphaJ"]
            AC = params["alphaC"]

            # Make updates with merit function
            if xiC:
                problem.delta_x.assign(
                    Constant(-AJ) * xiJ - Constant(AC) * xiC)
            else:
                problem.delta_x.assign(Constant(-AJ) * xiJ)
            normdx = fd.norm(problem.delta_x)

            merit_eval_new = partial(merit_eval, muls, indicesEps, dCtdCtTinv)
            merit = merit_eval_new(AJ, J, AC, C)
            results["merit"].append(merit)
            if len(results["merit"]) > 3:
                print(
                    f"Merit oscillation: {(results['merit'][-1] - results['merit'][-2]) * (results['merit'][-2] - results['merit'][-3])}"
                )

            if descent_output_dir:
                descent_pvd.write(problem.delta_x)

            orig_phi.assign(phi)
            new_phi, newJ, newG, newH = line_search(
                problem,
                orig_phi,
                new_phi,
                merit_eval_new,
                merit,
                AJ,
                AC,
                dt=params["dt"],
                maxtrials=params["maxtrials"],
                tol_merit=params["tol_merit"],
                debug=params["debug"],
            )
            phi.assign(new_phi)
            (J, G, H) = (newJ, newG, newH)

        if params["monitor_time"]:
            print(
                f"Max time per iteration: {timings.max_time}, min time per iteration: {timings.min_time}"
            )

    results["J"].append(J)
    results["G"].append(G)
    results["H"].append(H)

    display("\n", params["debug"], -1)
    display("Optimization completed.", params["debug"], -1)
    return results
コード例 #11
0
            str(LC1), "-setnumber", "lc2",
            str(LC2), "mesh/hexa.geo"
        ])

        permittivity_dict = {1: 1, 2: 11.8, 3: 1}
        s = np.array([1, 2])
        p = np.array([-2, 1])
        k0L = np.pi

        print("Isotropic Scattering with permittivity {} and n {}".format(
            permittivity_dict, i))
        problem = IsotropicScattering(mesh_file, permittivity_dict, k0L)
        pw = PlaneWave(s, p)

        E_isotropic = problem.solve(pw)
        File(f"results/isotropic_{i}.pvd").write(E_isotropic)

        phi, FF_isotropic = problem.get_far_field(E_isotropic,
                                                  FAR_FIELD_POINTS)
        np.save(f"results/ff_isotropic-{i}.npy", FF_isotropic)

        epsilon = [[5.46549124, 0], [0, 5.7717177]]

        permittivity_dict = {1: epsilon, 2: epsilon, 3: np.identity(2)}
        print("Anisotropic Scattering with permittivity {} and n {}".format(
            permittivity_dict, i))
        problem = AnisotropicScattering(problem.mesh, permittivity_dict, k0L)
        E_anisotropic = problem.solve(pw)
        File(f"results/anisotropic_{i}.pvd").write(E_anisotropic)

        _, FF_anisotropic = problem.get_far_field(E_anisotropic,
コード例 #12
0
ファイル: test_forward_3d.py プロジェクト: krober10nd/spyro
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
コード例 #13
0
ファイル: outputting.py プロジェクト: tommbendall/peakondrake
    def __init__(self,
                 prognostic_variables,
                 diagnostic_variables,
                 simulation_parameters,
                 peakon_equations=None,
                 diagnostic_values=None):

        self.ndump = simulation_parameters['ndump'][-1]
        self.field_ndump = simulation_parameters['field_ndump'][-1]
        self.prognostic_variables = prognostic_variables
        self.diagnostic_variables = diagnostic_variables
        self.simulation_parameters = simulation_parameters
        self.peakon_equations = peakon_equations
        file_name = simulation_parameters['file_name'][-1]
        dirname = simulation_parameters['dirname'][-1]
        self.data_file = Dataset(file_name, 'a')

        # set up things for dumping diagnostics
        if diagnostic_values is not None:
            if isinstance(diagnostic_values, str):
                dimensions = self.data_file[diagnostic_values].dimensions
            else:
                if diagnostic_values[0] != 'mu':
                    dimensions = self.data_file[
                        diagnostic_values[0]].dimensions
                else:
                    dimensions = self.data_file[diagnostic_values[0] + '_' +
                                                str(0)].dimensions

        index_list = []
        variable_list = []
        for dimension in dimensions:
            if dimension not in ('time', 'x'):
                variable_list.append(dimension)
                index_list.append(simulation_parameters[dimension][0])

        self.index_slices = [slice(index, index + 1) for index in index_list]
        self.t_idx = 0
        self.diagnostic_values = diagnostic_values
        self.list_of_peakon_diagnostics = [
            'peakon_loc', 'peakon_min_du', 'peakon_max_du',
            'peakon_min_du_loc', 'peakon_max_du_loc', 'peakon_max_u',
            'peakon_mu', 'peakon_nu'
        ]

        # set up things for dumping fields
        if self.field_ndump > 0:
            field_file_name = dirname + '/fields'
            for dimension, index in zip(variable_list, index_list):
                field_file_name += '_' + str(dimension) + str(index)
            field_file_name += '_output.pvd'
            self.field_file = File(field_file_name)

            prognostic_variables = [
                value for value in self.prognostic_variables.fields.values()
            ]
            diagnostic_variables = [
                value
                for value in self.diagnostic_variables.dumpfields.values()
            ]
            self.dumpfields = prognostic_variables + diagnostic_variables

        self.out_string = ''
        for key, value in simulation_parameters.items():
            if len(value) > 1:
                self.out_string += str(key) + ' = %s, ' % str(value[0])

        # write initial wallclock time
        self.data_file['wallclock_time'][
            [slice(0, 1)] + self.index_slices] = datetime.now().timestamp()

        # set up coordinate field
        if self.simulation_parameters['store_coordinates'][-1]:
            self.data_file[
                'x'][:] = self.diagnostic_variables.coords.dat.data[:]
コード例 #14
0
ファイル: state.py プロジェクト: ViniVaseekaran/gusto
    def setup_dump(self, tmax, pickup=False):
        """
        Setup dump files
        Check for existence of directory so as not to overwrite
        output files
        Setup checkpoint file

        :arg tmax: model stop time
        :arg pickup: recover state from the checkpointing file if true,
        otherwise dump and checkpoint to disk. (default is False).
        """
        self.dumpdir = path.join("results", self.output.dirname)
        outfile = path.join(self.dumpdir, "field_output.pvd")
        if self.mesh.comm.rank == 0 and "pytest" not in self.output.dirname \
           and path.exists(self.dumpdir) and not pickup:
            raise IOError("results directory '%s' already exists" %
                          self.dumpdir)
        self.dumpcount = itertools.count()
        self.dumpfile = File(outfile,
                             project_output=self.output.project_fields,
                             comm=self.mesh.comm)
        if self.output.checkpoint and not pickup:
            self.chkpt = DumbCheckpoint(path.join(self.dumpdir, "chkpt"),
                                        mode=FILE_CREATE)

        # make list of fields to dump
        self.to_dump = [field for field in self.fields if field.dump]

        # if there are fields to be dumped in latlon coordinates,
        # setup the latlon coordinate mesh and make output file
        if len(self.output.dumplist_latlon) > 0:
            mesh_ll = get_latlon_mesh(self.mesh)
            outfile_ll = path.join(self.dumpdir, "field_output_latlon.pvd")
            self.dumpfile_ll = File(outfile_ll,
                                    project_output=self.output.project_fields,
                                    comm=self.mesh.comm)

        # make list of fields to pickup (this doesn't include diagnostic fields)
        self.to_pickup = [field for field in self.fields if field.pickup]

        # make functions on latlon mesh, as specified by dumplist_latlon
        self.to_dump_latlon = []
        for name in self.output.dumplist_latlon:
            f = self.fields(name)
            field = Function(functionspaceimpl.WithGeometry(
                f.function_space(), mesh_ll),
                             val=f.topological,
                             name=name + '_ll')
            self.to_dump_latlon.append(field)

        # we create new netcdf files to write to, unless pickup=True, in
        # which case we just need the filenames
        if self.output.dump_diagnostics:
            diagnostics_filename = self.dumpdir + "/diagnostics.nc"
            self.diagnostic_output = DiagnosticsOutput(diagnostics_filename,
                                                       self.diagnostics,
                                                       self.output.dirname,
                                                       create=not pickup)

        if len(self.output.point_data) > 0:
            pointdata_filename = self.dumpdir + "/point_data.nc"

            ndt = int(tmax / self.timestepping.dt)
            self.pointdata_output = PointDataOutput(pointdata_filename,
                                                    ndt,
                                                    self.output.point_data,
                                                    self.output.dirname,
                                                    self.fields,
                                                    create=not pickup)
コード例 #15
0
ファイル: experiment.py プロジェクト: tommbendall/peakondrake
def do_simulation_loop(N,
                       variable_parameters,
                       simulation_parameters,
                       diagnostics=None,
                       fields_to_output=None,
                       expected_u=False):
    """
    A recursive strategy for setting up a variable number of for loops
    for the experiment.

    :arg N: the level of loop.
    :arg variable_parameters: an OrderedDict of the parameters to be varied.
    :arg simulation_parameters: a dict storing the parameters for that simulation.
    :arg diagnostics: a list of diagnostic values to be output.
    :arg fields_to_output: a list of fields to be output.
    """

    # we do the loop in reverse order to get the resolution loop on the outside
    M = len(variable_parameters)
    key = list(variable_parameters.items())[M - N][0]
    have_setup = False

    # we must turn the ordered dict into a list to iterate through it
    for index, value in enumerate(
            list(variable_parameters.items())[M - N][1][1]):
        simulation_parameters[key] = (index, value)

        # make mesh if loop is a resolution loop
        if key == 'resolution':
            mesh = PeriodicIntervalMesh(value, simulation_parameters['Ld'][-1])
            simulation_parameters['mesh'] = (mesh, )

        # do recursion if we aren't finished yet
        if N > 1:
            do_simulation_loop(N - 1,
                               variable_parameters,
                               simulation_parameters,
                               diagnostics=diagnostics,
                               fields_to_output=fields_to_output,
                               expected_u=expected_u)

        # finally do simulation
        elif N == 1:

            if expected_u:
                this_u = simulation(simulation_parameters,
                                    diagnostic_values=diagnostics,
                                    fields_to_output=fields_to_output,
                                    expected_u=True)
                if have_setup:
                    Eu.assign(counter * Eu + this_u)
                    counter.assign(counter + 1)
                    Eu.assign(Eu / counter)
                else:
                    scheme = simulation_parameters['scheme'][-1]
                    mesh = simulation_parameters['mesh'][-1]
                    prognostic_variables = PrognosticVariables(scheme, mesh)
                    Eu = Function(prognostic_variables.Vu,
                                  name='expected u').assign(this_u)
                    counter = Constant(1.0)
                    have_setup = True
            else:
                simulation(simulation_parameters,
                           diagnostic_values=diagnostics,
                           fields_to_output=fields_to_output)

    if expected_u:
        expected_u_file = File(simulation_parameters['dirname'][-1] +
                               '/expected_u.pvd')
        expected_u_file.write(Eu)
コード例 #16
0
ファイル: run_forward_3d.py プロジェクト: Ig-dolci/spyro-1
    "num_receivers": len(receivers),
    "receiver_locations": receivers,
}
model["timeaxis"] = {
    "t0": 0.0,  #  Initial time for event
    "tf": 4.00,  # 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"],
)
t1 = time.time()
p, p_r = spyro.solvers.forward(model,
                               mesh,
                               comm,
                               vp,
                               sources,
                               wavelet,
                               receivers,
コード例 #17
0
def run(steady=False):
    """
    solve CdT/dt = S + div(k*grad(T))
    => C*v*(dT/dt)/k*dx - S*v/k*dx + grad(v)*grad(T)*dx = v*dot(grad(T), n)*ds
    """
    steps = 250
    dt = 1e-10
    timescale = (0, steps * dt)
    if steady:
        print('Running steady state.')
    else:
        print(f'Running with time step {dt:.2g}s on time interval: '
              f'{timescale[0]:.2g}s - {timescale[1]:.2g}s')
    dt_invc = Constant(1 / dt)
    extent = [40e-6, 40e-6, 40e-6]
    mesh = BoxMesh(20, 20, 20, *extent)

    V = FunctionSpace(mesh, 'CG', 1)
    print(V.dim())

    T = Function(V)  # temperature at time i+1 (electron for now)
    T_ = Function(V)  # temperature at time i
    v = TestFunction(V)  # test function

    S = create_S(mesh, V, extent)
    C = create_heat_capacity(mesh, V, extent)
    k = create_conductivity(mesh, V, T)

    set_initial_value(mesh, T_, extent)

    # Mass matrix section
    M = C * T * dt_invc * v * dx
    M_ = C * T_ * dt_invc * v * dx
    # Stiffness matrix section
    A = k * dot(grad(T), grad(v)) * dx
    # function section
    f = S * v * dx
    # boundaries
    bcs, R, b = create_dirichlet_bounds(mesh,
                                        V,
                                        T,
                                        v,
                                        k,
                                        g=100,
                                        boundary=[1, 2, 3, 4, 5, 6])
    # bcs += create_dirichlet_bounds(mesh, V, T, v, k, 500, [6])[0]
    # bcs, R, b = create_robin_bounds(mesh, T, v, k, 1e8/(100), 1e8)

    if steady:
        steps = 1
        a = A + R
        L = f + b
    else:
        a = M + A + R
        L = M_ + f + b

    prob = NonlinearVariationalProblem(a - L, T, bcs=bcs)
    solver = NonlinearVariationalSolver(prob, solver_parameters=SOLVE_PARAMS)

    T.assign(T_)

    timestamp = datetime.now().strftime("%d-%b-%Y-%H-%M-%S")
    outfile = File(f'{timestamp}/first_output.pvd')
    outfile.write(T_, target_degree=1, target_continuity=H1)
    last_perc = 0
    for i in range(steps):
        solver.solve()

        perc = int(100 * (i + 1) / steps)
        if perc > last_perc:
            print(f'{perc}%')
            last_perc = perc

        T_.assign(T)
        outfile.write(T_, target_degree=1, target_continuity=H1)