On Jul 18, 2008, at 6:59 AM, Etienne Rivard wrote:

Jonathan, although I'm starting a new thread here, I first want to thank you for your once again very complete answer on the use of operator variables to get access to additional functions. I'm not 100\% sure yet whether I'll need to use one of those. Nevertheless, I found your answer extremely useful, it helped me a lot to understand more of the mechanics of FiPy.

I'm glad it was helpful. Now we just need to figure out how to properly document it and make it a bit more transparent for users to actually do.



Now, I'd like to have your thoughts on another aspect of my problem which is basically a Stefan problem or a free or moving boundary problem, whatever you like to call it. I want to use a front-fixing method to alleviate the moving boundary difficulty.

We wrote FiPy for solving phase field and level set problems, because we didn't ever want to think about "the moving boundary difficulty"! 8^)

Here is an example, not the problem I want to solve, but the idea is the same:

\[
\frac{\partial^2 u}{\partial \xi ^2} = s^2 \frac{\partial u} {\partial t}
- s \xi \frac{ds}{dt}\frac{\partial u}{\partial \xi}
\]

I believe you'll want to divide through by $s^2$ and render this as

\[
\nabla\cdot\left(\frac{1}{s^2} u \right) = \frac{\partial u}{\partial t}
- \nabla\cdot\left(\xi \frac{1}{s} \frac{d s}{d t} u \right)
+ \frac{1}{s} \frac{d s}{d t} u
\]

or

DiffusionTerm(coeff=1/s**2) == TransientTerm() - PowerLawConvectionTerm(coeff=xi * sdot / s) + ImplicitSourceTerm(coeff=sdot / s)



\[
-\frac{1}{s} \left. \frac{\partial u}{\partial \xi}\right|_{\xi = 1}
= \frac{ds}{dt}
\]

You want to use this as an ODE to solve for s or as a boundary condition on u? Either way, you need at least one more BC on u.


My first idea was to declare $s$ as a Variable() as in the diffusion example on page 64 of the manual, ``manually'' linearize $\frac{ds} {dt}$ with something like $\frac{s-s_{old}}{\Delta t}$ and solve the resulting algebraic equation for $s$ at every sweep.

You'll need to explicitly track $s_{old}$, as only CellVariables have that property. Alternatively, you could set up a one-element mesh and make $s$ a CellVariable on that mesh and solve it as a PDE, but we're pretty sure you'll have trouble communicating values back and forth between the two different meshes. I think FiPy will raise an error if you try to use $s$, defined on one mesh, as a coefficient for solving a variable on a different mesh, but maybe you'll get lucky... no, unfortunately you won't. I just tried:

    >>> from fipy import *
    >>> mesh = Grid1D(nx=10)
    >>> xi = mesh.getCellCenters()
    >>> u = CellVariable(mesh=mesh, hasOld=True)

    >>> smesh = Grid1D(nx=1)
    >>> s = CellVariable(mesh=smesh, value=1. hasOld=True)

    >>> dt = 1.
    >>> sdot = (s - s.getOld()) / dt
>>> eq = DiffusionTerm(coeff=1/s**2) == TransientTerm() - PowerLawConvectionTerm(coeff=xi * sdot / s) + ImplicitSourceTerm(coeff=sdot / s)

I was shocked to actually get this far, but when I tried:

    >>> s.updateOld()
    >>> s.setValue(2.)
    >>> eq.solve(vars=u)

it throws "ValueError: shape mismatch: objects cannot be broadcast to a single shape"

It turns out this is because both DiffusionTerm and ConvectionTerm want their coefficients as FaceVariables, and will interpolate a CellVariable to a FaceVariable if necessary, but a FaceVariable on smesh has two faces, instead of the optimal 1 or acceptable 11. I can probably come up with an ugly hack to avoid this, but will need to think about it.



To get $\left. \frac{\partial u}{\partial \xi}\right|_{\xi = 1}$, I think you may need to resort to the techniques discussed in this recent thread:

  http://thread.gmane.org/gmane.comp.python.fipy/973

but maybe Daniel or Recif has something better?

Reply via email to