forked from the-iterator/VIE
/
viepy3mp.py
246 lines (210 loc) · 8.2 KB
/
viepy3mp.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#******************************************************************************#
#
# viepy3mp.py
#
# Python 3 (multiprocessing) version of VIE solver
#
# Neil Budko (c) 2012-2015
# n.v.budko@gmail.com
#
#******************************************************************************#
#
# This file contains the main program
#
# Standard modules: scipy, matplotlib, time, sys, os, inspect
# Extra modules: green, incident, scattered, addobject, visualization, matvec
#
# Input: see basic_input.py (inside ../Input folder)
# Output: matlab files (see ../Output folder)
# Visualization: 2D slices, GMRES convergence plot
#
# To run in background on Linux:
# at now (press 'Enter')
# python viepy3.py (press 'Enter')
# (press 'Ctrl+D')
#
# To monitor the output:
# tail -f stdout.log
#
# To see if the job is running, in terminal
# atq
#
#******************************************************************************#
import scipy as sci
import scipy.io as scio
from scipy import sparse
from scipy.sparse import linalg as ssla
from scipy import linalg as scila
import matplotlib.pyplot as plt
import time
import sys
import os
import inspect
import incident # module for computing icident field
import scattered # module for computing scattered field
import green # module for computing Green's tensor
import addobject # module for adding objects to the domain
import visualization as vis # visualization module
import matvecpar # matrix-vector multiplication module
from multiprocessing import Pool
print('\n*************')
print('PROGRAM START')
print('VIE solver \nNeil Budko (c) 2012-2015\n')
c0 = 299792458.0 # speed of light in vacuum
Mu0 = 4.0*sci.pi*1e-7 # vacuum permeability
Eps0 = 1.0/(Mu0*c0*c0) # vacuum permittivity
#******************************************************************************#
# Loading input parameters
#******************************************************************************#
# determining the current script directory
myDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
fileName = myDir+'/Input/basic_input.inp' # name of the file with basic input
f = open(fileName,'r') # open data file for reading
print('data file:', fileName,'\n')
print('Problem parameters:\n')
for line in f.readlines(): # reading and executing lines from input file
exec(line)
f.close()
print('NX =',NX,'NY =',NY,'NZ =',NZ)
print('Freq =',Freq, '(frequency, [Hz])')
print('Lambda0 =',Lambda0, '(vacuum wavelength, [m])')
print('EpsRelMax =',EpsRelMax, 'maximum relative permittivity')
print('LambdaMed =',LambdaMed, '(minimum wavelength, [m])')
print('Kappa =',Kappa, '(points per vacuum wavelength)')
print('Cell =',Cell, '(discretization cell, [m])')
print('KappaMed =',LambdaMed/Cell, '(points per medium wavelength)')
print('Source: ',source)
print('(PolX,PolY,PolZ)=(',PolX,PolY,PolZ,') polarization of source')
print('(Xs,Ys,Zs)=(',Xs,Ys,Zs,') coordinates of source, [m]')
#******************************************************************************#
# Computing Ein
# Possibilities:
# Ein = incident.PointDipole(Freq,EpsRelB,Cell,NX,NY,NZ,Xs,Ys,Zs,PolX,PolY,PolZ)
# Ein = incident.PlaneWave(Freq,EpsRelB,Cell,NX,NY,NZ,Kx,Ky,Kz,Xs,Ys,Zs,PolX,PolY,PolZ)
#******************************************************************************#
t0 = time.clock()
Ein = sci.zeros([NX,NY,NZ,3],complex)
Ein = incident.PointDipole(Freq,EpsRelB,Cell,NX,NY,NZ,Xs,Ys,Zs,PolX,PolY,PolZ)
t1 = time.clock()
# saving Ein in a *.mat file
outFile = myDir+'/Output/IncidentField' # file name
scio.savemat(outFile, {'Ein':Ein})
Bvec = sci.reshape(Ein,(NX*NY*NZ*3,1))
deltaT = t1-t0
sys.stdout.write('Incident field computed in '+str(deltaT)+' seconds\n')
# Slicing Ein
figNum = 1
fieldName = 'E^{in}'
SliceX = round(NX/2.)
SliceY = round(NY/2.)
SliceZ = round(NZ/2.)
vis.sliceFieldArr(sci.real(Ein),NX,NY,NZ,SliceX,SliceY,SliceZ,figNum,fieldName)
#******************************************************************************#
# Computing G tensor
#******************************************************************************#
t0 = time.clock()
GF = green.greentensor(Freq,EpsRelB,Cell,NX,NY,NZ)
t1 = time.clock()
# saving GF in a *.mat file
#outFile = myDir+'/Output/GreenTensor' # file name
#scio.savemat(outFile, {'GF':GF})
deltaT = t1-t0
print('GF tensor computed in',deltaT, 'seconds')
#******************************************************************************#
# Constructing an object
#******************************************************************************#
# setting all permittivity to EpsRelB
EpsArr = sci.ones((NX,NY,NZ),complex) # array with all elements 1+0j
EpsArr = EpsArr*EpsRelB
# adding a homogeneous brick to the domain (repeat if necessary)
CornerX,CornerY,CornerZ = 0.1*Xdim, 0.1*Ydim, 0.1*Zdim # corner coordinates of the brick, in [m] (use Lambda0)
Lx,Ly,Lz = 0.8*Xdim, 0.8*Ydim, 0.8*Zdim # dimensions of the brick, in [m] (use Lambda0)
EpsRel = 2.0 # permittivity of the brick, can be complex
addobject.brick(EpsArr,Cell,CornerX,CornerY,CornerZ,Lx,Ly,Lz,EpsRel)
# adding a homogeneous ball to the domain (repeat if necessary)
Xc,Yc,Zc = 0.5*Xdim, 0.5*Ydim, 0.5*Zdim
Radius = 0.3*Zdim
EpsRel = 6.0
addobject.sphere(EpsArr,Cell,Xc,Yc,Zc,Radius,EpsRel,NX,NY,NZ)
# adding a homogeneous ball to the domain (repeat if necessary)
Xc,Yc,Zc = 0.5*Xdim, 0.5*Ydim, 0.5*Zdim
Radius = 0.2*Zdim
EpsRel = 4.0
addobject.sphere(EpsArr,Cell,Xc,Yc,Zc,Radius,EpsRel,NX,NY,NZ)
# Plotting EpsArrClean
figNum = 2
vis.sliceEpsArr(EpsArr,NX,NY,NZ,figNum)
# saving EpsArrClean in a *.mat file
outFile = myDir+'/Output/EpsRelArr' # file name
scio.savemat(outFile, {'EpsArr':EpsArr})
relres = []
def resnorm(residual):
global it
relres.append(residual)
print('it =', it, ' rel. res. =', residual)
it = it+1
return
def solver():
global it
#******************************************************************************#
# Computing the total field
#******************************************************************************#
# parameters for the GMRES solver
tol = 1e-6 # relative residual tolerance
restart = 300 # inner iterations
maxiter = 300 # max total iterations
# memory calculation
MemReq = (restart+6)*Ein.nbytes + GF.nbytes + EpsArr.nbytes
proceed = input('You may need extra '+str(round((MemReq/(1024*1024*1024)),2))+\
' GB. Proceed? [y/n]: ')
if proceed == 'n':
sys.exit('PROGRAM ABORTED')
p = Pool(3) # creating a pool of workers/threads
# declearing the operator
def AuClean(U):
V = matvecpar.Au(U,GF,EpsArr,NX,NY,NZ,p)
return V
Aop = ssla.LinearOperator((NX*NY*NZ*3,NX*NY*NZ*3),matvec = AuClean,dtype = complex)
# preparing to read the residual vector
nb = scila.norm(Bvec)
print('Computing total field...')
print('Starting GMRES with: tol =', tol,' restart =',restart, ' maxiter =', maxiter)
t0 = time.clock()
it = 1
(Vsol,info) = ssla.gmres(Aop,Bvec, tol=tol, restart=restart, maxiter=maxiter, callback=resnorm)
t1 = time.clock()
V0 = Vsol # for use as an initial guess
Etot = sci.reshape(Vsol,(NX,NY,NZ,3))
# saving Etot in a *.mat file
outFile = myDir+'/Output/TotalField' # file name
scio.savemat(outFile, {'Etot':Etot})
deltaT = t1-t0
print('Total field computed in', deltaT, 'seconds')
print('GMRES Info:', info)
# Plotting residual
plt.ion()
fig = plt.figure(3)
plt.semilogy(relres)
plt.title('GMRES residual')
fig.canvas.draw()
plt.ioff()
# Slicing E
figNum = 4
fieldName = 'E'
vis.sliceFieldArr(sci.absolute(Etot),NX,NY,NZ,SliceX,SliceY,SliceZ,figNum,fieldName)
#******************************************************************************#
# Computing force density
#******************************************************************************#
print('Computing force density...')
t0 = time.clock()
# To do: Here comes the computation of the force density
t1 = time.clock()
deltaT = t1-t0
print('Force density computed in', deltaT, 'seconds')
#plt.show() # show and keep all the figures untill closed
print('\nPROGRAM END :-)')
print('***************\n')
#******************************************************************************#
return
if __name__ == '__main__':
solver()