20 Jul 13:35
Re: Front-fixing method for moving boundary problem
From: Etienne Rivard <etienne.rivard@...>
Subject: Re: Front-fixing method for moving boundary problem
Newsgroups: gmane.comp.python.fipy
Date: 2008-07-20 11:35:40 GMT
Subject: Re: Front-fixing method for moving boundary problem
Newsgroups: gmane.comp.python.fipy
Date: 2008-07-20 11:35:40 GMT
Jonathan Guyer wrote: > > > 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. I'll trust you on that> > > >> 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^) Right. I remember once considering swithcing to another method like the phase field method to solve my problem. But I have to admit I was somewhat demotivated by the apparent complexity of the method. For the moment, I don't think I'll get deeper into that. > >> 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. Thanks for the offer, I appreciate it but. I have time to work on this and this actually a part of my PhD work so I need to show a deep understanding of everything I use, so I would rather shoot for a more elegant solution. Also, it makes me feel really good to know that this problem is not as simple as it looks and actually requires some thought. > > > > 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? I'll have a close look at that. Thanks for the valuable input. Etienne
>
>
>
>> 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^)
Right. I remember once considering swithcing to another method like the
phase field method to solve my problem. But I have to admit I was
somewhat demotivated by the apparent complexity of the method. For the
moment, I don't think I'll get deeper into that.
>
>> 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.
Thanks for the offer, I appreciate it but. I have time to work on this
and this actually a part of my PhD work so I need to show a deep
understanding of everything I use, so I would rather shoot for a more
elegant solution.
Also, it makes me feel really good to know that this problem is not as
simple as it looks and actually requires some thought.
>
>
>
> 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:
>
>
RSS Feed