4 from qpms
.argproc
import ArgParser
7 ap
= ArgParser(['rectlattice2d_finite', 'single_particle', 'single_lMax', ])
9 ap
.add_argument("-t", "--rank-tolerance", type=float, default
=1e11
)
10 ap
.add_argument("-c", "--min-candidates", type=int, default
=1, help='always try at least this many eigenvalue candidates, even if their SVs in the rank tests are lower than rank_tolerance')
11 ap
.add_argument("-T", "--residual-tolerance", type=float, default
=0.)
13 ap
.add_argument("-o", "--output", type=str, required
=False, help='output path (if not provided, will be generated automatically)')
14 #ap.add_argument("-O", "--plot-out", type=str, required=False, help="path to plot output (optional)")
15 #ap.add_argument("-P", "--plot", action='store_true', help="if -p not given, plot to a default path")
16 #ap.add_argument("-g", "--save-gradually", action='store_true', help="saves the partial result after computing each irrep")
18 ap
.add_argument("-f", "--centre", type=complex, required
=True, help='Contour centre in eV')
19 ap
.add_argument("--ai", type=float, default
=0.05, help="Contour imaginary half-axis in eV")
20 ap
.add_argument("--ar", type=float, default
=0.05, help="Contour real half-axis in eV")
21 ap
.add_argument("-N", type=int, default
="150", help="Integration contour discretisation size")
23 ap
.add_argument("--irrep", type=str, default
="none", help="Irrep subspace (irrep index from 0 to 7, irrep label, or 'none' for no irrep decomposition")
28 logging
.basicConfig(format
='%(asctime)s %(message)s', level
=logging
.INFO
)
33 particlestr
= ("sph" if a
.height
is None else "cyl") + ("_r%gnm" % (a
.radius
*1e9
))
34 if a
.height
is not None: particlestr
+= "_h%gnm" % (a
.height
* 1e9
)
35 defaultprefix
= "%s_p%gnmx%gnm_%dx%d_m%s_n%g_L%d_c(%s±%g±%gj)eV_cn%d" % (
36 particlestr
, px
*1e9
, py
*1e9
, Nx
, Ny
, str(a
.material
), a
.refractive_index
, a
.lMax
,
37 str(a
.centre
), a
.ai
, a
.ar
, a
.N
)
38 logging
.info("Default file prefix: %s" % defaultprefix
)
40 def inside_ellipse(point_xy
, centre_xy
, halfaxes_xy
):
41 x
= point_xy
[0] - centre_xy
[0]
42 y
= point_xy
[1] - centre_xy
[1]
45 return ((x
/ax
)**2 + (y
/ay
)**2) <= 1
50 from qpms
.cybspec
import BaseSpec
51 from qpms
.cytmatrices
import CTMatrix
, TMatrixGenerator
52 from qpms
.qpms_c
import Particle
53 from qpms
.cymaterials
import EpsMu
, EpsMuGenerator
, LorentzDrudeModel
, lorentz_drude
54 from qpms
.cycommon
import DebugFlags
, dbgmsg_enable
55 from qpms
import FinitePointGroup
, ScatteringSystem
, BesselType
, eV
, hbar
56 from qpms
.symmetries
import point_group_info
59 dbgmsg_enable(DebugFlags
.INTEGRATION
)
62 orig_x
= (np
.arange(Nx
/2) + (0 if (Nx
% 2) else .5)) * px
63 orig_y
= (np
.arange(Ny
/2) + (0 if (Ny
% 2) else .5)) * py
65 orig_xy
= np
.stack(np
.meshgrid(orig_x
, orig_y
), axis
= -1)
68 bspec
= BaseSpec(lMax
= a
.lMax
)
69 medium
= EpsMuGenerator(ap
.background_epsmu
)
70 particles
= [Particle(orig_xy
[i
], ap
.tmgen
, bspec
) for i
in np
.ndindex(orig_xy
.shape
[:-1])]
72 sym
= FinitePointGroup(point_group_info
['D2h'])
73 logging
.info("Creating scattering system object")
74 ss
, ssw
= ScatteringSystem
.create(particles
, medium
, sym
, a
.centre
* eh
)
77 iri
= None # no irrep decomposition
79 logging
.info("Not performing irrep decomposition and working with the full space of dimension %d." % ss
.fecv_size
)
84 iri
= ss
.irrep_names
.index(a
.irrep
)
85 irname
= ss
.irrep_names
[iri
]
86 logging
.info("Using irrep subspace %s (iri = %d) of dimension %d." % (irname
, iri
, ss
.saecv_sizes
[iri
]))
88 outfile_tmp
= defaultprefix
+ ".tmp" if a
.output
is None else a
.output
+ ".tmp"
90 logging
.info("Starting Beyn's algorithm")
91 results
= ss
.find_modes(iri
=iri
, omega_centre
= a
.centre
*eh
, omega_rr
=a
.ar
*eh
, omega_ri
=a
.ai
*eh
, contour_points
=a
.N
,
92 rank_tol
=a
.rank_tolerance
, rank_min_sel
=a
.min_candidates
, res_tol
=a
.residual_tolerance
)
93 results
['inside_contour'] = inside_ellipse((results
['eigval'].real
, results
['eigval'].imag
),
94 (a
.centre
.real
*eh
, a
.centre
.imag
*eh
), (a
.ar
*eh
, a
.ai
*eh
))
95 results
['refractive_index_internal'] = [medium(om
).n
for om
in results
['eigval']]
97 outfile
= defaultprefix
+ (('_ir%s_%s.npz' % (str(iri
), irname
)) if iri
is not None else '.npz') if a
.output
is None else a
.output
98 np
.savez(outfile
, meta
=vars(a
), **results
)
99 logging
.info("Saved to %s" % outfile
)
104 if a
.plot
or (a
.plot_out
is not None):
106 matplotlib
.use('pdf')
107 from matplotlib
import pyplot
as plt
110 ax
= fig
.add_subplot(111)
111 ax
.plot(sinalpha_list
, σ_ext
*1e12
,label
='$\sigma_\mathrm{ext}$')
112 ax
.plot(sinalpha_list
, σ_scat
*1e12
, label
='$\sigma_\mathrm{scat}$')
113 ax
.plot(sinalpha_list
, σ_abs
*1e12
, label
='$\sigma_\mathrm{abs}$')
115 ax
.set_xlabel('$\sin\\alpha$')
116 ax
.set_ylabel('$\sigma/\mathrm{\mu m^2}$')
118 plotfile
= defaultprefix
+ ".pdf" if a
.plot_out
is None else a
.plot_out
119 fig
.savefig(plotfile
)