PLaSK library

Loading...
Searching...
No Matches
boundary.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__BOUNDARY_H
15#define PLASK__BOUNDARY_H
16
85#include "../utils/iterators.hpp"
86#include "../utils/xml/reader.hpp"
87#include "../memory.hpp"
88#include "../log/log.hpp"
89
90#include "../exceptions.hpp"
91#include "../geometry/space.hpp"
92#include <vector>
93#include <set>
94
95 namespace plask {
96
101 struct PLASK_API BoundaryNodeSetImpl {
102
104 typedef PolymorphicForwardIteratorImpl<std::size_t, std::size_t> IteratorImpl;
105
107 typedef PolymorphicForwardIterator<IteratorImpl> Iterator;
108
110 typedef Iterator const_iterator;
111 typedef const_iterator iterator;
112
113 virtual ~BoundaryNodeSetImpl() {}
114
120 virtual bool contains(std::size_t mesh_index) const = 0;
121
126 virtual const_iterator begin() const = 0;
127
132 virtual const_iterator end() const = 0;
133
138 virtual bool empty() const { return begin() == end(); }
139
146 virtual std::size_t size() const { return std::size_t(std::distance(begin(), end())); }
147
148};
149
155 template <typename MeshType>
156 struct BoundaryNodeSetWithMeshImpl: public BoundaryNodeSetImpl {
157
159 typedef typename BoundaryNodeSetImpl::const_iterator const_iterator;
160
162 typedef typename BoundaryNodeSetImpl::iterator iterator;
163
165 const MeshType& mesh;
166
171 BoundaryNodeSetWithMeshImpl(const MeshType& mesh)
172 : mesh(mesh) {}
173
179 struct IteratorWithMeshImpl: public BoundaryNodeSetImpl::IteratorImpl {
180
181 const BoundaryNodeSetWithMeshImpl<MeshType>& boundaryWithMesh;
182
183 const BoundaryNodeSetWithMeshImpl<MeshType>& getBoundary() const { return boundaryWithMesh; }
184 const MeshType& getMesh() const { return boundaryWithMesh.mesh; }
185
186 IteratorWithMeshImpl(const BoundaryNodeSetWithMeshImpl<MeshType>& boundaryImpl)
187 : boundaryWithMesh(boundaryImpl) {}
188 };
189
190};
191
195 struct PLASK_API BoundaryNodeSet: public HolderRef< const BoundaryNodeSetImpl > {
196
197 typedef typename BoundaryNodeSetImpl::const_iterator const_iterator;
198 typedef typename BoundaryNodeSetImpl::iterator iterator;
199
204 BoundaryNodeSet(const BoundaryNodeSetImpl* to_hold = nullptr): HolderRef< const BoundaryNodeSetImpl >(to_hold) {}
205
206 virtual ~BoundaryNodeSet() {}
207
213 bool contains(std::size_t mesh_index) const {
214 return this->held->contains(mesh_index);
215 }
216
221 const_iterator begin() const {
222 return this->held->begin();
223 }
224
229 const_iterator end() const {
230 return this->held->end();
231 }
232
237 std::size_t size() const {
238 return this->held->size();
239 }
240
245 virtual bool empty() const { return this->held->empty(); }
246
247};
248
254 struct PLASK_API EmptyBoundaryImpl: public BoundaryNodeSetImpl {
255
256 struct IteratorImpl: public BoundaryNodeSetImpl::IteratorImpl {
257
258 std::size_t dereference() const override {
259 throw Exception("dereference of empty boundary iterator.");
260 }
261
262 void increment() override {}
263
264 bool equal(const typename BoundaryNodeSetImpl::IteratorImpl& PLASK_UNUSED(other)) const override {
265 return true;
266 }
267
268 std::unique_ptr<typename BoundaryNodeSetImpl::IteratorImpl> clone() const override {
269 return std::unique_ptr<typename BoundaryNodeSetImpl::IteratorImpl>(new IteratorImpl);
270 }
271
272 };
273
274 bool contains(std::size_t PLASK_UNUSED(mesh_index)) const override { return false; }
275
276 typename BoundaryNodeSetImpl::const_iterator begin() const override {
277 return typename BoundaryNodeSetImpl::Iterator(new IteratorImpl);
278 }
279
280 typename BoundaryNodeSetImpl::const_iterator end() const override {
281 return typename BoundaryNodeSetImpl::Iterator(new IteratorImpl);
282 }
283
284 std::size_t size() const override {
285 return 0;
286 }
287
288 bool empty() const override { return true; }
289};
290
295 struct PLASK_API StdSetBoundaryImpl: public BoundaryNodeSetImpl {
296
297 typedef std::set<std::size_t> StdNodeSet;
298
299 typedef PolymorphicForwardIteratorWrapperImpl<StdNodeSet::const_iterator, std::size_t, std::size_t> IteratorImpl;
300
301 StdNodeSet set;
302
303 StdSetBoundaryImpl(StdNodeSet set): set(std::move(set)) {}
304
305 bool contains(std::size_t mesh_index) const override {
306 return set.find(mesh_index) != set.end();
307 }
308
309 typename BoundaryNodeSetImpl::const_iterator begin() const override {
310 return typename BoundaryNodeSetImpl::Iterator(new IteratorImpl(set.begin()));
311 }
312
313 typename BoundaryNodeSetImpl::const_iterator end() const override {
314 return typename BoundaryNodeSetImpl::Iterator(new IteratorImpl(set.end()));
315 }
316
317 std::size_t size() const override {
318 return set.size();
319 }
320
321 bool empty() const override {
322 return set.empty();
323 }
324};
325
326// TODO może wykluczyć MeshType jako parametr szablonu i dodać w zamian DIM (używać MeshD)?
335 template <typename MeshT>
336 struct Boundary {
337
338 typedef MeshT MeshType;
339
340 protected:
341 std::function<BoundaryNodeSet(const MeshType&, const shared_ptr<const GeometryD<MeshType::DIM>>&)> create;
342
343 public:
344
345 //template <typename... T>
346 //Boundary(T&&... args): create(std::forward<T>(args)...) {}
347
348 Boundary(std::function<BoundaryNodeSet(const MeshType&, const shared_ptr<const GeometryD<MeshType::DIM>>&)> create_fun): create(create_fun) {}
349
351 Boundary() {}
352
353 //Boundary(const Boundary<MeshType>&) = default;
354 //Boundary(Boundary<MeshType>&&) = default;
355
361 BoundaryNodeSet operator()(const MeshType& mesh, const shared_ptr<const GeometryD<MeshType::DIM>>& geometry) const {
362 if (isNull()) return new EmptyBoundaryImpl();
363 return this->create(mesh, geometry);
364 }
365
371 BoundaryNodeSet operator()(const shared_ptr<const MeshType>& mesh, const shared_ptr<const GeometryD<MeshType::DIM>>& geometry) const {
372 if (isNull()) return new EmptyBoundaryImpl();
373 return this->create(*mesh, geometry);
374 }
375
381 BoundaryNodeSet get(const MeshType& mesh, const shared_ptr<const GeometryD<MeshType::DIM>>& geometry) const {
382 if (isNull()) return new EmptyBoundaryImpl();
383 return this->create(mesh, geometry);
384 }
385
391 BoundaryNodeSet get(const shared_ptr<const MeshType>& mesh, const shared_ptr<const GeometryD<MeshType::DIM>>& geometry) const {
392 if (isNull()) return new EmptyBoundaryImpl();
393 return this->create(*mesh, geometry);
394 }
395
401 bool empty(const MeshType& mesh) const {
402 if (isNull()) return true;
403 return get(mesh).empty();
404 }
405
410 bool isNull() const {
411 return !create;
412 }
413};
414
416 template <typename MeshType, typename OpNodeSetImplT>
417 struct BoundaryOp {
418
419 Boundary<MeshType> A, B;
420
421 BoundaryOp(Boundary<MeshType> A, Boundary<MeshType> B): A(std::move(A)), B(std::move(B)) {}
422
423 BoundaryNodeSet operator()(const MeshType& mesh, const shared_ptr<const GeometryD<MeshType::DIM>>& geom) const {
424 return new OpNodeSetImplT(A.get(mesh, geom), B.get(mesh, geom));
425 }
426};
427
431 struct UnionBoundarySetImpl: public BoundaryNodeSetImpl {
432
433 typedef std::vector< BoundaryNodeSet > BoundariesVec;
434 BoundariesVec boundaries;
435
436 struct IteratorImpl: public BoundaryNodeSetImpl::IteratorImpl {
437
438 struct IteratorWithEnd {
439 BoundaryNodeSet::const_iterator iter;
440 BoundaryNodeSet::const_iterator end;
441
442 IteratorWithEnd(BoundaryNodeSet::const_iterator iter, BoundaryNodeSet::const_iterator end)
443 : iter(std::move(iter)), end(std::move(end)) {}
444
445 bool valid() const { return iter != end; }
446
447 bool operator==(const IteratorWithEnd& o) const { return iter == o.iter; }
448 };
449
450 std::vector<IteratorWithEnd> position;
451
452 bool equal(const typename BoundaryNodeSetImpl::IteratorImpl &other) const override {
453 const IteratorImpl& o = static_cast<const IteratorImpl&>(other);
454 return position.size() == o.position.size() && std::equal(position.begin(), position.end(), o.position.begin());
455 }
456
457 std::unique_ptr<BoundaryNodeSetImpl::IteratorImpl> clone() const override {
458 return std::unique_ptr<BoundaryNodeSetImpl::IteratorImpl>(new IteratorImpl(*this));
459 }
460
461 private:
462 std::size_t minimal_position() const {
463 std::size_t minimum = std::numeric_limits<std::size_t>::max();
464 for (const IteratorWithEnd& v: position)
465 if (v.valid()) {
466 auto vv = *v.iter;
467 if (vv < minimum) minimum = vv;
468 }
469 return minimum;
470 }
471
472 public:
473 std::size_t dereference() const override {
474 return minimal_position();
475 }
476
477 void increment() override {
478 std::size_t m = minimal_position();
479 for (IteratorWithEnd& v: position)
480 if (v.valid() && *v.iter == m) ++v.iter;
481 }
482
483 };
484
485 template <typename... Args>
486 UnionBoundarySetImpl(Args&&... args):
487 boundaries(std::forward<Args>(args)...) { }
488
489 UnionBoundarySetImpl(BoundaryNodeSet A, BoundaryNodeSet B)
490 : boundaries(std::initializer_list<plask::BoundaryNodeSet>{A, B}) {}
491
492 bool contains(std::size_t mesh_index) const override {
493 for (auto& b: boundaries)
494 if (b.contains(mesh_index)) return true;
495 return false;
496 }
497
498 typename BoundaryNodeSetImpl::Iterator begin() const override {
499 std::unique_ptr<IteratorImpl> impl(new IteratorImpl());
500 impl->position.reserve(boundaries.size());
501 for (const BoundaryNodeSet& b: boundaries)
502 impl->position.emplace_back(b.begin(), b.end());
503 return typename BoundaryNodeSetImpl::Iterator(impl.release());
504 }
505
506 typename BoundaryNodeSetImpl::Iterator end() const override {
507 std::unique_ptr<IteratorImpl> impl(new IteratorImpl());
508 impl->position.reserve(boundaries.size());
509 for (const BoundaryNodeSet& b: boundaries)
510 impl->position.emplace_back(b.end(), b.end());
511 return typename BoundaryNodeSetImpl::Iterator(impl.release());
512 }
513
514 bool empty() const override {
515 for (auto bound: boundaries)
516 if (!bound.empty()) return false;
517 return true;
518 }
519
520 /*std::size_t size() const override {
521 std::size_t s = 0;
522 for (auto bound: boundaries) s += bound.size();
523 return s;
524 }*/
525
526 void push_back(const BoundaryNodeSet& to_append) { boundaries.push_back(to_append); }
527
528 void push_back(BoundaryNodeSet&& to_append) { boundaries.push_back(std::move(to_append)); }
529
530};
531
535 struct DiffBoundarySetImpl: public BoundaryNodeSetImpl {
536
537 BoundaryNodeSet A, B;
538
539 struct IteratorImpl: public BoundaryNodeSetImpl::IteratorImpl {
540
541 struct IteratorWithEnd {
542 BoundaryNodeSet::const_iterator iter;
543 BoundaryNodeSet::const_iterator end;
544
545 IteratorWithEnd(BoundaryNodeSet::const_iterator iter, BoundaryNodeSet::const_iterator end)
546 : iter(std::move(iter)), end(std::move(end)) {}
547
548 bool valid() const { return iter != end; }
549
550 bool operator==(const IteratorWithEnd& o) const { return iter == o.iter; }
551 };
552
553 IteratorWithEnd Apos, Bpos;
554
555 private:
556 void advanceAtoNearestValidPos() {
557 while (Apos.valid()) {
558 const std::size_t Aindex = *Apos.iter;
559 while (true) {
560 if (!Bpos.valid()) return; // accept current Apos
561 const std::size_t Bindex = *Bpos.iter;
562 if (Bindex == Aindex) break; // go to next A index
563 if (Bindex > Aindex) return; // accept current Apos
564 // here Bindex < Aindex
565 ++Bpos.iter; // go to next B index
566 }
567 ++Apos.iter;
568 }
569 }
570
571 public:
572
573 IteratorImpl(BoundaryNodeSet::const_iterator Aiter, BoundaryNodeSet::const_iterator Aend,
574 BoundaryNodeSet::const_iterator Biter, BoundaryNodeSet::const_iterator Bend):
575 Apos(std::move(Aiter), std::move(Aend)), Bpos(std::move(Biter), std::move(Bend))
576 {
577 advanceAtoNearestValidPos();
578 }
579
580 bool equal(const typename BoundaryNodeSetImpl::IteratorImpl &other) const override {
581 const IteratorImpl& o = static_cast<const IteratorImpl&>(other);
582 return Apos == o.Apos;
583 }
584
585 std::unique_ptr<BoundaryNodeSetImpl::IteratorImpl> clone() const override {
586 return std::unique_ptr<BoundaryNodeSetImpl::IteratorImpl>(new IteratorImpl(*this));
587 }
588
589 std::size_t dereference() const override {
590 return *Apos.iter;
591 }
592
593 void increment() override {
594 ++Apos.iter;
595 advanceAtoNearestValidPos();
596 }
597
598 };
599
600 DiffBoundarySetImpl(BoundaryNodeSet A, BoundaryNodeSet B):
601 A(std::move(A)), B(std::move(B)) { }
602
603 bool contains(std::size_t mesh_index) const override {
604 return A.contains(mesh_index) && !B.contains(mesh_index);
605 }
606
607 typename BoundaryNodeSetImpl::Iterator begin() const override {
608 return typename BoundaryNodeSetImpl::Iterator(new IteratorImpl(A.begin(), A.end(), B.begin(), B.end()));
609 }
610
611 typename BoundaryNodeSetImpl::Iterator end() const override {
612 return typename BoundaryNodeSetImpl::Iterator(new IteratorImpl(A.end(), A.end(), B.end(), B.end()));
613 }
614
615 bool empty() const override {
616 return begin() == end();
617 }
618
619};
620
621
625 struct IntersectionBoundarySetImpl: public BoundaryNodeSetImpl {
626
627 BoundaryNodeSet A, B;
628
629 struct IteratorImpl: public BoundaryNodeSetImpl::IteratorImpl {
630
631 struct IteratorWithEnd {
632 BoundaryNodeSet::const_iterator iter;
633 BoundaryNodeSet::const_iterator end;
634
635 IteratorWithEnd(BoundaryNodeSet::const_iterator iter, BoundaryNodeSet::const_iterator end)
636 : iter(std::move(iter)), end(std::move(end)) {}
637
638 bool valid() const { return iter != end; }
639
640 bool operator==(const IteratorWithEnd& o) const { return iter == o.iter; }
641 };
642
643 IteratorWithEnd Apos, Bpos;
644
645 private:
646 void advanceToNearestValidPos() {
647 while (Apos.valid()) {
648 if (!Bpos.valid()) {
649 Apos.iter = Apos.end;
650 return;
651 }
652 const std::size_t Aindex = *Apos.iter;
653 const std::size_t Bindex = *Bpos.iter;
654 if (Aindex == Bindex) return;
655 if (Aindex < Bindex) ++Apos.iter; else ++Bpos.iter;
656 }
657 }
658
659 public:
660
661 IteratorImpl(BoundaryNodeSet::const_iterator Aiter, BoundaryNodeSet::const_iterator Aend,
662 BoundaryNodeSet::const_iterator Biter, BoundaryNodeSet::const_iterator Bend):
663 Apos(std::move(Aiter), std::move(Aend)), Bpos(std::move(Biter), std::move(Bend))
664 {
665 advanceToNearestValidPos();
666 }
667
668 bool equal(const typename BoundaryNodeSetImpl::IteratorImpl &other) const override {
669 const IteratorImpl& o = static_cast<const IteratorImpl&>(other);
670 return Apos == o.Apos;
671 }
672
673 std::unique_ptr<BoundaryNodeSetImpl::IteratorImpl> clone() const override {
674 return std::unique_ptr<BoundaryNodeSetImpl::IteratorImpl>(new IteratorImpl(*this));
675 }
676
677 std::size_t dereference() const override {
678 return *Apos.iter;
679 }
680
681 void increment() override {
682 ++Apos.iter;
683 ++Bpos.iter;
684 advanceToNearestValidPos();
685 }
686
687 };
688
689 IntersectionBoundarySetImpl(BoundaryNodeSet A, BoundaryNodeSet B):
690 A(std::move(A)), B(std::move(B)) { }
691
692 bool contains(std::size_t mesh_index) const override {
693 return A.contains(mesh_index) && B.contains(mesh_index);
694 }
695
696 typename BoundaryNodeSetImpl::Iterator begin() const override {
697 return typename BoundaryNodeSetImpl::Iterator(new IteratorImpl(A.begin(), A.end(), B.begin(), B.end()));
698 }
699
700 typename BoundaryNodeSetImpl::Iterator end() const override {
701 return typename BoundaryNodeSetImpl::Iterator(new IteratorImpl(A.end(), A.end(), B.end(), B.end()));
702 }
703
704 bool empty() const override {
705 return begin() == end();
706 }
707
708};
709
711 template <typename MeshType> using UnionBoundary = BoundaryOp<MeshType, UnionBoundarySetImpl>;
712
714 template <typename MeshType> using DiffBoundary = BoundaryOp<MeshType, DiffBoundarySetImpl>;
715
717 template <typename MeshType> using IntersectionBoundary = BoundaryOp<MeshType, IntersectionBoundarySetImpl>;
718
720
725 inline BoundaryNodeSet operator+(BoundaryNodeSet left, BoundaryNodeSet right) {
726 return new UnionBoundarySetImpl(std::move(left), std::move(right));
727}
728 inline BoundaryNodeSet operator|(BoundaryNodeSet left, BoundaryNodeSet right) {
729 return new UnionBoundarySetImpl(std::move(left), std::move(right));
730}
732
734
739 inline BoundaryNodeSet operator*(BoundaryNodeSet left, BoundaryNodeSet right) {
740 return new IntersectionBoundarySetImpl(std::move(left), std::move(right));
741}
742 inline BoundaryNodeSet operator&(BoundaryNodeSet left, BoundaryNodeSet right) {
743 return new IntersectionBoundarySetImpl(std::move(left), std::move(right));
744}
746
752 inline BoundaryNodeSet operator-(BoundaryNodeSet left, BoundaryNodeSet right) {
753 return new DiffBoundarySetImpl(std::move(left), std::move(right));
754}
755
757
762 template <typename MeshType>
763 inline Boundary<MeshType> operator+(Boundary<MeshType> left, Boundary<MeshType> right) {
764 return Boundary<MeshType>(UnionBoundary<MeshType>(std::move(left), std::move(right)));
765}
766 template <typename MeshType>
767 inline Boundary<MeshType> operator|(Boundary<MeshType> left, Boundary<MeshType> right) {
768 return Boundary<MeshType>(UnionBoundary<MeshType>(std::move(left), std::move(right)));
769}
771
773
778 template <typename MeshType>
779 inline Boundary<MeshType> operator*(Boundary<MeshType> left, Boundary<MeshType> right) {
780 return Boundary<MeshType>(IntersectionBoundary<MeshType>(std::move(left), std::move(right)));
781}
782 template <typename MeshType>
783 inline Boundary<MeshType> operator&(Boundary<MeshType> left, Boundary<MeshType> right) {
784 return Boundary<MeshType>(IntersectionBoundary<MeshType>(std::move(left), std::move(right)));
785}
787
793 template <typename MeshType>
794 inline Boundary<MeshType> operator-(Boundary<MeshType> left, Boundary<MeshType> right) {
795 return Boundary<MeshType>(DiffBoundary<MeshType>(std::move(left), std::move(right)));
796}
797
804 template <typename MeshT, typename Predicate>
805 struct PredicateBoundaryImpl: public BoundaryNodeSetWithMeshImpl<typename MeshT::Boundary::MeshType> {
806
807 typedef typename MeshT::Boundary::MeshType MeshType;
808
809 struct PredicateIteratorImpl: public BoundaryNodeSetWithMeshImpl<MeshType>::IteratorWithMeshImpl {
810
811 typedef decltype(std::begin(std::declval<MeshType>())) MeshBeginIterator;
812 typedef decltype(std::end(std::declval<MeshType>())) MeshEndIterator;
813
814 MeshBeginIterator meshIterator;
815 MeshEndIterator meshIteratorEnd;
816
817 PredicateIteratorImpl(const BoundaryNodeSetWithMeshImpl<MeshType>& boundary, MeshBeginIterator meshIterator):
818 BoundaryNodeSetWithMeshImpl<MeshType>::IteratorWithMeshImpl(boundary),
819 meshIterator(meshIterator),
820 meshIteratorEnd(std::end(boundary.mesh)) {
821 while (this->meshIterator != meshIteratorEnd && !check_predicate())
822 ++this->meshIterator; //go to first element which fulfill predicate
823 }
824
825 std::size_t dereference() const override {
826 return meshIterator.getIndex();
827 }
828
829 private:
830 bool check_predicate() {
831 return static_cast<const PredicateBoundaryImpl&>(this->getBoundary())
832 .predicate(this->getMesh(), meshIterator.getIndex());
833 }
834
835 public:
836
837 void increment() override {
838 do {
839 ++meshIterator;
840 } while (meshIterator != meshIteratorEnd && !check_predicate());
841 }
842
843 bool equal(const typename BoundaryNodeSetImpl::IteratorImpl& other) const override {
844 return meshIterator == static_cast<const PredicateIteratorImpl&>(other).meshIterator;
845 }
846
847 std::unique_ptr<typename BoundaryNodeSetImpl::IteratorImpl> clone() const override {
848 return std::unique_ptr<typename BoundaryNodeSetImpl::IteratorImpl>(new PredicateIteratorImpl(*this));
849 }
850
851 };
852
854 Predicate predicate;
855
861 PredicateBoundaryImpl(const MeshType& mesh, Predicate predicate):
862 BoundaryNodeSetWithMeshImpl<MeshType>(mesh), predicate(predicate) {}
863
864 //virtual PredicateBoundary<MeshType, Predicate>* clone() const { return new PredicateBoundary<MeshType, Predicate>(predicate); }
865
866 private:
867 bool check_predicate(std::size_t mesh_index) const {
868 return predicate(this->mesh, mesh_index);
869 }
870
871 public:
872
873 bool contains(std::size_t mesh_index) const override {
874 return this->check_predicate(mesh_index);
875 }
876
877 typename BoundaryNodeSetImpl::Iterator begin() const override {
878 return typename BoundaryNodeSetImpl::Iterator(new PredicateIteratorImpl(*this, std::begin(this->mesh)));
879 }
880
881 typename BoundaryNodeSetImpl::Iterator end() const override {
882 return typename BoundaryNodeSetImpl::Iterator(new PredicateIteratorImpl(*this, std::end(this->mesh)));
883 }
884
885};
886
892 template <typename MeshType>
893 inline typename MeshType::Boundary makeEmptyBoundary() {
894 return typename MeshType::Boundary(
895 [](const MeshType&, const shared_ptr<const GeometryD<MeshType::DIM>>&) { return new EmptyBoundaryImpl(); }
896 );
897}
898
899
909 template <typename Boundary, typename Predicate>
910 inline Boundary makePredicateBoundary(Predicate predicate) {
911 return Boundary( [=](const typename Boundary::MeshType& mesh, const shared_ptr<const GeometryD<Boundary::MeshType::DIM>>&) {
912 return new PredicateBoundaryImpl<typename Boundary::MeshType, Predicate>(mesh, predicate);
913 } );
914}
915
916 struct Manager;
917
918
931 template <typename Boundary>
932 inline Boundary parseBoundary(const std::string& PLASK_UNUSED(boundary_desc), Manager& PLASK_UNUSED(manager)) { return Boundary(); }
933
934
949 template <typename Boundary>
950 inline Boundary parseBoundary(XMLReader& PLASK_UNUSED(boundary_desc), Manager& PLASK_UNUSED(manager)) { return Boundary(); }
951
952} // namespace plask
953
954#endif // PLASK__BOUNDARY_H