PLaSK library
Loading...
Searching...
No Matches
rectangular_common.hpp
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#ifndef PLASK__MESH__RECTANGULAR_COMMON_H
15#define PLASK__MESH__RECTANGULAR_COMMON_H
16
17#include "boundary.hpp"
18#include "ordered1d.hpp"
19#include "../geometry/path.hpp"
20#include "../manager.hpp"
21
22namespace plask {
23
29shared_ptr<MeshAxis> readMeshAxis(XMLReader& reader);
30
31namespace details {
32
41inline bool getLineLo(std::size_t& line, const MeshAxis& axis, double box_lower, double box_upper) {
43 line = axis.findIndex(box_lower);
44 return line != axis.size() && axis[line] <= box_upper;
45}
46
55inline bool getLineHi(std::size_t& line, const MeshAxis& axis, double box_lower, double box_upper) {
57 line = axis.findIndex(box_upper);
58 if (line != axis.size() && axis[line] == box_upper) return true;
59 if (line == 0) return false;
60 --line;
61 return axis[line] >= box_lower;
62}
63
72inline bool getIndexesInBounds(std::size_t& begInd, std::size_t& endInd, const MeshAxis& axis, double box_lower, double box_upper) {
73 if(box_lower > box_upper) return false;
74 begInd = axis.findIndex(box_lower);
75 endInd = axis.findIndex(box_upper);
76 if (endInd != axis.size() && axis[endInd] == box_upper) ++endInd; // endInd is excluded
77 return begInd != endInd;
78}
79
86inline void tryMakeLower(const MeshAxis& axis, std::size_t& index, double real_pos) {
87 if (index == 0) return;
88 if ((real_pos - axis[index-1]) * 100.0 < (axis[index] - axis[index-1])) --index;
89}
90
97inline void tryMakeHigher(const MeshAxis& axis, std::size_t& index, double real_pos) {
98 if (index == axis.size() || index == 0) return; //index == 0 means empty mesh
99 if ((axis[index] - real_pos) * 100.0 < (axis[index] - axis[index-1])) ++index;
100}
101
110inline bool getIndexesInBoundsExt(std::size_t& begInd, std::size_t& endInd, const MeshAxis& axis, double box_lower, double box_upper) {
114 return begInd != endInd;
115}
116
124template <typename MeshType, typename GetBoxes, typename GetBoundaryForBox>
126 return typename MeshType::Boundary(
127 [=](const MeshType& mesh, const shared_ptr<const GeometryD<MeshType::DIM>>& geometry) -> BoundaryNodeSet {
128 std::vector<typename MeshType::Boundary> boundaries;
129 std::vector<BoundaryNodeSet> boundaries_with_meshes;
130 auto boxes = getBoxes(geometry); // probably std::vector<BoxdirD>
131 for (auto& box: boxes) {
132 typename MeshType::Boundary boundary = getBoundaryForBox(box);
133 BoundaryNodeSet boundary_with_mesh = boundary(mesh, geometry);
134 if (!boundary_with_mesh.empty()) {
135 boundaries.push_back(std::move(boundary));
136 boundaries_with_meshes.push_back(std::move(boundary_with_mesh));
137 }
138 }
139 if (boundaries.empty()) return new EmptyBoundaryImpl();
140 if (boundaries.size() == 1) return boundaries_with_meshes[0];
141 return new UnionBoundarySetImpl(std::move(boundaries_with_meshes));
142 }
143 );
144}
145
146/*struct GetObjectBoundingBoxesCaller {
147
148 shared_ptr<const GeometryObject> object;
149 std::unique_ptr<PathHints> path;
150
151 GetObjectBoundingBoxesCaller(shared_ptr<const GeometryObject> object, const PathHints* path)
152 : object(object), path(path ? new PathHints(*path) : nullptr)
153 {}
154
155 auto operator()(const shared_ptr<const GeometryD<2>>& geometry) const -> decltype(geometry->getObjectBoundingBoxes(object)) {
156 return geometry->getObjectBoundingBoxes(object, path.get());
157 }
158
159 auto operator()(const shared_ptr<const GeometryD<3>>& geometry) const -> decltype(geometry->getObjectBoundingBoxes(object)) {
160 return geometry->getObjectBoundingBoxes(object, path.get());
161 }
162
163};*/
164
174template <typename Boundary, int DIM>
177 plask::optional<std::string> of = boundary_desc.getAttribute("object");
178 if (!of) {
179 boundary_desc.requireTagEnd();
180 return getXBoundary();
181 } else {
183 boundary_desc.requireTagEnd();
184 return getXOfBoundary(manager.requireGeometryObject(*of),
185 path_name ? &manager.requirePathHints(*path_name) : nullptr);
186 }
187}
188
189} // namespace details
190
192
195
196 template <typename Predicate>
197 static Boundary getBoundary(Predicate predicate) {
199 }
200
207
214 return Boundary( [line_nr_axis0](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
216 } );
217 }
218
225 virtual BoundaryNodeSet createVerticalBoundaryAtLine(std::size_t line_nr_axis0, std::size_t indexBegin, std::size_t indexEnd) const = 0;
226
233 static Boundary getVerticalBoundaryAtLine(std::size_t line_nr_axis0, std::size_t indexBegin, std::size_t indexEnd) {
234 return Boundary( [=](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
236 } );
237 }
238
245
252 return Boundary( [axis0_coord](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
254 } );
255 }
256
263 virtual BoundaryNodeSet createVerticalBoundaryNear(double axis0_coord, double from, double to) const = 0;
264
271 static Boundary getVerticalBoundaryNear(double axis0_coord, double from, double to) {
272 return Boundary( [axis0_coord, from, to](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
273 return mesh.createVerticalBoundaryNear(axis0_coord, from, to);
274 } );
275 }
276
282
288 return Boundary( [](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
289 return mesh.createLeftBoundary();
290 } );
291 }
292
298
299
305 return Boundary( [](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
306 return mesh.createRightBoundary();
307 } );
308 }
309
316
323 if (!box.isValid()) return makeEmptyBoundary<RectangularMeshBase2D>();
324 return Boundary( [=](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
325 return mesh.createLeftOfBoundary(box);
326 } );
327 }
328
335
342 if (!box.isValid()) return makeEmptyBoundary<RectangularMeshBase2D>();
343 return Boundary( [=](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
344 return mesh.createRightOfBoundary(box);
345 } );
346 }
347
354
361 if (!box.isValid()) return makeEmptyBoundary<RectangularMeshBase2D>();
362 return Boundary( [=](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
363 return mesh.createBottomOfBoundary(box);
364 } );
365 }
366
372 virtual BoundaryNodeSet createTopOfBoundary(const Box2D& box) const = 0;
373
380 if (!box.isValid()) return makeEmptyBoundary<RectangularMeshBase2D>();
381 return Boundary( [=](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
382 return mesh.createTopOfBoundary(box);
383 } );
384 }
385
393 return details::getBoundaryForBoxes< RectangularMeshBase2D >(
394 [=](const shared_ptr<const GeometryD<2>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
396 );
397 }
398
405 return details::getBoundaryForBoxes< RectangularMeshBase2D >(
406 [=](const shared_ptr<const GeometryD<2>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
408 );
409 }
410
418 return path ? getLeftOfBoundary(object, *path) : getLeftOfBoundary(object);
419 }
420
428 return details::getBoundaryForBoxes< RectangularMeshBase2D >(
429 [=](const shared_ptr<const GeometryD<2>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
431 );
432 }
433
440 return details::getBoundaryForBoxes< RectangularMeshBase2D >(
441 [=](const shared_ptr<const GeometryD<2>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
443 );
444 }
445
453 return path ? getRightOfBoundary(object, *path) : getRightOfBoundary(object);
454 }
455
463 return details::getBoundaryForBoxes< RectangularMeshBase2D >(
464 [=](const shared_ptr<const GeometryD<2>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
466 );
467 }
468
475 return details::getBoundaryForBoxes< RectangularMeshBase2D >(
476 [=](const shared_ptr<const GeometryD<2>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
478 );
479 }
480
488 return path ? getBottomOfBoundary(object, *path) : getBottomOfBoundary(object);
489 }
490
498 return details::getBoundaryForBoxes< RectangularMeshBase2D >(
499 [=](const shared_ptr<const GeometryD<2>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
501 );
502 }
503
510 return details::getBoundaryForBoxes< RectangularMeshBase2D >(
511 [=](const shared_ptr<const GeometryD<2>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
513 );
514 }
515
523 return path ? getTopOfBoundary(object, *path) : getTopOfBoundary(object);
524 }
525
532
539 return Boundary( [line_nr_axis1](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
541 } );
542 }
543
550 virtual BoundaryNodeSet createHorizontalBoundaryAtLine(std::size_t line_nr_axis1, std::size_t indexBegin, std::size_t indexEnd) const = 0;
551
558 static Boundary getHorizontalBoundaryAtLine(std::size_t line_nr_axis1, std::size_t indexBegin, std::size_t indexEnd) {
559 return Boundary( [=](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
561 } );
562 }
563
570
577 return Boundary( [axis1_coord](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
579 } );
580 }
581
588 virtual BoundaryNodeSet createHorizontalBoundaryNear(double axis1_coord, double from, double to) const = 0;
589
596 static Boundary getHorizontalBoundaryNear(double axis1_coord, double from, double to) {
597 return Boundary( [axis1_coord, from, to](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
598 return mesh.createHorizontalBoundaryNear(axis1_coord, from, to);
599 } );
600 }
601
607
613 return Boundary( [](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
614 return mesh.createTopBoundary();
615 } );
616 }
617
623
629 return Boundary( [](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
630 return mesh.createBottomBoundary();
631 } );
632 }
633
634 static Boundary getBoundary(const std::string &boundary_desc);
635
636 static Boundary getBoundary(XMLReader &boundary_desc, Manager &manager);
637
638};
639
640template <>
642
643template <>
645
647
650
651 template <typename Predicate>
652 static Boundary getBoundary(Predicate predicate) {
654 }
655
662
669 return Boundary( [line_nr_axis0](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
671 } );
672 }
673
681 std::size_t index1Begin, std::size_t index1End,
682 std::size_t index2Begin, std::size_t index2End
683 ) const = 0;
684
692 std::size_t index1Begin, std::size_t index1End,
693 std::size_t index2Begin, std::size_t index2End) {
694 return Boundary( [=](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
696 } );
697 }
698
705
712 return Boundary( [line_nr_axis1](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
714 } );
715 }
716
724 std::size_t index0Begin, std::size_t index0End,
725 std::size_t index2Begin, std::size_t index2End
726 ) const = 0;
727
735 std::size_t index0Begin, std::size_t index0End,
736 std::size_t index2Begin, std::size_t index2End) {
737 return Boundary( [=](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
739 } );
740 }
741
748
755 return Boundary( [line_nr_axis2](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
757 } );
758 }
759
767 std::size_t index0Begin, std::size_t index0End,
768 std::size_t index1Begin, std::size_t index1End
769 ) const = 0;
770
778 std::size_t index0Begin, std::size_t index0End,
779 std::size_t index1Begin, std::size_t index1End) {
780 return Boundary( [=](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
782 } );
783 }
784
790
796 return Boundary( [](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
797 return mesh.createBackBoundary();
798 } );
799 }
800
807
814 if (!box.isValid()) return makeEmptyBoundary<RectangularMeshBase3D>();
815 return Boundary( [=](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
816 return mesh.createBackOfBoundary(box);
817 } );
818 }
819
825
831 return Boundary( [](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
832 return mesh.createFrontBoundary();
833 } );
834 }
835
842
849 if (!box.isValid()) return makeEmptyBoundary<RectangularMeshBase3D>();
850 return Boundary( [=](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
851 return mesh.createFrontOfBoundary(box);
852 } );
853 }
854
860
866 return Boundary( [](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
867 return mesh.createLeftBoundary();
868 } );
869 }
870
877
884 if (!box.isValid()) return makeEmptyBoundary<RectangularMeshBase3D>();
885 return Boundary( [=](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
886 return mesh.createLeftOfBoundary(box);
887 } );
888 }
889
895
896
902 return Boundary( [](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
903 return mesh.createRightBoundary();
904 } );
905 }
906
913
920 if (!box.isValid()) return makeEmptyBoundary<RectangularMeshBase3D>();
921 return Boundary( [=](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
922 return mesh.createLeftOfBoundary(box);
923 } );
924 }
925
931
937 return Boundary( [](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
938 return mesh.createTopBoundary();
939 } );
940 }
941
947 virtual BoundaryNodeSet createTopOfBoundary(const Box3D& box) const = 0;
948
955 if (!box.isValid()) return makeEmptyBoundary<RectangularMeshBase3D>();
956 return Boundary( [=](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
957 return mesh.createTopOfBoundary(box);
958 } );
959 }
960
966
972 return Boundary( [](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
973 return mesh.createBottomBoundary();
974 } );
975 }
976
983
990 if (!box.isValid()) return makeEmptyBoundary<RectangularMeshBase3D>();
991 return Boundary( [=](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
992 return mesh.createBottomOfBoundary(box);
993 } );
994 }
995
1004 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1005 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
1007 );
1008 }
1009
1018 return path ? getLeftOfBoundary(object, *path) : getLeftOfBoundary(object);
1019 }
1020
1028 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1029 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
1031 );
1032 }
1033
1042 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1043 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
1045 );
1046 }
1047
1056 return path ? getRightOfBoundary(object, *path) : getRightOfBoundary(object);
1057 }
1058
1066 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1067 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
1069 );
1070 }
1071
1080 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1081 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
1083 );
1084 }
1085
1094 return path ? getBottomOfBoundary(object, *path) : getBottomOfBoundary(object);
1095 }
1096
1104 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1105 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
1107 );
1108 }
1109
1118 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1119 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
1121 );
1122 }
1123
1131 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1132 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
1134 );
1135 }
1136
1145 return path ? getTopOfBoundary(object, *path) : getTopOfBoundary(object);
1146 }
1147
1156 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1157 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
1159 );
1160 }
1161
1169 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1170 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
1172 );
1173 }
1174
1183 return path ? getBackOfBoundary(object, *path) : getBackOfBoundary(object);
1184 }
1185
1194 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1195 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
1197 );
1198 }
1199
1207 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1208 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
1210 );
1211 }
1212
1221 return path ? getFrontOfBoundary(object, *path) : getFrontOfBoundary(object);
1222 }
1223
1224 static Boundary getBoundary(const std::string &boundary_desc);
1225
1226 static Boundary getBoundary(XMLReader &boundary_desc, Manager &manager);
1227};
1228
1229template <>
1231
1232template <>
1234
1235
1236template <int DIM>
1238 typename std::conditional<
1239 DIM == 2,
1241 typename std::conditional<DIM == 3, RectangularMeshBase3D, void>::type
1242 >::type;
1243
1244} // namespace plask
1245
1246#endif // PLASK__MESH__RECTANGULAR_COMMON_H