PLaSK library
Loading...
Searching...
No Matches
expansioncyl-fini.cpp
Go to the documentation of this file.
1
/*
2
* This file is part of PLaSK (https://plask.app) by Photonics Group at TUL
3
* Copyright (c) 2022 Lodz University of Technology
4
*
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, version 3.
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*/
14
#include "
expansioncyl-fini.hpp
"
15
#include "
solvercyl.hpp
"
16
#include "
zeros-data.hpp
"
17
18
#include "../gauss_legendre.hpp"
19
20
#include "
besselj.hpp
"
21
22
#define SOLVER static_cast<BesselSolverCyl*>(solver)
23
24
namespace
plask
{
namespace
optical {
namespace
modal {
25
26
ExpansionBesselFini::ExpansionBesselFini
(
BesselSolverCyl
* solver) :
ExpansionBessel
(solver) {}
27
28
void
ExpansionBesselFini::computeBesselZeros
() {
29
size_t
N
=
SOLVER
->size;
30
size_t
n
= 0;
31
kpts
.resize(
N
);
32
if
(
m
< 5) {
33
n
=
min
(
N
,
size_t
(100));
34
std::copy_n(
bessel_zeros
[
m
],
n
,
kpts
.begin());
35
}
36
if
(
n
<
N
) {
37
SOLVER
->writelog(
LOG_DEBUG
,
"Computing Bessel function J_({:d}) zeros {:d} to {:d}"
,
m
,
n
+ 1,
N
);
38
PLASK_NO_CONVERSION_WARNING_BEGIN
39
cyl_bessel_j_zero(
double
(
m
),
n
+1,
N
-
n
,
kpts
.begin()+
n
);
40
PLASK_NO_WARNING_END
41
}
42
// #ifndef NDEBUG
43
// for (size_t i = 0; i != N; ++i) {
44
// auto report = [i,m,this]()->bool{
45
// std::cerr << "J(" << m << ", " << kpts[i] << ") = " << cyl_bessel_j(m, kpts[i]) << "\n";
46
// return false;
47
// };
48
// assert(is_zero(cyl_bessel_j(m, kpts[i]), 1e-9) || report());
49
// }
50
// #endif
51
}
52
53
void
ExpansionBesselFini::init2
() {
54
SOLVER
->writelog(
LOG_DETAIL
,
"Preparing Bessel functions for m = {}"
,
m
);
55
computeBesselZeros
();
56
57
init3
();
58
59
// Compute integrals for permeability
60
auto
raxis
=
mesh
->tran();
61
62
size_t
nr =
raxis
->size(),
N
=
SOLVER
->size;
63
64
double
ib
= 1. /
rbounds
[
rbounds
.
size
() - 1];
65
66
// Compute mu integrals
67
if
(
SOLVER
->pml.size > 0. &&
SOLVER
->pml.factor != 1.) {
68
69
SOLVER
->writelog(
LOG_DETAIL
,
"Computing permeability integrals with {} rule"
,
SOLVER
->ruleName());
70
71
size_t
pmlseg
=
segments
.
size
() - 1;
72
73
size_t
pmli
=
raxis
->size() -
segments
[
pmlseg
].weights.size();
74
double
pmlr
=
rbounds
[
pmlseg
];
75
76
aligned_unique_ptr<dcomplex>
mu_data
(
aligned_malloc<dcomplex>
(nr));
77
aligned_unique_ptr<dcomplex>
imu_data
(
aligned_malloc<dcomplex>
(nr));
78
79
for
(
size_t
ri
= 0,
wi
= 0,
seg
= 0, nw =
segments
[0].weights.size();
ri
!= nr; ++
ri
, ++
wi
) {
80
if
(
wi
== nw) {
81
nw =
segments
[++
seg
].weights.size();
82
wi
= 0;
83
}
84
double
r =
raxis
->at(
ri
);
85
double
w =
segments
[
seg
].weights[
wi
] *
segments
[
seg
].D;
86
87
dcomplex
mu
= 1.,
imu
= 1.;
88
if
(
ri
>=
pmli
) {
89
mu
= 1. + (
SOLVER
->pml.factor - 1.) * pow((r -
pmlr
) /
SOLVER
->pml.size,
SOLVER
->pml.order);
90
imu
= 1. /
mu
;
91
}
92
93
mu_data
.get()[
ri
] =
mu
* w;
94
imu_data
.get()[
ri
] =
imu
* w;
95
}
96
97
switch
(
SOLVER
->rule) {
98
case
BesselSolverCyl::RULE_COMBINED_1
:
99
case
BesselSolverCyl::RULE_COMBINED_2
:
100
integrateParams
(
mu_integrals
,
mu_data
.get(),
mu_data
.get(),
mu_data
.get(), 1., 1., 1.);
break
;
101
case
BesselSolverCyl::RULE_DIRECT
:
102
integrateParams
(
mu_integrals
,
mu_data
.get(),
imu_data
.get(),
mu_data
.get(), 1., 1., 1.);
break
;
103
case
BesselSolverCyl::RULE_OLD
:
104
integrateParams
(
mu_integrals
,
mu_data
.get(),
imu_data
.get(),
imu_data
.get(), 1., 1., 1.);
break
;
105
}
106
107
}
else
{
108
109
mu_integrals
.
reset
(
N
);
110
zero_matrix
(
mu_integrals
.
V_k
);
111
zero_matrix
(
mu_integrals
.
Tss
);
112
zero_matrix
(
mu_integrals
.
Tsp
);
113
zero_matrix
(
mu_integrals
.
Tps
);
114
zero_matrix
(
mu_integrals
.
Tpp
);
115
for
(
size_t
i = 0; i <
N
; ++i) {
116
double
k =
kpts
[i] *
ib
;
117
mu_integrals
.
V_k
(i,i) = k;
118
mu_integrals
.
Tss
(i,i) =
mu_integrals
.
Tpp
(i,i) = 2.;
119
}
120
}
121
}
122
123
void
ExpansionBesselFini::reset
() {
124
mu_integrals
.
reset
();
125
ExpansionBessel::reset
();
126
}
127
128
void
ExpansionBesselFini::getMatrices
(
size_t
layer,
cmatrix
&
RE
,
cmatrix
&
RH
) {
129
assert
(
initialized
);
130
if
(
isnan
(
k0
))
throw
BadInput
(
SOLVER
->getId(),
"wavelength or k0 not set"
);
131
if
(
isinf
(
k0
.real()))
throw
BadInput
(
SOLVER
->getId(),
"wavelength must not be 0"
);
132
133
size_t
N
=
SOLVER
->size;
134
dcomplex
ik0
= 1. /
k0
;
135
double
ib
= 1. /
rbounds
[
rbounds
.
size
() - 1];
136
137
const
Integrals
& eps =
layers_integrals
[layer];
138
#define mu mu_integrals
139
140
for
(
size_t
j = 0; j !=
N
; ++j) {
141
size_t
js =
idxs
(j),
jp
=
idxp
(j);
142
// double k = kpts[j] * ib;
143
for
(
size_t
i = 0; i !=
N
; ++i) {
144
size_t
is
=
idxs
(i),
ip
=
idxp
(i);
145
double
g =
kpts
[i] *
ib
;
146
dcomplex
gVk
=
ik0
* g * eps.V_k(i,j);
147
RH
(
is
,
jp
) = 0.5 * (
gVk
-
k0
*
mu
.Tsp(i,j) );
148
RH
(
is
,js) = 0.5 * (
gVk
-
k0
*
mu
.Tss(i,j) );
149
RH
(
ip
,
jp
) = 0.5 * ( -
gVk
+
k0
*
mu
.Tpp(i,j) );
150
RH
(
ip
,js) = 0.5 * ( -
gVk
+
k0
*
mu
.Tps(i,j) );
151
}
152
}
153
154
for
(
size_t
j = 0; j !=
N
; ++j) {
155
size_t
js =
idxs
(j),
jp
=
idxp
(j);
156
// double k = kpts[j] * ib;
157
for
(
size_t
i = 0; i !=
N
; ++i) {
158
size_t
is
=
idxs
(i),
ip
=
idxp
(i);
159
double
g =
kpts
[i] *
ib
;
160
dcomplex
gVk
=
ik0
* g *
mu
.V_k(i,j);
161
RE
(
ip
,js) = 0.5 * ( -
gVk
+
k0
* eps.Tps(i,j) );
162
RE
(
ip
,
jp
) = 0.5 * ( -
gVk
+
k0
* eps.Tpp(i,j) );
163
RE
(
is
,js) = 0.5 * (
gVk
-
k0
* eps.Tss(i,j) );
164
RE
(
is
,
jp
) = 0.5 * (
gVk
-
k0
* eps.Tsp(i,j) );
165
}
166
}
167
#undef mu
168
}
169
170
double
ExpansionBesselFini::fieldFactor
(
size_t
i) {
171
double
eta
= cyl_bessel_j(
m
+ 1,
kpts
[i]) *
rbounds
[
rbounds
.
size
() - 1];
172
return
0.5 *
eta
*
eta
;
173
}
174
175
176
#ifndef NDEBUG
177
cmatrix
ExpansionBesselFini::muV_k
() {
178
size_t
N
=
SOLVER
->size;
179
cmatrix
result
(
N
,
N
, 0.);
180
for
(
size_t
i = 0; i !=
N
; ++i)
181
for
(
size_t
j = 0; j !=
N
; ++j)
182
result
(i,j) =
mu_integrals
.
V_k
(i,j);
183
return
result
;
184
}
185
cmatrix
ExpansionBesselFini::muTss
() {
186
size_t
N
=
SOLVER
->size;
187
cmatrix
result
(
N
,
N
, 0.);
188
for
(
size_t
i = 0; i !=
N
; ++i)
189
for
(
size_t
j = 0; j !=
N
; ++j)
190
result
(i,j) =
mu_integrals
.
Tss
(i,j);
191
return
result
;
192
}
193
cmatrix
ExpansionBesselFini::muTsp
() {
194
size_t
N
=
SOLVER
->size;
195
cmatrix
result
(
N
,
N
, 0.);
196
for
(
size_t
i = 0; i !=
N
; ++i)
197
for
(
size_t
j = 0; j !=
N
; ++j)
198
result
(i,j) =
mu_integrals
.
Tsp
(i,j);
199
return
result
;
200
}
201
cmatrix
ExpansionBesselFini::muTps
() {
202
size_t
N
=
SOLVER
->size;
203
cmatrix
result
(
N
,
N
, 0.);
204
for
(
size_t
i = 0; i !=
N
; ++i)
205
for
(
size_t
j = 0; j !=
N
; ++j)
206
result
(i,j) =
mu_integrals
.
Tps
(i,j);
207
return
result
;
208
}
209
cmatrix
ExpansionBesselFini::muTpp
() {
210
size_t
N
=
SOLVER
->size;
211
cmatrix
result
(
N
,
N
, 0.);
212
for
(
size_t
i = 0; i !=
N
; ++i)
213
for
(
size_t
j = 0; j !=
N
; ++j)
214
result
(i,j) =
mu_integrals
.
Tpp
(i,j);
215
return
result
;
216
}
217
#endif
218
219
void
ExpansionBesselFini::integrateParams
(
Integrals
&
integrals
,
220
const
dcomplex*
datap
,
const
dcomplex*
datar
,
const
dcomplex*
dataz
,
221
dcomplex
datap0
, dcomplex
datar0
, dcomplex
dataz0
) {
222
auto
raxis
=
mesh
->tran();
223
224
size_t
nr =
raxis
->size(),
N
=
SOLVER
->size;
225
double
R =
rbounds
[
rbounds
.
size
()-1];
226
double
ib
= 1. / R;
227
double
*
factors
;
// scale factors for making matrices orthonormal
228
229
integrals
.reset(
N
);
230
231
TempMatrix
temp
=
getTempMatrix
();
232
aligned_unique_ptr<double>
_tmp
;
233
234
cmatrix
JmJp
,
JpJm
;
235
if
(
N
< 2) {
236
_tmp
.
reset
(
aligned_malloc<double>
(4*
N
));
237
factors
=
_tmp
.get();
238
}
else
if
(
SOLVER
->rule ==
BesselSolverCyl::RULE_COMBINED_1
) {
239
factors
=
reinterpret_cast<
double
*
>
(
integrals
.V_k.data());
240
}
else
if
(
SOLVER
->rule ==
BesselSolverCyl::RULE_COMBINED_2
) {
241
_tmp
.reset(
aligned_malloc<double>
(3*
N
+ 4*
N
*
N
));
242
JmJp
.reset(
N
,
N
,
integrals
.V_k.data());
243
JpJm
.reset(
N
,
N
,
reinterpret_cast<
dcomplex*
>
(
_tmp
.get() + 3*
N
));
244
factors
=
_tmp
.get();
245
}
else
{
246
factors
=
reinterpret_cast<
double
*
>
(
temp
.data());
247
}
248
for
(
size_t
i = 0; i <
N
; ++i) {
249
double
fact
= R * cyl_bessel_j(
m
+1,
kpts
[i]);
250
factors
[i] = 2. / (
fact
*
fact
);
251
}
252
double
*
Jm
=
factors
+
N
;
253
double
*
Jp
=
factors
+ 2*
N
;
254
255
if
(
SOLVER
->rule ==
BesselSolverCyl::RULE_OLD
) {
256
257
double
* J =
factors
+ 3*
N
;
258
259
zero_matrix
(
integrals
.V_k);
260
zero_matrix
(
integrals
.Tss);
261
zero_matrix
(
integrals
.Tsp);
262
zero_matrix
(
integrals
.Tps);
263
zero_matrix
(
integrals
.Tpp);
264
265
for
(
size_t
ri
= 0;
ri
!= nr; ++
ri
) {
266
double
r =
raxis
->at(
ri
);
267
dcomplex
repst
= r * (
datar
[
ri
] +
datap
[
ri
]),
repsd
= r * (
datar
[
ri
] -
datap
[
ri
]);
268
const
dcomplex
riepsz
= r *
dataz
[
ri
];
269
270
for
(
size_t
i = 0; i <
N
; ++i) {
271
double
kr
=
kpts
[i] *
ib
* r;
272
Jm
[i] = cyl_bessel_j(
m
-1,
kr
);
273
J[i] = cyl_bessel_j(
m
,
kr
);
274
Jp
[i] = cyl_bessel_j(
m
+1,
kr
);
275
}
276
for
(
size_t
j = 0; j <
N
; ++j) {
277
double
k =
kpts
[j] *
ib
;
278
double
Jk
= J[j],
Jmk
=
Jm
[j],
Jpk
=
Jp
[j];
279
for
(
size_t
i = 0; i <
N
; ++i) {
280
double
Jg
= J[i],
Jmg
=
Jm
[i],
Jpg
=
Jp
[i];
281
integrals
.V_k(i,j) +=
Jg
*
riepsz
*
Jk
* k *
factors
[i];
282
integrals
.Tss(i,j) +=
Jmg
*
repst
*
Jmk
*
factors
[i];
283
integrals
.Tsp(i,j) +=
Jmg
*
repsd
*
Jpk
*
factors
[i];
284
integrals
.Tps(i,j) +=
Jpg
*
repsd
*
Jmk
*
factors
[i];
285
integrals
.Tpp(i,j) +=
Jpg
*
repst
*
Jpk
*
factors
[i];
286
}
287
}
288
}
289
290
}
else
{
291
292
if
(
SOLVER
->rule ==
BesselSolverCyl::RULE_DIRECT
) {
293
294
zero_matrix
(
integrals
.Tss);
295
zero_matrix
(
integrals
.Tsp);
296
zero_matrix
(
integrals
.Tps);
297
zero_matrix
(
integrals
.Tpp);
298
299
for
(
size_t
ri
= 0;
ri
!= nr; ++
ri
) {
300
double
r =
raxis
->at(
ri
);
301
dcomplex
repst
= r * (
datar
[
ri
] +
datap
[
ri
]),
repsd
= r * (
datar
[
ri
] -
datap
[
ri
]);
302
for
(
size_t
i = 0; i <
N
; ++i) {
303
double
kr
=
kpts
[i] *
ib
* r;
304
Jm
[i] = cyl_bessel_j(
m
-1,
kr
);
305
Jp
[i] = cyl_bessel_j(
m
+1,
kr
);
306
}
307
for
(
size_t
i = 0; i <
N
; ++i) {
308
dcomplex cs =
factors
[i] *
repst
,
cd
=
factors
[i] *
repsd
;
309
for
(
size_t
j = 0; j <
N
; ++j) {
310
integrals
.Tss(i,j) += cs *
Jm
[i] *
Jm
[j];
311
integrals
.Tsp(i,j) +=
cd
*
Jm
[i] *
Jp
[j];
312
integrals
.Tps(i,j) +=
cd
*
Jp
[i] *
Jm
[j];
313
integrals
.Tpp(i,j) += cs *
Jp
[i] *
Jp
[j];
314
}
315
}
316
}
317
318
}
else
{
319
320
if
(
SOLVER
->rule ==
BesselSolverCyl::RULE_COMBINED_1
) {
321
322
cmatrix
workess
(
N
,
N
,
temp
.data()),
workepp
(
N
,
N
,
temp
.data()+
N
*
N
),
323
worksp
(
N
,
N
,
temp
.data()+2*
N
*
N
),
workps
(
N
,
N
,
temp
.data()+3*
N
*
N
);
324
325
zero_matrix
(
workess
);
326
zero_matrix
(
workepp
);
327
zero_matrix
(
worksp
);
328
zero_matrix
(
workps
);
329
330
for
(
size_t
ri
= 0,
wi
= 0,
seg
= 0, nw =
segments
[0].weights.size();
ri
!= nr; ++
ri
, ++
wi
) {
331
if
(
wi
== nw) {
332
nw =
segments
[++
seg
].weights.size();
333
wi
= 0;
334
}
335
double
r =
raxis
->at(
ri
);
336
double
rw
= r *
segments
[
seg
].weights[
wi
] *
segments
[
seg
].D;
337
dcomplex
riepsr
= r *
datar
[
ri
];
338
for
(
size_t
i = 0; i <
N
; ++i) {
339
double
kr
=
kpts
[i] *
ib
* r;
340
Jm
[i] = cyl_bessel_j(
m
-1,
kr
);
341
Jp
[i] = cyl_bessel_j(
m
+1,
kr
);
342
}
343
for
(
size_t
i = 0; i <
N
; ++i) {
344
double
cw
=
factors
[i] *
rw
;
345
dcomplex
ce
=
factors
[i] *
riepsr
;
346
for
(
size_t
j = 0; j <
N
; ++j) {
347
workess
(i,j) +=
ce
*
Jm
[i] *
Jm
[j];
348
workepp
(i,j) +=
ce
*
Jp
[i] *
Jp
[j];
349
worksp
(i,j) +=
cw
*
Jm
[i] *
Jp
[j];
350
workps
(i,j) +=
cw
*
Jp
[i] *
Jm
[j];
351
}
352
}
353
}
354
make_unit_matrix
(
integrals
.Tss);
355
make_unit_matrix
(
integrals
.Tpp);
356
357
invmult
(
workess
,
integrals
.Tss);
358
invmult
(
workepp
,
integrals
.Tpp);
359
360
mult_matrix_by_matrix
(
integrals
.Tss,
worksp
,
integrals
.Tsp);
361
mult_matrix_by_matrix
(
integrals
.Tpp,
workps
,
integrals
.Tps);
362
363
if
(
N
> 2) {
364
std::copy_n(
factors
,
N
,
reinterpret_cast<
double
*
>
(
temp
.data()));
365
factors
=
reinterpret_cast<
double
*
>
(
temp
.data());
366
Jm
=
factors
+
N
;
Jp
=
factors
+ 2*
N
;
367
}
368
369
}
else
{
// if (SOLVER->rule == BesselSolverCyl::RULE_COMBINED_2)
370
371
cmatrix
work
(
temp
);
372
373
zero_matrix
(
integrals
.TT);
374
zero_matrix
(
work
);
375
zero_matrix
(
JmJp
);
376
zero_matrix
(
JpJm
);
377
378
for
(
size_t
ri
= 0,
wi
= 0,
seg
= 0, nw =
segments
[0].weights.size();
ri
!= nr; ++
ri
, ++
wi
) {
379
if
(
wi
== nw) {
380
nw =
segments
[++
seg
].weights.size();
381
wi
= 0;
382
}
383
double
r =
raxis
->at(
ri
);
384
double
rw
= r *
segments
[
seg
].weights[
wi
] *
segments
[
seg
].D;
385
dcomplex
riepsr
= r *
datar
[
ri
];
386
for
(
size_t
i = 0; i <
N
; ++i) {
387
double
kr
=
kpts
[i] *
ib
* r;
388
Jm
[i] = cyl_bessel_j(
m
-1,
kr
);
389
Jp
[i] = cyl_bessel_j(
m
+1,
kr
);
390
}
391
for
(
size_t
j = 0; j <
N
; ++j) {
392
for
(
size_t
i = 0; i <
N
; ++i) {
393
dcomplex
ce
=
riepsr
*
factors
[i];
394
double
cw
=
rw
*
factors
[i];
395
integrals
.TT(i,j) +=
ce
*
Jm
[i] *
Jm
[j];
396
integrals
.TT(i,j+
N
) +=
ce
*
Jm
[i] *
Jp
[j];
397
integrals
.TT(i+
N
,j) +=
ce
*
Jp
[i] *
Jm
[j];
398
integrals
.TT(i+
N
,j+
N
) +=
ce
*
Jp
[i] *
Jp
[j];
399
double
mp
=
cw
*
Jm
[i] *
Jp
[j];
400
double
pm
=
cw
*
Jp
[i] *
Jm
[j];
401
work
(i,j+
N
) +=
mp
;
402
work
(i+
N
,j) +=
pm
;
403
JmJp
(i,j) +=
mp
;
404
JpJm
(i,j) +=
pm
;
405
}
406
}
407
}
408
for
(
size_t
i = 0; i <
N
; ++i)
work
(i,i) = 1.;
409
for
(
size_t
i = 0; i <
N
; ++i)
work
(i+
N
,i+
N
) = 1.;
410
411
invmult
(
integrals
.TT,
work
);
412
413
for
(
size_t
j = 0; j <
N
; ++j) {
414
for
(
size_t
i = 0; i <
N
; ++i)
integrals
.Tss(i,j) =
work
(i,j);
415
for
(
size_t
i = 0; i <
N
; ++i)
integrals
.Tps(i,j) =
work
(i+
N
,j);
416
}
417
for
(
size_t
j = 0; j <
N
; ++j) {
418
for
(
size_t
i = 0; i <
N
; ++i)
integrals
.Tsp(i,j) =
work
(i,j+
N
);
419
for
(
size_t
i = 0; i <
N
; ++i)
integrals
.Tpp(i,j) =
work
(i+
N
,j+
N
);
420
}
421
422
zgemm
(
'N'
,
'N'
,
int
(
N
),
int
(
N
),
int
(
N
), 1.,
JpJm
.data(),
int
(
N
),
work
.data()+2*
N
*
N
,
int
(2*
N
), 1.,
423
integrals
.Tpp.data(),
int
(
N
));
424
zgemm
(
'N'
,
'N'
,
int
(
N
),
int
(
N
),
int
(
N
), 1.,
JmJp
.data(),
int
(
N
),
work
.data()+
N
,
int
(2*
N
), 1.,
425
integrals
.Tss.data(),
int
(
N
));
426
zgemm
(
'N'
,
'N'
,
int
(
N
),
int
(
N
),
int
(
N
), 1.,
JpJm
.data(),
int
(
N
),
work
.data(),
int
(2*
N
), 1.,
427
integrals
.Tps.data(),
int
(
N
));
428
zgemm
(
'N'
,
'N'
,
int
(
N
),
int
(
N
),
int
(
N
), 1.,
JmJp
.data(),
int
(
N
),
work
.data()+2*
N
*
N
+
N
,
int
(2*
N
), 1.,
429
integrals
.Tsp.data(),
int
(
N
));
430
}
431
432
for
(
size_t
ri
= 0;
ri
!= nr; ++
ri
) {
433
double
r =
raxis
->at(
ri
);
434
dcomplex
repsp
= r *
datap
[
ri
];
435
for
(
size_t
i = 0; i <
N
; ++i) {
436
double
kr
=
kpts
[i] *
ib
* r;
437
Jm
[i] = cyl_bessel_j(
m
-1,
kr
);
438
Jp
[i] = cyl_bessel_j(
m
+1,
kr
);
439
}
440
for
(
size_t
i = 0; i <
N
; ++i) {
441
dcomplex c =
repsp
*
factors
[i];
442
for
(
size_t
j = 0; j <
N
; ++j) {
443
integrals
.Tss(i,j) += c *
Jm
[i] *
Jm
[j];
444
integrals
.Tsp(i,j) -= c *
Jm
[i] *
Jp
[j];
445
integrals
.Tps(i,j) -= c *
Jp
[i] *
Jm
[j];
446
integrals
.Tpp(i,j) += c *
Jp
[i] *
Jp
[j];
447
}
448
}
449
}
450
}
451
452
cmatrix
work
(
N
,
N
,
temp
.data()+
N
*
N
);
453
454
zero_matrix
(
work
);
455
double
* J =
Jm
;
456
457
for
(
size_t
ri
= 0;
ri
!= nr; ++
ri
) {
458
double
r =
raxis
->at(
ri
);
459
dcomplex
repsz
= r *
dataz
[
ri
];
460
for
(
size_t
i = 0; i <
N
; ++i) {
461
double
kr
=
kpts
[i] *
ib
* r;
462
J[i] = cyl_bessel_j(
m
,
kr
);
463
}
464
for
(
size_t
j = 0; j <
N
; ++j) {
465
for
(
size_t
i = 0; i <
N
; ++i) {
466
work
(i,j) +=
repsz
*
factors
[i] * J[i] * J[j];
467
}
468
}
469
}
470
471
// make_unit_matrix(integrals.V_k);
472
zero_matrix
(
integrals
.V_k);
473
for
(
int
i = 0; i <
N
; ++i) {
474
double
k =
kpts
[i] *
ib
;
475
integrals
.V_k(i,i) = k;
476
}
477
invmult
(
work
,
integrals
.V_k);
478
// for (size_t i = 0; i < N; ++i) {
479
// double g = kpts[i] * ib;
480
// for (size_t j = 0; j < N; ++j) integrals.V_k(i,j) *= g;
481
// }
482
483
}
484
}
485
486
}}}
// namespace plask::optical::modal
solvers
optical
modal
bessel
expansioncyl-fini.cpp
Generated by
1.9.8