4 from qpms
.argproc
import ArgParser
7 ap
= ArgParser(['rectlattice2d_finite', 'single_particle', 'single_lMax', 'single_omega'])
8 ap
.add_argument("-k", '--kx-lim', nargs
=2, type=float, required
=True, help='k vector', metavar
=('KX_MIN', 'KX_MAX'))
9 # ap.add_argument("--kpi", action='store_true', help="Indicates that the k vector is given in natural units instead of SI, i.e. the arguments given by -k shall be automatically multiplied by pi / period (given by -p argument)")
10 ap
.add_argument("-o", "--output", type=str, required
=False, help='output path (if not provided, will be generated automatically)')
11 ap
.add_argument("-N", type=int, default
="151", help="Number of angles")
12 ap
.add_argument("-O", "--plot-out", type=str, required
=False, help="path to plot output (optional)")
13 ap
.add_argument("-P", "--plot", action
='store_true', help="if -p not given, plot to a default path")
14 ap
.add_argument("-g", "--save-gradually", action
='store_true', help="saves the partial result after computing each irrep")
20 logging
.basicConfig(format
='%(asctime)s %(message)s', level
=logging
.INFO
)
25 particlestr
= ("sph" if a
.height
is None else "cyl") + ("_r%gnm" % (a
.radius
*1e9
))
26 if a
.height
is not None: particlestr
+= "_h%gnm" % (a
.height
* 1e9
)
27 defaultprefix
= "%s_p%gnmx%gnm_%dx%d_m%s_n%g_angles(%g_%g)_Ey_f%geV_L%d_cn%d" % (
28 particlestr
, px
*1e9
, py
*1e9
, Nx
, Ny
, str(a
.material
), a
.refractive_index
, a
.kx_lim
[0], a
.kx_lim
[1], a
.eV
, a
.lMax
, a
.N
)
29 logging
.info("Default file prefix: %s" % defaultprefix
)
34 from qpms
.cybspec
import BaseSpec
35 from qpms
.cytmatrices
import CTMatrix
, TMatrixGenerator
36 from qpms
.qpms_c
import Particle
37 from qpms
.cymaterials
import EpsMu
, EpsMuGenerator
, LorentzDrudeModel
, lorentz_drude
38 from qpms
.cycommon
import DebugFlags
, dbgmsg_enable
39 from qpms
import FinitePointGroup
, ScatteringSystem
, BesselType
, eV
, hbar
40 from qpms
.symmetries
import point_group_info
43 dbgmsg_enable(DebugFlags
.INTEGRATION
)
46 orig_x
= (np
.arange(Nx
/2) + (0 if (Nx
% 2) else .5)) * px
47 orig_y
= (np
.arange(Ny
/2) + (0 if (Ny
% 2) else .5)) * py
49 orig_xy
= np
.stack(np
.meshgrid(orig_x
, orig_y
), axis
= -1)
54 bspec
= BaseSpec(lMax
= a
.lMax
)
55 Tmatrix
= ap
.tmgen(bspec
, ap
.omega
)
56 particles
= [Particle(orig_xy
[i
], Tmatrix
) for i
in np
.ndindex(orig_xy
.shape
[:-1])]
58 sym
= FinitePointGroup(point_group_info
['D2h'])
59 ss
= ScatteringSystem(particles
, sym
)
61 wavenumber
= ap
.background_epsmu
.k(omega
).real
# Currently, ScatteringSystem does not "remember" frequency nor wavenumber
63 sinalpha_list
= np
.linspace(a
.kx_lim
[0],a
.kx_lim
[1],a
.N
)
66 E_cart_list
= np
.empty((a
.N
,3), dtype
=complex)
67 E_cart_list
[:,:] = np
.array((0,1,0))[None,:]
68 k_cart_list
= np
.empty((a
.N
,3), dtype
=float)
69 k_cart_list
[:,0] = sinalpha_list
71 k_cart_list
[:,2] = np
.sqrt(1-sinalpha_list
**2)
72 k_cart_list
*= wavenumber
74 σ_ext_list_ir
= np
.empty((a
.N
, ss
.nirreps
), dtype
=float)
75 σ_scat_list_ir
= np
.empty((a
.N
, ss
.nirreps
), dtype
=float)
77 outfile_tmp
= defaultprefix
+ ".tmp" if a
.output
is None else a
.output
+ ".tmp"
79 for iri
in range(ss
.nirreps
):
80 logging
.info("processing irrep %d/%d" % (iri
, ss
.nirreps
))
81 LU
= None # to trigger garbage collection before the next call
82 translation_matrix
= None
83 LU
= ss
.scatter_solver(wavenumber
,iri
)
84 logging
.info("LU solver created")
85 translation_matrix
= ss
.translation_matrix_packed(wavenumber
, iri
, BesselType
.REGULAR
) + np
.eye(ss
.saecv_sizes
[iri
])
86 logging
.info("auxillary translation matrix created")
89 # the following two could be calculated only once, but probably not a big deal
90 ã
= ss
.planewave_full(k_cart
=k_cart_list
[j
], E_cart
=E_cart_list
[j
])
91 Tã
= ss
.apply_Tmatrices_full(ã
)
93 Tãi
= ss
.pack_vector(Tã
, iri
)
94 ãi
= ss
.pack_vector(ã
, iri
)
96 σ_ext_list_ir
[j
, iri
] = -np
.vdot(ãi
, fi
).real
/wavenumber
**2
97 σ_scat_list_ir
[j
, iri
] = np
.vdot(fi
,np
.dot(translation_matrix
, fi
)).real
/wavenumber
**2
99 iriout
= outfile_tmp
+ ".%d" % iri
100 np
.savez(iriout
, iri
=iri
, meta
=vars(a
), sinalpha
=sinalpha_list
, k_cart
= k_cart_list
, E_cart
=E_cart_list
,
101 omega
=omega
, wavenumber
=wavenumber
, σ_ext_list_ir
=σ_ext_list_ir
[:,iri
], σ_scat_list_ir
=σ_scat_list_ir
[:,iri
])
102 logging
.info("partial results saved to %s"%iriout
)
104 σ_abs_list_ir
= σ_ext_list_ir
- σ_scat_list_ir
105 σ_abs
= np
.sum(σ_abs_list_ir
, axis
=-1)
106 σ_scat
= np
.sum(σ_scat_list_ir
, axis
=-1)
107 σ_ext
= np
.sum(σ_ext_list_ir
, axis
=-1)
110 outfile
= defaultprefix
+ ".npz" if a
.output
is None else a
.output
111 np
.savez(outfile
, meta
=vars(a
), sinalpha
=sinalpha_list
, k_cart
= k_cart_list
, E_cart
=E_cart_list
, σ_ext
=σ_ext
,σ_abs
=σ_abs
,σ_scat
=σ_scat
,
112 σ_ext_ir
=σ_ext_list_ir
,σ_abs_ir
=σ_abs_list_ir
,σ_scat_ir
=σ_scat_list_ir
, omega
=omega
, wavenumber
=wavenumber
114 logging
.info("Saved to %s" % outfile
)
117 if a
.plot
or (a
.plot_out
is not None):
119 matplotlib
.use('pdf')
120 from matplotlib
import pyplot
as plt
123 ax
= fig
.add_subplot(111)
124 ax
.plot(sinalpha_list
, σ_ext
*1e12
,label
='$\sigma_\mathrm{ext}$')
125 ax
.plot(sinalpha_list
, σ_scat
*1e12
, label
='$\sigma_\mathrm{scat}$')
126 ax
.plot(sinalpha_list
, σ_abs
*1e12
, label
='$\sigma_\mathrm{abs}$')
128 ax
.set_xlabel('$\sin\\alpha$')
129 ax
.set_ylabel('$\sigma/\mathrm{\mu m^2}$')
131 plotfile
= defaultprefix
+ ".pdf" if a
.plot_out
is None else a
.plot_out
132 fig
.savefig(plotfile
)