On Feb 1, 2008, at 9:57 AM, Etienne Rivard wrote:
First of all, thank you for your previous answers, it was very
helpful and quite hit the mark.
We're glad we could help.
Now, I'm still struggling with the concept of Face/CellVariable.
What confuses me is the use of CellVariables in diffusion or
convection terms.
For example in the module examples.diffusion.mesh1D on page 67,
phi, which is a CellVariable, is used in the coefficient of the
ImplicitDiffusionTerm. Is this one of those cases where "FiPy will
automatically substitute var.getArithmeticFaceValue()" as
mentionned in the FAQs?
Exactly.
If so, how would it be possible to be more rigorous and "explicitly
supply the desired FaceVariable rather than letting FiPy assume
one"? In other words, how is it possible to explicitly supply a
FaceVariable when this variable is already declared as a CellVariable?
phi.getArithmeticFaceValue() returns $\phi_f = (\phi_1 - \phi_2) \frac
{d_{f2}}{d_{12}} + \phi_2$
phi.getHarmonicFaceValue() returns $\phi_f = \frac{\phi_1 \phi_2}
{(\phi_2 - \phi_1) \frac{d_{f2}}{d_{12}} + \phi_1}$
where $phi_1$ and $phi_2$ are the CellVariable values on either side
of the face in question, $d_{12}$ is the distance between those cell
centers, and $d_{f2}$ is the distance from the face to the center of
cell 2. I thought that I'd done a geometric version, too, but it
doesn't look like it. It wouldn't be hard. I've never needed it,
whereas I use getHarmonicFaceValue() all the time (very important
with concentration variables that step from very small values to very
large values).
If you need some other interpolation, you will need to subclass form
fipy.variables.cellToFaceVariable.CellToFaceVariable. For example, in
my own code, I've defined a CellToFaceVariable that implements
Scharfetter-Gummel discretization (used in semiconductor charge
transport) to interpolate from a CellVariable containing Fermi levels
(chemical potentials) to produce a FaceVariable containing carrier
concentrations. This will eventually be included with FiPy, but if
somebody needs it in the meantime, just ask.
It is important to me because I encounter this situation in the
system of equations I would like to solve:
\[
\frac{\partial}{\partial t}(c y_F) + \nabla \cdot (c \vec{v} y_F) =
\nabla \cdot (c \bar{D} \nabla y_F)
\]
\[
\frac{\partial}{\partial t}(c y_F \theta) + \nabla \cdot (c \vec{v}
y_F \theta) =
\nabla \cdot (c \tilde{D} \nabla y_F \theta)
\]
\[
\frac{\partial}{\partial t}(c y_F \Psi) + \nabla \cdot (c \vec{v}
y_F \Psi) =
\nabla \cdot (c \hat{D} \nabla y_F \Psi)
\]
The variables I'm solving for are yF, theta and Psi.
For these equations, the issue only seems to arise for the third term
(RHS) of each equation. In those cases, you'll need to factor them
for FiPy:
1) the first term is fine in FiPy, as is, and is just a DiffusionTerm
whereas
2) $\nabla \cdot (c \tilde{D} \nabla y_F \theta)$ becomes $\nabla
\cdot (c \tilde{D} \theta \nabla y_F) + \nabla \cdot (c \tilde{D} y_F
\nabla \theta)$
3) $\nabla \cdot (c \hat{D} \nabla y_F \Psi)$ becomes $\nabla \cdot
(c \hat{D} \Psi \nabla y_F) + \nabla \cdot (c \hat{D} y_F \nabla \Psi)$
become
a ConvectionTerm, with velocity proportional to $\nabla y_F$, so use
yF.getFaceGrad() and
a DiffusionTerm, with diffusivity proportional to $y_F$. Here you'll
need to use the specific interpolation you want, but if you don't
specify, then FiPy will use getArithmeticFaceValue().