Sergey,
On Jun 29, 2007, at 2:52 PM, you wrote:
<offtopic>Few days ago I tried FiPy and have to tell that I am
delighted with it. Basically in few hours I learned the interface
of FiPy
and wrote a 100-line simulation code which is more or less equivalent
to more than 6500 lines of C++ code which I am maintaining. And I have
to say it seems to be quite effective in terms of performance. I think
FiPy may provide a huge productivity improvement, especially in
academic environment. It is quite flexible and has a big potential.
And in addition it is Free as in Speech. So I want to thank all the
developers of this software. I like it and hope it will develop
further.</offtopic>
That's very nice of you to say; thank you.
Now I am trying to figure out how to select a subset of faces. The
problem is how to define a boundary condition on a part of the
boundary, and another boundary condition on the rest of the boundary.
This is definitely a weak spot. It can be done, but it's not well
documented and it's not as easy as it should be.
getFacesBottom() (and all the other getFaces...() calls) returns a
FaceIterator object, which has a where() method. So you can do this:
>>> from fipy import *
>>> mesh = Grid3D(nz=3)
>>> mesh.getFaces()
FaceIterator(mesh=UniformGrid3D(dx=1.0, dy=1.0, dz=1.0, nx=1,
ny=1, nz=3), ids=array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15]))
>>> z = mesh.getFaceCenters()[...,2]
>>> mesh.getFaces().where(z < 2)
FaceIterator(mesh=UniformGrid3D(dx=1.0, dy=1.0, dz=1.0, nx=1,
ny=1, nz=3), ids=array([ 0, 1, 4, 5, 6, 7, 10, 11, 12, 13]))
However, if you try to do the logical thing for ((y==0) and (z <
z0)), you get
>>> mesh.getFacesBottom().where(z < 2)
------------------------------------------------------------
Traceback (most recent call last):
File "<ipython console>", line 1, in ?
File "/Users/guyer/Documents/research/FiPy/trunk/fipy/meshes/
meshIterator.py", line 77, in where
ids=numerix.compress(condition, self.getIDs()))
File "/Library/Frameworks/Python.framework/Versions/2.4/lib/
python2.4/site-packages/numpy/core/fromnumeric.py", line 370, in
compress
return compress(condition, axis, out)
IndexError: index out of range for array
This is because z is shaped like all the faces in the mesh, but the
result of getFacesBottom() is much smaller. Instead, you can do
>>> z = mesh.getFacesBottom().getCenters()[...,2]
>>> mesh.getFacesBottom().where(z < 2)
FaceIterator(mesh=UniformGrid3D(dx=1.0, dy=1.0, dz=1.0, nx=1,
ny=1, nz=3), ids=array([4, 6]))
Alternatively, you can write
>>> y = mesh.getFaceCenters()[...,1]
>>> z = mesh.getFaceCenters()[...,2]
>>> mesh.getFaces().where((y == 0) & (z < 2))
FaceIterator(mesh=UniformGrid3D(dx=1.0, dy=1.0, dz=1.0, nx=1,
ny=1, nz=3), ids=array([4, 6]))
This is very clumsy and we will try to come up with something better.
- Jon
--
Jonathan E. Guyer, PhD
Metallurgy Division
National Institute of Standards and Technology
<http://www.metallurgy.nist.gov/>