Jonathan Guyer | 18 Jul 18:30
Favicon

Re: Front-fixing method for moving boundary problem


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?


Gmane