PLaSK library

Loading...
Searching...
No Matches
scaled_provider.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__MULTIPLIED_PROVIDERS_H
15#define PLASK__MULTIPLIED_PROVIDERS_H
16
17#include "providerfor.hpp"
18
24 namespace plask {
25
29 template <typename DstProviderT, typename SrcProviderT, typename ScaleT=double>
30 struct ScaledProviderBase: public DstProviderT {
31
32 typedef SrcProviderT SourceType;
33 typedef DstProviderT DestinationType;
34 typedef ScaleT ScaleType;
35
36 protected:
38 SrcProviderT* source;
39
40 private:
42 bool priv;
43
44 void onChange(Provider& PLASK_UNUSED(which), bool isDeleted) {
45 if (isDeleted) {
46 source = nullptr;
47 }
48 this->fireChanged();
49 }
50
51 public:
52
54 ScaleT scale;
55
60 ScaledProviderBase(ScaleT scale=1.): source(nullptr), priv(false), scale(scale) {}
61
67 void set(SrcProviderT* src, bool prv=false) {
68 if (priv) delete source;
69 source = src;
70 priv = prv;
71 if (src) src->changed.connect(boost::bind(&ScaledProviderBase::onChange, this, _1, _2));
72 this->fireChanged();
73 }
74
79 void set(std::unique_ptr<SrcProviderT>&& src) {
80 set(src->release(), true);
81 }
82
86 void reset() {
87 if (source) source->changed.disconnect(boost::bind(&ScaledProviderBase::onChange, this, _1, _2));
88 if (priv) delete source;
89 source = nullptr;
90 this->fireChanged();
91 }
92
97 SrcProviderT* getSource() const {
98 return source;
99 }
100
101 ~ScaledProviderBase() {
102 reset();
103 }
104
108 void ensureHasProvider() const {
109 if (!source)
110 throw Exception("scaled {0} provider has no source", this->name());
111 }
112
113};
114
115
119 template <typename, typename, PropertyType, typename, typename, typename> struct ScaledFieldProviderImpl;
120
121 template <typename DstPropertyT, typename SrcPropertyT, PropertyType propertyType, typename SpaceT, typename ScaleT, typename... ExtraArgs>
122 struct ScaledFieldProviderImpl<DstPropertyT, SrcPropertyT, propertyType, SpaceT, ScaleT, VariadicTemplateTypesHolder<ExtraArgs...>>:
123 public ScaledProviderBase<ProviderFor<DstPropertyT,SpaceT>, ProviderFor<SrcPropertyT,SpaceT>, ScaleT> {
124
125 ScaledFieldProviderImpl(double scale=1.): ScaledProviderBase<ProviderFor<DstPropertyT,SpaceT>, ProviderFor<SrcPropertyT,SpaceT>, ScaleT>(scale) {}
126
127 typedef typename ProviderFor<DstPropertyT,SpaceT>::ProvidedType ProvidedType;
128
129 virtual ProvidedType operator()(shared_ptr<const MeshD<SpaceT::DIM>> dst_mesh, ExtraArgs... extra_args, InterpolationMethod method=INTERPOLATION_DEFAULT) const {
130 this->ensureHasProvider();
131 return (*this->source)(dst_mesh, std::forward<ExtraArgs>(extra_args)..., method) * this->scale;
132 }
133};
134
135 template <typename DstPropertyT, typename SrcPropertyT, typename SpaceT, typename ScaleT, typename... ExtraArgs>
136 struct ScaledFieldProviderImpl<DstPropertyT, SrcPropertyT, MULTI_FIELD_PROPERTY, SpaceT, ScaleT, VariadicTemplateTypesHolder<ExtraArgs...>>:
137 public ScaledProviderBase<ProviderFor<DstPropertyT,SpaceT>, ProviderFor<SrcPropertyT,SpaceT>, ScaleT> {
138
139 ScaledFieldProviderImpl(double scale=1.): ScaledProviderBase<ProviderFor<DstPropertyT,SpaceT>, ProviderFor<SrcPropertyT,SpaceT>, ScaleT>(scale) {}
140
141 typedef typename ProviderFor<DstPropertyT,SpaceT>::ProvidedType ProvidedType;
142
143 ProvidedType operator()(size_t n, shared_ptr<const MeshD<SpaceT::DIM>> dst_mesh, ExtraArgs... extra_args, InterpolationMethod method=INTERPOLATION_DEFAULT) const override {
144 this->ensureHasProvider();
145 return (*this->source)(n, dst_mesh, std::forward<ExtraArgs>(extra_args)..., method) * this->scale;
146 }
147
148 size_t size() const override {
149 this->ensureHasProvider();
150 return this->source->size();
151 }
152};
153
157 template <typename DstPropertyT, typename SrcPropertyT, typename SpaceT, typename ScaleT=double>
158 struct ScaledFieldProvider: public ScaledFieldProviderImpl<DstPropertyT, SrcPropertyT, DstPropertyT::propertyType, SpaceT, ScaleT, typename DstPropertyT::ExtraParams> {
159 static_assert(DstPropertyT::propertyType == SrcPropertyT::propertyType, "Source and destination property types do not match");
160 static_assert(std::is_same<typename DstPropertyT::ExtraParams, typename SrcPropertyT::ExtraParams>::value, "Source and destination extra arguments do not match");
161 ScaledFieldProvider(double scale=1.): ScaledFieldProviderImpl<DstPropertyT, SrcPropertyT, DstPropertyT::propertyType, SpaceT, ScaleT, typename DstPropertyT::ExtraParams>(scale) {}
162};
163
164
165} // namespace plask
166
167#endif // PLASK__MULTIPLIED_PROVIDERS_H