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
19namespace 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
41
42
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) {
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
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 :
72}
73
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 }
85}
86
87void RectilinearMesh3D::onAxisChanged(Mesh::Event &e) {
88 assert(!e.isDelete());
89 fireChanged(e.flags());
90}
91
93 : axis{plask::make_shared<OrderedAxis>(), plask::make_shared<OrderedAxis>(), plask::make_shared<OrderedAxis>()} {
95 setChangeSignal(this->axis[0]);
96 setChangeSignal(this->axis[1]);
97 setChangeSignal(this->axis[2]);
98}
99
100RectilinearMesh3D::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{
104 setChangeSignal(this->axis[0]);
105 setChangeSignal(this->axis[1]);
106 setChangeSignal(this->axis[2]);
107}
108
109void 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);
114}
115
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{
123 setChangeSignal(this->axis[0]);
124 setChangeSignal(this->axis[1]);
125 setChangeSignal(this->axis[2]);
126}
127
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
137 unsetChangeSignal(this->axis[0]);
138 unsetChangeSignal(this->axis[1]);
139 unsetChangeSignal(this->axis[2]);
140}
141
142void 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
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
160
164
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
175
179
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
190
194
203
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))
210 else
211 return new EmptyBoundaryImpl();
212}
213
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))
220 else
221 return new EmptyBoundaryImpl();
222}
223
233
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))
240 else
241 return new EmptyBoundaryImpl();
242}
243
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))
250 else
251 return new EmptyBoundaryImpl();
252}
253
263
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))
270 else
271 return new EmptyBoundaryImpl();
272}
273
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))
280 else
281 return new EmptyBoundaryImpl();
282}
283
284} // namespace plask
285
286
287
288