RE: casting implicit Boundary Conditions in FiPy

2016-06-17 Thread Gopalakrishnan, Krishnakumar
Hi Dan,



Thanks for your reply, and for the tip to use Grid1D with variable dx. I was 
able to deploy  it right away.



There  is a new complexity in this connection.



My problem models the  solid diffusion in a spherical particle.  Matter 
diffuses  from the centre of the particle  and reacts at the surface.   This is 
captured in a normalised 1-D domain  with suitable equations and co-ordinate 
scaling.  Particle-centre is represented at x = 0 boundary, and surface of the 
sphere represented by x=1 boundary.



Now, my meshing algorithm is a special one. My inter-nodal distance (the 
thickness of each sub-shell of the sphere) is such that, all of the internal 
shells have equal volume.  This is done so that mass is conserved within the 
domain. This practise is stemming from my finite difference/finite element 
colleagues who advocate this.



The problem is that, it is impossible to EXACTLY divide the shell into integer 
number of iso-volume subshells. Thus, the scheme is chosen such that, we get 
iso-volume shells for all inner sub-shells upto the last shell.  The last 
shell's thickness (dx) is obviously and purposefully made ultra-small   
following the discussions and Dan's solution proposed in this thread. Clearly, 
this last shell's volume differs from the rest of the inner subshells.



Am I violating any conservation laws here by doing it ? I know that finite 
volume is a conservative method.  But this question nevertheless nags me.



Is there any advantage to doing iso-volume subshells ( for the inner shells) 
only to break  this concept for the last shell ?   Given that all the solution 
dynamics happen at the surface (right boundary) , does a simple  geometric 
progression suffice with a very small dx at the right boundary  suffice ?  Or 
is there any other optimal (structured) mesh generation algorithm for choosing 
mesh sizes depending on problem-type, that I need to refer to ?





Krishna





-Original Message-
From: fipy-boun...@nist.gov [mailto:fipy-boun...@nist.gov] On Behalf Of Daniel 
Wheeler
Sent: 17 June 2016 14:50
To: Multiple recipients of list 
Subject: Re: casting implicit Boundary Conditions in FiPy



On Thu, Jun 16, 2016 at 12:35 PM, Gopalakrishnan, Krishnakumar 
mailto:k.gopalakrishna...@imperial.ac.uk>> 
wrote:

> Thanks.

>

> Yes, this Is indeed only first order accurate.  I verified this by 
> successively cutting my dx by half, running your code, and comparing against 
> the Mathematica generated result. Each time dx is cut by half, the error is 
> also proportionately halved.

>

> This code requires me to take unreasonably small dx values.  Since, neither 
> the solution, nor the gradients are available at each implicit time-steps, I 
> think that higher order schemes are probably ruled out.



I think you're right. It's not easy.



> I am thinking of using a variable mesh-sizing, let's say a log-spacing in 1D, 
> keeping a very fine spacing (ultra-small dx) for the last cell near the 
> boundary, and gradually taking bigger steps.  This is also physically 
> consistent with my problem, wherein all the action takes place close to the 
> boundary, and nothing much is happening at the middle or left edges.



Maybe it's possible to make the edge cell almost infinitely small and have the 
rest of the cells evenly spaced.



> This brings me to another issue.  I don't see a way to import a 1D .msh file 
> generated by gmsh into FiPy.



I'm not sure if Gmsh does 1D meshes, you can always use a 2D mesh as a 1D mesh 
of course.



> Secondly,  I notice that there is an optimistic sounding  grid1DBuilder 
> method.   I couldn't find any help on how to use this method. Is this method 
> capable of creating the log-spaced mesh that I am considering ?



Note that Grid1D takes an array for dx. So you can do



>>> mesh = fp.Grid1D(dx=[0.5, 1.0, 2.0])

>>> print(mesh.cellCenters)

[[ 0.25  1.   2.5 ]]



As long as you can calculate the grid spacing then you don't need Gmsh.



--

Daniel Wheeler



___

fipy mailing list

fipy@nist.gov

http://www.ctcms.nist.gov/fipy

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


RE: casting implicit Boundary Conditions in FiPy

2016-06-17 Thread Gopalakrishnan, Krishnakumar
Dear Dr. Jonathan Guyer,



Thank you very much for your help. For the benefit of the community wishing to 
use 1D meshes in gmsh format for any of their external applications, I am 
bringing into your attention a nifty script available from the 'fluidity' CFD 
project.



For my 1D case, I have been able to use a very handy python script located 
here: https://github.com/FluidityProject/fluidity/blob/master/tools/interval.py



The usage is as follows:.  python interval.py --variable_dx=example.py 0.0 50.0 
my_variable_mesh, will create a mesh in gmsh format  called 
'my_variabel_mesh.msh' in the current directory.



The example.py can contain  any arbitrary numpy  function (with name val(X) ) 
for defining the mesh spacing.



For example something like

def val(X):

return (5. / (X+1))



But clearly your script is much more amenable for a FiPy-centric workflow,  
since we don't have to worry about the intricacies of importing  a  1D .msh 
file.



Thank you for your help.





Krishna









-Original Message-
From: fipy-boun...@nist.gov [mailto:fipy-boun...@nist.gov] On Behalf Of Guyer, 
Jonathan E. Dr. (Fed)
Sent: 17 June 2016 15:28
To: FIPY 
Subject: Re: casting implicit Boundary Conditions in FiPy



Gmsh does do 1D meshes, and I've got experimental code that imports them, but 
it's not ready to merge, yet.



In the meantime, this approach I've used for modeling semiconductor device 
contacts in 1D is probably better:







n_thickness = 1e-6 # m

p_thickness = 149e-6 # m

grid_resolution = 5e-8 # m



compression_factor = 0.8

compression_count = 10



compressed_dx = grid_resolution * 
compression_factor**numerix.arange(compression_count)

compressed_length = compressed_dx.sum()

compressed_dx = list(compressed_dx)



n_uncompressed_thickness = n_thickness - 2 * compressed_length n_dx = 
n_uncompressed_thickness / round(n_uncompressed_thickness / grid_resolution) 
n_dx = compressed_dx[::-1] + [n_dx] * int(n_uncompressed_thickness / n_dx) + 
compressed_dx



p_uncompressed_thickness = p_thickness - 2 * compressed_length p_dx = 
p_uncompressed_thickness / round(p_uncompressed_thickness / grid_resolution) 
p_dx = compressed_dx[::-1] + [p_dx] * int(p_uncompressed_thickness / p_dx + 
0.5) + compressed_dx



mesh = Grid1D(dx=n_dx + p_dx)











> On Jun 17, 2016, at 9:50 AM, Daniel Wheeler 
> mailto:daniel.wheel...@gmail.com>> wrote:

>

> On Thu, Jun 16, 2016 at 12:35 PM, Gopalakrishnan, Krishnakumar

> mailto:k.gopalakrishna...@imperial.ac.uk>> 
> wrote:

>> Thanks.

>>

>> Yes, this Is indeed only first order accurate.  I verified this by 
>> successively cutting my dx by half, running your code, and comparing against 
>> the Mathematica generated result. Each time dx is cut by half, the error is 
>> also proportionately halved.

>>

>> This code requires me to take unreasonably small dx values.  Since, neither 
>> the solution, nor the gradients are available at each implicit time-steps, I 
>> think that higher order schemes are probably ruled out.

>

> I think you're right. It's not easy.

>

>> I am thinking of using a variable mesh-sizing, let's say a log-spacing in 
>> 1D, keeping a very fine spacing (ultra-small dx) for the last cell near the 
>> boundary, and gradually taking bigger steps.  This is also physically 
>> consistent with my problem, wherein all the action takes place close to the 
>> boundary, and nothing much is happening at the middle or left edges.

>

> Maybe it's possible to make the edge cell almost infinitely small and

> have the rest of the cells evenly spaced.

>

>> This brings me to another issue.  I don't see a way to import a 1D .msh file 
>> generated by gmsh into FiPy.

>

> I'm not sure if Gmsh does 1D meshes, you can always use a 2D mesh as a

> 1D mesh of course.

>

>> Secondly,  I notice that there is an optimistic sounding  grid1DBuilder 
>> method.   I couldn't find any help on how to use this method. Is this method 
>> capable of creating the log-spaced mesh that I am considering ?

>

> Note that Grid1D takes an array for dx. So you can do

>

 mesh = fp.Grid1D(dx=[0.5, 1.0, 2.0])

 print(mesh.cellCenters)

>[[ 0.25  1.   2.5 ]]

>

> As long as you can calculate the grid spacing then you don't need Gmsh.

>

> --

> Daniel Wheeler

>

> ___

> fipy mailing list

> fipy@nist.gov

> http://www.ctcms.nist.gov/fipy

>  [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]





___

fipy mailing list

fipy@nist.gov

http://www.ctcms.nist.gov/fipy

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


Re: casting implicit Boundary Conditions in FiPy

2016-06-17 Thread Guyer, Jonathan E. Dr. (Fed)
Gmsh does do 1D meshes, and I've got experimental code that imports them, but 
it's not ready to merge, yet.

In the meantime, this approach I've used for modeling semiconductor device 
contacts in 1D is probably better:



n_thickness = 1e-6 # m
p_thickness = 149e-6 # m
grid_resolution = 5e-8 # m

compression_factor = 0.8
compression_count = 10

compressed_dx = grid_resolution * 
compression_factor**numerix.arange(compression_count)
compressed_length = compressed_dx.sum()
compressed_dx = list(compressed_dx)

n_uncompressed_thickness = n_thickness - 2 * compressed_length
n_dx = n_uncompressed_thickness / round(n_uncompressed_thickness / 
grid_resolution)
n_dx = compressed_dx[::-1] + [n_dx] * int(n_uncompressed_thickness / n_dx) + 
compressed_dx

p_uncompressed_thickness = p_thickness - 2 * compressed_length
p_dx = p_uncompressed_thickness / round(p_uncompressed_thickness / 
grid_resolution)
p_dx = compressed_dx[::-1] + [p_dx] * int(p_uncompressed_thickness / p_dx + 
0.5) + compressed_dx

mesh = Grid1D(dx=n_dx + p_dx)





> On Jun 17, 2016, at 9:50 AM, Daniel Wheeler  wrote:
> 
> On Thu, Jun 16, 2016 at 12:35 PM, Gopalakrishnan, Krishnakumar
>  wrote:
>> Thanks.
>> 
>> Yes, this Is indeed only first order accurate.  I verified this by 
>> successively cutting my dx by half, running your code, and comparing against 
>> the Mathematica generated result. Each time dx is cut by half, the error is 
>> also proportionately halved.
>> 
>> This code requires me to take unreasonably small dx values.  Since, neither 
>> the solution, nor the gradients are available at each implicit time-steps, I 
>> think that higher order schemes are probably ruled out.
> 
> I think you're right. It's not easy.
> 
>> I am thinking of using a variable mesh-sizing, let's say a log-spacing in 
>> 1D, keeping a very fine spacing (ultra-small dx) for the last cell near the 
>> boundary, and gradually taking bigger steps.  This is also physically 
>> consistent with my problem, wherein all the action takes place close to the 
>> boundary, and nothing much is happening at the middle or left edges.
> 
> Maybe it's possible to make the edge cell almost infinitely small and
> have the rest of the cells evenly spaced.
> 
>> This brings me to another issue.  I don't see a way to import a 1D .msh file 
>> generated by gmsh into FiPy.
> 
> I'm not sure if Gmsh does 1D meshes, you can always use a 2D mesh as a
> 1D mesh of course.
> 
>> Secondly,  I notice that there is an optimistic sounding  grid1DBuilder 
>> method.   I couldn't find any help on how to use this method. Is this method 
>> capable of creating the log-spaced mesh that I am considering ?
> 
> Note that Grid1D takes an array for dx. So you can do
> 
 mesh = fp.Grid1D(dx=[0.5, 1.0, 2.0])
 print(mesh.cellCenters)
>[[ 0.25  1.   2.5 ]]
> 
> As long as you can calculate the grid spacing then you don't need Gmsh.
> 
> -- 
> Daniel Wheeler
> 
> ___
> fipy mailing list
> fipy@nist.gov
> http://www.ctcms.nist.gov/fipy
>  [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]


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


Re: scipy's Delaunay output to fipy mesh2D object

2016-06-17 Thread James Pringle
Thanks --

   Once I have pounded on this a bit more, I will write the function. It
should be straightforward. I concentrated on making it simple and easy to
understand; since it is run only to make the grid, efficiency was not a
great issue for me.

Jamie

On Fri, Jun 17, 2016 at 10:03 AM, Daniel Wheeler 
wrote:

> 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  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(ve

Re: scipy's Delaunay output to fipy mesh2D object

2016-06-17 Thread Daniel Wheeler
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  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 ]


Re: casting implicit Boundary Conditions in FiPy

2016-06-17 Thread Daniel Wheeler
On Thu, Jun 16, 2016 at 12:35 PM, Gopalakrishnan, Krishnakumar
 wrote:
> Thanks.
>
> Yes, this Is indeed only first order accurate.  I verified this by 
> successively cutting my dx by half, running your code, and comparing against 
> the Mathematica generated result. Each time dx is cut by half, the error is 
> also proportionately halved.
>
> This code requires me to take unreasonably small dx values.  Since, neither 
> the solution, nor the gradients are available at each implicit time-steps, I 
> think that higher order schemes are probably ruled out.

I think you're right. It's not easy.

> I am thinking of using a variable mesh-sizing, let's say a log-spacing in 1D, 
> keeping a very fine spacing (ultra-small dx) for the last cell near the 
> boundary, and gradually taking bigger steps.  This is also physically 
> consistent with my problem, wherein all the action takes place close to the 
> boundary, and nothing much is happening at the middle or left edges.

Maybe it's possible to make the edge cell almost infinitely small and
have the rest of the cells evenly spaced.

> This brings me to another issue.  I don't see a way to import a 1D .msh file 
> generated by gmsh into FiPy.

I'm not sure if Gmsh does 1D meshes, you can always use a 2D mesh as a
1D mesh of course.

> Secondly,  I notice that there is an optimistic sounding  grid1DBuilder 
> method.   I couldn't find any help on how to use this method. Is this method 
> capable of creating the log-spaced mesh that I am considering ?

Note that Grid1D takes an array for dx. So you can do

>>> mesh = fp.Grid1D(dx=[0.5, 1.0, 2.0])
>>> print(mesh.cellCenters)
[[ 0.25  1.   2.5 ]]

As long as you can calculate the grid spacing then you don't need Gmsh.

-- 
Daniel Wheeler

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