Вы находитесь на странице: 1из 47

FiPy

A Finite Volume PDE Solver Using Python


D. Wheeler, J. E. Guyer & J. A. Warren
www.ctcms.nist.gov/fipy/
Metallurgy Division &
Center for Theoretical and Computational Materials Science
Materials Science and Engineering Laboratory

ay,
ines and
ation of all
freezes to
were to look
strong
m, but is
u were able to
werful
hat looks like
to each other.
ndrites. The
t" of dendrites in a metal would look like

Motivation

PDEs are ubiquitous in Materials Science problems


Solve PDEs in weird and unique ways
Easy to pose problems
Easy to customize

word "dendron", which means a tree.


often describe the form and structure of
ure to left), with a main branch or trunk,
h grow smaller side branches, and so
branches grow into each other and there
The figure to
a metal. In
ny thousands,
s most
dendrites are
t and welded

Dont care about numerical methods

is, how
d or stretch it
under what
out or rusts.
conductor of electricity. The dendrites
other, and what's the best way to do the
cation profoundly influences a material's

What is FiPy?
FiPy is a computer program written in Python to solve partial differential
equations (PDEs) using the Finite Volume method
Python is a powerful object oriented scripting language with tools for
numerics
The Finite Volume method is a way to solve a set of PDEs, similar to the
Finite Element or Finite Difference methods

Why a common code?


Many interface motion codes for solving Materials Science problems at
NIST.
Phase Field for solidification and melting
Phase Field for grain boundary motion
Phase Field for elasticity
Phase Field for electrochemistry
Level Set code for electrochemistry
etc
Need for code homogeneity
Institutional memory is lost with constant rewriting of codes
Need for preservation and reuse
Leverage different skill sets

Design
Implement interface tracking
Phase Field, Level Set,Volume of Fluid, particle tracking
Object-oriented structure
Encapsulation and Inheritance
Adapt, extend, reuse
Test-based development
Open Source
CVS and compressed source archives
Bug tracker and mailing lists
High-level scripting language
Python programming language

Design: test-based development


485 major tests, comprising thousands of low-level tests
Tests are documentation (and vice versa)
298

Module fipy.variables.variable

ge (self, other )
Test if a Variable is greater than or equal to another quantity
>>> a = Variable(value = 3)
>>> b = (a >= 4)
>>> b
(Variable(value = 3) >= 4)
>>> b()
0
>>> a.setValue(4)
>>> b()
1
>>> a.setValue(5)
>>> b()
1

getitem (self, index )


Evaluate the variable and return the specified element
>>> a = Variable(value = ((3.,4.),(5.,6.)), unit = "m") + "4 m"

Design: test-based development


485 major tests, comprising thousands of low-level tests
Tests are documentation (and vice versa)
Running __main__.Variable.__gt__.__doc__
Trying: a = Variable(value = 3)
Expecting: nothing
ok
Trying: b = (a > 4)
Expecting: nothing
ok
Trying: b
Expecting: (Variable(value = 3) > 4)
ok
Trying: b()
Expecting: 0
ok
Trying: a.setValue(5)
Expecting: nothing
ok
Trying: b()
Expecting: 1
ok
0 of 6 examples failed in __main__.Variable.__gt__.__doc__

! "# $

! "# $

"#

Finite Volume Method


transient

Solve a general PDE

diffusion

source

1 1
m
T) =
forarctan
on2 (,
a given
domain
a field(
2T )
2


a11 a12
()
b1
()
[ (i )]n .. (#u) S1 = 0
!"#$
b2
.
a
a

21
22
2
! t
"# $ ! "# $
!
"#
$
!
"#
$


th
source

transient
convection
diffusion
.. = ..
n order diffusion
.
.
.
.
.
.

.
.
.
.

.
%
%
%
%
% bn
..
n
()
dV (#n ) dS n (#n ).dS ann (#n #u) dS
S dV = 0
!V

t
"#

transient

!S

"#

diffusion

S
!
() "#

!S

"#

! V "#

source
convection
+ ($u) =
() + S

'
()
*
'
()
*
t
'()*
' () *
nth order diffusion

transient
&

convection

diffusion

source

&
V (V )old &
+ [(#n #u)A]face
+V
+[A#n ]face + [A#n { }]face
()
t
face
face($
face
dV
+
n

$
u
)
dS
=
($
n )"#dS + $ S!
!
"#
$ !
"#
$
!
"#
$
!
domain
t
transient

' V diffusion
()

transient

'S

()

nth order diffusion

convection

'S

so
()convection
* ' V ()

sou

diffusion

,
V (V )old ,
+
[($n $u)A]face =
[A$n ]face +
t
face
face
'
()
* '
()
* '
()
*

m2 (, T ) =

1 1

arctan (2 T )
2

Finite Volume Method

Solve

()
n
PDE
()

[ (domain
a (#
u)
i )] for
S = 0
a general
on
a
given
field
t
! "# $ ! "# $ ! "#
$
! "# $ !"#$

transient
diffusion
adiffusion
a12 convection source
nth order
Integrate
PDE over
arbitrary
control
11 volumes
1
b1

.
.. %
2 % b2
%
%
% a21 a22


()
n (#n . . ) dS. . (#

dS.. =S
dV (#n ) dS
n

#u)
=0
..
.
dV
.

. V .
t
. $ . ! S ."#
! V "#
$ !S
"#
$ ! S "#
$ ! "# $
sourcebn
transient
convection n
diffusion
nth order diffusion . .
. ann

()
&
&
V (V )old &
+
($
= ()
+ face
S V S =

[A#n ]face
[A#
n
{
u)
}]face
[(#n #u)A]
t
t
'face
() * ' () * ' face() * '()*
face
convection
!
"#
$ !
"#
$ transient
!
"#
$ !diffusion"# source
$ !"#$
transient

diffusion

'V

nth order diffusion

source

convection

()
dV v+contro ($n $u) dS =
($n ) dS +
S
o
l
t
lu
()
* 'mSe
()
* 'S
()
* ' V ()

transient

convection

sou

diffusion

,
V (V )old ,
+
[($n $u)A]face =
[A$n ]face +
t
face
face
'
()
* '
()
* '
()
*

() [ (i )]n (#u) S = 0
! t
"# $ ! "# $ !
"#
$
! "# $ !"#$

Finite Volume Method

transient

nth order diffusion

diffusion

convection

source

Solve a general
PDE on a%given domain for a% field
%
%
()

dV

(#
n

)
dS

(#
n

)
dS

(#
n

#
u
)
dS

S dV= 0
n
a
a
Integrate
PDE
over
arbitrary
control
volumes
11
12
t
S
V

! V "#
$ !S
"#
$ !S
"#
$
!
"#
$
!
"# $ b1
1

.
. .convection source
transient

b2
nth order
diffusion
Evaluate PDEdiffusion
over polyhedral
control
volumes
a
a
21
22
2

.. = ..
.
.
.
.
.
.

. .
.
.
.
old

&
&
&
V (V )

[A#n ]face
[A#n { .}]. face
[(#n #un)A]face bV
n S = 0
.
t
ann
face
face
face
%

"#

transient

"#

diffusion

"#

'V

"#

!"#$

source
convection
nth order diffusion
()
+ ($u) = () + S
' t
() * ' () * ' () * '()*

transient

convection

diffusion

source

()
dV + ($n $u) dS =
($n ) dS +
S
fat
ce
vertex
()
* ' S ()
* 'S
()
* ' V ()

transient
cell

convection

sou

diffusion

,
V (V )old ,
+
[($n $u)A]face =
[A$n ]face +
t
face
face
'
()
* '
()
* '
()
*

Finite Volume Method

Solve a general PDE on a given domain for a field


a11 volumes
a12
Integrate PDE over arbitrary control
1
b1

.
..
2 b2
Evaluate PDE over polyhedral
control
volumes
a
a
21
22

.. = ..
.
.
.
.
.
.

. .
Obtain a large coupled set of linear
equations
.
. in .

.
n bn
.. a
a11 a12
nn

1
b1

a11 a12
..

2 b2
a
a
21
22

b
1
1
()

.
.

..S
.. = +
+. 2.
($u). .
=

()
a21 a22 .

b
.
2
'
* '()*

'
()
*
()
.
.
.
t
.
.
* . = .
' ()

.
.
.
source
diffusion
..
. .transient
. . convection

.... ..
n
bn
+

.
ann +
+
+
.

b
n
n
.
() . ann
dV
+ ($n $u) dS =
($n ) dS +
S
()
t
+
u) *= 'S()
+ S* ' V ()
V
S ($
'
()
*
'
()
()
' () * ' () * '()*
()
t
'
()
*
+

($
u
)
=

() + Sdiffusion
sou
transient
convection
diffusionsource

convection
* ' () * '()*
transient
' t
() * ' ()
source
convection +
diffusion
+
+
+
transient()
old
,
V

(V
)
+
+
+n [($
+
dV + + ,
($
$un)
dS
=
($
n
)
dS
+
S+

$
u
)A]
=
[A$
n

]
face
face
()
t
S
V
t $u)*dS '=S ()
' V ($n
()
*
'
()
*
'
()
dV +
($
n

)
dS
+
S
dV

face
face
t
()
*
V
S ()
'
()
*' 'transient
()
** 'convection
'S
()
** diffusion
' V' () *() sourc

Diffusion Example

() = 0
t
!"#$
! "# $

# create a mesh

transient

# create a field variable

(#u) + () = 0
! "# $ ! "# $

# create the equation terms

diffusion

convection

# create the equation

diffusion

|x=0 = 0

|x=L = 1

# create a viewer
# solve

= 2 2 + (1 )m2 (, T )
t
T

2
= DT T +
t
t

! "# $

transient

! "# $
diffusion

m2 (, T ) =

"#

source

1 1

arctan (2 T )
2

()
= () + [ (i )]n + (#u) + S
! t
"# $
! "# $ !
"#
$
! "# $ !"#$

Diffusion Example

() = 0
t
!"#$
! "# $

# create a mesh

transient

diffusion

L = nx * dx
(#u) + () = 0
"# $ ! "# $
from fipy.meshes.grid2D import! Grid2D
convection
diffusion
mesh = Grid2D(nx = nx, dx = dx)

|x=0 = 0

# create a field variable

|x=L = 1

# create the equation


# create a viewer
# solve

= 2 2 + (1 )m2 (, T )
t
T

2
= DT T +
t
t

! "# $

transient

! "# $
diffusion

m2 (, T ) =

"#

source

1 1

arctan (2 T )
2

()
= () + [ (i )]n + (#u) + S
! t
"# $
! "# $ !
"#
$
! "# $ !"#$

Diffusion Example

() = 0
t
!"#$
! "# $

# create a mesh

transient

diffusion

(#u) + () = 0
! "# $ ! "# $

# create a field variable

from fipy.variables.cellVariableconvection
import CellVariable
diffusion
var = CellVariable(mesh = mesh, value = 0)

|x=0 = 0

|x=L = 1

def centerCells(cell):
return abs(cell.getCenter()[0] - L/2.) < L/10.

t
T

2
= DT T +
t
t

var.setValue(value = 1., cells


= centerCells))
= mesh.getCells(filter
= 2 2 + (1 )m
2 (, T )
# create the equation
# create a viewer
# solve

! "# $

transient

! "# $
diffusion

m2 (, T ) =

"#

source

1 1

arctan (2 T )
2

()
= () + [ (i )]n + (#u) + S
! t
"# $
! "# $ !
"#
$
! "# $ !"#$

Diffusion Example

() = 0
t
!"#$
! "# $

# create a mesh

transient

diffusion

(#u) + () = 0
! "# $ ! "# $

# create a field variable

# set the initial conditions


convection
diffusion
def centerCells(cell):
return abs(cell.getCenter()[0]
- L/2.)
|x=0
= 0< L/10.
|x=L = 1
var.setValue(value = 1., cells = mesh.getCells(filter = centerCells))
# create the equation
# create a viewer
# solve

= 2 2 + (1 )m2 (, T )
t
T

2
= DT T +
t
t

! "# $

transient

! "# $
diffusion

m2 (, T ) =

"#

source

1 1

arctan (2 T )
2

()
= () + [ (i )]n + (#u) + S
! t
"# $
! "# $ !
"#
$
! "# $ !"#$

Diffusion Example

() = 0
t
!"#$
! "# $

# create a mesh

transient

# create a field variable

(#u) + () = 0
! "# $ ! "# $

# create the equation

diffusion

convection

diffusion

from fipy.terms.transientTerm import TransientTerm


|x=0 = 0
|x=L = 1
from fipy.terms.implicitDiffusionTerm import ImplicitDiffusionTerm
## equivalent forms

## eq = (TransientTerm() ==
= 1))
ImplicitDiffusionTerm(coeff
= 2 2 + (1 )m (,
T)

t
## eq = TransientTerm() - ImplicitDiffusionTerm(coeff = 1)
T

2
= DT T +
eq = (TransientTerm() - ImplicitDiffusionTerm(coeff
= 1) == 0)
t
t
# create a viewer
# solve

! "# $

transient

! "# $
diffusion

m2 (, T ) =

"#

source

1 1

arctan (2 T )
2

()
= () + [ (i )]n + (#u) + S
! t
"# $
! "# $ !
"#
$
! "# $ !"#$

Diffusion Example

() = 0
t
!"#$
! "# $

# create a mesh

transient

# create a field variable

(#u) + () = 0
! "# $ ! "# $

# create the equation terms

diffusion

convection

# create the equation

diffusion

|x=0 = 0

|x=L = 1

# create a viewer
from fipy.viewers.gist1DViewer import Gist1DViewer

viewer = Gist1DViewer(vars
('e',
'e',)m
0, 1))
= (var,),
= 2limits
2 +=(1
2 (, T )
t
viewer.plot()
# solve

2
= DT T +
t
t
! "# $

transient

! "# $
diffusion

m2 (, T ) =

"#

source

1 1

arctan (2 T )
2

()
= () + [ (i )]n + (#u) + S
! t
"# $
! "# $ !
"#
$
! "# $ !"#$

Diffusion Example

() = 0
t
!"#$
! "# $

# create a mesh

transient

# create a field variable

(#u) + () = 0
! "# $ ! "# $

# create the equation terms

diffusion

convection

# create the equation

diffusion

|x=0 = 0

|x=L = 1

# create a viewer
# solve
for i in range(steps):
var.updateOld()
eq.solve()
viewer.plot()

= 2 2 + (1 )m2 (, T )
t
T

2
= DT T +
t
t

! "# $

transient

! "# $
diffusion

m2 (, T ) =

"#

source

1 1

arctan (2 T )
2

()
= () + [ (i )]n + (#u) + S
! t
"# $
! "# $ !
"#
$
! "# $ !"#$


= ()
= ()
t
t
!"#$
!! "#
!"#$
"# $$

Convection Example
transient
transient

# create a mesh

diffusion
diffusion

(#
u
)
+

()
=
00

(#
u
)
+

()
=
!! "#
"# $$ !! "#
"# $$

convection
convection

diffusion
diffusion

|x=0 = 0
|x=L = 1
diffusion
source
# $! "
# $! " #
$!
"
# create the boundary conditions

2 2

+ (1 source
)m2 (, T )

transient
diffusion
t
# create the equation
# $! "
# $! " #
$!
"
T
L

# create a viewer
=D
t =
2T2 T++(1

)m2 (, T )
c
t
p
t
# solve
T
L
2
= DT T
1+
1
t
m2 (, T ) = cp t
arctan (2 T )
2

1 1
m2 (, T ) =
arctan (2 T )
2

# create a field variable

transient


= ()
= ()
t
t
!"#$
!! "#
!"#$
"# $$

Convection Example
transient
transient

# create a mesh

diffusion
diffusion

(#
u
)
+

()
=
00

(#
u
)
+

()
=
!! "#
"# $$ !! "#
"# $$

convection
convection

diffusion
diffusion

|x=0 = 0
|x=L = 1
diffusion
source
# $! "
# $! " #
$!
"
# create the boundary conditions

2 2

+ (1 source
)m2 (, T )

transient
diffusion
t
from fipy.boundaryConditions.fixedValue
FixedValue
# $! "
# $! " import
#
$!
"
T
L

bcs = (
= D2 22 T +
T + (1 )m2 (, T )

t = 0),
FixedValue(mesh.getFacesLeft(),
cp t
t
FixedValue(mesh.getFacesRight(), 1),
T
L
2
)
= DT T
1+
1
t
m2 (, T ) = cp t
arctan (2 T )
# create the equation
2

1 1
# create a viewer
m2 (, T ) =
arctan (2 T )
2

# create a field variable

transient

# solve


= ()
= ()
t
t
!"#$
!! "#
!"#$
"# $$

Convection Example
transient
transient

# create a mesh

diffusion
diffusion

(#
u
)
+

()
=
00

(#
u
)
+

()
=
!! "#
"# $$ !! "#
"# $$

convection
convection

diffusion
diffusion

|x=0 = 0
|x=L = 1
diffusion
source
# $! "
# $! " #
$!
"
# create the boundary conditions

2 2

+ (1 source
)m2 (, T )

transient
diffusion
t
# create the equation
# $! "
# $! " #
$!
"
T
L

22 T + ImplicitDiffusionTerm
from fipy.terms.implicitDiffusionTerm
=D
t =
2Timport
+ (1

)m2 (, T )
c
t
p
t
diffusionTerm = ImplicitDiffusionTerm(coeff
= 1)
T
L
2
= DT T
1 + import

1
from fipy.terms.exponentialConvectionTerm
ExponentialConvectionTerm
t
m2 (, T ) = cp t
arctan
(2 T )
convectionTerm = ExponentialConvectionTerm(coeff
= (10,0),
2

1 1diffusionTerm = diffusionTerm)
m2 (, T ) =
arctan (2 T )
2

eq = (diffusionTerm + convectionTerm == 0)
# create a field variable

transient

# create a viewer
# solve


= ()
= ()
t
t
!"#$
!! "#
!"#$
"# $$

Convection Example
transient
transient

# create a mesh

diffusion
diffusion

(#
u
)
+

()
=
00

(#
u
)
+

()
=
!! "#
"# $$ !! "#
"# $$

convection
convection

diffusion
diffusion

|x=0 = 0
|x=L = 1
diffusion
source
# $! " 1.0
# $! " #
$!
"
# create the boundary conditions

2 2

+ (1 source
)m2 (, T )

transient
diffusion
t
# create the equation
# $! "
# $! " #
$!
"
T
L

0.82
# create a viewer
=D
t =
T2 T++(1

)m2 (, T )
c
t
p
t
# solve
T
L
2
= 0.6
DT T
+ 1
1LinearCGSSolver
from fipy.solvers.linearCGSSolver
import
t
m2 (, T ) = cp t
arctan (2 T )
2

eq.solve(var = var,
1 1
m2 (, T ) 0.4
= = 1.e-15,
arctan
(2 T=)2000),
solver = LinearCGSSolver(tolerance
steps
2

# create a field variable

transient

boundaryConditions = boundaryConditions)

viewer.plot()

0.2

0.0
0

Phase Field Dendrite


# $!"Example
$! "+ (1
# )m
$! (, T )"
= #
transient

after J. A. Warren, R. Kobayashi, A. E. Lobkovsky,


and W. C. Carter, Acta Materialia 51(20), (2003) 60356058

# create a mesh

diffusion
2 2

source

t
2 22 2
=
+(1
TT
) )= 0
(1)m
)m
2 (,
2 (,
T

t
t
= DT 2 T +
T
t
T
L
t
2 2
=DD

=0

T
+
T T
t
t
t
c
! "# $ ! "# $ ! p t "#
$

source
!transient
"# $ ! diffusion
"# $ !
"#
$
1 source
transient
diffusion 1
m
(,
T
)
=

2
12 1 arctan (2 T )
# create the phase equation
m2 (, T ) =
arctan (2 T )
1

2
1
# create the temperature equation
m2 (, T ) =
arctan (2 T )
2

()
# create a viewer
= () + [ (i )]n + (#u) +
()
# solve
! t
"# $ ! ()
"#
$ [! (i"#
"#
)]n $ ! (#
u) $ S
t
!transient
"# $ ! diffusion
"# $ !nth order
"# diffusion
$
! convection
"# $ !"s

# create the field variables

transient

diffusion

nth order diffusion

convection

so

%
%
%
%
()
%
dV = % (#n ) dS + % n (#n ) dS + % (#n #u
()
t
) dS
) dS
#u
! V "# dV
$ ! S (#n"#
$ ! S n (#n "#
$ ! S (#n "#
t
! Vtransient
"#
$ ! S diffusion
"#
$ ! Snth order"#diffusion $ ! Sconvec
"#
transient

diffusion

nth order diffusion

conve

&
&
V (V )old
=
[A#n ]face + &[A#n { }]face +
V t
(V )old &
face [A#n ]face face [A#n { }]face
!
"#
$ !
"#
$ !
"#
$
t
face diffusion
face
! transient
"#
$ !
"#
$ ! nth order"#diffusion $
th

Phase Field Dendrite


# $!"Example
$! "+ (1
# )m
$! (, T )"
= #
transient

after J. A. Warren, R. Kobayashi, A. E. Lobkovsky,


and W. C. Carter, Acta Materialia 51(20), (2003) 60356058

# create a mesh

diffusion
2 2

source

t
2 22 2
=
+(1
TT
) )= 0
(1)m
)m
2 (,
2 (,
T

t
t
= DT 2 T +
T
t
T
L
t
2 2
=DD

=0

T
+
T T
t
t
t
c
! "# $ ! "# $ ! p t "#
$

source
!transient
"# $ ! diffusion
"# $ !
"#
$
1 source
transient
diffusion 1
m
(,
T
)
=

2
12 1 arctan (2 T )
# create the phase equation
m2 (, T ) =
arctan (2 T )
1

2
1
m2 = phase - 0.5 - kappa1 * arctan(kappa2 * m
temperatue)

arctan (2 T )
2 (, T ) =
2

()
phaseEq = (TransientTerm(coeff = tau) == \
= () + [ (i )]n + (#u) +
()
ImplicitDiffusionTerm(coeff
alpha**2)
! t
"# =$
"# +
$\ [! (i"#
"#
! ()
)]n $ ! (#
u) $ S
t
!transient
"# $ ! diffusion
"# $ !nth order
"# diffusion
$
! convection
"# $ !"s

# create the field variables

ImplicitSourceTerm(coeff = m2 * ((m2 < 0) - phase))


+\
th
transient

% * phase)
(m2 > 0) * m2

diffusion

order diffusion

convection

so

%
%
%
()
%
dV = % (#n ) dS + % n (#n ) dS + % (#n #u
()
t
) dS
) dS
#u
! V "# dV
$ ! S (#n"#
$ ! S n (#n "#
$ ! S (#n "#
t
Vtransient
# create the temperature!equation
"#
$ ! S diffusion
"#
$ ! Snth order"#diffusion $ ! Sconvec
"#

# create an iterator
# create a viewer
# solve

transient

diffusion

nth order diffusion

conve

&
&
V (V )old
=
[A#n ]face + &[A#n { }]face +
V t
(V )old &
face [A#n ]face face [A#n { }]face
!
"#
$ !
"#
$ !
"#
$
t
face diffusion
face
! transient
"#
$ !
"#
$ ! nth order"#diffusion $
th

Phase Field Dendrite


# $!"Example
$! "+ (1
# )m
$! (, T )"
= #
transient

after J. A. Warren, R. Kobayashi, A. E. Lobkovsky,


and W. C. Carter, Acta Materialia 51(20), (2003) 60356058

# create a mesh

diffusion
2 2

source

t
2 22 2
=
+(1
TT
) )= 0
(1)m
)m
2 (,
2 (,
T

t
t
= DT 2 T +
T
t
T
L
t
2 2
=DD

=0

T
+
T T
t
t
t
c
! "# $ ! "# $ ! p t "#
$

source
!transient
"# $ ! diffusion
"# $ !
"#
$
1 source
transient
diffusion 1
m
(,
T
)
=

2
12 1 arctan (2 T )
# create the phase equation
m2 (, T ) =
arctan (2 T )
1

2
1
# create the temperature equation
m2 (, T ) =
arctan (2 T )
2

temperatureEq = (TransientTerm() == \
()
n
=

()
+
[

(
)]
+ (#u) +
i
ImplicitDiffusionTerm(coeff
= tempDiffCoeff) + \ n
()
t
! "# $ ! ()
"#
$ [! (i"#
"#
)] $ ! (#
u) $ S
t
diffusion
(phase - phase.getOld())
!transient
"# $ /!timeStepDuration)
"# $ !nth order
"# diffusion
$
! convection
"# $ !"s

# create the field variables

# create a viewer
# solve

transient

diffusion

nth order diffusion

convection

so

%
%
%
%
()
%
dV = % (#n ) dS + % n (#n ) dS + % (#n #u
()
t
) dS
) dS
#u
! V "# dV
$ ! S (#n"#
$ ! S n (#n "#
$ ! S (#n "#
t
! Vtransient
"#
$ ! S diffusion
"#
$ ! Snth order"#diffusion $ ! Sconvec
"#
transient

diffusion

nth order diffusion

conve

&
&
V (V )old
=
[A#n ]face + &[A#n { }]face +
V t
(V )old &
face [A#n ]face face [A#n { }]face
!
"#
$ !
"#
$ !
"#
$
t
face diffusion
face
! transient
"#
$ !
"#
$ ! nth order"#diffusion $
th

Phase Field Dendrite


# $!"Example
$! "+ (1
# )m
$! (, T )"
= #
transient

after J. A. Warren, R. Kobayashi, A. E. Lobkovsky,


and W. C. Carter, Acta Materialia 51(20), (2003) 60356058

# create a mesh

diffusion
2 2

source

t
2 22 2
=
+(1
TT
) )= 0
(1)m
)m
2 (,
2 (,
T

t
t
= DT 2 T +
T
t
T
L
t
2 2
=DD

=0

T
+
T T
t
t
t
c
! "# $ ! "# $ ! p t "#
$

source
!transient
"# $ ! diffusion
"# $ !
"#
$
1 source
transient
diffusion 1
m
(,
T
)
=

2
12 1 arctan (2 T )
# create the phase equation
m2 (, T ) =
arctan (2 T )
1

2
1
# create the temperature equation
m2 (, T ) =
arctan (2 T )
2

()
# create an iterator
= () + [ (i )]n + (#u) +
()
# create a viewer
! t
"# $ ! ()
"#
$ [! (i"#
"#
)]n $ ! (#
u) $ S
t
s
transient
convection
diffusion
nth order
diffusion
!
"#
$
!
"#
$
!
"#
$
!
"#
$
!"
# solve

# create the field variables

transient

diffusion

nth order diffusion

convection

so

%
%
%
for i for range(steps): %
()
phase.updateOld() %
dV = % (#n ) dS + % n (#n ) dS + % (#n #u
()
t
temperature.updateOld()
) dS
) dS
#u
! V "# dV
$ ! S (#n"#
$ ! S n (#n "#
$ ! S (#n "#
t
phaseEq.solve(phase, dt
= timeStepDuration)
! Vtransient
"#
$ ! S diffusion
"#
$ ! Snth order"#diffusion $ ! Sconvec
"#
temperatureEq.solve(temperature,
dt
=
timeStepDuration)
transient
conve
diffusion
nth order diffusion
if i%frameRate == 0:
phaseViewer.plot()V (V )old
&
&
temperatureViewer.plot()
n ]face + &[A#n { }]face +
old = &[A#

V t
(V )
face [A#n ]face face [A#n { }]face
!
"#
$ !
"#
$ !
"#
$
t
face diffusion
face
! transient
"#
$ !
"#
$ ! nth order"#diffusion $
th

Cahn-Hilliard Example

!
"
!
"

f
D f #2222 = 0
t D # = 0
t

a22 2
f = a 2(1 )22
f = 2 (1 )
2

# create a mesh
# create the field variable

$n = 0
= 0
$n 3 3 = 0
=0

# create the equation


# create the boundary conditions
# create a viewer
# solve

on all boundaries
on all boundaries
on all boundaries
on all boundaries

D [1 6 (1 )] + D#22
(1 )] + D#
t # D [1 6
#$%&
$%
& #
$%
t
#$%&
#
$%
&
#
$%
nd
th
transient
transient

2 nd order diffusion
2
order diffusion

4 th order diff
4 order diff

!
"
$n 3 = 0 on all boundaries

f
D
#2 2 = 0
t

Da2 [1 6 (1 )] +2 D#2 2 = 0
a
t
#$%&
#
$%
f =& #2 (1 $%
)2 &
2 4th order diffusion
transient
2nd order diffusion

Cahn-Hilliard Example
# create a mesh
# create the field variable

$n = 0 on all boundaries

# create the equation

$n 3 = 0 on all boundaries

# create the boundary conditions


# create a viewer
# solve

D [1 6 (1 )] + D#2
t
#$%&
#
$%
& #
$%

transient

2nd order diffusion

4th order diff

!
"
$n 3 = 0 on all boundaries

f
D
#2 2 = 0
t

Da2 [1 6 (1 )] +2 D#2 2 = 0
a
t
#$%&
#
$%
f =& #2 (1 $%
)2 &
2 4th order diffusion
transient
2nd order diffusion

Cahn-Hilliard Example
# create a mesh
# create the field variable
# create the equation

$n = 0 on all boundaries

$n 3 = 0 on all boundaries

faceVar = var.getArithmeticFaceValue()
doubleWellDerivative = a**2 * ( 1 - 6 * faceVar
* (1 - faceVar))

D [1 6 (1 )] + D#2
t
#$%&
#
$%
& #
$%
from fipy.terms.nthOrderDiffusionTerm import NthOrderDiffusionTerm
nd

th

4 order diff
from fipy.terms.transientTerm importtransient
TransientTerm2 order diffusion
eq = (TransientTerm() == \
NthOrderDiffusionTerm(coeffs = (diffusionCoeff * doubleWellDerivative,)) -\
NthOrderDiffusionTerm(coeffs = (diffusionCoeff, epsilon**2)))

# create the boundary conditions


# create a viewer
# solve

!
"
$n 3 = 0 on all boundaries

f
D
#2 2 = 0
t

Da2 [1 6 (1 )] +2 D#2 2 = 0
a
t
#$%&
#
$%
f =& #2 (1 $%
)2 &
2 4th order diffusion
transient
2nd order diffusion

Cahn-Hilliard Example
# create a mesh
# create the field variable

$n = 0 on all boundaries

# create the equation

$n 3 = 0 on all boundaries

# create the boundary conditions

from fipy.boundaryConditions.nthOrderBoundaryCondition
D [1 6\ (1 )] + D#2
t
import NthOrderBoundaryCondition #$%&
#
$%
& #
$%
transient

2nd order diffusion

BCs = (NthOrderBoundaryCondition(mesh.getExteriorFaces(), 0, 3),)

4th order diff

# create a viewer
# solve

!
"
$n 3 = 0 on all boundaries

f
D
#2 2 = 0
t

Da2 [1 6 (1 )] +2 D#2 2 = 0
a
t
#$%&
#
$%
f =& #2 (1 $%
)2 &
2 4th order diffusion
transient
2nd order diffusion

Cahn-Hilliard Example
# create a mesh
# create the field variable

$n = 0 on all boundaries

# create the equation

$n 3 = 0 on all boundaries

# create the boundary conditions


# create a viewer
# solve

D [1 6 (1 )] + D#2
t
#$%&
#
$%
& #
$%

transient

2nd order diffusion

dexp = 0.01
for step in range(steps):
dt = Numeric.exp(dexp)
dt = min(100, dt)
dexp += 0.01
var.updateOld()
eq.solve(var, boundaryConditions = BCs, solver = solver, dt = dt)
viewer.plot()

4th order diff

CEAC Example

specimens ( = 0.44 and 0.88) rather


than the predicted seams. Such depletion effects have been fully modeled
elsewhere.15
Via
Filling
Experiments
and
SimulationsDeposition in vias, unlike
trenches, is a three-dimensional problem by virtue of the nonzero curvature
of the cylindrical sidewalls. Cross sections detailing the filling of cylindrical
vias with a 4.5 sidewall slope are
shown in 10 s increments in Fig. 7.16 In
this experiment the catalyst is adsorbed
simultaneously with copper plating in
accord with conventional practice.
Wafer fragments were immersed in the
SPS-PEG-Cl electrolyte, containing 6.4
mol/L SPS, with a -0.25 V (Cu/Cu2+)
growth potential already applied.
Growth is essentially conformal for the
first 60 s followed by the onset of bottom-up superfilling at 70 s. The filling
process is summarized by tracking the
height of the deposit along the centerline of the via, as a function of deposition time. Favorable agreement with
the CEAC simulation is evident and the
corresponding
simulated growth conLEVELER
tours
are
given
in
the inset.16
ACCELERATOR

Curvature

Copper electodeposition in submicron features


electrolyte additives influence deposition rate
CEAC - Curvature Enhanced Accelerator Coverage.
Momentum plating

e of images of direct copper deposition on trenches coated

are considered only across the hydrodynamic boundary in these simulations.


However, for the higher deposition rates
associated with higher catalyst coverBottom Up fill
ages, significant depletion of the Cu2+
ion occurs within the trench, resulting
in faster deposition toward the top of the
feature. This leads to an earlier impingement at this location and void formation as observed in two experimental

2004

1/2
coverage
K Accelerator
= k exp
a

da
= |%v |a + ka (a0 a )
dt
Interface speed

fixed point moving


s =with
s0 the
at t = 0
interface
Experimental sequence

a = a0 at t = 0

s0

K0
=
1 + K0

INHIBITOR

Seedless Superfill

45 degree
Current
metallization
side wall
tilt

technology
employs three layers, a barrier metal,

51

K0 = k exp a0

$1/2 "

"

!
= Jv +i (k0 +!k3 3 )ci (1
" ) ci
! + b!) m"exp
t
cm
F
vi =
(b
"
1
i

c
v=
(b0 + b1 ) exp
cm 0 F
c

F
m nF
m
(b
! exp "
= b1 )
(b0 RT
+ b1exp
)
nF v =
c 0v +
c
RT RT
m ||
nF m nFcim
F
m= vcext
v=
(b0 +

b1 ) texp
= vcext
||
nF
RT
m
3 i
t
t = Jv + (k0 + k3 )c (1
i0 || = 0
+ vext
+mk=
v cext
= ||
Jvc
+
(1 )
t t t
= Dm cm

t
c

mi = + D
vcext
=0
i||
mc
m
Jv kt
cJv
(1

)
=
0

k
c
(1

=0
= D)
t
c
t
t c
t

D
c
i
cm Jv
c
t m

k
c
0 ) = 0

(1

D
c
=

D
m
m
m cm = 0
v
tt
t
D
n

c
=
on = 0
c
m
m

v
c Dm n
c

c
D
m
m =
c
= 00= 0(1 ) o
m
tm D
=
0on
=
c
D
D
c
c
n
= kc

t
t
Dn
c = k c (1 ) on = 0
c
D c = 0
t
|| = 1
v
2
Dm n
cm =
on = 0
2

v v
D n
Dc
k
)on
on
n
=
c
= (1
=

mD
m c
c
= on
0= 0= 0
mn
m

D D
n
n
)
= 0= 0
= k
c (1
c
c
= k
c (1
)on on

CEAC Example
after D. Josell, D. Wheeler, W. H. Huber, and T. P. Moffat,
Physical Review Letters, 87(1), (2001) 016102

# create a mesh
# create the field variables
# create the governing equations
# create the boundary conditions
# solve

2
2 2

!
= Jv +i (k0 +!k3 3 )ci (1
" ) ci
! + b!) m"exp
t
cm
F
vi =
(b
"
1
i

c
v=
(b0 + b1 ) exp
cm 0 F
c

F
m nF
m
(b
! exp "
= b1 )
(b0 RT
+ b1exp
)
nF v =
c 0v +
c
RT RT
m ||
nF m nFcim
F
m= vcext
after D. Josell, D. Wheeler, W. H. Huber, and T. P. Moffat,
v=
(b0 +

b1 ) texp
=
v
||
nF
c
RT
ext
Physical Review Letters, 87(1), (2001) 016102
m
3 i
t
t = Jv + (k0 + k3 )c (1
i0 || = 0
+ vext
+mk=
v cext
= ||
Jvc
+
(1 )
t
t
t
= Dm cm
# create a mesh

t
c

mi = + D
vcext
=0
i||
mc
m
from gapFillMesh import TrenchMesh
Jv kt
cJv
(1

)
=
0

k
c
(1

=0
= D)
t
c
t
t
mesh = TrenchMesh(cellSize = 0.002e-6,
t
c

D
c
i
cm Jv
trenchSpacing = 1e-6,
c
t m

k
c
0 ) = 0

(1

D
c
=

D
m
m
m cm = 0
trenchDepth = 0.5e-6,
v
tt
t
D
n

c
=
on = 0
c
m
m
boundaryLayerDepth = 50e-6,

v
c Dm n
c

c
D
m
m =
c
= 00= 0(1 ) o
m
tm D
=
0on
=
aspectRatio = 2.)
c
D
D
c
c
n
= kc

t
t
Dn
c = k c (1 ) on = 0
c
# create the field variables
D c = 0
t
|| = 1
# create the governing equations
v
2
Dm n
cm =
on = 0
2
# create the boundary conditions

v v
D n
Dc
k
)on
on
n
=
c
= (1
=

mD
m c
# solve
c
= on
0= 0= 0
mn
m

D D
n
n
)
= 0= 0
= k
c (1
c
c
= k
c (1
)on on

CEAC Example

2
2 2

!
= Jv +i (k0 +!k3 3 )ci (1
" ) ci
! + b!) m"exp
t
cm
F
vi =
(b
"
1
i

c
v=
(b0 + b1 ) exp
cm 0 F
c

F
m nF
m
(b
! exp "
= b1 )
(b0 RT
+ b1exp
)
nF v =
c 0v +
c
RT RT
m ||
nF m nFcim
F
m= vcext
after D. Josell, D. Wheeler, W. H. Huber, and T. P. Moffat,
v=
(b0 +

b1 ) texp
=
v
||
nF
c
RT
ext
Physical Review Letters, 87(1), (2001) 016102
m
3 i
t
t = Jv + (k0 + k3 )c (1
i0 || = 0
+ vext
+mk=
v cext
= ||
Jvc
+
(1 )
t
t
t
= Dm cm
# create a mesh

t
c

mi = + D
vcext
=0
i||
mc
m

Jv

k
c
(1

)
=
0

Jv

k
c
(1

=0
t

= D)
t
# create the field variables
c
t
t c
t

D
c
i
cm Jv
c
t m

k
c
0 ) = 0
# distance variable

(1

D
c
=

D
m
m
t
m cm = 0
v
t
t
D
n

c
=
on = 0
# surface accelerator concentration
c
m
m

v
c Dm n
c

c
0
D
m
m =
c
=
on
=
0kc
m D
m

c
=
0

D
c
= 0 (1 ) o

D
n

c
=
t

# bulk accelerator concentration


t
t
Dn
c = k c (1 ) on = 0
c
D c = 0
# metal ion concentration
t
|| = 1
# interfacial velocity
v
2
Dm n
cm =
on = 0
2

exchangeCurrentDensity = constantCurrentDensity
\v
von
D n
Dc
k
c
(1
)on
on
n
*=
acceleratorVar.getInterfaceVar()
c
=
=
+ acceleratorDependenceCurrentDensity

mD
m
cm
=
0= 0= 0
mn

D D
n
metalVar
n
)
= 0= 0
= k
c (1
currentDensity = exchangeCurrentDensity
*
c
c
=/ bulkMetalConcentration
k
c (1
)on on

CEAC Example

* Numeric.exp(-transferCoefficient * faradaysConstant * overpotential \


/ gasConstant / temperature)
2

depositionRateVariable = currentDensity * atomicVolume /2charge


/ faradaysC
2
# create the governing equations
# create an iterator

!
= Jv +i (k0 +!k3 3 )ci (1
" ) ci
! + b!) m"exp
t
cm
F
vi =
(b
"
1
i

c
v=
(b0 + b1 ) exp
cm 0 F
c

F
m nF
m
(b
! exp "
= b1 )
(b0 RT
+ b1exp
)
nF v =
c 0v +
c
RT RT
m ||
nF m nFcim
F
m= vcext
after D. Josell, D. Wheeler, W. H. Huber, and T. P. Moffat,
v=
(b0 +

b1 ) texp
=
v
||
nF
c
RT
ext
Physical Review Letters, 87(1), (2001) 016102
m
3 i
t
t = Jv + (k0 + k3 )c (1
i0 || = 0
+ vext
+mk=
v cext
= ||
Jvc
+
(1 )
t
t
t
= Dm cm
# create a mesh

t
c

mi = + D
vcext
=0
i||
mc
m

Jv

k
c
(1

)
=
0

Jv

k
c
(1

=0
t

= D)
t
# create the field variables
c
t
t c
t

D
c
i
cm Jv
c
t m

k
c
0 ) = 0
# create the governing equations

(1

D
c
=

D
m
m
t
m cm = 0
v
t
t
D
n

c
=
on = 0
# advection equation
c
m
m

v
c Dm n
c

c
0
D
m
m =
c
=
on
=
0kc
m D
m

c
=
0

D
c
= 0 (1 ) o

D
n

c
=
t

from fipy.terms.transientTerm import TransientTerm


t
t
Dn
c = k\c (1 ) on = 0
c
from fipy.models.levelSet.advection.higherOrderAdvectionTerm
D c = 0
import HigherOrderAdvectionTerm
t
|| = 1
v
2
D
n

c
=
on

=
0
m
advectionEquation = TransientTerm()
+ m
2

HigherOrderAdvectionTerm(coeff = extensionVelocityVariable)
v v
D n
Dc
k
)on
on
n
=
c
= (1
=

mD
m c
c
= on
0= 0= 0
mn
m
# surfactant equation

D D
n
n
)
= 0= 0
= k
c (1
c
c
= k
c (1
)on on

CEAC Example

# metal equation

# bulk accelerator equation


# create the boundary conditions

2
2 2

# solve

!
= Jv +i (k0 +!k3 3 )ci (1
" ) ci
! + b!) m"exp
t
cm
F
vi =
(b
"
1
i

c
v=
(b0 + b1 ) exp
cm 0 F
c

F
m nF
m
(b
! exp "
= b1 )
(b0 RT
+ b1exp
)
nF v =
c 0v +
c
RT RT
m ||
nF m nFcim
F
m= vcext
after D. Josell, D. Wheeler, W. H. Huber, and T. P. Moffat,
v=
(b0 +

b1 ) texp
=
v
||
nF
c
RT
ext
Physical Review Letters, 87(1), (2001) 016102
m
3 i
t
t = Jv + (k0 + k3 )c (1
i0 || = 0
+ vext
+mk=
v cext
= ||
Jvc
+
(1 )
t
t
t
= Dm cm
# create a mesh

t
c

mi = + D
vcext
=0
i||
mc
m

Jv

k
c
(1

)
=
0

Jv

k
c
(1

=0
t

= D)
t
# create the field variables
c
t
t c
t

D
c
i
cm Jv
c
t m

k
c
0 ) = 0
# create the governing equations

(1

D
c
=

D
m
m
t
m cm = 0
v
t
t
D
n

c
=
on = 0
# create the boundary conditions
c
m
m

v
c Dm n
c

c
0
D
m
m =
c
=
on
=
0kc
m D
m

c
=
0

D
c
= 0 (1 ) o

D
n

c
=
t

# solve
t
t
Dn
c = k c (1 ) on = 0
c
D c = 0
for step in range(numberOfSteps):
t
if step % levelSetUpdateFrequency == 0:
|| = 1
v
2
distanceVar.calcDistanceFunction()
Dm n
cm =
on = 0
2
bulAcceleratorVar):
for var in (distanceVar, acceleratorVar, metalVar,
v v
var.updateOld()
D n
Dc
k
)on
on
n
=
c
= (1
=

mD
m c
c
= on
0= 0= 0
mn
m
dt = cflNumber * cellSize / max(extensionVelocityVariable)

D D
n
n
)
= 0= 0
distanceVar.extendVariable(extensionVelocityVariable)
= k
c (1
c
c
= k
c (1
)on on

CEAC Example

advectionEquation.solve(distanceVar, dt = dt)
2
surfactantEquation.solve(acceleratorVar, dt = dt)
metalEquation.solve(metalVar, dt = dt, boundaryConditions 2= metalEquationBCs)
2
bulkAcceleratorEquation.solve(bulkAcceleratorVar, dt = dt,
boundaryConditions = acceleratorBCs)

CEAC Example
after D. Josell, D. Wheeler, W. H. Huber, and T. P. Moffat,
Physical Review Letters, 87(1), (2001) 016102

accelerator coverage

no leveler

CEAC Example
after D. Josell, D. Wheeler, W. H. Huber, and T. P. Moffat,
Physical Review Letters, 87(1), (2001) 016102

accelerator coverage

no leveler

with leveler
(just add another
surfactant equation set)

FiPy Design - Objects


Cell

Mesh

Variable

Viewer

Face
Vertex

Solver
Term
BoundaryCondition

SparseMatrix

FiPy Design - Objects


Cell

Mesh

Variable

Viewer

Face
Vertex

Solver
Term
BoundaryCondition

SparseMatrix

"#

transient

"#

diffusion

"#

"#

FiPy Design - Terms


nth order diffusion

convection

"#

source

&
&
V (V )old &

[A#n ]face
[A#n { }]face
[(#n #u)A]face V S = 0
t
face
face
face
!
"#
$ !
"#
$ !
"#
$ !
"#
$ !"#$
transient

nth order diffusion

diffusion

Variable

Solver

source

convection

SparseMatrix

fa

Term

CellTerm

TransientTerm

SourceTerm

BoundaryCondition

NthOrderTerm

ce adjacent
cell
cell

vertex

FaceTerm

1
DiffusionTerm

ConvectionTerm
Cell

Mesh

Variable

Face
Vertex

Solver

Viewer

Term

BoundaryCondition

SparseMatrix

"#

transient

"#

"#

"#

FiPy Design - Variables

diffusion

nth order diffusion

convection

"#

source

&
&
V (V )old &

[A#n ]face
[A#n { }]face
[(#n #u)A]face V S = 0
t
face
face
face
!
"#
$ !
"#
$ !
"#
$ !
"#
$ !"#$
transient

Term

nth order diffusion

diffusion

Viewer

Mesh

Either:
solution variables (evaluated by
Term)
set by intermediate calculation
Lazy evaluation

Variable

CellVariable

FaceVariable

source

convection

GradVariable

CellGradVariable

Physical dimensions

1FaceGradVariable
Cell

Mesh

Variable

Face
Vertex

Solver

Viewer

Term

BoundaryCondition

SparseMatrix

Efficiency Issues
Tested efficiency against Ryo Kobayashis FORTRAN code specifically
written to solve grain impingement problem.
Naive all-Python FiPy was 200X as slow
Smarter all-Python FiPy is 30X as slow
After optimization and judicious C-inline, FiPy is now 7X as slow
Development time is reduced considerably
FORTRAN requires 1800 lines of single-use code
Python smart requires 100 lines
Python inline requires 300 lines

Future Work
Adaptive meshes
Multigrid
Cell-centered finite volume
Repair/improve support for physical dimensions
Export (formatted text, HDF, etc.)
Viewers (refactor and add more, e.g., OpenDX (Dan Lewis?))
More examples:
Fluid flow
Elasticity
Electrochemistry Phase Field (implemented, but vexing)
???

Summary

Cross-platform, Open Source code for solving phase transformation


problems
Capable of solving multivariate, coupled, non-linear PDEs
Extensive documentation, dozens of examples, hundreds of tests
Python syntax both easy to learn and powerful
Object-oriented structure easy to adapt to unique problems
Slower to run than hand-tailored FORTRAN or C
but much faster to write

www.ctcms.nist.gov/fipy/

Acknowledgements

Alex Mont

Montgomery Blair High School

John Dukovic Applied Materials


Daniel Josell NIST Metallurgy Division
Tom Moffat

NIST Metallurgy Division

Steve Langer NIST Information Technology Laboratory


Andrew Reid NIST Materials Science and Engineering Laboratory
Edwin Garca NIST Materials Science and Engineering Laboratory
Daniel Lewis GE Ceramic and Metallurgy Technologies

Вам также может понравиться