Daniel Wheeler wrote:
> Hi Michael,
>
> Reply is  below.
>
> On Fri, Feb 22, 2008 at 2:13 PM, Michael Waters <[EMAIL PROTECTED]> wrote:
>   
>>  I am trying to compute an interface angle in the same way that was done
>>  in the paper "Extending phase field models of solidification to
>>  polycrystalline materials"  by James Warren, Ryo Kobayashi, Alexander
>>  Lobkovsky, Craig Carter. I used a snippet of code from the fipy
>>  anisotropy example (section 9.4), but this returns an error that I'm not
>>  sure how to correct. If anyone knows a better way to do this or how to
>>  work around the error, I'd love to hear.
>>
>>  This is the code that I'm using,  I'd like it if I could keep theta as a
>>  modular variable:
>>
>>  phase = CellVariable(name='phase field', mesh=mesh, value = 0.0)
>>  theta = ModularVariable( name='theta', mesh=mesh, value=-pi + 0.0001,
>>  hasOld=1 )
>>
>>  phaseY = phase.getFaceGrad().dot((0, 1))*1.0
>>  phaseX = phase.getFaceGrad().dot((1, 0))*1.0
>>  psi= arctan2(phaseY, phaseX)  + theta
>>     
>
> I think this error is simply due to doing mixed operations with face
> and cell values. It has
> nothing to do with the fact that theta is a ModularVariable. The error
> message is not particularly helpful though.
>
> To fix it do the following. Make phaseY and phaseX cell values
>
>     phaseY = phase.getGrad().dot((0, 1))
>     phaseX = phase.getGrad().dot((1, 0))
>
> Then
>
>     psi= arctan2(phaseY, phaseX)  + theta
>
> works. FYI is not a ModularVariable. Do you want it to be?
>
> Looking into this I realize that ModularVariable does not have
> addition defined. This doesn't work
>
>     >>> print theta + theta
>     [-6.28298531 -6.28298531 -6.28298531 -6.28298531] 1
>
> This does work
>
>     >>> print theta - (-theta)
>    [ 0.0002  0.0002  0.0002  0.0002] 1
>
> which I believe is correct. Also this works
>
>     >>> print 4 * theta - theta
>     [-3.14129265 -3.14129265 -3.14129265 -3.14129265] 1
>
> I am not sure why the addition operator was never included. Probably
> there is a reason, but I can't remember.
> I am now worried that the other operators need to be fixed. What about this?
>
>     >>> print theta * 4
>     [-12.56597061 -12.56597061 -12.56597061 -12.56597061] 1
>
> Anyhow, if you are only doing limited operations, then I think you can
> work around it.
>
> Is ModularVariable worth fixing up to work properly? Or is there a
> better way such as just defining a calculation
> and then just using a mod operator like this
>
>     >>> a = CellVariable(..)
>     >>> b = CellVariable(..)
>     >>> c = (a + b) % numerix.pi
>
> Seems more natural to me. The % operator should return a BinOp, which
> is currently not the case (Is it?).
> We would then have to do something about the weird face grads that
> need to be done in some of
> the examples in a modular fashion, but they probably could be defined
> as special variables or even in the script.
> I think this makes much more sense. Of course, the following,
>
>     >>> d = ((a + b) % numerix.pi) + a
>
> would not be a modular variable, which also makes sense to me.
>
> Cheers
>
> --
> Daniel Wheeler
>
> >Thank you, Daniel Wheeler. 
I'm running into a new error however, and was hoping someone could
explain to me what is happening. I am trying to create a simple
solidification model.
The problem comes up as this:
    TypeError: unsupported operand type(s) for +: 'binOp' and 'unOp'
I am new to fipy and python so im having trouble conceptualizing binOp
vs. unOp.  The error comes up around line 120.
thanks!

-Mike W.

#!/usr/bin/env python


from fipy.tools.parser import parse

numberOfElements = parse('--numberOfElements', action = 'store',
                         type = 'int', default = 40)
numberOfSteps = parse('--numberOfSteps', action = 'store',
                      type = 'int', default = 1000)

steps = numberOfSteps
from fipy.tools.numerix import sqrt
N = int(sqrt(numberOfElements))
L = 2.5 * N / 100.
dL = L / N
dx = L/N
dy = L/N
from fipy.meshes.grid2D import Grid2D
mesh = Grid2D(dx=dx, dy=dx, nx=N, ny=N)

timeStepDuration = 1e-5
phaseTransientCoeff = 0.1
thetaSmallValue = 1e-6
beta = 1e5
mu = 1e3
thetaTransientCoeff = 0.01
gamma= 1e3
epsilon = 0.008
s = 0.01
alpha = 0.015
initial_temperature= -1.0
Boundary_Temperature = -1.0
#############################
tau = 3e-4
c = 0.02
Fold_Symetry = 4.0
kappa1 = 0.9
kappa2 = 20.0
tempDiffusionCoeff = 2.25


from fipy.variables.cellVariable import CellVariable
phase = CellVariable(name='phase field', mesh=mesh, hasOld = 1)
temperature = CellVariable(name='Temperature', mesh=mesh, 
value=initial_temperature,hasOld=1)


from fipy.variables.modularVariable import ModularVariable
from fipy.tools.numerix import pi
theta = ModularVariable(
    name='theta',
    mesh=mesh,
    value=-pi + 0.0001,
    hasOld=1
    )
#

#
L = dx*N
LL = dx*5
x, y = mesh.getCellCenters()[...,0], mesh.getCellCenters()[...,1]

import random
num_grains = 5
list_of_grains = []
for grain in range(num_grains):
    xx = L*random.random()
    yy = L*random.random()
    angle = 2*pi*random.random() - pi
    list_of_grains.append((xx,yy,angle))
for a, b, thetaValue in list_of_grains:
    segment = (x - a)**2 + (y - b)**2 < (LL)**2
    phase.setValue(1., where=segment)
    theta.setValue(thetaValue, where=segment)

#
# .. raw:: latex
from fipy.tools.numerix import pi, arctan, arctan2, tan

phaseY = phase.getGrad().dot((0, 1))
phaseX = phase.getGrad().dot((1, 0)) 

psi= arctan2(phaseY, phaseX)  + theta 

Phi = tan(Fold_Symetry * psi / 2.0)
PhiSq = Phi**2
beta_2 = (1.0 - PhiSq) / (1.0 + PhiSq)
beta_2Psi = -Fold_Symetry * 2 * Phi / (1.0 + PhiSq)
A = alpha**2 * c * (1.+ c * beta_2) * beta_2Psi
D = alpha**2 * (1.+ c * beta)**2
#############
dxi = (A*phase).getGrad()._take((1, 0), axis = 1) * (-1, 1)
anisotropySource =(dxi).getDivergence() 
###########


########

#
print 'building phase equation'

from fipy.terms.transientTerm import TransientTerm
from fipy.terms.explicitDiffusionTerm import ExplicitDiffusionTerm
from fipy.terms.implicitSourceTerm import ImplicitSourceTerm
#
def buildPhaseEquation(phase, theta):

    mVar = phase - 0.5 - kappa1 / pi * arctan(kappa2 * temperature)
    thetaMag = theta.getOld().getGrad().getMag()
    BB= mVar * ((mVar < 0.0) - phase) +  (mVar > 0.0) * mVar * phase #variable 
BB is really meant to reduce the line length below

    print 'BB + anisotropySource =', thetaMag + anisotropySource   ### if this 
line is enabled, the error returned is :
    #####  TypeError: unsupported operand type(s) for +: 'unOp' and 'unOp'

    ## this is odd because the addition below causes this error:
    #### TypeError: unsupported operand type(s) for +: 'binOp' and 'unOp'

    #to me, it seems that these should be the same type just in different 
lines. 

    
   


    return TransientTerm(phaseTransientCoeff) ==  ImplicitSourceTerm(BB+ 
anisotropySource) + ExplicitDiffusionTerm(D) ###  anisotropySource term is 
causing the problem. 
            
phaseEq = buildPhaseEquation(phase, theta) 
#
print 'theta equation building'

from fipy.tools.numerix import exp
def buildThetaEquation(phase, theta):

    phaseMod = phase + ( phase < thetaSmallValue ) * thetaSmallValue
    phaseModSq = phaseMod * phaseMod
    expo = epsilon * beta * theta.getGrad().getMag()
    expo = (expo < 100.) * (expo - 100.) + 100.
    pFunc = 1. + exp(-expo) * (mu / epsilon - 1.)

    phaseFace = phase.getArithmeticFaceValue()
    print phaseFace
    phaseSq = phaseFace * phaseFace
    gradMag = theta.getFaceGrad().getMag()
    eps = 1. / gamma / 10.
    gradMag += (gradMag < eps) * eps
    IGamma = (gradMag > 1. / gamma) * (1 / gradMag - gamma) + gamma
    diffusionCoeff = phaseSq * (s * IGamma + epsilon**2)

    thetaGradDiff = theta.getFaceGrad() - theta.getFaceGradNoMod()
    sourceCoeff = (diffusionCoeff * thetaGradDiff).getDivergence()

    from fipy.terms.implicitDiffusionTerm import ImplicitDiffusionTerm
    return TransientTerm(thetaTransientCoeff * phaseModSq * pFunc) == \
               ImplicitDiffusionTerm(diffusionCoeff) \
               + sourceCoeff


thetaEq = buildThetaEquation(phase, theta)
#

from fipy.solvers.linearLUSolver import LinearLUSolver
solver = LinearLUSolver(tolerance=1e-10)
#
####### conduction and transient temperature 
############################################
print 'building thermal diffusion equation'

from fipy.terms.implicitDiffusionTerm import ImplicitDiffusionTerm
tempDiffusionCoeff = 2.25

temperature_Eq = TransientTerm() == ImplicitDiffusionTerm(tempDiffusionCoeff) + 
 (phase-phase.getOld())/timeStepDuration 
from fipy.boundaryConditions.fixedValue import FixedValue


BCS_temperature=(FixedValue(mesh.getFacesRight(),Boundary_Temperature),FixedValue(mesh.getFacesLeft(),Boundary_Temperature),FixedValue(mesh.getFacesTop(),Boundary_Temperature),FixedValue(mesh.getFacesBottom(),Boundary_Temperature))




######################################################################


if __name__ == '__main__':
    from fipy.viewers import make
    phaseViewer = make(vars=phase,
                       limits={'datamin': 0., 'datamax': 1.})
    thetaProd = -pi + phase * (theta + pi)
    thetaPhase = phase*theta
    thetaProductViewer = make(vars=thetaProd,
                              limits={'datamin': -pi, 
                                      'datamax': pi})
    temp_view = make(vars=temperature,
                              limits={'datamin': Boundary_Temperature, 
                                      'datamax': 0.0 })
    phaseViewer.plot()
    thetaProductViewer.plot()
    temp_view.plot()
    from fipy.viewers.tsvViewer import TSVViewer
    thetaSave = TSVViewer(vars = thetaProd)
    phaseSave = TSVViewer(vars = phase)
    Temperature_Save = TSVViewer(vars = temperature)
    target = "/Users/mjwaters/DVLP/Solidify"
    

    print 'running model'
    for i in range(steps):
        theta.updateOld()
        phase.updateOld()
        temperature.updateOld()
        thetaRES=1.0
        phaseRES=1.0
        temperatureRES=1.0
       
       

        

        while  temperatureRES > 1e-3 or phaseRES > 1e-3  or thetaRES > 1e-3:
            
            thetaRES=   thetaEq.sweep(theta,solver = solver , 
dt=timeStepDuration)
            phaseRES= phaseEq.sweep(phase,solver = solver  ,dt=timeStepDuration)
            temperatureRES=temperature_Eq.sweep(temperature,solver = solver,  
dt=timeStepDuration, boundaryConditions = BCS_temperature)
    
            print thetaRES, phaseRES, temperatureRES

    
            
            
        print i
        print 'temperature max = ', max(temperature)

        if __name__ == '__main__':
            phaseViewer.plot()
            thetaProductViewer.plot()
            temp_view.plot()
            save = False
            if save is True:
                if i <10:
                    thetaProductViewer.plot(filename = target +  
"theta00%i.eps"%i)
                    thetaSave.plot(filename = target + "thetafield00%i.txt"%i)
                    phaseSave.plot(filename = target + "phasefield00%i.txt"%i)
                elif i<100:
                    thetaProductViewer.plot(filename = target + 
"theta0%i.eps"%i)
                    thetaSave.plot(filename = target + "thetafield0%i.txt"%i)
                    phaseSave.plot(filename = target + "phasefield0%i.txt"%i)
                else:
                    thetaProductViewer.plot(filename = target + "theta%i.eps"%i)
                    thetaSave.plot(filename = target + "thetafield%i.txt"%i)
                    phaseSave.plot(filename = target + "phasefield%i.txt"%i)

Reply via email to