示例#1
0
def mergeMeshes(meshList, verbose=False):
    """Merge several meshes into one new mesh and return the new mesh.

    Merge several meshes into one new mesh and return the new mesh.

    Parameters
    ----------
    meshList : [:gimliapi:`GIMLI::Mesh`, ...] | [str, ...]
        List of at least two meshes or (filenames to meshes) to be merged.

    verbose : bool
        Give some output

    See Also
    --------
    merge2Meshes
    """
    if not isinstance(meshList, list):
        raise Exception("Argument meshList is no list")

    if len(meshList) < 2:
        raise Exception(
            "To few meshes in meshList, at least 2 meshes are needed.")

    if isinstance(meshList[0], str):
        mL = []
        if verbose:
            print("Reading meshes ... ")

        for mFileName in meshList:
            m = pg.Mesh(2)
            m.load(mFileName)
            if verbose:
                print("loaded", mFileName, m)
            mL.append(m)

        meshList = mL
        #meshList = [pg.Mesh(2); m.load(m) ]

    if verbose:
        print("Merging meshes ... ")

    mesh = meshList[0]
    if verbose:
        print(mesh)

    for m in range(1, len(meshList)):
        mesh = merge2Meshes(mesh, meshList[m])
        if verbose:
            print(mesh)

    return mesh
示例#2
0
def tetgen(filename, quality=1.2, preserveBoundary=False, verbose=False):
    """Create a mesh with :term:`Tetgen` from file.

    Create a :term:`Tetgen` :cite:`Si2004` mesh from a PLC.

    Forwards to system call tetgen, which must be known to your system.

    Parameters
    ----------
    filename: str

    quality: float [1.2]
        Refines mesh (to improve mesh quality). [1.1 ... ]

    preserveBoundary: bool [False]
        Preserve PLC boundary mesh

    verbose: bool [False]
        be verbose

    Returns
    -------
    mesh : :gimliapi:`GIMLI::Mesh`
    """
    filebody = filename.replace('.poly', '')
    syscal = 'tetgen -pazAC'
    syscal += 'q' + str(quality)

    if not verbose:
        syscal += 'Q'
    else:
        syscal += 'V'

    if preserveBoundary:
        syscal += 'Y'

    syscal += ' ' + filebody + '.poly'

    if verbose:
        print(syscal)

    system(syscal)
    system('meshconvert -it -BD -o ' + filebody + ' ' + filebody + '.1')
    try:
        os.remove(filebody + '.1.node')
        os.remove(filebody + '.1.ele')
        os.remove(filebody + '.1.face')
    except BaseException as e:
        print(e)
    mesh = pg.Mesh(filebody)
    return mesh
示例#3
0
    def restore(self):
        """Read data from json infos"""
        if os.path.exists(self._name + '.json'):

            # Fricking mpl kills locale setting to system default .. this went
            # horrible wrong for german 'decimal_point': ','
            pg.checkAndFixLocaleDecimal_point(verbose=False)

            try:
                with open(self._name + '.json') as file:
                    self.info = json.load(file)

                # if len(self.info['type']) != 1:
                #     pg.error('only single return caches supported for now.')

                if self.info['type'] == 'DataContainerERT':
                    self._value = pg.DataContainerERT(self.info['file'],
                                                      removeInvalid=False)
                    # print(self._value)
                elif self.info['type'] == 'RVector':
                    self._value = pg.Vector()
                    self._value.load(self.info['file'], format=pg.core.Binary)
                elif self.info['type'] == 'Mesh':
                    pg.tic()
                    self._value = pg.Mesh()
                    self._value.loadBinaryV2(self.info['file'] + '.bms')
                    pg.debug("Restoring cache took:", pg.dur(), "s")
                elif self.info['type'] == 'ndarray':
                    self._value = np.load(self.info['file'] + '.npy', 
                                          allow_pickle=True)
                else:
                    self._value = np.load(self.info['file'] + '.npy', 
                                          allow_pickle=True)

                if self.value is not None:
                    self.info['restored'] = self.info['restored'] + 1           
                    self.updateCacheInfo()
                    pg.info('Cache {3} restored ({1}s x {0}): {2}'.\
                        format(self.info['restored'],
                               round(self.info['dur'], 1),
                               self._name, self.info['codeinfo']))
                else:
                    # default try numpy 
                    pg.warn('Could not restore cache of type {0}.'.format(self.info['type']))

                pg.debug("Restoring cache took:", pg.dur(), "s")
            except Exception as e:
                import traceback
                traceback.print_exc(file=sys.stdout)
                print(self.info)
                pg.error('Cache restoring failed.')
示例#4
0
def triangle(p2=False):
    mesh = pg.Mesh()
    n1 = mesh.createNode(0.0, 0.0, 0.0)
    n2 = mesh.createNode(1.0, 0.0, 0.0)
#    n3 = mesh.createNode(1.0, 1.0, 0.0)
    n4 = mesh.createNode(0.0, 1.0, 0.0)
    mesh.createTriangle(n1, n2, n4)
    mesh.rotate(pg.RVector3(0.0, 0.0, 45))
#    mesh.createTriangle(n2, n3, n4)

    if p2:
        mesh = mesh.createP2()

    show(mesh)
示例#5
0
def quadrangle(p2=False):
    mesh = pg.Mesh()
    n1 = mesh.createNode(0.0, 0.0, 0.0)
    n2 = mesh.createNode(1.0, 0.0, 0.0)
    n3 = mesh.createNode(1.0, 1.0, 0.0)
    n4 = mesh.createNode(0.0, 1.0, 0.0)
    mesh.createQuadrangle(n1, n2, n3, n4)
    mesh.rotate(pg.RVector3(0.0, 0.0, 45))
    mesh.scale(pg.RVector3(1.0, 0.5, 1.0))

    if p2:
        mesh = mesh.createP2()

    show(mesh)
示例#6
0
def modelPlume(maxArea=0.1):
    boundary = []

    boundary.append([-1., 0.0])  #0
    boundary.append([-1., -1.0])  #1

    boundary.append([-0.1, -1.0])  #2
    boundary.append([0.1, -1.0])  #3

    boundary.append([1., -1.0])  #4
    boundary.append([1., 0.0])  #5
    boundary.append([0.1, 0.0])  #6
    boundary.append([-0.1, 0.0])  #7

    poly = pg.Mesh(2)
    nodes = [poly.createNode(b) for b in boundary]

    polyCreateDefaultEdges_(poly, boundaryMarker=[1, 2, 3, 2, 4, 5, 6, 7])

    #poly.createEdge(nodes[0], nodes[1], 1) # left
    #poly.createEdge(nodes[1], nodes[2], 2) # bottom1
    #poly.createEdge(nodes[2], nodes[3], 3) # bottom2
    #poly.createEdge(nodes[3], nodes[4], 2) # bottom3
    #poly.createEdge(nodes[4], nodes[5], 4) # right
    #poly.createEdge(nodes[5], nodes[6], 5) # top1
    #poly.createEdge(nodes[6], nodes[7], 6) # topcenter
    #poly.createEdge(nodes[7], nodes[0], 7) # top2

    mesh = createMesh(poly,
                      quality=33.4,
                      area=maxArea,
                      smooth=[0, 10],
                      verbose=False)

    velBoundary = [  #[1, [0.0,  0.0]],
        #                [2, [0.0,  0.0]],
        #[3, [0.0,  0.0]],
        #[4, [0.0,  0.0]],
        [5, [1.0, 0.0]],
        [6, [0.0, 0.0]],
        [7, [-1.0, 0.0]]
    ]

    b = mesh.findBoundaryByMarker(2)[0]
    b.setMarker(8)
    #preBoundary=None
    preBoundary = [[8, 0.0]]

    a = 1
    return mesh, velBoundary, preBoundary, a, 100
示例#7
0
def readHydrus3dMesh(filename='MESHTRIA.TXT'):
    """Import mesh from Hydrus3D.

    Parameters
    ----------
    fname : str, optional
        Filename of Hydrus output file.

    See Also
    --------
    readHydrus2dMesh : Similar routine for two-dimensional meshes.

    References
    ----------
    .. http://www.pc-progress.com/en/Default.aspx?h3d-description
    """
    f = open(filename, 'r')
    for i in range(6):
        line1 = f.readline()

    nnodes = int(line1.split()[0])
    ncells = int(line1.split()[1])
    # print(nnodes, ncells)

    line1 = f.readline()
    nodes = []
    dx = 0.01
    mesh = pg.Mesh()
    for _ in range(nnodes):
        pos = f.readline().split()
        p = pg.RVector3(
            float(pos[1]) * dx,
            float(pos[2]) * dx,
            float(pos[3]) * dx * (-1.))
        n = mesh.createNode(p)
        nodes.append(n)

    line1 = f.readline()
    line1 = f.readline()
    cells = []
    for _ in range(ncells):
        pos = f.readline().split()
        i, j, k, l = int(pos[1]), int(pos[2]), int(pos[3]), int(pos[4]),
        c = mesh.createTetrahedron(nodes[i - 1], nodes[j - 1], nodes[k - 1],
                                   nodes[l - 1])
        cells.append(c)

    f.close()
    mesh.createNeighbourInfos()
    return mesh
示例#8
0
def refineQuad2Tri(mesh, style=1):
    """Refine mesh of quadrangles into a mesh of triangle cells.

        TODO mixed meshes

    Parameters
    ----------
    mesh : :gimliapi:`GIMLI::Mesh`
        mesh containing quadrangle cells

    style: int [1]
        * 1 bisect each quadrangle into 2 triangles
        * 2 bisect each quadrangle into 4 triangles

    Returns
    -------
    ret : :gimliapi:`GIMLI::Mesh`
        mesh containing triangle cells

    """
    out = pg.Mesh(2)
    newNode = None

    for n in mesh.nodes():
        out.createNode(n.pos())

    for c in mesh.cells():

        if style == 1:
            out.createCell([c.node(0).id(), c.node(1).id(), c.node(2).id()])
            out.createCell([c.node(0).id(), c.node(2).id(), c.node(3).id()])

        elif style == 2:
            newNode = out.createNodeWithCheck(c.center())

            for i in range(4):
                out.createCell(
                    [c.node(i).id(),
                     c.node((i + 1) % 4).id(),
                     newNode.id()])

        for i in range(c.boundaryCount()):
            b = c.boundary(i)
            if b.marker() != 0:
                out.createBoundary(
                    [b.node(0).id(), b.node(1).id()], b.marker())

    out.createNeighbourInfos()

    return out
示例#9
0
    def test_io_triangle(self):
        """
        """
        # create tempfile in most secure manner, only accesible by this process
        # id no execution allowed at all, will be deleted as soon as this
        # process stops
        try:
            import tempfile as tmp
        except ImportError:
            return

        _, name2D = tmp.mkstemp(suffix='.poly')

        # 2D, creating test trinangle poly
        m = pg.Mesh(2)
        nodes = []
        nodes.append(m.createNode([-1, -2]))
        nodes.append(m.createNode([-1, 2]))
        nodes.append(m.createNode([1, 2]))
        nodes.append(m.createNode([1, -2]))
        for i in range(4):
            m.createEdge(nodes[i], nodes[(i + 1) % 4])

        nodes.append(m.createNode([-1, -3]))
        nodes.append(m.createNode([1, -3]))

        m.createEdge(nodes[0], nodes[4])
        m.createEdge(nodes[1], nodes[5])
        m.createEdge(nodes[4], nodes[5])

        m.addRegionMarker([0., 0.], -3, area=-1)
        m.addRegionMarker([0., -2.5], 1, area=42.42)
        pg.meshtools.exportPLC(m, name2D)

        # 2D, test triangle mesh for consistincy
        poly = pg.meshtools.readPLC(name2D)

        np.testing.assert_allclose(poly.regionMarkers()[0].array(),
                                   np.array([0., -2.5, 0.]))
        np.testing.assert_allclose(poly.holeMarkers()[0].array(),
                                   np.array([0., 0., 0.]))
        np.testing.assert_allclose(np.sort(poly.positions().array()),
                                   np.sort(m.positions().array()))
        np.testing.assert_equal(poly.regionMarkers()[0].area(), 42.42)

        try:
            os.remove(name2D)
        except:
            print("can't remove:", name2D)
示例#10
0
def tetrahedron( p2 ):
    
    mesh = g.Mesh( 3 )
    n0 = mesh.createNode( 0.0, 0.0, 0.0 )
    n1 = mesh.createNode( 1.0, 0.0, 0.0 )
    n2 = mesh.createNode( 0.0, 1.0, 0.0 )
    n3 = mesh.createNode( 0.0, 0.0, 1.0 )

    mesh.createTetrahedron( n0, n1, n2, n3 )
    mesh.rotate( g.RVector3( 10.0, 34.0, 45 ) )
    mesh.scale( g.RVector3( 0.9, 0.8, 0.7 ) )

    if p2: mesh = mesh.createP2()
    
    show( mesh )
示例#11
0
def modelCavity2(area, refine=True):
    boundary = []
    boundary.append([-1.0, 0.0])  #0
    boundary.append([-1.0, -1.0])  #1

    boundary.append([-0.2, -1.0])  #2
    boundary.append([-0.2, -0.8])  #3
    boundary.append([0.2, -0.8])  #4
    boundary.append([0.2, -1.0])  #5

    boundary.append([1.0, -1.0])  #6
    boundary.append([1.0, 0.0])  #7

    boundary.append([0.2, 0.0])  #8
    boundary.append([0.2, -0.2])  #9
    boundary.append([-0.2, -0.2])  #10
    boundary.append([-0.2, 0.0])  #11

    poly = pg.Mesh(2)
    nodes = [poly.createNode(b) for b in boundary]

    eMarker = [1, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2]
    for i in range(len(nodes)):
        poly.createEdge(nodes[i], nodes[(i + 1) % len(nodes)], eMarker[i])

    if refine:
        poly.createNode([-0.21, -0.99])
    mesh = createMesh(poly, quality=34.0, area=area, smooth=[0, 10])

    # Diffusions coefficient, viscosity

    b7 = mesh.findBoundaryByMarker(2)[0]
    for b in mesh.findBoundaryByMarker(1):
        if b.center()[1] < b.center()[1]:
            b7 = b
    b7.setMarker(4)

    velBoundary = [
        [1, [1.0, 0.0]],
        [2, [0.0, 0.0]],
        [3, [1.0, 0.0]],
        [4, [0.0, 0.0]],
    ]
    preBoundary = [[4, 0.0]]

    a = pg.RVector(mesh.cellCount(), 1.0)
    return mesh, velBoundary, preBoundary, a, 50000
示例#12
0
def exportHDF5Mesh(mesh,
                   exportname,
                   group='mesh',
                   indices='cell_indices',
                   pos='coordinates',
                   cells='topology',
                   marker='values'):
    """Writes given :gimliapi:`GIMLI::Mesh` in a hdf5 format file.

    3D tetrahedron meshes only! Boundary markers are ignored.

    Keywords are explained in :py:mod:`pygimli.meshtools.readHDFS`
    """
    h5py = pg.optImport('h5py', requiredFor='export mesh in .h5 data format')

    if not isinstance(mesh, pg.Mesh):
        mesh = pg.Mesh(mesh)

    # prepare output for writing in hdf data container
    pg_pos = mesh.positions()
    mesh_pos = np.array((np.array(pg.x(pg_pos)), np.array(pg.y(pg_pos)),
                         np.array(pg.z(pg_pos)))).T

    mesh_cells = np.zeros((mesh.cellCount(), 4))  # hard coded for tetrahedrons
    for i, cell in enumerate(mesh.cells()):
        mesh_cells[i] = cell.ids()

    mesh_indices = np.arange(0, mesh.cellCount() + 1, 1, dtype=np.int64)
    mesh_markers = np.array(mesh.cellMarkers())

    with h5py.File(exportname, 'w') as out:
        for grp in np.atleast_1d(group):  # can use more than one group
            # writing indices
            idx_name = '{}/{}'.format(grp, indices)
            out.create_dataset(idx_name, data=mesh_indices, dtype=int)
            # writing node positions
            pos_name = '{}/{}'.format(grp, pos)
            out.create_dataset(pos_name, data=mesh_pos, dtype=float)
            # writing cells via indices
            cells_name = '{}/{}'.format(grp, cells)
            out.create_dataset(cells_name, data=mesh_cells, dtype=int)
            # writing marker
            marker_name = '{}/{}'.format(grp, marker)
            out.create_dataset(marker_name, data=mesh_markers, dtype=int)
            out[grp][cells].attrs['celltype'] = np.string_('tetrahedron')
            out[grp][cells].attrs.create('partition', [0])
    return True
示例#13
0
def createMesh2():
    boundary = []
    boundary.append([-20.0, 0.0])
    boundary.append([-20.0, -20.0])
    boundary.append([20.0, -20.0])
    boundary.append([20.0, 0.0])

    poly = pg.Mesh(2)
    nodes = [poly.createNode(b) for b in boundary]

    poly.createEdge(nodes[0], nodes[1], 1)  # dirichlet (inflow)
    poly.createEdge(nodes[1], nodes[2], 3)  # hom neumann (outflow)
    poly.createEdge(nodes[2], nodes[3], 2)  # hom dirichlet (isolation)
    poly.createEdge(nodes[3], nodes[0], 4)  # hom dirichlet (isolation)

    mesh = createMesh(poly, quality=34, area=0.05, smooth=[0, 10])
    return mesh
示例#14
0
def readHydrus2dMesh(fname='MESHTRIA.TXT'):
    """
    Import mesh from Hydrus2D.

    Parameters
    ----------
    fname : str, optional
        Filename of Hydrus output file.

    See Also
    --------
    readHydrus3dMesh : Similar routine for three-dimensional meshes.

    References
    ----------
    .. http://www.pc-progress.com/en/Default.aspx?h3d-description
    """
    fid = open(fname)
    line = fid.readline().split()
    nnodes = int(line[1])
    ncells = int(line[3])
    mesh = pg.Mesh()
    for _ in range(nnodes):
        line = fid.readline().split()
        mesh.createNode(
            pg.RVector3(float(line[1]) / 100.,
                        float(line[2]) / 100., 0.))

    for _ in range(3):
        line = fid.readline()

    for _ in range(ncells):
        line = fid.readline().split()
        if len(line) == 4:
            mesh.createTriangle(mesh.node(int(line[1]) - 1),
                                mesh.node(int(line[2]) - 1),
                                mesh.node(int(line[3]) - 1), 1)
        elif len(line) == 5:
            mesh.createTetrahedron(mesh.node(int(line[1]) - 1),
                                   mesh.node(int(line[2]) - 1),
                                   mesh.node(int(line[3]) - 1),
                                   mesh.node(int(line[4]) - 1), 1)

    fid.close()
    mesh.createNeighbourInfos()
    return mesh
示例#15
0
def exportHDF5Mesh(mesh,
                   exportname,
                   group='mesh',
                   indices='cell_indices',
                   pos='coordinates',
                   cells='topology',
                   marker='values'):
    '''
    3D tetrahedron meshes only! Boundary markers are ignored.

    Keywords are explained in "readH5"
    '''
    h5py = pg.io.opt_import('h5py',
                            requiredTo='export mesh in .h5 data format')
    if not isinstance(mesh, pg.Mesh):
        mesh = pg.Mesh(mesh)

    # prepare output for writing in hdf data container
    pg_pos = mesh.positions()
    mesh_pos = np.array((np.array(pg.x(pg_pos)), np.array(pg.y(pg_pos)),
                         np.array(pg.z(pg_pos)))).T

    mesh_cells = np.zeros((mesh.cellCount(), 4))  # hard coded for tetrahedrons
    for i, cell in enumerate(mesh.cells()):
        mesh_cells[i] = cell.ids()

    mesh_indices = np.arange(0, mesh.cellCount() + 1, 1, dtype=np.int64)
    mesh_markers = np.array(mesh.cellMarkers())

    with h5py.File(exportname, 'w') as out:
        # writing indices
        idx_name = '{}/{}'.format(group, indices)
        out.create_dataset(idx_name, data=mesh_indices, dtype=np.int64)
        # writing node positions
        pos_name = '{}/{}'.format(group, pos)
        out.create_dataset(pos_name, data=mesh_pos, dtype=float)
        # writing cells via indices
        cells_name = '{}/{}'.format(group, cells)
        out.create_dataset(cells_name, data=mesh_cells, dtype=np.int64)
        # writing marker
        marker_name = '{}/{}'.format(group, marker)
        out.create_dataset(marker_name, data=mesh_markers, dtype=np.uint64)
        out[group][cells].attrs['celltype'] = np.array(('tetrahedron'))
        out[group][cells].attrs['partition'] = np.array([0], dtype=np.uint64)
    return True
示例#16
0
def createLine(start, end, segments, **kwargs):
    """Create simple line polygon.

    Create simple line polygon from start to end.

    Parameters
    ----------
    start : [x, y]
        start position
    end : [x, y]
        end position
    segments : int
        Discrete amount of segments for the line

    **kwargs:

        boundaryMarker : int [1]
            Marker for the resulting boundary edges
        leftDirection : bool [True]
            Rotational direction

    Returns
    -------
    poly : gimliapi:`GIMLI::Mesh`
        The resulting polygon is a gimliapi:`GIMLI::Mesh`.

    Examples
    --------
    """
    poly = pg.Mesh(2)
    startPos = pg.RVector3(start)
    endPos = pg.RVector3(end)
    a = endPos - startPos

    dt = 1 / segments
    for i in range(0, segments + 1):
        if kwargs.pop('leftDirection', True):
            p = startPos + a * (dt * i)
        else:
            p = endPos - a * (dt * i)

        poly.createNode(p)

    polyCreateDefaultEdges_(poly, isClosed=False, **kwargs)
    return poly
示例#17
0
    def test_MeshDataAccess(self):
        mesh = pg.Mesh()
        a = pg.Vector(10, 1.0)
        b = [pg.Vector(10, 1.0)] * 3
        c = np.array(b).T

        mesh['a'] = a
        mesh['b'] = b
        mesh['v'] = c
        mesh['vs'] = [c, c, c]

        # pg.core.setDeepDebug(True)
        # pg.core.setDeepDebug(False)

        np.testing.assert_array_equal(mesh['a'], a)
        np.testing.assert_array_equal(mesh['b'], b)
        np.testing.assert_array_equal(mesh['v'], c)
        np.testing.assert_array_equal(mesh['vs'], [c, c, c])
示例#18
0
    def __init__(self,
                 mesh,
                 ertfop,
                 rstfop,
                 petromodel,
                 fix_poro=True,
                 zWeight=1,
                 verbose=True,
                 corr_l=None,
                 fix_water=False,
                 fix_ice=False,
                 fix_air=False):
        """Joint petrophysical modeling operator.

        Parameters
        ----------
        mesh : pyGIMLi mesh
        ertfop : ERT forward operator
        rstfop : RST forward operator
        petromodel : Petrophysical four-phase model
        zWeight : zWeight for more or less layering
        verbose : Be more verbose
        corr_l : tuple
            Horizontal and vertical correlation lengths. If provided,
            geostatistical regularization will be used and classical smoothing
            with zWeight will be ignored.
        fix_poro|water|ice|air : boolean or vector
            Fix to starting model or provide weight vector for particular cells.
        """
        pg.ModellingBase.__init__(self, verbose)
        self.mesh = pg.Mesh(mesh)
        self.ERT = ertfop
        self.RST = rstfop
        self.fops = [self.RST, self.ERT]
        self.fpm = petromodel
        self.cellCount = self.mesh.cellCount()
        self.fix_water = fix_water
        self.fix_ice = fix_ice
        self.fix_air = fix_air
        self.fix_poro = fix_poro
        self.zWeight = zWeight
        # self.fix_cells = fix_cells
        self.corr_l = corr_l
        self.createConstraints()
示例#19
0
def merge2Meshes(m1, m2):
    """Merge two meshes into one new mesh and return combined mesh."""
    mesh = pg.Mesh(m1)

    for c in m2.cells():
        mesh.copyCell(c)

    for b in m2.boundaries():
        mesh.copyBoundary(b)

    for key in list(mesh.exportDataMap().keys()):
        d = mesh.exportDataMap()[key]
        d.resize(mesh.cellCount())
        d.setVal(m1.exportDataMap()[key], 0, m1.cellCount())
        d.setVal(m2.exportDataMap()[key], m1.cellCount(),
                 m1.cellCount() + m2.cellCount())
        mesh.addExportData(key, d)

    return mesh
示例#20
0
def modelPipe():
    boundary = []
    #left inflow
    boundary.append([0.1, 0.0])  # 0
    boundary.append([0.0, 0.0])  # 1

    boundary.append([0.0, -1.0])
    boundary.append([0.0, -1.1])

    boundary.append([1.0, -1.1])
    boundary.append([1.0, -1.0])

    #right outflow
    boundary.append([1.0, 0.0])  # 1
    boundary.append([0.9, 0.0])  # 0

    #closing
    boundary.append([0.9, -1.0])  # 0
    boundary.append([0.1, -1.0])  # 0

    poly = pg.Mesh(2)
    nodes = [poly.createNode(b) for b in boundary]

    for i in range(len(nodes)):
        poly.createEdge(nodes[i], nodes[(i + 1) % len(nodes)], 1)
    poly.boundaries()[0].setMarker(2)

    for b in poly.boundaries():
        if b.norm()[1] == 1.0 and b.center()[0] == 0.95:
            b.setMarker(3)
        if b.norm()[1] == -1.0 and b.center()[0] == 0.5:
            b.setMarker(4)

    mesh = createMesh(poly, quality=34.0, area=0.0005, smooth=[0, 10])

    velBoundary = [[1, [0.0, 0.0]], [2, [0.0, -1.0]], [3, [0.0, 1.0]],
                   [4, [0.0, 0.0]]]

    #preBoundary=None
    preBoundary = [[4, 0.0]]

    a = 1
    return mesh, velBoundary, preBoundary, a, 400
示例#21
0
def createHolstein1999Model():
    mesh = pg.Mesh(3)

    mesh.createNode(pg.RVector3(0, 0, 0))  # dummy
    mesh.createNode(pg.RVector3(+10, 10, -12))
    mesh.createNode(pg.RVector3(+10, -10, -12))
    mesh.createNode(pg.RVector3(-10, -10, -12))
    mesh.createNode(pg.RVector3(-10, 10, -12))
    mesh.createNode(pg.RVector3(-20, 30, -12))
    mesh.createNode(pg.RVector3(+30, 30, -12))
    mesh.createNode(pg.RVector3(+20, 20, -22))
    mesh.createNode(pg.RVector3(+20, -30, -22))
    mesh.createNode(pg.RVector3(-20, -30, -22))
    mesh.createNode(pg.RVector3(-20, 20, -22))

    facets = [[1, 6, 5, 4, 3, 2], [1, 2, 8, 7], [2, 3, 9, 8], [3, 4, 10, 9],
              [4, 5, 10], [5, 6, 7, 10], [1, 7, 6], [7, 8, 9, 10]]

    return mesh, facets
示例#22
0
    def init(self, mesh, tMax, satSteps, ertSteps):
        """Initialize some settings."""

        if mesh is not None:
            self.parMesh = pg.Mesh(mesh)
            self.setMesh(mesh)
            self.createRefinedForwardMesh(refine=False, pRefine=False)

        self.tMax = tMax
        self.satSteps = satSteps
        self.ertSteps = ertSteps
        self.timesAdvection = np.linspace(1, tMax, satSteps)
        self.timesERT = pg.IndexArray(
            np.floor(
                np.linspace(0,
                            len(self.timesAdvection) - 1, self.ertSteps)))

        self._J = pg.Matrix()
        self.setJacobian(self._J)
        self.ws = WorkSpace()
示例#23
0
    def createFwdMesh_(self):
        """"""
        pg.info("Creating forward mesh from region infos.")
        m = pg.Mesh(self.regionManager().mesh())

        regionIds = self.regionManager().regionIdxs()
        for iId in regionIds:
            pg.verbose("\tRegion: {0}, Parameter: {1}, PD: {2},"
                       " Single: {3}, Background: {4}, Fixed: {5}"
                .format(iId,
                        self.regionManager().region(iId).parameterCount(),
                        self.regionManager().region(iId).isInParaDomain(),
                        self.regionManager().region(iId).isSingle(),
                        self.regionManager().region(iId).isBackground(),
                        self.regionManager().region(iId).fixValue(),
                        ))

        m = self.createRefinedFwdMesh(m)
        self.setMeshPost(m)
        self._regionChanged = False
        super(Modelling, self).setMesh(m, ignoreRegionManager=True)
示例#24
0
    def createMesh(self, quality=34.6, maxarea=0.1, addpoints=None):
        """Create (inversion) mesh by circumventing PLC"""
        data = self.dataContainer
        sx = list(pg.x(data.sensorPositions()))
        sz = list(pg.y(data.sensorPositions()))

        if addpoints is not None:
            for po in addpoints:
                sx.append(po[0])
                sz.append(po[1])

        iS = np.argsort(np.arctan2(sx - np.mean(sx), sz - np.mean(sz)))
        plc = pg.Mesh(2)
        nodes = [plc.createNode(sx[i], sz[i], 0) for i in iS]
        for i in range(len(nodes) - 1):
            plc.createEdge(nodes[i], nodes[i + 1])

        plc.createEdge(nodes[-1], nodes[0])
        tri = pg.TriangleWrapper(plc)
        tri.setSwitches("-pzFq" + str(quality) + "a" + str(maxarea))
        self.setMesh(tri.generate())
示例#25
0
    def test_zweight_2meshes(self):

        # marker = 0
        mesh = pg.meshtools.createGrid(x=np.arange(0, 4), y=np.arange(0, 3))
        mesh.setCellMarkers(np.zeros(mesh.cellCount(), dtype=int))

        # marker = 1
        mesh2 = pg.Mesh(mesh)
        mesh2.setCellMarkers(np.ones(mesh.cellCount(), dtype=int))

        together = pg.meshtools.merge2Meshes(
            mesh,
            mesh2.translate(pg.Vector([0., 0., 1.])))

        fop = pg.Modelling()

        fop.setMesh(together)
        fop.createConstraints()

        rm = fop.regionManager()

        rm.setZWeight(0.1)

        # check distribution of zWeight
        self.assertTrue(np.isclose(rm.region(0).zWeight(), 0.1))
        self.assertTrue(np.isclose(rm.region(1).zWeight(), 0.1))
        # self.assertTrue(np.isclose(rm.region(2).zWeight(), 0.1))

        w0 = rm.region(0).constraintWeights()
        w1 = rm.region(1).constraintWeights()

        # print(w0, w1)
        # w2 = rm.region(2).constraintWeights()

        # check actual constraint weight values
        self.assertTrue(np.isclose(np.min(w0), 0.1))

        # check distribution of zWeight
        self.assertTrue(np.allclose(w0, w1))
示例#26
0
def readSTL(fileName, ascii=True):
    """Read :term:`STL` surface mesh and returns a :gimliapi:`GIMLI::Mesh`.

    Read :term:`STL` surface mesh and returns a :gimliapi:`GIMLI::Mesh` 
    of triangle boundary faces. Multiple solids are supported with increasing
    boundary marker.

    TODO: ASCII=False, read binary STL

    Parameters
    ----------

    fileName : str
        name of the .stl file containing the STL surface mesh

    ascii : bool [True]
        STL Ascii format

    """
    mesh = pg.Mesh(dim=3)
    mesh.importSTL(fileName)
    return mesh
示例#27
0
    def __init__(self, data, nlay=2, verbose=False):
        """Parameters: FDEM data class and number of layers."""
        super(FDEM2dFOP, self).__init__(verbose)
        self.nlay = nlay
        self.FOP = data.FOP(nlay)
        self.nx = len(data.x)
        self.nf = len(data.freq())
        npar = 2 * nlay - 1
        self.mesh2d = pg.Mesh()
        self.mesh2d.create2DGrid(range(npar + 1), range(self.nx + 1))
        self.setMesh(self.mesh2d)

        self.J = pg.RBlockMatrix()
        self.FOP1d = []
        for i in range(self.nx):
            self.FOP1d.append(HEMmodelling(nlay, data.z[i]))
            n = self.J.addMatrix(self.FOP1d[-1].jacobian())
            self.J.addMatrixEntry(n, self.nf * 2 * i, npar * i)

        self.J.recalcMatrixSize()
        print(self.J.rows(), self.J.cols())
        self.setJacobian(self.J)
示例#28
0
def test_Refraction():
    """Test Refraction manager stability some data/mesh set / data update"""
    import os
    datafile = os.path.dirname(__file__) + '/example_topo.sgt'

    ra = Refraction(datafile, verbose=False, doSave=False)
    ra.createMesh(depth=80)
    ra.inv.setMaxIter(1)

    ra.invert()
    m1 = ra.model()
    mesh = pg.Mesh(ra.mesh)

    ra.setMesh(mesh)
    ra.invert()
    m2 = ra.model()

    np.testing.assert_array_equal(m1, m2)

    ra.setData(pg.DataContainer(datafile, 's g'))
    m3 = ra.invert()

    np.testing.assert_array_equal(m1, m3)
示例#29
0
def createMesh(poly,
               quality=30,
               area=0.0,
               smooth=None,
               switches=None,
               verbose=False,
               **kwargs):
    """Create a mesh for a given geometry polygon.

    The mesh is created by :term:`triangle` or :term:`tetgen` if the
    gimli support for these mesh generators are installed.
    The geometry needs to contain nodes and boundaries and should be valid
    in the sense that the boundaries are non intersecting.

    If poly is a list of coordinates a simple Delaunay mesh of the convex hull
    will be created.
    TODO: Tetgen support need to be implemented

    Parameters
    ----------
    poly: :gimliapi:`GIMLI::Mesh` or list
        * 2D or 3D gimli mesh that contains the PLC.
        * 2D mesh needs edges
        * 3D mesh needs ... to be implemented
        * List of x y pairs [[x0, y0], ... ,[xN, yN]]
        * PLC or list of PLC
    quality: float
        2D triangle quality sets a minimum angle constraint.
        Be careful with values above 34 degrees.
    area: float
        2D maximum triangle size in m*m
    smooth: tuple
        [smoothing algorithm, number of iterations]
        0, no smoothing
        1, node center
        2, weighted node center
    switches: str
        Force triangle to use the gives command switches.

    Returns
    -------
    mesh: :gimliapi:`GIMLI::Mesh`

    Examples
    --------
    >>> # no need to import matplotlib. pygimli's show does
    >>> import pygimli as pg
    >>> import pygimli.meshtools as mt
    >>> rect = mt.createRectangle(start=[0, 0], end=[4, 1])
    >>> ax, _ = pg.show(mt.createMesh(rect, quality=10))
    >>> ax, _ = pg.show(mt.createMesh(rect, quality=33))
    >>> ax, _ = pg.show(mt.createMesh(rect, quality=33, area=0.01))
    >>> pg.wait()
    """
    #  poly == [pg.Mesh, ]
    if isinstance(poly, list):
        if isinstance(poly[0], pg.Mesh):
            return createMesh(pg.meshtools.mergePLC(poly), quality, area,
                              smooth, switches, verbose)
    # poly == [pos, pos, ]
    if isinstance(poly, list) or isinstance(poly, type(zip)):
        delPLC = pg.Mesh(2)
        for p in poly:
            delPLC.createNode(p[0], p[1], 0.0)
        return createMesh(delPLC, switches='-zeY')

    # poly == Mesh
    if poly.dim() == 2:
        if poly.nodeCount() == 0:
            raise Exception("No nodes in poly to create a valid mesh")

        tri = pg.TriangleWrapper(poly)

        if switches is None:
            # -D Conforming delaunay
            # -F Uses Steven Fortune's sweepline algorithm
            # no -a here ignores per region area
            switches = 'pazeA'

            if area > 0:
                switches += 'a' + str(area)
                pass
            else:
                switches += 'a'

            # switches = switches.replace('.', ',')
            switches += 'q' + str(quality)

        if not verbose:
            switches += 'Q'

        if verbose:
            print(switches)

        tri.setSwitches(switches)
        mesh = tri.generate()

        if smooth is not None:
            mesh.smooth(nodeMoving=kwargs.pop('node_move', False),
                        edgeSwapping=False,
                        smoothFunction=smooth[0],
                        smoothIteration=smooth[1])
        return mesh

    else:
        raise Exception('not yet implemented')
示例#30
0
def createParaMesh2DGrid(sensors,
                         paraDX=1,
                         paraDZ=1,
                         paraDepth=0,
                         nLayers=11,
                         boundary=-1,
                         paraBoundary=2,
                         **kwargs):
    """Create a grid style mesh for an inversion parameter mesh.

    Create a grid style mesh for an inversion parameter mesh.
    Return parameter grid for a given list of sensor positions.
    Uses and forwards arguments to
    :py:mod:`pygimli.meshtools.appendTriangleBoundary`.

    Parameters
    ----------
    sensors : list of RVector3 objects or data container with sensorPositions
        Sensor positions. Must be sorted in positive x direction
    paraDX : float, optional
        Horizontal distance between sensors, relative regarding sensor
        distance. Value must be greater than 0 otherwise 1 is assumed.
    paraDZ : float, optional
        Vertical distance to the first depth layer, relative regarding sensor
        distance. Value must be greater than 0 otherwise 1 is assumed.
    paraDepth : float, optional
        Maximum depth for parametric domain, 0 (default) means 0.4 * maximum
        sensor range.
    nLayers : int, optional [11]
        Number of depth layers.
    boundary : int, optional [-1]
        Boundary width to be appended for domain prolongation in absolute
        para domain width.
        Values lower than 0 force the boundary to be 4 times para domain width.
    paraBoundary : int, optional [2]
        Offset to the parameter domain boundary in absolute sensor spacing.

    Returns
    -------
    mesh: :gimliapi:`GIMLI::Mesh`

    Examples
    --------
    >>> import pygimli as pg
    >>> import matplotlib.pyplot as plt
    >>>
    >>> from pygimli.meshtools import createParaMesh2DGrid
    >>> mesh = createParaMesh2DGrid(sensors=pg.RVector(range(10)),
    ...                             boundary=1, paraDX=1,
    ...                             paraDZ=1, paraDepth=5)
    >>> ax, _ = pg.show(mesh, mesh.cellMarkers(), alpha=0.3, cmap="summer",
    ...                 hold=True)
    >>> ax, _ = pg.show(mesh, ax=ax)
    """
    mesh = pg.Mesh(2)

    # maybe separate x y z and sort
    if isinstance(sensors, np.ndarray) or isinstance(sensors, pg.RVector):
        sensors = [pg.RVector3(s, 0) for s in sensors]

    sensorX = pg.x(sensors)

    eSpacing = abs(sensorX[1] - sensorX[0])

    xmin = min(sensorX) - paraBoundary * eSpacing
    xmax = max(sensorX) + paraBoundary * eSpacing

    if paraDX == 0:
        paraDX = 1.
    if paraDZ == 0:
        paraDZ = 1.

    dx = eSpacing * paraDX
    dz = eSpacing * paraDZ

    if paraDepth == 0:
        paraDepth = 0.4 * (xmax - xmin)

    x = pg.utils.grange(xmin, xmax, dx=dx)

    y = -pg.increasingRange(dz, paraDepth, nLayers)

    mesh.createGrid(x, y)
    mesh.setCellMarkers([2] * mesh.cellCount())

    paraXLimits = [xmin, xmax]
    #    paraYLimits = [min(y), max(y)]  # not used

    if boundary < 0:
        boundary = abs((paraXLimits[1] - paraXLimits[0]) * 4.0)

    mesh = pg.meshtools.appendTriangleBoundary(mesh,
                                               xbound=boundary,
                                               ybound=boundary,
                                               marker=1,
                                               **kwargs)

    return mesh