PLaSK library
Loading...
Searching...
No Matches
2d.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__VECTOR2D_H
15#define PLASK__VECTOR2D_H
16
21#include <iostream>
22
23#include "../math.hpp"
24#include "plask/exceptions.hpp"
25
26#include "common.hpp"
27#include <cassert>
28
29#include "../utils/metaprog.hpp" // for is_callable
30#include "../utils/warnings.hpp"
31
32namespace plask {
33
37template <typename T>
38struct Vec<2,T> {
39
40 static const int DIMS = 2;
41
42 T c0, c1;
43
44 T& tran() { return c0; }
45 constexpr const T& tran() const { return c0; }
46
47 T& vert() { return c1; }
48 constexpr const T& vert() const { return c1; }
49
50 // radial coordinates
51 T& rad_r() { return c0; }
52 constexpr const T& rad_r() const { return c0; }
53 T& rad_z() { return c1; }
54 constexpr const T& rad_z() const { return c1; }
55
56 // for surface-emitting lasers (z-axis up)
57 T& se_y() { return c0; }
58 constexpr const T& se_y() const { return c0; }
59 T& se_z() { return c1; }
60 constexpr const T& se_z() const { return c1; }
61
62 // for surface-emitting lasers (z-axis up)
63 T& zup_y() { return c0; }
64 constexpr const T& z_up_y() const { return c0; }
65 T& zup_z() { return c1; }
66 constexpr const T& z_up_z() const { return c1; }
67
68 // for edge emitting lasers (y-axis up), we keep the coordinates right-handed
69 T& ee_x() { return c0; }
70 constexpr const T& ee_x() const { return c0; }
71 T& ee_y() { return c1; }
72 constexpr const T& ee_y() const { return c1; }
73
74 // for edge emitting lasers (y-axis up), we keep the coordinates right-handed
75 T& yup_x() { return c0; }
76 constexpr const T& y_up_x() const { return c0; }
77 T& yup_y() { return c1; }
78 constexpr const T& y_up_y() const { return c1; }
79
80
84 typedef T* iterator;
85
89 typedef const T* const_iterator;
90
92 Vec() {}
93
98 template <typename OtherT>
99 constexpr Vec(const Vec<2,OtherT>& p): c0(p.c0), c1(p.c1) {}
100
105 constexpr Vec(const T& c0__tran, const T& c1__up): c0(c0__tran), c1(c1__up) {}
106
111 template <typename T0, typename T1>
112 constexpr Vec(const std::pair<T0,T1>& comp): c0(comp.first), c1(comp.second) {}
113
119 template <typename InputIteratorType>
122 result.c0 = T(*inputIt);
123 result.c1 = T(*++inputIt);
124 return result;
125 }
126
131 iterator begin() { return &c0; }
132
137 const_iterator begin() const { return &c0; }
138
143 iterator end() { return &c0 + 2; }
144
149 const_iterator end() const { return &c0 + 2; }
150
156 template <typename OtherT>
157 constexpr bool operator==(const Vec<2,OtherT>& p) const { return p.c0 == c0 && p.c1 == c1; }
158
165 template <typename OtherT, typename SuprType>
166 constexpr bool equals(const Vec<2, OtherT>& p, const SuprType& abs_supremum) const {
167 return is_zero(p.c0 - c0, abs_supremum) && is_zero(p.c1 - c1, abs_supremum); }
168
174 template <typename OtherT>
175 constexpr bool equals(const Vec<2, OtherT>& p) const {
176 return is_zero(p.c0 - c0) && is_zero(p.c1 - c1); }
177
183 template <typename OtherT>
184 constexpr bool operator!=(const Vec<2,OtherT>& p) const { return p.c0 != c0 || p.c1 != c1; }
185
192 inline T& operator[](size_t i) {
193 assert(i < 2);
194 return *(&c0 + i);
195 }
196
203 inline const T& operator[](size_t i) const {
204 assert(i < 2);
205 return *(&c0 + i);
206 }
207
213 template <typename OtherT>
214 constexpr auto operator+(const Vec<2,OtherT>& other) const -> Vec<2,decltype(c0 + other.c0)> {
215 return Vec<2,decltype(this->c0 + other.c0)>(c0 + other.c0, c1 + other.c1);
216 }
217
223 Vec<2,T>& operator+=(const Vec<2,T>& other) {
224 c0 += other.c0;
225 c1 += other.c1;
226 return *this;
227 }
228
234 template <typename OtherT>
235 constexpr auto operator-(const Vec<2,OtherT>& other) const -> Vec<2,decltype(c0 - other.c0)> {
236 return Vec<2,decltype(this->c0 - other.c0)>(c0 - other.c0, c1 - other.c1);
237 }
238
244 Vec<2,T>& operator-=(const Vec<2,T>& other) {
245 c0 -= other.c0;
246 c1 -= other.c1;
247 return *this;
248 }
249
255 template <typename OtherT>
256 constexpr auto operator*(const OtherT scale) const -> Vec<2,decltype(c0*scale)> {
258 return Vec<2,decltype(c0*scale)>(c0 * scale, c1 * scale);
260 }
261
268 c0 *= scalar;
269 c1 *= scalar;
270 return *this;
271 }
272
278 constexpr Vec<2,T> operator/(const T scale) const { return Vec<2,T>(c0 / scale, c1 / scale); }
279
286 c0 /= scalar;
287 c1 /= scalar;
288 return *this;
289 }
290
295 constexpr Vec<2,T> operator-() const {
296 return Vec<2,T>(-c0, -c1);
297 }
298
303 Vec<2,T> sqr() const {
304 return Vec<2,T>(c0*c0, c1*c1);
305 }
306
312 c0 *= c0; c1 *= c1;
313 return *this;
314 }
315
320 Vec<2,T> sqrt() const {
321 return Vec<2,T>(std::sqrt(c0), std::sqrt(c1));
322 }
323
329 c0 = std::sqrt(c0); c1 = std::sqrt(c1);
330 return *this;
331 }
332
337 template <typename OtherT>
339 return Vec<2,T>(std::pow(c0, a), std::pow(c1, a));
340 }
341
347 inline void flip(size_t i) {
348 assert(i < 2);
349 operator[](i) = -operator[](i);
350 }
351
358 inline Vec<2,T> flipped(size_t i) {
359 Vec<2,T> res = *this;
360 res.flip(i);
361 return res;
362 }
363
370 friend inline std::ostream& operator<<(std::ostream& out, const Vec<2,T>& to_print) {
371 return out << '[' << to_print.c0 << ", " << to_print.c1 << ']';
372 }
373
381 template<class OT> inline
382 bool operator< (Vec<2, OT> const& v) const {
383 if (dbl_compare_lt(this->c0, v.c0)) return true;
384 if (dbl_compare_gt(this->c0, v.c0)) return false;
385 return dbl_compare_lt(this->c1, v.c1);
386 }
387};
388
394template <typename T>
395inline constexpr Vec<2,T> conj(const Vec<2,T>& v) { return Vec<2,T>(conj(v.c0), conj(v.c1)); }
396
403template <typename T1, typename T2>
404inline auto dot(const Vec<2,T1>& v1, const Vec<2,T2>& v2) -> decltype(v1.c0*v2.c0) {
405 return ::plask::fma(v1.c0, v2.c0, v1.c1 * v2.c1); //MSVC needs ::plask::
406}
407
413template <typename T1, typename T2>
414inline auto cross(const Vec<2,T1>& v1, const Vec<2,T2>& v2) -> decltype(v1.c0*v2.c1) {
415 return ::plask::fma(v1.c0, v2.c1, - v1.c1 * v2.c0); //MSVC needs ::plask::
416}
417
424//template <> //MSVC2015 doesn't support this specialization, and using overloding shouldn't have negative consequences
425inline auto dot(const Vec<2,dcomplex>& v1, const Vec<2,double>& v2) -> decltype(v1.c0*v2.c0) {
426 return ::plask::fma(conj(v1.c0), v2.c0, conj(v1.c1) * v2.c1); //MSVC needs ::plask::
427}
428
435//template <> //MSVC2015 doesn't support this specialization, and using overloding shouldn't have negative consequences
436inline auto dot(const Vec<2,dcomplex>& v1, const Vec<2,dcomplex>& v2) -> decltype(v1.c0*v2.c0) {
437 return ::plask::fma(conj(v1.c0), v2.c0, conj(v1.c1) * v2.c1); //MSVC needs ::plask::
438}
439
445template <typename T>
446inline constexpr Vec<2,T> vec(const T c0__tran, const T c1__up) {
447 return Vec<2,T>(c0__tran, c1__up);
448}
449
451template <typename T>
452struct NaNImpl<Vec<2,T>> {
453 static constexpr Vec<2,T> get() { return Vec<2,T>(NaN<T>(), NaN<T>()); }
454};
455
457template <typename T>
458struct ZeroImpl<Vec<2,T>> {
459 static constexpr Vec<2,T> get() { return Vec<2,T>(0., 0.); }
460};
461
464template <typename T>
465inline bool is_zero(const Vec<2,T>& v) {
466 return is_zero(v.c0) && is_zero(v.c1);
467}
468
469
471PLASK_API_EXTERN_TEMPLATE_SPECIALIZATION_STRUCT(Vec<2, std::complex<double> >)
473
474} //namespace plask
475
477 template <typename T>
481
482 template <typename T, typename OtherT>
486}
487
488#endif // PLASK__VECTOR2D_H