def cylinder(h):
    cylinder = SeismicMesh.Cylinder(h=1.0, r=1.0)
    points, cells = SeismicMesh.generate_mesh(domain=cylinder, edge_length=h, verbose=0)
    points, cells = SeismicMesh.sliver_removal(
        points=points, domain=cylinder, edge_length=h, verbose=0
    )
    return points, cells
Пример #2
0
def test_3dmesher():

    fname = os.path.join(os.path.dirname(__file__), "test3D.bin")
    wl = 10
    hmin = 50
    freq = 2
    grade = 0.005
    nz, nx, ny = 20, 10, 10
    ef = SeismicMesh.MeshSizeFunction(
        bbox=(-2e3, 0, 0, 1e3, 0, 1e3),
        nx=nx,
        ny=ny,
        nz=nz,
        endianness="big",
        grade=grade,
        freq=freq,
        wl=wl,
        model=fname,
        hmin=hmin,
    )
    ef = ef.build()
    mshgen = SeismicMesh.MeshGenerator(ef, method="qhull")
    points, cells = mshgen.build(nscreen=1, max_iter=20, seed=0)
    # 16459 vertices and 102868 cells
    assert len(points) == 16459
    assert np.abs(len(cells) - 102868) < 150
def ball(h):
    ball = SeismicMesh.Ball([0.0, 0.0, 0.0], 1.0)
    points, cells = SeismicMesh.generate_mesh(
        domain=ball, h0=h, edge_length=h, verbose=0
    )
    points, cells = SeismicMesh.sliver_removal(
        domain=ball, points=points, h0=h, edge_length=h, verbose=0
    )
    return points, cells
Пример #4
0
def test_verbose():
    square = SeismicMesh.Rectangle((0.0, 1.0, 0.0, 1.0))

    for verbosity, correct_size in zip([0, 1, 2], [0, 191, 6013]):
        sys.stdout = open("output.txt", "w")
        points, cells = SeismicMesh.generate_mesh(domain=square,
                                                  edge_length=0.1,
                                                  verbose=verbosity)
        sys.stdout.close()
        sys.stdout = sys.__stdout__
        output_size = os.path.getsize("output.txt")

        assert output_size == correct_size
Пример #5
0
def run_SeismicMesh(HMIN=0.025):

    bbox = (-1.0, 1.0, -1.0, 1.0, -1.0, 1.0)

    def dsphere(p, xc, yc, zc, r):
        """Signed distance function for a sphere centered at xc,yc,zc with radius  r."""
        return (
            numpy.sqrt((p[:, 0] - xc) ** 2 + (p[:, 1] - yc) ** 2 + (p[:, 2] - zc) ** 2)
            - r
        )

    def sphere(x):
        return dsphere(x, 0, 0, 0, 1)

    def fh(x):
        return numpy.abs(numpy.sqrt(numpy.einsum("ij, ij->i", x, x)) - 0.5) / 5 + HMIN

    t1 = time.time()
    points, cells = SeismicMesh.generate_mesh(
        bbox=bbox,
        h0=HMIN,
        domain=sphere,
        edge_length=fh,
        max_iter=25,
        delta_t=0.3,
    )
    points, cells = SeismicMesh.sliver_removal(
        points=points,
        bbox=bbox,
        h0=HMIN,
        domain=sphere,
        edge_length=fh,
        min_dh_angle_bound=10,
        max_iter=50,
    )
    elapsed = time.time() - t1

    # meshio.write_points_cells(
    #    "SeismicMesh_sphere.vtk",
    #    points,
    #    [("tetra", cells)],
    # )

    plex = meshplex.MeshTetra(points, cells)
    angles = plex.q_min_sin_dihedral_angles
    quality = plex.q_radius_ratio

    num_cells = len(cells)
    num_vertices = len(points)

    return angles, quality, elapsed, num_vertices, num_cells
Пример #6
0
def example_2D():
    # Name of SEG-Y file containg velocity model.
    fname = "velocity_models/vel_z6.25m_x12.5m_exact.segy"
    bbox = (-12e3, 0, 0, 67e3)

    # Construct mesh sizing object from velocity model
    ef = SeismicMesh.MeshSizeFunction(
        bbox=bbox,
        model=fname,
        domain_ext=500,
        dt=0.001,
        freq=5,
        wl=5,
        hmax=1e3,
        hmin=50.0,
        grade=0.05,
    )

    # Build mesh size function
    ef = ef.build()

    ef.WriteVelocityModel("BP2004")

    # Save your mesh size function options.
    ef.SaveMeshSizeFunctionOptions("BP2004_SizingFunction")

    # Visualize mesh size function
    # ef.plot()

    # Construct mesh generator
    mshgen = SeismicMesh.MeshGenerator(
        ef, method="qhull"
    )  # if you have cgal installed, you can use method="cgal"

    # Build the mesh (note the seed makes the result deterministic)
    points, facets = mshgen.build(max_iter=2, nscreen=1, seed=0)

    import numpy as np

    np.savetxt("points.out", points, delimiter=",")

    # Write to disk (see meshio for more details)
    meshio.write_points_cells(
        "BP2004.msh",
        points / 1000,
        [("triangle", facets)],
        file_format="gmsh22",
        binary=False,
    )
Пример #7
0
def test_smooth_diff():
    cube1 = sm.Cube((-0.5, 0.5, -0.5, 0.5, -0.5, 0.5))
    ball1 = sm.Ball((0.0, 0.0, 0.5), 0.85)

    domain = sm.Difference([ball1, cube1], smoothness=0.20)
    points, cells = sm.generate_mesh(
        domain=domain,
        edge_length=0.10,
    )
    points, cells = sm.sliver_removal(
        points=points,
        domain=domain,
        edge_length=0.10,
    )
    assert np.abs(cells.shape[0] - 9004) < 100
def disk(h):
    domain = SeismicMesh.geometry.Disk([0.0, 0.0], 1.0)

    points, cells = SeismicMesh.generate_mesh(
        h0=h, domain=domain, edge_length=h, verbose=0
    )
    return points, cells
Пример #9
0
def example_write():
    # Name of SEG-Y file containg velocity model.
    fname = "velocity_models/vel_z6.25m_x12.5m_exact.segy"
    bbox = (-12e3, 0, 0, 67e3)

    # Construct mesh sizing object from velocity model
    ef = SeismicMesh.MeshSizeFunction(
        bbox=bbox,
        model=fname,
        domain_ext=2e3,
        dt=0.001,
        freq=5,
        wl=5,
        hmax=1e3,
        hmin=50.0,
        grade=0.05,
    )

    ef = ef.build()

    # Write it to an hdf5 file for later use.
    ef.WriteVelocityModel("BP2004")

    # Save your mesh size function options.
    ef.SaveMeshSizeFunctionOptions("BP2004_SizingFunction")
Пример #10
0
def run_SeismicMesh(HMIN=0.01):

    bbox = (-1.0, 1.0, -1.0, 1.0)

    disk = SeismicMesh.geometry.Disk([0, 0], 1)

    def fh(x):
        return numpy.array([HMIN] * len(x))

    t1 = time.time()
    points, cells = SeismicMesh.generate_mesh(
        bbox=bbox,
        h0=HMIN,
        domain=disk,
        edge_length=fh,
        max_iter=25,
        delta_t=0.3,
    )
    elapsed = time.time() - t1

    # meshio.write_points_cells(
    #    "SeismicMesh_circle.vtk",
    #    points,
    #    [("triangle", cells)],
    # )

    plex = meshplex.MeshTri(points, cells)
    quality = numpy.abs(plex.cell_quality)

    num_cells = len(cells)
    num_vertices = len(points)

    return quality, elapsed, num_vertices, num_cells
def box_with_refinement(h):
    cube = SeismicMesh.geometry.Cube((-1.0, 1.0, -1.0, 1.0, -1.0, 1.0))

    def edge_length(x):
        return h + 0.1 * numpy.sqrt(x[:, 0] ** 2 + x[:, 1] ** 2 + x[:, 2] ** 2)

    points, cells = SeismicMesh.generate_mesh(
        domain=cube, h0=h, edge_length=edge_length, verbose=0
    )
    points, cells = SeismicMesh.sliver_removal(
        domain=cube,
        points=points,
        h0=h,
        edge_length=edge_length,
        verbose=0,
    )
    return points, cells
Пример #12
0
def test_2dmesher():

    fname = os.path.join(os.path.dirname(__file__), "testing.segy")
    wl = 5
    hmin = 100
    grade = 0.005
    ef = SeismicMesh.MeshSizeFunction(bbox=(-10e3, 0, 0, 10e3),
                                      grade=grade,
                                      wl=wl,
                                      model=fname,
                                      hmin=hmin)
    ef = ef.build()
    mshgen = SeismicMesh.MeshGenerator(ef)
    points, facets = mshgen.build(max_iter=100, seed=0)
    # should have: 7690 vertices and 15045 cells
    assert np.abs((len(points) == 7690))
    assert len(facets) == 15045
Пример #13
0
def ball(h):
    bbox = (-1.0, 1.0, -1.0, 1.0, -1.0, 1.0)

    def ball(x):
        return numpy.sqrt(x[:, 0]**2 + x[:, 1]**2 + x[:, 2]**2) - 1.0

    points, cells = SeismicMesh.generate_mesh(bbox=bbox,
                                              h0=h,
                                              domain=ball,
                                              edge_length=h,
                                              verbose=False)
    points, cells = SeismicMesh.sliver_removal(points=points,
                                               bbox=bbox,
                                               h0=h,
                                               domain=ball,
                                               edge_length=h,
                                               verbose=False)
    return points, cells
def rect_with_refinement(h):
    domain = SeismicMesh.geometry.Rectangle((-1.0, +1.0, -1.0, +1.0))

    def f(x):
        return h + 0.1 * numpy.sqrt(x[:, 0] ** 2 + x[:, 1] ** 2)

    points, cells = SeismicMesh.generate_mesh(
        domain=domain, h0=h, edge_length=f, verbose=0
    )
    return points, cells
Пример #15
0
def rect_with_refinement(h):
    bbox = (-1.0, 1.0, -1.0, 1.0)
    domain = SeismicMesh.geometry.Rectangle([-1.0, +1.0, -1.0, +1.0])

    points, cells = SeismicMesh.generate_mesh(
        bbox=bbox,
        h0=h,
        domain=domain,
        edge_length=lambda x: h + 0.1 * numpy.sqrt(x[:, 0]**2 + x[:, 1]**2),
    )
    return points, cells
Пример #16
0
def box_with_refinement(h):
    bbox = (-1.0, 1.0, -1.0, 1.0, -1.0, 1.0)
    cube = SeismicMesh.geometry.Cube([-1.0, 1.0, -1.0, 1.0, -1.0, 1.0])

    def edge_length(x):
        return h + 0.1 * numpy.sqrt(x[:, 0]**2 + x[:, 1]**2 + x[:, 2]**2)

    points, cells = SeismicMesh.generate_mesh(bbox=bbox,
                                              h0=h,
                                              domain=cube,
                                              edge_length=edge_length,
                                              verbose=False)
    points, cells = SeismicMesh.sliver_removal(
        points=points,
        bbox=bbox,
        h0=h,
        domain=cube,
        edge_length=edge_length,
        verbose=False,
    )
    return points, cells
Пример #17
0
def test_immersion():
    for radius in radii:
        box0 = SeismicMesh.Rectangle((0.0, 1.0, 0.0, 1.0))
        disk0 = SeismicMesh.Disk([0.5, 0.5], radius)

        def fh(p):
            return 0.05 * np.abs(disk0.eval(p)) + hmin

        points, cells = SeismicMesh.generate_mesh(
            domain=box0,
            edge_length=fh,
            h0=hmin,
            subdomains=[disk0],
        )

        pmid = points[cells].sum(1) / 3  # Compute centroids
        sd = disk0.eval(pmid)

        # measure the subdomain volume
        subdomain_vol = np.sum(SeismicMesh.geometry.simp_vol(points, cells[sd < 0]))

        assert np.isclose(subdomain_vol, np.pi * radius ** 2, rtol=1e-2)
Пример #18
0
def example_3D():
    # Name of SEG-Y file containg velocity model.
    fname = "velocity_models/EGAGE_Salt.bin"
    bbox = (-4200, 0, 0, 13520, 0, 13520)
    # Construct mesh sizing object from velocity model
    ef = SeismicMesh.MeshSizeFunction(
        bbox=bbox,
        model=fname,
        nx=676,
        ny=676,
        nz=210,
        dt=0.001,
        freq=2,
        wl=10,
        hmin=25,
        grade=0.35,
        domain_ext=1000,
    )

    # Build mesh size function
    ef = ef.build()

    # Save your options so you have a record
    ef.SaveMeshSizeFunctionOptions("EGAGE_Salt")

    # Construct mesh generator
    mshgen = SeismicMesh.MeshGenerator(ef, method="cgal")

    # Build the mesh
    points, cells = mshgen.build(nscreen=1, max_iter=30, seed=0)

    # Write to disk (see meshio for more details)
    meshio.write_points_cells(
        "foo3D_V3.vtk",
        points,
        [("tetra", cells)],
    )
Пример #19
0
def test_pfix():
    hmin = 0.05
    bbox = (0.0, 1.0, 0.0, 1.0, 0.0, 1.0)

    pfix = np.linspace((0.0, 0.0, 0.0), (1.0, 0.0, 1.0),
                       int(np.sqrt(2) / hmin))

    pfix = np.vstack((pfix, SeismicMesh.geometry.corners(bbox)))

    cube = SeismicMesh.Cube(bbox)

    points, cells = SeismicMesh.generate_mesh(domain=cube,
                                              edge_length=hmin,
                                              pfix=pfix)

    def _closest_node(node, nodes):
        nodes = np.asarray(nodes)
        deltas = nodes - node
        dist_2 = np.einsum("ij,ij->i", deltas, deltas)
        return dist_2

    for p in pfix:
        d = _closest_node(p, points)
        assert np.isclose(np.min(d), 0.0)
Пример #20
0
def test_hmin():
    fname = os.path.join(os.path.dirname(__file__), "testing.segy")
    hmin = 100
    ef = SeismicMesh.MeshSizeFunction(bbox=(-1e3, 0, 0, 1e3),
                                      wl=5,
                                      model=fname,
                                      hmin=hmin)
    ef = ef.build()

    fh = ef.fh
    zg, xg = ef.GetDomainMatrices()
    sz1z, sz1x = zg.shape
    sz2 = sz1z * sz1x
    _zg = np.reshape(zg, (sz2, 1))
    _xg = np.reshape(xg, (sz2, 1))
    hh = fh((_zg, _xg))
    hh = np.reshape(hh, (sz1z, sz1x))
    assert np.amin(hh) == hmin
def l_shape_3d(h):
    tol = h / 10

    cube0 = SeismicMesh.Cube((-1.0, 1.0, -1.0, 1.0, -1.0, tol))
    cube1 = SeismicMesh.Cube((-1.0, 1.0, 0.0, 1.0, -tol, 1.0))
    cube2 = SeismicMesh.Cube((-tol, 1.0, -1.0, 1.0, -tol, 1.0))
    domain = SeismicMesh.Union([cube0, cube1, cube2])

    points, cells = SeismicMesh.generate_mesh(domain=domain, edge_length=h, verbose=0)
    points, cells = SeismicMesh.sliver_removal(
        domain=domain, points=points, edge_length=h, verbose=0
    )
    return points, cells
def quarter_annulus(h):
    rect = SeismicMesh.Rectangle((0.0, 1.0, 0.0, 1.0))
    disk0 = SeismicMesh.Disk([0.0, 0.0], 0.25)
    diff0 = SeismicMesh.Difference([rect, disk0])

    disk1 = SeismicMesh.Disk([0.0, 0.0], 1.0)
    quarter = SeismicMesh.Intersection([diff0, disk1])

    points, cells = SeismicMesh.generate_mesh(
        domain=quarter,
        edge_length=lambda x: h + 0.1 * numpy.abs(disk0.eval(x)),
        h0=h,
        verbose=0,
    )
    return points, cells
Пример #23
0
def test_grade():
    fname = os.path.join(os.path.dirname(__file__), "testing.segy")
    wl = 5
    hmin = 10
    grade = 0.005
    elen = 1e3
    ef = SeismicMesh.MeshSizeFunction(bbox=(-10e3, 0, 0, 10e3),
                                      grade=grade,
                                      wl=wl,
                                      model=fname,
                                      hmin=hmin)
    ef = ef.build()

    fh = ef.fh
    zg, xg = ef.GetDomainMatrices()
    nz, nx = zg.shape
    _zg = np.reshape(zg, (nz * nx, 1))
    _xg = np.reshape(xg, (nz * nx, 1))
    hh = fh((_zg, _xg))
    hh = np.reshape(hh, (nz, nx))
    max_grade = CheckGrade(hh, nz, nx, elen=elen)
    assert max_grade <= grade
Пример #24
0
def generate_mesh3D(model, G, comm):

    print('Entering mesh generation', flush=True)
    M = grid_point_to_mesh_point_converter_for_seismicmesh(model, G)
    method = model["opts"]["method"]

    Lz = model["mesh"]['Lz']
    lz = model['BCs']['lz']
    Lx = model["mesh"]['Lx']
    lx = model['BCs']['lx']
    Ly = model["mesh"]['Ly']
    ly = model['BCs']['ly']

    Real_Lz = Lz + lz
    Real_Lx = Lx + 2 * lx
    Real_Ly = Ly + 2 * ly

    minimum_mesh_velocity = model['testing_parameters'][
        'minimum_mesh_velocity']
    frequency = model["acquisition"]['frequency']
    lbda = minimum_mesh_velocity / frequency

    edge_length = lbda / M
    #print(Real_Lz)

    bbox = (-Real_Lz, 0.0, -lx, Real_Lx - lx, -ly, Real_Ly - ly)
    cube = SeismicMesh.Cube(bbox)

    if comm.comm.rank == 0:
        # Creating rectangular mesh
        points, cells = SeismicMesh.generate_mesh(domain=cube,
                                                  edge_length=edge_length,
                                                  mesh_improvement=False,
                                                  max_iter=75,
                                                  comm=comm.ensemble_comm,
                                                  verbose=0)

        points, cells = SeismicMesh.sliver_removal(points=points,
                                                   bbox=bbox,
                                                   domain=cube,
                                                   edge_length=edge_length,
                                                   preserve=True,
                                                   max_iter=200)

        print('entering spatial rank 0 after mesh generation')

        meshio.write_points_cells("meshes/3Dhomogeneous" + str(G) + ".msh",
                                  points, [("tetra", cells)],
                                  file_format="gmsh22",
                                  binary=False)
        meshio.write_points_cells("meshes/3Dhomogeneous" + str(G) + ".vtk",
                                  points, [("tetra", cells)],
                                  file_format="vtk")

    comm.comm.barrier()
    if method == "CG" or method == "KMV":
        mesh = fire.Mesh(
            "meshes/3Dhomogeneous" + str(G) + ".msh",
            distribution_parameters={
                "overlap_type": (fire.DistributedMeshOverlapType.NONE, 0)
            },
        )

    print('Finishing mesh generation', flush=True)
    return mesh
Пример #25
0
def generate_mesh2D(model, G, comm):

    print('Entering mesh generation', flush=True)
    M = grid_point_to_mesh_point_converter_for_seismicmesh(model, G)
    method = model["opts"]["method"]

    Lz = model["mesh"]['Lz']
    lz = model['BCs']['lz']
    Lx = model["mesh"]['Lx']
    lx = model['BCs']['lx']

    Real_Lz = Lz + lz
    Real_Lx = Lx + 2 * lx

    if model['testing_parameters']['experiment_type'] == 'homogeneous':
        minimum_mesh_velocity = model['testing_parameters'][
            'minimum_mesh_velocity']
        frequency = model["acquisition"]['frequency']
        lbda = minimum_mesh_velocity / frequency

        Real_Lz = Lz + lz
        Real_Lx = Lx + 2 * lx
        edge_length = lbda / M

        bbox = (-Real_Lz, 0.0, -lx, Real_Lx - lx)
        rec = SeismicMesh.Rectangle(bbox)

        if comm.comm.rank == 0:
            # Creating rectangular mesh
            points, cells = SeismicMesh.generate_mesh(domain=rec,
                                                      edge_length=edge_length,
                                                      mesh_improvement=False,
                                                      comm=comm.ensemble_comm,
                                                      verbose=0)
            print('entering spatial rank 0 after mesh generation')

            points, cells = SeismicMesh.geometry.delete_boundary_entities(
                points, cells, min_qual=0.6)
            a = np.amin(SeismicMesh.geometry.simp_qual(points, cells))

            meshio.write_points_cells("meshes/2Dhomogeneous" + str(G) + ".msh",
                                      points, [("triangle", cells)],
                                      file_format="gmsh22",
                                      binary=False)
            meshio.write_points_cells("meshes/2Dhomogeneous" + str(G) + ".vtk",
                                      points, [("triangle", cells)],
                                      file_format="vtk")

        comm.comm.barrier()
        if method == "CG" or method == "KMV":
            mesh = fire.Mesh(
                "meshes/2Dhomogeneous" + str(G) + ".msh",
                distribution_parameters={
                    "overlap_type": (fire.DistributedMeshOverlapType.NONE, 0)
                },
            )

    elif model['testing_parameters']['experiment_type'] == 'heterogeneous':
        # Name of SEG-Y file containg velocity model.
        fname = "vel_z6.25m_x12.5m_exact.segy"

        # Bounding box describing domain extents (corner coordinates)
        bbox = (-12000.0, 0.0, 0.0, 67000.0)

        rectangle = SeismicMesh.Rectangle(bbox)

        # Desired minimum mesh size in domain
        frequency = model["acquisition"]['frequency']
        hmin = 1429.0 / (M * frequency)

        # Construct mesh sizing object from velocity model
        ef = SeismicMesh.get_sizing_function_from_segy(
            fname,
            bbox,
            hmin=hmin,
            wl=M,
            freq=5.0,
            grade=0.15,
            domain_pad=model["BCs"]["lz"],
            pad_style="edge",
        )

        points, cells = SeismicMesh.generate_mesh(domain=rectangle,
                                                  edge_length=ef,
                                                  verbose=0,
                                                  mesh_improvement=False)

        meshio.write_points_cells("meshes/2Dheterogeneous" + str(G) + ".msh",
                                  points / 1000, [("triangle", cells)],
                                  file_format="gmsh22",
                                  binary=False)
        meshio.write_points_cells("meshes/2Dheterogeneous" + str(G) + ".vtk",
                                  points / 1000, [("triangle", cells)],
                                  file_format="vtk")

        comm.comm.barrier()
        if method == "CG" or method == "KMV":
            mesh = fire.Mesh(
                "meshes/2Dheterogeneous" + str(G) + ".msh",
                distribution_parameters={
                    "overlap_type": (fire.DistributedMeshOverlapType.NONE, 0)
                },
            )
    print('Finishing mesh generation', flush=True)
    return mesh
Пример #26
0
# when testing multiple cores.

print('Entering mesh generation', flush=True)
if model['opts']['degree'] == 2:
    M = 5.1
elif model['opts']['degree'] == 3:
    M = 3.1

edge_length = 0.286 / M
Real_Lz = model["mesh"]["Lz"] + model["BCs"]["lz"]
Lx = model["mesh"]["Lx"]
Ly = model["mesh"]["Ly"]
pad = model["BCs"]["lz"]

bbox = (-Real_Lz, 0.0, -pad, Lx + pad, -pad, Ly + pad)
cube = SeismicMesh.Cube(bbox)
points, cells = SeismicMesh.generate_mesh(domain=cube,
                                          edge_length=edge_length,
                                          max_iter=80,
                                          comm=comm.ensemble_comm,
                                          verbose=2)

points, cells = SeismicMesh.sliver_removal(points=points,
                                           bbox=bbox,
                                           max_iter=100,
                                           domain=cube,
                                           edge_length=edge_length,
                                           preserve=True)

meshio.write_points_cells("meshes/benchmark_3d.msh",
                          points, [("tetra", cells)],
Пример #27
0
def test_2d_domain_ext():

    fname = os.path.join(os.path.dirname(__file__), "testing.segy")
    wl = 5
    freq = 10
    hmin = 100
    hmax = 1000
    grade = 0.005
    domain_ext = 1e3
    ef = SeismicMesh.MeshSizeFunction(
        bbox=(-10e3, 0, 0, 10e3),
        grade=grade,
        domain_ext=domain_ext,
        wl=wl,
        freq=freq,
        model=fname,
        hmin=hmin,
        hmax=hmax,
    )
    ef = ef.build()
    mshgen = SeismicMesh.MeshGenerator(ef)
    points, facets = mshgen.build(max_iter=100, seed=0, nscreen=1)
    # 12284 vertices and 24144 cells
    assert len(points) == 12284
    assert len(facets) == 24144

    ef = SeismicMesh.MeshSizeFunction(
        bbox=(-10e3, 0, 0, 10e3),
        grade=grade,
        domain_ext=500,
        padstyle="constant",
        wl=wl,
        freq=freq,
        model=fname,
        hmin=hmin,
        hmax=hmax,
    )
    ef = ef.build()
    mshgen = SeismicMesh.MeshGenerator(ef)
    points, facets = mshgen.build(max_iter=100, seed=0, nscreen=1)
    # 10992 vertices and 21580 cells
    assert len(points) == 10992
    assert len(facets) == 21580

    ef = SeismicMesh.MeshSizeFunction(
        bbox=(-10e3, 0, 0, 10e3),
        grade=grade,
        domain_ext=2000,
        padstyle="linear_ramp",
        wl=wl,
        freq=freq,
        model=fname,
        hmin=hmin,
        hmax=hmax,
    )
    ef = ef.build()
    mshgen = SeismicMesh.MeshGenerator(ef)
    points, facets = mshgen.build(max_iter=100, seed=0, nscreen=1)

    # 14773 vertices and 29102 cells
    assert len(points) == 14773
    assert len(facets) == 29102
Пример #28
0
if model['opts']['degree'] == 2:
    M = 5.85
elif model['opts']['degree'] == 3:
    M = 3.08
elif model['opts']['degree'] == 4:
    M = 2.22
elif model['opts']['degree'] == 5:
    M = 1.69

edge_length = 0.286 / M
Real_Lz = model["mesh"]["Lz"] + model["BCs"]["lz"]
Lx = model["mesh"]["Lx"]
pad = model["BCs"]["lz"]

bbox = (-Real_Lz, 0.0, -pad, Lx + pad)
rec = SeismicMesh.Rectangle(bbox)
if comm.comm.rank == 0:
    points, cells = SeismicMesh.generate_mesh(domain=rec,
                                              edge_length=edge_length,
                                              comm=comm.ensemble_comm,
                                              verbose=0)

    points, cells = SeismicMesh.geometry.delete_boundary_entities(points,
                                                                  cells,
                                                                  min_qual=0.6)

    meshio.write_points_cells("meshes/benchmark_2d.msh",
                              points, [("triangle", cells)],
                              file_format="gmsh22",
                              binary=False)
Пример #29
0
def create_model_2D_heterogeneous(grid_point_calculator_parameters, degree):
    ''' Creates models  with the correct parameters for for grid point calculation experiments.
    
    Parameters
    ----------
    frequency: `float`
        Source frequency to use in calculation
    degree: `int`
        Polynomial degree of finite element space
    method: `string`
        The finite element method choosen
    minimum_mesh_velocity: `float`
        Minimum velocity presented in the medium
    experiment_type: `string`
        Only options are `homogenous` or `heterogenous`
    receiver_type: `string`
        Options: `near`, `far` or `near_and_far`. Specifies receiver grid locations for experiment

    Returns
    -------
    model: Python `dictionary`
        Contains model options and parameters for use in Spyro
        

    '''
    minimum_mesh_velocity = grid_point_calculator_parameters['minimum_velocity_in_the_domain']
    frequency = grid_point_calculator_parameters['source_frequency']
    dimension = grid_point_calculator_parameters['dimension']
    receiver_type = grid_point_calculator_parameters['receiver_setup']

    method = grid_point_calculator_parameters['FEM_method_to_evaluate']
    velocity_model = grid_point_calculator_parameters['velocity_model_file_name']
    model = {}

    if minimum_mesh_velocity > 500:
        print("Warning: minimum mesh velocity seems to be in m/s, input should be in km/s", flush = True)
    # domain calculations
    pady = 0.0
    Ly = 0.0

    #using the BP2004 velocity model
    
    Lz = 12000.0/1000.
    Lx = 67000.0/1000.
    pad = 1000./1000.
    Real_Lz = Lz+ pad
    Real_Lx = Lx+ 2*pad
    source_z = -1.0
    source_x = Real_Lx/2.
    source_coordinates = [(source_z,source_x)]
    if velocity_model != None:
        if velocity_model[-4:] == "segy":
            SeismicMesh.write_velocity_model(velocity_model, ofname = 'velocity_models/gridsweepcalc')
        elif velocity_model[-4:] == "hdf5":
            shutil.copy(velocity_model,'velocity_models/gridsweepcalc.hdf5' )
        else:
            raise ValueError("Velocity model filetype not recognized.")
    else:
        print("Warning: running without a velocity model is suitable for testing purposes only.", flush = True)
    padz = pad
    padx = pad
    

    if receiver_type == 'bins':

        # time calculations
        tmin = 1./frequency
        final_time = 25*tmin #should be 35

        # receiver calculations

        receiver_bin_center1 = 2.5*750.0/1000
        receiver_bin_width = 500.0/1000
        receiver_quantity_in_bin = 100#2500 # 50 squared

        bin1_startZ = source_z - receiver_bin_width/2.
        bin1_endZ   = source_z + receiver_bin_width/2.
        bin1_startX = source_x + receiver_bin_center1 - receiver_bin_width/2.
        bin1_endX   = source_x + receiver_bin_center1 + receiver_bin_width/2.

        receiver_coordinates = spyro.create_2d_grid(bin1_startZ, bin1_endZ, bin1_startX, bin1_endX, int(np.sqrt(receiver_quantity_in_bin)))

        receiver_bin_center2 = 6500.0/1000
        receiver_bin_width = 500.0/1000

        bin2_startZ = source_z - receiver_bin_width/2.
        bin2_endZ   = source_z + receiver_bin_width/2.
        bin2_startX = source_x + receiver_bin_center2 - receiver_bin_width/2.
        bin2_endX   = source_x + receiver_bin_center2 + receiver_bin_width/2.

        receiver_coordinates= receiver_coordinates + spyro.create_2d_grid(bin2_startZ, bin2_endZ, bin2_startX, bin2_endX, int(np.sqrt(receiver_quantity_in_bin))) 

        receiver_quantity = 2*receiver_quantity_in_bin

    
    if receiver_type == 'line':

        # time calculations
        tmin = 1./frequency
        final_time = 2*10*tmin + 5.0 #should be 35

        # receiver calculations

        receiver_bin_center1 = 2000.0/1000
        receiver_bin_center2 = 10000.0/1000
        receiver_quantity = 500

        bin1_startZ = source_z 
        bin1_endZ   = source_z 
        bin1_startX = source_x + receiver_bin_center1
        bin1_endX   = source_x + receiver_bin_center2

        receiver_coordinates = spyro.create_transect( (bin1_startZ, bin1_startX), (bin1_endZ, bin1_endX), receiver_quantity)

    
    # Choose method and parameters
    model["opts"] = {
        "method": method,
        "variant": None,
        "element": "tria",  # tria or tetra
        "degree": degree,  # p order
        "dimension": dimension,  # dimension
    }

    model["BCs"] = {
        "status": True,  # True or false
        "outer_bc": "non-reflective",  #  neumann, non-reflective (outer boundary condition)
        "damping_type": "polynomial",  # polynomial. hyperbolic, shifted_hyperbolic
        "exponent": 1,
        "cmax": 4.7,  # maximum acoustic wave velocity in PML - km/s
        "R": 0.001,  # theoretical reflection coefficient
        "lz": padz,  # thickness of the pml in the z-direction (km) - always positive
        "lx": padx,  # thickness of the pml in the x-direction (km) - always positive
        "ly": pady,  # thickness of the pml in the y-direction (km) - always positive
    }

    model["mesh"] = {
        "Lz": Lz,  # depth in km - always positive
        "Lx": Lx,  # width in km - always positive
        "Ly": Ly,  # thickness in km - always positive
        "meshfile": "demos/mm_exact.msh",
        "initmodel": "velocity_models/gridsweepcalc.hdf5",
        "truemodel": "velocity_models/gridsweepcalc.hdf5",
    }

    model["acquisition"] = {
        "source_type": "Ricker",
        "num_sources": 1,
        "source_pos": source_coordinates,
        "source_mesh_point": False,
        "source_point_dof": False,
        "frequency": frequency,
        "delay": 1.0,
        "num_receivers": receiver_quantity,
        "receiver_locations": receiver_coordinates,
    }

    model["timeaxis"] = {
        "t0": 0.0,  #  Initial time for event
        "tf": final_time,  # Final time for event
        "dt": 0.001,  # timestep size
        "nspool": 200,  # how frequently to output solution to pvds
        "fspool": 100,  # how frequently to save solution to RAM
    }  
    model["parallelism"] = {
    "type": "off",  # options: automatic (same number of cores for evey processor), custom, off.
    "custom_cores_per_shot": [],  # only if the user wants a different number of cores for every shot.
    # input is a list of integers with the length of the number of shots.
    }
    model['testing_parameters'] = {
        'minimum_mesh_velocity': minimum_mesh_velocity,
        'pml_fraction': padz/Lz,
        'receiver_type': receiver_type
    }

    # print(source_coordinates)
    # print(receiver_coordinates)
    return model
def l_shape(h):
    rect0 = SeismicMesh.Rectangle([-1.0, 1.0, -1.0, 0.0])
    rect1 = SeismicMesh.Rectangle([-1.0, 0.0, -1.0, 1.0])
    domain = SeismicMesh.Union([rect0, rect1])
    points, cells = SeismicMesh.generate_mesh(domain=domain, edge_length=h, verbose=0)
    return points, cells