/
Problem1.py
130 lines (100 loc) · 3.97 KB
/
Problem1.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# coding: utf-8
from fipy import CellVariable, DiffusionTerm, Grid2D, parallelComm, TransientTerm, Variable
from fipy.tools import dump, numerix
import numpy as np
# Numerical parameters
nx = ny = 100 # domain size
dx = dy = 1.0 # mesh resolution
dt = Variable(0.1) # initial timestep
# Physical parameters
mm = 4. # anisotropic symmetry
epsilon_m = 0.025 # degree of anisotropy
theta_0 = 0.0 # tilt w.r.t. x-axis
tau_0 = 1. # numerical mobility
DD = 10. # thermal diffusivity
W_0 = 1. # isotropic well height
lamda = DD * tau_0 / 0.6267 / W_0**2
delta = 0.05 # undercooling
# Mesh and field variables
mesh = Grid2D(nx=nx, ny=ny, dx=dx, dy=dy)
phase = CellVariable(mesh=mesh, hasOld=True)
uu = CellVariable(mesh=mesh, hasOld=True)
uu.constrain(-delta, mesh.exteriorFaces)
def initialize():
phase[:] = -1.0
x, y = mesh.cellCenters
radius = 2.0 # Initial r=1 collapses due to Gibbs-Thomson, r=2 slumps to phi=0.6, r=4 seems OK.
center = (nx * dx / 2., ny * dy / 2.)
mask = (x - center[0])**2 + (y - center[1])**2 < radius**2
phase.setValue(1., where=mask)
uu[:] = -delta
initialize()
def make_tau(phase_):
theta_cell = numerix.arctan2(phase_.grad[1], phase_.grad[0])
a_cell = 1 + epsilon_m * numerix.cos(mm * theta_cell + theta_0)
return tau_0 * a_cell**2
tau = make_tau(phase)
tau_old = make_tau(phase.old)
source = (phase - lamda * uu * (1 - phase**2)) * (1 - phase**2)
theta = numerix.arctan2(phase.faceGrad[1], phase.faceGrad[0])
W = W_0 * (1 + epsilon_m * numerix.cos(mm * theta - theta_0))
W_theta = - W_0 * mm * epsilon_m * numerix.sin(mm * theta - theta_0)
# Build up the diffusivity matrix
I0 = Variable(value=((1,0), (0,1)))
I1 = Variable(value=((0,-1), (1,0)))
Dphase = W**2 * I0 + W * W_theta * I1
heat_eqn = TransientTerm() == DiffusionTerm(DD) + (phase - phase.old) / dt / 2.
phase_eqn = TransientTerm(tau) == DiffusionTerm(Dphase) + source
initialize()
solid_area = (np.array(phase.globalValue)>0).sum()*dx*dy # initial size of solid nucleus
if parallelComm.procID==0:
print 'solid area', solid_area
total_steps = 20000
sweeps = 2
tolerance = 0.5
# Serial:
#from fipy.solvers.pysparse import LinearLUSolver as Solver
#solver_heat = Solver()
#solver_phase = Solver()
# Parallel: mpirun with --trilinos for proper meshing, etc.
from fipy.solvers.trilinos import LinearGMRESSolver as Solver
solver_heat = Solver(precon=None)
solver_phase = Solver(precon=None)
elapsed_time = 0.0
current_step = 0
while current_step < total_steps:
uu.updateOld()
phase.updateOld()
res_heat0 = heat_eqn.sweep(uu, dt=dt.value, solver=solver_heat)
res_phase0 = phase_eqn.sweep(phase, dt=dt.value, solver=solver_phase)
for sweep in range(sweeps):
res_heat = heat_eqn.sweep(uu, dt=dt.value, solver=solver_heat)
res_phase = phase_eqn.sweep(phase, dt=dt.value, solver=solver_phase)
if sweep == 0:
res_heat1 = res_heat
res_phase1 = res_phase
print
print 'sweep',sweep
print res_heat
print res_phase
solid_area = (np.array(phase.globalValue)>0).sum()*dx*dy # initial size of solid nucleus
if parallelComm.procID==0:
print
print 'dt',dt.value
print 'current_step',current_step
print 'res_heat',res_heat0, res_heat
print 'res_phase',res_phase0, res_phase
print 'solid area', solid_area
if (res_heat < res_heat1 * tolerance) and (res_phase < res_phase1 * tolerance):
elapsed_time += dt.value
current_step += 1
dt.setValue(dt.value * 1.1)
if current_step % 10 == 0:
glu = uu.globalValue
glp = phase.globalValue
if parallelComm.procID==0:
np.savez_compressed('data-test/dump{0}.npz'.format(current_step), uu=np.array(glu), phase=np.array(glp), elapsed_time=np.array(elapsed_time))
else:
dt.setValue(dt.value * 0.8)
uu[:] == uu.old
phase[:] = phase.old