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
21namespace plask { namespace optical { namespace modal {
22
28
35
36using phys::Z0;
37
38struct ModalBase;
39struct Expansion;
40class Diagonalizer;
41
49 INCIDENCE_BOTTOM
50 };
51
54 DETERMINED_NOTHING = 0,
56 DETERMINED_REFLECTED
57 };
58
67
71 DETERMINANT_FULL
72 };
73
74 protected:
76 dcomplex* interface_field;
77
79
81
82 dcomplex* evals;
83 double* rwrk;
84 std::size_t lwrk;
85 dcomplex* wrk;
86
89
91
92 public:
94 void initDiagonalization();
95
97 std::unique_ptr<Diagonalizer> diagonalizer;
98
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
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:
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
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
264 const shared_ptr<const Mesh>& dst_mesh,
265 InterpolationMethod method) {
266 determineFields();
267 return computeFieldMagnitude(power, dst_mesh, method, false);
268 }
269
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
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
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