PLaSK library
Loading...
Searching...
No Matches
rectilinear3d.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 "
rectilinear3d.hpp
"
15
16
#include "
regular1d.hpp
"
17
#include "
ordered1d.hpp
"
18
19
namespace
plask
{
20
21
#define RECTILINEAR_MESH_3D_DECLARE_ITERATION_ORDER(first, second, third) \
22
static std::size_t index_##first##second##third(const RectilinearMesh3D* mesh, std::size_t index0, std::size_t index1, std::size_t index2) { \
23
return index##third + mesh->axis[third]->size() * (index##second + mesh->axis[second]->size() * index##first); \
24
} \
25
static std::size_t index##first##_##first##second##third(const RectilinearMesh3D* mesh, std::size_t mesh_index) { \
26
return mesh_index / mesh->axis[third]->size() / mesh->axis[second]->size(); \
27
} \
28
static std::size_t index##second##_##first##second##third(const RectilinearMesh3D* mesh, std::size_t mesh_index) { \
29
return (mesh_index / mesh->axis[third]->size()) % mesh->axis[second]->size(); \
30
} \
31
static std::size_t index##third##_##first##second##third(const RectilinearMesh3D* mesh, std::size_t mesh_index) { \
32
return mesh_index % mesh->axis[third]->size(); \
33
}
34
35
RECTILINEAR_MESH_3D_DECLARE_ITERATION_ORDER
(0,1,2)
36
RECTILINEAR_MESH_3D_DECLARE_ITERATION_ORDER
(0,2,1)
37
RECTILINEAR_MESH_3D_DECLARE_ITERATION_ORDER
(1,0,2)
38
RECTILINEAR_MESH_3D_DECLARE_ITERATION_ORDER
(1,2,0)
39
RECTILINEAR_MESH_3D_DECLARE_ITERATION_ORDER
(2,0,1)
40
RECTILINEAR_MESH_3D_DECLARE_ITERATION_ORDER
(2,1,0)
41
42
43
void
RectilinearMesh3D
::setIterationOrder(
IterationOrder
iterationOrder
) {
44
# define RECTILINEAR_MESH_3D_CASE_ITERATION_ORDER(o1,o2,o3) \
45
case ORDER_##o1##o2##o3: \
46
index_f = index_##o1##o2##o3; index0_f = index0_##o1##o2##o3; \
47
index1_f = index1_##o1##o2##o3; index2_f = index2_##o1##o2##o3; \
48
major_axis = &axis[o1]; medium_axis = &axis[o2]; minor_axis = &axis[o3]; \
49
break;
50
switch
(
iterationOrder
) {
51
RECTILINEAR_MESH_3D_CASE_ITERATION_ORDER
(0,1,2)
52
RECTILINEAR_MESH_3D_CASE_ITERATION_ORDER
(0,2,1)
53
RECTILINEAR_MESH_3D_CASE_ITERATION_ORDER
(1,0,2)
54
RECTILINEAR_MESH_3D_CASE_ITERATION_ORDER
(1,2,0)
55
RECTILINEAR_MESH_3D_CASE_ITERATION_ORDER
(2,0,1)
56
RECTILINEAR_MESH_3D_CASE_ITERATION_ORDER
(2,1,0)
57
default
:
58
index_f =
index_210
; index0_f =
index0_210
; index1_f =
index1_210
; index2_f =
index2_210
;
59
major_axis = &axis[2]; medium_axis = &axis[1]; minor_axis = &axis[0];
60
}
61
fireChanged();
62
}
63
64
65
typename
RectilinearMesh3D::IterationOrder
RectilinearMesh3D::getIterationOrder
()
const
{
66
return
this->index_f ==
decltype
(this->index_f)(
index_012
) ?
ORDER_012
:
67
this->index_f ==
decltype
(this->index_f)(
index_021
) ?
ORDER_021
:
68
this->index_f ==
decltype
(this->index_f)(
index_102
) ?
ORDER_102
:
69
this->index_f ==
decltype
(this->index_f)(
index_120
) ?
ORDER_120
:
70
this->index_f ==
decltype
(this->index_f)(
index_201
) ?
ORDER_201
:
71
ORDER_210
;
72
}
73
74
void
RectilinearMesh3D::setOptimalIterationOrder
() {
75
# define RECTILINEAR_MESH_3D_DETERMINE_ITERATION_ORDER(first, second, third) \
76
if (this->axis[third]->size() <= this->axis[second]->size() && this->axis[second]->size() <= this->axis[first]->size()) { \
77
setIterationOrder(ORDER_##first##second##third); return; \
78
}
79
RECTILINEAR_MESH_3D_DETERMINE_ITERATION_ORDER
(0,1,2)
80
RECTILINEAR_MESH_3D_DETERMINE_ITERATION_ORDER
(0,2,1)
81
RECTILINEAR_MESH_3D_DETERMINE_ITERATION_ORDER
(1,0,2)
82
RECTILINEAR_MESH_3D_DETERMINE_ITERATION_ORDER
(1,2,0)
83
RECTILINEAR_MESH_3D_DETERMINE_ITERATION_ORDER
(2,0,1)
84
RECTILINEAR_MESH_3D_DETERMINE_ITERATION_ORDER
(2,1,0)
85
}
86
87
void
RectilinearMesh3D::onAxisChanged(
Mesh::Event
&
e
) {
88
assert
(!
e
.isDelete());
89
fireChanged
(
e
.flags());
90
}
91
92
RectilinearMesh3D::RectilinearMesh3D
(
IterationOrder
iterationOrder
)
93
: axis{
plask
::make_shared<
OrderedAxis
>(),
plask
::make_shared<
OrderedAxis
>(),
plask
::make_shared<
OrderedAxis
>()} {
94
setIterationOrder
(
iterationOrder
);
95
setChangeSignal(this->
axis
[0]);
96
setChangeSignal(this->
axis
[1]);
97
setChangeSignal(this->
axis
[2]);
98
}
99
100
RectilinearMesh3D::RectilinearMesh3D
(shared_ptr<MeshAxis>
mesh0
, shared_ptr<MeshAxis> mesh1, shared_ptr<MeshAxis> mesh2,
IterationOrder
iterationOrder
)
101
: axis{
std
::move(
mesh0
),
std
::move(mesh1),
std
::move(mesh2)}
102
{
103
setIterationOrder
(
iterationOrder
);
104
setChangeSignal(this->
axis
[0]);
105
setChangeSignal(this->
axis
[1]);
106
setChangeSignal(this->
axis
[2]);
107
}
108
109
void
RectilinearMesh3D::reset
(shared_ptr<MeshAxis>
axis0
, shared_ptr<MeshAxis>
axis1
, shared_ptr<MeshAxis>
axis2
,
RectilinearMesh3D::IterationOrder
iterationOrder
) {
110
setAxis
(0, std::move(
axis0
),
false
);
111
setAxis
(1, std::move(
axis1
),
false
);
112
setAxis
(2, std::move(
axis2
),
false
);
113
setIterationOrder
(
iterationOrder
);
114
}
115
116
RectilinearMesh3D::RectilinearMesh3D
(
const
RectilinearMesh3D
&src,
bool
clone_axes
)
117
:
RectangularMeshBase3D
(src),
118
axis{
clone_axes
? src.axis[0]->clone() : src.axis[0],
119
clone_axes
? src.axis[1]->clone() : src.axis[1],
120
clone_axes
? src.axis[2]->clone() : src.axis[2]}
121
{
122
setIterationOrder
(src.
getIterationOrder
());
123
setChangeSignal(this->
axis
[0]);
124
setChangeSignal(this->
axis
[1]);
125
setChangeSignal(this->
axis
[2]);
126
}
127
128
void
RectilinearMesh3D::reset
(
const
RectilinearMesh3D
&src,
bool
clone_axes
)
129
{
130
if
(
clone_axes
)
131
reset
(src.
axis
[0]->clone(), src.
axis
[1]->clone(), src.
axis
[2]->clone(), src.
getIterationOrder
());
132
else
133
reset
(src.
axis
[0], src.
axis
[1], src.
axis
[2], src.
getIterationOrder
());
134
}
135
136
RectilinearMesh3D::~RectilinearMesh3D
() {
137
unsetChangeSignal(this->
axis
[0]);
138
unsetChangeSignal(this->
axis
[1]);
139
unsetChangeSignal(this->
axis
[2]);
140
}
141
142
void
RectilinearMesh3D::setAxis
(std::size_t
axis_nr
, shared_ptr<MeshAxis>
new_val
,
bool
fireResized) {
143
assert
(
axis_nr
< 3);
144
if
(
axis
[
axis_nr
] ==
new_val
)
return
;
145
unsetChangeSignal(
axis
[
axis_nr
]);
146
const_cast<
shared_ptr<MeshAxis>&
>
(
axis
[
axis_nr
]) =
new_val
;
147
setChangeSignal(
axis
[
axis_nr
]);
148
if
(
fireResized
) this->
fireResized
();
149
}
150
151
BoundaryNodeSet
RectilinearMesh3D::createIndex0BoundaryAtLine
(std::size_t
line_nr_axis0
)
const
{
152
if
(this->
isChangeSlower
(1, 2))
153
return
new
BoundaryNodeSetImpl<1, 2>
(*
this
, line_nr_axis0);
154
else
155
return
new
BoundaryNodeSetImpl<2, 1>
(*
this
,
line_nr_axis0
);
156
}
157
158
BoundaryNodeSet
RectilinearMesh3D::createBackBoundary
()
const
{
159
return
createIndex0BoundaryAtLine
(0);
160
}
161
162
BoundaryNodeSet
RectilinearMesh3D::createFrontBoundary
()
const
{
163
return
createIndex0BoundaryAtLine
(
axis
[0]->
size
()-1);
164
}
165
166
BoundaryNodeSet
RectilinearMesh3D::createIndex1BoundaryAtLine
(std::size_t
line_nr_axis1
)
const
{
167
if
(this->
isChangeSlower
(0, 2))
168
return
new
BoundaryNodeSetImpl<0, 2>
(*
this
, line_nr_axis1);
169
else
170
return
new
BoundaryNodeSetImpl<2, 0>
(*
this
,
line_nr_axis1
);
171
}
172
173
BoundaryNodeSet
RectilinearMesh3D::createLeftBoundary
()
const
{
174
return
createIndex1BoundaryAtLine
(0);
175
}
176
177
BoundaryNodeSet
RectilinearMesh3D::createRightBoundary
()
const
{
178
return
createIndex1BoundaryAtLine
(
axis
[1]->
size
()-1);
179
}
180
181
BoundaryNodeSet
RectilinearMesh3D::createIndex2BoundaryAtLine
(std::size_t
line_nr_axis2
)
const
{
182
if
(this->
isChangeSlower
(0, 1))
183
return
new
BoundaryNodeSetImpl<0, 1>
(*
this
, line_nr_axis2);
184
else
185
return
new
BoundaryNodeSetImpl<1, 0>
(*
this
,
line_nr_axis2
);
186
}
187
188
BoundaryNodeSet
RectilinearMesh3D::createBottomBoundary
()
const
{
189
return
createIndex2BoundaryAtLine
(0);
190
}
191
192
BoundaryNodeSet
RectilinearMesh3D::createTopBoundary
()
const
{
193
return
createIndex2BoundaryAtLine
(
axis
[2]->
size
()-1);
194
}
195
196
BoundaryNodeSet
RectilinearMesh3D::createIndex0BoundaryAtLine
(std::size_t
line_nr_axis0
, std::size_t
index1Begin
, std::size_t
index1End
, std::size_t
index2Begin
, std::size_t
index2End
)
const
{
197
if
(
index1Begin
>=
index1End
||
index2Begin
>=
index2End
)
198
return
new
EmptyBoundaryImpl
();
199
if
(
isChangeSlower
(1, 2))
200
return
new
BoundaryNodeSetRangeImpl<1, 2>
(*
this
,
line_nr_axis0
,
index1Begin
,
index2Begin
,
index1End
,
index2End
);
201
else
202
return
new
BoundaryNodeSetRangeImpl<2, 1>
(*
this
,
line_nr_axis0
,
index1Begin
,
index2Begin
,
index2End
,
index1End
);
203
}
204
205
BoundaryNodeSet
RectilinearMesh3D::createBackOfBoundary
(
const
Box3D
&
box
)
const
{
206
std::size_t line,
begInd1
,
endInd1
,
begInd2
,
endInd2
;
207
if
(
details::getLineLo
(line, *
axis
[0],
box
.lower.c0,
box
.upper.c0) &&
208
details::getIndexesInBounds
(
begInd1
,
endInd1
, *
axis
[1],
box
.lower.c1,
box
.upper.c1) &&
209
details::getIndexesInBounds
(
begInd2
,
endInd2
, *
axis
[2],
box
.lower.c2,
box
.upper.c2))
210
return
createIndex0BoundaryAtLine
(line,
begInd1
,
endInd1
,
begInd2
,
endInd2
);
211
else
212
return
new
EmptyBoundaryImpl
();
213
}
214
215
BoundaryNodeSet
RectilinearMesh3D::createFrontOfBoundary
(
const
Box3D
&
box
)
const
{
216
std::size_t line,
begInd1
,
endInd1
,
begInd2
,
endInd2
;
217
if
(
details::getLineHi
(line, *
axis
[0],
box
.lower.c0,
box
.upper.c0) &&
218
details::getIndexesInBounds
(
begInd1
,
endInd1
, *
axis
[1],
box
.lower.c1,
box
.upper.c1) &&
219
details::getIndexesInBounds
(
begInd2
,
endInd2
, *
axis
[2],
box
.lower.c2,
box
.upper.c2))
220
return
createIndex0BoundaryAtLine
(line,
begInd1
,
endInd1
,
begInd2
,
endInd2
);
221
else
222
return
new
EmptyBoundaryImpl
();
223
}
224
225
BoundaryNodeSet
RectilinearMesh3D::createIndex1BoundaryAtLine
(std::size_t
line_nr_axis1
, std::size_t
index0Begin
, std::size_t
index0End
, std::size_t
index2Begin
, std::size_t
index2End
)
const
226
{
227
if
(
index0Begin
>=
index0End
||
index2Begin
>=
index2End
)
228
return
new
EmptyBoundaryImpl
();
229
if
(
isChangeSlower
(0, 2))
230
return
new
BoundaryNodeSetRangeImpl<0, 2>
(*
this
,
index0Begin
,
line_nr_axis1
,
index2Begin
,
index0End
,
index2End
);
231
else
232
return
new
BoundaryNodeSetRangeImpl<2, 0>
(*
this
,
index0Begin
,
line_nr_axis1
,
index2Begin
,
index2End
,
index0End
);
233
}
234
235
BoundaryNodeSet
RectilinearMesh3D::createLeftOfBoundary
(
const
Box3D
&
box
)
const
{
236
std::size_t line,
begInd0
,
endInd0
,
begInd2
,
endInd2
;
237
if
(
details::getLineLo
(line, *
axis
[1],
box
.lower.c1,
box
.upper.c1) &&
238
details::getIndexesInBounds
(
begInd0
,
endInd0
, *
axis
[0],
box
.lower.c0,
box
.upper.c0) &&
239
details::getIndexesInBounds
(
begInd2
,
endInd2
, *
axis
[2],
box
.lower.c2,
box
.upper.c2))
240
return
createIndex1BoundaryAtLine
(line,
begInd0
,
endInd0
,
begInd2
,
endInd2
);
241
else
242
return
new
EmptyBoundaryImpl
();
243
}
244
245
BoundaryNodeSet
RectilinearMesh3D::createRightOfBoundary
(
const
Box3D
&
box
)
const
{
246
std::size_t line,
begInd0
,
endInd0
,
begInd2
,
endInd2
;
247
if
(
details::getLineHi
(line, *
axis
[1],
box
.lower.c1,
box
.upper.c1) &&
248
details::getIndexesInBounds
(
begInd0
,
endInd0
, *
axis
[0],
box
.lower.c0,
box
.upper.c0) &&
249
details::getIndexesInBounds
(
begInd2
,
endInd2
, *
axis
[2],
box
.lower.c2,
box
.upper.c2))
250
return
createIndex1BoundaryAtLine
(line,
begInd0
,
endInd0
,
begInd2
,
endInd2
);
251
else
252
return
new
EmptyBoundaryImpl
();
253
}
254
255
BoundaryNodeSet
RectilinearMesh3D::createIndex2BoundaryAtLine
(std::size_t
line_nr_axis2
, std::size_t
index0Begin
, std::size_t
index0End
, std::size_t
index1Begin
, std::size_t
index1End
)
const
256
{
257
if
(
index0Begin
>=
index0End
||
index1Begin
>=
index1End
)
258
return
new
EmptyBoundaryImpl
();
259
if
(
isChangeSlower
(0, 1))
260
return
new
BoundaryNodeSetRangeImpl<0, 1>
(*
this
,
index0Begin
,
index1Begin
,
line_nr_axis2
,
index0End
,
index1End
);
261
else
262
return
new
BoundaryNodeSetRangeImpl<1, 0>
(*
this
,
index0Begin
,
index1Begin
,
line_nr_axis2
,
index1End
,
index0End
);
263
}
264
265
BoundaryNodeSet
RectilinearMesh3D::createBottomOfBoundary
(
const
Box3D
&
box
)
const
{
266
std::size_t line,
begInd0
,
endInd0
,
begInd1
,
endInd1
;
267
if
(
details::getLineLo
(line, *
axis
[2],
box
.lower.c2,
box
.upper.c2) &&
268
details::getIndexesInBounds
(
begInd0
,
endInd0
, *
axis
[0],
box
.lower.c0,
box
.upper.c0) &&
269
details::getIndexesInBounds
(
begInd1
,
endInd1
, *
axis
[1],
box
.lower.c1,
box
.upper.c1))
270
return
createIndex2BoundaryAtLine
(line,
begInd0
,
endInd0
,
begInd1
,
endInd1
);
271
else
272
return
new
EmptyBoundaryImpl
();
273
}
274
275
BoundaryNodeSet
RectilinearMesh3D::createTopOfBoundary
(
const
Box3D
&
box
)
const
{
276
std::size_t line,
begInd0
,
endInd0
,
begInd1
,
endInd1
;
277
if
(
details::getLineHi
(line, *
axis
[2],
box
.lower.c2,
box
.upper.c2) &&
278
details::getIndexesInBounds
(
begInd0
,
endInd0
, *
axis
[0],
box
.lower.c0,
box
.upper.c0) &&
279
details::getIndexesInBounds
(
begInd1
,
endInd1
, *
axis
[1],
box
.lower.c1,
box
.upper.c1))
280
return
createIndex2BoundaryAtLine
(line,
begInd0
,
endInd0
,
begInd1
,
endInd1
);
281
else
282
return
new
EmptyBoundaryImpl
();
283
}
284
285
}
// namespace plask
plask
mesh
rectilinear3d.cpp
Generated by
1.9.8