Share
Using FiPy¶
This document explains how to use FiPy in a practical sense. To see the problems that FiPy is capable of solving, you can run any of the scripts in the examples.
Note
We strongly recommend you proceed through the examples, but at the very least work through
examples.diffusion.mesh1D
to understand the notation and
basic concepts of FiPy.
We exclusively use either the unix command line or IPython to interact with FiPy. The commands in the examples are written with the assumption that they will be executed from the command line. For instance, from within the main FiPy directory, you can type:
$ python examples/diffusion/mesh1D.py
A viewer should appear and you should be prompted through a series of examples.
In order to customize the examples, or to develop your own scripts, some knowledge of Python syntax is required. We recommend you familiarize yourself with the excellent Python tutorial [11] or with Dive Into Python [12].
As you gain experience, you may want to browse through the Commandline Flags and Environment Variables that affect FiPy.
Testing FiPy¶
For a general installation, FiPy can be tested by running:
$ python c "import fipy; fipy.test()"
This command runs all the test cases in FiPy’s modules, but doesn’t include any of the tests in FiPy’s examples. To run the test cases in both modules and examples, use:
$ python setup.py test
in an unpacked FiPy archive. The test suite can be run with a number of different configurations depending on which solver suite is available and other factors. See Commandline Flags and Environment Variables for more details.
FiPy will skip tests that depend on Optional Packages that have not been installed. For example, if Mayavi and Gmsh are not installed, FiPy will warn:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Skipped 131 doctest examples because `gmsh` cannot be found on the $PATH
Skipped 42 doctest examples because the `tvtk` package cannot be imported
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
We have a few known, intermittent failures:
 #425
 The test suite can freeze, usually in
examples.chemotaxis
, when running on multiple processors. This has never affected us in an actual parallel simulation, only in the test suite. #430
 When running in parallel, the tests for
_BinaryTerm
sometimes return one erroneous result. This is not reliably reproducible and doesn’t seem to have an effect on actual simulations.
Although the test suite may show warnings, there should be no other errors. Any errors should be investigated or reported on the issue tracker. Users can see if there are any known problems for the latest FiPy distribution by checking FiPy’s automated test display.
Below are a number of common Commandline Flags for testing various FiPy configurations.
Parallel Tests¶
If FiPy is configured for Solving in Parallel, you can run the tests on multiple processor cores with:
$ mpirun np {# of processors} python setup.py test trilinos
or:
$ mpirun np {# of processors} python c "import fipy; fipy.test('trilinos')"
Commandline Flags and Environment Variables¶
FiPy chooses a default run time configuration based on the available packages on the system. The Commandline Flags and Environment Variables sections below describe how to override FiPy‘s default behavior.
Commandline Flags¶
You can add any of the following caseinsensitive flags after the name of a script you call from the command line, e.g:
$ python myFiPyScript someflag

inline
¶
Causes many mathematical operations to be performed in C, rather than Python, for improved performance. Requires the
scipy.weave
package.
The following flags take precedence over the FIPY_SOLVERS
environment variable:

skfmm
¶
Forces the use of the Scikitfmm level set solver.
Environment Variables¶
You can set any of the following environment variables in the manner
appropriate for your shell. If you are not running in a shell (e.g.,
you are invoking FiPy scripts from within IPython or IDLE),
you can set these variables via the os.environ
dictionary,
but you must do so before importing anything from the fipy
package.

FIPY_DISPLAY_MATRIX
¶ If present, causes the graphical display of the solution matrix of each equation at each call of
solve()
orsweep()
. Setting the value to “terms
,” causes the display of the matrix for eachTerm
that composes the equation. Requires the Matplotlib package.

FIPY_INLINE
¶ If present, causes many mathematical operations to be performed in C, rather than Python. Requires the
scipy.weave
package.

FIPY_INLINE_COMMENT
¶ If present, causes the addition of a comment showing the Python context that produced a particular piece of
scipy.weave
C code. Useful for debugging.

FIPY_SOLVERS
¶ Forces the use of the specified suite of linear solvers. Valid (caseinsensitive) choices are “
pysparse
”, “trilinos
”, “nopysparse
”, “scipy
” and “pyamg
”.

FIPY_VERBOSE_SOLVER
¶ If present, causes the linear solvers to print a variety of diagnostic information.

FIPY_VIEWER
¶ Forces the use of the specified viewer. Valid values are any
<viewer>
from thefipy.viewers.<viewer>Viewer
modules. The special value ofdummy
will allow the script to run without displaying anything.
Solving in Parallel¶
FiPy can use Trilinos to solve equations in
parallel. Most mesh classes in fipy.meshes
can solve in
parallel. This includes all “...Grid...
” and “...Gmsh...
”
class meshes. Currently, the only remaining serialonly meshes are
Tri2D
and
SkewedGrid2D
.
Attention
Trilinos must be compiled with MPI support.
Note
Parallel efficiency is greatly improved by installing
PySparse in addition to Trilinos. If
PySparse is not installed be sure to use the
nopysparse
flag when running in parallel.
It should not generally be necessary to change anything in your script. Simply invoke:
$ mpirun np {# of processors} python myScript.py trilinos
instead of:
$ python myScript.py
To confirm that FiPy and Trilinos are properly configured to solve in parallel, the easiest way to tell is to run one of the examples, e.g.,:
$ mpirun np 2 examples/diffusion/mesh1D.py
You should see two viewers open with half the simulation running in one of them and half in the other. If this does not look right (e.g., you get two viewers, both showing the entire simultion), or if you just want to be sure, you can run a diagnostic script:
$ mpirun np 3 python examples/parallel.py
which should print out:
mpi4py: processor 0 of 3 :: PyTrilinos: processor 0 of 3 :: FiPy: 5 cells on processor 0 of 3
mpi4py: processor 1 of 3 :: PyTrilinos: processor 1 of 3 :: FiPy: 7 cells on processor 1 of 3
mpi4py: processor 2 of 3 :: PyTrilinos: processor 2 of 3 :: FiPy: 6 cells on processor 2 of 3
If there is a problem with your parallel environment, it should be clear that there is either a problem importing one of the required packages or that there is some problem with the MPI environment. For example:
mpi4py: processor 2 of 3 :: PyTrilinos: processor 0 of 1 :: FiPy: 10 cells on processor 0 of 1
[my.machine.com:69815] WARNING: There were 4 Windows created but not freed.
mpi4py: processor 1 of 3 :: PyTrilinos: processor 0 of 1 :: FiPy: 10 cells on processor 0 of 1
[my.machine.com:69814] WARNING: There were 4 Windows created but not freed.
mpi4py: processor 0 of 3 :: PyTrilinos: processor 0 of 1 :: FiPy: 10 cells on processor 0 of 1
[my.machine.com:69813] WARNING: There were 4 Windows created but not freed.
indicates mpi4py is properly communicating with MPI and is running in parallel, but that Trilinos is not, and is running three separate serial environments. As a result, FiPy is limited to three separate serial operations, too. In this instance, the problem is that although Trilinos was compiled with MPI enabled, it was compiled against a different MPI library than is currently available (and which mpi4py was compiled against). The solution is to rebuild Trilinos against the active MPI libraries.
When solving in parallel, FiPy essentially breaks the problem
up into separate subdomains and solves them (somewhat) independently.
FiPy generally “does the right thing”, but if you find that
you need to do something with the entire solution, you can use
var.
globalValue
.
Note
Trilinos solvers frequently give intermediate output that FiPy cannot suppress. The most commonly encountered messages are
Gen_Prolongator warning : Max eigen <= 0.0
 which is not significant to FiPy.
Aztec status AZ_loss: loss of precision
 which indicates that there was some difficulty in solving the problem to the requested tolerance due to precision limitations, but usually does not prevent the solver from finding an adequate solution.
Aztec status AZ_ill_cond: GMRES hessenberg illconditioned
 which indicates that GMRES is having trouble with the problem, and may indicate that trying a different solver or preconditioner may give more accurate results if GMRES fails.
Aztec status AZ_breakdown: numerical breakdown
 which usually indicates serious problems solving the equation which forced the solver to stop before reaching an adequate solution. Different solvers, different preconditioners, or a less restrictive tolerance may help.
Meshing with Gmsh¶
FiPy works with arbitrary polygonal meshes generated by
Gmsh. FiPy provides two wrappers classes
(Gmsh2D
and
Gmsh3D
) enabling Gmsh to be
used directly from python. The classes can be instantiated with a set
of Gmsh style commands (see
examples.diffusion.circle
). The classes can also be
instantiated with the path to either a Gmsh geometry file
(.geo
) or a Gmsh mesh file (.msh
) (see
examples.diffusion.anisotropy
).
As well as meshing arbitrary geometries, Gmsh partitions
meshes for parallel simulations. Mesh partitioning automatically
occurs whenever a parallel communicator is passed to the mesh on
instantiation. This is the default setting for all meshes that work in
parallel including Gmsh2D
and
Gmsh3D
.
Note
FiPy solution accuracy can be compromised with highly nonorthogonal or nonconjunctional meshes.
Coupled and Vector Equations¶
Equations can now be coupled together so that the contributions from
all the equations appear in a single system matrix. This results in
tighter coupling for equations with spatial and temporal derivatives
in more than one variable. In FiPy equations are coupled
together using the &
operator:
>>> eqn0 = ...
>>> eqn1 = ...
>>> coupledEqn = eqn0 & eqn1
The coupledEqn
will use a combined system matrix that includes
four quadrants for each of the different variable and equation
combinations. In previous versions of FiPy there has been no
need to specify which variable a given term acts on when generating
equations. The variable is simply specified when calling solve
or
sweep
and this functionality has been maintained in the case of
single equations. However, for coupled equations the variable that a
given term operates on now needs to be specified when the equation is
generated. The syntax for generating coupled equations has the form:
>>> eqn0 = Term00(coeff=..., var=var0) + Term01(coeff..., var=var1) == source0
>>> eqn1 = Term10(coeff=..., var=var0) + Term11(coeff..., var=var1) == source1
>>> coupledEqn = eqn0 & eqn1
and there is now no need to pass any variables when solving:
>>> coupledEqn.solve(dt=..., solver=...)
In this case the matrix system will have the form
FiPy tries to make sensible decisions regarding each term’s
location in the matrix and the ordering of the variable column
array. For example, if Term01
is a transient term then Term01
would appear in the upper left diagonal and the ordering of the
variable column array would be reversed.
The use of coupled equation is described in detail in
examples.diffusion.coupled
. Other examples that demonstrate the
use of coupled equations are examples.phase.binaryCoupled
,
examples.phase.polyxtalCoupled
and
examples.cahnHilliard.mesh2DCoupled
. As well as coupling
equations, true vector equations can now be written in FiPy
(see examples.diffusion.coupled
for more details).
Boundary Conditions¶
Applying fixed value (Dirichlet) boundary conditions¶
To apply a fixed value boundary condition use the
constrain()
method. For example, to fix var to
have a value of 2 along the upper surface of a domain, use
>>> var.constrain(2., where=mesh.facesTop)
Note
The old equivalent
FixedValue
boundary
condition is now deprecated.
Applying fixed gradient boundary conditions (Neumann)¶
To apply a fixed Gradient boundary condition use the
faceGrad
.constrain()
method. For
example, to fix var to have a gradient of (0,2) along the upper
surface of a 2D domain, use
>>> var.faceGrad.constrain(((0,),(2,)), where=mesh.facesTop)
If the gradient normal to the boundary (e.g., ) is to be set to a scalar value of 2, use
>>> var.faceGrad.constrain(2 * mesh.faceNormals, where=mesh.exteriorFaces)
Applying fixed flux boundary conditions¶
Generally these can be implemented with a judicious use of
faceGrad
.constrain()
. Failing that, an
exterior flux term can be added to the equation. Firstly, set the
terms’ coefficients to be zero on the exterior faces,
>>> diffCoeff.constrain(0., mesh.exteriorFaces)
>>> convCoeff.constrain(0., mesh.exteriorFaces)
then create an equation with an extra term to account for the exterior flux,
>>> eqn = (TransientTerm() + ConvectionTerm(convCoeff)
... == DiffusionCoeff(diffCoeff)
... + (mesh.exteriorFaces * exteriorFlux).divergence)
where exteriorFlux is a rank 1
FaceVariable
.
Note
The old equivalent FixedFlux
boundary condition is now deprecated.
Applying outlet or inlet boundary conditions¶
Convection terms default to a no flux boundary condition unless the exterior faces are associated with a constraint, in which case either an inlet or an outlet boundary condition is applied depending on the flow direction.
Applying spatially varying boundary conditions¶
The use of spatial varying boundary conditions is best demonstrated with an example. Given a 2D equation in the domain and with boundary conditions,
where represents the flux. The boundary conditions in FiPy can be written with the following code,
>>> X, Y = mesh.faceCenters
>>> mask = ((X < 0.5)  (Y < 0.5))
>>> var.faceGrad.constrain(0, where=mesh.exteriorFaces & mask)
>>> var.constrain(X * Y, where=mesh.exteriorFaces & ~mask)
then
>>> eqn.solve(...)
Further demonstrations of spatially varying boundary condition can be found
in examples.diffusion.mesh20x20
and examples.diffusion.circle
Applying internal boundary conditions¶
Applying internal boundary conditions can be achieved through the use of implicit and explicit sources. An equation of the form
>>> eqn = TransientTerm() == DiffusionTerm()
can be constrained to have a fixed internal value
at a position
given by mask
with the following alterations
>>> eqn = TransientTerm() == DiffusionTerm()  ImplicitSourceTerm(mask * largeValue) + mask * largeValue * value
The parameter largeValue
must be chosen to be large enough to
completely dominate the matrix diagonal and the RHS vector in cells
that are masked. The mask
variable would typically be a
CellVariable
boolean constructed using the cell center values.
One must be careful to distinguish between constraining internal cell
values during the solve step and simply applying arbitrary constraints
to a CellVariable
. Applying a constraint,
>>> var.constrain(value, where=mask)
simply fixes the returned value of var
at mask
to be
value
. It does not have any effect on the implicit value of var
at the
mask
location during the linear solve so it is not a substitute
for the source term machinations described above. Future releases of
FiPy may implicitly deal with this discrepancy, but the current
release does not. A simple example can be used to demonstrate this:
>>> m = Grid1D(nx=2, dx=1.)
>>> var = CellVariable(mesh=m)
Apply a constraint to the faces for a right side boundary condition (which works).
>>> var.constrain(1., where=m.facesRight)
Create the equation with the source term constraint described above
>>> mask = m.x < 1.
>>> largeValue = 1e+10
>>> value = 0.25
>>> eqn = DiffusionTerm()  ImplicitSourceTerm(largeValue * mask) + largeValue * mask * value
and the expected value is obtained.
>>> eqn.solve(var)
>>> print var
[ 0.25 0.75]
However, if a constraint is used without the source term constraint an unexpected value is obtained
>>> var.constrain(0.25, where=mask)
>>> eqn = DiffusionTerm()
>>> eqn.solve(var)
>>> print var
[ 0.25 1. ]
although the left cell has the expected value as it is constrained.
Running under Python 3¶
It is possible to run FiPy scripts under Python 3, but there is admittedly little advantage in doing so at this time. We still develop and use FiPy under Python 2.x. To use, you must first convert FiPy‘s code to Python 3 syntax. From within the main FiPy directory:
$ 2to3 write .
$ 2to3 write doctests_only .
You can expect some harmless warnings from this conversion.
The minimal prerequisites are:
 NumPy version 1.5 or greater.
 SciPy version 0.9 or greater.
 Matplotlib version 1.2 or greater (this hasn’t been released yet, and we haven’t been able to successfully test the
matplotlibViewer
classes with their development code).
Manual¶
You can view the manual online at <http://www.ctcms.nist.gov/fipy> or you can download the latest manual from <http://www.ctcms.nist.gov/fipy/download/>. Alternatively, it may be possible to build a fresh copy by issuing the following command in the base directory:
$ python setup.py build_docs pdf html
Note
This mechanism is intended primarily for the developers. At a minimum, you will need at least version 1.1.2 of Sphinx, plus all of its prerequisites, although we build the documentation witih the latest development code (you will need hg installed):
$ pip install upgrade e hg+https://bitbucket.org/birkenfeld/sphinx#egg=sphinx
We use several contributed Sphinx plugins:
$ hg clone https://bitbucket.org/birkenfeld/sphinxcontrib/
$ cd sphinxcontrib/traclinks $ python setup.py install
Bibliographic citations require the sphinxcontribbibtex package. For the moment, the development versions of several packages are required to properly render our bibliography (you will need both bzr and git installed):
$ pip install e bzr+lp:~pybtexdevs/pybtex/trunk
$ pip install e git+git@github.com:mcmtroffaes/pybtexdocutils.git#egg=pybtexdocutils
$ pip install e git+git@github.com:mcmtroffaes/sphinxcontribbibtex.git#egg=sphinxcontribbibtex
Version 3.1.2
Table Of Contents
This Page
Quick search
Enter search terms or a module, class or function name.
Organizations
Contact
Join our mailing list, open an issue at the tracker, or ask a question on StackOverflow.