A Finite Volume PDE Solver Using Python - NIST · 1 FiPy A Finite Volume PDE Solver Using Python D....

Post on 08-Jun-2018

236 views 1 download

Transcript of A Finite Volume PDE Solver Using Python - NIST · 1 FiPy A Finite Volume PDE Solver Using Python D....

ϕπϕπ

1

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

ϕπϕπ

1

Motivation

PDEs are ubiquitous in Materials Science problems

Solve PDEs in weird and unique ways

Easy to pose problems

Easy to customize

Don’t care about numerical methods

Dendrites

What Are Dendrites:

A vast amount of the products and devices that we use everyday,everything from aluminum foil and soda cans, to cars, jet engines andcomputers, are made from metals and alloys. Early in the creation of allthese products the metals are in a liquid, or molten state, that freezes toform a solid, just like water freezes to form ice. Now, if you were to lookat some just frozen, or freshly solidified metallic alloy with a strongmagnifying glass you would see that its structure is not uniform, but ismade up of tiny individual crystalline grains. Moreover, If you were able tolook even more carefully at the individual grains through a powerfulmicroscope, you would see that each grain is made up from what looks likea bunch of tiny metallic snowflakes crowding and growing into each other.Scientists and engineers call these tiny metallic snowflakes dendrites. Thepicture to the right shows what a surface cut through a "forest" of dendrites in a metal would look likethrough a microscope.

The term dendrite comes from the Greek word "dendron", which means a tree.This description is appropriate because we often describe the form and structure ofa metallic dendrite as that of a tree (see figure to left), with a main branch or trunk,from which grow side branches, from which grow smaller side branches, and soon, until all the main branches and the side branches grow into each other and thereis no room for any more branches to grow. The figure to

the right shows a few dendrites growing out of the surface of a metal. Infact, almost all freshly crystallized alloys are composed of many thousands,or even millions of dendritic crystals all stuck together. What's mostimportant is that the shape, size, and speed of growth of these dendrites areall factors that profoundly influence the final properties of cast and weldedmetals.For example, the dendrites affect how hard or soft a material is, howstretchable or springy it behaves, and how much you can bend or stretch itbefore it breaks. The dendrites also affect both how long and under whatenvironmental conditions you can use an alloy before it wears out or rusts.The dendrites affect whether the material is a good or a poor conductor of electricity. The dendriteseven affect how easily you can weld one piece of metal to another, and what's the best way to do thewelding. In short, the dendritic pattern formed during solidification profoundly influences a material'smechanical, electrical, and chemical properties.

ϕπϕπ

1

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 numericsThe Finite Volume method is a way to solve a set of PDEs, similar to the Finite Element or Finite Difference methods

ϕπϕπ

1

Why a common code?Many interface motion codes for solving Materials Science problems at NIST.

Phase Field for solidification and meltingPhase Field for grain boundary motionPhase Field for elasticityPhase Field for electrochemistryLevel Set code for electrochemistryetc…

Need for code homogeneity

Institutional memory is lost with constant rewriting of codesNeed for preservation and reuseLeverage different skill sets

ϕπϕπ

1

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

ϕπϕπ

1

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">>> print a[1,1]10.0 m

It is an error to slice a Variable whose value is not sliceable>>> Variable(value = 3)[2]Traceback (most recent call last):

...TypeError: unsubscriptable object

gt (self, other)

Test if a Variable is greater than another quantity>>> a = Variable(value = 3)>>> b = (a > 4)>>> b(Variable(value = 3) > 4)>>> b()0>>> a.setValue(5)>>> b()1

ϕπϕπ

1

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: nothingokTrying: b = (a > 4)Expecting: nothingokTrying: bExpecting: (Variable(value = 3) > 4)okTrying: b()Expecting: 0okTrying: a.setValue(5)Expecting: nothingokTrying: b()Expecting: 1ok0 of 6 examples failed in __main__.Variable.__gt__.__doc__

ϕπϕπ

1

Finite Volume MethodSolve a general PDE on a given domain for a field

!("#)!t︸ ︷︷ ︸

transient

+$.("u#)︸ ︷︷ ︸convection

= $.(%$#)︸ ︷︷ ︸diffusion

+ S#︸︷︷︸source

φa11 a12

a21 a22. . .

. . . . . . . . .. . . ann

φ1

φ2...

φn

=

b1

b2...

bn

∂(ρφ)

∂t︸ ︷︷ ︸transient

+∇ · ($uφ)︸ ︷︷ ︸convection

= ∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

+ Sφ︸︷︷︸source∫

V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

+∫

S($n · $u)φ dS︸ ︷︷ ︸convection

=∫

SΓ($n ·∇φ) dS︸ ︷︷ ︸

diffusion

+∫

VSφ dV︸ ︷︷ ︸

source

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

+∑face

[($n · $u)Aφ]face︸ ︷︷ ︸convection

=∑face

[ΓA$n ·∇φ]face︸ ︷︷ ︸diffusion

+ V Sφ︸︷︷︸source

1

domain

∂φ

∂t︸︷︷︸transient

−∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t= α2∇2φ + φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

∂φ

∂t︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

−∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

− [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

− ∇ · (#uφ)︸ ︷︷ ︸convection

− Sφ︸︷︷︸source

= 0

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

−∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

−∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

−∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

−∫

VSφ dV︸ ︷︷ ︸

source

= 0

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

−∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

−∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

−∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

− V Sφ︸︷︷︸source

= 0

1

ϕπϕπ

1

Finite Volume MethodSolve a general PDE on a given domain for a field

Integrate PDE over arbitrary control volumes

!("#)!t︸ ︷︷ ︸

transient

+$.("u#)︸ ︷︷ ︸convection

= $.(%$#)︸ ︷︷ ︸diffusion

+ S#︸︷︷︸source

φa11 a12

a21 a22. . .

. . . . . . . . .. . . ann

φ1

φ2...

φn

=

b1

b2...

bn

∂(ρφ)

∂t︸ ︷︷ ︸transient

+∇ · ($uφ)︸ ︷︷ ︸convection

= ∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

+ Sφ︸︷︷︸source∫

V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

+∫

S($n · $u)φ dS︸ ︷︷ ︸convection

=∫

SΓ($n ·∇φ) dS︸ ︷︷ ︸

diffusion

+∫

VSφ dV︸ ︷︷ ︸

source

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

+∑face

[($n · $u)Aφ]face︸ ︷︷ ︸convection

=∑face

[ΓA$n ·∇φ]face︸ ︷︷ ︸diffusion

+ V Sφ︸︷︷︸source

1

controlvolume

∂φ

∂t︸︷︷︸transient

−∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t= α2∇2φ + φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

∂φ

∂t︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

−∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

− [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

− ∇ · (#uφ)︸ ︷︷ ︸convection

− Sφ︸︷︷︸source

= 0

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

−∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

−∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

−∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

−∫

VSφ dV︸ ︷︷ ︸

source

= 0

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

−∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

−∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

−∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

− V Sφ︸︷︷︸source

= 0

1

ϕπϕπ

1

Finite Volume MethodSolve a general PDE on a given domain for a field

Integrate PDE over arbitrary control volumes

Evaluate PDE over polyhedral control volumes !("#)!t︸ ︷︷ ︸

transient

+$.("u#)︸ ︷︷ ︸convection

= $.(%$#)︸ ︷︷ ︸diffusion

+ S#︸︷︷︸source

φa11 a12

a21 a22. . .

. . . . . . . . .. . . ann

φ1

φ2...

φn

=

b1

b2...

bn

∂(ρφ)

∂t︸ ︷︷ ︸transient

+∇ · ($uφ)︸ ︷︷ ︸convection

= ∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

+ Sφ︸︷︷︸source∫

V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

+∫

S($n · $u)φ dS︸ ︷︷ ︸convection

=∫

SΓ($n ·∇φ) dS︸ ︷︷ ︸

diffusion

+∫

VSφ dV︸ ︷︷ ︸

source

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

+∑face

[($n · $u)Aφ]face︸ ︷︷ ︸convection

=∑face

[ΓA$n ·∇φ]face︸ ︷︷ ︸diffusion

+ V Sφ︸︷︷︸source

1

face

cell

vertex

∂φ

∂t︸︷︷︸transient

−∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t= α2∇2φ + φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

∂φ

∂t︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

−∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

− [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

− ∇ · (#uφ)︸ ︷︷ ︸convection

− Sφ︸︷︷︸source

= 0

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

−∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

−∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

−∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

−∫

VSφ dV︸ ︷︷ ︸

source

= 0

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

−∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

−∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

−∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

− V Sφ︸︷︷︸source

= 0

1

ϕπϕπ

1

Finite Volume MethodSolve a general PDE on a given domain for a field

Integrate PDE over arbitrary control volumes

Evaluate PDE over polyhedral control volumes

Obtain a large coupled set of linear equations in

!("#)!t︸ ︷︷ ︸

transient

+$.("u#)︸ ︷︷ ︸convection

= $.(%$#)︸ ︷︷ ︸diffusion

+ S#︸︷︷︸source

φa11 a12

a21 a22. . .

. . . . . . . . .. . . ann

φ1

φ2...

φn

=

b1

b2...

bn

∂(ρφ)

∂t︸ ︷︷ ︸transient

+∇ · ($uφ)︸ ︷︷ ︸convection

= ∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

+ Sφ︸︷︷︸source∫

V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

+∫

S($n · $u)φ dS︸ ︷︷ ︸convection

=∫

SΓ($n ·∇φ) dS︸ ︷︷ ︸

diffusion

+∫

VSφ dV︸ ︷︷ ︸

source

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

+∑face

[($n · $u)Aφ]face︸ ︷︷ ︸convection

=∑face

[ΓA$n ·∇φ]face︸ ︷︷ ︸diffusion

+ V Sφ︸︷︷︸source

1

φa11 a12

a21 a22. . .

. . . . . . . . .. . . ann

φ1

φ2...

φn

=

b1

b2...

bn

∂(ρφ)

∂t︸ ︷︷ ︸transient

+∇ · ($uφ)︸ ︷︷ ︸convection

= ∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

+ Sφ︸︷︷︸source∫

V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

+∫

S($n · $u)φ dS︸ ︷︷ ︸convection

=∫

SΓ($n ·∇φ) dS︸ ︷︷ ︸

diffusion

+∫

VSφ dV︸ ︷︷ ︸

source

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

+∑face

[($n · $u)Aφ]face︸ ︷︷ ︸convection

=∑face

[ΓA$n ·∇φ]face︸ ︷︷ ︸diffusion

+ V Sφ︸︷︷︸source

1

φa11 a12

a21 a22. . .

. . . . . . . . .. . . ann

φ1

φ2...

φn

=

b1

b2...

bn

∂(ρφ)

∂t︸ ︷︷ ︸transient

+∇ · ($uφ)︸ ︷︷ ︸convection

= ∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

+ Sφ︸︷︷︸source∫

V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

+∫

S($n · $u)φ dS︸ ︷︷ ︸convection

=∫

SΓ($n ·∇φ) dS︸ ︷︷ ︸

diffusion

+∫

VSφ dV︸ ︷︷ ︸

source

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

+∑face

[($n · $u)Aφ]face︸ ︷︷ ︸convection

=∑face

[ΓA$n ·∇φ]face︸ ︷︷ ︸diffusion

+ V Sφ︸︷︷︸source

1

ϕπϕπ

1

# create a mesh

# create a field variable

# create the equation terms

# create the equation

# create a viewer

# solve

Diffusion Example∂φ

∂t︸︷︷︸transient

−∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t= α2∇2φ + φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

∂φ

∂t︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

= ∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

+ [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

+∇ · (#uφ)︸ ︷︷ ︸convection

+ Sφ︸︷︷︸source

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

=∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

+∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

+∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

+∫

VSφ dV︸ ︷︷ ︸

source

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

=∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

+∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

+∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

+ V Sφ︸︷︷︸source

1

ϕπϕπ

1

Diffusion Example

# create a mesh

L = nx * dxfrom fipy.meshes.grid2D import Grid2Dmesh = Grid2D(nx = nx, dx = dx)

# create a field variable

# create the equation

# create a viewer

# solve

∂φ

∂t︸︷︷︸transient

−∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t= α2∇2φ + φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

∂φ

∂t︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

= ∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

+ [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

+∇ · (#uφ)︸ ︷︷ ︸convection

+ Sφ︸︷︷︸source

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

=∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

+∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

+∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

+∫

VSφ dV︸ ︷︷ ︸

source

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

=∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

+∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

+∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

+ V Sφ︸︷︷︸source

1

ϕπϕπ

1

Diffusion Example

# create a mesh

# create a field variable

from fipy.variables.cellVariable import CellVariablevar = CellVariable(mesh = mesh, value = 0)

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

var.setValue(value = 1., cells = mesh.getCells(filter = centerCells))

# create the equation

# create a viewer

# solve

∂φ

∂t︸︷︷︸transient

−∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t= α2∇2φ + φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

∂φ

∂t︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

= ∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

+ [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

+∇ · (#uφ)︸ ︷︷ ︸convection

+ Sφ︸︷︷︸source

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

=∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

+∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

+∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

+∫

VSφ dV︸ ︷︷ ︸

source

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

=∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

+∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

+∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

+ V Sφ︸︷︷︸source

1

ϕπϕπ

1

Diffusion Example

# create a mesh

# create a field variable

# set the initial conditionsdef centerCells(cell): return abs(cell.getCenter()[0] - L/2.) < L/10.

var.setValue(value = 1., cells = mesh.getCells(filter = centerCells))

# create the equation

# create a viewer

# solve

∂φ

∂t︸︷︷︸transient

−∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t= α2∇2φ + φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

∂φ

∂t︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

= ∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

+ [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

+∇ · (#uφ)︸ ︷︷ ︸convection

+ Sφ︸︷︷︸source

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

=∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

+∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

+∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

+∫

VSφ dV︸ ︷︷ ︸

source

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

=∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

+∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

+∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

+ V Sφ︸︷︷︸source

1

ϕπϕπ

1

Diffusion Example

# create a mesh

# create a field variable

# create the equation

from fipy.terms.transientTerm import TransientTermfrom fipy.terms.implicitDiffusionTerm import ImplicitDiffusionTerm

## equivalent forms

## eq = (TransientTerm() == ImplicitDiffusionTerm(coeff = 1))

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

eq = (TransientTerm() - ImplicitDiffusionTerm(coeff = 1) == 0)

# create a viewer

# solve

∂φ

∂t︸︷︷︸transient

−∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t= α2∇2φ + φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

∂φ

∂t︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

= ∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

+ [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

+∇ · (#uφ)︸ ︷︷ ︸convection

+ Sφ︸︷︷︸source

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

=∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

+∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

+∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

+∫

VSφ dV︸ ︷︷ ︸

source

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

=∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

+∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

+∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

+ V Sφ︸︷︷︸source

1

ϕπϕπ

1

Diffusion Example∂φ

∂t︸︷︷︸transient

−∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t= α2∇2φ + φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

∂φ

∂t︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

= ∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

+ [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

+∇ · (#uφ)︸ ︷︷ ︸convection

+ Sφ︸︷︷︸source

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

=∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

+∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

+∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

+∫

VSφ dV︸ ︷︷ ︸

source

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

=∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

+∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

+∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

+ V Sφ︸︷︷︸source

1

# create a mesh

# create a field variable

# create the equation terms

# create the equation

# create a viewer

from fipy.viewers.gist1DViewer import Gist1DViewerviewer = Gist1DViewer(vars = (var,), limits = ('e', 'e', 0, 1))viewer.plot()

# solve

ϕπϕπ

1

# create a mesh

# create a field variable

# create the equation terms

# create the equation

# create a viewer

# solve

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

Diffusion Example∂φ

∂t︸︷︷︸transient

−∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t= α2∇2φ + φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

∂φ

∂t︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

= ∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

+ [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

+∇ · (#uφ)︸ ︷︷ ︸convection

+ Sφ︸︷︷︸source

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

=∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

+∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

+∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

+∫

VSφ dV︸ ︷︷ ︸

source

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

=∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

+∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

+∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

+ V Sφ︸︷︷︸source

1

ϕπϕπ

1

Convection Example∂φ

∂t︸︷︷︸transient

= ∇ · (∇φ)︸ ︷︷ ︸diffusion

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

transient︷ ︸︸ ︷τφ

∂φ

∂t=

diffusion︷ ︸︸ ︷α2∇2φ+

source︷ ︸︸ ︷φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

L

cp

∂φ

∂t

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

1

# create a mesh

# create a field variable

# create the boundary conditions

# create the equation

# create a viewer

# solve

∂φ

∂t︸︷︷︸transient

= ∇ · (∇φ)︸ ︷︷ ︸diffusion

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

transient︷ ︸︸ ︷τφ

∂φ

∂t=

diffusion︷ ︸︸ ︷α2∇2φ+

source︷ ︸︸ ︷φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

L

cp

∂φ

∂t

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

1

ϕπϕπ

1

Convection Example∂φ

∂t︸︷︷︸transient

= ∇ · (∇φ)︸ ︷︷ ︸diffusion

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

transient︷ ︸︸ ︷τφ

∂φ

∂t=

diffusion︷ ︸︸ ︷α2∇2φ+

source︷ ︸︸ ︷φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

L

cp

∂φ

∂t

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

1

# create a mesh

# create a field variable

# create the boundary conditions

from fipy.boundaryConditions.fixedValue import FixedValuebcs = ( FixedValue(mesh.getFacesLeft(), 0), FixedValue(mesh.getFacesRight(), 1),)

# create the equation

# create a viewer

# solve

∂φ

∂t︸︷︷︸transient

= ∇ · (∇φ)︸ ︷︷ ︸diffusion

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

transient︷ ︸︸ ︷τφ

∂φ

∂t=

diffusion︷ ︸︸ ︷α2∇2φ+

source︷ ︸︸ ︷φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

L

cp

∂φ

∂t

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

1

ϕπϕπ

1

Convection Example∂φ

∂t︸︷︷︸transient

= ∇ · (∇φ)︸ ︷︷ ︸diffusion

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

transient︷ ︸︸ ︷τφ

∂φ

∂t=

diffusion︷ ︸︸ ︷α2∇2φ+

source︷ ︸︸ ︷φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

L

cp

∂φ

∂t

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

1

# create a mesh

# create a field variable

# create the boundary conditions

# create the equation

from fipy.terms.implicitDiffusionTerm import ImplicitDiffusionTermdiffusionTerm = ImplicitDiffusionTerm(coeff = 1)

from fipy.terms.exponentialConvectionTerm import ExponentialConvectionTermconvectionTerm = ExponentialConvectionTerm(coeff = (10,0),

diffusionTerm = diffusionTerm)

eq = (diffusionTerm + convectionTerm == 0)

# create a viewer

# solve

∂φ

∂t︸︷︷︸transient

= ∇ · (∇φ)︸ ︷︷ ︸diffusion

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

transient︷ ︸︸ ︷τφ

∂φ

∂t=

diffusion︷ ︸︸ ︷α2∇2φ+

source︷ ︸︸ ︷φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

L

cp

∂φ

∂t

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

1

ϕπϕπ

1

Convection Example∂φ

∂t︸︷︷︸transient

= ∇ · (∇φ)︸ ︷︷ ︸diffusion

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

transient︷ ︸︸ ︷τφ

∂φ

∂t=

diffusion︷ ︸︸ ︷α2∇2φ+

source︷ ︸︸ ︷φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

L

cp

∂φ

∂t

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

1

1.0

0.8

0.6

0.4

0.2

0.0

210

# create a mesh

# create a field variable

# create the boundary conditions

# create the equation

# create a viewer

# solve

from fipy.solvers.linearCGSSolver import LinearCGSSolver

eq.solve(var = var, solver = LinearCGSSolver(tolerance = 1.e-15, steps = 2000), boundaryConditions = boundaryConditions)

viewer.plot()

∂φ

∂t︸︷︷︸transient

= ∇ · (∇φ)︸ ︷︷ ︸diffusion

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

transient︷ ︸︸ ︷τφ

∂φ

∂t=

diffusion︷ ︸︸ ︷α2∇2φ+

source︷ ︸︸ ︷φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

L

cp

∂φ

∂t

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

1

ϕπϕπ

1

# create a mesh

# create the field variables

# create the phase equation

# create the temperature equation

# create a viewer

# solve

Phase Field Dendrite Exampleafter J. A. Warren, R. Kobayashi, A. E. Lobkovsky,

and W. C. Carter, Acta Materialia 51(20), (2003) 6035–6058

∂φ

∂t︸︷︷︸transient

= ∇ · (∇φ)︸ ︷︷ ︸diffusion

transient︷ ︸︸ ︷τφ

∂φ

∂t=

diffusion︷ ︸︸ ︷α2∇2φ+

source︷ ︸︸ ︷φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

L

cp

∂φ

∂t

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

1

∂φ

∂t︸︷︷︸transient

= ∇ · (∇φ)︸ ︷︷ ︸diffusion

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t= α2∇2φ + φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

∂φ

∂t︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

= ∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

+ [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

+∇ · (#uφ)︸ ︷︷ ︸convection

+ Sφ︸︷︷︸source

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

=∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

+∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

+∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

+∫

VSφ dV︸ ︷︷ ︸

source

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

=∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

+∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

+∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

+ V Sφ︸︷︷︸source

1

∂φ

∂t︸︷︷︸transient

−∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t− α2∇2φ− φ(1− φ)m2(φ, T ) = 0

∂T

∂t−DT∇2T − ∂φ

∂t= 0

︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

−∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

− [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

− ∇ · (#uφ)︸ ︷︷ ︸convection

− Sφ︸︷︷︸source

= 0

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

−∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

−∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

−∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

−∫

VSφ dV︸ ︷︷ ︸

source

= 0

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

−∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

−∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

−∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

− V Sφ︸︷︷︸source

= 0

1

ϕπϕπ

1

Phase Field Dendrite Example

# create a mesh

# create the field variables

# create the phase equation

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

phaseEq = (TransientTerm(coeff = tau) == \

ImplicitDiffusionTerm(coeff = alpha**2) + \

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

(m2 > 0) * m2 * phase)

# create the temperature equation

# create an iterator

# create a viewer

# solve

after J. A. Warren, R. Kobayashi, A. E. Lobkovsky, and W. C. Carter, Acta Materialia 51(20), (2003) 6035–6058

∂φ

∂t︸︷︷︸transient

= ∇ · (∇φ)︸ ︷︷ ︸diffusion

transient︷ ︸︸ ︷τφ

∂φ

∂t=

diffusion︷ ︸︸ ︷α2∇2φ+

source︷ ︸︸ ︷φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

L

cp

∂φ

∂t

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

1

∂φ

∂t︸︷︷︸transient

= ∇ · (∇φ)︸ ︷︷ ︸diffusion

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t= α2∇2φ + φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

∂φ

∂t︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

= ∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

+ [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

+∇ · (#uφ)︸ ︷︷ ︸convection

+ Sφ︸︷︷︸source

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

=∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

+∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

+∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

+∫

VSφ dV︸ ︷︷ ︸

source

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

=∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

+∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

+∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

+ V Sφ︸︷︷︸source

1

∂φ

∂t︸︷︷︸transient

−∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t− α2∇2φ− φ(1− φ)m2(φ, T ) = 0

∂T

∂t−DT∇2T − ∂φ

∂t= 0

︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

−∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

− [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

− ∇ · (#uφ)︸ ︷︷ ︸convection

− Sφ︸︷︷︸source

= 0

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

−∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

−∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

−∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

−∫

VSφ dV︸ ︷︷ ︸

source

= 0

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

−∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

−∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

−∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

− V Sφ︸︷︷︸source

= 0

1

ϕπϕπ

1

Phase Field Dendrite Example

# create a mesh

# create the field variables

# create the phase equation

# create the temperature equationtemperatureEq = (TransientTerm() == \

ImplicitDiffusionTerm(coeff = tempDiffCoeff) + \

(phase - phase.getOld()) / timeStepDuration)

# create a viewer

# solve

after J. A. Warren, R. Kobayashi, A. E. Lobkovsky, and W. C. Carter, Acta Materialia 51(20), (2003) 6035–6058

∂φ

∂t︸︷︷︸transient

= ∇ · (∇φ)︸ ︷︷ ︸diffusion

transient︷ ︸︸ ︷τφ

∂φ

∂t=

diffusion︷ ︸︸ ︷α2∇2φ+

source︷ ︸︸ ︷φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

L

cp

∂φ

∂t

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

1

∂φ

∂t︸︷︷︸transient

= ∇ · (∇φ)︸ ︷︷ ︸diffusion

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t= α2∇2φ + φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

∂φ

∂t︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

= ∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

+ [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

+∇ · (#uφ)︸ ︷︷ ︸convection

+ Sφ︸︷︷︸source

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

=∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

+∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

+∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

+∫

VSφ dV︸ ︷︷ ︸

source

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

=∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

+∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

+∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

+ V Sφ︸︷︷︸source

1

∂φ

∂t︸︷︷︸transient

−∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t− α2∇2φ− φ(1− φ)m2(φ, T ) = 0

∂T

∂t−DT∇2T − ∂φ

∂t= 0

︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

−∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

− [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

− ∇ · (#uφ)︸ ︷︷ ︸convection

− Sφ︸︷︷︸source

= 0

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

−∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

−∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

−∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

−∫

VSφ dV︸ ︷︷ ︸

source

= 0

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

−∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

−∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

−∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

− V Sφ︸︷︷︸source

= 0

1

ϕπϕπ

1

# create a mesh

# create the field variables

# create the phase equation

# create the temperature equation

# create an iterator

# create a viewer

# solve

for i for range(steps): phase.updateOld() temperature.updateOld() phaseEq.solve(phase, dt = timeStepDuration) temperatureEq.solve(temperature, dt = timeStepDuration) if i%frameRate == 0: phaseViewer.plot() temperatureViewer.plot()

Phase Field Dendrite Exampleafter J. A. Warren, R. Kobayashi, A. E. Lobkovsky,

and W. C. Carter, Acta Materialia 51(20), (2003) 6035–6058

∂φ

∂t︸︷︷︸transient

= ∇ · (∇φ)︸ ︷︷ ︸diffusion

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t= α2∇2φ + φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

∂φ

∂t︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

= ∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

+ [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

+∇ · (#uφ)︸ ︷︷ ︸convection

+ Sφ︸︷︷︸source

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

=∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

+∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

+∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

+∫

VSφ dV︸ ︷︷ ︸

source

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

=∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

+∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

+∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

+ V Sφ︸︷︷︸source

1

∂φ

∂t︸︷︷︸transient

−∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t− α2∇2φ− φ(1− φ)m2(φ, T ) = 0

∂T

∂t−DT∇2T − ∂φ

∂t= 0

︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

−∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

− [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

− ∇ · (#uφ)︸ ︷︷ ︸convection

− Sφ︸︷︷︸source

= 0

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

−∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

−∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

−∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

−∫

VSφ dV︸ ︷︷ ︸

source

= 0

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

−∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

−∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

−∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

− V Sφ︸︷︷︸source

= 0

1

∂φ

∂t︸︷︷︸transient

= ∇ · (∇φ)︸ ︷︷ ︸diffusion

transient︷ ︸︸ ︷τφ

∂φ

∂t=

diffusion︷ ︸︸ ︷α2∇2φ+

source︷ ︸︸ ︷φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

L

cp

∂φ

∂t

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

1

ϕπϕπ

1

Cahn-Hilliard Example

# create a mesh

# create the field variable

# create the equation

# create the boundary conditions

# create a viewer

# solve

∂φ

∂t−∇ · D∇

(∂f

∂φ− ε2∇2φ

)= 0

f =a2

2φ2(1− φ)2

∇φ = 0 on all boundaries

∇3φ = 0 on all boundaries

∂φ

∂t︸︷︷︸transient

−∇ · D [1− 6φ (1− φ)]∇φ︸ ︷︷ ︸2nd order diffusion

+ ∇ · D∇ε2∇2φ︸ ︷︷ ︸4th order diffusion

= 0

3

∂φ

∂t−∇ · D∇

(∂f

∂φ− ε2∇2φ

)= 0

f =a2

2φ2(1− φ)2

$n ·∇φ = 0 on all boundaries

$n ·∇3φ = 0 on all boundaries

∂φ

∂t︸︷︷︸transient

−∇ · D [1− 6φ (1− φ)]∇φ︸ ︷︷ ︸2nd order diffusion

+ ∇ · D∇ε2∇2φ︸ ︷︷ ︸4th order diffusion

= 0

3

ϕπϕπ

1

Cahn-Hilliard Example

# create a mesh

# create the field variable

# create the equation

# create the boundary conditions

# create a viewer

# solve

∂φ

∂t−∇ · D∇

(∂f

∂φ− ε2∇2φ

)= 0

f =a2

2φ2(1− φ)2

$n ·∇φ = 0 on all boundaries

$n ·∇3φ = 0 on all boundaries

∂φ

∂t︸︷︷︸transient

−∇ · D [1− 6φ (1− φ)]∇φ︸ ︷︷ ︸2nd order diffusion

+ ∇ · D∇ε2∇2φ︸ ︷︷ ︸4th order diffusion

= 0

3

∂φ

∂t−∇ · D∇

(∂f

∂φ− ε2∇2φ

)= 0

f =a2

2φ2(1− φ)2

$n ·∇φ = 0 on all boundaries

$n ·∇3φ = 0 on all boundaries

∂φ

∂t︸︷︷︸transient

−∇ · Da2 [1− 6φ (1− φ)]∇φ︸ ︷︷ ︸2nd order diffusion

+ ∇ · D∇ε2∇2φ︸ ︷︷ ︸4th order diffusion

= 0

3

ϕπϕπ

1

Cahn-Hilliard Example

# create a mesh

# create the field variable

# create the equation

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

from fipy.terms.nthOrderDiffusionTerm import NthOrderDiffusionTermfrom fipy.terms.transientTerm import TransientTermeq = (TransientTerm() == \ NthOrderDiffusionTerm(coeffs = (diffusionCoeff * doubleWellDerivative,)) -\ NthOrderDiffusionTerm(coeffs = (diffusionCoeff, epsilon**2)))

# create the boundary conditions

# create a viewer

# solve

∂φ

∂t−∇ · D∇

(∂f

∂φ− ε2∇2φ

)= 0

f =a2

2φ2(1− φ)2

$n ·∇φ = 0 on all boundaries

$n ·∇3φ = 0 on all boundaries

∂φ

∂t︸︷︷︸transient

−∇ · D [1− 6φ (1− φ)]∇φ︸ ︷︷ ︸2nd order diffusion

+ ∇ · D∇ε2∇2φ︸ ︷︷ ︸4th order diffusion

= 0

3

∂φ

∂t−∇ · D∇

(∂f

∂φ− ε2∇2φ

)= 0

f =a2

2φ2(1− φ)2

$n ·∇φ = 0 on all boundaries

$n ·∇3φ = 0 on all boundaries

∂φ

∂t︸︷︷︸transient

−∇ · Da2 [1− 6φ (1− φ)]∇φ︸ ︷︷ ︸2nd order diffusion

+ ∇ · D∇ε2∇2φ︸ ︷︷ ︸4th order diffusion

= 0

3

ϕπϕπ

1

Cahn-Hilliard Example

# create a mesh

# create the field variable

# create the equation

# create the boundary conditions

from fipy.boundaryConditions.nthOrderBoundaryCondition \ import NthOrderBoundaryCondition

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

# create a viewer

# solve

∂φ

∂t−∇ · D∇

(∂f

∂φ− ε2∇2φ

)= 0

f =a2

2φ2(1− φ)2

$n ·∇φ = 0 on all boundaries

$n ·∇3φ = 0 on all boundaries

∂φ

∂t︸︷︷︸transient

−∇ · D [1− 6φ (1− φ)]∇φ︸ ︷︷ ︸2nd order diffusion

+ ∇ · D∇ε2∇2φ︸ ︷︷ ︸4th order diffusion

= 0

3

∂φ

∂t−∇ · D∇

(∂f

∂φ− ε2∇2φ

)= 0

f =a2

2φ2(1− φ)2

$n ·∇φ = 0 on all boundaries

$n ·∇3φ = 0 on all boundaries

∂φ

∂t︸︷︷︸transient

−∇ · Da2 [1− 6φ (1− φ)]∇φ︸ ︷︷ ︸2nd order diffusion

+ ∇ · D∇ε2∇2φ︸ ︷︷ ︸4th order diffusion

= 0

3

ϕπϕπ

1

# create a mesh

# create the field variable

# create the equation

# create the boundary conditions

# create a viewer

# solve

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()

∂φ

∂t−∇ · D∇

(∂f

∂φ− ε2∇2φ

)= 0

f =a2

2φ2(1− φ)2

$n ·∇φ = 0 on all boundaries

$n ·∇3φ = 0 on all boundaries

∂φ

∂t︸︷︷︸transient

−∇ · D [1− 6φ (1− φ)]∇φ︸ ︷︷ ︸2nd order diffusion

+ ∇ · D∇ε2∇2φ︸ ︷︷ ︸4th order diffusion

= 0

3

Cahn-Hilliard Example

∂φ

∂t−∇ · D∇

(∂f

∂φ− ε2∇2φ

)= 0

f =a2

2φ2(1− φ)2

$n ·∇φ = 0 on all boundaries

$n ·∇3φ = 0 on all boundaries

∂φ

∂t︸︷︷︸transient

−∇ · Da2 [1− 6φ (1− φ)]∇φ︸ ︷︷ ︸2nd order diffusion

+ ∇ · D∇ε2∇2φ︸ ︷︷ ︸4th order diffusion

= 0

3

ϕπϕπ

1

CEAC Example

Copper electodeposition in submicron features

electrolyte additives influence deposition rate

CEAC - Curvature Enhanced Accelerator Coverage.

“Bottom Up” fill

“Momentum plating”

Curvature

θl =Klcl

1 + Klcl(1 − θs)

i = (1 − θs)i0 exp(−

αcF

RTη)

dθs

dt= −ks [θs − K(1 − θs)]

K = k exp(−αθ1/2

a

)

dθa

dt= κ|%v|θa + ka(θ

0a − θa)

θs = θ0s at t = 0

θa = θ0a at t = 0

θ0s =

K0

1 + K0

K0 = k exp(−α

(θ0

a

)1/2)

i = i0 exp(−

αF

RTη)

i0 = i00 + i10θa

α = α0 + α1θa

4

Interface speed

fixed point moving with the interface

Accelerator coverage

Experimental sequence

45 degree side wall tilt

The Electrochemical Society Interface • Winter 2004 51

FIG. 8. Seedless superfill is demonstrated by a sequence of images of direct copper deposition on trenches coatedwith a ruthenium barrier.3

FIG. 7. (a) A time sequence of images showing bottom-up copper superfilling of a via. (b) Tracking the interface midheight position during via filling provides a compari-son between the simulation and experiment. The inset shows a θSPS colorized contour plot of simulated bottom-up film growth.16

(a) (b)

With further increases in the differentialdeposition rate being so constrained, thesidewalls impinge before the bottom sur-face is able to escape the trench. For ini-tial catalyst coverage of 0.88, the deposi-tion rate is predicted to be effectively sat-urated at the start of metal depositionwith geometrically driven changes incatalyst coverage on the concave sur-faces being minimal. Depletion effects

are considered only across the hydrody-namic boundary in these simulations.However, for the higher deposition ratesassociated with higher catalyst cover-ages, significant depletion of the Cu2+

ion occurs within the trench, resultingin faster deposition toward the top of thefeature. This leads to an earlier impinge-ment at this location and void forma-tion as observed in two experimental

specimens (θ = 0.44 and 0.88) ratherthan the predicted seams. Such deple-tion effects have been fully modeledelsewhere.15

Via Filling Experiments andSimulations—Deposition in vias, unliketrenches, is a three-dimensional prob-lem by virtue of the nonzero curvatureof the cylindrical sidewalls. Cross sec-tions detailing the filling of cylindricalvias with a 4.5° sidewall slope areshown in 10 s increments in Fig. 7.16 Inthis experiment the catalyst is adsorbedsimultaneously with copper plating inaccord with conventional practice.Wafer fragments were immersed in theSPS-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 thefirst 60 s followed by the onset of bot-tom-up superfilling at ≈70 s. The fillingprocess is summarized by tracking theheight of the deposit along the center-line of the via, as a function of deposi-tion time. Favorable agreement withthe CEAC simulation is evident and thecorresponding simulated growth con-tours are given in the inset.16

Seedless Superfill

Current metallization technologyemploys three layers, a barrier metal,

LEVELER

ACCELERATOR

INHIBITOR

ϕπϕπ

1

# create a mesh

# create the field variables

# create the governing equations

# create the boundary conditions

# solve

CEAC Exampleafter D. Josell, D. Wheeler, W. H. Huber, and T. P. Moffat,

Physical Review Letters, 87(1), (2001) 016102

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)∂φ

∂t= −vext|∇φ|

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

∂cm

∂t= ∇ · Dm∇cm

∂cθ

∂t= ∇ · Dθ∇cθ

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

2

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)∂φ

∂t= −vext|∇φ|

∂θ

∂t= Jvθ + kθc

iθ(1− θ)

∂cm

∂t= ∇ · Dm∇cm

∂cθ

∂t= ∇ · Dθ∇cθ

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)

∂φ

∂t+ vext|∇φ| = 0

∂θ

∂t− Jvθ − kθc

iθ(1− θ) = 0

∂cm

∂t−∇ · Dm∇cm = 0

∂cθ

∂t−∇ · Dθ∇cθ = 0

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)

∂φ

∂t+ vext|∇φ| = 0

∂θ

∂t− Jvθ − kθc

iθ(1− θ) = 0

∂cm

∂t−∇ · Dm∇cm = 0

∂cθ

∂t−∇ · Dθ∇cθ = 0

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)∂φ

∂t+ vext|∇φ| = 0

∂θ

∂t− Jvθ − kθc

iθ(1− θ) = 0

∂cm

∂t−∇ · Dm∇cm = 0

∂cθ

∂t−∇ · Dθ∇cθ = 0

|∇φ| = 1

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

ϕπϕπ

1

# create a meshfrom gapFillMesh import TrenchMesh mesh = TrenchMesh(cellSize = 0.002e-6, trenchSpacing = 1e-6, trenchDepth = 0.5e-6, boundaryLayerDepth = 50e-6, aspectRatio = 2.)

# create the field variables

# create the governing equations

# create the boundary conditions

# solve

CEAC Exampleafter D. Josell, D. Wheeler, W. H. Huber, and T. P. Moffat,

Physical Review Letters, 87(1), (2001) 016102

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)∂φ

∂t= −vext|∇φ|

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

∂cm

∂t= ∇ · Dm∇cm

∂cθ

∂t= ∇ · Dθ∇cθ

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

2

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)∂φ

∂t= −vext|∇φ|

∂θ

∂t= Jvθ + kθc

iθ(1− θ)

∂cm

∂t= ∇ · Dm∇cm

∂cθ

∂t= ∇ · Dθ∇cθ

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)

∂φ

∂t+ vext|∇φ| = 0

∂θ

∂t− Jvθ − kθc

iθ(1− θ) = 0

∂cm

∂t−∇ · Dm∇cm = 0

∂cθ

∂t−∇ · Dθ∇cθ = 0

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)

∂φ

∂t+ vext|∇φ| = 0

∂θ

∂t− Jvθ − kθc

iθ(1− θ) = 0

∂cm

∂t−∇ · Dm∇cm = 0

∂cθ

∂t−∇ · Dθ∇cθ = 0

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)∂φ

∂t+ vext|∇φ| = 0

∂θ

∂t− Jvθ − kθc

iθ(1− θ) = 0

∂cm

∂t−∇ · Dm∇cm = 0

∂cθ

∂t−∇ · Dθ∇cθ = 0

|∇φ| = 1

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

ϕπϕπ

1

# create a mesh

# create the field variables

# distance variable

# surface accelerator concentration

# bulk accelerator concentration

# metal ion concentration

# interfacial velocity

exchangeCurrentDensity = constantCurrentDensity \ + acceleratorDependenceCurrentDensity * acceleratorVar.getInterfaceVar()

currentDensity = exchangeCurrentDensity * metalVar / bulkMetalConcentration * Numeric.exp(-transferCoefficient * faradaysConstant * overpotential \ / gasConstant / temperature)

depositionRateVariable = currentDensity * atomicVolume / charge / faradaysC

# create the governing equations

# create an iterator

# create the viewers

# solve

CEAC Exampleafter D. Josell, D. Wheeler, W. H. Huber, and T. P. Moffat,

Physical Review Letters, 87(1), (2001) 016102

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)∂φ

∂t= −vext|∇φ|

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

∂cm

∂t= ∇ · Dm∇cm

∂cθ

∂t= ∇ · Dθ∇cθ

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

2

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)∂φ

∂t= −vext|∇φ|

∂θ

∂t= Jvθ + kθc

iθ(1− θ)

∂cm

∂t= ∇ · Dm∇cm

∂cθ

∂t= ∇ · Dθ∇cθ

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)

∂φ

∂t+ vext|∇φ| = 0

∂θ

∂t− Jvθ − kθc

iθ(1− θ) = 0

∂cm

∂t−∇ · Dm∇cm = 0

∂cθ

∂t−∇ · Dθ∇cθ = 0

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)

∂φ

∂t+ vext|∇φ| = 0

∂θ

∂t− Jvθ − kθc

iθ(1− θ) = 0

∂cm

∂t−∇ · Dm∇cm = 0

∂cθ

∂t−∇ · Dθ∇cθ = 0

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)∂φ

∂t+ vext|∇φ| = 0

∂θ

∂t− Jvθ − kθc

iθ(1− θ) = 0

∂cm

∂t−∇ · Dm∇cm = 0

∂cθ

∂t−∇ · Dθ∇cθ = 0

|∇φ| = 1

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

ϕπϕπ

1

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)∂φ

∂t+ vext|∇φ| = 0

∂θ

∂t− Jvθ − kθc

iθ(1− θ) = 0

∂cm

∂t−∇ · Dm∇cm = 0

∂cθ

∂t−∇ · Dθ∇cθ = 0

|∇φ| = 1

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)∂φ

∂t= −vext|∇φ|

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

∂cm

∂t= ∇ · Dm∇cm

∂cθ

∂t= ∇ · Dθ∇cθ

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

2

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)∂φ

∂t= −vext|∇φ|

∂θ

∂t= Jvθ + kθc

iθ(1− θ)

∂cm

∂t= ∇ · Dm∇cm

∂cθ

∂t= ∇ · Dθ∇cθ

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)

∂φ

∂t+ vext|∇φ| = 0

∂θ

∂t− Jvθ − kθc

iθ(1− θ) = 0

∂cm

∂t−∇ · Dm∇cm = 0

∂cθ

∂t−∇ · Dθ∇cθ = 0

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)

∂φ

∂t+ vext|∇φ| = 0

∂θ

∂t− Jvθ − kθc

iθ(1− θ) = 0

∂cm

∂t−∇ · Dm∇cm = 0

∂cθ

∂t−∇ · Dθ∇cθ = 0

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

CEAC Exampleafter 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

# advection equation

from fipy.terms.transientTerm import TransientTermfrom fipy.models.levelSet.advection.higherOrderAdvectionTerm \ import HigherOrderAdvectionTerm

advectionEquation = TransientTerm() + HigherOrderAdvectionTerm(coeff = extensionVelocityVariable)

# surfactant equation

# metal equation

# bulk accelerator equation

# create the boundary conditions

# solve

ϕπϕπ

1

CEAC Exampleafter D. Josell, D. Wheeler, W. H. Huber, and T. P. Moffat,

Physical Review Letters, 87(1), (2001) 016102

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)∂φ

∂t= −vext|∇φ|

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

∂cm

∂t= ∇ · Dm∇cm

∂cθ

∂t= ∇ · Dθ∇cθ

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

2

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)∂φ

∂t= −vext|∇φ|

∂θ

∂t= Jvθ + kθc

iθ(1− θ)

∂cm

∂t= ∇ · Dm∇cm

∂cθ

∂t= ∇ · Dθ∇cθ

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)

∂φ

∂t+ vext|∇φ| = 0

∂θ

∂t− Jvθ − kθc

iθ(1− θ) = 0

∂cm

∂t−∇ · Dm∇cm = 0

∂cθ

∂t−∇ · Dθ∇cθ = 0

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)

∂φ

∂t+ vext|∇φ| = 0

∂θ

∂t− Jvθ − kθc

iθ(1− θ) = 0

∂cm

∂t−∇ · Dm∇cm = 0

∂cθ

∂t−∇ · Dθ∇cθ = 0

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

# create a mesh

# create the field variables

# create the governing equations

# create the boundary conditions

# solve

for step in range(numberOfSteps): if step % levelSetUpdateFrequency == 0: distanceVar.calcDistanceFunction() for var in (distanceVar, acceleratorVar, metalVar, bulAcceleratorVar): var.updateOld() dt = cflNumber * cellSize / max(extensionVelocityVariable) distanceVar.extendVariable(extensionVelocityVariable)

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

boundaryConditions = acceleratorBCs)

v =iΩnF

i = i0cim

c∞mexp

(−αF

RTη

)i0(θ) = b0 + b1θ

∂cm

∂t= ∇ · Dm∇cm

Dm =

DL

m when φ ≥ 0,0 when φ < 0

Dmn ·∇cm =v

Ωon φ = 0

∂cθ

∂t= ∇ · Dθ∇cθ

Dθ =

DL

θ when φ ≥ 00 when φ < 0

Dθn ·∇cθ = −kcθ(1− θ) on φ = 0

∂θ

∂t= Jvθ + (k0 + k3η

3)ciθ(1− θ)

v =ΩnF

(b0 + b1θ)cim

c∞mexp

(−αF

RTη

)∂φ

∂t+ vext|∇φ| = 0

∂θ

∂t− Jvθ − kθc

iθ(1− θ) = 0

∂cm

∂t−∇ · Dm∇cm = 0

∂cθ

∂t−∇ · Dθ∇cθ = 0

|∇φ| = 1

Dmn ·∇cm =v

Ωon φ = 0

Dθn ·∇cθ = −kθcθΓ(1− θ) on φ = 0

2

ϕπϕπ

1

CEAC Exampleafter D. Josell, D. Wheeler, W. H. Huber, and T. P. Moffat,

Physical Review Letters, 87(1), (2001) 016102

no “leveler”

acce

lera

tor

cove

rage

ϕπϕπ

1

CEAC Exampleafter D. Josell, D. Wheeler, W. H. Huber, and T. P. Moffat,

Physical Review Letters, 87(1), (2001) 016102with “leveler”

(just add another surfactant equation set)no “leveler”

acce

lera

tor

cove

rage

ϕπϕπ

1

Term

Solver

BoundaryCondition

Variable Viewer

SparseMatrix

Mesh

Cell

Face

Vertex

FiPy Design - Objects

ϕπϕπ

1

Term

Solver

BoundaryCondition

Variable Viewer

SparseMatrix

Mesh

Cell

Face

Vertex

FiPy Design - Objects

ϕπϕπ

1

FiPy Design - Terms

Term

Solver

BoundaryCondition

Variable Viewer

SparseMatrix

Mesh

Cell

Face

Vertex

∂φ

∂t︸︷︷︸transient

−∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t= α2∇2φ + φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

∂φ

∂t︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

−∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

− [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

− ∇ · (#uφ)︸ ︷︷ ︸convection

− Sφ︸︷︷︸source

= 0

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

−∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

−∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

−∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

−∫

VSφ dV︸ ︷︷ ︸

source

= 0

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

−∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

−∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

−∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

− V Sφ︸︷︷︸source

= 0

1

Variable

Term

Solver

BoundaryCondition

FaceTermNthOrderTerm

SparseMatrix

CellTerm

TransientTerm SourceTerm DiffusionTerm ConvectionTerm

cell

adjacentcell

face

vertex

ϕπϕπ

1

FiPy Design - Variables

∂φ

∂t︸︷︷︸transient

−∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

∇ · (#uφ)︸ ︷︷ ︸convection

+∇ · (∇φ)︸ ︷︷ ︸diffusion

= 0

φ|x=0 = 0 φ|x=L = 1

τφ∂φ

∂t= α2∇2φ + φ(1− φ)m2(φ, T )

∂T

∂t= DT∇2T +

∂φ

∂t︸ ︷︷ ︸transient

︸ ︷︷ ︸diffusion

︸ ︷︷ ︸source

m2(φ, T ) = φ− 12− κ1

πarctan (κ2T )

∂(ρφ)∂t︸ ︷︷ ︸

transient

−∇ · (Γ∇φ)︸ ︷︷ ︸diffusion

− [∇ · (Γi∇)]nφ︸ ︷︷ ︸nth order diffusion

− ∇ · (#uφ)︸ ︷︷ ︸convection

− Sφ︸︷︷︸source

= 0

∫V

∂(ρφ)∂t

dV︸ ︷︷ ︸transient

−∫

SΓ(#n ·∇φ) dS︸ ︷︷ ︸

diffusion

−∫

SΓn(#n ·∇ · · · ) dS︸ ︷︷ ︸

nth order diffusion

−∫

S(#n · #u)φ dS︸ ︷︷ ︸convection

−∫

VSφ dV︸ ︷︷ ︸

source

= 0

ρφV − (ρφV )old

∆t︸ ︷︷ ︸transient

−∑face

[ΓA#n ·∇φ]face︸ ︷︷ ︸diffusion

−∑face

[ΓA#n ·∇ · · · ]face︸ ︷︷ ︸nth order diffusion

−∑face

[(#n · #u)Aφ]face︸ ︷︷ ︸convection

− V Sφ︸︷︷︸source

= 0

1

Term

Solver

BoundaryCondition

Variable Viewer

SparseMatrix

Mesh

Cell

Face

Vertex

Term

Variable

CellVariable FaceVariable GradVariable

Viewer Mesh

CellGradVariable FaceGradVariable

Either:

solution variables (evaluated by Term)set by intermediate calculation

Lazy evaluation

Physical dimensions

ϕπϕπ

1

Efficiency Issues

Tested efficiency against Ryo Kobayashi’s 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 codePython “smart” requires ≈ 100 linesPython “inline” requires ≈ 300 lines

ϕπϕπ

1

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 flowElasticityElectrochemistry Phase Field (implemented, but vexing)

???

ϕπϕπ

1

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/

ϕπϕπ

1

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 García – NIST Materials Science and Engineering Laboratory

Daniel Lewis – GE Ceramic and Metallurgy Technologies