1 |
from esys.escript import * |
2 |
from esys.escript.models import TemperatureCartesian, StokesProblemCartesian |
3 |
from esys.finley import Rectangle, Brick, LoadMesh |
4 |
from optparse import OptionParser |
5 |
from math import pi, ceil |
6 |
def removeRestartDirectory(dir_name): |
7 |
if os.path.isdir(dir_name): |
8 |
for root, dirs, files in os.walk(dir_name, topdown=False): |
9 |
for name in files: os.remove(os.path.join(root,name)) |
10 |
for name in dirs: os.remove(os.path.join(root,name)) |
11 |
os.rmdir(dir_name) |
12 |
print "Restart files %s have been removed."%dir_name |
13 |
|
14 |
NE=20 |
15 |
DIM=2 |
16 |
H=1. |
17 |
L=4*H |
18 |
THETA=0.5 |
19 |
TOL=1.e-3 |
20 |
PERTURBATION=0.1 |
21 |
T_END=0.3 |
22 |
DT_OUT=T_END/500 |
23 |
VERBOSE=False |
24 |
RA=1.e5 # Rayleigh number |
25 |
A=22. # Arenious number |
26 |
DI = 0. # dissipation number |
27 |
SUPG=False |
28 |
create_restartfiles_every_step=10 |
29 |
|
30 |
print "total number of elements = ",NE**DIM*int(L/H)**(DIM-1) |
31 |
|
32 |
# read options: |
33 |
parser = OptionParser(usage="%prog [-r [DIR]]") |
34 |
parser.add_option("-r", "--restart", dest="restart", help="restart from latest directory. It will be deleted after a new directory has been created.", default=False, action="store_true") |
35 |
parser.add_option("-d", "--dir", dest="restart_dir", help="restart from directory DIR. The directory will not be deleted but new restart directories are created.",metavar="DIR", default=None) |
36 |
(options, args) = parser.parse_args() |
37 |
restart=options.restart or (options.restart_dir !=None) |
38 |
# |
39 |
# set up domain: |
40 |
# |
41 |
if restart: |
42 |
if options.restart_dir ==None: |
43 |
restart_files=[] |
44 |
for f in os.listdir("."): |
45 |
if f.startswith("restart"): restart_files.append(f) |
46 |
if len(restart_files)==0: |
47 |
raise IOError,"no restart files" |
48 |
restart_files.sort() |
49 |
f=restart_files[-1] |
50 |
else: |
51 |
f=options.restart_dir |
52 |
print "restart from directory ",f |
53 |
dom=LoadMesh("mesh.nc") |
54 |
ff=open(os.path.join(f,"stamp.%d"%dom.getMPIRank()),"r").read().split(";") |
55 |
t=float(ff[0]) |
56 |
t_out=float(ff[1]) |
57 |
n=int(ff[2]) |
58 |
n_out=int(ff[3]) |
59 |
dt=float(ff[4]) |
60 |
v=load(os.path.join(f,"v.nc"),dom) |
61 |
p=load(os.path.join(f,"p.nc"),dom) |
62 |
T=load(os.path.join(f,"T.nc"),dom) |
63 |
if n>1: |
64 |
dt_a=float(ff[5]) |
65 |
a=load(os.path.join(f,"a.nc"),dom) |
66 |
else: |
67 |
dt_a=None |
68 |
a=None |
69 |
if dom.getMPIRank()==0: nusselt_file=open("nusselt.csv","a") |
70 |
else: |
71 |
if DIM==2: |
72 |
dom=Rectangle(int(ceil(L*NE/H)),NE,l0=L,l1=H,order=2, useFullElementOrder=True,optimize=True) |
73 |
else: |
74 |
dom=Brick(int(ceil(L*NE/H)),int(ceil(L*NE/H)),NE,l0=L,l1=L,l2=H,order=2, useFullElementOrder=True,optimize=True) |
75 |
dom.dump("mesh.nc") |
76 |
x=dom.getX() |
77 |
T=Scalar(1,ReducedSolution(dom)) |
78 |
for d in range(DIM): |
79 |
if d == DIM-1: |
80 |
T*=sin(x[d]/H*pi) |
81 |
else: |
82 |
T*=cos(x[d]*((d+1)/L*pi)) |
83 |
|
84 |
T=1.-x[DIM-1]+PERTURBATION*T |
85 |
v=Vector(0,Solution(dom)) |
86 |
if dom.getMPIRank() ==0: nusselt_file=open("nusselt.csv","w") |
87 |
t=0 |
88 |
t_out=0 |
89 |
n=0 |
90 |
n_out=0 |
91 |
dt=None |
92 |
a=None |
93 |
dt_a=None |
94 |
|
95 |
vol=integrate(1.,Function(dom)) |
96 |
x=dom.getX() |
97 |
# |
98 |
# set up heat problem: |
99 |
# |
100 |
heat=TemperatureCartesian(dom,theta=THETA,useSUPG=SUPG) |
101 |
heat.setTolerance(TOL) |
102 |
|
103 |
fixed_T_at=whereZero(x[DIM-1])+whereZero(H-x[DIM-1]) |
104 |
heat.setInitialTemperature(T) |
105 |
print "initial Temperature range ",inf(T),sup(T) |
106 |
heat.setValue(rhocp=Scalar(1.,Function(dom)),k=Scalar(1.,Function(dom)),given_T_mask=fixed_T_at) |
107 |
# |
108 |
# set up velovity problem |
109 |
# |
110 |
sp=StokesProblemCartesian(dom) |
111 |
sp.setTolerance(TOL) |
112 |
sp.setToleranceReductionFactor(TOL) |
113 |
x2=ReducedSolution(dom).getX() |
114 |
p=-RA*(x2[DIM-1]-0.5*x2[DIM-1]**2) |
115 |
|
116 |
fixed_v_mask=Vector(0,Solution(dom)) |
117 |
for d in range(DIM): |
118 |
if d == DIM-1: |
119 |
ll = H |
120 |
else: |
121 |
ll = L |
122 |
fixed_v_mask+=(whereZero(x[d])+whereZero(x[d]-ll))*unitVector(d,DIM) |
123 |
|
124 |
# |
125 |
# let the show begin: |
126 |
# |
127 |
while t<T_END: |
128 |
v_last=v*1 |
129 |
print "============== solve for v ========================" |
130 |
viscosity=exp(A*(1./(1+T.interpolate(Function(dom)))-2./3.)) |
131 |
print "viscosity range :", inf(viscosity), sup(viscosity) |
132 |
sp.initialize(f=T*(RA*unitVector(DIM-1,DIM)),eta=viscosity,fixed_u_mask=fixed_v_mask) |
133 |
v,p=sp.solve(v,p,show_details=VERBOSE, verbose=True,max_iter=500,solver='PCG') |
134 |
# v,p=sp.solve(v,p,show_details=VERBOSE, verbose=True,max_iter=500,solver='GMRES') |
135 |
|
136 |
for d in range(DIM): |
137 |
print "range %d-velocity"%d,inf(v[d]),sup(v[d]) |
138 |
|
139 |
if t>=t_out: |
140 |
saveVTK("state.%d.vtu"%n_out,T=T,v=v,p=p) |
141 |
print "visualization file %d for time step %e generated."%(n_out,t) |
142 |
n_out+=1 |
143 |
t_out+=DT_OUT |
144 |
Nu=1.+integrate(viscosity*length(grad(v))**2)/(RA*vol) |
145 |
if dom.getMPIRank() ==0: nusselt_file.write("%e %e\n"%(t,Nu)) |
146 |
heat.setValue(v=v,Q=DI/RA*viscosity*length(symmetric(grad(v)))**2) |
147 |
print "nusselt number = ",Nu,n |
148 |
if n>0: |
149 |
a,a_alt = (v_last-v)/dt, a |
150 |
dt_a,dt_a_alt = dt, dt_a |
151 |
if n>1: |
152 |
z=(a-a_alt)/((dt_a+dt_a_alt)/2) |
153 |
f=Lsup(z)/Lsup(v) |
154 |
print "estimated error ",f*dt**2 |
155 |
dt_new=min(2*dt,max(dt/2,sqrt(0.05/f))) |
156 |
dt=min(dt_new,heat.getSafeTimeStepSize()) |
157 |
else: |
158 |
dt=heat.getSafeTimeStepSize() |
159 |
print n,". time step t=",t," step size ",dt |
160 |
print "============== solve for T ========================" |
161 |
T=heat.solve(dt, verbose=VERBOSE) |
162 |
print "Temperature range ",inf(T),sup(T) |
163 |
n+=1 |
164 |
t+=dt |
165 |
# ========================= |
166 |
# |
167 |
# create restart files: |
168 |
# |
169 |
if create_restartfiles_every_step>0: |
170 |
if (n-1)%create_restartfiles_every_step == 0: |
171 |
c=(n-1)/create_restartfiles_every_step |
172 |
old_restart_dir="restart_%s_"%(c-1) |
173 |
new_restart_dir="restart_%s_"%c |
174 |
|
175 |
print "Write restart files to ",new_restart_dir |
176 |
if not os.path.isdir(new_restart_dir): os.mkdir(new_restart_dir) |
177 |
v.dump(os.path.join(new_restart_dir,"v.nc")) |
178 |
p.dump(os.path.join(new_restart_dir,"p.nc")) |
179 |
T.dump(os.path.join(new_restart_dir,"T.nc")) |
180 |
if n>1: |
181 |
file(os.path.join(new_restart_dir,"stamp.%d"%dom.getMPIRank()),"w").write("%e; %e; %s; %s; %e; %e;\n"%(t, t_out, n, n_out, dt, dt_a)) |
182 |
a.dump(os.path.join(new_restart_dir,"a.nc")) |
183 |
else: |
184 |
file(os.path.join(new_restart_dir,"stamp.%d"%dom.getMPIRank()),"w").write("%e; %e; %s; %s; %e;\n"%(t, t_out, n, n_out, dt)) |
185 |
removeRestartDirectory(old_restart_dir) |
186 |
|