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
22 namespace plask {
23
29shared_ptr<MeshAxis> readMeshAxis(XMLReader& reader);
30
31 namespace details {
32
41 inline bool getLineLo(std::size_t& line, const MeshAxis& axis, double box_lower, double box_upper) {
42 assert(box_lower <= box_upper);
43 line = axis.findIndex(box_lower);
44 return line != axis.size() && axis[line] <= box_upper;
45}
46
55 inline bool getLineHi(std::size_t& line, const MeshAxis& axis, double box_lower, double box_upper) {
56 assert(box_lower <= 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
72 inline 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
86 inline 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
97 inline 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
110 inline bool getIndexesInBoundsExt(std::size_t& begInd, std::size_t& endInd, const MeshAxis& axis, double box_lower, double box_upper) {
111 getIndexesInBounds(begInd, endInd, axis, box_lower, box_upper);
112 tryMakeLower(axis, begInd, box_lower);
113 tryMakeHigher(axis, endInd, box_upper);
114 return begInd != endInd;
115}
116
124 template <typename MeshType, typename GetBoxes, typename GetBoundaryForBox>
125 inline typename MeshType::Boundary getBoundaryForBoxes(GetBoxes getBoxes, GetBoundaryForBox 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
174 template <typename Boundary, int DIM>
175 inline Boundary parseBoundaryFromXML(XMLReader& boundary_desc, Manager& manager, Boundary (*getXBoundary)(),
176 Boundary (*getXOfBoundary)(shared_ptr<const GeometryObject>, const PathHints*)) {
177 plask::optional<std::string> of = boundary_desc.getAttribute("object");
178 if (!of) {
179 boundary_desc.requireTagEnd();
180 return getXBoundary();
181 } else {
182 plask::optional<std::string> path_name = boundary_desc.getAttribute("path");
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
191 struct PLASK_API RectangularMeshBase2D: public MeshD<2> {
192
194 typedef plask::Boundary<RectangularMeshBase2D> Boundary;
195
196 template <typename Predicate>
197 static Boundary getBoundary(Predicate predicate) {
198 return Boundary(new PredicateBoundaryImpl<RectangularMeshBase2D, Predicate>(predicate));
199 }
200
206 virtual BoundaryNodeSet createVerticalBoundaryAtLine(std::size_t line_nr_axis0) const = 0;
207
213 static Boundary getVerticalBoundaryAtLine(std::size_t line_nr_axis0) {
214 return Boundary( [line_nr_axis0](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
215 return mesh.createVerticalBoundaryAtLine(line_nr_axis0);
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>>&) {
235 return mesh.createVerticalBoundaryAtLine(line_nr_axis0, indexBegin, indexEnd);
236 } );
237 }
238
244 virtual BoundaryNodeSet createVerticalBoundaryNear(double axis0_coord) const = 0;
245
251 static Boundary getVerticalBoundaryNear(double axis0_coord) {
252 return Boundary( [axis0_coord](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
253 return mesh.createVerticalBoundaryNear(axis0_coord);
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
281 virtual BoundaryNodeSet createLeftBoundary() const = 0;
282
287 static Boundary getLeftBoundary() {
288 return Boundary( [](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
289 return mesh.createLeftBoundary();
290 } );
291 }
292
297 virtual BoundaryNodeSet createRightBoundary() const = 0;
298
299
304 static Boundary getRightBoundary() {
305 return Boundary( [](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
306 return mesh.createRightBoundary();
307 } );
308 }
309
315 virtual BoundaryNodeSet createLeftOfBoundary(const Box2D& box) const = 0;
316
322 static Boundary getLeftOfBoundary(const Box2D& box) {
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
334 virtual BoundaryNodeSet createRightOfBoundary(const Box2D& box) const = 0;
335
341 static Boundary getRightOfBoundary(const Box2D& box) {
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
353 virtual BoundaryNodeSet createBottomOfBoundary(const Box2D& box) const = 0;
354
360 static Boundary getBottomOfBoundary(const Box2D& box) {
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
379 static Boundary getTopOfBoundary(const Box2D& box) {
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
392 static Boundary getLeftOfBoundary(shared_ptr<const GeometryObject> object, const PathHints& path) {
393 return details::getBoundaryForBoxes< RectangularMeshBase2D >(
394 [=](const shared_ptr<const GeometryD<2>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
395 [](const Box2D& box) { return RectangularMeshBase2D::getLeftOfBoundary(box); }
396 );
397 }
398
404 static Boundary getLeftOfBoundary(shared_ptr<const GeometryObject> object) {
405 return details::getBoundaryForBoxes< RectangularMeshBase2D >(
406 [=](const shared_ptr<const GeometryD<2>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
407 [](const Box2D& box) { return RectangularMeshBase2D::getLeftOfBoundary(box); }
408 );
409 }
410
417 static Boundary getLeftOfBoundary(shared_ptr<const GeometryObject> object, const PathHints* path) {
418 return path ? getLeftOfBoundary(object, *path) : getLeftOfBoundary(object);
419 }
420
427 static Boundary getRightOfBoundary(shared_ptr<const GeometryObject> object, const PathHints& path) {
428 return details::getBoundaryForBoxes< RectangularMeshBase2D >(
429 [=](const shared_ptr<const GeometryD<2>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
430 [](const Box2D& box) { return RectangularMeshBase2D::getRightOfBoundary(box); }
431 );
432 }
433
439 static Boundary getRightOfBoundary(shared_ptr<const GeometryObject> object) {
440 return details::getBoundaryForBoxes< RectangularMeshBase2D >(
441 [=](const shared_ptr<const GeometryD<2>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
442 [](const Box2D& box) { return RectangularMeshBase2D::getRightOfBoundary(box); }
443 );
444 }
445
452 static Boundary getRightOfBoundary(shared_ptr<const GeometryObject> object, const PathHints* path) {
453 return path ? getRightOfBoundary(object, *path) : getRightOfBoundary(object);
454 }
455
462 static Boundary getBottomOfBoundary(shared_ptr<const GeometryObject> object, const PathHints& path) {
463 return details::getBoundaryForBoxes< RectangularMeshBase2D >(
464 [=](const shared_ptr<const GeometryD<2>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
465 [](const Box2D& box) { return RectangularMeshBase2D::getBottomOfBoundary(box); }
466 );
467 }
468
474 static Boundary getBottomOfBoundary(shared_ptr<const GeometryObject> object) {
475 return details::getBoundaryForBoxes< RectangularMeshBase2D >(
476 [=](const shared_ptr<const GeometryD<2>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
477 [](const Box2D& box) { return RectangularMeshBase2D::getBottomOfBoundary(box); }
478 );
479 }
480
487 static Boundary getBottomOfBoundary(shared_ptr<const GeometryObject> object, const PathHints* path) {
488 return path ? getBottomOfBoundary(object, *path) : getBottomOfBoundary(object);
489 }
490
497 static Boundary getTopOfBoundary(shared_ptr<const GeometryObject> object, const PathHints& path) {
498 return details::getBoundaryForBoxes< RectangularMeshBase2D >(
499 [=](const shared_ptr<const GeometryD<2>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
500 [](const Box2D& box) { return RectangularMeshBase2D::getTopOfBoundary(box); }
501 );
502 }
503
509 static Boundary getTopOfBoundary(shared_ptr<const GeometryObject> object) {
510 return details::getBoundaryForBoxes< RectangularMeshBase2D >(
511 [=](const shared_ptr<const GeometryD<2>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
512 [](const Box2D& box) { return RectangularMeshBase2D::getTopOfBoundary(box); }
513 );
514 }
515
522 static Boundary getTopOfBoundary(shared_ptr<const GeometryObject> object, const PathHints* path) {
523 return path ? getTopOfBoundary(object, *path) : getTopOfBoundary(object);
524 }
525
531 virtual BoundaryNodeSet createHorizontalBoundaryAtLine(std::size_t line_nr_axis1) const = 0;
532
538 static Boundary getHorizontalBoundaryAtLine(std::size_t line_nr_axis1) {
539 return Boundary( [line_nr_axis1](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
540 return mesh.createHorizontalBoundaryAtLine(line_nr_axis1);
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>>&) {
560 return mesh.createHorizontalBoundaryAtLine(line_nr_axis1, indexBegin, indexEnd);
561 } );
562 }
563
569 virtual BoundaryNodeSet createHorizontalBoundaryNear(double axis1_coord) const = 0;
570
576 static Boundary getHorizontalBoundaryNear(double axis1_coord) {
577 return Boundary( [axis1_coord](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
578 return mesh.createHorizontalBoundaryNear(axis1_coord);
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
606 virtual BoundaryNodeSet createTopBoundary() const = 0;
607
612 static Boundary getTopBoundary() {
613 return Boundary( [](const RectangularMeshBase2D& mesh, const shared_ptr<const GeometryD<2>>&) {
614 return mesh.createTopBoundary();
615 } );
616 }
617
622 virtual BoundaryNodeSet createBottomBoundary() const = 0;
623
628 static Boundary getBottomBoundary() {
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
640 template <>
641 inline RectangularMeshBase2D::Boundary parseBoundary<RectangularMeshBase2D::Boundary>(const std::string& boundary_desc, plask::Manager&) { return RectangularMeshBase2D::getBoundary(boundary_desc); }
642
643 template <>
644 inline RectangularMeshBase2D::Boundary parseBoundary<RectangularMeshBase2D::Boundary>(XMLReader& boundary_desc, Manager& env) { return RectangularMeshBase2D::getBoundary(boundary_desc, env); }
645
646 struct PLASK_API RectangularMeshBase3D: public MeshD<3> {
647
649 typedef plask::Boundary<RectangularMeshBase3D> Boundary;
650
651 template <typename Predicate>
652 static Boundary getBoundary(Predicate predicate) {
653 return Boundary(new PredicateBoundaryImpl<RectangularMeshBase3D, Predicate>(predicate));
654 }
655
661 virtual BoundaryNodeSet createIndex0BoundaryAtLine(std::size_t line_nr_axis0) const = 0;
662
668 static Boundary getIndex0BoundaryAtLine(std::size_t line_nr_axis0) {
669 return Boundary( [line_nr_axis0](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
670 return mesh.createIndex0BoundaryAtLine(line_nr_axis0);
671 } );
672 }
673
680 virtual BoundaryNodeSet createIndex0BoundaryAtLine(std::size_t line_nr_axis0,
681 std::size_t index1Begin, std::size_t index1End,
682 std::size_t index2Begin, std::size_t index2End
683 ) const = 0;
684
691 static Boundary getIndex0BoundaryAtLine(std::size_t line_nr_axis0,
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>>&) {
695 return mesh.createIndex0BoundaryAtLine(line_nr_axis0, index1Begin, index1End, index2Begin, index2End);
696 } );
697 }
698
704 virtual BoundaryNodeSet createIndex1BoundaryAtLine(std::size_t line_nr_axis1) const = 0;
705
711 static Boundary getIndex1BoundaryAtLine(std::size_t line_nr_axis1) {
712 return Boundary( [line_nr_axis1](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
713 return mesh.createIndex1BoundaryAtLine(line_nr_axis1);
714 } );
715 }
716
723 virtual BoundaryNodeSet createIndex1BoundaryAtLine(std::size_t line_nr_axis1,
724 std::size_t index0Begin, std::size_t index0End,
725 std::size_t index2Begin, std::size_t index2End
726 ) const = 0;
727
734 static Boundary getIndex1BoundaryAtLine(std::size_t line_nr_axis1,
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>>&) {
738 return mesh.createIndex1BoundaryAtLine(line_nr_axis1, index0Begin, index0End, index2Begin, index2End);
739 } );
740 }
741
747 virtual BoundaryNodeSet createIndex2BoundaryAtLine(std::size_t line_nr_axis2) const = 0;
748
754 static Boundary getIndex2BoundaryAtLine(std::size_t line_nr_axis2) {
755 return Boundary( [line_nr_axis2](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
756 return mesh.createIndex2BoundaryAtLine(line_nr_axis2);
757 } );
758 }
759
766 virtual BoundaryNodeSet createIndex2BoundaryAtLine(std::size_t line_nr_axis2,
767 std::size_t index0Begin, std::size_t index0End,
768 std::size_t index1Begin, std::size_t index1End
769 ) const = 0;
770
777 static Boundary getIndex2BoundaryAtLine(std::size_t line_nr_axis2,
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>>&) {
781 return mesh.createIndex2BoundaryAtLine(line_nr_axis2, index0Begin, index0End, index1Begin, index1End);
782 } );
783 }
784
789 virtual BoundaryNodeSet createBackBoundary() const = 0;
790
795 static Boundary getBackBoundary() {
796 return Boundary( [](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
797 return mesh.createBackBoundary();
798 } );
799 }
800
806 virtual BoundaryNodeSet createBackOfBoundary(const Box3D& box) const = 0;
807
813 static Boundary getBackOfBoundary(const Box3D& box) {
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
824 virtual BoundaryNodeSet createFrontBoundary() const = 0;
825
830 static Boundary getFrontBoundary() {
831 return Boundary( [](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
832 return mesh.createFrontBoundary();
833 } );
834 }
835
841 virtual BoundaryNodeSet createFrontOfBoundary(const Box3D& box) const = 0;
842
848 static Boundary getFrontOfBoundary(const Box3D& box) {
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
859 virtual BoundaryNodeSet createLeftBoundary() const = 0;
860
865 static Boundary getLeftBoundary() {
866 return Boundary( [](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
867 return mesh.createLeftBoundary();
868 } );
869 }
870
876 virtual BoundaryNodeSet createLeftOfBoundary(const Box3D& box) const = 0;
877
883 static Boundary getLeftOfBoundary(const Box3D& box) {
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
894 virtual BoundaryNodeSet createRightBoundary() const = 0;
895
896
901 static Boundary getRightBoundary() {
902 return Boundary( [](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
903 return mesh.createRightBoundary();
904 } );
905 }
906
912 virtual BoundaryNodeSet createRightOfBoundary(const Box3D& box) const = 0;
913
919 static Boundary getRightOfBoundary(const Box3D& box) {
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
930 virtual BoundaryNodeSet createTopBoundary() const = 0;
931
936 static Boundary getTopBoundary() {
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
954 static Boundary getTopOfBoundary(const Box3D& box) {
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
965 virtual BoundaryNodeSet createBottomBoundary() const = 0;
966
971 static Boundary getBottomBoundary() {
972 return Boundary( [](const RectangularMeshBase3D& mesh, const shared_ptr<const GeometryD<3>>&) {
973 return mesh.createBottomBoundary();
974 } );
975 }
976
982 virtual BoundaryNodeSet createBottomOfBoundary(const Box3D& box) const = 0;
983
989 static Boundary getBottomOfBoundary(const Box3D& box) {
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
1003 static Boundary getLeftOfBoundary(shared_ptr<const GeometryObject> object, const PathHints& path) {
1004 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1005 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
1006 [](const Box3D& box) { return RectangularMeshBase3D::getLeftOfBoundary(box); }
1007 );
1008 }
1009
1017 static Boundary getLeftOfBoundary(shared_ptr<const GeometryObject> object, const PathHints* path) {
1018 return path ? getLeftOfBoundary(object, *path) : getLeftOfBoundary(object);
1019 }
1020
1027 static Boundary getLeftOfBoundary(shared_ptr<const GeometryObject> object) {
1028 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1029 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
1030 [](const Box3D& box) { return RectangularMeshBase3D::getLeftOfBoundary(box); }
1031 );
1032 }
1033
1041 static Boundary getRightOfBoundary(shared_ptr<const GeometryObject> object, const PathHints& path) {
1042 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1043 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
1044 [](const Box3D& box) { return RectangularMeshBase3D::getRightOfBoundary(box); }
1045 );
1046 }
1047
1055 static Boundary getRightOfBoundary(shared_ptr<const GeometryObject> object, const PathHints* path) {
1056 return path ? getRightOfBoundary(object, *path) : getRightOfBoundary(object);
1057 }
1058
1065 static Boundary getRightOfBoundary(shared_ptr<const GeometryObject> object) {
1066 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1067 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
1068 [](const Box3D& box) { return RectangularMeshBase3D::getRightOfBoundary(box); }
1069 );
1070 }
1071
1079 static Boundary getBottomOfBoundary(shared_ptr<const GeometryObject> object, const PathHints& path) {
1080 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1081 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
1082 [](const Box3D& box) { return RectangularMeshBase3D::getBottomOfBoundary(box); }
1083 );
1084 }
1085
1093 static Boundary getBottomOfBoundary(shared_ptr<const GeometryObject> object, const PathHints* path) {
1094 return path ? getBottomOfBoundary(object, *path) : getBottomOfBoundary(object);
1095 }
1096
1103 static Boundary getBottomOfBoundary(shared_ptr<const GeometryObject> object) {
1104 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1105 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
1106 [](const Box3D& box) { return RectangularMeshBase3D::getBottomOfBoundary(box); }
1107 );
1108 }
1109
1117 static Boundary getTopOfBoundary(shared_ptr<const GeometryObject> object, const PathHints& path) {
1118 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1119 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
1120 [](const Box3D& box) { return RectangularMeshBase3D::getTopOfBoundary(box); }
1121 );
1122 }
1123
1130 static Boundary getTopOfBoundary(shared_ptr<const GeometryObject> object) {
1131 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1132 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
1133 [](const Box3D& box) { return RectangularMeshBase3D::getTopOfBoundary(box); }
1134 );
1135 }
1136
1144 static Boundary getTopOfBoundary(shared_ptr<const GeometryObject> object, const PathHints* path) {
1145 return path ? getTopOfBoundary(object, *path) : getTopOfBoundary(object);
1146 }
1147
1155 static Boundary getBackOfBoundary(shared_ptr<const GeometryObject> object, const PathHints& path) {
1156 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1157 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
1158 [](const Box3D& box) { return RectangularMeshBase3D::getBackOfBoundary(box); }
1159 );
1160 }
1161
1168 static Boundary getBackOfBoundary(shared_ptr<const GeometryObject> object) {
1169 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1170 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
1171 [](const Box3D& box) { return RectangularMeshBase3D::getBackOfBoundary(box); }
1172 );
1173 }
1174
1182 static Boundary getBackOfBoundary(shared_ptr<const GeometryObject> object, const PathHints* path) {
1183 return path ? getBackOfBoundary(object, *path) : getBackOfBoundary(object);
1184 }
1185
1193 static Boundary getFrontOfBoundary(shared_ptr<const GeometryObject> object, const PathHints& path) {
1194 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1195 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object, path); },
1196 [](const Box3D& box) { return RectangularMeshBase3D::getFrontOfBoundary(box); }
1197 );
1198 }
1199
1206 static Boundary getFrontOfBoundary(shared_ptr<const GeometryObject> object) {
1207 return details::getBoundaryForBoxes< RectangularMeshBase3D >(
1208 [=](const shared_ptr<const GeometryD<3>>& geometry) { return geometry->getObjectBoundingBoxes(object); },
1209 [](const Box3D& box) { return RectangularMeshBase3D::getFrontOfBoundary(box); }
1210 );
1211 }
1212
1220 static Boundary getFrontOfBoundary(shared_ptr<const GeometryObject> object, const PathHints* path) {
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
1229 template <>
1230 inline RectangularMeshBase3D::Boundary parseBoundary<RectangularMeshBase3D::Boundary>(const std::string& boundary_desc, plask::Manager&) { return RectangularMeshBase3D::getBoundary(boundary_desc); }
1231
1232 template <>
1233 inline RectangularMeshBase3D::Boundary parseBoundary<RectangularMeshBase3D::Boundary>(XMLReader& boundary_desc, Manager& env) { return RectangularMeshBase3D::getBoundary(boundary_desc, env); }
1234
1235
1236 template <int DIM>
1237 using RectangularMeshBase =
1238 typename std::conditional<
1239 DIM == 2,
1240 RectangularMeshBase2D,
1241 typename std::conditional<DIM == 3, RectangularMeshBase3D, void>::type
1242 >::type;
1243
1244} // namespace plask
1245
1246#endif // PLASK__MESH__RECTANGULAR_COMMON_H