5 from qpms
.argproc
import ArgParser
, annotate_pdf_metadata
7 ap
= ArgParser(['rectlattice2d', 'single_particle', 'single_lMax', 'omega_seq_real_ng', 'planewave'])
8 ap
.add_argument("-o", "--output", type=str, required
=False, help='output path (if not provided, will be generated automatically)')
9 ap
.add_argument("-O", "--plot-out", type=str, required
=False, help="path to plot output (optional)")
10 ap
.add_argument("-P", "--plot", action
='store_true', help="if -p not given, plot to a default path")
11 #ap.add_argument("-g", "--save-gradually", action='store_true', help="saves the partial result after computing each irrep")
17 logging
.basicConfig(format
='%(asctime)s %(message)s', level
=logging
.INFO
)
21 from qpms
.qpms_p
import cart2sph
, sph2cart
, sph_loccart2cart
, sph_loccart_basis
23 from qpms
.cybspec
import BaseSpec
24 from qpms
.cytmatrices
import CTMatrix
, TMatrixGenerator
25 from qpms
.qpms_c
import Particle
, pgsl_ignore_error
26 from qpms
.cymaterials
import EpsMu
, EpsMuGenerator
, LorentzDrudeModel
, lorentz_drude
27 from qpms
.cycommon
import DebugFlags
, dbgmsg_enable
28 from qpms
import FinitePointGroup
, ScatteringSystem
, BesselType
, eV
, hbar
31 dbgmsg_enable(DebugFlags
.INTEGRATION
)
35 particlestr
= ("sph" if a
.height
is None else "cyl") + ("_r%gnm" % (a
.radius
*1e9
))
36 if a
.height
is not None: particlestr
+= "_h%gnm" % (a
.height
* 1e9
)
37 defaultprefix
= "%s_p%gnmx%gnm_m%s_bg%s_φ%g_θ(%g_%g)π_ψ%gπ_χ%gπ_f%s_L%d" % (
38 particlestr
, px
*1e9
, py
*1e9
, str(a
.material
), str(a
.background
), a
.phi
/pi
, np
.amin(a
.theta
)/pi
, np
.amax(a
.theta
)/pi
, a
.psi
/pi
, a
.chi
/pi
, ap
.omega_descr
, a
.lMax
)
39 logging
.info("Default file prefix: %s" % defaultprefix
)
42 a1
= ap
.direct_basis
[0]
43 a2
= ap
.direct_basis
[1]
48 orig_xy
= np
.stack(np
.meshgrid(orig_x
,orig_y
),axis
=-1)
50 bspec
= BaseSpec(lMax
= a
.lMax
)
51 # The parameters here should probably be changed (needs a better qpms_c.Particle implementation)
52 pp
= Particle(orig_xy
[0][0], ap
.tmgen
, bspec
=bspec
)
56 ss
, ssw
= ScatteringSystem
.create(par
, ap
.background_emg
, ap
.allomegas
[0], latticebasis
= ap
.direct_basis
)
60 a
.theta
= np
.array(a
.theta
)
61 dir_sph_list
= np
.stack((np
.broadcast_to(1, a
.theta
.shape
), a
.theta
, np
.broadcast_to(a
.phi
, a
.theta
.shape
)), axis
=-1)
62 sψ
, cψ
= math
.sin(a
.psi
), math
.cos(a
.psi
)
63 sχ
, cχ
= math
.sin(a
.chi
), math
.cos(a
.chi
)
64 E_sph
= (0., cψ
*cχ
+ 1j
*sψ
*sχ
, sψ
*cχ
+ 1j
*cψ
*sχ
)
66 dir_cart_list
= sph2cart(dir_sph_list
)
67 E_cart_list
= sph_loccart2cart(E_sph
, dir_sph_list
)
69 nfreq
= len(ap
.allomegas
)
70 ndir
= len(dir_sph_list
)
72 k_cart_arr
= np
.empty((nfreq
, ndir
, 3), dtype
=float)
73 wavenumbers
= np
.empty((nfreq
,), dtype
=float)
75 σ_ext_arr
= np
.empty((nfreq
,ndir
), dtype
=float)
76 σ_scat_arr
= np
.empty((nfreq
,ndir
), dtype
=float)
78 with
pgsl_ignore_error(15): # avoid gsl crashing on underflow
79 for i
, omega
in enumerate(ap
.allomegas
):
82 if ssw
.wavenumber
.imag
!= 0:
83 warnings
.warn("The background medium wavenumber has non-zero imaginary part. Don't expect meaningful results for cross sections.")
84 wavenumber
= ssw
.wavenumber
.real
85 wavenumbers
[i
] = wavenumber
87 k_sph_list
= np
.array(dir_sph_list
, copy
=True)
88 k_sph_list
[:,0] = wavenumber
90 k_cart_arr
[i
] = sph2cart(k_sph_list
)
94 k_cart
= k_cart_arr
[i
,j
]
95 blochvector
= (k_cart
[0], k_cart
[1], 0)
96 # the following two could be calculated only once, but probably not a big deal
97 LU
= ssw
.scatter_solver(k
=blochvector
)
98 ã
= ss
.planewave_full(k_cart
=k_cart
, E_cart
=E_cart_list
[j
])
99 Tã
= ssw
.apply_Tmatrices_full(ã
)
102 σ_ext_arr
[i
,j
] = -np
.vdot(ã
, f
).real
/wavenumber
**2
103 translation_matrix
= ssw
.translation_matrix_full(blochvector
=blochvector
) + np
.eye(ss
.fecv_size
)
104 σ_scat_arr
[i
,j
] = np
.vdot(f
,np
.dot(translation_matrix
, f
)).real
/wavenumber
**2
106 σ_abs_arr
= σ_ext_arr
- σ_scat_arr
108 outfile
= defaultprefix
+ ".npz" if a
.output
is None else a
.output
109 np
.savez(outfile
, meta
={**vars(a
), 'qpms_version' : qpms
.__version
__()}, dir_sph
=dir_sph_list
, k_cart
= k_cart_arr
, omega
= ap
.allomegas
, E_cart
= E_cart_list
, wavenumbers
= wavenumbers
, σ_ext
=σ_ext_arr
,σ_abs
=σ_abs_arr
,σ_scat
=σ_scat_arr
, unitcell_area
=ss
.unitcell_volume
111 logging
.info("Saved to %s" % outfile
)
114 if a
.plot
or (a
.plot_out
is not None):
116 from matplotlib
.backends
.backend_pdf
import PdfPages
117 matplotlib
.use('pdf')
118 from matplotlib
import pyplot
as plt
119 from scipy
.interpolate
import griddata
121 plotfile
= defaultprefix
+ ".pdf" if a
.plot_out
is None else a
.plot_out
122 with
PdfPages(plotfile
) as pdf
:
124 sintheta
= np
.sin(a
.theta
)
125 if False: #len(ap.omega_ranges) != 0:
126 # angle plot ---------------------------------
127 fig
= plt
.figure(figsize
=(210/25.4, 297/25.4))
128 vmax
= max(np
.amax(σ_ext_arr
), np
.amax(σ_scat_arr
), np
.amax(σ_abs_arr
))
129 vmin
= min(np
.amin(σ_ext_arr
), np
.amin(σ_scat_arr
), np
.amin(σ_abs_arr
))
131 ax
= fig
.add_subplot(311)
132 ax
.pcolormesh(a
.theta
, ap
.allomegas
/eh
, σ_ext_arr
, vmin
=vmin
, vmax
=vmax
)
133 ax
.set_xlabel('$\\theta$')
134 ax
.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
135 ax
.set_title('$\\sigma_\\mathrm{ext}$')
137 ax
= fig
.add_subplot(312)
138 ax
.pcolormesh(a
.theta
, ap
.allomegas
/eh
, σ_scat_arr
, vmin
=vmin
, vmax
=vmax
)
139 ax
.set_xlabel('$\\theta$')
140 ax
.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
141 ax
.set_title('$\\sigma_\\mathrm{scat}$')
143 ax
= fig
.add_subplot(313)
144 im
= ax
.pcolormesh(a
.theta
, ap
.allomegas
/eh
, σ_abs_arr
, vmin
=vmin
, vmax
=vmax
)
145 ax
.set_xlabel('$\\theta$')
146 ax
.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
147 ax
.set_title('$\\sigma_\\mathrm{abs}$')
150 fig
.subplots_adjust(right
=0.8)
151 fig
.colorbar(im
, cax
= fig
.add_axes([0.85, 0.15, 0.05, 0.7]))
156 if len(ap
.omega_ranges
) != 0:
157 # "k-space" plot -----------------------------
158 domega
= np
.amin(np
.diff(ap
.allomegas
))
159 dsintheta
= np
.amin(abs(np
.diff(sintheta
)))
160 dk
= dsintheta
* wavenumbers
[0]
163 grid_y
, grid_x
= np
.mgrid
[ap
.allomegas
[0] : ap
.allomegas
[-1] : domega
, np
.amin(sintheta
) * wavenumbers
[-1] : np
.amax(sintheta
) * wavenumbers
[-1] : dk
]
164 imextent
= (np
.amin(sintheta
) * wavenumbers
[-1] / 1e6
, np
.amax(sintheta
) * wavenumbers
[-1] / 1e6
, ap
.allomegas
[0] / eh
, ap
.allomegas
[-1] / eh
)
166 # source coordinates for griddata
167 ktheta
= sintheta
[None, :] * wavenumbers
[:, None]
168 omegapoints
= np
.broadcast_to(ap
.allomegas
[:, None], ktheta
.shape
)
169 points
= np
.stack( (ktheta
.flatten(), omegapoints
.flatten()), axis
= -1)
171 fig
= plt
.figure(figsize
=(210/25.4, 297/25.4))
172 vmax
= np
.amax(σ_ext_arr
)
174 ax
= fig
.add_subplot(311)
175 grid_z
= griddata(points
, σ_ext_arr
.flatten(), (grid_x
, grid_y
), method
= ipm
)
176 ax
.imshow(grid_z
, extent
= imextent
, origin
= 'lower', vmin
= 0, vmax
= vmax
, aspect
= 'auto', interpolation
='none')
177 ax
.set_xlabel('$k_\\theta / \\mathrm{\\mu m^{-1}}$')
178 ax
.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
179 ax
.set_title('$\\sigma_\\mathrm{ext}$')
181 ax
= fig
.add_subplot(312)
182 grid_z
= griddata(points
, σ_scat_arr
.flatten(), (grid_x
, grid_y
), method
= ipm
)
183 ax
.imshow(grid_z
, extent
= imextent
, origin
= 'lower', vmin
= 0, vmax
= vmax
, aspect
= 'auto', interpolation
='none')
184 ax
.set_xlabel('$k_\\theta / \\mathrm{\\mu m^{-1}}$')
185 ax
.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
186 ax
.set_title('$\\sigma_\\mathrm{scat}$')
188 ax
= fig
.add_subplot(313)
189 grid_z
= griddata(points
, σ_abs_arr
.flatten(), (grid_x
, grid_y
), method
= ipm
)
190 im
= ax
.imshow(grid_z
, extent
= imextent
, origin
= 'lower', vmin
= 0, vmax
= vmax
, aspect
= 'auto', interpolation
='none')
191 ax
.set_xlabel('$k_\\theta / \\mathrm{\\mu m^{-1}}$')
192 ax
.set_ylabel('$\\hbar\\omega / \\mathrm{eV}$')
193 ax
.set_title('$\\sigma_\\mathrm{abs}$')
195 fig
.subplots_adjust(right
=0.8)
196 fig
.colorbar(im
, cax
= fig
.add_axes([0.85, 0.15, 0.05, 0.7]))
201 for omega
in ap
.omega_singles
:
202 i
= np
.searchsorted(ap
.allomegas
, omega
)
205 fig
.suptitle("%g eV" % (omega
/ eh
))
206 ax
= fig
.add_subplot(111)
207 sintheta
= np
.sin(a
.theta
)
208 ax
.plot(sintheta
, σ_ext_arr
[i
]*1e12
,label
='$\sigma_\mathrm{ext}$')
209 ax
.plot(sintheta
, σ_scat_arr
[i
]*1e12
, label
='$\sigma_\mathrm{scat}$')
210 ax
.plot(sintheta
, σ_abs_arr
[i
]*1e12
, label
='$\sigma_\mathrm{abs}$')
212 ax
.set_xlabel('$\sin\\theta$')
213 ax
.set_ylabel('$\sigma/\mathrm{\mu m^2}$')
217 annotate_pdf_metadata(pdf
)