Hi,

My ultimate goal: a numerical model very similar to doi:10.2298/SOS1001033N
(Computer simulation of rapid solidification with undercooling: A case
study of spherical ceramics sample on metallic substrate).  The full text
pdf of that paper is easily found online.  I'm interested in solidification
of a pure metal with interface velocity a function of interface temperature
(thermally undercooled solidification of a pure metal). My knowledge of
solidification, Python, and FiPy is quite basic. I just discovered FiPy a
few weeks ago.


I want to start by considering the level set method in FiPy. Start with the
basic 1D Stefan problem: solidification of a pure material on a finite
domain. I know nothing about the phase field method and whether it is
applicable to the ultimate goal in paragraph 1, in which interface velocity
is a specified function of interface temperature.


I found a thread from 2007
https://www.mail-archive.com/fipy@nist.gov/msg00320.html, but the code of
Daniel Wheeler is too advanced for me to understand, and does not run
unmodified in current FiPy.  Without being able to comprehend this code in
1D, extension to 2D cylindrical coordinates seems unattainable.


I looked at the level set example of a 'simple trench system:'
http://www.ctcms.nist.gov/fipy/examples/levelSet/generated/examples.levelSet.electroChem.howToWriteAScript.html


I tried to imitate this example (the metal ion Cm part) with the scripts
below, but am stuck as to how to couple the interface velocity into my
problem as an unknown. In my script below, the interface velocity appears
to remain at the initial specified value, since it apparently never gets
updated or coupled into the system. It would seem necessary to have the
Stefan condition as the coupling equation, but I am unable to look at the
FiPy manual and FiPy Python code and identify the necessary commands. I
looked for the equivalent of the Stefan condition (not expressed as a
source term, but expressed in terms of gradients of metal ion concentration
on either side of the interface) in the code for the example Simple Trench
System, but was unable to identify it. The Stefan condition is currently
represented in my script as a source term, but I do not see how to couple
Vinterface into the unknowns. It seems like one approach could be to
replace Vinterface in the source term with an expression involving
gradients of temperature on either side of the interface, but I am stuck as
to how to write this in the language of FiPy in both 1D and eventually 2D
(first Cartesian 2D then cylindrical 2D).


I would love to see code that is can be obviously generalized to 2D
Cartesian then 2D Cylindrical, instead of being specialized only to 1D.
The code in https://www.mail-archive.com/fipy@nist.gov/msg00320.html might
be 1D-only and/or non-obvious to translate to 2D, for example.


Thanks


MY MAIN PYTHON SCRIPT



# from IPython import embed #then put embed() in your script at a point
where you want to be at ipython prompt


# take the approach of having variables with conventional names e.g.
temperature, then set to 1.0 etc for nondimensional

# this lets you choose different nondimensionalization schemes

#
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((

nx = 20

L=1.

cellSize = L/nx

#there is no use for a graded mesh since grid is fixed and interface is
moving

mesh = Grid1D(nx=nx, Lx=L)

x=mesh.cellCenters

#
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((

numberOfCellsInNarrowBand = 10

narrowBandWidth = numberOfCellsInNarrowBand * cellSize

cflNumber=.2

#
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((

#level set method distance variable, initialized to -1.

distanceVar = DistanceVariable(name = 'distance variable',mesh = mesh,value
= -1.,hasOld = 1)

#TODO I think the interface has to advance a little into the domain to
establish where it is?

#alternative is to have extra cells to the left of the actual x=0, as in
simpleTrenchSystem.py

distanceVar.setValue(1., where=(x > cellSize))

distanceVar.calcDistanceFunction(order=2)

#
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((

#thermal diffusivity

alphaSolid=1.

alphaLiquid=1.


# #thermal conductivity

# kSolid=1.

# kLiquid=1.


# #mass density

# rhoSolid=1.

# rhoLiquid=1.


#specific heat

cpSolid=1.

cpLiquid=1.


latentHeat=1.

Tm=.5 #melting T


temperature =
CellVariable(name="temperature",mesh=mesh,value=1.,hasOld=False)


#left boundary is step change in temperature

valueLeft=0.

temperature.constrain(valueLeft, mesh.facesLeft)


#right boundary is zero flux, which is default BC in FiPy


#
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((

#TODO this scheme is not going to work. interface velocity starts out with
initial guess. how is it updated or linked to anything?

#simple trench electro problem: interface velocity was a function of metal
ion bulk concentration and theta


interfaceVelocVar=CellVariable(name='interface
velocity',mesh=mesh,value=0.1) #TODO initializing V at zero results in
errors


advectionEquation = TransientTerm() + AdvectionTerm(interfaceVelocVar)


#
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((

energyEquation=buildEnergyEquation(temperature=temperature,distanceVar=distanceVar,interfaceVelocVar=interfaceVelocVar,cellSize=cellSize,alphaSolid=alphaSolid,alphaLiquid=alphaLiquid,latentHeat=latentHeat,cpSolid=cpSolid,cpLiquid=cpLiquid,Tm=Tm)

#
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((


viewer = Viewer(vars=(temperature,),datamin=0., datamax=1.)

viewer.plot()

raw_input()


levelSetUpdateFrequency = int(0.8 * narrowBandWidth / (cellSize * cflNumber
* 2)) #TODO where does this come from?


numberOfSteps=80


for step in range(numberOfSteps):

if step>5 and step % 5 == 0 and viewer is not None:

viewer.plot()

raw_input()


if step % levelSetUpdateFrequency == 0:

distanceVar.calcDistanceFunction(order=2)


distanceVar.updateOld()


distanceVar.extendVariable(interfaceVelocVar, order=2)

dt = cflNumber * cellSize / interfaceVelocVar.max()


advectionEquation.solve(distanceVar, dt = dt)

energyEquation.solve(temperature,dt=dt)







MY SUBROUTINE SCRIPT TO BUILD ENERGY EQUATION


from fipy.terms.implicitSourceTerm import ImplicitSourceTerm

from fipy.terms.transientTerm import TransientTerm

from fipy import FaceVariable, CellVariable, DiffusionTerm


def
buildEnergyEquation(temperature,distanceVar,interfaceVelocVar,cellSize,alphaSolid=1.0,alphaLiquid=1.0,latentHeat=1.0,cpSolid=1.,cpLiquid=1.,Tm=0.):

r'''

#based on metalIonDiffusionEquation.py from NIST


#solve the one dimensional solidification problem from materials processing
class,

#9/28/1999 lecture: solidification in finite domain; page 105 in class notes

#level set method

'''

#
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((

mesh = distanceVar.mesh

#
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((

#
http://www.ctcms.nist.gov/fipy/examples/diffusion/generated/examples.diffusion.mesh1D.html

#trying to adapt the position-dependent diffusivity example to
distanceVar-dependent diffusivity

D = FaceVariable(mesh=mesh, value=alphaSolid)


#https://www.mail-archive.com/fipy@nist.gov/msg00854.html

distVarAtFaceCenters=distanceVar.getHarmonicFaceValue()


D.setValue(alphaLiquid, where=(distVarAtFaceCenters > 0.))

#
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((


cp=CellVariable(name='specific heat',mesh=mesh,value=cpSolid,hasOld=0)

cp.setValue(cpLiquid, where=(distanceVar > 0))


#
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((


#TODO is it OK that interfaceVelocVar is a CellVariable? in
metalIonDiffusion.py, the default interface V was a scalar

#here is where the Stefan condition is expressed as a  source term

#dividing by solution variable because of ImplicitSourceTerm: see FiPy
manual

coeff = interfaceVelocVar * latentHeat * distanceVar.cellInterfaceAreas /
(mesh.cellVolumes) / cp / temperature


#
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((

#need to fix interface T at solidification T

#
http://www.ctcms.nist.gov/fipy/documentation/USAGE.html#applying-internal-boundary-conditions

mask1=((distanceVar >= -cellSize/2.) & (distanceVar<cellSize/2.)) #TODO
will this always select a single cell center? is syntax correct? ipython

largeValue=1e+10


#
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((

#TODO or the == version?

#TODO check signs

transientCoeff=1.

eq = TransientTerm(transientCoeff) - DiffusionTerm(D) -
ImplicitSourceTerm(coeff) + ImplicitSourceTerm(largeValue*mask1) -
largeValue*mask1*Tm


return eq




END OF MESSAGE
_______________________________________________
fipy mailing list
fipy@nist.gov
http://www.ctcms.nist.gov/fipy
  [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]

Reply via email to