PLaSK library

Loading...
Searching...
No Matches
rectangular_masked2d.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 "rectangular_masked2d.hpp"
15
16 namespace plask {
17
18 void RectangularMaskedMesh2D::reset(const RectangularMaskedMesh2D::Predicate &predicate) {
19 RectangularMaskedMeshBase<2>::reset();
20 initNodesAndElements(predicate);
21}
22
23 RectangularMaskedMesh2D::RectangularMaskedMesh2D(const RectangularMesh<2> &rectangularMesh, const RectangularMaskedMesh2D::Predicate &predicate, bool clone_axes)
24 : RectangularMaskedMeshBase(rectangularMesh, clone_axes)
25{
26 initNodesAndElements(predicate);
27}
28
29 void RectangularMaskedMesh2D::reset(const RectangularMesh<2> &rectangularMesh, const RectangularMaskedMesh2D::Predicate &predicate, bool clone_axes) {
30 this->fullMesh.reset(rectangularMesh, clone_axes);
31 reset(predicate);
32}
33
34 RectangularMaskedMesh2D::RectangularMaskedMesh2D(const RectangularMesh<DIM> &rectangularMesh, RectangularMaskedMeshBase::Set nodeSet, bool clone_axes)
35 : RectangularMaskedMeshBase(rectangularMesh, std::move(nodeSet), clone_axes)
36{
37}
38
39 void RectangularMaskedMesh2D::initNodesAndElements(const RectangularMaskedMesh2D::Predicate &predicate)
40{
41 for (auto el_it = this->fullMesh.elements().begin(); el_it != this->fullMesh.elements().end(); ++el_it)
42 if (predicate(*el_it)) {
43 elementSet.push_back(el_it.index);
44 nodeSet.insert(el_it->getLoLoIndex());
45 nodeSet.insert(el_it->getLoUpIndex());
46 nodeSet.insert(el_it->getUpLoIndex());
47 nodeSet.push_back(el_it->getUpUpIndex()); //this is safe also for 10 axis order
48 /*boundaryIndex[0].improveLo(el_it->getLowerIndex0());
49 boundaryIndex[0].improveUp(el_it->getUpperIndex0());
50 boundaryIndex[1].improveLo(el_it->getLowerIndex1());
51 boundaryIndex[1].improveUp(el_it->getUpperIndex1());*/ // this is initialized lazy
52 }
53 nodeSet.shrink_to_fit();
54 elementSet.shrink_to_fit();
55 elementSetInitialized = true;
56}
57
58 bool RectangularMaskedMesh2D::prepareInterpolation(const Vec<2> &point, Vec<2> &wrapped_point, std::size_t &index0_lo, std::size_t &index0_hi, std::size_t &index1_lo, std::size_t &index1_hi, const InterpolationFlags &flags) const {
59 wrapped_point = flags.wrap(point);
60
61 if (!canBeIncluded(wrapped_point)) return false;
62
63 findIndexes(*fullMesh.axis[0], wrapped_point.c0, index0_lo, index0_hi);
64 findIndexes(*fullMesh.axis[1], wrapped_point.c1, index1_lo, index1_hi);
65 assert(index0_hi == index0_lo + 1);
66 assert(index1_hi == index1_lo + 1);
67
68 double lo0 = fullMesh.axis[0]->at(index0_lo), hi0 = fullMesh.axis[0]->at(index0_hi),
69 lo1 = fullMesh.axis[1]->at(index1_lo), hi1 = fullMesh.axis[1]->at(index1_hi);
70
71 ensureHasElements();
72 for (char i1 = 0; i1 < 2; ++i1) {
73 for (char i0 = 0; i0 < 2; ++i0) {
74 if (elementSet.includes(fullMesh.getElementIndexFromLowIndexes(index0_lo, index1_lo))) {
75 index0_hi = index0_lo + 1; index1_hi = index1_lo + 1;
76 return true;
77 }
78 if (index0_lo > 0 && lo0 <= wrapped_point.c0 && wrapped_point.c0 < lo0+MIN_DISTANCE) index0_lo = index0_hi-2;
79 else if (index0_lo < fullMesh.axis[0]->size()-2 && hi0-MIN_DISTANCE < wrapped_point.c0 && wrapped_point.c0 <= hi0) index0_lo = index0_hi;
80 else break;
81 }
82 index0_lo = index0_hi - 1;
83 if (index1_lo > 0 && lo1 <= wrapped_point.c1 && wrapped_point.c1 < lo1+MIN_DISTANCE) index1_lo = index1_hi-2;
84 else if (index1_lo < fullMesh.axis[1]->size()-2 && hi1-MIN_DISTANCE < wrapped_point.c1 && wrapped_point.c1 <= hi1) index1_lo = index1_hi;
85 else break;
86 }
87
88 return false;
89}
90
91
92
93
94 BoundaryNodeSet RectangularMaskedMesh2D::createVerticalBoundaryAtLine(std::size_t line_nr_axis0) const {
95 ensureHasBoundaryIndex();
96 return createVerticalBoundaryAtLine(line_nr_axis0, boundaryIndex[1].lo, boundaryIndex[1].up+1);
97}
98
99 BoundaryNodeSet RectangularMaskedMesh2D::createVerticalBoundaryAtLine(std::size_t line_nr_axis0, std::size_t indexBegin, std::size_t indexEnd) const {
100 return new BoundaryNodeSetImpl<1>(*this, line_nr_axis0, indexBegin, indexEnd);
101}
102
103 BoundaryNodeSet RectangularMaskedMesh2D::createVerticalBoundaryNear(double axis0_coord) const {
104 return createVerticalBoundaryAtLine(fullMesh.axis[0]->findNearestIndex(axis0_coord));
105}
106
107 BoundaryNodeSet RectangularMaskedMesh2D::createVerticalBoundaryNear(double axis0_coord, double from, double to) const {
108 std::size_t begInd, endInd;
109 if (!details::getIndexesInBoundsExt(begInd, endInd, *fullMesh.axis[1], from, to))
110 return new EmptyBoundaryImpl();
111 return createVerticalBoundaryAtLine(fullMesh.axis[0]->findNearestIndex(axis0_coord), begInd, endInd);
112}
113
114 BoundaryNodeSet RectangularMaskedMesh2D::createLeftBoundary() const {
115 return createVerticalBoundaryAtLine(ensureHasBoundaryIndex()[0].lo);
116}
117
118 BoundaryNodeSet RectangularMaskedMesh2D::createRightBoundary() const {
119 return createVerticalBoundaryAtLine(ensureHasBoundaryIndex()[0].up);
120}
121
122 BoundaryNodeSet RectangularMaskedMesh2D::createLeftOfBoundary(const Box2D &box) const {
123 std::size_t line, begInd, endInd;
124 if (details::getLineLo(line, *fullMesh.axis[0], box.lower.c0, box.upper.c0) &&
125 details::getIndexesInBounds(begInd, endInd, *fullMesh.axis[1], box.lower.c1, box.upper.c1))
126 return createVerticalBoundaryAtLine(line, begInd, endInd);
127 else
128 return new EmptyBoundaryImpl();
129}
130
131 BoundaryNodeSet RectangularMaskedMesh2D::createRightOfBoundary(const Box2D &box) const {
132 std::size_t line, begInd, endInd;
133 if (details::getLineHi(line, *fullMesh.axis[0], box.lower.c0, box.upper.c0) &&
134 details::getIndexesInBounds(begInd, endInd, *fullMesh.axis[1], box.lower.c1, box.upper.c1))
135 return createVerticalBoundaryAtLine(line, begInd, endInd);
136 else
137 return new EmptyBoundaryImpl();
138}
139
140 BoundaryNodeSet RectangularMaskedMesh2D::createBottomOfBoundary(const Box2D &box) const {
141 std::size_t line, begInd, endInd;
142 if (details::getLineLo(line, *fullMesh.axis[1], box.lower.c1, box.upper.c1) &&
143 details::getIndexesInBounds(begInd, endInd, *fullMesh.axis[0], box.lower.c0, box.upper.c0))
144 return createHorizontalBoundaryAtLine(line, begInd, endInd);
145 else
146 return new EmptyBoundaryImpl();
147}
148
149 BoundaryNodeSet RectangularMaskedMesh2D::createTopOfBoundary(const Box2D &box) const {
150 std::size_t line, begInd, endInd;
151 if (details::getLineHi(line, *fullMesh.axis[1], box.lower.c1, box.upper.c1) &&
152 details::getIndexesInBounds(begInd, endInd, *fullMesh.axis[0], box.lower.c0, box.upper.c0))
153 return createHorizontalBoundaryAtLine(line, begInd, endInd);
154 else
155 return new EmptyBoundaryImpl();
156}
157
158 BoundaryNodeSet RectangularMaskedMesh2D::createHorizontalBoundaryAtLine(std::size_t line_nr_axis1) const {
159 ensureHasBoundaryIndex();
160 return createHorizontalBoundaryAtLine(line_nr_axis1, boundaryIndex[0].lo, boundaryIndex[0].up+1);
161}
162
163 BoundaryNodeSet RectangularMaskedMesh2D::createHorizontalBoundaryAtLine(std::size_t line_nr_axis1, std::size_t indexBegin, std::size_t indexEnd) const {
164 return new BoundaryNodeSetImpl<0>(*this, indexBegin, line_nr_axis1, indexEnd);
165}
166
167 BoundaryNodeSet RectangularMaskedMesh2D::createHorizontalBoundaryNear(double axis1_coord) const {
168 return createHorizontalBoundaryAtLine(fullMesh.axis[1]->findNearestIndex(axis1_coord));
169}
170
171 BoundaryNodeSet RectangularMaskedMesh2D::createHorizontalBoundaryNear(double axis1_coord, double from, double to) const {
172 std::size_t begInd, endInd;
173 if (!details::getIndexesInBoundsExt(begInd, endInd, *fullMesh.axis[0], from, to))
174 return new EmptyBoundaryImpl();
175 return createHorizontalBoundaryAtLine(fullMesh.axis[1]->findNearestIndex(axis1_coord), begInd, endInd);
176}
177
178 BoundaryNodeSet RectangularMaskedMesh2D::createTopBoundary() const {
179 return createHorizontalBoundaryAtLine(ensureHasBoundaryIndex()[1].up);
180}
181
182 BoundaryNodeSet RectangularMaskedMesh2D::createBottomBoundary() const {
183 return createHorizontalBoundaryAtLine(ensureHasBoundaryIndex()[1].lo);
184}
185
186} // namespace plask