PLaSK library

Loading...
Searching...
No Matches
boundary_conditions.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_CONDITIONS_H
15#define PLASK__BOUNDARY_CONDITIONS_H
16
17#include <list>
18#include "../exceptions.hpp"
19#include "boundary.hpp"
20
21 namespace plask {
22
24 template <typename BoundaryT, typename ValueT>
25 struct BoundaryCondition {
26 typedef BoundaryT Boundary;
27 typedef typename Boundary::MeshType MeshType;
28 typedef ValueT ValueType;
29
30 Boundary place;
31 ValueType value;
32
38 template <typename... ConditionArgumentsTypes>
39 BoundaryCondition(const Boundary& place, ConditionArgumentsTypes&&... value_args)
40 : place(place),
41 value(std::forward<ConditionArgumentsTypes>(value_args)...) {}
42
48 template <typename... ConditionArgumentsTypes>
49 BoundaryCondition(Boundary&& place, ConditionArgumentsTypes&&... value_args)
50 : place(std::forward<Boundary>(place)),
51 value(std::forward<ConditionArgumentsTypes>(value_args)...) {}
52};
53
54
56 template <typename BoundaryT, typename ValueT>
57 struct BoundaryConditionWithMesh {
58 typedef BoundaryT Boundary;
59 typedef typename Boundary::MeshType MeshType;
60 typedef ValueT ValueType;
61
62 BoundaryNodeSet place;
63 ValueType value;
64
70 template <typename... ConditionArgumentsTypes>
71 BoundaryConditionWithMesh(const BoundaryNodeSet& place, ConditionArgumentsTypes&&... value_args)
72 : place(place),
73 value(std::forward<ConditionArgumentsTypes>(value_args)...) {}
74
80 template <typename... ConditionArgumentsTypes>
81 BoundaryConditionWithMesh(BoundaryNodeSet&& place, ConditionArgumentsTypes&&... value_args)
82 : place(std::move(place)),
83 value(std::forward<ConditionArgumentsTypes>(value_args)...) {}
84};
85
86 template <typename BoundaryT, typename ValueT> struct BoundaryConditions;
87
94 template <typename BoundaryT, typename ValueT>
95 struct BoundaryConditionsWithMesh
96{
97 typedef BoundaryT Boundary;
98 typedef typename Boundary::MeshType MeshType;
99 typedef ValueT ValueType;
100
102 typedef BoundaryConditionWithMesh<Boundary, ValueType> Element;
103
104 private:
105 typedef std::vector<Element> elements_container_t;
106 elements_container_t container;
107 friend struct BoundaryConditions<BoundaryT,ValueType>;
108
109 public:
110 typedef typename elements_container_t::iterator iterator;
111 typedef typename elements_container_t::const_iterator const_iterator;
112
113 iterator begin() { return container.begin(); }
114 const_iterator begin() const { return container.begin(); }
115
116 iterator end() { return container.end(); }
117 const_iterator end() const { return container.end(); }
118
123 template <typename... ArgsTypes>
124 BoundaryConditionsWithMesh(ArgsTypes&&... args): container(std::forward<ArgsTypes>(args)...) {}
125
134 Element& operator[](std::size_t index) {
135 return container[index];
136 }
137
146 const Element& operator[](std::size_t index) const {
147 return container[index];
148 }
149
156 std::size_t size() const {
157 return container.size();
158 }
159
166 bool empty() const {
167 return container.empty();
168 }
169
176 const_iterator find(std::size_t mesh_index) const {
177 auto i = begin();
178 while (i != end() && !i->place.contains(mesh_index)) ++i;
179 return i;
180 }
181
182 plask::optional<ValueType> getValue(std::size_t mesh_index) const {
183 for (auto i: container)
184 if (i.place.contains(mesh_index)) return plask::optional<ValueType>(i.value);
185 return plask::optional<ValueType>();
186 }
187};
188
189
196 template <typename BoundaryT, typename ValueT>
197 struct BoundaryConditions
198{
199 typedef BoundaryT Boundary;
200 typedef typename Boundary::MeshType MeshType;
201 typedef ValueT ValueType;
202
204 typedef BoundaryCondition<Boundary, ValueType> Element;
205
206 private:
207 typedef std::list<Element> elements_container_t; // std::list does not invalidate iterators on add/erase
208 elements_container_t container;
209
210 public:
211 typedef typename elements_container_t::iterator iterator;
212 typedef typename elements_container_t::const_iterator const_iterator;
213
214 iterator begin() { return container.begin(); }
215 const_iterator begin() const { return container.begin(); }
216
217 iterator end() { return container.end(); }
218 const_iterator end() const { return container.end(); }
219
220 private:
222 iterator lastIterator() { return --end(); }
223
224 public:
225
230 template <typename... ArgsTypes>
231 BoundaryConditions(ArgsTypes&&... args): container(std::forward<ArgsTypes>(args)...) {}
232
240 iterator getIteratorForIndex(std::size_t index) {
241 iterator result = begin();
242 while (index > 0 && result != end()) { ++result; --index; }
243 return result;
244 }
245
253 const_iterator getIteratorForIndex(std::size_t index) const {
254 const_iterator result = begin();
255 while (index > 0 && result != end()) { ++result; --index; }
256 return result;
257 }
258
267 Element& operator[](std::size_t index) {
268 iterator i = getIteratorForIndex(index);
269 if (i == end()) OutOfBoundsException("BoundaryConditions[]", "index");
270 return *i;
271 }
272
281 const Element& operator[](std::size_t index) const {
282 const_iterator i = getIteratorForIndex(index);
283 if (i == end()) OutOfBoundsException("BoundaryConditions::at", "index");
284 return *i;
285 }
286
294 iterator add(Element&& element) {
295 container.push_back(std::forward<Element>(element));
296 return lastIterator();
297 }
298
307 template <typename... ConditionArgumentsTypes>
308 iterator add(Boundary&& place, ConditionArgumentsTypes&&... value_args) {
309 container.emplace_back(std::forward<Boundary>(place), std::forward<ConditionArgumentsTypes>(value_args)...);
310 return lastIterator();
311 }
312
321 iterator insert(std::size_t index, Element&& element) {
322 iterator i = getIteratorForIndex(index);
323 container.insert(i, std::forward<Element>(element));
324 return lastIterator();
325 }
326
336 template <typename... ConditionArgumentsTypes>
337 iterator insert(std::size_t index, Boundary&& place, ConditionArgumentsTypes&&... value_args) {
338 iterator i = getIteratorForIndex(index);
339 container.emplace(i, std::forward<Boundary>(place), std::forward<ConditionArgumentsTypes>(value_args)...);
340 return lastIterator();
341 }
342
344 void clear() {
345 container.clear();
346 }
347
354 void erase(iterator to_erase) {
355 container.erase(to_erase);
356 }
357
364 void erase(iterator first, iterator last) {
365 container.erase(first, last);
366 }
367
377 void erase(std::size_t index) {
378 iterator i = getIteratorForIndex(index);
379 if (i == end()) OutOfBoundsException("BoundaryConditions[]", "index");
380 erase(i);
381 }
382
389 std::size_t size() const {
390 return container.size();
391 }
392
399 bool empty() const {
400 return container.empty();
401 }
402
407 BoundaryConditionsWithMesh<Boundary,ValueType> get(const typename Boundary::MeshType& mesh,
408 const shared_ptr<const GeometryD<MeshType::DIM>>& geometry) const {
409 BoundaryConditionsWithMesh<Boundary,ValueType> impl;
410 impl.container.reserve(container.size());
411 for (auto& el: container) {
412 auto place = el.place(mesh, geometry);
413 if (place.empty())
414 writelog(LOG_WARNING, "Boundary condition with value {} contains no points for given mesh", str(el.value));
415 impl.container.push_back(
416 BoundaryConditionWithMesh<Boundary,ValueType>(place, el.value)
417 );
418 }
419 return impl;
420 }
421
427 BoundaryConditionsWithMesh<Boundary,ValueType> get(const shared_ptr<const typename Boundary::MeshType>& mesh,
428 const shared_ptr<const GeometryD<MeshType::DIM>>& geometry) const {
429 return get(*mesh, geometry);
430 }
431
437 BoundaryConditionsWithMesh<Boundary,ValueType> operator()(const MeshType& mesh,
438 const shared_ptr<const GeometryD<MeshType::DIM>>& geometry) const {
439 return get(mesh, geometry);
440 }
441
447 BoundaryConditionsWithMesh<Boundary,ValueType> operator()(const shared_ptr<const MeshType>& mesh,
448 const shared_ptr<const GeometryD<MeshType::DIM>>& geometry) const {
449 return get(*mesh, geometry);
450 }
451
452};
453
454} // namespace plask
455
456#endif // PLASK__BOUNDARY_CONDITIONS_H