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
if
(
axis
[
axis_nr
] ==
new_val
)
return
;
144
unsetChangeSignal(
axis
[
axis_nr
]);
145
const_cast<
shared_ptr<MeshAxis>&
>
(
axis
[
axis_nr
]) =
new_val
;
146
setChangeSignal(
axis
[
axis_nr
]);
147
if
(
fireResized
) this->
fireResized
();
148
}
149
150
BoundaryNodeSet
RectilinearMesh3D::createIndex0BoundaryAtLine
(std::size_t
line_nr_axis0
)
const
{
151
if
(this->
isChangeSlower
(1, 2))
152
return
new
BoundaryNodeSetImpl<1, 2>
(*
this
, line_nr_axis0);
153
else
154
return
new
BoundaryNodeSetImpl<2, 1>
(*
this
,
line_nr_axis0
);
155
}
156
157
BoundaryNodeSet
RectilinearMesh3D::createBackBoundary
()
const
{
158
return
createIndex0BoundaryAtLine
(0);
159
}
160
161
BoundaryNodeSet
RectilinearMesh3D::createFrontBoundary
()
const
{
162
return
createIndex0BoundaryAtLine
(
axis
[0]->
size
()-1);
163
}
164
165
BoundaryNodeSet
RectilinearMesh3D::createIndex1BoundaryAtLine
(std::size_t
line_nr_axis1
)
const
{
166
if
(this->
isChangeSlower
(0, 2))
167
return
new
BoundaryNodeSetImpl<0, 2>
(*
this
, line_nr_axis1);
168
else
169
return
new
BoundaryNodeSetImpl<2, 0>
(*
this
,
line_nr_axis1
);
170
}
171
172
BoundaryNodeSet
RectilinearMesh3D::createLeftBoundary
()
const
{
173
return
createIndex1BoundaryAtLine
(0);
174
}
175
176
BoundaryNodeSet
RectilinearMesh3D::createRightBoundary
()
const
{
177
return
createIndex1BoundaryAtLine
(
axis
[1]->
size
()-1);
178
}
179
180
BoundaryNodeSet
RectilinearMesh3D::createIndex2BoundaryAtLine
(std::size_t
line_nr_axis2
)
const
{
181
if
(this->
isChangeSlower
(0, 1))
182
return
new
BoundaryNodeSetImpl<0, 1>
(*
this
, line_nr_axis2);
183
else
184
return
new
BoundaryNodeSetImpl<1, 0>
(*
this
,
line_nr_axis2
);
185
}
186
187
BoundaryNodeSet
RectilinearMesh3D::createBottomBoundary
()
const
{
188
return
createIndex2BoundaryAtLine
(0);
189
}
190
191
BoundaryNodeSet
RectilinearMesh3D::createTopBoundary
()
const
{
192
return
createIndex2BoundaryAtLine
(
axis
[2]->
size
()-1);
193
}
194
195
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
{
196
if
(
index1Begin
>=
index1End
||
index2Begin
>=
index2End
)
197
return
new
EmptyBoundaryImpl
();
198
if
(
isChangeSlower
(1, 2))
199
return
new
BoundaryNodeSetRangeImpl<1, 2>
(*
this
,
line_nr_axis0
,
index1Begin
,
index2Begin
,
index1End
,
index2End
);
200
else
201
return
new
BoundaryNodeSetRangeImpl<2, 1>
(*
this
,
line_nr_axis0
,
index1Begin
,
index2Begin
,
index2End
,
index1End
);
202
}
203
204
BoundaryNodeSet
RectilinearMesh3D::createBackOfBoundary
(
const
Box3D
&
box
)
const
{
205
std::size_t line,
begInd1
,
endInd1
,
begInd2
,
endInd2
;
206
if
(
details::getLineLo
(line, *
axis
[0],
box
.lower.c0,
box
.upper.c0) &&
207
details::getIndexesInBounds
(
begInd1
,
endInd1
, *
axis
[1],
box
.lower.c1,
box
.upper.c1) &&
208
details::getIndexesInBounds
(
begInd2
,
endInd2
, *
axis
[2],
box
.lower.c2,
box
.upper.c2))
209
return
createIndex0BoundaryAtLine
(line,
begInd1
,
endInd1
,
begInd2
,
endInd2
);
210
else
211
return
new
EmptyBoundaryImpl
();
212
}
213
214
BoundaryNodeSet
RectilinearMesh3D::createFrontOfBoundary
(
const
Box3D
&
box
)
const
{
215
std::size_t line,
begInd1
,
endInd1
,
begInd2
,
endInd2
;
216
if
(
details::getLineHi
(line, *
axis
[0],
box
.lower.c0,
box
.upper.c0) &&
217
details::getIndexesInBounds
(
begInd1
,
endInd1
, *
axis
[1],
box
.lower.c1,
box
.upper.c1) &&
218
details::getIndexesInBounds
(
begInd2
,
endInd2
, *
axis
[2],
box
.lower.c2,
box
.upper.c2))
219
return
createIndex0BoundaryAtLine
(line,
begInd1
,
endInd1
,
begInd2
,
endInd2
);
220
else
221
return
new
EmptyBoundaryImpl
();
222
}
223
224
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
225
{
226
if
(
index0Begin
>=
index0End
||
index2Begin
>=
index2End
)
227
return
new
EmptyBoundaryImpl
();
228
if
(
isChangeSlower
(0, 2))
229
return
new
BoundaryNodeSetRangeImpl<0, 2>
(*
this
,
index0Begin
,
line_nr_axis1
,
index2Begin
,
index0End
,
index2End
);
230
else
231
return
new
BoundaryNodeSetRangeImpl<2, 0>
(*
this
,
index0Begin
,
line_nr_axis1
,
index2Begin
,
index2End
,
index0End
);
232
}
233
234
BoundaryNodeSet
RectilinearMesh3D::createLeftOfBoundary
(
const
Box3D
&
box
)
const
{
235
std::size_t line,
begInd0
,
endInd0
,
begInd2
,
endInd2
;
236
if
(
details::getLineLo
(line, *
axis
[1],
box
.lower.c1,
box
.upper.c1) &&
237
details::getIndexesInBounds
(
begInd0
,
endInd0
, *
axis
[0],
box
.lower.c0,
box
.upper.c0) &&
238
details::getIndexesInBounds
(
begInd2
,
endInd2
, *
axis
[2],
box
.lower.c2,
box
.upper.c2))
239
return
createIndex1BoundaryAtLine
(line,
begInd0
,
endInd0
,
begInd2
,
endInd2
);
240
else
241
return
new
EmptyBoundaryImpl
();
242
}
243
244
BoundaryNodeSet
RectilinearMesh3D::createRightOfBoundary
(
const
Box3D
&
box
)
const
{
245
std::size_t line,
begInd0
,
endInd0
,
begInd2
,
endInd2
;
246
if
(
details::getLineHi
(line, *
axis
[1],
box
.lower.c1,
box
.upper.c1) &&
247
details::getIndexesInBounds
(
begInd0
,
endInd0
, *
axis
[0],
box
.lower.c0,
box
.upper.c0) &&
248
details::getIndexesInBounds
(
begInd2
,
endInd2
, *
axis
[2],
box
.lower.c2,
box
.upper.c2))
249
return
createIndex1BoundaryAtLine
(line,
begInd0
,
endInd0
,
begInd2
,
endInd2
);
250
else
251
return
new
EmptyBoundaryImpl
();
252
}
253
254
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
255
{
256
if
(
index0Begin
>=
index0End
||
index1Begin
>=
index1End
)
257
return
new
EmptyBoundaryImpl
();
258
if
(
isChangeSlower
(0, 1))
259
return
new
BoundaryNodeSetRangeImpl<0, 1>
(*
this
,
index0Begin
,
index1Begin
,
line_nr_axis2
,
index0End
,
index1End
);
260
else
261
return
new
BoundaryNodeSetRangeImpl<1, 0>
(*
this
,
index0Begin
,
index1Begin
,
line_nr_axis2
,
index1End
,
index0End
);
262
}
263
264
BoundaryNodeSet
RectilinearMesh3D::createBottomOfBoundary
(
const
Box3D
&
box
)
const
{
265
std::size_t line,
begInd0
,
endInd0
,
begInd1
,
endInd1
;
266
if
(
details::getLineLo
(line, *
axis
[2],
box
.lower.c2,
box
.upper.c2) &&
267
details::getIndexesInBounds
(
begInd0
,
endInd0
, *
axis
[0],
box
.lower.c0,
box
.upper.c0) &&
268
details::getIndexesInBounds
(
begInd1
,
endInd1
, *
axis
[1],
box
.lower.c1,
box
.upper.c1))
269
return
createIndex2BoundaryAtLine
(line,
begInd0
,
endInd0
,
begInd1
,
endInd1
);
270
else
271
return
new
EmptyBoundaryImpl
();
272
}
273
274
BoundaryNodeSet
RectilinearMesh3D::createTopOfBoundary
(
const
Box3D
&
box
)
const
{
275
std::size_t line,
begInd0
,
endInd0
,
begInd1
,
endInd1
;
276
if
(
details::getLineHi
(line, *
axis
[2],
box
.lower.c2,
box
.upper.c2) &&
277
details::getIndexesInBounds
(
begInd0
,
endInd0
, *
axis
[0],
box
.lower.c0,
box
.upper.c0) &&
278
details::getIndexesInBounds
(
begInd1
,
endInd1
, *
axis
[1],
box
.lower.c1,
box
.upper.c1))
279
return
createIndex2BoundaryAtLine
(line,
begInd0
,
endInd0
,
begInd1
,
endInd1
);
280
else
281
return
new
EmptyBoundaryImpl
();
282
}
283
284
}
// namespace plask
285
286
287
288
plask
mesh
rectilinear3d.cpp
Generated by
1.9.8