Example #1
0
def savevtk(name, mesh):
    """
    SAVEVTK: save a JIGSAW MSH object to file.

    SAVEVTK(NAME, MESH)

    MESH is JIGSAW's primary mesh/grid/geom class. See MSH_t
    for details.

    Data in MESH is written as-needed -- any objects defined
    will be saved to file.

    """

    if (not isinstance(name, str)):
        raise Exception("Incorrect type: NAME.")

    if (not isinstance(mesh, jigsaw_msh_t)):
        raise Exception("Incorrect type: MESH.")

    certify(mesh)

    fext = Path(name).suffix

    if (fext.strip() != ".vtk"):
        name = name + ".vtk"

    kind = mesh.mshID.lower()

    with Path(name).open("w") as fptr:
        #----------------------------------- write JIGSAW object
        if (kind == "euclidean-mesh"):

            save_mesh_file(mesh, fptr)

        elif (kind == "ellipsoid-mesh"):

            save_mesh_file(mesh, fptr)

        elif (kind == "euclidean-grid"):

            save_grid_file(mesh, fptr)

        elif (kind == "ellipsoid-grid"):

            save_grid_file(mesh, fptr)

        else:
            raise Exception("MESH.mshID is not supported!!")

    return
Example #2
0
def savemsh(name, mesh):
    """
    SAVEMSH: save a JIGSAW MSH object to file.

    SAVEMSH(NAME, MESH)

    MESH is JIGSAW's primary mesh/grid/geom class. See MSH_t
    for details.

    Data in MESH is written as-needed -- any objects defined
    will be saved to file.

    """

    if (not isinstance(name, str)):
        raise Exception("Incorrect type: NAME.")

    if (not isinstance(mesh, jigsaw_msh_t)):
        raise Exception("Incorrect type: MESH.")

    nver = +3

    certify(mesh)

    fext = Path(name).suffix

    if (fext.strip() != ".msh"):
        name = name + ".msh"

    kind = mesh.mshID.lower()

    with Path(name).open("w") as fptr:
        #----------------------------------- write JIGSAW object
        fptr.write("# " + Path(name).name +
                   "; created by JIGSAW's PYTHON interface \n")

        if (kind == "euclidean-mesh"):
            save_mesh_file(mesh, fptr, nver, "euclidean-mesh")

        if (kind == "euclidean-grid"):
            save_grid_file(mesh, fptr, nver, "euclidean-grid")

        if (kind == "ellipsoid-mesh"):
            save_mesh_file(mesh, fptr, nver, "ellipsoid-mesh")

        if (kind == "ellipsoid-grid"):
            save_grid_file(mesh, fptr, nver, "ellipsoid-grid")

    return
Example #3
0
def put_msh_t(msht, mshl):
    """
    PUT-MSH_t: Assign ptrs from python-to-ctypes objects.

    """
    if (msht is None): return

    certify(msht)

    if (msht.mshID is not None):
        #--------------------------------- assign mshID variable
        istr = msht.mshID.lower()

        if (istr == "euclidean-mesh"):
            mshl.flags = \
                defs.JIGSAW_EUCLIDEAN_MESH

        if (istr == "euclidean-grid"):
            mshl.flags = \
                defs.JIGSAW_EUCLIDEAN_GRID

        if (istr == "ellipsoid-mesh"):
            mshl.flags = \
                defs.JIGSAW_ELLIPSOID_MESH

        if (istr == "ellipsoid-grid"):
            mshl.flags = \
                defs.JIGSAW_ELLIPSOID_GRID

    if (msht.radii is not None and msht.radii.size != +0):
        #--------------------------------- assign ptrs for RADII
        mshl.radii.size = msht.radii.size
        mshl.radii.data = \
            put_ptr_t(msht.radii, real_t)

    if (msht.vert2 is not None and msht.vert2.size != +0):
        #--------------------------------- assign ptrs for VERT2
        mshl.vert2.size = msht.vert2.size
        mshl.vert2.data = put_ptr_t(msht.vert2, libsaw_VERT2_t)

    if (msht.vert3 is not None and msht.vert3.size != +0):
        #--------------------------------- assign ptrs for VERT3
        mshl.vert3.size = msht.vert3.size
        mshl.vert3.data = put_ptr_t(msht.vert3, libsaw_VERT3_t)

    if (msht.power is not None and msht.power.size != +0):
        #--------------------------------- assign ptrs for POWER
        mshl.power.size = msht.power.size
        mshl.power.data = \
            put_ptr_t(msht.power, real_t)

    if (msht.edge2 is not None and msht.edge2.size != +0):
        #--------------------------------- assign ptrs for EDGE2
        mshl.edge2.size = msht.edge2.size
        mshl.edge2.data = put_ptr_t(msht.edge2, libsaw_EDGE2_t)

    if (msht.tria3 is not None and msht.tria3.size != +0):
        #--------------------------------- assign ptrs for TRIA3
        mshl.tria3.size = msht.tria3.size
        mshl.tria3.data = put_ptr_t(msht.tria3, libsaw_TRIA3_t)

    if (msht.quad4 is not None and msht.quad4.size != +0):
        #--------------------------------- assign ptrs for QUAD4
        mshl.quad4.size = msht.quad4.size
        mshl.quad4.data = put_ptr_t(msht.quad4, libsaw_QUAD4_t)

    if (msht.tria4 is not None and msht.tria4.size != +0):
        #--------------------------------- assign ptrs for TRIA4
        mshl.tria4.size = msht.tria4.size
        mshl.tria4.data = put_ptr_t(msht.tria4, libsaw_TRIA4_t)

    if (msht.hexa8 is not None and msht.hexa8.size != +0):
        #--------------------------------- assign ptrs for HEXA8
        mshl.hexa8.size = msht.hexa8.size
        mshl.hexa8.data = put_ptr_t(msht.hexa8, libsaw_HEXA8_t)

    if (msht.wedg6 is not None and msht.wedg6.size != +0):
        #--------------------------------- assign ptrs for WEDG6
        mshl.wedg6.size = msht.wedg6.size
        mshl.wedg6.data = put_ptr_t(msht.wedg6, libsaw_WEDG6_t)

    if (msht.pyra5 is not None and msht.pyra5.size != +0):
        #--------------------------------- assign ptrs for PYRA5
        mshl.pyra5.size = msht.pyra5.size
        mshl.pyra5.data = put_ptr_t(msht.pyra5, libsaw_PYRA5_t)

    if (msht.bound is not None and msht.bound.size != +0):
        #--------------------------------- assign ptrs for BOUND
        mshl.bound.size = msht.bound.size
        mshl.bound.data = put_ptr_t(msht.bound, libsaw_BOUND_t)

    if (msht.xgrid is not None and msht.xgrid.size != +0):
        #--------------------------------- assign ptrs for XGRID
        mshl.xgrid.size = msht.xgrid.size
        mshl.xgrid.data = \
            put_ptr_t(msht.xgrid, real_t)

    if (msht.ygrid is not None and msht.ygrid.size != +0):
        #--------------------------------- assign ptrs for YGRID
        mshl.ygrid.size = msht.ygrid.size
        mshl.ygrid.data = \
            put_ptr_t(msht.ygrid, real_t)

    if (msht.zgrid is not None and msht.zgrid.size != +0):
        #--------------------------------- assign ptrs for ZGRID
        mshl.zgrid.size = msht.zgrid.size
        mshl.zgrid.data = \
            put_ptr_t(msht.zgrid, real_t)

    if (msht.value is not None and msht.value.size != +0):
        #--------------------------------- assign ptrs for VALUE
        mshl.value.size = msht.value.size
        mshl.value.data = \
            put_ptr_t(msht.value, real_t)

    if (msht.slope is not None and msht.slope.size != +0):
        #--------------------------------- assign ptrs for SLOPE
        mshl.slope.size = msht.slope.size
        mshl.slope.data = \
            put_ptr_t(msht.slope, real_t)

    return
Example #4
0
def bisect(mesh):
    """
    BISECT: perform uniform bisection of a mesh object.

    """

    if (not isinstance(mesh, jigsaw_msh_t)):
        raise Exception("Incorrect type: MESH.")

    certify(mesh)

    if (mesh.point is None): return

    #------------------------------ map elements to unique edges
    edge = np.empty((0, 2), dtype=np.int32)
    emap = mapper()
    quad = np.empty((0, 4), dtype=np.int32)
    qmap = mapper()
    hexa = np.empty((0, 8), dtype=np.int32)
    #   hmap = mapper()

    if (mesh.edge2 is not None and mesh.edge2.size != +0):
        #-------------------------- map EDGE2's onto JOIN arrays
        nedg = edge.shape[0]
        ncel = mesh.edge2.shape[0]

        cell = mesh.edge2["index"]

        edge = np.concatenate((edge, cell[:, (0, 1)]), axis=0)

        indx = np.arange(0, ncel)

        emap.edge2.index = \
            np.empty((ncel, 1), dtype=np.int32)
        emap.edge2.index[:, 0] = \
            indx + ncel * 0 + nedg

    if (mesh.tria3 is not None and mesh.tria3.size != +0):
        #-------------------------- map TRIA3's onto JOIN arrays
        nedg = edge.shape[0]
        ncel = mesh.tria3.shape[0]

        cell = mesh.tria3["index"]

        edge = np.concatenate((edge, cell[:, (0, 1)]), axis=0)
        edge = np.concatenate((edge, cell[:, (1, 2)]), axis=0)
        edge = np.concatenate((edge, cell[:, (2, 0)]), axis=0)

        indx = np.arange(0, ncel)

        emap.tria3.index = \
            np.empty((ncel, 3), dtype=np.int32)
        emap.tria3.index[:, 0] = \
            indx + ncel * 0 + nedg
        emap.tria3.index[:, 1] = \
            indx + ncel * 1 + nedg
        emap.tria3.index[:, 2] = \
            indx + ncel * 2 + nedg

    if (mesh.quad4 is not None and mesh.quad4.size != +0):
        #-------------------------- map QUAD4's onto JOIN arrays
        nedg = edge.shape[0]
        nfac = quad.shape[0]
        ncel = mesh.quad4.shape[0]

        cell = mesh.quad4["index"]

        quad = np.concatenate((quad, cell[:, +0:+4]), axis=0)

        edge = np.concatenate((edge, cell[:, (0, 1)]), axis=0)
        edge = np.concatenate((edge, cell[:, (1, 2)]), axis=0)
        edge = np.concatenate((edge, cell[:, (2, 3)]), axis=0)
        edge = np.concatenate((edge, cell[:, (3, 0)]), axis=0)

        indx = np.arange(0, ncel)

        qmap.quad4.index = \
            np.empty((ncel, 1), dtype=np.int32)
        qmap.quad4.index[:, 0] = \
            indx + ncel * 0 + nfac

        emap.quad4.index = \
            np.empty((ncel, 4), dtype=np.int32)
        emap.quad4.index[:, 0] = \
            indx + ncel * 0 + nedg
        emap.quad4.index[:, 1] = \
            indx + ncel * 1 + nedg
        emap.quad4.index[:, 2] = \
            indx + ncel * 2 + nedg
        emap.quad4.index[:, 3] = \
            indx + ncel * 3 + nedg

    if (mesh.tria4 is not None and mesh.tria4.size != +0):
        #-------------------------- map TRIA4's onto JOIN arrays
        nedg = edge.shape[0]
        ncel = mesh.tria4.shape[0]

        cell = mesh.tria4["index"]

        edge = np.concatenate((edge, cell[:, (0, 1)]), axis=0)
        edge = np.concatenate((edge, cell[:, (1, 2)]), axis=0)
        edge = np.concatenate((edge, cell[:, (2, 0)]), axis=0)
        edge = np.concatenate((edge, cell[:, (0, 3)]), axis=0)
        edge = np.concatenate((edge, cell[:, (1, 3)]), axis=0)
        edge = np.concatenate((edge, cell[:, (2, 3)]), axis=0)

        indx = np.arange(0, ncel)

        emap.tria4.index = \
            np.empty((ncel, 6), dtype=np.int32)
        emap.tria4.index[:, 0] = \
            indx + ncel * 0 + nedg
        emap.tria4.index[:, 1] = \
            indx + ncel * 1 + nedg
        emap.tria4.index[:, 2] = \
            indx + ncel * 2 + nedg
        emap.tria4.index[:, 3] = \
            indx + ncel * 3 + nedg
        emap.tria4.index[:, 4] = \
            indx + ncel * 4 + nedg
        emap.tria4.index[:, 5] = \
            indx + ncel * 5 + nedg

    if (mesh.hexa8 is not None and mesh.hexa8.size != +0):
        #-------------------------- map HEXA8's onto JOIN arrays
        warnings.warn("HEXA8 is not unsupported", Warning)

    if (mesh.wedg6 is not None and mesh.wedg6.size != +0):
        #-------------------------- map WEDG6's onto JOIN arrays
        warnings.warn("WEDG6 is not unsupported", Warning)

    if (mesh.pyra5 is not None and mesh.pyra5.size != +0):
        #-------------------------- map PYRA5's onto JOIN arrays
        warnings.warn("PYRA5 is not unsupported", Warning)

#------------------------------ unique joins and re-indexing
    if (edge.size != 0):
        __, efwd, erev = np.unique(np.sort(edge, axis=+1),
                                   return_index=True,
                                   return_inverse=True,
                                   axis=0)

        edge = edge[efwd, :]

    if (quad.size != 0):
        __, qfwd, qrev = np.unique(np.sort(quad, axis=+1),
                                   return_index=True,
                                   return_inverse=True,
                                   axis=0)

        quad = quad[qfwd, :]

    if (hexa.size != 0):
        __, hfwd, hrev = np.unique(np.sort(hexa, axis=+1),
                                   return_index=True,
                                   return_inverse=True,
                                   axis=0)

        hexa = hexa[hfwd, :]

#------------------------------ map unique joins to elements
    if (mesh.edge2 is not None and mesh.edge2.size != +0):
        emap.edge2.index[:, 0] = \
            erev[emap.edge2.index[:, 0]]

    if (mesh.tria3 is not None and mesh.tria3.size != +0):
        emap.tria3.index[:, 0] = \
            erev[emap.tria3.index[:, 0]]
        emap.tria3.index[:, 1] = \
            erev[emap.tria3.index[:, 1]]
        emap.tria3.index[:, 2] = \
            erev[emap.tria3.index[:, 2]]

    if (mesh.quad4 is not None and mesh.quad4.size != +0):
        qmap.quad4.index[:, 0] = \
            qrev[emap.quad4.index[:, 0]]

        emap.quad4.index[:, 0] = \
            erev[emap.quad4.index[:, 0]]
        emap.quad4.index[:, 1] = \
            erev[emap.quad4.index[:, 1]]
        emap.quad4.index[:, 2] = \
            erev[emap.quad4.index[:, 2]]
        emap.quad4.index[:, 3] = \
            erev[emap.quad4.index[:, 3]]

    if (mesh.tria4 is not None and mesh.tria4.size != +0):
        emap.tria4.index[:, 0] = \
            erev[emap.tria4.index[:, 0]]
        emap.tria4.index[:, 1] = \
            erev[emap.tria4.index[:, 1]]
        emap.tria4.index[:, 2] = \
            erev[emap.tria4.index[:, 2]]
        emap.tria4.index[:, 3] = \
            erev[emap.tria4.index[:, 3]]
        emap.tria4.index[:, 4] = \
            erev[emap.tria4.index[:, 4]]
        emap.tria4.index[:, 5] = \
            erev[emap.tria4.index[:, 5]]

#------------------------------ create new midpoint vertices
    enew = np.empty((0), dtype=np.int32)
    qnew = np.empty((0), dtype=np.int32)
    hnew = np.empty((0), dtype=np.int32)

    if (edge.size != +0):
        #-------------------------- create new vertices for EDGE
        if (mesh.point is not None and mesh.point.size != +0):

            vert = mesh.point["coord"]
            itag = mesh.point["IDtag"]

            emid = \
                vert[edge[:, 0], :] + \
                vert[edge[:, 1], :]
            emid = emid / +2.0

            imid = itag[edge[:, 0]]

            nold = np.size(vert, 0)
            nnew = np.size(emid, 0)

            enew = nold + np.arange(+0, nnew)

            vnew = np.empty(nnew, dtype=mesh.point.dtype)

            vnew["coord"] = emid
            vnew["IDtag"] = imid

            mesh.point = np.concatenate((mesh.point, vnew), axis=0)

    if (quad.size != +0):
        #-------------------------- create new vertices for QUAD
        if (mesh.point is not None and mesh.point.size != +0):

            vert = mesh.point["coord"]
            itag = mesh.point["IDtag"]

            qmid = \
                vert[quad[:, 0], :] + \
                vert[quad[:, 1], :] + \
                vert[quad[:, 2], :] + \
                vert[quad[:, 3], :]
            qmid = qmid / +4.0

            imid = itag[quad[:, 0]]

            nold = np.size(vert, 0)
            nnew = np.size(qmid, 0)

            qnew = nold + np.arange(+0, nnew)

            vnew = np.empty(nnew, dtype=mesh.point.dtype)

            vnew["coord"] = qmid
            vnew["IDtag"] = imid

            mesh.point = np.concatenate((mesh.point, vnew), axis=0)

    if (hexa.size != +0):
        #-------------------------- create new vertices for HEXA
        if (mesh.point is not None and mesh.point.size != +0):

            vert = mesh.point["coord"]
            itag = mesh.point["IDtag"]

            hmid = \
                vert[hexa[:, 0], :] + \
                vert[hexa[:, 1], :] + \
                vert[hexa[:, 2], :] + \
                vert[hexa[:, 3], :] + \
                vert[hexa[:, 4], :] + \
                vert[hexa[:, 5], :] + \
                vert[hexa[:, 6], :] + \
                vert[hexa[:, 7], :]
            hmid = hmid / +8.0

            imid = itag[hexa[:, 0]]

            nold = np.size(vert, 0)
            nnew = np.size(hmid, 0)

            hnew = nold + np.arange(+0, nnew)

            vnew = np.empty(nnew, dtype=mesh.point.dtype)

            vnew["coord"] = hmid
            vnew["IDtag"] = imid

            mesh.point = np.concatenate((mesh.point, vnew), axis=0)

    if (mesh.edge2 is not None and mesh.edge2.size != +0):
        #------------------------------ create new indexes for EDGE2
        node1 = mesh.edge2["index"][:, 0]
        node2 = mesh.edge2["index"][:, 1]

        node3 = \
            enew[emap.edge2.index[:, 0]]

        edgeA = np.empty((mesh.edge2.shape[0]), dtype=jigsaw_msh_t.EDGE2_t)

        edgeA["index"][:, 0] = node1
        edgeA["index"][:, 1] = node3
        edgeA["IDtag"] = mesh.edge2["IDtag"]

        edgeB = np.empty((mesh.edge2.shape[0]), dtype=jigsaw_msh_t.EDGE2_t)

        edgeB["index"][:, 0] = node3
        edgeB["index"][:, 1] = node2
        edgeB["IDtag"] = mesh.edge2["IDtag"]

        mesh.edge2 = np.concatenate((edgeA, edgeB), axis=+0)

    if (mesh.tria3 is not None and mesh.tria3.size != +0):
        #------------------------------ create new indexes for TRIA3
        node1 = mesh.tria3["index"][:, 0]
        node2 = mesh.tria3["index"][:, 1]
        node3 = mesh.tria3["index"][:, 2]

        node4 = \
            enew[emap.tria3.index[:, 0]]
        node5 = \
            enew[emap.tria3.index[:, 1]]
        node6 = \
            enew[emap.tria3.index[:, 2]]

        triaA = np.empty((mesh.tria3.shape[0]), dtype=jigsaw_msh_t.TRIA3_t)

        triaA["index"][:, 0] = node1
        triaA["index"][:, 1] = node4
        triaA["index"][:, 2] = node6
        triaA["IDtag"] = mesh.tria3["IDtag"]

        triaB = np.empty((mesh.tria3.shape[0]), dtype=jigsaw_msh_t.TRIA3_t)

        triaB["index"][:, 0] = node2
        triaB["index"][:, 1] = node5
        triaB["index"][:, 2] = node4
        triaB["IDtag"] = mesh.tria3["IDtag"]

        triaC = np.empty((mesh.tria3.shape[0]), dtype=jigsaw_msh_t.TRIA3_t)

        triaC["index"][:, 0] = node3
        triaC["index"][:, 1] = node6
        triaC["index"][:, 2] = node5
        triaC["IDtag"] = mesh.tria3["IDtag"]

        triaD = np.empty((mesh.tria3.shape[0]), dtype=jigsaw_msh_t.TRIA3_t)

        triaD["index"][:, 0] = node4
        triaD["index"][:, 1] = node5
        triaD["index"][:, 2] = node6
        triaD["IDtag"] = mesh.tria3["IDtag"]

        mesh.tria3 = np.concatenate((triaA, triaB, triaC, triaD), axis=+0)

    if (mesh.quad4 is not None and mesh.quad4.size != +0):
        #------------------------------ create new indexes for QUAD4
        node1 = mesh.quad4["index"][:, 0]
        node2 = mesh.quad4["index"][:, 1]
        node3 = mesh.quad4["index"][:, 2]
        node4 = mesh.quad4["index"][:, 3]

        node5 = \
            enew[emap.quad4.index[:, 0]]
        node6 = \
            enew[emap.quad4.index[:, 1]]
        node7 = \
            enew[emap.quad4.index[:, 2]]
        node8 = \
            enew[emap.quad4.index[:, 3]]

        node9 = \
            qnew[qmap.quad4.index[:, 0]]

        quadA = np.empty((mesh.quad4.shape[0]), dtype=jigsaw_msh_t.QUAD4_t)

        quadA["index"][:, 0] = node1
        quadA["index"][:, 1] = node5
        quadA["index"][:, 2] = node9
        quadA["index"][:, 3] = node8
        quadA["IDtag"] = mesh.quad4["IDtag"]

        quadB = np.empty((mesh.quad4.shape[0]), dtype=jigsaw_msh_t.QUAD4_t)

        quadB["index"][:, 0] = node2
        quadB["index"][:, 1] = node6
        quadB["index"][:, 2] = node9
        quadB["index"][:, 3] = node5
        quadB["IDtag"] = mesh.quad4["IDtag"]

        quadC = np.empty((mesh.quad4.shape[0]), dtype=jigsaw_msh_t.QUAD4_t)

        quadC["index"][:, 0] = node3
        quadC["index"][:, 1] = node7
        quadC["index"][:, 2] = node9
        quadC["index"][:, 3] = node6
        quadC["IDtag"] = mesh.quad4["IDtag"]

        quadD = np.empty((mesh.quad4.shape[0]), dtype=jigsaw_msh_t.QUAD4_t)

        quadD["index"][:, 0] = node4
        quadD["index"][:, 1] = node8
        quadD["index"][:, 2] = node9
        quadD["index"][:, 3] = node7
        quadD["IDtag"] = mesh.quad4["IDtag"]

        mesh.quad4 = np.concatenate((quadA, quadB, quadC, quadD), axis=+0)

    if (mesh.tria4 is not None and mesh.tria4.size != +0):
        #------------------------------ create new indexes for TRIA4
        node1 = mesh.tria4["index"][:, 0]
        node2 = mesh.tria4["index"][:, 1]
        node3 = mesh.tria4["index"][:, 2]
        node4 = mesh.tria4["index"][:, 3]

        nodeA = \
            enew[emap.tria4.index[:, 0]]
        nodeB = \
            enew[emap.tria4.index[:, 1]]
        nodeC = \
            enew[emap.tria4.index[:, 2]]
        nodeD = \
            enew[emap.tria4.index[:, 3]]
        nodeE = \
            enew[emap.tria4.index[:, 4]]
        nodeF = \
            enew[emap.tria4.index[:, 5]]

        verts = mesh.point

        # 1st subdiv. of octahedron
        triaA = np.empty((mesh.tria4.shape[0]), dtype=jigsaw_msh_t.TRIA4_t)

        triaA["index"][:, 0] = nodeC
        triaA["index"][:, 1] = nodeE
        triaA["index"][:, 2] = nodeA
        triaA["index"][:, 3] = nodeB
        triaA["IDtag"] = mesh.tria4["IDtag"]

        triaB = np.empty((mesh.tria4.shape[0]), dtype=jigsaw_msh_t.TRIA4_t)

        triaB["index"][:, 0] = nodeC
        triaB["index"][:, 1] = nodeE
        triaB["index"][:, 2] = nodeB
        triaB["index"][:, 3] = nodeF
        triaB["IDtag"] = mesh.tria4["IDtag"]

        triaC = np.empty((mesh.tria4.shape[0]), dtype=jigsaw_msh_t.TRIA4_t)

        triaC["index"][:, 0] = nodeC
        triaC["index"][:, 1] = nodeE
        triaC["index"][:, 2] = nodeF
        triaC["index"][:, 3] = nodeD
        triaC["IDtag"] = mesh.tria4["IDtag"]

        triaD = np.empty((mesh.tria4.shape[0]), dtype=jigsaw_msh_t.TRIA4_t)

        triaD["index"][:, 0] = nodeC
        triaD["index"][:, 1] = nodeE
        triaD["index"][:, 2] = nodeD
        triaD["index"][:, 3] = nodeA
        triaD["IDtag"] = mesh.tria4["IDtag"]

        costA = triscr3(verts["coord"], triaA["index"])
        costB = triscr3(verts["coord"], triaB["index"])
        costC = triscr3(verts["coord"], triaC["index"])
        costD = triscr3(verts["coord"], triaD["index"])

        cost1 = np.minimum(costA, costB)
        cost1 = np.minimum(cost1, costC)
        cost1 = np.minimum(cost1, costD)

        # 2nd subdiv. of octahedron
        triaE = np.empty((mesh.tria4.shape[0]), dtype=jigsaw_msh_t.TRIA4_t)

        triaE["index"][:, 0] = nodeA
        triaE["index"][:, 1] = nodeF
        triaE["index"][:, 2] = nodeE
        triaE["index"][:, 3] = nodeB
        triaE["IDtag"] = mesh.tria4["IDtag"]

        triaF = np.empty((mesh.tria4.shape[0]), dtype=jigsaw_msh_t.TRIA4_t)

        triaF["index"][:, 0] = nodeA
        triaF["index"][:, 1] = nodeF
        triaF["index"][:, 2] = nodeB
        triaF["index"][:, 3] = nodeC
        triaF["IDtag"] = mesh.tria4["IDtag"]

        triaG = np.empty((mesh.tria4.shape[0]), dtype=jigsaw_msh_t.TRIA4_t)

        triaG["index"][:, 0] = nodeA
        triaG["index"][:, 1] = nodeF
        triaG["index"][:, 2] = nodeC
        triaG["index"][:, 3] = nodeD
        triaG["IDtag"] = mesh.tria4["IDtag"]

        triaH = np.empty((mesh.tria4.shape[0]), dtype=jigsaw_msh_t.TRIA4_t)

        triaH["index"][:, 0] = nodeA
        triaH["index"][:, 1] = nodeF
        triaH["index"][:, 2] = nodeD
        triaH["index"][:, 3] = nodeE
        triaH["IDtag"] = mesh.tria4["IDtag"]

        costE = triscr3(verts["coord"], triaE["index"])
        costF = triscr3(verts["coord"], triaF["index"])
        costG = triscr3(verts["coord"], triaG["index"])
        costH = triscr3(verts["coord"], triaH["index"])

        cost2 = np.minimum(costE, costF)
        cost2 = np.minimum(cost2, costG)
        cost2 = np.minimum(cost2, costH)

        # 3rd subdiv. of octahedron
        triaI = np.empty((mesh.tria4.shape[0]), dtype=jigsaw_msh_t.TRIA4_t)

        triaI["index"][:, 0] = nodeB
        triaI["index"][:, 1] = nodeD
        triaI["index"][:, 2] = nodeA
        triaI["index"][:, 3] = nodeE
        triaI["IDtag"] = mesh.tria4["IDtag"]

        triaJ = np.empty((mesh.tria4.shape[0]), dtype=jigsaw_msh_t.TRIA4_t)

        triaJ["index"][:, 0] = nodeB
        triaJ["index"][:, 1] = nodeD
        triaJ["index"][:, 2] = nodeE
        triaJ["index"][:, 3] = nodeF
        triaJ["IDtag"] = mesh.tria4["IDtag"]

        triaK = np.empty((mesh.tria4.shape[0]), dtype=jigsaw_msh_t.TRIA4_t)

        triaK["index"][:, 0] = nodeB
        triaK["index"][:, 1] = nodeD
        triaK["index"][:, 2] = nodeF
        triaK["index"][:, 3] = nodeC
        triaK["IDtag"] = mesh.tria4["IDtag"]

        triaL = np.empty((mesh.tria4.shape[0]), dtype=jigsaw_msh_t.TRIA4_t)

        triaL["index"][:, 0] = nodeB
        triaL["index"][:, 1] = nodeD
        triaL["index"][:, 2] = nodeC
        triaL["index"][:, 3] = nodeA
        triaL["IDtag"] = mesh.tria4["IDtag"]

        costI = triscr3(verts["coord"], triaI["index"])
        costJ = triscr3(verts["coord"], triaJ["index"])
        costK = triscr3(verts["coord"], triaK["index"])
        costL = triscr3(verts["coord"], triaL["index"])

        cost3 = np.minimum(costI, costJ)
        cost3 = np.minimum(cost3, costK)
        cost3 = np.minimum(cost3, costL)

        # 4 cells in tetra. corners
        tria1 = np.empty((mesh.tria4.shape[0]), dtype=jigsaw_msh_t.TRIA4_t)

        tria1["index"][:, 0] = node1
        tria1["index"][:, 1] = nodeA
        tria1["index"][:, 2] = nodeC
        tria1["index"][:, 3] = nodeD
        tria1["IDtag"] = mesh.tria4["IDtag"]

        tria2 = np.empty((mesh.tria4.shape[0]), dtype=jigsaw_msh_t.TRIA4_t)

        tria2["index"][:, 0] = node2
        tria2["index"][:, 1] = nodeB
        tria2["index"][:, 2] = nodeA
        tria2["index"][:, 3] = nodeE
        tria2["IDtag"] = mesh.tria4["IDtag"]

        tria3 = np.empty((mesh.tria4.shape[0]), dtype=jigsaw_msh_t.TRIA4_t)

        tria3["index"][:, 0] = node3
        tria3["index"][:, 1] = nodeC
        tria3["index"][:, 2] = nodeB
        tria3["index"][:, 3] = nodeF
        tria3["IDtag"] = mesh.tria4["IDtag"]

        tria4 = np.empty((mesh.tria4.shape[0]), dtype=jigsaw_msh_t.TRIA4_t)

        tria4["index"][:, 0] = nodeD
        tria4["index"][:, 1] = nodeE
        tria4["index"][:, 2] = nodeF
        tria4["index"][:, 3] = node4
        tria4["IDtag"] = mesh.tria4["IDtag"]

        # subdiv. with max(min(scr))
        index = np.argsort(np.stack((cost1, cost2, cost3), axis=1), axis=1)

        mesh.tria4 = np.concatenate(
            (
                tria1,
                tria2,
                tria3,
                tria4,
                triaA[index[:, 2] == 0],  # subdiv. 1
                triaB[index[:, 2] == 0],
                triaC[index[:, 2] == 0],
                triaD[index[:, 2] == 0],
                triaE[index[:, 2] == 1],  # subdiv. 2
                triaF[index[:, 2] == 1],
                triaG[index[:, 2] == 1],
                triaH[index[:, 2] == 1],
                triaI[index[:, 2] == 2],  # subdiv. 3
                triaJ[index[:, 2] == 2],
                triaK[index[:, 2] == 2],
                triaL[index[:, 2] == 2]),
            axis=0)

    return
Example #5
0
def savemsh(name, mesh, tags=None):
    """
    SAVEMSH: save a JIGSAW MSH object to file.

    SAVEMSH(NAME, MESH)

    MESH is JIGSAW's primary mesh/grid/geom class. See MSH_t
    for details.

    Data in MESH is written as-needed -- any objects defined
    will be saved to file.

    """

    if (not isinstance(name, str)):
        raise Exception("Incorrect type: NAME.")

    if (not isinstance(mesh, jigsaw_msh_t)):
        raise Exception("Incorrect type: MESH.")

    certify(mesh)

    class stub(object):
        pass

    args = stub()  ## savmsh params
    args.kind = "ascii"
    args.nver = +3
    args.prec = +17
    args.real = "f64"
    args.ints = "i32"

    fext = Path(name).suffix

    if (fext.strip() != ".msh"): name += ".msh"

    kind = mesh.mshID.lower()

    if (tags is not None):
        #----------------------------------- parse savmsh params
        stag = tags.lower().split(";")
        for this in stag:
            if "precision" in this:
                args.prec = this.split("=")[1]
                args.prec = int(args.prec)

            if "real:type" in this:
                args.real = this.split("=")[1]

            if "ints:type" in this:
                args.ints = this.split("=")[1]

            if "binary" in this:
                args.kind = "binary"

    with Path(name).open("w") as fptr:
        #----------------------------------- write JIGSAW object
        fptr.write("# " + Path(name).name +
                   "; created by JIGSAW's PYTHON interface \n")

        if (kind == "euclidean-mesh"):
            save_mesh_file(mesh, fptr, args, "euclidean-mesh")

        if (kind == "euclidean-grid"):
            save_grid_file(mesh, fptr, args, "euclidean-grid")

        if (kind == "ellipsoid-mesh"):
            save_mesh_file(mesh, fptr, args, "ellipsoid-mesh")

        if (kind == "ellipsoid-grid"):
            save_grid_file(mesh, fptr, args, "ellipsoid-grid")

    return
Example #6
0
def project(mesh, proj, sign):
    """
    PROJECT cartographic projections for JIGSAW MSH objects.

    PROJECT(MESH,PROJ,SIGN) returns the projected mesh
    object MESH resulting from application of the projection
    operator PROJ to the input object MESH. SIGN is a string
    defining the "sense" of the projection, either
    SIGN="FWD" for forward projections or SIGN="INV" for the
    inverse operation.

    The following projection operators are supported:

        PROJ.PRJID = "stereographic"
        PROJ.RADII = # sphere radii.
        PROJ.XBASE = # central XLON.
        PROJ.YBASE = # central YLAT.

    """

    if (not isinstance(mesh, jigsaw_msh_t)):
        raise Exception("Incorrect type: MESH.")

    if (not isinstance(proj, jigsaw_prj_t)):
        raise Exception("Incorrect type: PROJ.")

    if (not isinstance(sign, str)):
        raise Exception("Incorrect type: SIGN.")

    certify(mesh)

    kind = mesh.mshID.lower()

    if   (kind == "euclidean-mesh" or
          kind == "ellipsoid-mesh"):

    #------------------------------- proj. from MESH to MESH

        if (mesh.vert2 is not None and
                mesh.vert2.size != +0):

            XPOS = mesh.point["coord"][:, 0]
            YPOS = mesh.point["coord"][:, 1]

    #----------------------------------- proj. geometry parts
            if   (proj.prjID.lower() == "stereographic"):

                XNEW, YNEW, SCAL = stereo3(
                    proj.radii, XPOS, YPOS,
                    proj.xbase, proj.ybase, sign)

                """
            elif (proj.prjID.lower() == "hammer-aitoff"):

                XNEW, YNEW, SCAL = hammer3(
                    proj.radii, XPOS, YPOS,
                    proj.xbase, proj.ybase, sign)
                """

            else:

                raise Exception(
                    "Projection operator not suppoted.")

    #----------------------------------- setup proj.'d object
            if   (sign.lower() == "fwd"):

                mesh.mshID = "euclidean-mesh"

                if (mesh.radii is not None):
                    mesh.radii = None

            elif (sign.lower() == "inv"):

                mesh.mshID = "ellipsoid-mesh"

                mesh.radii = np.full(
                    +3, proj.radii,
                    dtype=jigsaw_msh_t.REALS_t)

            else:

                raise Exception(
                    "Incorrect projection PRJID flags.")

            mesh.point["coord"][:, 0] = XNEW
            mesh.point["coord"][:, 1] = YNEW

    #----------------------------------- setup proj.'d extras
            if (mesh.value is not None and
                    mesh.value.size != +0):

                mesh.value = mesh.value * SCAL

            if (mesh.power is not None and
                    mesh.power.size != +0):

                SPOW = np.sqrt(SCAL)

                mesh.power = mesh.power * SPOW

    elif (kind == "euclidean-grid" or
          kind == "ellipsoid-grid"):

    #------------------------------- proj. from GRID to MESH

        if (mesh.xgrid is not None and
                mesh.xgrid.size != +0 and
            mesh.ygrid is not None and
                mesh.ygrid.size != +0):

            XPOS, YPOS = \
                np.meshgrid(mesh.xgrid, mesh.ygrid)

            XPOS = np.reshape(XPOS, (XPOS.size))
            YPOS = np.reshape(YPOS, (YPOS.size))

    #----------------------------------- proj. geometry parts
            if   (proj.prjID.lower() == "stereographic"):

                XNEW, YNEW, SCAL = stereo3(
                    proj.radii, XPOS, YPOS,
                    proj.xbase, proj.ybase, sign)

                """
            elif (proj.prjID.lower() == "hammer-aitoff"):

                XNEW, YNEW, SCAL = hammer3(
                    proj.radii, XPOS, YPOS,
                    proj.xbase, proj.ybase, sign)
                """

            else:

                raise Exception(
                    "Projection operator not suppoted.")

    #----------------------------------- setup proj.'d object
            mesh.point = np.empty(
                XNEW.size, dtype=jigsaw_msh_t.VERT2_t)

            if   (sign.lower() == "fwd"):

                mesh.mshID = "euclidean-mesh"

                if (mesh.radii is not None):
                    mesh.radii = None

            elif (sign.lower() == "inv"):

                mesh.mshID = "ellipsoid-mesh"

                mesh.radii = np.full(
                    +3, proj.radii,
                    dtype=jigsaw_msh_t.REALS_t)

            else:

                raise Exception(
                    "Incorrect projection PRJID flags.")

            mesh.point["IDtag"] = +0
            mesh.point["coord"][:, 0] = XNEW
            mesh.point["coord"][:, 1] = YNEW

    #----------------------------------- setup proj.'d topol.
            mesh.tria3 = np.empty(
                +0, dtype=jigsaw_msh_t.TRIA3_t)

            dim1 = mesh.xgrid.size
            mesh.xgrid = None

            dim2 = mesh.ygrid.size
            mesh.ygrid = None

            tset = []
            for jpos in range(dim2 - 1):

    #----------------------------------- 1st tria. per column
                triaA = np.empty(
                    dim1 - 1, dtype=mesh.TRIA3_t)

                triaA["IDtag"] = 0

                index = triaA["index"]
                index[:, 0] = range(0, dim1 - 1)
                index[:, 0] += (jpos + 0) * dim1

                index[:, 1] = range(1, dim1 - 0)
                index[:, 1] += (jpos + 0) * dim1

                index[:, 2] = range(1, dim1 - 0)
                index[:, 2] += (jpos + 1) * dim1

                tset.append(triaA)

    #----------------------------------- 2nd tria. per column
                triaB = np.empty(
                    dim1 - 1, dtype=mesh.TRIA3_t)

                triaB["IDtag"] = 0

                index = triaB["index"]
                index[:, 0] = range(0, dim1 - 1)
                index[:, 0] += (jpos + 0) * dim1

                index[:, 1] = range(1, dim1 - 0)
                index[:, 1] += (jpos + 1) * dim1

                index[:, 2] = range(0, dim1 - 1)
                index[:, 2] += (jpos + 1) * dim1

                tset.append(triaB)

            mesh.tria3 = \
                np.concatenate(tset, axis=0)

    #----------------------------------- setup proj.'d extras
            if (mesh.slope is not None and
                    mesh.slope.size != +0):

                mesh.slope = np.reshape(
                    mesh.slope, mesh.slope.size)

            if (mesh.value is not None and
                    mesh.value.size != +0):

                mesh.value = np.reshape(
                    mesh.value, mesh.value.size)

                mesh.value = mesh.value * SCAL

            if (mesh.power is not None and
                    mesh.power.size != +0):

                mesh.power = np.reshape(
                    mesh.power, mesh.power.size)

                SPOW = np.sqrt(SCAL)

                mesh.power = mesh.power * SPOW

    return