fipy package

Subpackages

Submodules

fipy.testFiPy module

Module contents

FiPy is an object oriented, partial differential equation (PDE) solver, written in Python, based on a standard finite volume (FV) approach. The framework has been developed in the Materials Science and Engineering Division (MSED) and Center for Theoretical and Computational Materials Science (CTCMS), in the Material Measurement Laboratory (MML) at the National Institute of Standards and Technology (NIST).

The solution of coupled sets of PDEs is ubiquitous to the numerical simulation of science problems. Numerous PDE solvers exist, using a variety of languages and numerical approaches. Many are proprietary, expensive and difficult to customize. As a result, scientists spend considerable resources repeatedly developing limited tools for specific problems. Our approach, combining the FV method and Python, provides a tool that is extensible, powerful and freely available. A significant advantage to Python is the existing suite of tools for array calculations, sparse matrices and data rendering.

The FiPy framework includes terms for transient diffusion, convection and standard sources, enabling the solution of arbitrary combinations of coupled elliptic, hyperbolic and parabolic PDEs. Currently implemented models include phase field [1] [2] [3] treatments of polycrystalline, dendritic, and electrochemical phase transformations, as well as drug eluting stents [4], reactive wetting [5], photovoltaics [6] and a level set treatment of the electrodeposition process [7].

exception fipy.AbstractBaseClassError(s="can't instantiate abstract base class")

Bases: NotImplementedError

__init__(s="can't instantiate abstract base class")

Initialize self. See help(type(self)) for accurate signature.

__module__ = 'fipy.terms'
__weakref__

list of weak references to the object (if defined)

class fipy.AdvectionTerm(coeff=None)

Bases: fipy.terms.firstOrderAdvectionTerm.FirstOrderAdvectionTerm

The AdvectionTerm object constructs the b vector contribution for the advection term given by

u \abs{\nabla \phi}

from the advection equation given by:

\frac{\partial \phi}{\partial t} + u \abs{\nabla \phi} = 0

The construction of the gradient magnitude term requires upwinding as in the standard FirstOrderAdvectionTerm. The higher order terms are incorporated as follows. The formula used here is given by:

u_P \abs{\nabla \phi}_P = \max \left( u_P , 0 \right) \left[  \sum_A \min \left( D_{AP}, 0 \right)^2 \right]^{1/2} +  \min \left( u_P , 0 \right) \left[  \sum_A \max \left( D_{AP}, 0 \right)^2 \right]^{1/2}

where,

D_{AP} = \frac{ \phi_A - \phi_P } { d_{AP}} - \frac{ d_{AP} } {2} m \left(L_A, L_P \right)

and

m\left(x, y\right) &= x \qquad \text{if $\abs{x} \le \abs{y} \forall xy \ge 0$} \\
m\left(x, y\right) &= y \qquad \text{if $\abs{x} > \abs{y} \forall xy \ge 0$} \\
m\left(x, y\right) &= 0 \qquad \text{if $xy < 0$}

also,

L_A &= \frac{\phi_{AA} + \phi_P - 2 \phi_A}{d_{AP}^2} \\
L_P &= \frac{\phi_{A} + \phi_{PP} - 2 \phi_P}{d_{AP}^2}

Here are some simple test cases for this problem:

>>> from fipy.meshes import Grid1D
>>> from fipy.solvers import *
>>> SparseMatrix = LinearPCGSolver()._matrixClass
>>> mesh = Grid1D(dx = 1., nx = 3)

Trivial test:

>>> from fipy.variables.cellVariable import CellVariable
>>> coeff = CellVariable(mesh = mesh, value = numerix.zeros(3, 'd'))
>>> v, L, b = AdvectionTerm(0.)._buildMatrix(coeff, SparseMatrix)
>>> print(numerix.allclose(b, numerix.zeros(3, 'd'), atol = 1e-10)) 
True

Less trivial test:

>>> coeff = CellVariable(mesh = mesh, value = numerix.arange(3))
>>> v, L, b = AdvectionTerm(1.)._buildMatrix(coeff, SparseMatrix)
>>> print(numerix.allclose(b, numerix.array((0., -1., -1.)), atol = 1e-10)) 
True

Even less trivial

>>> coeff = CellVariable(mesh = mesh, value = numerix.arange(3))
>>> v, L, b = AdvectionTerm(-1.)._buildMatrix(coeff, SparseMatrix)
>>> print(numerix.allclose(b, numerix.array((1., 1., 0.)), atol = 1e-10)) 
True

Another trivial test case (more trivial than a trivial test case standing on a harpsichord singing “trivial test cases are here again”)

>>> vel = numerix.array((-1, 2, -3))
>>> coeff = CellVariable(mesh = mesh, value = numerix.array((4, 6, 1)))
>>> v, L, b = AdvectionTerm(vel)._buildMatrix(coeff, SparseMatrix)
>>> print(numerix.allclose(b, -vel * numerix.array((2, numerix.sqrt(5**2 + 2**2), 5)), atol = 1e-10)) 
True

Somewhat less trivial test case:

>>> from fipy.meshes import Grid2D
>>> mesh = Grid2D(dx = 1., dy = 1., nx = 2, ny = 2)
>>> vel = numerix.array((3, -5, -6, -3))
>>> coeff = CellVariable(mesh = mesh, value = numerix.array((3, 1, 6, 7)))
>>> v, L, b = AdvectionTerm(vel)._buildMatrix(coeff, SparseMatrix)
>>> answer = -vel * numerix.array((2, numerix.sqrt(2**2 + 6**2), 1, 0))
>>> print(numerix.allclose(b, answer, atol = 1e-10)) 
True

For the above test cases the AdvectionTerm gives the same result as the AdvectionTerm. The following test imposes a quadratic field. The higher order term can resolve this field correctly.

\phi = x^2

The returned vector b should have the value:

-\abs{\nabla \phi} = -\left|\frac{\partial \phi}{\partial x}\right| = - 2 \abs{x}

Build the test case in the following way,

>>> mesh = Grid1D(dx = 1., nx = 5)
>>> vel = 1.
>>> coeff = CellVariable(mesh = mesh, value = mesh.cellCenters[0]**2)
>>> v, L, b = __AdvectionTerm(vel)._buildMatrix(coeff, SparseMatrix)

The first order term is not accurate. The first and last element are ignored because they don’t have any neighbors for higher order evaluation

>>> print(numerix.allclose(CellVariable(mesh=mesh,
... value=b).globalValue[1:-1], -2 * mesh.cellCenters.globalValue[0][1:-1]))
False

The higher order term is spot on.

>>> v, L, b = AdvectionTerm(vel)._buildMatrix(coeff, SparseMatrix)
>>> print(numerix.allclose(CellVariable(mesh=mesh,
... value=b).globalValue[1:-1], -2 * mesh.cellCenters.globalValue[0][1:-1]))
True

The AdvectionTerm will also resolve a circular field with more accuracy,

\phi = \left( x^2 + y^2 \right)^{1/2}

Build the test case in the following way,

>>> mesh = Grid2D(dx = 1., dy = 1., nx = 10, ny = 10)
>>> vel = 1.
>>> x, y = mesh.cellCenters
>>> r = numerix.sqrt(x**2 + y**2)
>>> coeff = CellVariable(mesh = mesh, value = r)
>>> v, L, b = __AdvectionTerm(1.)._buildMatrix(coeff, SparseMatrix)
>>> error = CellVariable(mesh=mesh, value=b + 1)
>>> ans = CellVariable(mesh=mesh, value=b + 1)
>>> ans[(x > 2) & (x < 8) & (y > 2) & (y < 8)] = 0.123105625618
>>> print((error <= ans).all())
True

The maximum error is large (about 12 %) for the first order advection.

>>> v, L, b = AdvectionTerm(1.)._buildMatrix(coeff, SparseMatrix)
>>> error = CellVariable(mesh=mesh, value=b + 1)
>>> ans = CellVariable(mesh=mesh, value=b + 1)
>>> ans[(x > 2) & (x < 8) & (y > 2) & (y < 8)] = 0.0201715476598
>>> print((error <= ans).all())
True

The maximum error is 2 % when using a higher order contribution.

Create a Term.

Parameters

coeff (float or CellVariable or FaceVariable) – Coefficient for the term. FaceVariable objects are only acceptable for diffusion or convection terms.

__module__ = 'fipy.terms.advectionTerm'
class fipy.BetaNoiseVariable(*args, **kwds)

Bases: fipy.variables.noiseVariable.NoiseVariable

Represents a beta distribution of random numbers with the probability distribution

x^{\alpha - 1}\frac{\beta^\alpha e^{-\beta x}}{\Gamma(\alpha)}

with a shape parameter \alpha, a rate parameter \beta, and \Gamma(z) = \int_0^\infty t^{z - 1}e^{-t}\,dt.

Seed the random module for the sake of deterministic test results.

>>> from fipy import numerix
>>> numerix.random.seed(1)

We generate noise on a uniform Cartesian mesh

>>> from fipy.variables.variable import Variable
>>> alpha = Variable()
>>> beta = Variable()
>>> from fipy.meshes import Grid2D
>>> noise = BetaNoiseVariable(mesh = Grid2D(nx = 100, ny = 100), alpha = alpha, beta = beta)

We histogram the root-volume-weighted noise distribution

>>> from fipy.variables.histogramVariable import HistogramVariable
>>> histogram = HistogramVariable(distribution = noise, dx = 0.01, nx = 100)

and compare to a Gaussian distribution

>>> from fipy.variables.cellVariable import CellVariable
>>> betadist = CellVariable(mesh = histogram.mesh)
>>> x = CellVariable(mesh=histogram.mesh, value=histogram.mesh.cellCenters[0])
>>> from scipy.special import gamma as Gamma 
>>> betadist = ((Gamma(alpha + beta) / (Gamma(alpha) * Gamma(beta)))
...             * x**(alpha - 1) * (1 - x)**(beta - 1)) 
>>> if __name__ == '__main__':
...     from fipy import Viewer
...     viewer = Viewer(vars=noise, datamin=0, datamax=1)
...     histoplot = Viewer(vars=(histogram, betadist),
...                        datamin=0, datamax=1.5)
>>> from fipy.tools.numerix import arange
>>> for a in arange(0.5, 5, 0.5):
...     alpha.value = a
...     for b in arange(0.5, 5, 0.5):
...         beta.value = b
...         if __name__ == '__main__':
...             import sys
...             print("alpha: %g, beta: %g" % (alpha, beta), file=sys.stderr)
...             viewer.plot()
...             histoplot.plot()
>>> print(abs(noise.faceGrad.divergence.cellVolumeAverage) < 5e-15)
1
random values with a beta distribution histogram of random values with a beta distribution
Parameters
  • mesh (Mesh) – The mesh on which to define the noise.

  • alpha (float) – The parameter \alpha.

  • beta (float) – The parameter \beta.

__init__(mesh, alpha, beta, name='', hasOld=0)
Parameters
  • mesh (Mesh) – The mesh on which to define the noise.

  • alpha (float) – The parameter \alpha.

  • beta (float) – The parameter \beta.

__module__ = 'fipy.variables.betaNoiseVariable'
random()
class fipy.CellVariable(*args, **kwds)

Bases: fipy.variables.meshVariable._MeshVariable

Represents the field of values of a variable on a Mesh.

A CellVariable can be pickled to persistent storage (disk) for later use:

>>> from fipy.meshes import Grid2D
>>> mesh = Grid2D(dx = 1., dy = 1., nx = 10, ny = 10)
>>> var = CellVariable(mesh = mesh, value = 1., hasOld = 1, name = 'test')
>>> x, y = mesh.cellCenters
>>> var.value = (x * y)
>>> from fipy.tools import dump
>>> (f, filename) = dump.write(var, extension = '.gz')
>>> unPickledVar = dump.read(filename, f)
>>> print(var.allclose(unPickledVar, atol = 1e-10, rtol = 1e-10))
1
Parameters
  • mesh (Mesh) – the mesh that defines the geometry of this Variable

  • name (str) – the user-readable name of the Variable

  • value (float or array_like) – the initial value

  • rank (int) – the rank (number of dimensions) of each element of this Variable. Default: 0

  • elementshape (tuple of int) – the shape of each element of this variable Default: rank * (mesh.dim,)

  • unit (str or PhysicalUnit) – The physical units of the variable

__call__(points=None, order=0, nearestCellIDs=None)

Interpolates the CellVariable to a set of points using a method that has a memory requirement on the order of Ncells by Npoints in general, but uses only Ncells when the CellVariable’s mesh is a UniformGrid object.

Tests

>>> from fipy import *
>>> m = Grid2D(nx=3, ny=2)
>>> v = CellVariable(mesh=m, value=m.cellCenters[0])
>>> print(v(((0., 1.1, 1.2), (0., 1., 1.))))
[ 0.5  1.5  1.5]
>>> print(v(((0., 1.1, 1.2), (0., 1., 1.)), order=1))
[ 0.25  1.1   1.2 ]
>>> m0 = Grid2D(nx=2, ny=2, dx=1., dy=1.)
>>> m1 = Grid2D(nx=4, ny=4, dx=.5, dy=.5)
>>> x, y = m0.cellCenters
>>> v0 = CellVariable(mesh=m0, value=x * y)
>>> print(v0(m1.cellCenters.globalValue))
[ 0.25  0.25  0.75  0.75  0.25  0.25  0.75  0.75  0.75  0.75  2.25  2.25
  0.75  0.75  2.25  2.25]
>>> print(v0(m1.cellCenters.globalValue, order=1))
[ 0.125  0.25   0.5    0.625  0.25   0.375  0.875  1.     0.5    0.875
  1.875  2.25   0.625  1.     2.25   2.625]
Parameters
  • points (tuple or list of tuple) – A point or set of points in the format (X, Y, Z)

  • order ({0, 1}) – The order of interpolation, default is 0

  • nearestCellIDs (array_like) – Optional argument if user can calculate own nearest cell IDs array, shape should be same as points

__getstate__()

Used internally to collect the necessary information to pickle the CellVariable to persistent storage.

__init__(mesh, name='', value=0.0, rank=None, elementshape=None, unit=None, hasOld=0)
Parameters
  • mesh (Mesh) – the mesh that defines the geometry of this Variable

  • name (str) – the user-readable name of the Variable

  • value (float or array_like) – the initial value

  • rank (int) – the rank (number of dimensions) of each element of this Variable. Default: 0

  • elementshape (tuple of int) – the shape of each element of this variable Default: rank * (mesh.dim,)

  • unit (str or PhysicalUnit) – The physical units of the variable

__module__ = 'fipy.variables.cellVariable'
__setstate__(dict)

Used internally to create a new CellVariable from pickled persistent storage.

property arithmeticFaceValue

Returns a FaceVariable whose value corresponds to the arithmetic interpolation of the adjacent cells:

\phi_f = (\phi_1 - \phi_2) \frac{d_{f2}}{d_{12}} + \phi_2

>>> from fipy.meshes import Grid1D
>>> from fipy import numerix
>>> mesh = Grid1D(dx = (1., 1.))
>>> L = 1
>>> R = 2
>>> var = CellVariable(mesh = mesh, value = (L, R))
>>> faceValue = var.arithmeticFaceValue[mesh.interiorFaces.value]
>>> answer = (R - L) * (0.5 / 1.) + L
>>> print(numerix.allclose(faceValue, answer, atol = 1e-10, rtol = 1e-10))
True
>>> mesh = Grid1D(dx = (2., 4.))
>>> var = CellVariable(mesh = mesh, value = (L, R))
>>> faceValue = var.arithmeticFaceValue[mesh.interiorFaces.value]
>>> answer = (R - L) * (1.0 / 3.0) + L
>>> print(numerix.allclose(faceValue, answer, atol = 1e-10, rtol = 1e-10))
True
>>> mesh = Grid1D(dx = (10., 100.))
>>> var = CellVariable(mesh = mesh, value = (L, R))
>>> faceValue = var.arithmeticFaceValue[mesh.interiorFaces.value]
>>> answer = (R - L) * (5.0 / 55.0) + L
>>> print(numerix.allclose(faceValue, answer, atol = 1e-10, rtol = 1e-10))
True
property cellVolumeAverage

Return the cell-volume-weighted average of the CellVariable:

<\phi>_\text{vol}
= \frac{\sum_\text{cells} \phi_\text{cell} V_\text{cell}}
    {\sum_\text{cells} V_\text{cell}}

>>> from fipy.meshes import Grid2D
>>> from fipy.variables.cellVariable import CellVariable
>>> mesh = Grid2D(nx = 3, ny = 1, dx = .5, dy = .1)
>>> var = CellVariable(value = (1, 2, 6), mesh = mesh)
>>> print(var.cellVolumeAverage)
3.0
constrain(value, where=None)

Constrains the CellVariable to value at a location specified by where.

>>> from fipy import *
>>> m = Grid1D(nx=3)
>>> v = CellVariable(mesh=m, value=m.cellCenters[0])
>>> v.constrain(0., where=m.facesLeft)
>>> v.faceGrad.constrain([1.], where=m.facesRight)
>>> print(v.faceGrad)
[[ 1.  1.  1.  1.]]
>>> print(v.faceValue)
[ 0.   1.   2.   2.5]

Changing the constraint changes the dependencies

>>> v.constrain(1., where=m.facesLeft)
>>> print(v.faceGrad)
[[-1.  1.  1.  1.]]
>>> print(v.faceValue)
[ 1.   1.   2.   2.5]

Constraints can be Variable

>>> c = Variable(0.)
>>> v.constrain(c, where=m.facesLeft)
>>> print(v.faceGrad)
[[ 1.  1.  1.  1.]]
>>> print(v.faceValue)
[ 0.   1.   2.   2.5]
>>> c.value = 1.
>>> print(v.faceGrad)
[[-1.  1.  1.  1.]]
>>> print(v.faceValue)
[ 1.   1.   2.   2.5]

Constraints can have a Variable mask.

>>> v = CellVariable(mesh=m)
>>> mask = FaceVariable(mesh=m, value=m.facesLeft)
>>> v.constrain(1., where=mask)
>>> print(v.faceValue)
[ 1.  0.  0.  0.]
>>> mask[:] = mask | m.facesRight
>>> print(v.faceValue)
[ 1.  0.  0.  1.]
copy()

Make an duplicate of the Variable

>>> a = Variable(value=3)
>>> b = a.copy()
>>> b
Variable(value=array(3))

The duplicate will not reflect changes made to the original

>>> a.setValue(5)
>>> b
Variable(value=array(3))

Check that this works for arrays.

>>> a = Variable(value=numerix.array((0, 1, 2)))
>>> b = a.copy()
>>> b
Variable(value=array([0, 1, 2]))
>>> a[1] = 3
>>> b
Variable(value=array([0, 1, 2]))
property faceGrad

Return \nabla \phi as a rank-1 FaceVariable using differencing for the normal direction(second-order gradient).

property faceGradAverage

Deprecated since version 3.3: use grad.arithmeticFaceValue() instead

Return \nabla \phi as a rank-1 FaceVariable using averaging for the normal direction(second-order gradient)

property faceValue

Returns a FaceVariable whose value corresponds to the arithmetic interpolation of the adjacent cells:

\phi_f = (\phi_1 - \phi_2) \frac{d_{f2}}{d_{12}} + \phi_2

>>> from fipy.meshes import Grid1D
>>> from fipy import numerix
>>> mesh = Grid1D(dx = (1., 1.))
>>> L = 1
>>> R = 2
>>> var = CellVariable(mesh = mesh, value = (L, R))
>>> faceValue = var.arithmeticFaceValue[mesh.interiorFaces.value]
>>> answer = (R - L) * (0.5 / 1.) + L
>>> print(numerix.allclose(faceValue, answer, atol = 1e-10, rtol = 1e-10))
True
>>> mesh = Grid1D(dx = (2., 4.))
>>> var = CellVariable(mesh = mesh, value = (L, R))
>>> faceValue = var.arithmeticFaceValue[mesh.interiorFaces.value]
>>> answer = (R - L) * (1.0 / 3.0) + L
>>> print(numerix.allclose(faceValue, answer, atol = 1e-10, rtol = 1e-10))
True
>>> mesh = Grid1D(dx = (10., 100.))
>>> var = CellVariable(mesh = mesh, value = (L, R))
>>> faceValue = var.arithmeticFaceValue[mesh.interiorFaces.value]
>>> answer = (R - L) * (5.0 / 55.0) + L
>>> print(numerix.allclose(faceValue, answer, atol = 1e-10, rtol = 1e-10))
True
property gaussGrad

Return \frac{1}{V_P} \sum_f \vec{n} \phi_f A_f as a rank-1 CellVariable (first-order gradient).

property globalValue

Concatenate and return values from all processors

When running on a single processor, the result is identical to value.

property grad

Return \nabla \phi as a rank-1 CellVariable (first-order gradient).

property harmonicFaceValue

Returns a FaceVariable whose value corresponds to the harmonic interpolation of the adjacent cells:

\phi_f = \frac{\phi_1 \phi_2}{(\phi_2 - \phi_1) \frac{d_{f2}}{d_{12}} + \phi_1}

>>> from fipy.meshes import Grid1D
>>> from fipy import numerix
>>> mesh = Grid1D(dx = (1., 1.))
>>> L = 1
>>> R = 2
>>> var = CellVariable(mesh = mesh, value = (L, R))
>>> faceValue = var.harmonicFaceValue[mesh.interiorFaces.value]
>>> answer = L * R / ((R - L) * (0.5 / 1.) + L)
>>> print(numerix.allclose(faceValue, answer, atol = 1e-10, rtol = 1e-10))
True
>>> mesh = Grid1D(dx = (2., 4.))
>>> var = CellVariable(mesh = mesh, value = (L, R))
>>> faceValue = var.harmonicFaceValue[mesh.interiorFaces.value]
>>> answer = L * R / ((R - L) * (1.0 / 3.0) + L)
>>> print(numerix.allclose(faceValue, answer, atol = 1e-10, rtol = 1e-10))
True
>>> mesh = Grid1D(dx = (10., 100.))
>>> var = CellVariable(mesh = mesh, value = (L, R))
>>> faceValue = var.harmonicFaceValue[mesh.interiorFaces.value]
>>> answer = L * R / ((R - L) * (5.0 / 55.0) + L)
>>> print(numerix.allclose(faceValue, answer, atol = 1e-10, rtol = 1e-10))
True
property leastSquaresGrad

Return \nabla \phi, which is determined by solving for \nabla \phi in the following matrix equation,

\nabla \phi \cdot \sum_f d_{AP}^2 \vec{n}_{AP} \otimes \vec{n}_{AP} =
\sum_f d_{AP}^2 \left( \vec{n} \cdot \nabla \phi \right)_{AP}

The matrix equation is derived by minimizing the following least squares sum,

F \left( \phi_x, \phi_y \right) = \sqrt{\sum_f \left( d_{AP}
\vec{n}_{AP} \cdot \nabla \phi - d_{AP} \left( \vec{n}_{AP} \cdot
\nabla \phi \right)_{AP} \right)^2 }

Tests

>>> from fipy import Grid2D
>>> m = Grid2D(nx=2, ny=2, dx=0.1, dy=2.0)
>>> print(numerix.allclose(CellVariable(mesh=m, value=(0, 1, 3, 6)).leastSquaresGrad.globalValue, \
...                                     [[8.0, 8.0, 24.0, 24.0],
...                                      [1.2, 2.0, 1.2, 2.0]]))
True
>>> from fipy import Grid1D
>>> print(numerix.allclose(CellVariable(mesh=Grid1D(dx=(2.0, 1.0, 0.5)),
...                                     value=(0, 1, 2)).leastSquaresGrad.globalValue, [[0.461538461538, 0.8, 1.2]]))
True
property minmodFaceValue

Returns a FaceVariable with a value that is the minimum of the absolute values of the adjacent cells. If the values are of opposite sign then the result is zero:

\phi_f = \begin{cases}
               \phi_1& \text{when $|\phi_1| \le |\phi_2|$},\\
               \phi_2& \text{when $|\phi_2| < |\phi_1|$},\\
               0 & \text{when $\phi1 \phi2 < 0$}
         \end{cases}

>>> from fipy import *
>>> print(CellVariable(mesh=Grid1D(nx=2), value=(1, 2)).minmodFaceValue)
[1 1 2]
>>> print(CellVariable(mesh=Grid1D(nx=2), value=(-1, -2)).minmodFaceValue)
[-1 -1 -2]
>>> print(CellVariable(mesh=Grid1D(nx=2), value=(-1, 2)).minmodFaceValue)
[-1  0  2]
property old

Return the values of the CellVariable from the previous solution sweep.

Combinations of CellVariable’s should also return old values.

>>> from fipy.meshes import Grid1D
>>> mesh = Grid1D(nx = 2)
>>> from fipy.variables.cellVariable import CellVariable
>>> var1 = CellVariable(mesh = mesh, value = (2, 3), hasOld = 1)
>>> var2 = CellVariable(mesh = mesh, value = (3, 4))
>>> v = var1 * var2
>>> print(v)
[ 6 12]
>>> var1.value = ((3, 2))
>>> print(v)
[9 8]
>>> print(v.old)
[ 6 12]

The following small test is to correct for a bug when the operator does not just use variables.

>>> v1 = var1 * 3
>>> print(v1)
[9 6]
>>> print(v1.old)
[6 9]
release(constraint)

Remove constraint from self

>>> from fipy import *
>>> m = Grid1D(nx=3)
>>> v = CellVariable(mesh=m, value=m.cellCenters[0])
>>> c = Constraint(0., where=m.facesLeft)
>>> v.constrain(c)
>>> print(v.faceValue)
[ 0.   1.   2.   2.5]
>>> v.release(constraint=c)
>>> print(v.faceValue)
[ 0.5  1.   2.   2.5]
setValue(value, unit=None, where=None)

Set the value of the Variable. Can take a masked array.

>>> a = Variable((1, 2, 3))
>>> a.setValue(5, where=(1, 0, 1))
>>> print(a)
[5 2 5]
>>> b = Variable((4, 5, 6))
>>> a.setValue(b, where=(1, 0, 1))
>>> print(a)
[4 2 6]
>>> print(b)
[4 5 6]
>>> a.value = 3
>>> print(a)
[3 3 3]
>>> b = numerix.array((3, 4, 5))
>>> a.value = b
>>> a[:] = 1
>>> print(b)
[3 4 5]
>>> a.setValue((4, 5, 6), where=(1, 0)) 
Traceback (most recent call last):
    ....
ValueError: shape mismatch: objects cannot be broadcast to a single shape
updateOld()

Set the values of the previous solution sweep to the current values.

>>> from fipy import *
>>> v = CellVariable(mesh=Grid1D(), hasOld=False)
>>> v.updateOld()
Traceback (most recent call last):
   ...
AssertionError: The updateOld method requires the CellVariable to have an old value. Set hasOld to True when instantiating the CellVariable.
class fipy.CentralDifferenceConvectionTerm(coeff=1.0, var=None)

Bases: fipy.terms.abstractConvectionTerm._AbstractConvectionTerm

This Term represents

\int_V \nabla \cdot (\vec{u} \phi)\,dV \simeq \sum_{f} (\vec{n}
\cdot \vec{u})_f \phi_f A_f

where \phi_f=\alpha_f \phi_P +(1-\alpha_f)\phi_A and \alpha_f is calculated using the central differencing scheme. For further details see Numerical Schemes.

Create a _AbstractConvectionTerm object.

>>> from fipy import *
>>> m = Grid1D(nx = 2)
>>> cv = CellVariable(mesh = m)
>>> fv = FaceVariable(mesh = m)
>>> vcv = CellVariable(mesh=m, rank=1)
>>> vfv = FaceVariable(mesh=m, rank=1)
>>> __ConvectionTerm(coeff = cv) 
Traceback (most recent call last):
    ...
VectorCoeffError: The coefficient must be a vector value.
>>> __ConvectionTerm(coeff = fv) 
Traceback (most recent call last):
    ...
VectorCoeffError: The coefficient must be a vector value.
>>> __ConvectionTerm(coeff = vcv)
__ConvectionTerm(coeff=_ArithmeticCellToFaceVariable(value=array([[ 0.,  0.,  0.]]), mesh=UniformGrid1D(dx=1.0, nx=2)))
>>> __ConvectionTerm(coeff = vfv)
__ConvectionTerm(coeff=FaceVariable(value=array([[ 0.,  0.,  0.]]), mesh=UniformGrid1D(dx=1.0, nx=2)))
>>> __ConvectionTerm(coeff = (1,))
__ConvectionTerm(coeff=(1,))
>>> ExplicitUpwindConvectionTerm(coeff = (0,)).solve(var=cv, solver=DummySolver()) 
Traceback (most recent call last):
    ...
TransientTermError: The equation requires a TransientTerm with explicit convection.
>>> (TransientTerm(0.) - ExplicitUpwindConvectionTerm(coeff = (0,))).solve(var=cv, solver=DummySolver(), dt=1.)
>>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = 1)).solve(var=cv, solver=DummySolver(), dt=1.) 
Traceback (most recent call last):
    ...
VectorCoeffError: The coefficient must be a vector value.
>>> m2 = Grid2D(nx=2, ny=1)
>>> cv2 = CellVariable(mesh=m2)
>>> vcv2 = CellVariable(mesh=m2, rank=1)
>>> vfv2 = FaceVariable(mesh=m2, rank=1)
>>> __ConvectionTerm(coeff=vcv2)
__ConvectionTerm(coeff=_ArithmeticCellToFaceVariable(value=array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.]]), mesh=UniformGrid2D(dx=1.0, nx=2, dy=1.0, ny=1)))
>>> __ConvectionTerm(coeff=vfv2)
__ConvectionTerm(coeff=FaceVariable(value=array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.]]), mesh=UniformGrid2D(dx=1.0, nx=2, dy=1.0, ny=1)))
>>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = ((0,), (0,)))).solve(var=cv2, solver=DummySolver(), dt=1.)
>>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = (0, 0))).solve(var=cv2, solver=DummySolver(), dt=1.)
Parameters

coeff (The Term’s coefficient value.) –

__module__ = 'fipy.terms.centralDiffConvectionTerm'
class fipy.Constraint(value, where=None)

Bases: object

Object to hold a Variable to value at where

see constrain()

__dict__ = mappingproxy({'__module__': 'fipy.boundaryConditions.constraint', '__init__': <function Constraint.__init__>, '__repr__': <function Constraint.__repr__>, '__dict__': <attribute '__dict__' of 'Constraint' objects>, '__weakref__': <attribute '__weakref__' of 'Constraint' objects>, '__doc__': None, '__annotations__': {}})
__init__(value, where=None)

Object to hold a Variable to value at where

see constrain()

__module__ = 'fipy.boundaryConditions.constraint'
__repr__()

Return repr(self).

__weakref__

list of weak references to the object (if defined)

fipy.ConvectionTerm

alias of fipy.terms.powerLawConvectionTerm.PowerLawConvectionTerm

fipy.CylindricalGrid1D(dr=None, nr=None, Lr=None, dx=1.0, nx=None, Lx=None, origin=(0), overlap=2, communicator=SerialPETScCommWrapper())

Factory function to select between CylindricalUniformGrid1D and CylindricalNonUniformGrid1D. If Lr is specified the length of the domain is always Lr regardless of dr, unless dr is a list of spacings, in which case Lr will be the sum of dr.

Parameters
  • dr (float) – Grid spacing in the radial direction. Alternative: dx.

  • nr (int) – Number of cells in the radial direction. Alternative: nx.

  • Lr (float) – Domain length in the radial direction. Alternative: Lx.

  • overlap (int) – the number of overlapping cells for parallel simulations. Generally 2 is adequate. Higher order equations or discretizations require more.

  • communicator (CommWrapper) – Generally, fipy.tools.serialComm or fipy.tools.parallelComm. Select ~fipy.tools.serialComm to create a serial mesh when running in parallel; mostly used for test purposes.

fipy.CylindricalGrid2D(dr=None, dz=None, nr=None, nz=None, Lr=None, Lz=None, dx=1.0, dy=1.0, nx=None, ny=None, Lx=None, Ly=None, origin=((0), (0)), overlap=2, communicator=SerialPETScCommWrapper())

Factory function to select between CylindricalUniformGrid2D and CylindricalNonUniformGrid2D. If Lr is specified the length of the domain is always Lr regardless of dr, unless dr is a list of spacings, in which case Lr will be the sum of dr.

Parameters
  • dr (float) – Grid spacing in the radial direction. Alternative: dx.

  • dz (float) – grid spacing in the vertical direction. Alternative: dy.

  • nr (int) – Number of cells in the radial direction. Alternative: nx.

  • nz (int) – Number of cells in the vertical direction. Alternative: ny.

  • Lr (float) – Domain length in the radial direction. Alternative: Lx.

  • Lz (float) – Domain length in the vertical direction. Alternative: Ly.

  • overlap (int) – the number of overlapping cells for parallel simulations. Generally 2 is adequate. Higher order equations or discretizations require more.

  • communicator (CommWrapper) – Generally, fipy.tools.serialComm or fipy.tools.parallelComm. Select ~fipy.tools.serialComm to create a serial mesh when running in parallel; mostly used for test purposes.

fipy.DefaultAsymmetricSolver

alias of fipy.solvers.petsc.linearGMRESSolver.LinearGMRESSolver

fipy.DefaultSolver

alias of fipy.solvers.petsc.linearGMRESSolver.LinearGMRESSolver

class fipy.DiffusionTerm(coeff=(1.0), var=None)

Bases: fipy.terms.diffusionTermNoCorrection.DiffusionTermNoCorrection

This term represents a higher order diffusion term. The order of the term is determined by the number of coeffs, such that:

DiffusionTerm(D1)

represents a typical 2nd-order diffusion term of the form

\nabla\cdot\left(D_1 \nabla \phi\right)

and:

DiffusionTerm((D1,D2))

represents a 4th-order Cahn-Hilliard term of the form

\nabla \cdot \left\{ D_1 \nabla \left[ \nabla\cdot\left( D_2 \nabla \phi\right) \right] \right\}

and so on.

Create a Term.

Parameters

coeff (float or CellVariable or FaceVariable) – Coefficient for the term. FaceVariable objects are only acceptable for diffusion or convection terms.

__module__ = 'fipy.terms.diffusionTerm'
class fipy.DiffusionTermCorrection(coeff=(1.0), var=None)

Bases: fipy.terms.abstractDiffusionTerm._AbstractDiffusionTerm

Create a Term.

Parameters

coeff (float or CellVariable or FaceVariable) – Coefficient for the term. FaceVariable objects are only acceptable for diffusion or convection terms.

__module__ = 'fipy.terms.diffusionTermCorrection'
class fipy.DiffusionTermNoCorrection(coeff=(1.0), var=None)

Bases: fipy.terms.abstractDiffusionTerm._AbstractDiffusionTerm

Create a Term.

Parameters

coeff (float or CellVariable or FaceVariable) – Coefficient for the term. FaceVariable objects are only acceptable for diffusion or convection terms.

__module__ = 'fipy.terms.diffusionTermNoCorrection'
class fipy.DistanceVariable(*args, **kwds)

Bases: fipy.variables.cellVariable.CellVariable

A DistanceVariable object calculates \phi so it satisfies,

\abs{\nabla \phi} = 1

using the fast marching method with an initial condition defined by the zero level set. The solution can either be first or second order.

Here we will define a few test cases. Firstly a 1D test case

>>> from fipy.meshes import Grid1D
>>> from fipy.tools import serialComm
>>> mesh = Grid1D(dx = .5, nx = 8, communicator=serialComm)
>>> from .distanceVariable import DistanceVariable
>>> var = DistanceVariable(mesh = mesh, value = (-1., -1., -1., -1., 1., 1., 1., 1.))
>>> var.calcDistanceFunction() 
>>> answer = (-1.75, -1.25, -.75, -0.25, 0.25, 0.75, 1.25, 1.75)
>>> print(var.allclose(answer)) 
1

A 1D test case with very small dimensions.

>>> dx = 1e-10
>>> mesh = Grid1D(dx = dx, nx = 8, communicator=serialComm)
>>> var = DistanceVariable(mesh = mesh, value = (-1., -1., -1., -1., 1., 1., 1., 1.))
>>> var.calcDistanceFunction() 
>>> answer = numerix.arange(8) * dx - 3.5 * dx
>>> print(var.allclose(answer)) 
1

A 2D test case to test _calcTrialValue for a pathological case.

>>> dx = 1.
>>> dy = 2.
>>> from fipy.meshes import Grid2D
>>> mesh = Grid2D(dx = dx, dy = dy, nx = 2, ny = 3, communicator=serialComm)
>>> var = DistanceVariable(mesh = mesh, value = (-1., 1., 1., 1., -1., 1.))
>>> var.calcDistanceFunction() 
>>> vbl = -dx * dy / numerix.sqrt(dx**2 + dy**2) / 2.
>>> vbr = dx / 2
>>> vml = dy / 2.
>>> crossProd = dx * dy
>>> dsq = dx**2 + dy**2
>>> top = vbr * dx**2 + vml * dy**2
>>> sqrt = crossProd**2 *(dsq - (vbr - vml)**2)
>>> sqrt = numerix.sqrt(max(sqrt, 0))
>>> vmr = (top + sqrt) / dsq
>>> answer = (vbl, vbr, vml, vmr, vbl, vbr)
>>> print(var.allclose(answer)) 
1

The extendVariable method solves the following equation for a given extensionVariable.

\nabla u \cdot \nabla \phi = 0

using the fast marching method with an initial condition defined at the zero level set.

>>> from fipy.variables.cellVariable import CellVariable
>>> mesh = Grid2D(dx = 1., dy = 1., nx = 2, ny = 2, communicator=serialComm)
>>> var = DistanceVariable(mesh = mesh, value = (-1., 1., 1., 1.))
>>> var.calcDistanceFunction() 
>>> extensionVar = CellVariable(mesh = mesh, value = (-1, .5, 2, -1))
>>> tmp = 1 / numerix.sqrt(2)
>>> print(var.allclose((-tmp / 2, 0.5, 0.5, 0.5 + tmp))) 
1
>>> var.extendVariable(extensionVar, order=1) 
>>> print(extensionVar.allclose((1.25, .5, 2, 1.25))) 
1
>>> mesh = Grid2D(dx = 1., dy = 1., nx = 3, ny = 3, communicator=serialComm)
>>> var = DistanceVariable(mesh = mesh, value = (-1., 1., 1.,
...                                               1., 1., 1.,
...                                               1., 1., 1.))
>>> var.calcDistanceFunction(order=1) 
>>> extensionVar = CellVariable(mesh = mesh, value = (-1., .5, -1.,
...                                                    2., -1., -1.,
...                                                   -1., -1., -1.))
>>> v1 = 0.5 + tmp
>>> v2 = 1.5
>>> tmp1 = (v1 + v2) / 2 + numerix.sqrt(2. - (v1 - v2)**2) / 2
>>> tmp2 = tmp1 + 1 / numerix.sqrt(2)
>>> print(var.allclose((-tmp / 2, 0.5, 1.5, 0.5, 0.5 + tmp,
...                      tmp1, 1.5, tmp1, tmp2))) 
1
>>> answer = (1.25, .5, .5, 2, 1.25, 0.9544, 2, 1.5456, 1.25)
>>> var.extendVariable(extensionVar, order=1) 
>>> print(extensionVar.allclose(answer, rtol = 1e-4)) 
1

Test case for a bug that occurs when initializing the distance variable at the interface. Currently it is assumed that adjacent cells that are opposite sign neighbors have perpendicular normal vectors. In fact the two closest cells could have opposite normals.

>>> mesh = Grid1D(dx = 1., nx = 3, communicator=serialComm)
>>> var = DistanceVariable(mesh = mesh, value = (-1., 1., -1.))
>>> var.calcDistanceFunction() 
>>> print(var.allclose((-0.5, 0.5, -0.5))) 
1

Testing second order. This example failed with Scikit-fmm.

>>> mesh = Grid2D(dx = 1., dy = 1., nx = 4, ny = 4, communicator=serialComm)
>>> var = DistanceVariable(mesh = mesh, value = (-1., -1., 1., 1.,
...                                               -1., -1., 1., 1.,
...                                               1., 1., 1., 1.,
...                                               1, 1, 1, 1))
>>> var.calcDistanceFunction(order=2) 
>>> answer = [-1.30473785, -0.5, 0.5, 1.49923009,
...           -0.5, -0.35355339, 0.5, 1.45118446,
...            0.5, 0.5, 0.97140452, 1.76215286,
...            1.49923009, 1.45118446, 1.76215286, 2.33721352]
>>> print(numerix.allclose(var, answer, rtol=1e-9)) 
True

** A test for a bug in both LSMLIB and Scikit-fmm **

The following test gives different result depending on whether LSMLIB or Scikit-fmm is used. There is a deeper problem that is related to this issue. When a value becomes “known” after previously being a “trial” value it updates its neighbors’ values. In a second order scheme the neighbors one step away also need to be updated (if the in between cell is “known” and the far cell is a “trial” cell), but are not in either package. By luck (due to trial values having the same value), the values calculated in Scikit-fmm for the following example are correct although an example that didn’t work for Scikit-fmm could also be constructed.

>>> mesh = Grid2D(dx = 1., dy = 1., nx = 4, ny = 4, communicator=serialComm)
>>> var = DistanceVariable(mesh = mesh, value = (-1., -1., -1., -1.,
...                                               1.,  1., -1., -1.,
...                                               1.,  1., -1., -1.,
...                                               1.,  1., -1., -1.))
>>> var.calcDistanceFunction(order=2) 
>>> var.calcDistanceFunction(order=2) 
>>> answer = [-0.5,        -0.58578644, -1.08578644, -1.85136395,
...            0.5,         0.29289322, -0.58578644, -1.54389939,
...            1.30473785,  0.5,        -0.5,        -1.5,
...            1.49547948,  0.5,        -0.5,        -1.5]

The 3rd and 7th element are different for LSMLIB. This is because the 15th element is not “known” when the “trial” value for the 7th element is calculated. Scikit-fmm calculates the values in a slightly different order so gets a seemingly better answer, but this is just chance.

>>> print(numerix.allclose(var, answer, rtol=1e-9)) 
True

Creates a distanceVariable object.

Parameters
  • mesh (Mesh) – The mesh that defines the geometry of this variable.

  • name (str) – The name of the variable.

  • value (float or array_like) – The initial value.

  • unit (str or PhysicalUnit) – The physical units of the variable

  • hasOld (bool) – Whether the variable maintains an old value.

__init__(mesh, name='', value=0.0, unit=None, hasOld=0)

Creates a distanceVariable object.

Parameters
  • mesh (Mesh) – The mesh that defines the geometry of this variable.

  • name (str) – The name of the variable.

  • value (float or array_like) – The initial value.

  • unit (str or PhysicalUnit) – The physical units of the variable

  • hasOld (bool) – Whether the variable maintains an old value.

__module__ = 'fipy.variables.distanceVariable'
calcDistanceFunction(order=2)

Calculates the distanceVariable as a distance function.

Parameters

order ({1, 2}) – The order of accuracy for the distance function calculation

property cellInterfaceAreas

Returns the length of the interface that crosses the cell

A simple 1D test:

>>> from fipy.meshes import Grid1D
>>> mesh = Grid1D(dx = 1., nx = 4)
>>> distanceVariable = DistanceVariable(mesh = mesh,
...                                     value = (-1.5, -0.5, 0.5, 1.5))
>>> answer = CellVariable(mesh=mesh, value=(0, 0., 1., 0))
>>> print(numerix.allclose(distanceVariable.cellInterfaceAreas,
...                        answer))
True

A 2D test case:

>>> from fipy.meshes import Grid2D
>>> from fipy.variables.cellVariable import CellVariable
>>> mesh = Grid2D(dx = 1., dy = 1., nx = 3, ny = 3)
>>> distanceVariable = DistanceVariable(mesh = mesh,
...                                     value = (1.5, 0.5, 1.5,
...                                              0.5, -0.5, 0.5,
...                                              1.5, 0.5, 1.5))
>>> answer = CellVariable(mesh=mesh,
...                       value=(0, 1, 0, 1, 0, 1, 0, 1, 0))
>>> print(numerix.allclose(distanceVariable.cellInterfaceAreas, answer))
True

Another 2D test case:

>>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2)
>>> from fipy.variables.cellVariable import CellVariable
>>> distanceVariable = DistanceVariable(mesh = mesh,
...                                     value = (-0.5, 0.5, 0.5, 1.5))
>>> answer = CellVariable(mesh=mesh,
...                       value=(0, numerix.sqrt(2) / 4,  numerix.sqrt(2) / 4, 0))
>>> print(numerix.allclose(distanceVariable.cellInterfaceAreas,
...                        answer))
True

Test to check that the circumference of a circle is, in fact, 2\pi r.

>>> mesh = Grid2D(dx = 0.05, dy = 0.05, nx = 20, ny = 20)
>>> r = 0.25
>>> x, y = mesh.cellCenters
>>> rad = numerix.sqrt((x - .5)**2 + (y - .5)**2) - r
>>> distanceVariable = DistanceVariable(mesh = mesh, value = rad)
>>> print(numerix.allclose(distanceVariable.cellInterfaceAreas.sum(), 1.57984690073))
1
extendVariable(extensionVariable, order=2)

Calculates the extension of extensionVariable from the zero level set.

Parameters

extensionVariable (CellVariable) – The variable to extend from the zero level set.

getLSMshape()
class fipy.DummySolver(*args, **kwargs)

Bases: fipy.solvers.petsc.petscSolver.PETScSolver

Solver that doesn’t do anything.

PETSc is intolerant of having zeros on the diagonal

Create a Solver object.

Parameters
  • tolerance (float) – Required error tolerance.

  • iterations (int) – Maximum number of iterative steps to perform.

  • precon – Preconditioner to use. Not all solver suites support preconditioners.

__module__ = 'fipy.solvers.petsc.dummySolver'
class fipy.DummyViewer(vars, title=None, **kwlimits)

Bases: fipy.viewers.viewer.AbstractViewer

Create a AbstractViewer object.

Parameters
  • vars (CellVariable or list) – the CellVariable objects to display.

  • title (str, optional) – displayed at the top of the Viewer window

  • xmin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • xmax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • zmin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • zmax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

__module__ = 'fipy.viewers'
plot(filename=None)

Update the display of the viewed variables.

Parameters

filename (str) – If not None, the name of a file to save the image into.

class fipy.ExplicitDiffusionTerm(coeff=(1.0), var=None)

Bases: fipy.terms.abstractDiffusionTerm._AbstractDiffusionTerm

The discretization for the ExplicitDiffusionTerm is given by

\int_V \nabla \cdot (\Gamma\nabla\phi) dV \simeq \sum_f \Gamma_f
\frac{\phi_A^\text{old}-\phi_P^\text{old}}{d_{AP}} A_f

where \phi_A^\text{old} and \phi_P^\text{old} are the old values of the variable. The term is added to the RHS vector and makes no contribution to the solution matrix.

Create a Term.

Parameters

coeff (float or CellVariable or FaceVariable) – Coefficient for the term. FaceVariable objects are only acceptable for diffusion or convection terms.

__module__ = 'fipy.terms.explicitDiffusionTerm'
class fipy.ExplicitUpwindConvectionTerm(coeff=1.0, var=None)

Bases: fipy.terms.abstractUpwindConvectionTerm._AbstractUpwindConvectionTerm

The discretization for this Term is given by

\int_V \nabla \cdot (\vec{u} \phi)\,dV \simeq \sum_{f} (\vec{n}
\cdot \vec{u})_f \phi_f A_f

where \phi_f=\alpha_f \phi_P^\text{old} +(1-\alpha_f)\phi_A^\text{old} and \alpha_f is calculated using the upwind scheme. For further details see Numerical Schemes.

Create a _AbstractConvectionTerm object.

>>> from fipy import *
>>> m = Grid1D(nx = 2)
>>> cv = CellVariable(mesh = m)
>>> fv = FaceVariable(mesh = m)
>>> vcv = CellVariable(mesh=m, rank=1)
>>> vfv = FaceVariable(mesh=m, rank=1)
>>> __ConvectionTerm(coeff = cv) 
Traceback (most recent call last):
    ...
VectorCoeffError: The coefficient must be a vector value.
>>> __ConvectionTerm(coeff = fv) 
Traceback (most recent call last):
    ...
VectorCoeffError: The coefficient must be a vector value.
>>> __ConvectionTerm(coeff = vcv)
__ConvectionTerm(coeff=_ArithmeticCellToFaceVariable(value=array([[ 0.,  0.,  0.]]), mesh=UniformGrid1D(dx=1.0, nx=2)))
>>> __ConvectionTerm(coeff = vfv)
__ConvectionTerm(coeff=FaceVariable(value=array([[ 0.,  0.,  0.]]), mesh=UniformGrid1D(dx=1.0, nx=2)))
>>> __ConvectionTerm(coeff = (1,))
__ConvectionTerm(coeff=(1,))
>>> ExplicitUpwindConvectionTerm(coeff = (0,)).solve(var=cv, solver=DummySolver()) 
Traceback (most recent call last):
    ...
TransientTermError: The equation requires a TransientTerm with explicit convection.
>>> (TransientTerm(0.) - ExplicitUpwindConvectionTerm(coeff = (0,))).solve(var=cv, solver=DummySolver(), dt=1.)
>>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = 1)).solve(var=cv, solver=DummySolver(), dt=1.) 
Traceback (most recent call last):
    ...
VectorCoeffError: The coefficient must be a vector value.
>>> m2 = Grid2D(nx=2, ny=1)
>>> cv2 = CellVariable(mesh=m2)
>>> vcv2 = CellVariable(mesh=m2, rank=1)
>>> vfv2 = FaceVariable(mesh=m2, rank=1)
>>> __ConvectionTerm(coeff=vcv2)
__ConvectionTerm(coeff=_ArithmeticCellToFaceVariable(value=array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.]]), mesh=UniformGrid2D(dx=1.0, nx=2, dy=1.0, ny=1)))
>>> __ConvectionTerm(coeff=vfv2)
__ConvectionTerm(coeff=FaceVariable(value=array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.]]), mesh=UniformGrid2D(dx=1.0, nx=2, dy=1.0, ny=1)))
>>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = ((0,), (0,)))).solve(var=cv2, solver=DummySolver(), dt=1.)
>>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = (0, 0))).solve(var=cv2, solver=DummySolver(), dt=1.)
Parameters

coeff (The Term’s coefficient value.) –

__module__ = 'fipy.terms.explicitUpwindConvectionTerm'
exception fipy.ExplicitVariableError(s='Terms with explicit Variables cannot mix with Terms with implicit Variables.')

Bases: Exception

__init__(s='Terms with explicit Variables cannot mix with Terms with implicit Variables.')

Initialize self. See help(type(self)) for accurate signature.

__module__ = 'fipy.terms'
__weakref__

list of weak references to the object (if defined)

class fipy.ExponentialConvectionTerm(coeff=1.0, var=None)

Bases: fipy.terms.asymmetricConvectionTerm._AsymmetricConvectionTerm

The discretization for this Term is given by

\int_V \nabla \cdot (\vec{u} \phi)\,dV \simeq \sum_{f} (\vec{n}
\cdot \vec{u})_f \phi_f A_f

where \phi_f=\alpha_f \phi_P +(1-\alpha_f)\phi_A and \alpha_f is calculated using the exponential scheme. For further details see Numerical Schemes.

Create a _AbstractConvectionTerm object.

>>> from fipy import *
>>> m = Grid1D(nx = 2)
>>> cv = CellVariable(mesh = m)
>>> fv = FaceVariable(mesh = m)
>>> vcv = CellVariable(mesh=m, rank=1)
>>> vfv = FaceVariable(mesh=m, rank=1)
>>> __ConvectionTerm(coeff = cv) 
Traceback (most recent call last):
    ...
VectorCoeffError: The coefficient must be a vector value.
>>> __ConvectionTerm(coeff = fv) 
Traceback (most recent call last):
    ...
VectorCoeffError: The coefficient must be a vector value.
>>> __ConvectionTerm(coeff = vcv)
__ConvectionTerm(coeff=_ArithmeticCellToFaceVariable(value=array([[ 0.,  0.,  0.]]), mesh=UniformGrid1D(dx=1.0, nx=2)))
>>> __ConvectionTerm(coeff = vfv)
__ConvectionTerm(coeff=FaceVariable(value=array([[ 0.,  0.,  0.]]), mesh=UniformGrid1D(dx=1.0, nx=2)))
>>> __ConvectionTerm(coeff = (1,))
__ConvectionTerm(coeff=(1,))
>>> ExplicitUpwindConvectionTerm(coeff = (0,)).solve(var=cv, solver=DummySolver()) 
Traceback (most recent call last):
    ...
TransientTermError: The equation requires a TransientTerm with explicit convection.
>>> (TransientTerm(0.) - ExplicitUpwindConvectionTerm(coeff = (0,))).solve(var=cv, solver=DummySolver(), dt=1.)
>>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = 1)).solve(var=cv, solver=DummySolver(), dt=1.) 
Traceback (most recent call last):
    ...
VectorCoeffError: The coefficient must be a vector value.
>>> m2 = Grid2D(nx=2, ny=1)
>>> cv2 = CellVariable(mesh=m2)
>>> vcv2 = CellVariable(mesh=m2, rank=1)
>>> vfv2 = FaceVariable(mesh=m2, rank=1)
>>> __ConvectionTerm(coeff=vcv2)
__ConvectionTerm(coeff=_ArithmeticCellToFaceVariable(value=array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.]]), mesh=UniformGrid2D(dx=1.0, nx=2, dy=1.0, ny=1)))
>>> __ConvectionTerm(coeff=vfv2)
__ConvectionTerm(coeff=FaceVariable(value=array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.]]), mesh=UniformGrid2D(dx=1.0, nx=2, dy=1.0, ny=1)))
>>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = ((0,), (0,)))).solve(var=cv2, solver=DummySolver(), dt=1.)
>>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = (0, 0))).solve(var=cv2, solver=DummySolver(), dt=1.)
Parameters

coeff (The Term’s coefficient value.) –

__module__ = 'fipy.terms.exponentialConvectionTerm'
class fipy.ExponentialNoiseVariable(*args, **kwds)

Bases: fipy.variables.noiseVariable.NoiseVariable

Represents an exponential distribution of random numbers with the probability distribution

\mu^{-1} e^{-\frac{x}{\mu}}

with a mean parameter \mu.

Seed the random module for the sake of deterministic test results.

>>> from fipy import numerix
>>> numerix.random.seed(1)

We generate noise on a uniform Cartesian mesh

>>> from fipy.variables.variable import Variable
>>> mean = Variable()
>>> from fipy.meshes import Grid2D
>>> noise = ExponentialNoiseVariable(mesh = Grid2D(nx = 100, ny = 100), mean = mean)

We histogram the root-volume-weighted noise distribution

>>> from fipy.variables.histogramVariable import HistogramVariable
>>> histogram = HistogramVariable(distribution = noise, dx = 0.1, nx = 100)

and compare to a Gaussian distribution

>>> from fipy.variables.cellVariable import CellVariable
>>> expdist = CellVariable(mesh = histogram.mesh)
>>> x = histogram.mesh.cellCenters[0]
>>> if __name__ == '__main__':
...     from fipy import Viewer
...     viewer = Viewer(vars=noise, datamin=0, datamax=5)
...     histoplot = Viewer(vars=(histogram, expdist),
...                        datamin=0, datamax=1.5)
>>> from fipy.tools.numerix import arange, exp
>>> for mu in arange(0.5, 3, 0.5):
...     mean.value = (mu)
...     expdist.value = ((1/mean)*exp(-x/mean))
...     if __name__ == '__main__':
...         import sys
...         print("mean: %g" % mean, file=sys.stderr)
...         viewer.plot()
...         histoplot.plot()
>>> print(abs(noise.faceGrad.divergence.cellVolumeAverage) < 5e-15)
1
random values with an exponential distribution histogram of random values with an exponential distribution
Parameters
  • mesh (Mesh) – The mesh on which to define the noise.

  • mean (float) – The mean of the distribution \mu.

__init__(mesh, mean=0.0, name='', hasOld=0)
Parameters
  • mesh (Mesh) – The mesh on which to define the noise.

  • mean (float) – The mean of the distribution \mu.

__module__ = 'fipy.variables.exponentialNoiseVariable'
random()
class fipy.FaceVariable(*args, **kwds)

Bases: fipy.variables.meshVariable._MeshVariable

Parameters
  • mesh (Mesh) – the mesh that defines the geometry of this Variable

  • name (str) – the user-readable name of the Variable

  • value (float or array_like) – the initial value

  • rank (int) – the rank (number of dimensions) of each element of this Variable. Default: 0

  • elementshape (tuple of int) – the shape of each element of this variable Default: rank * (mesh.dim,)

  • unit (str or PhysicalUnit) – The physical units of the variable

__module__ = 'fipy.variables.faceVariable'
copy()

Make an duplicate of the Variable

>>> a = Variable(value=3)
>>> b = a.copy()
>>> b
Variable(value=array(3))

The duplicate will not reflect changes made to the original

>>> a.setValue(5)
>>> b
Variable(value=array(3))

Check that this works for arrays.

>>> a = Variable(value=numerix.array((0, 1, 2)))
>>> b = a.copy()
>>> b
Variable(value=array([0, 1, 2]))
>>> a[1] = 3
>>> b
Variable(value=array([0, 1, 2]))
property divergence

the divergence of self, \vec{u},

\nabla\cdot\vec{u} \approx \frac{\sum_f (\vec{u}\cdot\hat{n})_f A_f}{V_P}

Returns

divergence – one rank lower than self

Return type

fipy.variables.cellVariable.CellVariable

Examples

>>> from fipy.meshes import Grid2D
>>> from fipy.variables.cellVariable import CellVariable
>>> mesh = Grid2D(nx=3, ny=2)
>>> from builtins import range
>>> var = CellVariable(mesh=mesh, value=list(range(3*2)))
>>> print(var.faceGrad.divergence)
[ 4.  3.  2. -2. -3. -4.]
property globalValue
setValue(value, unit=None, where=None)

Set the value of the Variable. Can take a masked array.

>>> a = Variable((1, 2, 3))
>>> a.setValue(5, where=(1, 0, 1))
>>> print(a)
[5 2 5]
>>> b = Variable((4, 5, 6))
>>> a.setValue(b, where=(1, 0, 1))
>>> print(a)
[4 2 6]
>>> print(b)
[4 5 6]
>>> a.value = 3
>>> print(a)
[3 3 3]
>>> b = numerix.array((3, 4, 5))
>>> a.value = b
>>> a[:] = 1
>>> print(b)
[3 4 5]
>>> a.setValue((4, 5, 6), where=(1, 0)) 
Traceback (most recent call last):
    ....
ValueError: shape mismatch: objects cannot be broadcast to a single shape
class fipy.FirstOrderAdvectionTerm(coeff=None)

Bases: fipy.terms.nonDiffusionTerm._NonDiffusionTerm

The FirstOrderAdvectionTerm object constructs the b vector contribution for the advection term given by

u \abs{\nabla \phi}

from the advection equation given by:

\frac{\partial \phi}{\partial t} + u \abs{\nabla \phi} = 0

The construction of the gradient magnitude term requires upwinding. The formula used here is given by:

u_P \abs{\nabla \phi}_P = \max \left( u_P , 0 \right) \left[  \sum_A \min \left( \frac{ \phi_A - \phi_P } { d_{AP}}, 0 \right)^2 \right]^{1/2} +  \min \left( u_P , 0 \right) \left[  \sum_A \max \left( \frac{ \phi_A - \phi_P } { d_{AP}}, 0 \right)^2 \right]^{1/2}

Here are some simple test cases for this problem:

>>> from fipy.meshes import Grid1D
>>> from fipy.solvers import *
>>> SparseMatrix = LinearLUSolver()._matrixClass
>>> mesh = Grid1D(dx = 1., nx = 3)
>>> from fipy.variables.cellVariable import CellVariable

Trivial test:

>>> var = CellVariable(value = numerix.zeros(3, 'd'), mesh = mesh)
>>> v, L, b = FirstOrderAdvectionTerm(0.)._buildMatrix(var, SparseMatrix)
>>> print(numerix.allclose(b, numerix.zeros(3, 'd'), atol = 1e-10)) 
True

Less trivial test:

>>> var = CellVariable(value = numerix.arange(3), mesh = mesh)
>>> v, L, b = FirstOrderAdvectionTerm(1.)._buildMatrix(var, SparseMatrix)
>>> print(numerix.allclose(b, numerix.array((0., -1., -1.)), atol = 1e-10)) 
True

Even less trivial

>>> var = CellVariable(value = numerix.arange(3), mesh = mesh)
>>> v, L, b = FirstOrderAdvectionTerm(-1.)._buildMatrix(var, SparseMatrix)
>>> print(numerix.allclose(b, numerix.array((1., 1., 0.)), atol = 1e-10)) 
True

Another trivial test case (more trivial than a trivial test case standing on a harpsichord singing “trivial test cases are here again”)

>>> vel = numerix.array((-1, 2, -3))
>>> var = CellVariable(value = numerix.array((4, 6, 1)), mesh = mesh)
>>> v, L, b = FirstOrderAdvectionTerm(vel)._buildMatrix(var, SparseMatrix)
>>> print(numerix.allclose(b, -vel * numerix.array((2, numerix.sqrt(5**2 + 2**2), 5)), atol = 1e-10)) 
True

Somewhat less trivial test case:

>>> from fipy.meshes import Grid2D
>>> mesh = Grid2D(dx = 1., dy = 1., nx = 2, ny = 2)
>>> vel = numerix.array((3, -5, -6, -3))
>>> var = CellVariable(value = numerix.array((3, 1, 6, 7)), mesh = mesh)
>>> v, L, b = FirstOrderAdvectionTerm(vel)._buildMatrix(var, SparseMatrix)
>>> answer = -vel * numerix.array((2, numerix.sqrt(2**2 + 6**2), 1, 0))
>>> print(numerix.allclose(b, answer, atol = 1e-10)) 
True

Create a Term.

Parameters

coeff (float or CellVariable or FaceVariable) – Coefficient for the term. FaceVariable objects are only acceptable for diffusion or convection terms.

__init__(coeff=None)

Create a Term.

Parameters

coeff (float or CellVariable or FaceVariable) – Coefficient for the term. FaceVariable objects are only acceptable for diffusion or convection terms.

__module__ = 'fipy.terms.firstOrderAdvectionTerm'
class fipy.FixedFlux(faces, value)

Bases: fipy.boundaryConditions.boundaryCondition.BoundaryCondition

The FixedFlux boundary condition adds a contribution, equivalent to a fixed flux (Neumann condition), to the equation’s RHS vector. The contribution, given by value, is only added to entries corresponding to the specified faces, and is weighted by the face areas.

Parameters
  • faces (FaceVariable of bool) – Mask of faces where this condition applies.

  • value (float) – Value to impose.

__init__(faces, value)
Parameters
  • faces (FaceVariable of bool) – Mask of faces where this condition applies.

  • value (float) – Value to impose.

__module__ = 'fipy.boundaryConditions.fixedFlux'
class fipy.FixedValue(faces, value)

Bases: fipy.boundaryConditions.boundaryCondition.BoundaryCondition

The FixedValue boundary condition adds a contribution, equivalent to a fixed value (Dirichlet condition), to the equation’s RHS vector and coefficient matrix. The contributions are given by -\mathtt{value}\times G_{\text{face}} for the RHS vector and G_{\text{face}} for the coefficient matrix. The parameter G_{\text{face}} represents the term’s geometric coefficient, which depends on the type of term and the mesh geometry.

Contributions are only added to entries corresponding to the specified faces.

Parameters
  • faces (FaceVariable of bool) – Mask of faces where this condition applies.

  • value (float) – Value to impose.

__module__ = 'fipy.boundaryConditions.fixedValue'
class fipy.GammaNoiseVariable(*args, **kwds)

Bases: fipy.variables.noiseVariable.NoiseVariable

Represents a gamma distribution of random numbers with the probability distribution

x^{\alpha - 1}\frac{\beta^\alpha e^{-\beta x}}{\Gamma(\alpha)}

with a shape parameter \alpha, a rate parameter \beta, and \Gamma(z) = \int_0^\infty t^{z - 1}e^{-t}\,dt.

Seed the random module for the sake of deterministic test results.

>>> from fipy import numerix
>>> numerix.random.seed(1)

We generate noise on a uniform Cartesian mesh

>>> from fipy.variables.variable import Variable
>>> alpha = Variable()
>>> beta = Variable()
>>> from fipy.meshes import Grid2D
>>> noise = GammaNoiseVariable(mesh = Grid2D(nx = 100, ny = 100), shape = alpha, rate = beta)

We histogram the root-volume-weighted noise distribution

>>> from fipy.variables.histogramVariable import HistogramVariable
>>> histogram = HistogramVariable(distribution = noise, dx = 0.1, nx = 300)

and compare to a Gaussian distribution

>>> from fipy.variables.cellVariable import CellVariable
>>> x = CellVariable(mesh=histogram.mesh, value=histogram.mesh.cellCenters[0])
>>> from scipy.special import gamma as Gamma 
>>> from fipy.tools.numerix import exp
>>> gammadist = (x**(alpha - 1) * (beta**alpha * exp(-beta * x)) / Gamma(alpha)) 
>>> if __name__ == '__main__':
...     from fipy import Viewer
...     viewer = Viewer(vars=noise, datamin=0, datamax=30)
...     histoplot = Viewer(vars=(histogram, gammadist),
...                        datamin=0, datamax=1)
>>> from fipy.tools.numerix import arange
>>> for shape in arange(1, 8, 1):
...     alpha.value = shape
...     for rate in arange(0.5, 2.5, 0.5):
...         beta.value = rate
...         if __name__ == '__main__':
...             import sys
...             print("alpha: %g, beta: %g" % (alpha, beta), file=sys.stderr)
...             viewer.plot()
...             histoplot.plot()
>>> print(abs(noise.faceGrad.divergence.cellVolumeAverage) < 5e-15)
1
random values with a gamma distribution histogram of random values with a gamma distribution
Parameters
  • mesh (Mesh) – The mesh on which to define the noise.

  • shape (float) – The shape parameter, \alpha.

  • rate (float) – The rate or inverse scale parameter, \beta.

__init__(mesh, shape, rate, name='', hasOld=0)
Parameters
  • mesh (Mesh) – The mesh on which to define the noise.

  • shape (float) – The shape parameter, \alpha.

  • rate (float) – The rate or inverse scale parameter, \beta.

__module__ = 'fipy.variables.gammaNoiseVariable'
random()
class fipy.GaussianNoiseVariable(*args, **kwds)

Bases: fipy.variables.noiseVariable.NoiseVariable

Represents a normal (Gaussian) distribution of random numbers with mean \mu and variance \langle \eta(\vec{r}) \eta(\vec{r}\,') \rangle = \sigma^2, which has the probability distribution

\frac{1}{\sigma\sqrt{2\pi}} \exp -\frac{(x - \mu)^2}{2\sigma^2}

For example, the variance of thermal noise that is uncorrelated in space and time is often expressed as

\left\langle
    \eta(\vec{r}, t) \eta(\vec{r}\,', t')
\right\rangle =
M k_B T \delta(\vec{r} - \vec{r}\,')\delta(t - t')

which can be obtained with:

sigmaSqrd = Mobility * kBoltzmann * Temperature / (mesh.cellVolumes * timeStep)
GaussianNoiseVariable(mesh = mesh, variance = sigmaSqrd)

Note

If the time step will change as the simulation progresses, either through use of an adaptive iterator or by making manual changes at different stages, remember to declare timeStep as a Variable and to change its value with its setValue() method.

>>> import sys
>>> from fipy.tools.numerix import *
>>> mean = 0.
>>> variance = 4.

Seed the random module for the sake of deterministic test results.

>>> from fipy import numerix
>>> numerix.random.seed(3)

We generate noise on a non-uniform Cartesian mesh with cell dimensions of x^2 and y^3.

>>> from fipy.meshes import Grid2D
>>> mesh = Grid2D(dx = arange(0.1, 5., 0.1)**2, dy = arange(0.1, 3., 0.1)**3)
>>> from fipy.variables.cellVariable import CellVariable
>>> volumes = CellVariable(mesh=mesh, value=mesh.cellVolumes)
>>> noise = GaussianNoiseVariable(mesh = mesh, mean = mean,
...                               variance = variance / volumes)

We histogram the root-volume-weighted noise distribution

>>> from fipy.variables.histogramVariable import HistogramVariable
>>> histogram = HistogramVariable(distribution = noise * sqrt(volumes),
...                               dx = 0.1, nx = 600, offset = -30)

and compare to a Gaussian distribution

>>> gauss = CellVariable(mesh = histogram.mesh)
>>> x = histogram.mesh.cellCenters[0]
>>> gauss.value = ((1/(sqrt(variance * 2 * pi))) * exp(-(x - mean)**2 / (2 * variance)))
>>> if __name__ == '__main__':
...     from fipy.viewers import Viewer
...     viewer = Viewer(vars=noise,
...                     datamin=-5, datamax=5)
...     histoplot = Viewer(vars=(histogram, gauss))
>>> from builtins import range
>>> for i in range(10):
...     noise.scramble()
...     if __name__ == '__main__':
...         viewer.plot()
...         histoplot.plot()
>>> print(abs(noise.faceGrad.divergence.cellVolumeAverage) < 5e-15)
1

Note that the noise exhibits larger amplitude in the small cells than in the large ones

random values with a Gaussian distribution

but that the root-volume-weighted histogram is Gaussian.

histogram of random values with a Gaussian distribution
Parameters
  • mesh (Mesh) – The mesh on which to define the noise.

  • mean (float) – The mean of the noise distribution, \mu.

  • variance (float) – The variance of the noise distribution, \sigma^2.

__init__(mesh, name='', mean=0.0, variance=1.0, hasOld=0)
Parameters
  • mesh (Mesh) – The mesh on which to define the noise.

  • mean (float) – The mean of the noise distribution, \mu.

  • variance (float) – The variance of the noise distribution, \sigma^2.

__module__ = 'fipy.variables.gaussianNoiseVariable'
parallelRandom()
fipy.GeneralSolver

alias of fipy.solvers.petsc.linearGMRESSolver.LinearGMRESSolver

class fipy.Gmsh2D(arg, coordDimensions=2, communicator=SerialPETScCommWrapper(), overlap=1, background=None)

Bases: fipy.meshes.mesh2D.Mesh2D

Construct a 2D Mesh using Gmsh

>>> radius = 5.
>>> side = 4.
>>> squaredCircle = Gmsh2D('''
... // A mesh consisting of a square inside a circle inside a circle
...
... // define the basic dimensions of the mesh
...
... cellSize = 1;
... radius = %(radius)g;
... side = %(side)g;
...
... // define the compass points of the inner circle
...
... Point(1) = {0, 0, 0, cellSize};
... Point(2) = {-radius, 0, 0, cellSize};
... Point(3) = {0, radius, 0, cellSize};
... Point(4) = {radius, 0, 0, cellSize};
... Point(5) = {0, -radius, 0, cellSize};
...
... // define the compass points of the outer circle
...
... Point(6) = {-2*radius, 0, 0, cellSize};
... Point(7) = {0, 2*radius, 0, cellSize};
... Point(8) = {2*radius, 0, 0, cellSize};
... Point(9) = {0, -2*radius, 0, cellSize};
...
... // define the corners of the square
...
... Point(10) = {side/2, side/2, 0, cellSize/2};
... Point(11) = {-side/2, side/2, 0, cellSize/2};
... Point(12) = {-side/2, -side/2, 0, cellSize/2};
... Point(13) = {side/2, -side/2, 0, cellSize/2};
...
... // define the inner circle
...
... Circle(1) = {2, 1, 3};
... Circle(2) = {3, 1, 4};
... Circle(3) = {4, 1, 5};
... Circle(4) = {5, 1, 2};
...
... // define the outer circle
...
... Circle(5) = {6, 1, 7};
... Circle(6) = {7, 1, 8};
... Circle(7) = {8, 1, 9};
... Circle(8) = {9, 1, 6};
...
... // define the square
...
... Line(9) = {10, 13};
... Line(10) = {13, 12};
... Line(11) = {12, 11};
... Line(12) = {11, 10};
...
... // define the three boundaries
...
... Line Loop(1) = {1, 2, 3, 4};
... Line Loop(2) = {5, 6, 7, 8};
... Line Loop(3) = {9, 10, 11, 12};
...
... // define the three domains
...
... Plane Surface(1) = {2, 1};
... Plane Surface(2) = {1, 3};
... Plane Surface(3) = {3};
...
... // label the three domains
...
... // attention: if you use any "Physical" labels, you *must* label
... // all elements that correspond to FiPy Cells (Physical Surface in 2D
... // and Physical Volume in 3D) or Gmsh will not include them and FiPy
... // will not be able to include them in the Mesh.
...
... // note: if you do not use any labels, all Cells will be included.
...
... Physical Surface("Outer") = {1};
... Physical Surface("Middle") = {2};
... Physical Surface("Inner") = {3};
...
... // label the "north-west" part of the exterior boundary
...
... // note: you only need to label the Face elements
... // (Physical Line in 2D and Physical Surface in 3D) that correspond
... // to boundaries you are interested in. FiPy does not need them to
... // construct the Mesh.
...
... Physical Line("NW") = {5};
... ''' % locals()) 

It can be easier to specify certain domains and boundaries within Gmsh than it is to define the same domains and boundaries with FiPy expressions.

Here we compare obtaining the same Cells and Faces using FiPy’s parametric descriptions and Gmsh’s labels.

>>> x, y = squaredCircle.cellCenters 
>>> middle = ((x**2 + y**2 <= radius**2)
...           & ~((x > -side/2) & (x < side/2)
...               & (y > -side/2) & (y < side/2))) 
>>> print((middle == squaredCircle.physicalCells["Middle"]).all()) 
True
>>> X, Y = squaredCircle.faceCenters 
>>> NW = ((X**2 + Y**2 > (1.99*radius)**2)
...       & (X**2 + Y**2 < (2.01*radius)**2)
...       & (X <= 0) & (Y >= 0)) 
>>> print((NW == squaredCircle.physicalFaces["NW"]).all()) 
True

It is possible to direct Gmsh to give the mesh different densities in different locations

>>> geo = '''
... // A mesh consisting of a square
...
... // define the corners of the square
...
... Point(1) = {1, 1, 0, 1};
... Point(2) = {0, 1, 0, 1};
... Point(3) = {0, 0, 0, 1};
... Point(4) = {1, 0, 0, 1};
...
... // define the square
...
... Line(1) = {1, 2};
... Line(2) = {2, 3};
... Line(3) = {3, 4};
... Line(4) = {4, 1};
...
... // define the boundary
...
... Line Loop(1) = {1, 2, 3, 4};
...
... // define the domain
...
... Plane Surface(1) = {1};
... '''
>>> from fipy import CellVariable, numerix
>>> error = []
>>> bkg = None
>>> from builtins import range
>>> for refine in range(4):
...     square = Gmsh2D(geo, background=bkg) 
...     x, y = square.cellCenters 
...     bkg = CellVariable(mesh=square, value=abs(x / 4) + 0.01) 
...     error.append(((2 * numerix.sqrt(square.cellVolumes) / bkg - 1)**2).cellVolumeAverage) 

Check that the mesh is (semi)monotonically approaching the desired density (the first step may increase, depending on the number of partitions)

>>> print(numerix.greater(error[:-1], error[1:]).all()) 
True

and that the final density is close enough to the desired density

>>> print(error[-1] < 0.02) 
True

The initial mesh doesn’t have to be from Gmsh

>>> from fipy import Tri2D
>>> trisquare = Tri2D(nx=1, ny=1)
>>> x, y = trisquare.cellCenters
>>> bkg = CellVariable(mesh=trisquare, value=abs(x / 4) + 0.01)
>>> std1 = (numerix.sqrt(2 * trisquare.cellVolumes) / bkg).std()
>>> square = Gmsh2D(geo, background=bkg) 
>>> x, y = square.cellCenters 
>>> bkg = CellVariable(mesh=square, value=abs(x / 4) + 0.01) 
>>> std2 = (numerix.sqrt(2 * square.cellVolumes) / bkg).std() 
>>> print(std1 > std2) 
True
Parameters
  • arg (str) – (i) the path to an MSH file, (ii) a path to a Gmsh geometry (.geo) file, or (iii) a Gmsh geometry script

  • coordDimensions (int) – Dimension of shapes

  • overlap (int) – The number of overlapping cells for parallel simulations. Generally 1 is adequate. Higher order equations or discretizations require more. If overlap is greater than one, communication reverts to serial, as Gmsh only provides one layer of ghost cells.

  • background (CellVariable) – Specifies the desired characteristic lengths of the mesh cells

__init__(arg, coordDimensions=2, communicator=SerialPETScCommWrapper(), overlap=1, background=None)

Initialize self. See help(type(self)) for accurate signature.

__module__ = 'fipy.meshes.gmshMesh'
__setstate__(state)
class fipy.Gmsh2DIn3DSpace(arg, communicator=SerialPETScCommWrapper(), overlap=1, background=None)

Bases: fipy.meshes.gmshMesh.Gmsh2D

Create a topologically 2D Mesh in 3D coordinates using Gmsh

Parameters
  • arg (str) – (i) the path to an MSH file, (ii) a path to a Gmsh geometry (.geo) file, or (iii) a Gmsh geometry script

  • coordDimensions (int) – Dimension of shapes

  • overlap (int) – The number of overlapping cells for parallel simulations. Generally 1 is adequate. Higher order equations or discretizations require more. If overlap is greater than one, communication reverts to serial, as Gmsh only provides one layer of ghost cells.

  • background (CellVariable) – Specifies the desired characteristic lengths of the mesh cells

__init__(arg, communicator=SerialPETScCommWrapper(), overlap=1, background=None)

Initialize self. See help(type(self)) for accurate signature.

__module__ = 'fipy.meshes.gmshMesh'
class fipy.Gmsh3D(arg, communicator=SerialPETScCommWrapper(), overlap=1, background=None)

Bases: fipy.meshes.mesh.Mesh

Create a 3D Mesh using Gmsh

Parameters
  • arg (str) – (i) the path to an MSH file, (ii) a path to a Gmsh geometry (.geo) file, or (iii) a Gmsh geometry script

  • overlap (int) – The number of overlapping cells for parallel simulations. Generally 1 is adequate. Higher order equations or discretizations require more. If overlap is greater than one, communication reverts to serial, as Gmsh only provides one layer of ghost cells.

  • background (CellVariable) – Specifies the desired characteristic lengths of the mesh cells

__init__(arg, communicator=SerialPETScCommWrapper(), overlap=1, background=None)

Initialize self. See help(type(self)) for accurate signature.

__module__ = 'fipy.meshes.gmshMesh'
__setstate__(state)
class fipy.GmshGrid2D(dx=1.0, dy=1.0, nx=1, ny=None, coordDimensions=2, communicator=SerialPETScCommWrapper(), overlap=1)

Bases: fipy.meshes.gmshMesh.Gmsh2D

Should serve as a drop-in replacement for Grid2D

__init__(dx=1.0, dy=1.0, nx=1, ny=None, coordDimensions=2, communicator=SerialPETScCommWrapper(), overlap=1)

Initialize self. See help(type(self)) for accurate signature.

__module__ = 'fipy.meshes.gmshMesh'
class fipy.GmshGrid3D(dx=1.0, dy=1.0, dz=1.0, nx=1, ny=None, nz=None, communicator=SerialPETScCommWrapper(), overlap=1)

Bases: fipy.meshes.gmshMesh.Gmsh3D

Should serve as a drop-in replacement for Grid3D

__init__(dx=1.0, dy=1.0, dz=1.0, nx=1, ny=None, nz=None, communicator=SerialPETScCommWrapper(), overlap=1)

Initialize self. See help(type(self)) for accurate signature.

__module__ = 'fipy.meshes.gmshMesh'
fipy.Grid1D(dx=1.0, nx=None, Lx=None, overlap=2, communicator=SerialPETScCommWrapper())

Factory function to select between UniformGrid1D and NonUniformGrid1D. If Lx is specified the length of the domain is always Lx regardless of dx, unless dx is a list of spacings, in which case Lx will be the sum of dx and nx will be the count of dx.

Parameters
  • dx (float) – Grid spacing in the horizontal direction

  • nx (int) – Number of cells in the horizontal direction

  • Lx (float) – Domain length in the horizontal direction

  • overlap (int) – Number of overlapping cells for parallel simulations. Generally 2 is adequate. Higher order equations or discretizations require more.

  • communicator (CommWrapper) – Generally, fipy.tools.serialComm or fipy.tools.parallelComm. Select ~fipy.tools.serialComm to create a serial mesh when running in parallel; mostly used for test purposes.

fipy.Grid2D(dx=1.0, dy=1.0, nx=None, ny=None, Lx=None, Ly=None, overlap=2, communicator=SerialPETScCommWrapper())

Factory function to select between UniformGrid2D and NonUniformGrid2D. If L{x,y} is specified, the length of the domain is always L{x,y} regardless of d{x,y}, unless d{x,y} is a list of spacings, in which case L{x,y} will be the sum of d{x,y} and n{x,y} will be the count of d{x,y}.

>>> print(Grid2D(Lx=3., nx=2).dx)
1.5
Parameters
  • dx (float) – Grid spacing in the horizontal direction

  • dy (float) – Grid spacing in the vertical direction

  • nx (int) – Number of cells in the horizontal direction

  • ny (int) – Number of cells in the vertical direction

  • Lx (float) – Domain length in the horizontal direction

  • Ly (float) – Domain length in the vertical direction

  • overlap (int) – Number of overlapping cells for parallel simulations. Generally 2 is adequate. Higher order equations or discretizations require more.

  • communicator (CommWrapper) – Generally, fipy.tools.serialComm or fipy.tools.parallelComm. Select ~fipy.tools.serialComm to create a serial mesh when running in parallel; mostly used for test purposes.

fipy.Grid3D(dx=1.0, dy=1.0, dz=1.0, nx=None, ny=None, nz=None, Lx=None, Ly=None, Lz=None, overlap=2, communicator=SerialPETScCommWrapper())

Factory function to select between UniformGrid3D and NonUniformGrid3D. If L{x,y,z} is specified, the length of the domain is always L{x,y,z} regardless of d{x,y,z}, unless d{x,y,z} is a list of spacings, in which case L{x,y,z} will be the sum of d{x,y,z} and n{x,y,z} will be the count of d{x,y,z}.

Parameters
  • dx (float) – Grid spacing in the horizontal direction

  • dy (float) – Grid spacing in the vertical direction

  • dz (float) – Grid spacing in the depth direction

  • nx (int) – Number of cells in the horizontal direction

  • ny (int) – Number of cells in the vertical direction

  • nz (int) – Number of cells in the depth direction

  • Lx (float) – Domain length in the horizontal direction

  • Ly (float) – Domain length in the vertical direction

  • Lz (float) – Domain length in the depth direction

  • overlap (int) – Number of overlapping cells for parallel simulations. Generally 2 is adequate. Higher order equations or discretizations require more.

  • communicator (CommWrapper) – Generally, fipy.tools.serialComm or fipy.tools.parallelComm. Select ~fipy.tools.serialComm to create a serial mesh when running in parallel; mostly used for test purposes.

class fipy.HistogramVariable(*args, **kwds)

Bases: fipy.variables.cellVariable.CellVariable

Produces a histogram of the values of the supplied distribution.

Parameters
  • distribution (array_like or Variable) – The collection of values to sample.

  • dx (float) – The bin size

  • nx (int) – The number of bins

  • offset (float) – The position of the first bin

__init__(distribution, dx=1.0, nx=None, offset=0.0)

Produces a histogram of the values of the supplied distribution.

Parameters
  • distribution (array_like or Variable) – The collection of values to sample.

  • dx (float) – The bin size

  • nx (int) – The number of bins

  • offset (float) – The position of the first bin

__module__ = 'fipy.variables.histogramVariable'
class fipy.HybridConvectionTerm(coeff=1.0, var=None)

Bases: fipy.terms.asymmetricConvectionTerm._AsymmetricConvectionTerm

The discretization for this Term is given by

\int_V \nabla \cdot (\vec{u} \phi)\,dV \simeq \sum_{f} (\vec{n}
\cdot \vec{u})_f \phi_f A_f

where \phi_f=\alpha_f \phi_P +(1-\alpha_f)\phi_A and \alpha_f is calculated using the hybrid scheme. For further details see Numerical Schemes.

Create a _AbstractConvectionTerm object.

>>> from fipy import *
>>> m = Grid1D(nx = 2)
>>> cv = CellVariable(mesh = m)
>>> fv = FaceVariable(mesh = m)
>>> vcv = CellVariable(mesh=m, rank=1)
>>> vfv = FaceVariable(mesh=m, rank=1)
>>> __ConvectionTerm(coeff = cv) 
Traceback (most recent call last):
    ...
VectorCoeffError: The coefficient must be a vector value.
>>> __ConvectionTerm(coeff = fv) 
Traceback (most recent call last):
    ...
VectorCoeffError: The coefficient must be a vector value.
>>> __ConvectionTerm(coeff = vcv)
__ConvectionTerm(coeff=_ArithmeticCellToFaceVariable(value=array([[ 0.,  0.,  0.]]), mesh=UniformGrid1D(dx=1.0, nx=2)))
>>> __ConvectionTerm(coeff = vfv)
__ConvectionTerm(coeff=FaceVariable(value=array([[ 0.,  0.,  0.]]), mesh=UniformGrid1D(dx=1.0, nx=2)))
>>> __ConvectionTerm(coeff = (1,))
__ConvectionTerm(coeff=(1,))
>>> ExplicitUpwindConvectionTerm(coeff = (0,)).solve(var=cv, solver=DummySolver()) 
Traceback (most recent call last):
    ...
TransientTermError: The equation requires a TransientTerm with explicit convection.
>>> (TransientTerm(0.) - ExplicitUpwindConvectionTerm(coeff = (0,))).solve(var=cv, solver=DummySolver(), dt=1.)
>>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = 1)).solve(var=cv, solver=DummySolver(), dt=1.) 
Traceback (most recent call last):
    ...
VectorCoeffError: The coefficient must be a vector value.
>>> m2 = Grid2D(nx=2, ny=1)
>>> cv2 = CellVariable(mesh=m2)
>>> vcv2 = CellVariable(mesh=m2, rank=1)
>>> vfv2 = FaceVariable(mesh=m2, rank=1)
>>> __ConvectionTerm(coeff=vcv2)
__ConvectionTerm(coeff=_ArithmeticCellToFaceVariable(value=array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.]]), mesh=UniformGrid2D(dx=1.0, nx=2, dy=1.0, ny=1)))
>>> __ConvectionTerm(coeff=vfv2)
__ConvectionTerm(coeff=FaceVariable(value=array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.]]), mesh=UniformGrid2D(dx=1.0, nx=2, dy=1.0, ny=1)))
>>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = ((0,), (0,)))).solve(var=cv2, solver=DummySolver(), dt=1.)
>>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = (0, 0))).solve(var=cv2, solver=DummySolver(), dt=1.)
Parameters

coeff (The Term’s coefficient value.) –

__module__ = 'fipy.terms.hybridConvectionTerm'
exception fipy.IllConditionedPreconditionerWarning(solver, iter, relres)

Bases: fipy.solvers.solver.PreconditionerWarning

__module__ = 'fipy.solvers.solver'
__str__()

Return str(self).

fipy.ImplicitDiffusionTerm

alias of fipy.terms.diffusionTerm.DiffusionTerm

class fipy.ImplicitSourceTerm(coeff=0.0, var=None)

Bases: fipy.terms.sourceTerm.SourceTerm

The ImplicitSourceTerm represents

\int_V \phi S \,dV \simeq \phi_P S_P V_P

where S is the coeff value.

Create a Term.

Parameters

coeff (float or CellVariable or FaceVariable) – Coefficient for the term. FaceVariable objects are only acceptable for diffusion or convection terms.

__module__ = 'fipy.terms.implicitSourceTerm'
exception fipy.IncorrectSolutionVariable(s='The solution variable is incorrect.')

Bases: Exception

__init__(s='The solution variable is incorrect.')

Initialize self. See help(type(self)) for accurate signature.

__module__ = 'fipy.terms'
__weakref__

list of weak references to the object (if defined)

fipy.L1error(var, matrix, RHSvector)

\frac{\|\mathtt{var} - \mathtt{var}^\text{old}\|_1}
{\|\mathtt{var}^\text{old}\|_1}

where \|\vec{x}\|_1 is the L^1 norm of \vec{x}.

Parameters
  • var (CellVariable) – The CellVariable in question.

  • matrix(ignored)

  • RHSvector(ignored)

fipy.L2error(var, matrix, RHSvector)

\frac{\|\mathtt{var} - \mathtt{var}^\text{old}\|_2}
{\|\mathtt{var}^\text{old}\|_2}

where \|\vec{x}\|_2 is the L^2 norm of \vec{x}.

Parameters
  • var (CellVariable) – The CellVariable in question.

  • matrix(ignored)

  • RHSvector(ignored)

fipy.LINFerror(var, matrix, RHSvector)

\frac{\|\mathtt{var} - \mathtt{var}^\text{old}\|_\infty}
{\|\mathtt{var}^\text{old}\|_\infty}

where \|\vec{x}\|_\infty is the L^\infty norm of \vec{x}.

Parameters
  • var (CellVariable) – The CellVariable in question.

  • matrix(ignored)

  • RHSvector(ignored)

class fipy.LinearBicgSolver(tolerance=1e-10, iterations=1000, precon=None)

Bases: fipy.solvers.petsc.petscKrylovSolver.PETScKrylovSolver

The LinearBicgSolver is an interface to the biconjugate gradient solver in PETSc, using no preconditioner by default.

Parameters
  • tolerance: The required error tolerance.

  • iterations: The maximum number of iterative steps to perform.

  • precon: Preconditioner to use (string).

__module__ = 'fipy.solvers.petsc.linearBicgSolver'
solver = 'bicg'
class fipy.LinearCGSSolver(tolerance=1e-10, iterations=1000, precon=None)

Bases: fipy.solvers.petsc.petscKrylovSolver.PETScKrylovSolver

The LinearCGSSolver is an interface to the conjugate gradient squared solver in PETSc, using no preconditioner by default.

Parameters
  • tolerance: The required error tolerance.

  • iterations: The maximum number of iterative steps to perform.

  • precon: Preconditioner to use (string).

__module__ = 'fipy.solvers.petsc.linearCGSSolver'
solver = 'cgs'
class fipy.LinearGMRESSolver(tolerance=1e-10, iterations=1000, precon=None)

Bases: fipy.solvers.petsc.petscKrylovSolver.PETScKrylovSolver

The LinearGMRESSolver is an interface to the GMRES solver in PETSc, using no preconditioner by default.

Parameters
  • tolerance: The required error tolerance.

  • iterations: The maximum number of iterative steps to perform.

  • precon: Preconditioner to use (string).

__module__ = 'fipy.solvers.petsc.linearGMRESSolver'
solver = 'gmres'
class fipy.LinearLUSolver(tolerance=1e-10, iterations=10, precon='lu')

Bases: fipy.solvers.petsc.petscSolver.PETScSolver

The LinearLUSolver is an interface to the LU preconditioner in PETSc. A direct solve is performed.

Parameters
  • tolerance: The required error tolerance.

  • iterations: The maximum number of iterative steps to perform.

  • precon: Ignored.

__init__(tolerance=1e-10, iterations=10, precon='lu')
Parameters
  • tolerance: The required error tolerance.

  • iterations: The maximum number of iterative steps to perform.

  • precon: Ignored.

__module__ = 'fipy.solvers.petsc.linearLUSolver'
class fipy.LinearPCGSolver(tolerance=1e-10, iterations=1000, precon=None)

Bases: fipy.solvers.petsc.petscKrylovSolver.PETScKrylovSolver

The LinearPCGSolver is an interface to the cg solver in PETSc, using no preconditioner by default.

Parameters
  • tolerance: The required error tolerance.

  • iterations: The maximum number of iterative steps to perform.

  • precon: Preconditioner to use (string).

__module__ = 'fipy.solvers.petsc.linearPCGSolver'
solver = 'cg'
class fipy.Matplotlib1DViewer(vars, title=None, xlog=False, ylog=False, limits={}, legend='upper left', axes=None, **kwlimits)

Bases: fipy.viewers.matplotlibViewer.matplotlibViewer.AbstractMatplotlibViewer

Displays a y vs. x plot of one or more 1D CellVariable objects using Matplotlib.

>>> from fipy import *
>>> mesh = Grid1D(nx=100)
>>> x, = mesh.cellCenters
>>> xVar = CellVariable(mesh=mesh, name="x", value=x)
>>> k = Variable(name="k", value=0.)
>>> viewer = Matplotlib1DViewer(vars=(numerix.sin(k * xVar), numerix.cos(k * xVar / numerix.pi)),
...                 limits={'xmin': 10, 'xmax': 90},
...                 datamin=-0.9, datamax=2.0,
...                 title="Matplotlib1DViewer test")
>>> for kval in numerix.arange(0, 0.3, 0.03):
...     k.setValue(kval)
...     viewer.plot()
>>> viewer._promptForOpinion()
Parameters
  • vars (CellVariable or list) – CellVariable objects to plot

  • title (str, optional) – displayed at the top of the Viewer window

  • xlog (bool) – log scaling of x axis if True

  • ylog (bool) – log scaling of y axis if True

  • limits (dict) – a (deprecated) alternative to limit keyword arguments

  • xmin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale. (ymin and ymax are synonyms for datamin and datamax).

  • xmax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale. (ymin and ymax are synonyms for datamin and datamax).

  • datamin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale. (ymin and ymax are synonyms for datamin and datamax).

  • datamax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale. (ymin and ymax are synonyms for datamin and datamax).

  • legend (str) – place a legend at the specified position, if not None

  • axes (Axes) – if not None, vars will be plotted into this Matplotlib Axes object

__init__(vars, title=None, xlog=False, ylog=False, limits={}, legend='upper left', axes=None, **kwlimits)
Parameters
  • vars (CellVariable or list) – CellVariable objects to plot

  • title (str, optional) – displayed at the top of the Viewer window

  • xlog (bool) – log scaling of x axis if True

  • ylog (bool) – log scaling of y axis if True

  • limits (dict) – a (deprecated) alternative to limit keyword arguments

  • xmin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale. (ymin and ymax are synonyms for datamin and datamax).

  • xmax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale. (ymin and ymax are synonyms for datamin and datamax).

  • datamin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale. (ymin and ymax are synonyms for datamin and datamax).

  • datamax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale. (ymin and ymax are synonyms for datamin and datamax).

  • legend (str) – place a legend at the specified position, if not None

  • axes (Axes) – if not None, vars will be plotted into this Matplotlib Axes object

__module__ = 'fipy.viewers.matplotlibViewer.matplotlib1DViewer'
property log

logarithmic data scaling

class fipy.Matplotlib2DGridContourViewer(vars, title=None, limits={}, cmap=None, colorbar='vertical', axes=None, figaspect='auto', **kwlimits)

Bases: fipy.viewers.matplotlibViewer.matplotlib2DViewer.AbstractMatplotlib2DViewer

Displays a contour plot of a 2D CellVariable object.

The Matplotlib2DGridContourViewer plots a 2D CellVariable using Matplotlib.

>>> from fipy import *
>>> mesh = Grid2D(nx=50, ny=100, dx=0.1, dy=0.01)
>>> x, y = mesh.cellCenters
>>> xyVar = CellVariable(mesh=mesh, name="x y", value=x * y)
>>> k = Variable(name="k", value=0.)
>>> viewer = Matplotlib2DGridContourViewer(vars=numerix.sin(k * xyVar),
...                 limits={'ymin': 0.1, 'ymax': 0.9},
...                 datamin=-0.9, datamax=2.0,
...                 title="Matplotlib2DGridContourViewer test")
>>> from builtins import range
>>> for kval in range(10):
...     k.setValue(kval)
...     viewer.plot()
>>> viewer._promptForOpinion()

Creates a Matplotlib2DViewer.

Parameters
  • vars (CellVariable) – the Variable to display.

  • title (str, optional) – displayed at the top of the Viewer window

  • limits (dict) – a (deprecated) alternative to limit keyword arguments

  • xmin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • xmax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • cmap (Colormap, optional) – the Colormap. Defaults to matplotlib.cm.jet

  • colorbar (bool, optional) – plot a color bar if not None

  • axes (Axes, optional) – if not None, vars will be plotted into this Matplotlib Axes object

  • figaspect (float, optional) – desired aspect ratio of figure. If a number, use that aspect ratio. If auto, the aspect ratio will be determined from the vars’s mesh.

__init__(vars, title=None, limits={}, cmap=None, colorbar='vertical', axes=None, figaspect='auto', **kwlimits)

Creates a Matplotlib2DViewer.

Parameters
  • vars (CellVariable) – the Variable to display.

  • title (str, optional) – displayed at the top of the Viewer window

  • limits (dict) – a (deprecated) alternative to limit keyword arguments

  • xmin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • xmax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • cmap (Colormap, optional) – the Colormap. Defaults to matplotlib.cm.jet

  • colorbar (bool, optional) – plot a color bar if not None

  • axes (Axes, optional) – if not None, vars will be plotted into this Matplotlib Axes object

  • figaspect (float, optional) – desired aspect ratio of figure. If a number, use that aspect ratio. If auto, the aspect ratio will be determined from the vars’s mesh.

__module__ = 'fipy.viewers.matplotlibViewer.matplotlib2DGridContourViewer'
class fipy.Matplotlib2DGridViewer(vars, title=None, limits={}, cmap=None, colorbar='vertical', axes=None, figaspect='auto', **kwlimits)

Bases: fipy.viewers.matplotlibViewer.matplotlib2DViewer.AbstractMatplotlib2DViewer

Displays an image plot of a 2D CellVariable object using Matplotlib.

>>> from fipy import *
>>> mesh = Grid2D(nx=50, ny=100, dx=0.1, dy=0.01)
>>> x, y = mesh.cellCenters
>>> xyVar = CellVariable(mesh=mesh, name="x y", value=x * y)
>>> k = Variable(name="k", value=0.)
>>> viewer = Matplotlib2DGridViewer(vars=numerix.sin(k * xyVar),
...                 limits={'ymin': 0.1, 'ymax': 0.9},
...                 datamin=-0.9, datamax=2.0,
...                 title="Matplotlib2DGridViewer test")
>>> from builtins import range
>>> for kval in range(10):
...     k.setValue(kval)
...     viewer.plot()
>>> viewer._promptForOpinion()

Creates a Matplotlib2DGridViewer.

Parameters
  • vars (CellVariable) – the Variable to display.

  • title (str, optional) – displayed at the top of the Viewer window

  • limits (dict, optional) – a (deprecated) alternative to limit keyword arguments

  • cmap (Colormap, optional) – the Colormap. Defaults to matplotlib.cm.jet

  • xmin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • xmax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • colorbar (bool, optional) – plot a color bar in specified orientation if not None

  • axes (Axes, optional) – if not None, vars will be plotted into this Matplotlib Axes object

  • figaspect (float, optional) – desired aspect ratio of figure. If arg is a number, use that aspect ratio. If arg is auto, the aspect ratio will be determined from the Variable’s mesh.

__init__(vars, title=None, limits={}, cmap=None, colorbar='vertical', axes=None, figaspect='auto', **kwlimits)

Creates a Matplotlib2DGridViewer.

Parameters
  • vars (CellVariable) – the Variable to display.

  • title (str, optional) – displayed at the top of the Viewer window

  • limits (dict, optional) – a (deprecated) alternative to limit keyword arguments

  • cmap (Colormap, optional) – the Colormap. Defaults to matplotlib.cm.jet

  • xmin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • xmax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • colorbar (bool, optional) – plot a color bar in specified orientation if not None

  • axes (Axes, optional) – if not None, vars will be plotted into this Matplotlib Axes object

  • figaspect (float, optional) – desired aspect ratio of figure. If arg is a number, use that aspect ratio. If arg is auto, the aspect ratio will be determined from the Variable’s mesh.

__module__ = 'fipy.viewers.matplotlibViewer.matplotlib2DGridViewer'
class fipy.Matplotlib2DViewer(vars, title=None, limits={}, cmap=None, colorbar='vertical', axes=None, figaspect='auto', **kwlimits)

Bases: fipy.viewers.matplotlibViewer.matplotlib2DViewer.AbstractMatplotlib2DViewer

Displays a contour plot of a 2D CellVariable object.

The Matplotlib2DViewer plots a 2D CellVariable using Matplotlib.

>>> from fipy import *
>>> mesh = (Grid2D(nx=5, ny=10, dx=0.1, dy=0.1)
...         + (Tri2D(nx=5, ny=5, dx=0.1, dy=0.1)
...          + ((0.5,), (0.2,))))
>>> x, y = mesh.cellCenters
>>> xyVar = CellVariable(mesh=mesh, name="x y", value=x * y)
>>> k = Variable(name="k", value=0.)
>>> viewer = Matplotlib2DViewer(vars=numerix.sin(k * xyVar),
...                 limits={'ymin': 0.1, 'ymax': 0.9},
...                 datamin=-0.9, datamax=2.0,
...                 title="Matplotlib2DViewer test")
>>> from builtins import range
>>> for kval in range(10):
...     k.setValue(kval)
...     viewer.plot()
>>> viewer._promptForOpinion()

Creates a Matplotlib2DViewer.

Parameters
  • vars (CellVariable) – the Variable to display.

  • title (str, optional) – displayed at the top of the Viewer window

  • limits (dict, optional) – a (deprecated) alternative to limit keyword arguments

  • cmap (Colormap, optional) – the Colormap. Defaults to matplotlib.cm.jet

  • xmin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • xmax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • colorbar (bool, optional) – plot a color bar in specified orientation if not None

  • axes (Axes, optional) – if not None, vars will be plotted into this Matplotlib Axes object

  • figaspect (float, optional) – desired aspect ratio of figure. If arg is a number, use that aspect ratio. If arg is auto, the aspect ratio will be determined from the Variable’s mesh.

__init__(vars, title=None, limits={}, cmap=None, colorbar='vertical', axes=None, figaspect='auto', **kwlimits)

Creates a Matplotlib2DViewer.

Parameters
  • vars (CellVariable) – the Variable to display.

  • title (str, optional) – displayed at the top of the Viewer window

  • limits (dict, optional) – a (deprecated) alternative to limit keyword arguments

  • cmap (Colormap, optional) – the Colormap. Defaults to matplotlib.cm.jet

  • xmin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • xmax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • colorbar (bool, optional) – plot a color bar in specified orientation if not None

  • axes (Axes, optional) – if not None, vars will be plotted into this Matplotlib Axes object

  • figaspect (float, optional) – desired aspect ratio of figure. If arg is a number, use that aspect ratio. If arg is auto, the aspect ratio will be determined from the Variable’s mesh.

__module__ = 'fipy.viewers.matplotlibViewer.matplotlib2DViewer'
class fipy.MatplotlibStreamViewer(vars, title=None, log=False, limits={}, axes=None, figaspect='auto', density=1, linewidth=None, color=None, cmap=None, norm=None, arrowsize=1, arrowstyle='-|>', minlength=0.1, **kwlimits)

Bases: fipy.viewers.matplotlibViewer.matplotlib2DViewer.AbstractMatplotlib2DViewer

Displays a stream plot of a 2D rank-1 CellVariable or FaceVariable object using Matplotlib

One issue is that this Viewer relies on scipy.interpolate.griddata, which interpolates on the convex hull of the data. The results is that streams are plotted across any concavities in the mesh.

Another issue is that it does not seem possible to remove the streams without calling cla(), which means that different set of streams cannot be overlaid.

>>> from fipy import *
>>> mesh = Grid2D(nx=50, ny=100, dx=0.1, dy=0.01)
>>> x, y = mesh.cellCenters
>>> xyVar = CellVariable(mesh=mesh, name="x y", value=x * y)
>>> k = Variable(name="k", value=1.)
>>> viewer = MatplotlibStreamViewer(vars=numerix.sin(k * xyVar).grad,
...                 title="MatplotlibStreamViewer test")
>>> for kval in numerix.arange(1, 10):
...     k.setValue(kval)
...     viewer.plot()
>>> viewer._promptForOpinion()
>>> viewer = MatplotlibStreamViewer(vars=numerix.sin(k * xyVar).faceGrad,
...                 title="MatplotlibStreamViewer test")
>>> for kval in numerix.arange(1, 10):
...     k.setValue(kval)
...     viewer.plot()
>>> viewer._promptForOpinion()
>>> from fipy import *
>>> mesh = (Grid2D(nx=5, ny=10, dx=0.1, dy=0.1)
...         + (Tri2D(nx=5, ny=5, dx=0.1, dy=0.1)
...          + ((0.5,), (0.2,))))
>>> x, y = mesh.cellCenters
>>> xyVar = CellVariable(mesh=mesh, name="x y", value=x * y)
>>> k = Variable(name="k", value=1.)
>>> viewer = MatplotlibStreamViewer(vars=numerix.sin(k * xyVar).grad,
...                 title="MatplotlibStreamViewer test")
>>> for kval in numerix.arange(1, 10):
...     k.setValue(kval)
...     viewer.plot()
>>> viewer._promptForOpinion()
>>> viewer = MatplotlibStreamViewer(vars=numerix.sin(k * xyVar).faceGrad,
...                 title="MatplotlibStreamViewer test")
>>> for kval in numerix.arange(1, 10):
...     k.setValue(kval)
...     viewer.plot()
>>> viewer._promptForOpinion()

Creates a MatplotlibStreamViewer.

Parameters
  • vars (CellVariable or FaceVariable) – rank-1 Variable to display

  • title (str, optional) – displayed at the top of the Viewer window

  • log (bool, optional) – if True, arrow length goes at the base-10 logarithm of the magnitude

  • limits (dict, optional) – a (deprecated) alternative to limit keyword arguments

  • xmin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • xmax (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymax (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamax (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • axes (Axes, optional) – if not None, vars will be plotted into this Matplotlib Axes object

  • figaspect (float, optional) – desired aspect ratio of figure. If arg is a number, use that aspect ratio. If arg is auto, the aspect ratio will be determined from the Variable’s mesh.

  • density (float or (float, float), optional) – Controls the closeness of streamlines. When density = 1, the domain is divided into a 30x30 grid. density linearly scales this grid. Each cell in the grid can have, at most, one traversing streamline. For different densities in each direction, use a tuple (density_x, density_y).

  • linewidth (array_like or CellVariable or FaceVariable, optional) – The width of the stream lines. With a rank-0 CellVariable or FaceVariable the line width can be varied across the grid. The MeshVariable must have the same type and be defined on the same Mesh as vars.

  • color (str or CellVariable or FaceVariable, optional) – The streamline color as a matplotlib color code or a field of numbers. If given a rank-0 CellVariable or FaceVariable, its values are converted to colors using cmap and norm. The MeshVariable must have the same type and be defined on the same Mesh as vars.

  • cmap (Colormap, optional) – Colormap used to plot streamlines and arrows. This is only used if color is a MeshVariable.

  • norm (Normalize, optional) – Normalize object used to scale luminance data to 0, 1. If None, stretch (min, max) to (0, 1). Only necessary when color is a MeshVariable.

  • arrowsize (float, optional) – Scaling factor for the arrow size.

  • arrowstyle (str, optional) – Arrow style specification. See ~matplotlib.patches.FancyArrowPatch.

  • minlength (float, optional) – Minimum length of streamline in axes coordinates.

__init__(vars, title=None, log=False, limits={}, axes=None, figaspect='auto', density=1, linewidth=None, color=None, cmap=None, norm=None, arrowsize=1, arrowstyle='-|>', minlength=0.1, **kwlimits)

Creates a MatplotlibStreamViewer.

Parameters
  • vars (CellVariable or FaceVariable) – rank-1 Variable to display

  • title (str, optional) – displayed at the top of the Viewer window

  • log (bool, optional) – if True, arrow length goes at the base-10 logarithm of the magnitude

  • limits (dict, optional) – a (deprecated) alternative to limit keyword arguments

  • xmin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • xmax (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymax (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamax (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • axes (Axes, optional) – if not None, vars will be plotted into this Matplotlib Axes object

  • figaspect (float, optional) – desired aspect ratio of figure. If arg is a number, use that aspect ratio. If arg is auto, the aspect ratio will be determined from the Variable’s mesh.

  • density (float or (float, float), optional) – Controls the closeness of streamlines. When density = 1, the domain is divided into a 30x30 grid. density linearly scales this grid. Each cell in the grid can have, at most, one traversing streamline. For different densities in each direction, use a tuple (density_x, density_y).

  • linewidth (array_like or CellVariable or FaceVariable, optional) – The width of the stream lines. With a rank-0 CellVariable or FaceVariable the line width can be varied across the grid. The MeshVariable must have the same type and be defined on the same Mesh as vars.

  • color (str or CellVariable or FaceVariable, optional) – The streamline color as a matplotlib color code or a field of numbers. If given a rank-0 CellVariable or FaceVariable, its values are converted to colors using cmap and norm. The MeshVariable must have the same type and be defined on the same Mesh as vars.

  • cmap (Colormap, optional) – Colormap used to plot streamlines and arrows. This is only used if color is a MeshVariable.

  • norm (Normalize, optional) – Normalize object used to scale luminance data to 0, 1. If None, stretch (min, max) to (0, 1). Only necessary when color is a MeshVariable.

  • arrowsize (float, optional) – Scaling factor for the arrow size.

  • arrowstyle (str, optional) – Arrow style specification. See ~matplotlib.patches.FancyArrowPatch.

  • minlength (float, optional) – Minimum length of streamline in axes coordinates.

__module__ = 'fipy.viewers.matplotlibViewer.matplotlibStreamViewer'
class fipy.MatplotlibVectorViewer(vars, title=None, scale=None, sparsity=None, log=False, limits={}, axes=None, figaspect='auto', **kwlimits)

Bases: fipy.viewers.matplotlibViewer.matplotlib2DViewer.AbstractMatplotlib2DViewer

Displays a vector plot of a 2D rank-1 CellVariable or FaceVariable object using Matplotlib

>>> from fipy import *
>>> mesh = Grid2D(nx=50, ny=100, dx=0.1, dy=0.01)
>>> x, y = mesh.cellCenters
>>> xyVar = CellVariable(mesh=mesh, name="x y", value=x * y)
>>> k = Variable(name="k", value=1.)
>>> viewer = MatplotlibVectorViewer(vars=numerix.sin(k * xyVar).grad,
...                 title="MatplotlibVectorViewer test")
>>> for kval in numerix.arange(1, 10):
...     k.setValue(kval)
...     viewer.plot()
>>> viewer._promptForOpinion()
>>> viewer = MatplotlibVectorViewer(vars=numerix.sin(k * xyVar).faceGrad,
...                 title="MatplotlibVectorViewer test")
>>> for kval in numerix.arange(1, 10):
...     k.setValue(kval)
...     viewer.plot()
>>> viewer._promptForOpinion()
>>> for sparsity in numerix.arange(5000, 0, -500):
...     viewer.quiver(sparsity=sparsity)
...     viewer.plot()
>>> viewer._promptForOpinion()
>>> from fipy import *
>>> mesh = (Grid2D(nx=5, ny=10, dx=0.1, dy=0.1)
...         + (Tri2D(nx=5, ny=5, dx=0.1, dy=0.1)
...          + ((0.5,), (0.2,))))
>>> x, y = mesh.cellCenters
>>> xyVar = CellVariable(mesh=mesh, name="x y", value=x * y)
>>> k = Variable(name="k", value=1.)
>>> viewer = MatplotlibVectorViewer(vars=numerix.sin(k * xyVar).grad,
...                 title="MatplotlibVectorViewer test")
>>> for kval in numerix.arange(1, 10):
...     k.setValue(kval)
...     viewer.plot()
>>> viewer._promptForOpinion()
>>> viewer = MatplotlibVectorViewer(vars=numerix.sin(k * xyVar).faceGrad,
...                 title="MatplotlibVectorViewer test")
>>> for kval in numerix.arange(1, 10):
...     k.setValue(kval)
...     viewer.plot()
>>> viewer._promptForOpinion()

Creates a Matplotlib2DViewer.

Parameters
  • vars (CellVariable or FaceVariable) – rank-1 Variable to display

  • title (str, optional) – displayed at the top of the Viewer window

  • scale (float, optional) – if not None, scale all arrow lengths by this value

  • sparsity (int, optional) – if not None, then this number of arrows will be randomly chosen (weighted by the cell volume or face area)

  • log (bool, optional) – if True, arrow length goes at the base-10 logarithm of the magnitude

  • limits (dict, optional) – a (deprecated) alternative to limit keyword arguments

  • xmin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • xmax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • axes (Axes, optional) – if not None, vars will be plotted into this Matplotlib Axes object

  • figaspect (float, optional) – desired aspect ratio of figure. If arg is a number, use that aspect ratio. If arg is auto, the aspect ratio will be determined from the Variable’s mesh.

__init__(vars, title=None, scale=None, sparsity=None, log=False, limits={}, axes=None, figaspect='auto', **kwlimits)

Creates a Matplotlib2DViewer.

Parameters
  • vars (CellVariable or FaceVariable) – rank-1 Variable to display

  • title (str, optional) – displayed at the top of the Viewer window

  • scale (float, optional) – if not None, scale all arrow lengths by this value

  • sparsity (int, optional) – if not None, then this number of arrows will be randomly chosen (weighted by the cell volume or face area)

  • log (bool, optional) – if True, arrow length goes at the base-10 logarithm of the magnitude

  • limits (dict, optional) – a (deprecated) alternative to limit keyword arguments

  • xmin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • xmax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • axes (Axes, optional) – if not None, vars will be plotted into this Matplotlib Axes object

  • figaspect (float, optional) – desired aspect ratio of figure. If arg is a number, use that aspect ratio. If arg is auto, the aspect ratio will be determined from the Variable’s mesh.

__module__ = 'fipy.viewers.matplotlibViewer.matplotlibVectorViewer'
quiver(sparsity=None, scale=None)
fipy.MatplotlibViewer(vars, title=None, limits={}, cmap=None, colorbar='vertical', axes=None, **kwlimits)

Generic function for creating a MatplotlibViewer.

The MatplotlibViewer factory will search the module tree and return an instance of the first MatplotlibViewer it finds of the correct dimension and rank.

It is possible to view different Variables against different Matplotlib Axes

>>> from matplotlib import pyplot as plt
>>> from fipy import *
>>> plt.ion()
>>> fig = plt.figure()
>>> ax1 = plt.subplot((221))
>>> ax2 = plt.subplot((223))
>>> ax3 = plt.subplot((224))
>>> k = Variable(name="k", value=0.)
>>> mesh1 = Grid1D(nx=100)
>>> x, = mesh1.cellCenters
>>> xVar = CellVariable(mesh=mesh1, name="x", value=x)
>>> viewer1 = MatplotlibViewer(vars=(numerix.sin(0.1 * k * xVar), numerix.cos(0.1 * k * xVar / numerix.pi)),
...                            limits={'xmin': 10, 'xmax': 90},
...                            datamin=-0.9, datamax=2.0,
...                            title="Grid1D test",
...                            axes=ax1,
...                            legend=None)
>>> mesh2 = Grid2D(nx=50, ny=100, dx=0.1, dy=0.01)
>>> x, y = mesh2.cellCenters
>>> xyVar = CellVariable(mesh=mesh2, name="x y", value=x * y)
>>> viewer2 = MatplotlibViewer(vars=numerix.sin(k * xyVar),
...                            limits={'ymin': 0.1, 'ymax': 0.9},
...                            datamin=-0.9, datamax=2.0,
...                            title="Grid2D test",
...                            axes=ax2,
...                            colorbar=None)
>>> mesh3 = (Grid2D(nx=5, ny=10, dx=0.1, dy=0.1)
...          + (Tri2D(nx=5, ny=5, dx=0.1, dy=0.1)
...             + ((0.5,), (0.2,))))
>>> x, y = mesh3.cellCenters
>>> xyVar = CellVariable(mesh=mesh3, name="x y", value=x * y)
>>> viewer3 = MatplotlibViewer(vars=numerix.sin(k * xyVar),
...                            limits={'ymin': 0.1, 'ymax': 0.9},
...                            datamin=-0.9, datamax=2.0,
...                            title="Irregular 2D test",
...                            axes=ax3,
...                            cmap = plt.cm.OrRd)
>>> viewer = MultiViewer(viewers=(viewer1, viewer2, viewer3))
>>> from builtins import range
>>> for kval in range(10):
...     k.setValue(kval)
...     viewer.plot()
>>> viewer._promptForOpinion()
Parameters
  • vars (CellVariable or list) – the Variable objects to display.

  • title (str, optional) – displayed at the top of the Viewer window

  • limits (dict) – a (deprecated) alternative to limit keyword arguments

  • xmin (float) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • xmax (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • ymin (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • ymax (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • datamin (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • datamax (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • cmap (Colormap, optional) – the Colormap. Defaults to matplotlib.cm.jet

  • colorbar (bool, optional) – plot a color bar in specified orientation if not None

  • axes (Axes, optional) – if not None, vars will be plotted into this Matplotlib Axes object

exception fipy.MatrixIllConditionedWarning(solver, iter, relres)

Bases: fipy.solvers.solver.SolverConvergenceWarning

__module__ = 'fipy.solvers.solver'
__str__()

Return str(self).

exception fipy.MaximumIterationWarning(solver, iter, relres)

Bases: fipy.solvers.solver.SolverConvergenceWarning

__module__ = 'fipy.solvers.solver'
__str__()

Return str(self).

class fipy.MayaviClient(vars, title=None, daemon_file=None, fps=1.0, **kwlimits)

Bases: fipy.viewers.viewer.AbstractViewer

The MayaviClient uses the Mayavi python plotting package.

>>> from fipy import *
>>> mesh = Grid1D(nx=100)
>>> x, = mesh.cellCenters
>>> xVar = CellVariable(mesh=mesh, name="x", value=x)
>>> k = Variable(name="k", value=0.)
>>> viewer = MayaviClient(vars=(numerix.sin(k * xVar), numerix.cos(k * xVar / numerix.pi)),
...                 limits={'xmin': 10, 'xmax': 90},
...                 datamin=-0.9, datamax=2.0,
...                 title="MayaviClient test")
>>> for kval in numerix.arange(0, 0.3, 0.03):
...     k.setValue(kval)
...     viewer.plot()
>>> viewer._promptForOpinion()
>>> from fipy import *
>>> mesh = Grid2D(nx=50, ny=100, dx=0.1, dy=0.01)
>>> x, y = mesh.cellCenters
>>> xyVar = CellVariable(mesh=mesh, name="x y", value=x * y)
>>> k = Variable(name="k", value=0.)
>>> viewer = MayaviClient(vars=numerix.sin(k * xyVar),
...                 limits={'ymin': 0.1, 'ymax': 0.9},
...                 datamin=-0.9, datamax=2.0,
...                 title="MayaviClient test")
>>> from builtins import range
>>> for kval in range(10):
...     k.setValue(kval)
...     viewer.plot()
>>> viewer._promptForOpinion()
>>> from fipy import *
>>> mesh = (Grid2D(nx=5, ny=10, dx=0.1, dy=0.1)
...         + (Tri2D(nx=5, ny=5, dx=0.1, dy=0.1)
...          + ((0.5,), (0.2,))))
>>> x, y = mesh.cellCenters
>>> xyVar = CellVariable(mesh=mesh, name="x y", value=x * y)
>>> k = Variable(name="k", value=0.)
>>> viewer = MayaviClient(vars=numerix.sin(k * xyVar),
...                 limits={'ymin': 0.1, 'ymax': 0.9},
...                 datamin=-0.9, datamax=2.0,
...                 title="MayaviClient test")
>>> from builtins import range
>>> for kval in range(10):
...     k.setValue(kval)
...     viewer.plot()
>>> viewer._promptForOpinion()
>>> from fipy import *
>>> mesh = Grid3D(nx=50, ny=100, nz=10, dx=0.1, dy=0.01, dz=0.1)
>>> x, y, z = mesh.cellCenters
>>> xyzVar = CellVariable(mesh=mesh, name=r"x y z", value=x * y * z)
>>> k = Variable(name="k", value=0.)
>>> viewer = MayaviClient(vars=numerix.sin(k * xyzVar),
...                     limits={'ymin': 0.1, 'ymax': 0.9},
...                     datamin=-0.9, datamax=2.0,
...                     title="MayaviClient test")
>>> from builtins import range
>>> for kval in range(10):
...     k.setValue(kval)
...     viewer.plot()
>>> viewer._promptForOpinion()

Create a MayaviClient.

Parameters
  • vars (CellVariable or list) – CellVariable objects to plot

  • title (str, optional) – displayed at the top of the Viewer window

  • xmin (float) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • xmax (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • ymin (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • ymax (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • zmin (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • zmax (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • datamin (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • datamax (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • daemon_file (str, optional) – the path to the script to run the separate Mayavi viewer process. Defaults to fipy/viewers/mayaviViewer/mayaviDaemon.py

  • fps (float, optional) – frames per second to attempt to display

__del__()
__init__(vars, title=None, daemon_file=None, fps=1.0, **kwlimits)

Create a MayaviClient.

Parameters
  • vars (CellVariable or list) – CellVariable objects to plot

  • title (str, optional) – displayed at the top of the Viewer window

  • xmin (float) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • xmax (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • ymin (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • ymax (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • zmin (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • zmax (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • datamin (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • datamax (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • daemon_file (str, optional) – the path to the script to run the separate Mayavi viewer process. Defaults to fipy/viewers/mayaviViewer/mayaviDaemon.py

  • fps (float, optional) – frames per second to attempt to display

__module__ = 'fipy.viewers.mayaviViewer.mayaviClient'
plot(filename=None)

Update the display of the viewed variables.

Parameters

filename (str) – If not None, the name of a file to save the image into.

exception fipy.MeshDimensionError

Bases: IndexError

__module__ = 'fipy.viewers'
__weakref__

list of weak references to the object (if defined)

class fipy.ModularVariable(*args, **kwds)

Bases: fipy.variables.cellVariable.CellVariable

The ModularVariable defines a variable that exists on the circle between -\pi and \pi

The following examples show how ModularVariable works. When subtracting the answer wraps back around the circle.

>>> from fipy.meshes import Grid1D
>>> mesh = Grid1D(nx = 2)
>>> from fipy.tools import numerix
>>> pi = numerix.pi
>>> v1 = ModularVariable(mesh = mesh, value = (2*pi/3, -2*pi/3))
>>> v2 = ModularVariable(mesh = mesh, value = -2*pi/3)
>>> print(numerix.allclose(v2 - v1, (2*pi/3, 0)))
1

Obtaining the arithmetic face value.

>>> print(numerix.allclose(v1.arithmeticFaceValue, (2*pi/3, pi, -2*pi/3)))
1

Obtaining the gradient.

>>> print(numerix.allclose(v1.grad, ((pi/3, pi/3),)))
1

Obtaining the gradient at the faces.

>>> print(numerix.allclose(v1.faceGrad, ((0, 2*pi/3, 0),)))
1

Obtaining the gradient at the faces but without modular arithmetic.

>>> print(numerix.allclose(v1.faceGradNoMod, ((0, -4*pi/3, 0),)))
1
Parameters
  • mesh (Mesh) – the mesh that defines the geometry of this Variable

  • name (str) – the user-readable name of the Variable

  • value (float or array_like) – the initial value

  • rank (int) – the rank (number of dimensions) of each element of this Variable. Default: 0

  • elementshape (tuple of int) – the shape of each element of this variable Default: rank * (mesh.dim,)

  • unit (str or PhysicalUnit) – The physical units of the variable

__module__ = 'fipy.variables.modularVariable'
__rsub__(other)
__sub__(other)
property arithmeticFaceValue

Returns a FaceVariable whose value corresponds to the arithmetic interpolation of the adjacent cells:

\phi_f = (\phi_1 - \phi_2) \frac{d_{f2}}{d_{12}} + \phi_2

Adjusted for a ModularVariable

property faceGrad

Return \nabla \phi as a rank-1 FaceVariable (second-order gradient). Adjusted for a ModularVariable

property faceGradNoMod

Return \nabla \phi as a rank-1 FaceVariable (second-order gradient). Not adjusted for a ModularVariable

property grad

Return \nabla \phi as a rank-1 CellVariable (first-order gradient). Adjusted for a ModularVariable

updateOld()

Set the values of the previous solution sweep to the current values. Test case due to bug.

>>> from fipy.meshes import Grid1D
>>> mesh = Grid1D(nx = 1)
>>> var = ModularVariable(mesh=mesh, value=1., hasOld=1)
>>> var.updateOld()
>>> var[:] = 2
>>> answer = CellVariable(mesh=mesh, value=1.)
>>> print(var.old.allclose(answer))
True
class fipy.MultiViewer(viewers)

Bases: fipy.viewers.viewer.AbstractViewer

Treat a collection of different viewers (such for different 2D plots or 1D plots with different axes) as a single viewer that will plot() all subviewers simultaneously.

Parameters

viewers (list of ~fipy.viewers.viewer.Viewer) – the viewers to bind together

__init__(viewers)
Parameters

viewers (list of ~fipy.viewers.viewer.Viewer) – the viewers to bind together

__module__ = 'fipy.viewers.multiViewer'
plot()

Update the display of the viewed variables.

Parameters

filename (str) – If not None, the name of a file to save the image into.

setLimits(limits={}, **kwlimits)

Update the limits.

Parameters
  • limits (dict, optional) – a (deprecated) alternative to limit keyword arguments

  • xmin (float) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • xmax (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • ymin (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • ymax (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • zmin (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • zmax (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • datamin (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

  • datamax (float, optional) – displayed range of data. A 1D Viewer will only use xmin and xmax, a 2D viewer will also use ymin and ymax, and so on. All viewers will use datamin and datamax. Any limit set to a (default) value of None will autoscale.

class fipy.NthOrderBoundaryCondition(faces, value, order)

Bases: fipy.boundaryConditions.boundaryCondition.BoundaryCondition

This boundary condition is generally used in conjunction with a ImplicitDiffusionTerm that has multiple coefficients. It does not have any direct effect on the solution matrices, but its derivatives do.

Creates an NthOrderBoundaryCondition.

Parameters
  • faces (FaceVariable of bool) – Mask of faces where this condition applies.

  • value (float) – Value to impose.

  • order (int) – Order of the boundary condition. An order of 0 corresponds to a FixedValue and an order of 1 corresponds to a FixedFlux. Even and odd orders behave like FixedValue and FixedFlux objects, respectively, but apply to higher order terms.

__init__(faces, value, order)

Creates an NthOrderBoundaryCondition.

Parameters
  • faces (FaceVariable of bool) – Mask of faces where this condition applies.

  • value (float) – Value to impose.

  • order (int) – Order of the boundary condition. An order of 0 corresponds to a FixedValue and an order of 1 corresponds to a FixedFlux. Even and odd orders behave like FixedValue and FixedFlux objects, respectively, but apply to higher order terms.

__module__ = 'fipy.boundaryConditions.nthOrderBoundaryCondition'
class fipy.PeriodicGrid1D(dx=1.0, nx=None, overlap=2, *args, **kwargs)

Bases: fipy.meshes.nonUniformGrid1D.NonUniformGrid1D

Creates a Periodic grid mesh.

>>> mesh = PeriodicGrid1D(dx = (1, 2, 3))
>>> print(numerix.allclose(numerix.nonzero(mesh.exteriorFaces)[0],
...                        [3])) 
True
>>> print(numerix.allclose(mesh.faceCellIDs.filled(-999),
...                        [[2, 0, 1, 2],
...                         [0, 1, 2, -999]])) 
True
>>> print(numerix.allclose(mesh._cellDistances,
...                        [ 2., 1.5, 2.5, 1.5])) 
True
>>> print(numerix.allclose(mesh._cellToCellDistances,
...                        [[ 2.,   1.5,  2.5],
...                         [ 1.5,  2.5,  2. ]])) 
True
>>> print(numerix.allclose(mesh.faceNormals,
...                        [[ 1.,  1.,  1.,  1.]])) 
True
>>> print(numerix.allclose(mesh._cellVertexIDs,
...                        [[1, 2, 2],
...                        [0, 1, 0]])) 
True
__init__(dx=1.0, nx=None, overlap=2, *args, **kwargs)

Initialize self. See help(type(self)) for accurate signature.

__module__ = 'fipy.meshes.periodicGrid1D'
property cellCenters

Defined outside of a geometry class since we need the CellVariable version of cellCenters; that is, the cellCenters defined in fipy.meshes.mesh and not in any geometry (since a CellVariable requires a reference to a mesh).

class fipy.PeriodicGrid2D(dx=1.0, dy=1.0, nx=None, ny=None, overlap=2, communicator=SerialPETScCommWrapper(), *args, **kwargs)

Bases: fipy.meshes.periodicGrid2D._BasePeriodicGrid2D

Creates a periodic 2D grid mesh with horizontal faces numbered first and then vertical faces. Vertices and cells are numbered in the usual way.

>>> from fipy import numerix
>>> mesh = PeriodicGrid2D(dx = 1., dy = 0.5, nx = 2, ny = 2)
>>> print(numerix.allclose(numerix.nonzero(mesh.exteriorFaces)[0],
...                        [ 4,  5,  8, 11]))  
True
>>> print(numerix.allclose(mesh.faceCellIDs.filled(-1),
...                        [[2, 3, 0, 1, 2, 3, 1, 0, 1, 3, 2, 3],
...                         [0, 1, 2, 3, -1, -1, 0, 1, -1, 2, 3, -1]])) 
True
>>> print(numerix.allclose(mesh._cellDistances,
...                        [ 0.5, 0.5, 0.5, 0.5, 0.25, 0.25, 1., 1., 0.5, 1., 1., 0.5])) 
True
>>> print(numerix.allclose(mesh.cellFaceIDs,
...                        [[0, 1, 2, 3],
...                         [7, 6, 10, 9],
...                         [2, 3, 0, 1],
...                         [6, 7, 9, 10]])) 
True
>>> print(numerix.allclose(mesh._cellToCellDistances,
...                        [[ 0.5, 0.5, 0.5, 0.5],
...                         [ 1., 1., 1., 1. ],
...                         [ 0.5, 0.5, 0.5, 0.5],
...                         [ 1., 1., 1., 1. ]])) 
True
>>> normals = [[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1],
...            [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0]]
>>> print(numerix.allclose(mesh.faceNormals, normals)) 
True
>>> print(numerix.allclose(mesh._cellVertexIDs,
...                        [[4, 5, 7, 8],
...                         [3, 4, 6, 7],
...                         [1, 2, 4, 5],
...                         [0, 1, 3, 4]])) 
True
__module__ = 'fipy.meshes.periodicGrid2D'
class fipy.PeriodicGrid2DLeftRight(dx=1.0, dy=1.0, nx=None, ny=None, overlap=2, communicator=SerialPETScCommWrapper(), *args, **kwargs)

Bases: fipy.meshes.periodicGrid2D._BasePeriodicGrid2D

__module__ = 'fipy.meshes.periodicGrid2D'
class fipy.PeriodicGrid2DTopBottom(dx=1.0, dy=1.0, nx=None, ny=None, overlap=2, communicator=SerialPETScCommWrapper(), *args, **kwargs)

Bases: fipy.meshes.periodicGrid2D._BasePeriodicGrid2D

__module__ = 'fipy.meshes.periodicGrid2D'
class fipy.PeriodicGrid3D(dx=1.0, dy=1.0, dz=1.0, nx=None, ny=None, nz=None, overlap=2, communicator=SerialPETScCommWrapper(), *args, **kwargs)

Bases: fipy.meshes.periodicGrid3D._BasePeriodicGrid3D

Creates a periodic 3D grid mesh with horizontal faces numbered first and then vertical faces. Vertices and cells are numbered in the usual way.

>>> from fipy import numerix
>>> mesh = PeriodicGrid3D(dx=1., dy=0.5, dz=2., nx=2, ny=2, nz=1)
>>> print(numerix.allclose(numerix.nonzero(mesh.exteriorFaces)[0],
...                        [4, 5, 6, 7, 12, 13, 16, 19]))  
True
>>> print(numerix.allclose(mesh.faceCellIDs.filled(-1),
...                        [[0, 1, 2, 3, 0, 1, 2, 3, 2, 3,
...                          0, 1, 2, 3, 1, 0, 1, 3, 2, 3],
...                         [0, 1, 2, 3, -1, -1, -1, -1, 0, 1,
...                          2, 3, -1, -1, 0, 1, -1, 2, 3, -1]])) 
True
>>> print(numerix.allclose(mesh._cellDistances,
...                        [2., 2., 2., 2., 1., 1., 1., 1., 0.5, 0.5,
...                         0.5, 0.5, 0.25, 0.25, 1., 1., 0.5, 1., 1., 0.5])) 
True
>>> print(numerix.allclose(mesh.cellFaceIDs,
...                        [[14, 15, 17, 18],
...                         [15, 14, 18, 17],
...                         [8, 9, 10, 11],
...                         [10, 11, 8, 9],
...                         [0, 1, 2, 3],
...                         [0, 1, 2, 3]])) 
True
>>> print(numerix.allclose(mesh._cellToCellDistances,
...                        [[1., 1., 1., 1.],
...                         [1., 1., 1., 1.],
...                         [0.5, 0.5, 0.5, 0.5],
...                         [0.5, 0.5, 0.5, 0.5],
...                         [2., 2., 2., 2.],
...                         [2., 2., 2., 2.]])) 
True
>>> normals = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1],
...            [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
...            [1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
>>> print(numerix.allclose(mesh.faceNormals, normals)) 
True
>>> print(numerix.allclose(mesh._cellVertexIDs,
...                        [[13, 14, 16, 17],
...                         [12, 13, 15, 16],
...                         [10, 11, 13, 14],
...                         [9, 10, 12, 13],
...                         [4, 5, 7, 8],
...                         [3, 4, 6, 7],
...                         [1, 2, 4, 5],
...                         [0, 1, 3, 4]])) 
True
__module__ = 'fipy.meshes.periodicGrid3D'
class fipy.PeriodicGrid3DFrontBack(dx=1.0, dy=1.0, dz=1.0, nx=None, ny=None, nz=None, overlap=2, communicator=SerialPETScCommWrapper(), *args, **kwargs)

Bases: fipy.meshes.periodicGrid3D._BasePeriodicGrid3D

__module__ = 'fipy.meshes.periodicGrid3D'
class fipy.PeriodicGrid3DLeftRight(dx=1.0, dy=1.0, dz=1.0, nx=None, ny=None, nz=None, overlap=2, communicator=SerialPETScCommWrapper(), *args, **kwargs)

Bases: fipy.meshes.periodicGrid3D._BasePeriodicGrid3D

__module__ = 'fipy.meshes.periodicGrid3D'
class fipy.PeriodicGrid3DLeftRightFrontBack(dx=1.0, dy=1.0, dz=1.0, nx=None, ny=None, nz=None, overlap=2, communicator=SerialPETScCommWrapper(), *args, **kwargs)

Bases: fipy.meshes.periodicGrid3D._BasePeriodicGrid3D

__module__ = 'fipy.meshes.periodicGrid3D'
class fipy.PeriodicGrid3DLeftRightTopBottom(dx=1.0, dy=1.0, dz=1.0, nx=None, ny=None, nz=None, overlap=2, communicator=SerialPETScCommWrapper(), *args, **kwargs)

Bases: fipy.meshes.periodicGrid3D._BasePeriodicGrid3D

__module__ = 'fipy.meshes.periodicGrid3D'
class fipy.PeriodicGrid3DTopBottom(dx=1.0, dy=1.0, dz=1.0, nx=None, ny=None, nz=None, overlap=2, communicator=SerialPETScCommWrapper(), *args, **kwargs)

Bases: fipy.meshes.periodicGrid3D._BasePeriodicGrid3D

__module__ = 'fipy.meshes.periodicGrid3D'
class fipy.PeriodicGrid3DTopBottomFrontBack(dx=1.0, dy=1.0, dz=1.0, nx=None, ny=None, nz=None, overlap=2, communicator=SerialPETScCommWrapper(), *args, **kwargs)

Bases: fipy.meshes.periodicGrid3D._BasePeriodicGrid3D

__module__ = 'fipy.meshes.periodicGrid3D'
class fipy.PhysicalField(value, unit=None, array=None)

Bases: object

Physical field or quantity with units

Physical Fields can be constructed in one of two ways:

  • PhysicalField(*value*, *unit*), where *value* is a number of arbitrary type and *unit* is a string containing the unit name

    >>> print(PhysicalField(value = 10., unit = 'm'))
    10.0 m
    
  • PhysicalField(*string*), where *string* contains both the value and the unit. This form is provided to make interactive use more convenient

    >>> print(PhysicalField(value = "10. m"))
    10.0 m
    

Dimensionless quantities, with a unit of 1, can be specified in several ways

>>> print(PhysicalField(value = "1"))
1.0 1
>>> print(PhysicalField(value = 2., unit = " "))
2.0 1
>>> print(PhysicalField(value = 2.))
2.0 1

Physical arrays are also possible (and are the reason this code was adapted from Konrad Hinsen’s original PhysicalQuantity). The value can be a Numeric array:

>>> a = numerix.array(((3., 4.), (5., 6.)))
>>> print(PhysicalField(value = a, unit = "m"))
[[ 3.  4.]
 [ 5.  6.]] m

or a tuple:

>>> print(PhysicalField(value = ((3., 4.), (5., 6.)), unit = "m"))
[[ 3.  4.]
 [ 5.  6.]] m

or as a single value to be applied to every element of a supplied array:

>>> print(PhysicalField(value = 2., unit = "m", array = a))
[[ 2.  2.]
 [ 2.  2.]] m

Every element in an array has the same unit, which is stored only once for the whole array.

__abs__()

Return the absolute value of the quantity. The unit is unchanged.

>>> print(abs(PhysicalField(((3., -2.), (-1., 4.)), 'm')))
[[ 3.  2.]
 [ 1.  4.]] m
__add__(other)

Add two physical quantities, so long as their units are compatible. The unit of the result is the unit of the first operand.

>>> print(PhysicalField(10., 'km') + PhysicalField(10., 'm'))
10.01 km
>>> print(PhysicalField(10., 'km') + PhysicalField(10., 'J'))
Traceback (most recent call last):
    ...
TypeError: Incompatible units
__array__(t=None)

Return a dimensionless PhysicalField as a Numeric array.

>>> print(numerix.array(PhysicalField(((2., 3.), (4., 5.)), "m/m")))
[[ 2.  3.]
 [ 4.  5.]]

As a special case, fields with angular units are converted to base units (radians) and then assumed dimensionless.

>>> print(numerix.array(PhysicalField(((2., 3.), (4., 5.)), "deg")))
[[ 0.03490659  0.05235988]
 [ 0.06981317  0.08726646]]

If the array is not dimensionless, the numerical value in its base units is returned.

>>> numerix.array(PhysicalField(((2., 3.), (4., 5.)), "mm"))
array([[ 0.002,  0.003],
       [ 0.004,  0.005]])
__array_priority__ = 100.0
__array_wrap__(arr, context=None)

Required to prevent numpy not calling the reverse binary operations. Both the following tests are examples ufuncs.

>>> from fipy.tools.dimensions.physicalField import PhysicalField
>>> print(type(numerix.array([1.0, 2.0]) * PhysicalField([1.0, 2.0], unit="m")))
<class 'fipy.tools.dimensions.physicalField.PhysicalField'>
>>> print(type(numerix.array([1.0, 2.0]) * PhysicalField([1.0, 2.0])))
<class 'fipy.tools.dimensions.physicalField.PhysicalField'>
>>> from scipy.special import gamma as Gamma 
>>> print(isinstance(Gamma(PhysicalField([1.0, 2.0])), type(numerix.array(1)))) 
1
__bool__()

Test if the quantity is zero.

Should this only pass if the unit offset is zero?

__dict__ = mappingproxy({'__module__': 'fipy.tools.dimensions.physicalField', '__doc__': '\n Physical field or quantity with units\n ', '__init__': <function PhysicalField.__init__>, '_number': re.compile('[+-]?[0-9]+(\\.[0-9]*)?([eE][+-]?[0-9]+)?'), 'ravel': <function PhysicalField.ravel>, 'copy': <function PhysicalField.copy>, '__str__': <function PhysicalField.__str__>, '__repr__': <function PhysicalField.__repr__>, 'tostring': <function PhysicalField.tostring>, '_sum': <function PhysicalField._sum>, '__add__': <function PhysicalField.__add__>, '__radd__': <function PhysicalField.__add__>, 'add': <function PhysicalField.__add__>, '__sub__': <function PhysicalField.__sub__>, 'subtract': <function PhysicalField.__sub__>, '__rsub__': <function PhysicalField.__rsub__>, '__mul__': <function PhysicalField.__mul__>, '__rmul__': <function PhysicalField.__mul__>, 'multiply': <function PhysicalField.__mul__>, '__truediv__': <function PhysicalField.__truediv__>, '__div__': <function PhysicalField.__truediv__>, 'divide': <function PhysicalField.__truediv__>, '__rtruediv__': <function PhysicalField.__rtruediv__>, '__rdiv__': <function PhysicalField.__rtruediv__>, '__mod__': <function PhysicalField.__mod__>, '__pow__': <function PhysicalField.__pow__>, '__rpow__': <function PhysicalField.__rpow__>, '__abs__': <function PhysicalField.__abs__>, '__pos__': <function PhysicalField.__pos__>, '__neg__': <function PhysicalField.__neg__>, 'sign': <function PhysicalField.sign>, '__bool__': <function PhysicalField.__bool__>, '__nonzero__': <function PhysicalField.__bool__>, '_inMyUnits': <function PhysicalField._inMyUnits>, '__getitem__': <function PhysicalField.__getitem__>, '__setitem__': <function PhysicalField.__setitem__>, 'itemset': <function PhysicalField.itemset>, '__array_priority__': 100.0, '__array_wrap__': <function PhysicalField.__array_wrap__>, '__array__': <function PhysicalField.__array__>, '_array': <property object>, '__float__': <function PhysicalField.__float__>, '__gt__': <function PhysicalField.__gt__>, '__lt__': <function PhysicalField.__lt__>, '__le__': <function PhysicalField.__le__>, '__eq__': <function PhysicalField.__eq__>, '__hash__': <slot wrapper '__hash__' of 'object' objects>, '__ne__': <function PhysicalField.__ne__>, '__ge__': <function PhysicalField.__ge__>, '__len__': <function PhysicalField.__len__>, 'convertToUnit': <function PhysicalField.convertToUnit>, 'inRadians': <function PhysicalField.inRadians>, 'inDimensionless': <function PhysicalField.inDimensionless>, 'inUnitsOf': <function PhysicalField.inUnitsOf>, 'getsctype': <function PhysicalField.getsctype>, '_getUnit': <function PhysicalField._getUnit>, '_setUnit': <function PhysicalField._setUnit>, 'unit': <property object>, 'numericValue': <property object>, 'inBaseUnits': <function PhysicalField.inBaseUnits>, 'inSIUnits': <function PhysicalField.inSIUnits>, 'isCompatible': <function PhysicalField.isCompatible>, 'arccos': <function PhysicalField.arccos>, 'arccosh': <function PhysicalField.arccosh>, 'arcsin': <function PhysicalField.arcsin>, 'sqrt': <function PhysicalField.sqrt>, 'sin': <function PhysicalField.sin>, 'sinh': <function PhysicalField.sinh>, 'cos': <function PhysicalField.cos>, 'cosh': <function PhysicalField.cosh>, 'tan': <function PhysicalField.tan>, 'tanh': <function PhysicalField.tanh>, 'arctan2': <function PhysicalField.arctan2>, 'arctan': <function PhysicalField.arctan>, 'arctanh': <function PhysicalField.arctanh>, 'log': <function PhysicalField.log>, 'log10': <function PhysicalField.log10>, 'floor': <function PhysicalField.floor>, 'ceil': <function PhysicalField.ceil>, 'conjugate': <function PhysicalField.conjugate>, 'dot': <function PhysicalField.dot>, 'take': <function PhysicalField.take>, 'put': <function PhysicalField.put>, 'shape': <property object>, 'itemsize': <property object>, 'reshape': <function PhysicalField.reshape>, 'sum': <function PhysicalField.sum>, 'allclose': <function PhysicalField.allclose>, 'allequal': <function PhysicalField.allequal>, '__dict__': <attribute '__dict__' of 'PhysicalField' objects>, '__weakref__': <attribute '__weakref__' of 'PhysicalField' objects>, '__annotations__': {}})
__div__(other)

Divide two physical quantities. The unit of the result is the unit of the first operand divided by the unit of the second.

>>> print(PhysicalField(10., 'm') / PhysicalField(2., 's'))
5.0 m/s

As a special case, if the result is dimensionless, the value is returned without units, rather than with a dimensionless unit of 1. This facilitates passing physical quantities to packages such as Numeric that cannot use units, while ensuring the quantities have the desired units

>>> print((PhysicalField(1., 'inch')
...        / PhysicalField(1., 'mm')))
25.4
__eq__(other)

Return self==value.

__float__()

Return a dimensionless PhysicalField quantity as a float.

>>> float(PhysicalField("2. m/m"))
2.0

As a special case, quantities with angular units are converted to base units (radians) and then assumed dimensionless.

>>> print(numerix.round_(float(PhysicalField("2. deg")), 6))
0.034907

If the quantity is not dimensionless, the conversion fails.

>>> float(PhysicalField("2. m"))
Traceback (most recent call last):
    ...
TypeError: Not possible to convert a PhysicalField with dimensions to float

Just as a Numeric array cannot be cast to float, neither can PhysicalField arrays

>>> float(PhysicalField(((2., 3.), (4., 5.)), "m/m")) 
Traceback (most recent call last):
    ...
TypeError: only ...-1 arrays can be converted to Python scalars
__ge__(other)

Return self>=value.

__getitem__(index)

Return the specified element of the array. The unit of the result will be the unit of the array.

>>> a = PhysicalField(((3., 4.), (5., 6.)), "m")
>>> print(a[1, 1])
6.0 m
__gt__(other)

Compare self to other, returning an array of Boolean values corresponding to the test against each element.

>>> a = PhysicalField(((3., 4.), (5., 6.)), "m")
>>> print(numerix.allclose(a > PhysicalField("13 ft"),
...                        [[False, True], [ True, True]]))
True

Appropriately formatted dimensional quantity strings can also be compared.

>>> print(numerix.allclose(a > "13 ft",
...                        [[False, True], [ True, True]]))
True

Arrays are compared element to element

>>> print(numerix.allclose(a > PhysicalField(((3., 13.), (17., 6.)), "ft"),
...                        [[ True, True], [False, True]]))
True

Units must be compatible

>>> print(a > PhysicalField("1 lb"))
Traceback (most recent call last):
    ...
TypeError: Incompatible units

And so must array dimensions

>>> print(a > PhysicalField(((3., 13., 4.), (17., 6., 2.)), "ft")) 
Traceback (most recent call last):
    ...
ValueError: shape mismatch: objects cannot be broadcast to a single shape
__hash__()

Return hash(self).

__init__(value, unit=None, array=None)

Physical Fields can be constructed in one of two ways:

  • PhysicalField(*value*, *unit*), where *value* is a number of arbitrary type and *unit* is a string containing the unit name

    >>> print(PhysicalField(value = 10., unit = 'm'))
    10.0 m
    
  • PhysicalField(*string*), where *string* contains both the value and the unit. This form is provided to make interactive use more convenient

    >>> print(PhysicalField(value = "10. m"))
    10.0 m
    

Dimensionless quantities, with a unit of 1, can be specified in several ways

>>> print(PhysicalField(value = "1"))
1.0 1
>>> print(PhysicalField(value = 2., unit = " "))
2.0 1
>>> print(PhysicalField(value = 2.))
2.0 1

Physical arrays are also possible (and are the reason this code was adapted from Konrad Hinsen’s original PhysicalQuantity). The value can be a Numeric array:

>>> a = numerix.array(((3., 4.), (5., 6.)))
>>> print(PhysicalField(value = a, unit = "m"))
[[ 3.  4.]
 [ 5.  6.]] m

or a tuple:

>>> print(PhysicalField(value = ((3., 4.), (5., 6.)), unit = "m"))
[[ 3.  4.]
 [ 5.  6.]] m

or as a single value to be applied to every element of a supplied array:

>>> print(PhysicalField(value = 2., unit = "m", array = a))
[[ 2.  2.]
 [ 2.  2.]] m

Every element in an array has the same unit, which is stored only once for the whole array.

__le__(other)

Return self<=value.

__len__()
__lt__(other)

Return self<value.

__mod__(other)

Return the remainder of dividing two physical quantities. The unit of the result is the unit of the first operand divided by the unit of the second.

>>> print(PhysicalField(11., 'm') % PhysicalField(2., 's'))
1.0 m/s
__module__ = 'fipy.tools.dimensions.physicalField'
__mul__(other)

Multiply two physical quantities. The unit of the result is the product of the units of the operands.

>>> print(PhysicalField(10., 'N') * PhysicalField(10., 'm') == PhysicalField(100., 'N*m'))
True

As a special case, if the result is dimensionless, the value is returned without units, rather than with a dimensionless unit of 1. This facilitates passing physical quantities to packages such as Numeric that cannot use units, while ensuring the quantities have the desired units.

>>> print((PhysicalField(10., 's') * PhysicalField(2., 'Hz')))
20.0
__ne__(other)

Return self!=value.

__neg__()

Return the negative of the quantity. The unit is unchanged.

>>> print(-PhysicalField(((3., -2.), (-1., 4.)), 'm'))
[[-3.  2.]
 [ 1. -4.]] m
__nonzero__()

Test if the quantity is zero.

Should this only pass if the unit offset is zero?

__pos__()
__pow__(other)

Raise a PhysicalField to a power. The unit is raised to the same power.

>>> print(PhysicalField(10., 'm')**2)
100.0 m**2
__radd__(other)

Add two physical quantities, so long as their units are compatible. The unit of the result is the unit of the first operand.

>>> print(PhysicalField(10., 'km') + PhysicalField(10., 'm'))
10.01 km
>>> print(PhysicalField(10., 'km') + PhysicalField(10., 'J'))
Traceback (most recent call last):
    ...
TypeError: Incompatible units
__rdiv__(other)
__repr__()

Return representation of a physical quantity suitable for re-use

>>> PhysicalField(value = 3., unit = "eV")
PhysicalField(3.0,'eV')
__rmul__(other)

Multiply two physical quantities. The unit of the result is the product of the units of the operands.

>>> print(PhysicalField(10., 'N') * PhysicalField(10., 'm') == PhysicalField(100., 'N*m'))
True

As a special case, if the result is dimensionless, the value is returned without units, rather than with a dimensionless unit of 1. This facilitates passing physical quantities to packages such as Numeric that cannot use units, while ensuring the quantities have the desired units.

>>> print((PhysicalField(10., 's') * PhysicalField(2., 'Hz')))
20.0
__rpow__(other)
__rsub__(other)
__rtruediv__(other)
__setitem__(index, value)

Assign the specified element of the array, performing appropriate conversions.

>>> a = PhysicalField(((3., 4.), (5., 6.)), "m")
>>> a[0, 1] = PhysicalField("6 ft")
>>> print(a)
[[ 3.      1.8288]
 [ 5.      6.    ]] m
>>> a[1, 0] = PhysicalField("2 min")
Traceback (most recent call last):
    ...
TypeError: Incompatible units
__str__()

Return human-readable form of a physical quantity

>>> print(PhysicalField(value = 3., unit = "eV"))
3.0 eV
__sub__(other)

Subtract two physical quantities, so long as their units are compatible. The unit of the result is the unit of the first operand.

>>> print(PhysicalField(10., 'km') - PhysicalField(10., 'm'))
9.99 km
>>> print(PhysicalField(10., 'km') - PhysicalField(10., 'J'))
Traceback (most recent call last):
    ...
TypeError: Incompatible units
__truediv__(other)

Divide two physical quantities. The unit of the result is the unit of the first operand divided by the unit of the second.

>>> print(PhysicalField(10., 'm') / PhysicalField(2., 's'))
5.0 m/s

As a special case, if the result is dimensionless, the value is returned without units, rather than with a dimensionless unit of 1. This facilitates passing physical quantities to packages such as Numeric that cannot use units, while ensuring the quantities have the desired units

>>> print((PhysicalField(1., 'inch')
...        / PhysicalField(1., 'mm')))
25.4
__weakref__

list of weak references to the object (if defined)

add(other)

Add two physical quantities, so long as their units are compatible. The unit of the result is the unit of the first operand.

>>> print(PhysicalField(10., 'km') + PhysicalField(10., 'm'))
10.01 km
>>> print(PhysicalField(10., 'km') + PhysicalField(10., 'J'))
Traceback (most recent call last):
    ...
TypeError: Incompatible units
allclose(other, atol=None, rtol=1e-08)

This function tests whether or not self and other are equal subject to the given relative and absolute tolerances. The formula used is:

| self - other | < atol + rtol * | other |

This means essentially that both elements are small compared to atol or their difference divided by other’s value is small compared to rtol.

allequal(other)

This function tests whether or not self and other are exactly equal.

arccos()

Return the inverse cosine of the PhysicalField in radians

>>> print(PhysicalField(0).arccos().allclose("1.57079632679 rad"))
1

The input PhysicalField must be dimensionless

>>> print(numerix.round_(PhysicalField("1 m").arccos(), 6))
Traceback (most recent call last):
    ...
TypeError: Incompatible units
arccosh()

Return the inverse hyperbolic cosine of the PhysicalField

>>> print(numerix.allclose(PhysicalField(2).arccosh(),
...                        1.31695789692))
1

The input PhysicalField must be dimensionless

>>> print(numerix.round_(PhysicalField("1. m").arccosh(), 6))
Traceback (most recent call last):
    ...
TypeError: Incompatible units
arcsin()

Return the inverse sine of the PhysicalField in radians

>>> print(PhysicalField(1).arcsin().allclose("1.57079632679 rad"))
1

The input PhysicalField must be dimensionless

>>> print(numerix.round_(PhysicalField("1 m").arcsin(), 6))
Traceback (most recent call last):
    ...
TypeError: Incompatible units
arctan()

Return the arctangent of the PhysicalField in radians

>>> print(numerix.round_(PhysicalField(1).arctan(), 6))
0.785398

The input PhysicalField must be dimensionless

>>> print(numerix.round_(PhysicalField("1 m").arctan(), 6))
Traceback (most recent call last):
    ...
TypeError: Incompatible units
arctan2(other)

Return the arctangent of self divided by other in radians

>>> print(numerix.round_(PhysicalField(2.).arctan2(PhysicalField(5.)), 6))
0.380506

The input PhysicalField objects must be in the same dimensions

>>> print(numerix.round_(PhysicalField(2.54, "cm").arctan2(PhysicalField(1., "inch")), 6))
0.785398
>>> print(numerix.round_(PhysicalField(2.).arctan2(PhysicalField("5. m")), 6))
Traceback (most recent call last):
    ...
TypeError: Incompatible units
arctanh()

Return the inverse hyperbolic tangent of the PhysicalField

>>> print(PhysicalField(0.5).arctanh())
0.549306144334

The input PhysicalField must be dimensionless

>>> print(numerix.round_(PhysicalField("1 m").arctanh(), 6))
Traceback (most recent call last):
    ...
TypeError: Incompatible units
ceil()

Return the smallest integer greater than or equal to the PhysicalField.

>>> print(PhysicalField(2.2, "m").ceil())
3.0 m
conjugate()

Return the complex conjugate of the PhysicalField.

>>> print(PhysicalField(2.2 - 3j, "ohm").conjugate() == PhysicalField(2.2 + 3j, "ohm"))
True
convertToUnit(unit)

Changes the unit to unit and adjusts the value such that the combination is equivalent. The new unit is by a string containing its name. The new unit must be compatible with the previous unit of the object.

>>> e = PhysicalField('2.7 Hartree*Nav')
>>> e.convertToUnit('kcal/mol')
>>> print(e)
1694.27557621 kcal/mol
copy()

Make a duplicate.

>>> a = PhysicalField(1, unit = 'inch')
>>> b = a.copy()

The duplicate will not reflect changes made to the original

>>> a.convertToUnit('cm')
>>> print(a)
2.54 cm
>>> print(b)
1 inch

Likewise for arrays

>>> a = PhysicalField(numerix.array((0, 1, 2)), unit  = 'm')
>>> b = a.copy()
>>> a[0] = 3
>>> print(a)
[3 1 2] m
>>> print(b)
[0 1 2] m
cos()

Return the cosine of the PhysicalField

>>> print(numerix.round_(PhysicalField(2*numerix.pi/6, "rad").cos(), 6))
0.5
>>> print(numerix.round_(PhysicalField(60., "deg").cos(), 6))
0.5

The units of the PhysicalField must be an angle

>>> PhysicalField(60., "m").cos()
Traceback (most recent call last):
    ...
TypeError: Incompatible units
cosh()

Return the hyperbolic cosine of the PhysicalField

>>> PhysicalField(0.).cosh()
1.0

The units of the PhysicalField must be dimensionless

>>> PhysicalField(60., "m").cosh()
Traceback (most recent call last):
    ...
TypeError: Incompatible units
divide(other)

Divide two physical quantities. The unit of the result is the unit of the first operand divided by the unit of the second.

>>> print(PhysicalField(10., 'm') / PhysicalField(2., 's'))
5.0 m/s

As a special case, if the result is dimensionless, the value is returned without units, rather than with a dimensionless unit of 1. This facilitates passing physical quantities to packages such as Numeric that cannot use units, while ensuring the quantities have the desired units

>>> print((PhysicalField(1., 'inch')
...        / PhysicalField(1., 'mm')))
25.4
dot(other)

Return the dot product of self with other. The resulting unit is the product of the units of self and other.

>>> v = PhysicalField(((5., 6.), (7., 8.)), "m")
>>> print(PhysicalField(((1., 2.), (3., 4.)), "m").dot(v))
[ 26.  44.] m**2
floor()

Return the largest integer less than or equal to the PhysicalField.

>>> print(PhysicalField(2.2, "m").floor())
2.0 m
getsctype(default=None)

Returns the NumPy sctype of the underlying array.

>>> PhysicalField(1, 'm').getsctype() == numerix.NUMERIX.obj2sctype(numerix.array(1))
True
>>> PhysicalField(1., 'm').getsctype() == numerix.NUMERIX.obj2sctype(numerix.array(1.))
True
>>> PhysicalField((1, 1.), 'm').getsctype() == numerix.NUMERIX.obj2sctype(numerix.array((1., 1.)))
True
inBaseUnits()

Return the quantity with all units reduced to their base SI elements.

>>> e = PhysicalField('2.7 Hartree*Nav')
>>> print(e.inBaseUnits().allclose("7088849.01085 kg*m**2/s**2/mol"))
1
inDimensionless()

Returns the numerical value of a dimensionless quantity.

>>> print(PhysicalField(((2., 3.), (4., 5.))).inDimensionless())
[[ 2.  3.]
 [ 4.  5.]]

It’s an error to convert a quantity with units

>>> print(PhysicalField(((2., 3.), (4., 5.)), "m").inDimensionless())
Traceback (most recent call last):
    ...
TypeError: Incompatible units
inRadians()

Converts an angular quantity to radians and returns the numerical value.

>>> print(PhysicalField(((2., 3.), (4., 5.)), "rad").inRadians())
[[ 2.  3.]
 [ 4.  5.]]
>>> print(PhysicalField(((2., 3.), (4., 5.)), "deg").inRadians())
[[ 0.03490659  0.05235988]
 [ 0.06981317  0.08726646]]

As a special case, assumes a dimensionless quantity is already in radians.

>>> print(PhysicalField(((2., 3.), (4., 5.))).inRadians())
[[ 2.  3.]
 [ 4.  5.]]

It’s an error to convert a quantity with non-angular units

>>> print(PhysicalField(((2., 3.), (4., 5.)), "m").inRadians())
Traceback (most recent call last):
    ...
TypeError: Incompatible units
inSIUnits()

Return the quantity with all units reduced to SI-compatible elements.

>>> e = PhysicalField('2.7 Hartree*Nav')
>>> print(e.inSIUnits().allclose("7088849.01085 kg*m**2/s**2/mol"))
1
inUnitsOf(*units)

Returns one or more PhysicalField objects that express the same physical quantity in different units. The units are specified by strings containing their names. The units must be compatible with the unit of the object. If one unit is specified, the return value is a single PhysicalField.

>>> freeze = PhysicalField('0 degC')
>>> print(freeze.inUnitsOf('degF').allclose("32.0 degF"))
1

If several units are specified, the return value is a tuple of PhysicalField instances with with one element per unit such that the sum of all quantities in the tuple equals the the original quantity and all the values except for the last one are integers. This is used to convert to irregular unit systems like hour/minute/second. The original object will not be changed.

>>> t = PhysicalField(314159., 's')
>>> from builtins import zip
>>> print(numerix.allclose([e.allclose(v) for (e, v) in zip(t.inUnitsOf('d', 'h', 'min', 's'),
...                                                         ['3.0 d', '15.0 h', '15.0 min', '59.0 s'])],
...                        True))
1
isCompatible(unit)
itemset(value)

Assign the value of a scalar array, performing appropriate conversions.

>>> a = PhysicalField(4., "m")
>>> a.itemset(PhysicalField("6 ft"))
>>> print(a.allclose("1.8288 m"))
1
>>> a = PhysicalField(((3., 4.), (5., 6.)), "m")
>>> try: 
...     a.itemset(PhysicalField("6 ft"))
... except IndexError:
...     # NumPy 1.7 has changed the exception type
...     raise ValueError("can only place a scalar for an  array of size 1")
Traceback (most recent call last):
    ...
ValueError: can only convert an array of size 1 to a Python scalar
>>> a.itemset(PhysicalField("2 min"))
Traceback (most recent call last):
    ...
TypeError: Incompatible units
property itemsize
log()

Return the natural logarithm of the PhysicalField

>>> print(numerix.round_(PhysicalField(10).log(), 6))
2.302585

The input PhysicalField must be dimensionless

>>> print(numerix.round_(PhysicalField("1. m").log(), 6))
Traceback (most recent call last):
    ...
TypeError: Incompatible units
log10()

Return the base-10 logarithm of the PhysicalField

>>> print(numerix.round_(PhysicalField(10.).log10(), 6))
1.0

The input PhysicalField must be dimensionless

>>> print(numerix.round_(PhysicalField("1. m").log10(), 6))
Traceback (most recent call last):
    ...
TypeError: Incompatible units
multiply(other)

Multiply two physical quantities. The unit of the result is the product of the units of the operands.

>>> print(PhysicalField(10., 'N') * PhysicalField(10., 'm') == PhysicalField(100., 'N*m'))
True

As a special case, if the result is dimensionless, the value is returned without units, rather than with a dimensionless unit of 1. This facilitates passing physical quantities to packages such as Numeric that cannot use units, while ensuring the quantities have the desired units.

>>> print((PhysicalField(10., 's') * PhysicalField(2., 'Hz')))
20.0
property numericValue

Return the PhysicalField without units, after conversion to base SI units.

>>> print(numerix.round_(PhysicalField("1 inch").numericValue, 6))
0.0254
put(indices, values)

put is the opposite of take. The values of self at the locations specified in indices are set to the corresponding value of values.

The indices can be any integer sequence object with values suitable for indexing into the flat form of self. The values must be any sequence of values that can be converted to the typecode of self.

>>> f = PhysicalField((1., 2., 3.), "m")
>>> f.put((2, 0), PhysicalField((2., 3.), "inch"))
>>> print(f)
[ 0.0762  2.      0.0508] m

The units of values must be compatible with self.

>>> f.put(1, PhysicalField(3, "kg"))
Traceback (most recent call last):
    ...
TypeError: Incompatible units
ravel()
reshape(shape)

Changes the shape of self to that specified in shape

>>> print(PhysicalField((1., 2., 3., 4.), "m").reshape((2, 2)))
[[ 1.  2.]
 [ 3.  4.]] m

The new shape must have the same size as the existing one.

>>> print(PhysicalField((1., 2., 3., 4.), "m").reshape((2, 3))) 
Traceback (most recent call last):
    ...
ValueError: total size of new array must be unchanged
property shape

Tuple of array dimensions.

sign()

Return the sign of the quantity. The unit is unchanged.

>>> from fipy.tools.numerix import sign
>>> print(sign(PhysicalField(((3., -2.), (-1., 4.)), 'm')))
[[ 1. -1.]
 [-1.  1.]]
sin()

Return the sine of the PhysicalField

>>> print(PhysicalField(numerix.pi/6, "rad").sin())
0.5
>>> print(PhysicalField(30., "deg").sin())
0.5

The units of the PhysicalField must be an angle

>>> PhysicalField(30., "m").sin()
Traceback (most recent call last):
    ...
TypeError: Incompatible units
sinh()

Return the hyperbolic sine of the PhysicalField

>>> PhysicalField(0.).sinh()
0.0

The units of the PhysicalField must be dimensionless

>>> PhysicalField(60., "m").sinh()
Traceback (most recent call last):
    ...
TypeError: Incompatible units
sqrt()

Return the square root of the PhysicalField

>>> print(PhysicalField("100. m**2").sqrt())
10.0 m

The resulting unit must be integral

>>> print(PhysicalField("100. m").sqrt())
Traceback (most recent call last):
    ...
TypeError: Illegal exponent
subtract(other)

Subtract two physical quantities, so long as their units are compatible. The unit of the result is the unit of the first operand.

>>> print(PhysicalField(10., 'km') - PhysicalField(10., 'm'))
9.99 km
>>> print(PhysicalField(10., 'km') - PhysicalField(10., 'J'))
Traceback (most recent call last):
    ...
TypeError: Incompatible units
sum(index=0)

Returns the sum of all of the elements in self along the specified axis (first axis by default).

>>> print(PhysicalField(((1., 2.), (3., 4.)), "m").sum())
[ 4.  6.] m
>>> print(PhysicalField(((1., 2.), (3., 4.)), "m").sum(1))
[ 3.  7.] m
take(indices, axis=0)

Return the elements of self specified by the elements of indices. The resulting PhysicalField array has the same units as the original.

>>> print(PhysicalField((1., 2., 3.), "m").take((2, 0)))
[ 3.  1.] m

The optional third argument specifies the axis along which the selection occurs, and the default value (as in the example above) is 0, the first axis.

>>> print(PhysicalField(((1., 2., 3.), (4., 5., 6.)), "m").take((2, 0), axis = 1))
[[ 3.  1.]
 [ 6.  4.]] m
tan()

Return the tangent of the PhysicalField

>>> numerix.round_(PhysicalField(numerix.pi/4, "rad").tan(), 6)
1.0
>>> numerix.round_(PhysicalField(45, "deg").tan(), 6)
1.0

The units of the PhysicalField must be an angle

>>> PhysicalField(45., "m").tan()
Traceback (most recent call last):
    ...
TypeError: Incompatible units
tanh()

Return the hyperbolic tangent of the PhysicalField

>>> print(numerix.allclose(PhysicalField(1.).tanh(), 0.761594155956))
True

The units of the PhysicalField must be dimensionless

>>> PhysicalField(60., "m").tanh()
Traceback (most recent call last):
    ...
TypeError: Incompatible units
tostring(max_line_width=75, precision=8, suppress_small=False, separator=' ')

Return human-readable form of a physical quantity

>>> p = PhysicalField(value = (3., 3.14159), unit = "eV")
>>> print(p.tostring(precision = 3, separator = '|'))
[ 3.   | 3.142] eV
property unit

Return the unit object of self.

>>> PhysicalField("1 m").unit
<PhysicalUnit m>
class fipy.PowerLawConvectionTerm(coeff=1.0, var=None)

Bases: fipy.terms.asymmetricConvectionTerm._AsymmetricConvectionTerm

The discretization for this Term is given by

\int_V \nabla \cdot (\vec{u} \phi)\,dV \simeq \sum_{f} (\vec{n}
\cdot \vec{u})_f \phi_f A_f

where \phi_f=\alpha_f \phi_P +(1-\alpha_f)\phi_A and \alpha_f is calculated using the power law scheme. For further details see Numerical Schemes.

Create a _AbstractConvectionTerm object.

>>> from fipy import *
>>> m = Grid1D(nx = 2)
>>> cv = CellVariable(mesh = m)
>>> fv = FaceVariable(mesh = m)
>>> vcv = CellVariable(mesh=m, rank=1)
>>> vfv = FaceVariable(mesh=m, rank=1)
>>> __ConvectionTerm(coeff = cv) 
Traceback (most recent call last):
    ...
VectorCoeffError: The coefficient must be a vector value.
>>> __ConvectionTerm(coeff = fv) 
Traceback (most recent call last):
    ...
VectorCoeffError: The coefficient must be a vector value.
>>> __ConvectionTerm(coeff = vcv)
__ConvectionTerm(coeff=_ArithmeticCellToFaceVariable(value=array([[ 0.,  0.,  0.]]), mesh=UniformGrid1D(dx=1.0, nx=2)))
>>> __ConvectionTerm(coeff = vfv)
__ConvectionTerm(coeff=FaceVariable(value=array([[ 0.,  0.,  0.]]), mesh=UniformGrid1D(dx=1.0, nx=2)))
>>> __ConvectionTerm(coeff = (1,))
__ConvectionTerm(coeff=(1,))
>>> ExplicitUpwindConvectionTerm(coeff = (0,)).solve(var=cv, solver=DummySolver()) 
Traceback (most recent call last):
    ...
TransientTermError: The equation requires a TransientTerm with explicit convection.
>>> (TransientTerm(0.) - ExplicitUpwindConvectionTerm(coeff = (0,))).solve(var=cv, solver=DummySolver(), dt=1.)
>>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = 1)).solve(var=cv, solver=DummySolver(), dt=1.) 
Traceback (most recent call last):
    ...
VectorCoeffError: The coefficient must be a vector value.
>>> m2 = Grid2D(nx=2, ny=1)
>>> cv2 = CellVariable(mesh=m2)
>>> vcv2 = CellVariable(mesh=m2, rank=1)
>>> vfv2 = FaceVariable(mesh=m2, rank=1)
>>> __ConvectionTerm(coeff=vcv2)
__ConvectionTerm(coeff=_ArithmeticCellToFaceVariable(value=array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.]]), mesh=UniformGrid2D(dx=1.0, nx=2, dy=1.0, ny=1)))
>>> __ConvectionTerm(coeff=vfv2)
__ConvectionTerm(coeff=FaceVariable(value=array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.]]), mesh=UniformGrid2D(dx=1.0, nx=2, dy=1.0, ny=1)))
>>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = ((0,), (0,)))).solve(var=cv2, solver=DummySolver(), dt=1.)
>>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = (0, 0))).solve(var=cv2, solver=DummySolver(), dt=1.)
Parameters

coeff (The Term’s coefficient value.) –

__module__ = 'fipy.terms.powerLawConvectionTerm'
exception fipy.PreconditionerNotPositiveDefiniteWarning(solver, iter, relres)

Bases: fipy.solvers.solver.PreconditionerWarning

__module__ = 'fipy.solvers.solver'
__str__()

Return str(self).

exception fipy.PreconditionerWarning(solver, iter, relres)

Bases: fipy.solvers.solver.SolverConvergenceWarning

__module__ = 'fipy.solvers.solver'
class fipy.ResidualTerm(equation, underRelaxation=1.0)

Bases: fipy.terms.explicitSourceTerm._ExplicitSourceTerm

The ResidualTerm is a special form of explicit SourceTerm that adds the residual of one equation to another equation. Useful for Newton’s method.

Create a Term.

Parameters

coeff (float or CellVariable or FaceVariable) – Coefficient for the term. FaceVariable objects are only acceptable for diffusion or convection terms.

__init__(equation, underRelaxation=1.0)

Create a Term.

Parameters

coeff (float or CellVariable or FaceVariable) – Coefficient for the term. FaceVariable objects are only acceptable for diffusion or convection terms.

__module__ = 'fipy.terms.residualTerm'
__repr__()

The representation of a Term object is given by,

>>> print(__UnaryTerm(123.456))
__UnaryTerm(coeff=123.456)
exception fipy.ScalarQuantityOutOfRangeWarning(solver, iter, relres)

Bases: fipy.solvers.solver.SolverConvergenceWarning

__module__ = 'fipy.solvers.solver'
__str__()

Return str(self).

class fipy.ScharfetterGummelFaceVariable(*args, **kwds)

Bases: fipy.variables.cellToFaceVariable._CellToFaceVariable

Parameters
  • mesh (Mesh) – the mesh that defines the geometry of this Variable

  • name (str) – the user-readable name of the Variable

  • value (float or array_like) – the initial value

  • rank (int) – the rank (number of dimensions) of each element of this Variable. Default: 0

  • elementshape (tuple of int) – the shape of each element of this variable Default: rank * (mesh.dim,)

  • unit (str or PhysicalUnit) – The physical units of the variable

__init__(var, boundaryConditions=())
Parameters
  • mesh (Mesh) – the mesh that defines the geometry of this Variable

  • name (str) – the user-readable name of the Variable

  • value (float or array_like) – the initial value

  • rank (int) – the rank (number of dimensions) of each element of this Variable. Default: 0

  • elementshape (tuple of int) – the shape of each element of this variable Default: rank * (mesh.dim,)

  • unit (str or PhysicalUnit) – The physical units of the variable

__module__ = 'fipy.variables.scharfetterGummelFaceVariable'
fipy.SharedTemporaryFile(mode='w+b', buffering=- 1, encoding=None, newline=None, suffix='', prefix='tmp', dir=None, delete=True, communicator=SerialPETScCommWrapper())

Create a temporary file shared by all MPI ranks.

The file is created as NamedTemporaryFile would do it. The name of the returned file-like object is accessible as its name attribute. The file will be automatically deleted when it is closed unless the delete argument is set to False.

>>> from fipy.tools import SharedTemporaryFile, parallelComm
>>> with SharedTemporaryFile(mode='w+', suffix=".tmp") as tmpFile:
...     # write on processor 0
...     if parallelComm.procID == 0:
...         _ = tmpFile.write("shared text")
...
...     parallelComm.Barrier()
...
...     # read on all processors
...     _ = tmpFile.seek(0)
...     txt = tmpFile.read()
>>> print(txt)
shared text
Parameters
  • prefix (str) – As for mkstemp

  • suffix (str) – As for mkstemp

  • dir (str) – As for mkstemp

  • mode (str) – The mode argument to io.open (default “w+b”)

  • buffering (int) – The buffer size argument to io.open (default -1)

  • encoding (str or None) – The encoding argument to io.open (default None)

  • newline (str or None) – The newline argument to io.open (default None)

  • delete (bool) – Whether the file is deleted on close (default True)

  • communicator (CommWrapper) – MPI communicator describing ranks to share with. A duck-typed object with procID and Nproc attributes is sufficient.

Returns

Return type

file-like object

class fipy.SkewedGrid2D(dx=1.0, dy=1.0, nx=None, ny=1, rand=0, *args, **kwargs)

Bases: fipy.meshes.mesh2D.Mesh2D

Creates a 2D grid mesh with horizontal faces numbered first and then vertical faces. The points are skewed by a random amount (between rand and -rand) in the X and Y directions.

Note

This Mesh only operates in serial

__init__(dx=1.0, dy=1.0, nx=None, ny=1, rand=0, *args, **kwargs)

Initialize self. See help(type(self)) for accurate signature.

__module__ = 'fipy.meshes.skewedGrid2D'
property physicalShape

Return physical dimensions of Grid2D.

property shape
exception fipy.SolutionVariableNumberError(s='Different number of solution variables and equations.')

Bases: Exception

__init__(s='Different number of solution variables and equations.')

Initialize self. See help(type(self)) for accurate signature.

__module__ = 'fipy.terms'
__weakref__

list of weak references to the object (if defined)

exception fipy.SolutionVariableRequiredError(s='The solution variable needs to be specified.')

Bases: Exception

__init__(s='The solution variable needs to be specified.')

Initialize self. See help(type(self)) for accurate signature.

__module__ = 'fipy.terms'
__weakref__

list of weak references to the object (if defined)

class fipy.Solver(tolerance=1e-10, iterations=1000, precon=None)

Bases: object

The base LinearXSolver class.

Attention

This class is abstract. Always create one of its subclasses.

Create a Solver object.

Parameters
  • tolerance (float) – Required error tolerance.

  • iterations (int) – Maximum number of iterative steps to perform.

  • precon – Preconditioner to use. Not all solver suites support preconditioners.

__dict__ = mappingproxy({'__module__': 'fipy.solvers.solver', '__doc__': '\n The base `LinearXSolver` class.\n\n .. attention:: This class is abstract. Always create one of its subclasses.\n ', '__init__': <function Solver.__init__>, '_storeMatrix': <function Solver._storeMatrix>, '_solve': <function Solver._solve>, '_solve_': <function Solver._solve_>, '_applyUnderRelaxation': <function Solver._applyUnderRelaxation>, '_calcResidualVector': <function Solver._calcResidualVector>, '_calcResidual': <function Solver._calcResidual>, '_calcRHSNorm': <function Solver._calcRHSNorm>, '_warningList': (<class 'fipy.solvers.solver.ScalarQuantityOutOfRangeWarning'>, <class 'fipy.solvers.solver.StagnatedSolverWarning'>, <class 'fipy.solvers.solver.MatrixIllConditionedWarning'>, <class 'fipy.solvers.solver.PreconditionerNotPositiveDefiniteWarning'>, <class 'fipy.solvers.solver.IllConditionedPreconditionerWarning'>, <class 'fipy.solvers.solver.MaximumIterationWarning'>), '_raiseWarning': <function Solver._raiseWarning>, '__repr__': <function Solver.__repr__>, '_canSolveAsymmetric': <function Solver._canSolveAsymmetric>, '__enter__': <function Solver.__enter__>, '__exit__': <function Solver.__exit__>, '__dict__': <attribute '__dict__' of 'Solver' objects>, '__weakref__': <attribute '__weakref__' of 'Solver' objects>, '__annotations__': {}})
__enter__()
__exit__(exc_type, exc_value, traceback)
__init__(tolerance=1e-10, iterations=1000, precon=None)

Create a Solver object.

Parameters
  • tolerance (float) – Required error tolerance.

  • iterations (int) – Maximum number of iterative steps to perform.

  • precon – Preconditioner to use. Not all solver suites support preconditioners.

__module__ = 'fipy.solvers.solver'
__repr__()

Return repr(self).

__weakref__

list of weak references to the object (if defined)

exception fipy.SolverConvergenceWarning(solver, iter, relres)

Bases: Warning

__init__(solver, iter, relres)

Initialize self. See help(type(self)) for accurate signature.

__module__ = 'fipy.solvers.solver'
__str__()

Return str(self).

__weakref__

list of weak references to the object (if defined)

fipy.SphericalGrid1D(dr=None, nr=None, Lr=None, dx=1.0, nx=None, Lx=None, origin=(0), overlap=2, communicator=SerialPETScCommWrapper())

Factory function to select between SphericalUniformGrid1D and SphericalNonUniformGrid1D. If Lr is specified the length of the domain is always Lr regardless of dr, unless dr is a list of spacings, in which case Lr will be the sum of dr.

Parameters
  • dr (float) – Grid spacing in the radial direction. Alternative: dx.

  • nr (int) – Number of cells in the radial direction. Alternative: nx.

  • Lr (float) – Domain length in the radial direction. Alternative: Lx.

  • overlap (int) – the number of overlapping cells for parallel simulations. Generally 2 is adequate. Higher order equations or discretizations require more.

  • communicator (CommWrapper) – Generally, fipy.tools.serialComm or fipy.tools.parallelComm. Select ~fipy.tools.serialComm to create a serial mesh when running in parallel; mostly used for test purposes.

exception fipy.StagnatedSolverWarning(solver, iter, relres)

Bases: fipy.solvers.solver.SolverConvergenceWarning

__module__ = 'fipy.solvers.solver'
__str__()

Return str(self).

class fipy.SurfactantConvectionVariable(*args, **kwds)

Bases: fipy.variables.faceVariable.FaceVariable

Convection coefficient for the ConservativeSurfactantEquation. The coefficient only has a value for a negative distanceVar.

Simple one dimensional test:

>>> from fipy.variables.cellVariable import CellVariable
>>> from fipy.meshes import Grid2D
>>> mesh = Grid2D(nx = 3, ny = 1, dx = 1., dy = 1.)
>>> from fipy.variables.distanceVariable import DistanceVariable
>>> distanceVar = DistanceVariable(mesh, value = (-.5, .5, 1.5))
>>> ## answer = numerix.zeros((2, mesh.numberOfFaces),'d')
>>> answer = FaceVariable(mesh=mesh, rank=1, value=0.).globalValue
>>> answer[0, 7] = -1
>>> print(numerix.allclose(SurfactantConvectionVariable(distanceVar).globalValue, answer))
True

Change the dimensions:

>>> mesh = Grid2D(nx = 3, ny = 1, dx = .5, dy = .25)
>>> distanceVar = DistanceVariable(mesh, value = (-.25, .25, .75))
>>> answer[0, 7] = -.5
>>> print(numerix.allclose(SurfactantConvectionVariable(distanceVar).globalValue, answer))
True

Two dimensional example:

>>> mesh = Grid2D(nx = 2, ny = 2, dx = 1., dy = 1.)
>>> distanceVar = DistanceVariable(mesh, value = (-1.5, -.5, -.5, .5))
 >>> answer = FaceVariable(mesh=mesh, rank=1, value=0.).globalValue
>>> answer[1, 2] = -.5
>>> answer[1, 3] = -1
>>> answer[0, 7] = -.5
>>> answer[0, 10] = -1
>>> print(numerix.allclose(SurfactantConvectionVariable(distanceVar).globalValue, answer))
True

Larger grid:

>>> mesh = Grid2D(nx = 3, ny = 3, dx = 1., dy = 1.)
>>> distanceVar = DistanceVariable(mesh, value = (1.5, .5, 1.5,
...                                           .5, -.5, .5,
...                                           1.5, .5, 1.5))
 >>> answer = FaceVariable(mesh=mesh, rank=1, value=0.).globalValue
>>> answer[1, 4] = .25
>>> answer[1, 7] = -.25
>>> answer[0, 17] = .25
>>> answer[0, 18] = -.25
>>> print(numerix.allclose(SurfactantConvectionVariable(distanceVar).globalValue, answer))
True
__init__(distanceVar)

Simple one dimensional test:

>>> from fipy.variables.cellVariable import CellVariable
>>> from fipy.meshes import Grid2D
>>> mesh = Grid2D(nx = 3, ny = 1, dx = 1., dy = 1.)
>>> from fipy.variables.distanceVariable import DistanceVariable
>>> distanceVar = DistanceVariable(mesh, value = (-.5, .5, 1.5))
>>> ## answer = numerix.zeros((2, mesh.numberOfFaces),'d')
>>> answer = FaceVariable(mesh=mesh, rank=1, value=0.).globalValue
>>> answer[0, 7] = -1
>>> print(numerix.allclose(SurfactantConvectionVariable(distanceVar).globalValue, answer))
True

Change the dimensions:

>>> mesh = Grid2D(nx = 3, ny = 1, dx = .5, dy = .25)
>>> distanceVar = DistanceVariable(mesh, value = (-.25, .25, .75))
>>> answer[0, 7] = -.5
>>> print(numerix.allclose(SurfactantConvectionVariable(distanceVar).globalValue, answer))
True

Two dimensional example:

>>> mesh = Grid2D(nx = 2, ny = 2, dx = 1., dy = 1.)
>>> distanceVar = DistanceVariable(mesh, value = (-1.5, -.5, -.5, .5))
 >>> answer = FaceVariable(mesh=mesh, rank=1, value=0.).globalValue
>>> answer[1, 2] = -.5
>>> answer[1, 3] = -1
>>> answer[0, 7] = -.5
>>> answer[0, 10] = -1
>>> print(numerix.allclose(SurfactantConvectionVariable(distanceVar).globalValue, answer))
True

Larger grid:

>>> mesh = Grid2D(nx = 3, ny = 3, dx = 1., dy = 1.)
>>> distanceVar = DistanceVariable(mesh, value = (1.5, .5, 1.5,
...                                           .5, -.5, .5,
...                                           1.5, .5, 1.5))
 >>> answer = FaceVariable(mesh=mesh, rank=1, value=0.).globalValue
>>> answer[1, 4] = .25
>>> answer[1, 7] = -.25
>>> answer[0, 17] = .25
>>> answer[0, 18] = -.25
>>> print(numerix.allclose(SurfactantConvectionVariable(distanceVar).globalValue, answer))
True
__module__ = 'fipy.variables.surfactantConvectionVariable'
class fipy.SurfactantVariable(*args, **kwds)

Bases: fipy.variables.cellVariable.CellVariable

The SurfactantVariable maintains a conserved volumetric concentration on cells adjacent to, but in front of, the interface. The value argument corresponds to the initial concentration of surfactant on the interface (moles divided by area). The value held by the SurfactantVariable is actually a volume density (moles divided by volume).

A simple 1D test:

>>> from fipy.meshes import Grid1D
>>> mesh = Grid1D(dx = 1., nx = 4)
>>> from fipy.variables.distanceVariable import DistanceVariable
>>> distanceVariable = DistanceVariable(mesh = mesh,
...                                     value = (-1.5, -0.5, 0.5, 941.5))
>>> surfactantVariable = SurfactantVariable(value = 1,
...                                         distanceVar = distanceVariable)
>>> print(numerix.allclose(surfactantVariable, (0, 0., 1., 0)))
1

A 2D test case:

>>> from fipy.meshes import Grid2D
>>> mesh = Grid2D(dx = 1., dy = 1., nx = 3, ny = 3)
>>> distanceVariable = DistanceVariable(mesh = mesh,
...                                     value = (1.5, 0.5, 1.5,
...                                              0.5, -0.5, 0.5,
...                                              1.5, 0.5, 1.5))
>>> surfactantVariable = SurfactantVariable(value = 1,
...                                         distanceVar = distanceVariable)
>>> print(numerix.allclose(surfactantVariable, (0, 1, 0, 1, 0, 1, 0, 1, 0)))
1

Another 2D test case:

>>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2)
>>> distanceVariable = DistanceVariable(mesh = mesh,
...                                     value = (-0.5, 0.5, 0.5, 1.5))
>>> surfactantVariable = SurfactantVariable(value = 1,
...                                         distanceVar = distanceVariable)
>>> print(numerix.allclose(surfactantVariable,
...                  (0, numerix.sqrt(2), numerix.sqrt(2), 0)))
1
Parameters
  • value (float or array_like) – The initial value.

  • distanceVar (DistanceVariable) –

  • name (str) – The name of the variable.

__init__(value=0.0, distanceVar=None, name='surfactant variable', hasOld=False)

A simple 1D test:

>>> from fipy.meshes import Grid1D
>>> mesh = Grid1D(dx = 1., nx = 4)
>>> from fipy.variables.distanceVariable import DistanceVariable
>>> distanceVariable = DistanceVariable(mesh = mesh,
...                                     value = (-1.5, -0.5, 0.5, 941.5))
>>> surfactantVariable = SurfactantVariable(value = 1,
...                                         distanceVar = distanceVariable)
>>> print(numerix.allclose(surfactantVariable, (0, 0., 1., 0)))
1

A 2D test case:

>>> from fipy.meshes import Grid2D
>>> mesh = Grid2D(dx = 1., dy = 1., nx = 3, ny = 3)
>>> distanceVariable = DistanceVariable(mesh = mesh,
...                                     value = (1.5, 0.5, 1.5,
...                                              0.5, -0.5, 0.5,
...                                              1.5, 0.5, 1.5))
>>> surfactantVariable = SurfactantVariable(value = 1,
...                                         distanceVar = distanceVariable)
>>> print(numerix.allclose(surfactantVariable, (0, 1, 0, 1, 0, 1, 0, 1, 0)))
1

Another 2D test case:

>>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2)
>>> distanceVariable = DistanceVariable(mesh = mesh,
...                                     value = (-0.5, 0.5, 0.5, 1.5))
>>> surfactantVariable = SurfactantVariable(value = 1,
...                                         distanceVar = distanceVariable)
>>> print(numerix.allclose(surfactantVariable,
...                  (0, numerix.sqrt(2), numerix.sqrt(2), 0)))
1
Parameters
  • value (float or array_like) – The initial value.

  • distanceVar (DistanceVariable) –

  • name (str) – The name of the variable.

__module__ = 'fipy.variables.surfactantVariable'
copy()

Make an duplicate of the Variable

>>> a = Variable(value=3)
>>> b = a.copy()
>>> b
Variable(value=array(3))

The duplicate will not reflect changes made to the original

>>> a.setValue(5)
>>> b
Variable(value=array(3))

Check that this works for arrays.

>>> a = Variable(value=numerix.array((0, 1, 2)))
>>> b = a.copy()
>>> b
Variable(value=array([0, 1, 2]))
>>> a[1] = 3
>>> b
Variable(value=array([0, 1, 2]))
property interfaceVar

Returns the SurfactantVariable rendered as an _InterfaceSurfactantVariable which evaluates the surfactant concentration as an area concentration the interface rather than a volumetric concentration.

class fipy.TSVViewer(vars, title=None, limits={}, **kwlimits)

Bases: fipy.viewers.viewer.AbstractViewer

“Views” one or more variables in tab-separated-value format.

Output is a list of coordinates and variable values at each cell center.

File contents will be, e.g.:

title
x       y       ...     var0    var2    ...
0.0     0.0     ...     3.14    1.41    ...
1.0     0.0     ...     2.72    0.866   ...
:
:

Creates a TSVViewer.

Any cell centers that lie outside the limits provided will not be included. Any values that lie outside the datamin or datamax will be replaced with nan.

All variables must have the same mesh.

It tries to do something reasonable with rank-1 CellVariable and FaceVariable objects.

Parameters
  • vars (CellVariable or FaceVariable or list) – the MeshVariable objects to display.

  • title (str, optional) – displayed at the top of the Viewer window

  • limits (dict, optional) – a (deprecated) alternative to limit keyword arguments

  • xmin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • xmax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • zmin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • zmax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

__init__(vars, title=None, limits={}, **kwlimits)

Creates a TSVViewer.

Any cell centers that lie outside the limits provided will not be included. Any values that lie outside the datamin or datamax will be replaced with nan.

All variables must have the same mesh.

It tries to do something reasonable with rank-1 CellVariable and FaceVariable objects.

Parameters
  • vars (CellVariable or FaceVariable or list) – the MeshVariable objects to display.

  • title (str, optional) – displayed at the top of the Viewer window

  • limits (dict, optional) – a (deprecated) alternative to limit keyword arguments

  • xmin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • xmax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • zmin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • zmax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • datamax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

__module__ = 'fipy.viewers.tsvViewer'
plot(filename=None)

“plot” the coordinates and values of the variables to filename. If filename is not provided, “plots” to stdout.

>>> from fipy.meshes import Grid1D
>>> m = Grid1D(nx = 3, dx = 0.4)
>>> from fipy.variables.cellVariable import CellVariable
>>> v = CellVariable(mesh = m, name = "var", value = (0, 2, 5))
>>> TSVViewer(vars = (v, v.grad)).plot() 
x       var     var_gauss_grad_x
0.2     0       2.5
0.6     2       6.25
1       5       3.75
>>> from fipy.meshes import Grid2D
>>> m = Grid2D(nx = 2, dx = .1, ny = 2, dy = 0.3)
>>> v = CellVariable(mesh = m, name = "var", value = (0, 2, -2, 5))
>>> TSVViewer(vars = (v, v.grad)).plot() 
x       y       var     var_gauss_grad_x        var_gauss_grad_y
0.05    0.15    0       10      -3.33333333333333
0.15    0.15    2       10      5
0.05    0.45    -2      35      -3.33333333333333
0.15    0.45    5       35      5
Parameters

filename (str) – If not None, the name of a file to save the image into.

exception fipy.TermMultiplyError(s='Must multiply terms by int or float.')

Bases: Exception

__init__(s='Must multiply terms by int or float.')

Initialize self. See help(type(self)) for accurate signature.

__module__ = 'fipy.terms'
__weakref__

list of weak references to the object (if defined)

class fipy.TransientTerm(coeff=1.0, var=None)

Bases: fipy.terms.cellTerm.CellTerm

The TransientTerm represents

\int_V \frac{\partial (\rho \phi)}{\partial t} dV \simeq
\frac{(\rho_{P} \phi_{P} - \rho_{P}^\text{old} \phi_P^\text{old}) V_P}{\Delta t}

where \rho is the coeff value.

The following test case verifies that variable coefficients and old coefficient values work correctly. We will solve the following equation

\frac{ \partial \phi^2 } { \partial t } = k.

The analytic solution is given by

\phi = \sqrt{ \phi_0^2 + k t },

where \phi_0 is the initial value.

>>> phi0 = 1.
>>> k = 1.
>>> dt = 1.
>>> relaxationFactor = 1.5
>>> steps = 2
>>> sweeps = 8
>>> from fipy.meshes import Grid1D
>>> mesh = Grid1D(nx = 1)
>>> from fipy.variables.cellVariable import CellVariable
>>> var = CellVariable(mesh = mesh, value = phi0, hasOld = 1)
>>> from fipy.terms.transientTerm import TransientTerm
>>> from fipy.terms.implicitSourceTerm import ImplicitSourceTerm

Relaxation, given by relaxationFactor, is required for a converged solution.

>>> eq = TransientTerm(var) == ImplicitSourceTerm(-relaxationFactor) \
...                            + var * relaxationFactor + k

A number of sweeps at each time step are required to let the relaxation take effect.

>>> from builtins import range
>>> for step in range(steps):
...     var.updateOld()
...     for sweep in range(sweeps):
...         eq.solve(var, dt = dt)

Compare the final result with the analytical solution.

>>> from fipy.tools import numerix
>>> print(var.allclose(numerix.sqrt(k * dt * steps + phi0**2)))
1

Create a Term.

Parameters

coeff (float or CellVariable or FaceVariable) – Coefficient for the term. FaceVariable objects are only acceptable for diffusion or convection terms.

__module__ = 'fipy.terms.transientTerm'
class fipy.Tri2D(dx=1.0, dy=1.0, nx=1, ny=1, _RepresentationClass=<class 'fipy.meshes.representations.gridRepresentation._Grid2DRepresentation'>, _TopologyClass=<class 'fipy.meshes.topologies.meshTopology._Mesh2DTopology'>)

Bases: fipy.meshes.mesh2D.Mesh2D

This class creates a mesh made out of triangles. It does this by starting with a standard Cartesian mesh (Grid2D) and dividing each cell in that mesh (hereafter referred to as a “box”) into four equal parts with the dividing lines being the diagonals.

Creates a 2D triangular mesh with horizontal faces numbered first then vertical faces, then diagonal faces. Vertices are numbered starting with the vertices at the corners of boxes and then the vertices at the centers of boxes. Cells on the right of boxes are numbered first, then cells on the top of boxes, then cells on the left of boxes, then cells on the bottom of boxes. Within each of the “sub-categories” in the above, the vertices, cells and faces are numbered in the usual way.

Parameters
  • dx (float) – The X and Y dimensions of each “box”. If dx <> dy, the line segments connecting the cell centers will not be orthogonal to the faces.

  • dy (float) – The X and Y dimensions of each “box”. If dx <> dy, the line segments connecting the cell centers will not be orthogonal to the faces.

  • nx (int) – The number of boxes in the X direction and the Y direction. The total number of boxes will be equal to nx * ny, and the total number of cells will be equal to 4 * nx * ny.

  • ny (int) – The number of boxes in the X direction and the Y direction. The total number of boxes will be equal to nx * ny, and the total number of cells will be equal to 4 * nx * ny.

__init__(dx=1.0, dy=1.0, nx=1, ny=1, _RepresentationClass=<class 'fipy.meshes.representations.gridRepresentation._Grid2DRepresentation'>, _TopologyClass=<class 'fipy.meshes.topologies.meshTopology._Mesh2DTopology'>)

Creates a 2D triangular mesh with horizontal faces numbered first then vertical faces, then diagonal faces. Vertices are numbered starting with the vertices at the corners of boxes and then the vertices at the centers of boxes. Cells on the right of boxes are numbered first, then cells on the top of boxes, then cells on the left of boxes, then cells on the bottom of boxes. Within each of the “sub-categories” in the above, the vertices, cells and faces are numbered in the usual way.

Parameters
  • dx (float) – The X and Y dimensions of each “box”. If dx <> dy, the line segments connecting the cell centers will not be orthogonal to the faces.

  • dy (float) – The X and Y dimensions of each “box”. If dx <> dy, the line segments connecting the cell centers will not be orthogonal to the faces.

  • nx (int) – The number of boxes in the X direction and the Y direction. The total number of boxes will be equal to nx * ny, and the total number of cells will be equal to 4 * nx * ny.

  • ny (int) – The number of boxes in the X direction and the Y direction. The total number of boxes will be equal to nx * ny, and the total number of cells will be equal to 4 * nx * ny.

__module__ = 'fipy.meshes.tri2D'
property physicalShape

Return physical dimensions of Grid2D.

property shape
class fipy.UniformNoiseVariable(*args, **kwds)

Bases: fipy.variables.noiseVariable.NoiseVariable

Represents a uniform distribution of random numbers.

We generate noise on a uniform Cartesian mesh

>>> from fipy.meshes import Grid2D
>>> noise = UniformNoiseVariable(mesh=Grid2D(nx=100, ny=100))

and histogram the noise

>>> from fipy.variables.histogramVariable import HistogramVariable
>>> histogram = HistogramVariable(distribution=noise, dx=0.01, nx=120, offset=-.1)
>>> if __name__ == '__main__':
...     from fipy import Viewer
...     viewer = Viewer(vars=noise,
...                     datamin=0, datamax=1)
...     histoplot = Viewer(vars=histogram)
>>> from builtins import range
>>> for i in range(10):
...     noise.scramble()
...     if __name__ == '__main__':
...         viewer.plot()
...         histoplot.plot()
random values with a uniform distribution histogram of random values with a uniform distribution
Parameters
  • mesh (Mesh) – The mesh on which to define the noise.

  • minimum (float) – The minimum (not-inclusive) value of the distribution.

  • maximum (float) – The maximum (not-inclusive) value of the distribution.

__init__(mesh, name='', minimum=0.0, maximum=1.0, hasOld=0)
Parameters
  • mesh (Mesh) – The mesh on which to define the noise.

  • minimum (float) – The minimum (not-inclusive) value of the distribution.

  • maximum (float) – The maximum (not-inclusive) value of the distribution.

__module__ = 'fipy.variables.uniformNoiseVariable'
random()
class fipy.UpwindConvectionTerm(coeff=1.0, var=None)

Bases: fipy.terms.abstractUpwindConvectionTerm._AbstractUpwindConvectionTerm

The discretization for this Term is given by

\int_V \nabla \cdot (\vec{u} \phi)\,dV \simeq \sum_{f} (\vec{n}
\cdot \vec{u})_f \phi_f A_f

where \phi_f=\alpha_f \phi_P +(1-\alpha_f)\phi_A and \alpha_f is calculated using the upwind convection scheme. For further details see Numerical Schemes.

Create a _AbstractConvectionTerm object.

>>> from fipy import *
>>> m = Grid1D(nx = 2)
>>> cv = CellVariable(mesh = m)
>>> fv = FaceVariable(mesh = m)
>>> vcv = CellVariable(mesh=m, rank=1)
>>> vfv = FaceVariable(mesh=m, rank=1)
>>> __ConvectionTerm(coeff = cv) 
Traceback (most recent call last):
    ...
VectorCoeffError: The coefficient must be a vector value.
>>> __ConvectionTerm(coeff = fv) 
Traceback (most recent call last):
    ...
VectorCoeffError: The coefficient must be a vector value.
>>> __ConvectionTerm(coeff = vcv)
__ConvectionTerm(coeff=_ArithmeticCellToFaceVariable(value=array([[ 0.,  0.,  0.]]), mesh=UniformGrid1D(dx=1.0, nx=2)))
>>> __ConvectionTerm(coeff = vfv)
__ConvectionTerm(coeff=FaceVariable(value=array([[ 0.,  0.,  0.]]), mesh=UniformGrid1D(dx=1.0, nx=2)))
>>> __ConvectionTerm(coeff = (1,))
__ConvectionTerm(coeff=(1,))
>>> ExplicitUpwindConvectionTerm(coeff = (0,)).solve(var=cv, solver=DummySolver()) 
Traceback (most recent call last):
    ...
TransientTermError: The equation requires a TransientTerm with explicit convection.
>>> (TransientTerm(0.) - ExplicitUpwindConvectionTerm(coeff = (0,))).solve(var=cv, solver=DummySolver(), dt=1.)
>>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = 1)).solve(var=cv, solver=DummySolver(), dt=1.) 
Traceback (most recent call last):
    ...
VectorCoeffError: The coefficient must be a vector value.
>>> m2 = Grid2D(nx=2, ny=1)
>>> cv2 = CellVariable(mesh=m2)
>>> vcv2 = CellVariable(mesh=m2, rank=1)
>>> vfv2 = FaceVariable(mesh=m2, rank=1)
>>> __ConvectionTerm(coeff=vcv2)
__ConvectionTerm(coeff=_ArithmeticCellToFaceVariable(value=array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.]]), mesh=UniformGrid2D(dx=1.0, nx=2, dy=1.0, ny=1)))
>>> __ConvectionTerm(coeff=vfv2)
__ConvectionTerm(coeff=FaceVariable(value=array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.]]), mesh=UniformGrid2D(dx=1.0, nx=2, dy=1.0, ny=1)))
>>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = ((0,), (0,)))).solve(var=cv2, solver=DummySolver(), dt=1.)
>>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = (0, 0))).solve(var=cv2, solver=DummySolver(), dt=1.)
Parameters

coeff (The Term’s coefficient value.) –

__module__ = 'fipy.terms.upwindConvectionTerm'
class fipy.VTKCellViewer(vars, title=None, limits={}, **kwlimits)

Bases: fipy.viewers.vtkViewer.vtkViewer.VTKViewer

Renders CellVariable data in VTK format

Creates a VTKViewer

Parameters
  • vars (CellVariable or FaceVariable or list) – the MeshVariable objects to display.

  • title (str, optional) – displayed at the top of the Viewer window

  • limits (dict, optional) – a (deprecated) alternative to limit keyword arguments

  • xmin (float) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • xmax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymin (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • ymax (float, optional) – displayed range of data. Any limit set to a (default) value of None will autoscale.

  • zmin (float, optional) – displayed range of data. Any limit set to a (default)