James, this is awesome, thanks for posting. It would be a very good
idea to have a DelaunayMesh in FiPy that used Scipy for the
triangulation as it would give another way to make and test
unstructured meshes without the Gmsh dependency. Something like,

    mesh = DelaunayMesh(points_in_2D)

In the long run, it would be good to change your code so that it
doesn'y loop in Python. I suspect that your code is quite inefficient
due to these loops. However, you have something that works, which is
great and it is only a one time cost at the beginning of the
simulation. Is efficiency an issue for you with this?

On Thu, Jun 16, 2016 at 4:29 PM, James Pringle <jprin...@unh.edu> wrote:
> For the use of others --
>
>      Sometimes when dealing with arbitrary grids, it is useful to use the
> output of routines other than Gmsh to create the fipy mesh. In my case, I
> need to create a complex grid from ocean bathymetry, and I ended up using
> scipy.spatial.Delaunay to do so. With help from Daniel and Jonathan, I
> created a code to create a mesh2D object from the output of Delaunay. It is
> written to emphasize clarity over speed. I hope others find it useful.
>
> James Pringle
>
> #==================================================
> #This code creates a fipy grid from the output of a Delaunay
> #triangulation. The code is written to prioratize clarity over speed.
>
> from pylab import *
> from numpy import *
> import fipy
> from scipy.spatial import Delaunay
>
>
> #make a simple example set of points to triangulate with delaunay
> points=array([[ 0.,  0.],
>        [ 0.,  1.],
>        [ 1.,  0.],
>        [ 1.,  1.]])
> tri=Delaunay(points)
>
> #when this code is run as is, it should produce
> #  faceVertexIDs=
> #   [[3, 1, 0, 2, 0
> #    [1, 0, 3, 3, 2]]
> #and
> #  cellFaceIds=
> #    [[0, 3],
> #     [1, 2],
> #     [2, 4]]
>
>
> #now create the arrays that fipy.mesh.mesh2D needs.  vertexCoords is
> #of shape (2,N), where N is the number of points, and contains the
> #coordinates of the vertices. It is equivalent to tri.points in
> #content, but reshaped.
> print 'Making vertexCoords'
> vertexCoords=tri.points.T
>
> #faceVertexID is of shape (2,M) where M is the number of faces/edges
> #(faces is the fipy terminology, edges is the scipy.spatial.Delaunay
> #terminology). faceVertexID contains the points (as indices into
> #vertexCoords) which make up each face. This data can be extracted
> #from simplices from Delaunay, which contains the faces of each
> #triangle. HOWEVER, simplices contains many repeated faces, since each
> #triangle will border on others. Only one copy of each face should be
> #inserted into faceVertexID.
>
> print 'Making faceVertexIDs'
> faceIn={} #this is a dictionary of all faces that have already been
>           #inserted into the faceVertexID, with the key a tuple of
>           #indices, sorted
> faceVertexIDs_list=[] #structure to build
>
> for ntri in xrange(tri.simplices.shape[0]):
>     for nface in xrange(3):
>         if nface==0:
>             face=tri.simplices[ntri,[0,1]]
>         elif nface==1:
>             face=tri.simplices[ntri,[1,2]]
>         else:
>             face=tri.simplices[ntri,[2,0]]
>         faceKey=tuple(sort(face))
>         if not (faceKey in faceIn):
>             faceIn[faceKey]=True
>             faceVertexIDs_list.append(face)
>
> faceVertexIDs=array(faceVertexIDs_list).T
>
> #now create cellFaceIDs of shape (3,P) where P is the number of cells
> #in the domain. It contains the faces (as indices into faceVertexIDs)
> #that make up each cell.
>
> #first create dictionary with a key made up of a sorted tuple of vertex
> #indices which maps from a face to its location in faceVertexIDs
> print 'Making cellFaceIDs'
> faceMap={}
> for nface in xrange(faceVertexIDs.shape[1]):
>     faceKey=tuple(sort(faceVertexIDs[:,nface]))
>     faceMap[faceKey]=nface
>
> #now loop over simplices, find each edge/face, and map from points to
> #faces
> cellFaceIDs=tri.simplices.T*0
> for ntri in xrange(tri.simplices.shape[0]):
>     for nface in xrange(3):
>         if nface==0:
>             face=tri.simplices[ntri,[0,1]]
>         elif nface==1:
>             face=tri.simplices[ntri,[1,2]]
>         else:
>             face=tri.simplices[ntri,[2,0]]
>         faceKey=tuple(sort(face))
>         cellFaceIDs[nface,ntri]=faceMap[faceKey]
>
> #ok, now instantiate a mesh2D object with this data
> print 'Making mesh'
> mesh=fipy.meshes.mesh2D.Mesh2D(vertexCoords,faceVertexIDs,cellFaceIDs)
>
>
>
> _______________________________________________
> fipy mailing list
> fipy@nist.gov
> http://www.ctcms.nist.gov/fipy
>   [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]
>



-- 
Daniel Wheeler
_______________________________________________
fipy mailing list
fipy@nist.gov
http://www.ctcms.nist.gov/fipy
  [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]

Reply via email to