Search code examples
pythonpython-2.7fipy

How to represent source terms depending on position and time in Fipy python


I have the following partial differential equation

enter image description here

I would like to know how I can represent the source term in Fipy python. I have tried the following

from fipy import *
nx = 50
ny = 1
dx = dy = 0.025                     # grid spacing
L = dx * nx
mesh = Grid2D(dx=dx, dy=dy, nx=nx, ny=ny)
phi = CellVariable(name="solution variable", mesh=mesh, value=0.)
convCoeff = ((10.,), (10.,))
Gamma = 1.
eqX = TransientTerm() == DiffusionTerm(coeff=Gamma) - ConvectionTerm(coeff=convCoeff) + t*numerix(exp(x*y))
valueTopLeft = 0
valueBottomRight = 1
X, Y = mesh.faceCenters
facesTopLeft = ((mesh.facesLeft & (Y > L / 2)) | (mesh.facesTop & (X < L / 2)))
facesBottomRight = ((mesh.facesRight & (Y < L / 2)) |
                    (mesh.facesBottom & (X > L / 2)))
#
phi.constrain(valueTopLeft, facesTopLeft)
phi.constrain(valueBottomRight, facesBottomRight)
timeStepDuration = 10 * 0.9 * dx ** 2 / (2 * D)
steps = 10
results = []
for step in range(steps):
    eqX.solve(var=phi, dt=timeStepDuration)
    results.append(phi.value)

and this is not working. According to fipy manual I saw they said source terms are represnted the way they appear and its recommendated using numerix module over other modules like numpy. I dont know that am missing in this code. Thanks


Solution

  • I found a number of problems with the code

    • t was undefined
    • the use of numerix and exp in the source was nonsensical and gave an error
    • D was undefined

    To make the source time dependent, t needs to be a Variable so that the source will be reevaluated whenever time changes. The time variable also needs to be updated at each step.

    Here is a corrected version of your code that actually runs.

    from fipy import *
    nx = 50
    ny = 1
    dx = dy = 0.025                     # grid spacing
    L = dx * nx
    mesh = Grid2D(dx=dx, dy=dy, nx=nx, ny=ny)
    phi = CellVariable(name="solution variable", mesh=mesh, value=0.)
    t = Variable(0.)
    x = mesh.x
    y = mesh.y
    convCoeff = ((10.,), (10.,))
    Gamma = 1.
    D = Gamma
    eqX = TransientTerm() == DiffusionTerm(coeff=Gamma) - ConvectionTerm(coeff=convCoeff) + t*numerix.exp(x*y)
    valueTopLeft = 0
    valueBottomRight = 1
    X, Y = mesh.faceCenters
    facesTopLeft = ((mesh.facesLeft & (Y > L / 2)) | (mesh.facesTop & (X < L / 2)))
    facesBottomRight = ((mesh.facesRight & (Y < L / 2)) |
                        (mesh.facesBottom & (X > L / 2)))
    #
    phi.constrain(valueTopLeft, facesTopLeft)
    phi.constrain(valueBottomRight, facesBottomRight)
    timeStepDuration = 10 * 0.9 * dx ** 2 / (2 * D)
    steps = 10
    results = []
    for step in range(steps):
        eqX.solve(var=phi, dt=timeStepDuration)
        results.append(phi.value)
        t.setValue(t.value + timeStepDuration)
        print('step:', step)