PLaSK library

Loading...
Searching...
No Matches
change_space_size_cyl.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__FILTER__CHANGE_SPACE_SIZE_CYL_H
15#define PLASK__FILTER__CHANGE_SPACE_SIZE_CYL_H
16
17#include "base.hpp"
18#include "../mesh/basic.hpp"
19#include "../mesh/transformed.hpp"
20
21 namespace plask {
22
24 template <typename PropertyT, PropertyType propertyType, typename VariadicTemplateTypesHolder>
25 struct DataFrom3DtoCyl2DSourceImpl {
26 static_assert(propertyType == FIELD_PROPERTY || propertyType == MULTI_FIELD_PROPERTY,
27 "DataFrom3DtoCyl2DSource can't be used with value properties (it can be used only with fields properties)");
28};
29
31 template <typename PropertyT, typename... ExtraArgs>
32 struct DataFrom3DtoCyl2DSourceImpl<PropertyT, FIELD_PROPERTY, VariadicTemplateTypesHolder<ExtraArgs...>>
33: public OuterDataSource<PropertyT, Geometry2DCylindrical, Geometry3D, Revolution, GeometryObjectD<3>>
34{
36 std::size_t pointsCount;
37
38 explicit DataFrom3DtoCyl2DSourceImpl(std::size_t pointsCount = 10): pointsCount(pointsCount) {}
39
41 typedef typename PropertyAt<PropertyT, Geometry2DCylindrical>::ValueType ValueType;
42
43 std::function<plask::optional<ValueType>(std::size_t index)> operator()(const shared_ptr<const MeshD<2>>& dst_mesh, ExtraArgs... extra_args, InterpolationMethod method) const override {
44 const std::size_t point_count = this->pointsCount;
45 auto data = this->in(
46 plask::make_shared<PointsOnCircleMeshExtend>(dst_mesh, this->inTranslation, point_count),
47 std::forward<ExtraArgs>(extra_args)..., method);
48 return [point_count, data] (std::size_t index) {
49 index *= point_count;
50 auto sum = data[index];
51 for (std::size_t i = 1; i < point_count; ++i) sum += data[index+i];
52 PLASK_NO_CONVERSION_WARNING_BEGIN
53 return PropertyT::value3Dto2D(sum / double(point_count));
54 PLASK_NO_WARNING_END
55 };
56 }
57};
58
60 template <typename PropertyT, typename... ExtraArgs>
61 struct DataFrom3DtoCyl2DSourceImpl<PropertyT, MULTI_FIELD_PROPERTY, VariadicTemplateTypesHolder<ExtraArgs...>>
62: public OuterDataSource<PropertyT, Geometry2DCylindrical, Geometry3D, Revolution, GeometryObjectD<3>>
63{
65 std::size_t pointsCount;
66
67 explicit DataFrom3DtoCyl2DSourceImpl(std::size_t pointsCount = 10): pointsCount(pointsCount) {}
68
70 typedef typename PropertyAt<PropertyT, Geometry2DCylindrical>::ValueType ValueType;
71
72 typedef typename PropertyT::EnumType EnumType;
73
74 std::function<plask::optional<ValueType>(std::size_t index)> operator()(EnumType n, const shared_ptr<const MeshD<2>>& dst_mesh, ExtraArgs... extra_args, InterpolationMethod method) const override {
75 const std::size_t point_count = this->pointsCount;
76 auto data = this->in(n,
77 plask::make_shared<PointsOnCircleMeshExtend>(dst_mesh, this->inTranslation, point_count),
78 std::forward<ExtraArgs>(extra_args)..., method);
79 return [point_count, data] (std::size_t index) {
80 index *= point_count;
81 auto sum = data[index];
82 for (std::size_t i = 1; i < point_count; ++i) sum += data[index+i];
83 PLASK_NO_CONVERSION_WARNING_BEGIN
84 return PropertyT::value3Dto2D(sum / double(point_count));
85 PLASK_NO_WARNING_END
86 };
87 }
88
89 size_t size() const override { return this->in.size(); }
90};
91
95 template <typename PropertyT>
96 using DataFrom3DtoCyl2DSource = DataFrom3DtoCyl2DSourceImpl<PropertyT, PropertyT::propertyType, typename PropertyT::ExtraParams>;
97
98
99
101 template <typename PropertyT, PropertyType propertyType, typename VariadicTemplateTypesHolder>
102 struct DataFromCyl2Dto3DSourceImpl {
103 static_assert(propertyType == FIELD_PROPERTY || propertyType == MULTI_FIELD_PROPERTY,
104 "DataFromCyl2Dto3DSource can't be used with value properties (it can be used only with fields properties)");
105};
106
108 template <typename PropertyT, typename... ExtraArgs>
109 struct DataFromCyl2Dto3DSourceImpl<PropertyT, FIELD_PROPERTY, VariadicTemplateTypesHolder<ExtraArgs...>>
110: public InnerDataSource<PropertyT, Geometry3D, Geometry2DCylindrical, Geometry3D /*GeometryObjectD<3>*/, Revolution>
111{
112
113 using typename InnerDataSource<PropertyT, Geometry3D, Geometry2DCylindrical, Geometry3D /*GeometryObjectD<3>*/, Revolution>::Region;
114
116 typedef typename PropertyAt<PropertyT, Geometry3D>::ValueType ValueType;
117
119 typedef typename PropertyAt<PropertyT, Geometry2DCylindrical>::ValueType InputValueType;
120
121 double r_sqr_begin, r_sqr_end;
122
123 struct LazySourceImpl {
124
125 std::vector<LazyData<InputValueType>> dataForRegion;
126
127 const DataFromCyl2Dto3DSourceImpl< PropertyT, FIELD_PROPERTY, VariadicTemplateTypesHolder<ExtraArgs...> >& source;
128
129 const shared_ptr<const MeshD<3>> dst_mesh;
130
131 /*std::tuple<ExtraArgs...> extra_args;
132
133 InterpolationMethod method;*/
134
135 LazySourceImpl(const DataFromCyl2Dto3DSourceImpl< PropertyT, FIELD_PROPERTY, VariadicTemplateTypesHolder<ExtraArgs...> >& source,
136 const shared_ptr<const MeshD<3>>& dst_mesh, ExtraArgs... extra_args, InterpolationMethod method)
137 : dataForRegion(source.regions.size()), source(source), dst_mesh(dst_mesh)/*, extra_args(extra_args...), method(method)*/
138 {
139 for (std::size_t region_index = 0; region_index < source.regions.size(); ++region_index)
140 dataForRegion[region_index].reset(source.in(plask::make_shared<CylReductionTo2DMesh>(dst_mesh, source.regions[region_index].inTranslation), std::forward<ExtraArgs>(extra_args)..., method));
141 }
142
143 plask::optional<ValueType> operator()(std::size_t index) {
144 Vec<3, double> p = dst_mesh->at(index);
145 std::size_t region_index = source.findRegionIndex(p,
146 [&](const Region& r) {
147 //check if p can be in cylinder inside r
148 const Vec<3, double> v = p - r.inTranslation; // r.inTranslation points to center of cylinder base
149 const double distance_from_center_sqr = std::fma(v.rad_p(), v.rad_p(), v.rad_r() * v.rad_r());
150 return this->source.r_sqr_begin <= distance_from_center_sqr && distance_from_center_sqr <= this->source.r_sqr_end;
151 }
152 );
153 if (region_index == source.regions.size())
154 return plask::optional<ValueType>();
155
156 /*if (dataForRegion[region_index].isNull())
157 dataForRegion[region_index].reset(source.in(plask::make_shared<CylReductionTo2DMesh>(dst_mesh, source.regions[region_index].inTranslation), extra_args, method));*/
158
159 return PropertyT::value2Dto3D(dataForRegion[region_index][index]);
160 }
161
162 };
163
164 void calcConnectionParameters() override {
165 InnerDataSource<PropertyT, Geometry3D, Geometry2DCylindrical, Geometry3D, Revolution>::calcConnectionParameters();
166 auto child = this->inputObj->getChild();
167 if (!child) {
168 r_sqr_begin = r_sqr_end = 0.;
169 return;
170 }
171 auto box = child->getBoundingBox();
172 r_sqr_begin = std::max(box.lower.rad_r(), 0.0); r_sqr_begin *= r_sqr_begin;
173 r_sqr_end = std::abs(box.upper.rad_r()); r_sqr_end *= r_sqr_end;
174 }
175
176 std::function<plask::optional<ValueType>(std::size_t index)> operator()(const shared_ptr<const MeshD<3>>& dst_mesh, ExtraArgs... extra_args, InterpolationMethod method) const override {
177 return LazySourceImpl(*this, dst_mesh, std::forward<ExtraArgs>(extra_args)..., method);
178 }
179
180
181};
182
184 template <typename PropertyT, typename... ExtraArgs>
185 struct DataFromCyl2Dto3DSourceImpl<PropertyT, MULTI_FIELD_PROPERTY, VariadicTemplateTypesHolder<ExtraArgs...>>
186: public InnerDataSource<PropertyT, Geometry3D, Geometry2DCylindrical, Geometry3D /*GeometryObjectD<3>*/, Revolution>
187{
188
189 using typename InnerDataSource<PropertyT, Geometry3D, Geometry2DCylindrical, Geometry3D /*GeometryObjectD<3>*/, Revolution>::Region;
190
192 typedef typename PropertyAt<PropertyT, Geometry3D>::ValueType ValueType;
193
195 typedef typename PropertyAt<PropertyT, Geometry2DCylindrical>::ValueType InputValueType;
196
197 typedef typename PropertyT::EnumType EnumType;
198
199 double r_sqr_begin, r_sqr_end;
200
201 struct LazySourceImpl {
202
203 std::vector<LazyData<InputValueType>> dataForRegion;
204
205 const DataFromCyl2Dto3DSourceImpl< PropertyT, MULTI_FIELD_PROPERTY, VariadicTemplateTypesHolder<ExtraArgs...> >& source;
206
207 const shared_ptr<const MeshD<3>> dst_mesh;
208
209 /*std::tuple<ExtraArgs...> extra_args;
210
211 InterpolationMethod method;*/
212
213 LazySourceImpl(const DataFromCyl2Dto3DSourceImpl< PropertyT, MULTI_FIELD_PROPERTY, VariadicTemplateTypesHolder<ExtraArgs...> >& source,
214 EnumType n, const shared_ptr<const MeshD<3>>& dst_mesh, ExtraArgs... extra_args, InterpolationMethod method)
215 : dataForRegion(source.regions.size()), source(source), dst_mesh(dst_mesh)/*, extra_args(extra_args...), method(method)*/
216 {
217 for (std::size_t region_index = 0; region_index < source.regions.size(); ++region_index)
218 dataForRegion[region_index].reset(source.in(n, plask::make_shared<CylReductionTo2DMesh>(dst_mesh, source.regions[region_index].inTranslation), std::forward<ExtraArgs>(extra_args)..., method));
219 }
220
221 plask::optional<ValueType> operator()(std::size_t index) {
222 Vec<3, double> p = dst_mesh->at(index);
223 std::size_t region_index = source.findRegionIndex(p,
224 [&](const Region& r) {
225 //check if p can be in cylinder inside r
226 const Vec<3, double> v = p - r.inTranslation; // r.inTranslation points to center of cylinder base
227 const double distance_from_center_sqr = std::fma(v.rad_p(), v.rad_p(), v.rad_r() * v.rad_r());
228 return this->source.r_sqr_begin <= distance_from_center_sqr && distance_from_center_sqr <= this->source.r_sqr_end;
229 }
230 );
231 if (region_index == source.regions.size())
232 return plask::optional<ValueType>();
233
234 /*if (dataForRegion[region_index].isNull())
235 dataForRegion[region_index].reset(source.in(plask::make_shared<CylReductionTo2DMesh>(dst_mesh, source.regions[region_index].inTranslation), extra_args, method));*/
236
237 return PropertyT::value2Dto3D(dataForRegion[region_index][index]);
238 }
239
240 };
241
242 void calcConnectionParameters() override {
243 InnerDataSource<PropertyT, Geometry3D, Geometry2DCylindrical, Geometry3D, Revolution>::calcConnectionParameters();
244 auto child = this->inputObj->getChild();
245 if (!child) {
246 r_sqr_begin = r_sqr_end = 0.;
247 return;
248 }
249 auto box = child->getBoundingBox();
250 r_sqr_begin = std::max(box.lower.rad_r(), 0.0); r_sqr_begin *= r_sqr_begin;
251 r_sqr_end = std::abs(box.upper.rad_r()); r_sqr_end *= r_sqr_end;
252 }
253
254 std::function<plask::optional<ValueType>(std::size_t index)> operator()(EnumType n, const shared_ptr<const MeshD<3>>& dst_mesh, ExtraArgs... extra_args, InterpolationMethod method) const override {
255 return LazySourceImpl(*this, n, dst_mesh, std::forward<ExtraArgs>(extra_args)..., method);
256 }
257
258 size_t size() const override { return this->in.size(); }
259};
260
264 template <typename PropertyT>
265 using DataFromCyl2Dto3DSource = DataFromCyl2Dto3DSourceImpl<PropertyT, PropertyT::propertyType, typename PropertyT::ExtraParams>;
266
267
268} // namespace plask
269
270#endif // PLASK__FILTER__CHANGE_SPACE_SIZE_CYL_H