0

If I create a fipy 2D grid using:

mesh = Grid2D(nx=3, ny=3, dx=1., dy=1.)

I get a reasonable grid of rectangular elements. However, if I take the values of this mesh and use them to construct a vanilla Mesh2D:

mesh2d = Mesh2D(mesh.vertexCoords, mesh.faceVertexIDs, mesh.cellFaceIDs)

I get a mesh that is triangular, and some of the triangles seem to be invalid. If I do this:

model = CellVariable(mesh=mesh2d, value=1.)

and view it with the matplotlib viewer, some of the triangles are unfilled, which I assume means they are not valid.

Can I recreate the original rectangular grid using Mesh2D? I would like to do this because I have distorted rectangular grid coordinates from another source that I'd like substitute for mesh.vectorCoords in the call to Mesh2D. The face vertices and the cell faces are the same, it's just the mesh fabric that has been distorted.

Fadecomic
  • 1,220
  • 1
  • 10
  • 23

2 Answers2

1

I think the viewer is unable to display the Mesh2D mesh class rather than anything that is fundamentally wrong with using a Mesh2D object to solve equations. To demonstrate this, you can solve a simple equation using a Mesh2D and then map back to a Grid2D to display your data. For example,

import fipy

mesh = fipy.Grid2D(nx=3, ny=3, dx=1., dy=1.)
mesh2d = fipy.meshes.mesh2D.Mesh2D(mesh.vertexCoords, mesh.faceVertexIDs, mesh.cellFaceIDs)

var = fipy.CellVariable(mesh=mesh, value=1.)
var2D = fipy.CellVariable(mesh=mesh2d, value=1.)

var2D.constrain(2, where=mesh.facesRight)
var2D.constrain(0, where=mesh.facesLeft)

fipy.DiffusionTerm().solve(var2D)


var[:] = var2D(mesh.cellCenters, order=1)

fipy.Viewer(var).plot()
raw_input('stop')

and the result looks correct. We've solved an equation using a variable on the Mesh2D and it seems to work just fine.

The above is using the __call__ method of CellVariable to interpolate back to the variable on the Grid2D. This approach will work for your distorted grid as well. The interpolation is first order only.

wd15
  • 1,068
  • 5
  • 8
1

Grid2D has a number of optimizations that are self-consistent, both with solving and viewing, but that don't translate to the general meshes. You can achieve what you want by instead doing

mesh = fipy.meshes.nonUniformGrid2D.NonUniformGrid2D(nx=3, ny=3, dx=1., dy=1.)
mesh2d = Mesh2D(mesh.vertexCoords, mesh.faceVertexIDs, mesh.cellFaceIDs)
model = CellVariable(mesh=mesh2d, value=1.)
jeguyer
  • 2,379
  • 1
  • 11
  • 15
  • I don't follow. I'm not solving or viewing with Grid2D, but on Mesh2D. How can I use NonUniformGrid2D to set up a distorted mesh? The manual unfortunately says very little about this class. Right now, I only use Grid2D as a source of mesh connections required by the Mesh2D constructor, replacing the vertex coordinates with my own. – Fadecomic Apr 24 '19 at 21:23
  • 1
    Replace line 1 of your your code with the line I gave, then define `mesh2d` as you already do. `NonUniformGrid2D` has the topology you want, `Grid2D` does not. – jeguyer Apr 25 '19 at 00:40
  • Edited to clarify – jeguyer Apr 25 '19 at 00:41
  • This seems to work, but my boundary conditions seem to be enforced only at the most extreme points on the mesh rather than the entire boundary. E.g. `myVar.constrain(1.0, mesh2d.facesBottom)` doesn't constrain the bottom faces. It just constrains the bottommost point, giving the solution a bright spot there. Is there something special I have to do to enforce the BC properly? – Fadecomic Apr 25 '19 at 13:54
  • 1
    You would need to define a mask that captures the faces you want. `facesBottom` et al. are just extrema tests. If I wanted to distort a grid, I would use Gmsh, which enables identifying physical boundaries as part of the definition. – jeguyer Apr 25 '19 at 14:55
  • Actually, just using `mesh.facesBottom` in the constraint worked, since it's just a mask. – Fadecomic Apr 25 '19 at 15:19
  • ??? What does "E.g. `myVar.constrain(1.0, mesh2d.facesBottom)` doesn't constrain the bottom faces" mean, then? – jeguyer Apr 26 '19 at 11:58
  • You have `mesh2d`. I used `mesh.facesBottom`, not `mesh2d.facesBottom`, and that worked. I used the mask from the rectangular mesh. – Fadecomic Apr 26 '19 at 13:56
  • Ah, I see. Rather clever. – jeguyer Apr 26 '19 at 22:55