Daniel, Jonathan, and FiPyer's,

I'm a little confused about results I'm getting from getDivergence in a FiPy script.

I've created a triangular mesh with gmsh and extruded it with fipy. I'm solving a simple diffusion equation, with a diffusion coefficient that varies spatially, and running the model to a steady-state condition. In my current test, I'm just varying the diffusion coefficient assigned to a cell based on a uniform random distribution (from 0.5e-5 to 1.5e-5).

At the end to the simulation, I calculate the the diffusive fluxes across cell faces based on Fick's Law. To check for mass-balance errors, I calculate the divergence in the cells. As you know, the divergence under steady-state conditions should be zero (or a very tiny number). However, when I do this in FiPy the divergences are relatively large (about 1e-7). In the script I've separated the divergence calculated at the ends of the model with Type 1 boundaries (which shouldn't be zero due to the influence of the boundary conditions), from the 'internal' cells. The internal cells are only one or two orders of magnitude smaller than those impacted by boundary conditions.

I realize I don't need to use sweeps to solve this set of equations, but have left this in the script as I believe I'll need this when I add anisotropy. I don't think it is impacting the results.

Am I missing something here, or does the large divergence in this scenario indicate there are large mass-balance errors in each cell? Am I calculating the diffusive flux correctly? I've tried a variety of different methods of calculating this Flux term, but what is in the script now makes the most sense to me.

I've also run (and commented out in the script) a scenario with a regular mesh and this seems to yield better results (internal cells with a divergence of 1.e-18). The equation also works fine if Diff doesn't very spatially.

Hopefully I'll remember to attach the script, but here's a quick rundown of what I'm doing:

1) create mesh

mesh=GmshImporter2D('./semicircle.msh').extrude(layers=slices, 
extrudeFunc=addLayer)

2) define cellVariables: conc, por, Diff

3) vary Diff spatially:

Dist=random.uniform(.5,1.5,(mesh.getNumberOfCells()))
Diff.setValue(Dist*1.e-5)

4) define diffusion Equation:

Eq=TransientTerm(Por)==DiffusionTerm(Diff.getHarmonicFaceValue())

5) solve for conc. using sweeps, with const conc boundaries set at two ends

6) calculate diffusive flux

Flux=conc.getFaceGrad()*Diff.getHarmonicFaceValue()

7) calculate divergence and make list with divergences at 'internal' cells.

DivFlux=Flux.getDivergence()
X,Y,Z=mesh.getCellCenters()
InDivFx=[DivFlux()[i] for i in xrange(mesh.getNumberOfCells()) if (Z[i]>delZ) and (Z[i]<length-delZ)]

Eventually, I'd like to use a diffusion-type equation to calculate and assign fluxes to the advection-diffusion equation. If there are large mass-balance errors in the initial set of calculations, I'll get unreasonable results for the ADE equation...

Andy

----------------------
Andrew Reeve
Dept. of Earth Science
University of Maine
Orono, ME 04469

from fipy import *

###create regular mesh
## length=40. ##cm
## slices=40
## delZ=length/slices
## mesh=Grid3D(nx=8,ny=4,nz=slices,dx=.5,dy=.5,dz=delZ)

###create irregular mesh
def addLayer(verts):
    addArray = verts.copy()
    addArray[:] = 0
    addArray[2] = length/slices
    return verts + addArray

length=40. ##cm
slices=40
mesh=GmshImporter2D('./semicircle.msh').extrude(layers=slices, 
extrudeFunc=addLayer)
delZ=length/slices ##needed later in script


###calculate concentration
conc=CellVariable(name='concentration ',mesh=mesh,value=100.,hasOld=1.)
Por=CellVariable(name='effective porosity',mesh=mesh,rank=0,value=.2)
Diff=CellVariable(name='concentration ',mesh=mesh)
###generate random numbers
Dist=random.uniform(.5,1.5,(mesh.getNumberOfCells()))
###Set diffusion coeff
Diff.setValue(Dist*1.e-5)

Eq=TransientTerm(Por)==DiffusionTerm(Diff.getHarmonicFaceValue())

###Set constant conc. boundary conditions
X,Y,Z=mesh.getFaceCenters()
ZMax=max(Z)-0.005
bndry=(FixedValue(mesh.getFaces().where((Z<0.005)),120.),
       FixedValue(mesh.getFaces().where((Z>ZMax)),100.))
###Calculate steady state distribution
delTime=1.e12
timeSteps=10
for step in range(timeSteps):
    conc.updateOld()
    resid=1.
    print 'conc',step
    while resid>1.e-14:
        resid=Eq.sweep(
            var=conc,
            solver=LinearGMRESSolver(iterations=1000,tolerance=1.e-16),
            boundaryConditions=bndry,
            dt=delTime)
        print resid


###calculate diffusive flux
Flux=conc.getFaceGrad()*Diff.getHarmonicFaceValue()
DivFlux=Flux.getDivergence()
X,Y,Z=mesh.getCellCenters()
###divergence at internal cells
InDivFx=[DivFlux()[i] for i in xrange(mesh.getNumberOfCells()) if (Z[i]>delZ) 
and (Z[i]<length-delZ)]
OutDivFx=[DivFlux()[i] for i in xrange(mesh.getNumberOfCells()) if (Z[i]<delZ) 
or (Z[i]>length-delZ)]




$MeshFormat
2 0 8
$EndMeshFormat
$Nodes
22
1 0 0 0
2 2.54 0 0
3 5.08 0 0
4 4.828460924472671 1.102064697357506 0
5 4.123664096722479 1.985851965467763 0
6 3.10520317224885 2.476316896941875 0
7 1.974796827747875 2.476316896941128 0
8 0.9563359032731413 1.985851965464269 0
9 0.2515390755258018 1.102064697354334 0
10 1.015999999999299 0 0
11 2.031999999999298 0 0
12 3.048000000000643 0 0
13 4.064000000001987 0 0
14 4.155014625466476 0.8569626475459882 0
15 3.389915582005075 1.421237035085163 0
16 2.584548425562228 0.9504419447165823 0
17 1.662631170398718 1.24745043415448 0
18 2.642308901053341 1.826504769976305 0
19 1.978148650661269 1.796132000536478 0
20 3.543715653916555 0.5986322973810793 0
21 1.098957930737896 0.9683454136911297 0
22 1.703842637684158 0.5902104244185791 0
$EndNodes
$Elements
43
1 15 2 0 1 1
2 15 2 0 2 2
3 15 2 0 3 3
4 1 3 0 1 0 3 4
5 1 3 0 1 0 4 5
6 1 3 0 1 0 5 6
7 1 3 0 1 0 6 7
8 1 3 0 1 0 7 8
9 1 3 0 1 0 8 9
10 1 3 0 1 0 9 1
11 1 3 0 2 0 1 10
12 1 3 0 2 0 10 11
13 1 3 0 2 0 11 12
14 1 3 0 2 0 12 13
15 1 3 0 2 0 13 3
16 2 3 0 4 0 6 7 18
17 2 3 0 4 0 7 8 19
18 2 3 0 4 0 19 8 17
19 2 3 0 4 0 13 14 20
20 2 3 0 4 0 20 14 15
21 2 3 0 4 0 18 16 15
22 2 3 0 4 0 19 18 7
23 2 3 0 4 0 16 18 19
24 2 3 0 4 0 19 17 16
25 2 3 0 4 0 12 13 20
26 2 3 0 4 0 15 16 20
27 2 3 0 4 0 8 9 21
28 2 3 0 4 0 21 17 8
29 2 3 0 4 0 12 20 16
30 2 3 0 4 0 22 10 11
31 2 3 0 4 0 21 10 22
32 2 3 0 4 0 17 21 22
33 2 3 0 4 0 16 17 22
34 2 3 0 4 0 12 16 11
35 2 3 0 4 0 11 16 22
36 2 3 0 4 0 5 15 14
37 2 3 0 4 0 14 4 5
38 2 3 0 4 0 10 21 9
39 2 3 0 4 0 9 1 10
40 2 3 0 4 0 6 18 15
41 2 3 0 4 0 15 5 6
42 2 3 0 4 0 14 13 3
43 2 3 0 4 0 3 4 14
$EndElements

Reply via email to