PLaSK library

Loading...
Searching...
No Matches
transfer.hpp
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#ifndef PLASK__SLAB_TRANSFER_H
15#define PLASK__SLAB_TRANSFER_H
16
17#include <plask/solver.hpp>
18
19#include "matrices.hpp"
20
21 namespace plask { namespace optical { namespace modal {
22
24 enum WhichField {
25 FIELD_E,
26 FIELD_H
27};
28
30 enum PropagationDirection {
31 PROPAGATION_TOTAL = 0,
32 PROPAGATION_UPWARDS = 1,
33 PROPAGATION_DOWNWARDS = 2
34};
35
36 using phys::Z0;
37
38 struct ModalBase;
39 struct Expansion;
40 class Diagonalizer;
41
45 struct PLASK_SOLVER_API Transfer {
47 enum IncidentDirection {
48 INCIDENCE_TOP,
49 INCIDENCE_BOTTOM
50 };
51
53 enum Determined {
54 DETERMINED_NOTHING = 0,
55 DETERMINED_RESONANT,
56 DETERMINED_REFLECTED
57 };
58
60 enum Method {
61 METHOD_AUTO,
62 METHOD_REFLECTION_ADMITTANCE,
63 METHOD_REFLECTION_IMPEDANCE,
64 METHOD_ADMITTANCE,
65 METHOD_IMPEDANCE,
66 };
67
69 enum Determinant {
70 DETERMINANT_EIGENVALUE,
71 DETERMINANT_FULL
72 };
73
74 protected:
75 cmatrix interface_field_matrix;
76 dcomplex* interface_field;
77
78 cmatrix M;
79
80 cmatrix temp;
81
82 dcomplex* evals;
83 double* rwrk;
84 std::size_t lwrk;
85 dcomplex* wrk;
86
87 cvector incident_vector;
88 IncidentDirection incident_side;
89
90 ModalBase* solver;
91
92 public:
94 void initDiagonalization();
95
97 std::unique_ptr<Diagonalizer> diagonalizer;
98
100 Determined fields_determined;
101
107 Transfer(ModalBase* solver, Expansion& expansion);
108
109 virtual ~Transfer();
110
112 dcomplex determinant();
113
119 virtual cvector getReflectionVector(const cvector& incident, IncidentDirection side) = 0;
120
126 virtual cvector getTransmissionVector(const cvector& incident, IncidentDirection side) = 0;
127
128 protected:
130 virtual void getFinalMatrix() = 0;
131
135 virtual void determineFields() = 0;
136
143 virtual void determineReflectedFields(const cvector& incident, IncidentDirection side) = 0;
144
152 virtual cvector getFieldVectorE(double z, std::size_t n, PropagationDirection part = PROPAGATION_TOTAL) = 0;
153
161 virtual cvector getFieldVectorH(double z, std::size_t n, PropagationDirection part = PROPAGATION_TOTAL) = 0;
162
167 const_cvector getInterfaceVector();
168
177 LazyData<Vec<3, dcomplex>> computeFieldE(double power,
178 const shared_ptr<const Mesh>& dst_mesh,
179 InterpolationMethod method,
180 bool reflected,
181 PropagationDirection part = PROPAGATION_TOTAL);
182
191 LazyData<Vec<3, dcomplex>> computeFieldH(double power,
192 const shared_ptr<const Mesh>& dst_mesh,
193 InterpolationMethod method,
194 bool reflected,
195 PropagationDirection part = PROPAGATION_TOTAL);
196
204 LazyData<double> computeFieldMagnitude(double power,
205 const shared_ptr<const Mesh>& dst_mesh,
206 InterpolationMethod method,
207 bool reflected) {
208 auto E = computeFieldE(1., dst_mesh, method, reflected);
209 power *= 0.5 / Z0; // because <M> = ½ E conj(E) / Z0
210 return LazyData<double>(E.size(), [power, E](size_t i) { return power * abs2(E[i]); });
211 }
212
221 virtual double integrateField(WhichField field,
222 size_t n,
223 double z1,
224 double z2) = 0;
225
226 public:
234 LazyData<Vec<3, dcomplex>> getFieldE(double power,
235 const shared_ptr<const Mesh>& dst_mesh,
236 InterpolationMethod method,
237 PropagationDirection part = PROPAGATION_TOTAL) {
238 determineFields();
239 return computeFieldE(power, dst_mesh, method, false, part);
240 }
241
249 LazyData<Vec<3, dcomplex>> getFieldH(double power,
250 const shared_ptr<const Mesh>& dst_mesh,
251 InterpolationMethod method,
252 PropagationDirection part = PROPAGATION_TOTAL) {
253 determineFields();
254 return computeFieldH(power, dst_mesh, method, false, part);
255 }
256
263 LazyData<double> getFieldMagnitude(double power,
264 const shared_ptr<const Mesh>& dst_mesh,
265 InterpolationMethod method) {
266 determineFields();
267 return computeFieldMagnitude(power, dst_mesh, method, false);
268 }
269
278 LazyData<Vec<3, dcomplex>> getScatteredFieldE(const cvector& incident,
279 IncidentDirection side,
280 const shared_ptr<const Mesh>& dst_mesh,
281 InterpolationMethod method,
282 PropagationDirection part = PROPAGATION_TOTAL) {
283 determineReflectedFields(incident, side);
284 return computeFieldE(1e3 * Z0, dst_mesh, method, true, part);
285 }
286
295 LazyData<Vec<3, dcomplex>> getScatteredFieldH(const cvector& incident,
296 IncidentDirection side,
297 const shared_ptr<const Mesh>& dst_mesh,
298 InterpolationMethod method,
299 PropagationDirection part = PROPAGATION_TOTAL) {
300 determineReflectedFields(incident, side);
301 return computeFieldH(1e3 * Z0, dst_mesh, method, true, part);
302 }
303
311 LazyData<double> getScatteredFieldMagnitude(const cvector& incident,
312 IncidentDirection side,
313 const shared_ptr<const Mesh>& dst_mesh,
314 InterpolationMethod method) {
315 determineReflectedFields(incident, side);
316 return computeFieldMagnitude(1e3 * Z0, dst_mesh, method, true);
317 }
318
325 cvector getFieldVectorE(double z, PropagationDirection part = PROPAGATION_TOTAL);
326
333 cvector getFieldVectorH(double z, PropagationDirection part = PROPAGATION_TOTAL);
334
343 cvector getScatteredFieldVectorE(const cvector& incident,
344 IncidentDirection side,
345 double z,
346 PropagationDirection part = PROPAGATION_TOTAL);
347
356 cvector getScatteredFieldVectorH(const cvector& incident,
357 IncidentDirection side,
358 double z,
359 PropagationDirection part = PROPAGATION_TOTAL);
360
369 double getFieldIntegral(WhichField field, double z1, double z2, double power);
370
380 double getScatteredFieldIntegral(WhichField field,
381 const cvector& incident,
382 IncidentDirection side,
383 double z1,
384 double z2);
385};
386
387}}} // namespace plask::optical::modal
388
389#endif // PLASK__SLAB_TRANSFER_H