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 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
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
161
165
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
176
180
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
191
195
204
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))
211 else
212 return new EmptyBoundaryImpl();
213}
214
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))
221 else
222 return new EmptyBoundaryImpl();
223}
224
234
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))
241 else
242 return new EmptyBoundaryImpl();
243}
244
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))
251 else
252 return new EmptyBoundaryImpl();
253}
254
264
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))
271 else
272 return new EmptyBoundaryImpl();
273}
274
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))
281 else
282 return new EmptyBoundaryImpl();
283}
284
285} // namespace plask