PLaSK library
Loading...
Searching...
No Matches
rectangular2d.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 "rectangular2d.hpp"
15
16#include "regular1d.hpp"
17#include "ordered1d.hpp"
18
19namespace plask {
20
21static std::size_t normal_index(const RectangularMesh2D* mesh, std::size_t index0, std::size_t index1) {
22 return index0 + mesh->axis[0]->size() * index1;
23}
24static std::size_t normal_index0(const RectangularMesh2D* mesh, std::size_t mesh_index) {
25 return mesh_index % mesh->axis[0]->size();
26}
27static std::size_t normal_index1(const RectangularMesh2D* mesh, std::size_t mesh_index) {
28 return mesh_index / mesh->axis[0]->size();
29}
30
31static std::size_t transposed_index(const RectangularMesh2D* mesh, std::size_t index0, std::size_t index1) {
32 return mesh->axis[1]->size() * index0 + index1;
33}
34static std::size_t transposed_index0(const RectangularMesh2D* mesh, std::size_t mesh_index) {
35 return mesh_index / mesh->axis[1]->size();
36}
37static std::size_t transposed_index1(const RectangularMesh2D* mesh, std::size_t mesh_index) {
38 return mesh_index % mesh->axis[1]->size();
39}
40
42 if (iterationOrder == ORDER_01) {
43 index_f = transposed_index;
44 index0_f = transposed_index0;
45 index1_f = transposed_index1;
46 minor_axis = &axis[1];
47 major_axis = &axis[0];
48 } else {
49 index_f = normal_index;
50 index0_f = normal_index0;
51 index1_f = normal_index1;
52 minor_axis = &axis[0];
53 major_axis = &axis[1];
54 }
55 this->fireChanged();
56}
57
59 return (index_f == &transposed_index)? ORDER_01 : ORDER_10;
60}
61
62void RectangularMesh2D::onAxisChanged(Mesh::Event &e) {
63 assert(!e.isDelete());
64 this->fireChanged(e.flags());
65}
66
68 : axis{ plask::make_shared<OrderedAxis>(), plask::make_shared<OrderedAxis>() } {
70 setChangeSignal(this->axis[0]);
71 setChangeSignal(this->axis[1]);
72}
73
75 : axis{ std::move(axis0), std::move(axis1) } {
77 setChangeSignal(this->axis[0]);
78 setChangeSignal(this->axis[1]);
79}
80
81void RectangularMesh2D::reset(shared_ptr<MeshAxis> axis0, shared_ptr<MeshAxis> axis1, RectangularMesh2D::IterationOrder iterationOrder) {
82 setAxis(0, std::move(axis0), false);
83 setAxis(1, std::move(axis1), false);
85}
86
89 axis {clone_axes ? src.axis[0]->clone() : src.axis[0],
90 clone_axes ? src.axis[1]->clone() : src.axis[1]}
91{
93 setChangeSignal(this->axis[0]);
94 setChangeSignal(this->axis[1]);
95}
96
98 if (clone_axes)
99 reset(src.axis[0]->clone(), src.axis[1]->clone(), src.getIterationOrder());
100 else
101 reset(src.axis[0], src.axis[1], src.getIterationOrder());
102}
103
105 unsetChangeSignal(this->axis[0]);
106 unsetChangeSignal(this->axis[1]);
107}
108
109void RectangularMesh2D::setAxis(std::size_t axis_nr, shared_ptr<MeshAxis> new_val, bool fireResized)
110{
111 if (axis[axis_nr] == new_val) return;
112 unsetChangeSignal(axis[axis_nr]);
113 const_cast<shared_ptr<MeshAxis>&>(axis[axis_nr]) = new_val;
114 setChangeSignal(axis[axis_nr]);
115 if (fireResized) this->fireResized();
116}
117
121
123 if (const RectangularMesh2D* c = dynamic_cast<const RectangularMesh2D*>(&to_compare))
124 return *this == *c; // this will call == operator from RectangularMesh2D
126}
127
129 return new VerticalBoundary(*this, line_nr_axis0);
130}
131
133 return new VerticalBoundaryInRange(*this, line_nr_axis0, indexBegin, indexEnd);
134}
135
137 return new VerticalBoundary(*this, axis[0]->findNearestIndex(axis0_coord));
138}
139
141 std::size_t begInd, endInd;
142 if (!details::getIndexesInBoundsExt(begInd, endInd, *axis[1], from, to))
143 return new EmptyBoundaryImpl();
144 return new VerticalBoundaryInRange(*this, axis[0]->findNearestIndex(axis0_coord), begInd, endInd);
145}
146
148 return new VerticalBoundary(*this, 0);
149}
150
152 return new VerticalBoundary(*this, axis[0]->size()-1);
153}
154
156 std::size_t line, begInd, endInd;
157 if (details::getLineLo(line, *axis[0], box.lower.c0, box.upper.c0) &&
158 details::getIndexesInBounds(begInd, endInd, *axis[1], box.lower.c1, box.upper.c1))
159 return new VerticalBoundaryInRange(*this, line, begInd, endInd);
160 else
161 return new EmptyBoundaryImpl();
162}
163
165 std::size_t line, begInd, endInd;
166 if (details::getLineHi(line, *axis[0], box.lower.c0, box.upper.c0) &&
167 details::getIndexesInBounds(begInd, endInd, *axis[1], box.lower.c1, box.upper.c1))
168 return new VerticalBoundaryInRange(*this, line, begInd, endInd);
169 else
170 return new EmptyBoundaryImpl();
171}
172
174 std::size_t line, begInd, endInd;
175 if (details::getLineLo(line, *axis[1], box.lower.c1, box.upper.c1) &&
176 details::getIndexesInBounds(begInd, endInd, *axis[0], box.lower.c0, box.upper.c0))
177 return new HorizontalBoundaryInRange(*this, line, begInd, endInd);
178 else
179 return new EmptyBoundaryImpl();
180}
181
183 std::size_t line, begInd, endInd;
184 if (details::getLineHi(line, *axis[1], box.lower.c1, box.upper.c1) &&
185 details::getIndexesInBounds(begInd, endInd, *axis[0], box.lower.c0, box.upper.c0))
186 return new HorizontalBoundaryInRange(*this, line, begInd, endInd);
187 else
188 return new EmptyBoundaryImpl();
189}
190
192 return new HorizontalBoundary(*this, line_nr_axis1);
193}
194
196 return new HorizontalBoundaryInRange(*this, line_nr_axis1, indexBegin, indexEnd);
197}
198
200 return new HorizontalBoundary(*this, axis[1]->findNearestIndex(axis1_coord));
201}
202
204 std::size_t begInd, endInd;
205 if (!details::getIndexesInBoundsExt(begInd, endInd, *axis[0], from, to))
206 return new EmptyBoundaryImpl();
207 return new HorizontalBoundaryInRange(*this, axis[1]->findNearestIndex(axis1_coord), begInd, endInd);
208}
209
211 return new HorizontalBoundary(*this, axis[1]->size()-1);
212}
213
215 return new HorizontalBoundary(*this, 0);
216}
217
219 object.attr("type", "rectangular2d");
220 { auto a = object.addTag("axis0"); axis[0]->writeXML(a); }
221 { auto a = object.addTag("axis1"); axis[1]->writeXML(a); }
222}
223
227
228static shared_ptr<Mesh> readRectangularMesh2D(XMLReader& reader) {
229 shared_ptr<MeshAxis> axis[2];
230 XMLReader::CheckTagDuplication dub_check;
231 for (int i = 0; i < 2; ++i) {
232 reader.requireTag();
233 std::string node = reader.getNodeName();
234 if (node != "axis0" && node != "axis1") throw XMLUnexpectedElementException(reader, "<axis0> or <axis1>");
235 dub_check(std::string("<mesh>"), node);
236 axis[node[4]-'0'] = readMeshAxis(reader);
237 }
238 reader.requireTagEnd();
239 return plask::make_shared<RectangularMesh2D>(std::move(axis[0]), std::move(axis[1]));
240}
241
242static RegisterMeshReader rectangular2d_reader("rectangular2d", readRectangularMesh2D);
243
244// obsolete:
245static shared_ptr<Mesh> readRectangularMesh2D_obsolete(XMLReader& reader) {
246 writelog(LOG_WARNING, "Mesh type \"{0}\" is obsolete (will not work in future versions of PLaSK), use \"rectangular2d\" instead.", reader.requireAttribute("type"));
247 return readRectangularMesh2D(reader);
248}
249static RegisterMeshReader regularmesh2d_reader("regular2d", readRectangularMesh2D_obsolete);
250static RegisterMeshReader rectilinear2d_reader("rectilinear2d", readRectangularMesh2D_obsolete);
251
254 if (this->originalMesh == c->originalMesh) return true;
256}
257
258} // namespace plask
259
260
261
262
263
264
265
266
267