Reputation: 7089
I am looking to solve a diffusion equation using FiPy and have read some of their documentation, but can't seem to find anything that relates to writing a diffusion term that includes additional terms that are functions of the independent variable (i.e. space). The closest thing that I found was on the FAQ, where they suggest rewriting additional terms as a ConvectionTerm
. However, I believe this only applies to the case where the additional terms are functions of the solution variable rather than the independent variable. For example, I am trying to solve a 1D diffusion equation with the following diffusion term (where derivatives are w.r.t. to the independent variable x, and y is the solution variable):
D * sin(x) * Div_x {sin(x) * Grad_x {y}}
I feel that this is a pretty simple expression, but I can't find how to express it in FiPy notation. Any help would be hugely appreciated!
Exact Code:
from fipy import Variable,FaceVariable,CellVariable,Grid1D,ImplicitSourceTerm,TransientTerm,DiffusionTerm,Viewer,ConvectionTerm
from fipy.tools import numerix
D = 1
c0 = 1
ka = 1
r0 = 1
nx = 100
dx = 2*math.pi/100
mesh = Grid1D(nx=nx, dx=dx)
conc = CellVariable(name="concentration", mesh=mesh, value=0.) # This is the "phi" in the docs
valueLeft = c0
valueRight = 0
conc.constrain(valueRight, mesh.facesRight)
conc.constrain(valueLeft, mesh.facesLeft)
timeStepDuration = 0.9 * dx**2 / (2 * D)
steps = 100
show_per_steps = 50
A = 1 / (r0**2 * numerix.sin(mesh.x)[0])
dA = -(numerix.cos(mesh.x)[0])/(r0**2 * numerix.sin(mesh.x)[0]**2)
dsindA = (numerix.cos(mesh.x)[0])**3/(numerix.sin(mesh.x)[0])**2
eqX = TransientTerm() + ImplicitSourceTerm(ka) == DiffusionTerm(D*A*numerix.sin(mesh.x)[0]) - ConvectionTerm(D*dA*numerix.cos(mesh.x)[0])+ D*conc*dsindA
from builtins import range
for step in range(steps):
eqX.solve(var=conc, dt=timeStepDuration)
if __name__ == '__main__' and step % show_per_steps == 0:
viewer = Viewer(vars=(conc), datamin=0., datamax=c0)
viewer.plot()
Upvotes: 2
Views: 676
Reputation: 1068
FiPy allows the terms' coefficients to be functions of space. For example, the following works in FiPy,
from fipy import Grid1D, CellVariable, Viewer
from fipy import TransientTerm, numerix, DiffusionTerm
from fipy import LinearLUSolver
m = Grid1D(nx=100, Lx=numerix.pi / 4.)
v = CellVariable(mesh=m)
v[:] = m.x**2
eqn = TransientTerm() == DiffusionTerm(numerix.sin(m.x))
vi = Viewer(v, colorbar=None)
vi.plot()
solver = LinearLUSolver()
for i in range(10):
eqn.solve(v, dt=0.1, solver=solver)
vi.plot()
print('step', i)
input('stopped')
In the above, the diffusion coefficient is a function of space. The m.x
is a CellVariable
that holds the cell center positions. numerix
is used which enables operations on FiPy variables in the same way as Numpy does for Numpy arrays.
Now, in the above question there is a sin(x)
outside of the derivative which is not allowed in FiPy. Everything needs to fit inside of the derivative to work with FiPy. So, we need to rewrite the term so that all the coefficients are inside of the derivative. For any general case, we can write
which allows us to use a diffusion, convection and source to represent the term in FiPy. If f=sin(x)
and g=sin(x)
then the FiPy code would be
s = numerix.sin(m.cellCenters)
c = numerix.cos(m.cellCenters)
eqn = ... + DiffusionTerm(D * s[0] * s[0]) - ConvectionTerm(D * s * c) + D * y * (c[0] * c[0] - s[0] * s[0])
The ...
are included as I don't know the full equation.
Upvotes: 2