PLaSK library

Loading...
Searching...
No Matches
regular1d.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__REGULAR1D_H
15#define PLASK__REGULAR1D_H
16
21#include "mesh.hpp"
22#include "../math.hpp"
23#include "../utils/iterators.hpp"
24#include "../utils/interpolation.hpp"
25#include "../utils/stl.hpp"
26
27#include "axis1d.hpp"
28
29 namespace plask {
30
34 class PLASK_API RegularAxis: public MeshAxis {
35
36 double lo, _step;
37 std::size_t points_count;
38
39 public:
40
42 typedef double PointType;
43
44 typedef IndexedIterator<const RegularAxis, PointType> native_const_iterator;
45
47 native_const_iterator begin() const { return native_const_iterator(this, 0); }
48
50 native_const_iterator end() const { return native_const_iterator(this, points_count); }
51
53 RegularAxis():
54 lo(0.), _step(0.), points_count(0) {}
55
57 RegularAxis(const RegularAxis& src):
58 lo(src.lo), _step(src._step), points_count(src.points_count) {}
59
66 RegularAxis(double first, double last, std::size_t points_count):
67 lo(first), _step( (last - first) / ((points_count>1)?double(points_count-1):1.) ),
68 points_count(points_count) {}
69
71 RegularAxis& operator=(const RegularAxis& src);
72
79 void reset(double first, double last, std::size_t points_count);
80
84 double first() const { return lo; }
85
89 double last() const { return lo + _step * double(points_count-1); }
90
94 double step() const { return _step; }
95
97 std::size_t size() const override { return points_count; }
98
105 bool operator==(const RegularAxis& to_compare) const {
106 return this->lo == to_compare.lo && this->_step == to_compare._step && this->points_count == to_compare.points_count;
107 }
108
115 bool operator!=(const RegularAxis& to_compare) const {
116 return !(*this == to_compare);
117 }
118
120 bool empty() const override { return points_count == 0; }
121
127 double operator[](std::size_t index) const { return lo + double(index) * _step; }
128
129 double at(std::size_t index) const override { return lo + double(index) * _step; }
130
134 void clear() {
135 if (empty()) return;
136 points_count = 0;
137 fireResized();
138 }
139
140 std::size_t findIndex(double to_find) const override {
141 return clamp(std::ptrdiff_t(std::ceil((to_find - lo) / _step)), std::ptrdiff_t(0), std::ptrdiff_t(points_count));
142 }
143
152 native_const_iterator find(double to_find) const {
153 return begin() + findIndex(to_find);
154 }
155
156 std::size_t findUpIndex(double to_find) const override;
157
164 native_const_iterator findUp(double to_find) const {
165 return begin() + findUpIndex(to_find);
166 }
167
173 native_const_iterator findNearest(double to_find) const {
174 return find_nearest_using_lower_bound(begin(), end(), to_find, find(to_find));
175 }
176
182 std::size_t findNearestIndex(double to_find) const override { return findNearest(to_find) - begin(); }
183
184 shared_ptr<MeshAxis> clone() const override { return plask::make_shared<RegularAxis>(*this); }
185
186 void writeXML(XMLElement& object) const override;
187
188 bool isIncreasing() const override;
189
190 shared_ptr<MeshAxis> getMidpointAxis() const override;
191
198 template <typename RandomAccessContainer>
199 auto interpolateLinear(const RandomAccessContainer& data, double point) -> typename std::remove_reference<decltype(data[0])>::type;
200
201 protected:
202 bool hasSameNodes(const MeshD<1>& to_compare) const override;
203
204};
205
206// RegularAxis method templates implementation
207 template <typename RandomAccessContainer>
208 auto RegularAxis::interpolateLinear(const RandomAccessContainer& data, double point) -> typename std::remove_reference<decltype(data[0])>::type {
209 std::size_t index = findIndex(point);
210 if (index == size()) return data[index - 1]; //TODO what should do if mesh is empty?
211 if (index == 0 || this->operator[](index) == point) return data[index]; //hit exactly
212 // here: points[index-1] < point < points[index]
213 return interpolation::linear(this->operator[](index-1), data[index-1], this->operator[](index), data[index], point);
214}
215
216 typedef RegularAxis RegularMesh1D;
217
218 PLASK_API shared_ptr<RegularMesh1D> readRegularMeshAxis(XMLReader& reader);
219
220} // namespace plask
221
222#endif // PLASK__REGULAR1D_H