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
95namespace plask {
96
102
105
108
112
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
155template <typename MeshType>
191
195struct PLASK_API BoundaryNodeSet: public HolderRef< const BoundaryNodeSetImpl > {
196
199
205
206 virtual ~BoundaryNodeSet() {}
207
213 bool contains(std::size_t mesh_index) const {
214 return this->held->contains(mesh_index);
215 }
216
222 return this->held->begin();
223 }
224
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
255
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
296
297 typedef std::set<std::size_t> StdNodeSet;
298
300
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)?
335template <typename MeshT>
336struct Boundary {
337
339
340protected:
341 std::function<BoundaryNodeSet(const MeshType&, const shared_ptr<const GeometryD<MeshType::DIM>>&)> create;
342
343public:
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
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
416template <typename MeshType, typename OpNodeSetImplT>
418
420
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
432
433 typedef std::vector< BoundaryNodeSet > BoundariesVec;
435
437
441
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();
480 if (v.valid() && *v.iter == m) ++v.iter;
481 }
482
483 };
484
485 template <typename... Args>
488
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
527
528 void push_back(BoundaryNodeSet&& to_append) { boundaries.push_back(std::move(to_append)); }
529
530};
531
536
538
540
544
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
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
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
602
603 bool contains(std::size_t mesh_index) const override {
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
626
628
630
634
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
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
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
691
692 bool contains(std::size_t mesh_index) const override {
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
712
714template <typename MeshType> using DiffBoundary = BoundaryOp<MeshType, DiffBoundarySetImpl>;
715
718
720
726 return new UnionBoundarySetImpl(std::move(left), std::move(right));
727}
729 return new UnionBoundarySetImpl(std::move(left), std::move(right));
730}
732
734
740 return new IntersectionBoundarySetImpl(std::move(left), std::move(right));
741}
743 return new IntersectionBoundarySetImpl(std::move(left), std::move(right));
744}
746
753 return new DiffBoundarySetImpl(std::move(left), std::move(right));
754}
755
757
762template <typename MeshType>
764 return Boundary<MeshType>(UnionBoundary<MeshType>(std::move(left), std::move(right)));
765}
766template <typename MeshType>
768 return Boundary<MeshType>(UnionBoundary<MeshType>(std::move(left), std::move(right)));
769}
771
773
778template <typename MeshType>
780 return Boundary<MeshType>(IntersectionBoundary<MeshType>(std::move(left), std::move(right)));
781}
782template <typename MeshType>
784 return Boundary<MeshType>(IntersectionBoundary<MeshType>(std::move(left), std::move(right)));
785}
787
793template <typename MeshType>
795 return Boundary<MeshType>(DiffBoundary<MeshType>(std::move(left), std::move(right)));
796}
797
804template <typename MeshT, typename Predicate>
805struct 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
816
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
863
864 //virtual PredicateBoundary<MeshType, Predicate>* clone() const { return new PredicateBoundary<MeshType, Predicate>(predicate); }
865
866private:
867 bool check_predicate(std::size_t mesh_index) const {
868 return predicate(this->mesh, mesh_index);
869 }
870
871public:
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
892template <typename MeshType>
893inline 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
909template <typename Boundary, typename Predicate>
910inline Boundary makePredicateBoundary(Predicate predicate) {
911 return Boundary( [=](const typename Boundary::MeshType& mesh, const shared_ptr<const GeometryD<Boundary::MeshType::DIM>>&) {
913 } );
914}
915
916struct Manager;
917
918
931template <typename Boundary>
932inline Boundary parseBoundary(const std::string& PLASK_UNUSED(boundary_desc), Manager& PLASK_UNUSED(manager)) { return Boundary(); }
933
934
949template <typename Boundary>
951
952} // namespace plask
953
954#endif // PLASK__BOUNDARY_H