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 <cassert>
27
#include "
common.hpp
"
28
29
#include "../utils/metaprog.hpp"
// for is_callable
30
#include "../utils/warnings.hpp"
31
32
namespace
plask
{
33
37
template
<
typename
T>
struct
Vec
<2, T> {
38
static
const
int
DIMS = 2;
39
40
T
c0
, c1;
41
42
T&
tran
() {
return
c0; }
43
constexpr
const
T&
tran
()
const
{
return
c0; }
44
45
T&
vert
() {
return
c1; }
46
constexpr
const
T&
vert
()
const
{
return
c1; }
47
48
// radial coordinates
49
T&
rad_r
() {
return
c0; }
50
constexpr
const
T&
rad_r
()
const
{
return
c0; }
51
T&
rad_z
() {
return
c1; }
52
constexpr
const
T&
rad_z
()
const
{
return
c1; }
53
54
// for surface-emitting lasers (z-axis up)
55
T&
se_y
() {
return
c0; }
56
constexpr
const
T&
se_y
()
const
{
return
c0; }
57
T&
se_z
() {
return
c1; }
58
constexpr
const
T&
se_z
()
const
{
return
c1; }
59
60
// for surface-emitting lasers (z-axis up)
61
T&
zup_y
() {
return
c0; }
62
constexpr
const
T&
z_up_y
()
const
{
return
c0; }
63
T&
zup_z
() {
return
c1; }
64
constexpr
const
T&
z_up_z
()
const
{
return
c1; }
65
66
// for edge emitting lasers (y-axis up), we keep the coordinates right-handed
67
T&
ee_x
() {
return
c0; }
68
constexpr
const
T&
ee_x
()
const
{
return
c0; }
69
T&
ee_y
() {
return
c1; }
70
constexpr
const
T&
ee_y
()
const
{
return
c1; }
71
72
// for edge emitting lasers (y-axis up), we keep the coordinates right-handed
73
T&
yup_x
() {
return
c0; }
74
constexpr
const
T&
y_up_x
()
const
{
return
c0; }
75
T&
yup_y
() {
return
c1; }
76
constexpr
const
T&
y_up_y
()
const
{
return
c1; }
77
81
typedef
T*
iterator
;
82
86
typedef
const
T*
const_iterator
;
87
89
Vec
() {}
90
95
template
<
typename
OtherT>
constexpr
Vec
(
const
Vec<2, OtherT>
& p) : c0(p.c0), c1(p.c1) {}
96
101
constexpr
Vec
(
const
T&
c0__tran
,
const
T&
c1__up
) : c0(
c0__tran
), c1(
c1__up
) {}
102
107
template
<
typename
T0,
typename
T1>
constexpr
Vec
(
const
std::pair<T0, T1>& comp) : c0(comp.first), c1(comp.second) {}
108
114
template
<
typename
InputIteratorType>
static
inline
Vec<2, T>
fromIterator
(
InputIteratorType
inputIt
) {
115
Vec<2, T>
result
;
116
result
.c0 = T(*
inputIt
);
117
result
.c1 = T(*++
inputIt
);
118
return
result
;
119
}
120
125
iterator
begin
() {
return
&c0; }
126
131
const_iterator
begin
()
const
{
return
&c0; }
132
137
iterator
end
() {
return
&c0 + 2; }
138
143
const_iterator
end
()
const
{
return
&c0 + 2; }
144
150
template
<
typename
OtherT>
constexpr
bool
operator==
(
const
Vec<2, OtherT>
& p)
const
{
return
p.c0 == c0 && p.c1 == c1; }
151
158
template
<
typename
OtherT,
typename
SuprType>
159
constexpr
bool
equals
(
const
Vec<2, OtherT>
& p,
const
SuprType
&
abs_supremum
)
const
{
160
return
is_zero
(p.c0 - c0,
abs_supremum
) &&
is_zero
(p.c1 - c1,
abs_supremum
);
161
}
162
168
template
<
typename
OtherT>
constexpr
bool
equals
(
const
Vec<2, OtherT>
& p)
const
{
169
return
is_zero
(p.c0 - c0) &&
is_zero
(p.c1 - c1);
170
}
171
177
template
<
typename
OtherT>
constexpr
bool
operator!=
(
const
Vec<2, OtherT>
& p)
const
{
return
p.c0 != c0 || p.c1 != c1; }
178
185
inline
T&
operator[]
(
size_t
i) {
186
assert
(i < 2);
187
return
*(&c0 + i);
188
}
189
196
inline
const
T&
operator[]
(
size_t
i)
const
{
197
assert
(i < 2);
198
return
*(&c0 + i);
199
}
200
206
template
<
typename
OtherT>
constexpr
auto
operator+
(
const
Vec<2, OtherT>
& other)
const
->
Vec
<2,
decltype
(c0 + other.c0)> {
207
return
Vec
<2,
decltype
(this->c0 + other.c0)>(c0 + other.c0, c1 + other.c1);
208
}
209
215
Vec<2, T>
&
operator+=
(
const
Vec<2, T>
& other) {
216
c0 += other.c0;
217
c1 += other.c1;
218
return
*
this
;
219
}
220
227
template
<
typename
OtherT>
constexpr
auto
operator-
(
const
Vec<2, OtherT>
& other)
const
->
Vec
<2,
decltype
(c0 - other.c0)> {
228
return
Vec
<2,
decltype
(this->c0 - other.c0)>(c0 - other.c0, c1 - other.c1);
229
}
230
236
Vec<2, T>
&
operator-=
(
const
Vec<2, T>
& other) {
237
c0 -= other.c0;
238
c1 -= other.c1;
239
return
*
this
;
240
}
241
247
template
<
typename
OtherT>
constexpr
auto
operator*
(
const
OtherT
scale)
const
->
Vec
<2,
decltype
(c0 * scale)> {
248
PLASK_NO_CONVERSION_WARNING_BEGIN
249
return
Vec<2, decltype(c0 * scale)>
(c0 * scale, c1 * scale);
250
PLASK_NO_WARNING_END
251
}
252
258
Vec<2, T>
&
operator*=
(
const
T
scalar
) {
259
c0 *=
scalar
;
260
c1 *=
scalar
;
261
return
*
this
;
262
}
263
269
template
<
typename
OtherT>
constexpr
auto
operator/
(
const
OtherT
scale)
const
->
Vec
<2,
decltype
(c0 / scale)> {
270
PLASK_NO_CONVERSION_WARNING_BEGIN
271
return
Vec<2, decltype(c0 * scale)>
(c0 / scale, c1 / scale);
272
PLASK_NO_WARNING_END
273
}
274
280
Vec<2, T>
&
operator/=
(
const
T
scalar
) {
281
c0 /=
scalar
;
282
c1 /=
scalar
;
283
return
*
this
;
284
}
285
290
constexpr
Vec<2, T>
operator-
()
const
{
return
Vec<2, T>
(-c0, -c1); }
291
296
Vec<2, T>
sqr
()
const
{
return
Vec<2, T>
(c0 * c0, c1 * c1); }
297
302
Vec<2, T>
&
sqr_inplace
() {
303
c0 *= c0;
304
c1 *= c1;
305
return
*
this
;
306
}
307
312
Vec<2, T>
sqrt
()
const
{
313
PLASK_NO_CONVERSION_WARNING_BEGIN
314
return
Vec<2, T>
(
std::sqrt
(c0),
std::sqrt
(c1));
315
PLASK_NO_WARNING_END
316
}
317
322
Vec<2, T>
&
sqrt_inplace
() {
323
c0 =
std::sqrt
(c0);
324
c1 =
std::sqrt
(c1);
325
return
*
this
;
326
}
327
332
template
<
typename
OtherT>
Vec<2, T>
pow
(
OtherT
a
)
const
{
return
Vec<2, T>
(
std::pow
(c0,
a
),
std::pow
(c1,
a
)); }
333
339
inline
void
flip
(
size_t
i) {
340
assert
(i < 2);
341
operator[](i) = -operator[](i);
342
}
343
350
inline
Vec<2, T>
flipped
(
size_t
i) {
351
Vec<2, T>
res
= *
this
;
352
res
.flip(i);
353
return
res
;
354
}
355
362
friend
inline
std::ostream&
operator<<
(std::ostream& out,
const
Vec<2, T>
&
to_print
) {
363
return
out <<
'['
<<
to_print
.c0 <<
", "
<<
to_print
.c1 <<
']'
;
364
}
365
373
template
<
class
OT>
inline
bool
operator<
(
Vec<2, OT>
const
&
v
)
const
{
374
if
(
dbl_compare_lt
(this->c0,
v
.c0))
return
true
;
375
if
(
dbl_compare_gt
(this->c0,
v
.c0))
return
false
;
376
return
dbl_compare_lt
(this->c1,
v
.c1);
377
}
378
};
379
385
template
<
typename
T>
inline
constexpr
Vec<2, T>
conj
(
const
Vec<2, T>
&
v
) {
return
Vec<2, T>
(
conj
(
v
.c0),
conj
(
v
.c1)); }
386
393
template
<
typename
T1,
typename
T2>
inline
auto
dot
(
const
Vec<2, T1>
&
v1
,
const
Vec<2, T2>
&
v2
) ->
decltype
(
v1
.c0 *
v2
.c0) {
394
return ::plask::fma(
v1
.c0,
v2
.c0,
v1
.c1 *
v2
.c1);
// MSVC needs ::plask::
395
}
396
402
template
<
typename
T1,
typename
T2>
inline
auto
cross
(
const
Vec<2, T1>
&
v1
,
const
Vec<2, T2>
&
v2
) ->
decltype
(
v1
.c0 *
v2
.c1) {
403
return ::plask::fma(
v1
.c0,
v2
.c1, -
v1
.c1 *
v2
.c0);
// MSVC needs ::plask::
404
}
405
412
// template <> //MSVC2015 doesn't support this specialization, and using overloding shouldn't have negative consequences
413
inline
auto
dot
(
const
Vec<2, dcomplex>
&
v1
,
const
Vec<2, double>
&
v2
) ->
decltype
(
v1
.c0 *
v2
.c0) {
414
return ::plask::fma(
conj
(
v1
.c0),
v2
.c0,
conj
(
v1
.c1) *
v2
.c1);
// MSVC needs ::plask::
415
}
416
423
// template <> //MSVC2015 doesn't support this specialization, and using overloding shouldn't have negative consequences
424
inline
auto
dot
(
const
Vec<2, dcomplex>
&
v1
,
const
Vec<2, dcomplex>
&
v2
) ->
decltype
(
v1
.c0 *
v2
.c0) {
425
return ::plask::fma(
conj
(
v1
.c0),
v2
.c0,
conj
(
v1
.c1) *
v2
.c1);
// MSVC needs ::plask::
426
}
427
433
template
<
typename
T>
inline
constexpr
Vec<2, T>
vec
(
const
T
c0__tran
,
const
T
c1__up
) {
return
Vec<2, T>
(
c0__tran
,
c1__up
); }
434
436
template
<
typename
T>
struct
NaNImpl
<
Vec
<2, T>> {
437
static
constexpr
Vec<2, T>
get
() {
return
Vec<2, T>
(
NaN<T>
(),
NaN<T>
()); }
438
};
439
441
template
<
typename
T>
struct
ZeroImpl
<
Vec
<2, T>> {
442
static
constexpr
Vec<2, T>
get
() {
return
Vec<2, T>
(0., 0.); }
443
};
444
447
template
<
typename
T>
inline
bool
is_zero
(
const
Vec<2, T>
&
v
) {
return
is_zero
(
v
.c0) &&
is_zero
(
v
.c1); }
448
449
PLASK_API_EXTERN_TEMPLATE_SPECIALIZATION_STRUCT
(
Vec<2, double>
)
450
PLASK_API_EXTERN_TEMPLATE_SPECIALIZATION_STRUCT
(Vec<2, std::complex<double>>)
451
452
}
// namespace plask
453
454
namespace
std
{
455
template
<
typename
T>
plask::Vec<2, T>
sqrt
(
plask::Vec<2, T>
vec) {
return
vec.
sqrt
(); }
456
457
template
<
typename
T,
typename
OtherT>
plask::Vec<2, T>
pow
(
plask::Vec<2, T>
vec, OtherT a) {
return
vec.
pow
(a); }
458
}
// namespace std
459
460
#if FMT_VERSION >= 90000
461
template
<
typename
T>
struct
fmt::formatter<
plask
::Vec<2, T>> : ostream_formatter {};
462
#endif
463
464
#endif
// PLASK__VECTOR2D_H
plask
vector
2d.hpp
Generated by
1.9.8