teqp 0.23.1
Loading...
Searching...
No Matches
deriv_adapter.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "teqp/derivs.hpp"
5#include "teqp/exceptions.hpp"
6
7#if defined(TEQP_MULTIPRECISION_ENABLED)
8// Imports from boost
9#include <boost/multiprecision/cpp_bin_float.hpp>
10using namespace boost::multiprecision;
12#endif
13
14namespace teqp{
15namespace cppinterface{
16namespace adapter{
17
20template<typename ModelType>
21struct Owner{
22private:
23 ModelType model;
24public:
25 auto& get_ref(){ return model; };
26 const auto& get_cref() const { return model; };
27 const std::type_index index;
28 Owner(ModelType&& m) : model(m), index(std::type_index(typeid(ModelType))) {};
29};
30
33template<typename ModelType>
35private:
36 const ModelType& model;
37public:
38 auto& get_ref(){ return model; };
39 const auto& get_cref() const { return model; };
40 const std::type_index index;
41 ConstViewer(ModelType& m) : model(m), index(std::type_index(typeid(ModelType))) {};
42};
43
53template<typename... Funcs>
55public:
56 std::tuple<Funcs...> contributions;
57 OwnershipSummer(Funcs && ...f) : contributions(std::forward<Funcs>(f)...){};
58
59 auto& get_ref(){ return *this; };
60 const auto& get_cref() const { return *this; };
61 const std::type_index index;
62
64 template<typename MoleFracType>
65 auto R(const MoleFracType& molefrac){
66 return std::get<0>(contributions).R(molefrac);
67 }
68
70 template<typename TType, typename RhoType, typename MoleFracType>
71 auto alphar(const TType& T, const RhoType& rhomolar, const MoleFracType& molefrac) const {
72 auto sum_func = [&T, &rhomolar, &molefrac](auto const&... e)->decltype(auto) {
73 return (e.alphar(T, rhomolar, molefrac)+...);
74 };
75 return std::apply(sum_func, contributions);
76 }
77};
78
79template <typename... Args>
80OwnershipSummer<Args...> make_OwnershipSummer(Args&&... args)
81{
82 return OwnershipSummer<Args...>(std::forward<Args>(args)...);
83}
84
85namespace internal{
86 template<class T>struct tag{using type=T;};
87}
88
89template<typename T, typename U>
90concept CallableReducingDensity = requires(T t, U u) {
91 { t.get_reducing_density(u) };
92};
93
94template<typename T, typename U>
95concept CallableReducingTemperature = requires(T t, U u) {
96 { t.get_reducing_temperature(u) };
97};
98
106template<typename ModelPack>
108private:
109 ModelPack mp;
110public:
111 auto& get_ModelPack_ref(){ return mp; }
112 const auto& get_ModelPack_cref() const { return mp; }
113
114 template<typename T>
115 DerivativeAdapter(internal::tag<T> /*tag_*/, const T&& mp): mp(mp) {}
116
117 const std::type_index& get_type_index() const override {
118 return mp.index;
119 };
120
121// template<typename T>
122// DerivativeAdapter(const Owner<T>&& mp): mp(mp) {} ;
123//
124// template<typename T>
125// DerivativeAdapter(const ConstViewer<T>&& mp): mp(mp) {} ;
126
127 virtual double get_R(const EArrayd& molefrac) const override {
128 return mp.get_cref().R(molefrac);
129 };
130
131 virtual double get_Arxy(const int NT, const int ND, const double T, const double rhomolar, const EArrayd& molefrac) const override{
132 return TDXDerivatives<decltype(mp.get_cref()), double, EArrayd>::get_Ar(NT, ND, mp.get_cref(), T, rhomolar, molefrac);
133 };
134
135 // Here X-Macros are used to create functions like get_Ar00, get_Ar01, ....
136#define X(i,j) virtual double get_Ar ## i ## j(const double T, const double rho, const REArrayd& molefrac) const override { return TDXDerivatives<decltype(mp.get_cref()), double, EArrayd>::template get_Arxy<i,j>(mp.get_cref(), T, rho, molefrac); };
138#undef X
139 // And like get_Ar01n, get_Ar02n, ....
140#define X(i) virtual EArrayd get_Ar0 ## i ## n(const double T, const double rho, const REArrayd& molefrac) const override { auto vals = TDXDerivatives<decltype(mp.get_cref()), double, EArrayd>::template get_Ar0n<i>(mp.get_cref(), T, rho, molefrac); return Eigen::Map<Eigen::ArrayXd>(&(vals[0]), vals.size()); };
142#undef X
143 // And like get_Ar10n, get_Ar20n, ....
144#define X(i) virtual EArrayd get_Ar ## i ## 0n(const double T, const double rho, const REArrayd& molefrac) const override { auto vals = TDXDerivatives<decltype(mp.get_cref()), double, EArrayd>::template get_Arn0<i>(mp.get_cref(), T, rho, molefrac); return Eigen::Map<Eigen::ArrayXd>(&(vals[0]), vals.size()); };
146#undef X
147
148 virtual double get_Ar01ep(const double T, const double rho, const EArrayd& molefrac) const override {
149 using namespace boost::multiprecision;
150 using my_float_t = number<cpp_bin_float<100U>>;
151 auto f = [&](const auto& rhoep){
152 return mp.get_cref().alphar(T, rhoep, molefrac);
153 };
154 return rho*static_cast<double>(centered_diff<1,4>(f, static_cast<my_float_t>(rho), 1e-16*static_cast<my_float_t>(rho)));
155 }
156 virtual double get_Ar02ep(const double T, const double rho, const EArrayd& molefrac) const override {
157 using namespace boost::multiprecision;
158 using my_float_t = number<cpp_bin_float<100U>>;
159 auto f = [&](const auto& rhoep){
160 return mp.get_cref().alphar(T, rhoep, molefrac);
161 };
162 return rho*rho*static_cast<double>(centered_diff<2,4>(f, static_cast<my_float_t>(rho), 1e-16*static_cast<my_float_t>(rho)));
163 }
164 virtual double get_Ar03ep(const double T, const double rho, const EArrayd& molefrac) const override {
165 using namespace boost::multiprecision;
166 using my_float_t = number<cpp_bin_float<100U>>;
167 auto f = [&](const auto& rhoep){
168 return mp.get_cref().alphar(T, rhoep, molefrac);
169 };
170 return rho*rho*rho*static_cast<double>(centered_diff<3,4>(f, static_cast<my_float_t>(rho), 1e-16*static_cast<my_float_t>(rho)));
171 }
172
173 virtual double get_reducing_density(const EArrayd& molefrac) const override {
174 using Model = std::decay_t<decltype(mp.get_cref())>;
176 return mp.get_cref().get_reducing_density(molefrac);
177 }
178 else{
179 throw teqp::NotImplementedError("Cannot call get_reducing_density of a class that doesn't define it");
180 }
181 }
182 virtual double get_reducing_temperature(const EArrayd& molefrac) const override {
183 using Model = std::decay_t<decltype(mp.get_cref())>;
185 return mp.get_cref().get_reducing_temperature(molefrac);
186 }
187 else{
188 throw teqp::NotImplementedError("Cannot call get_reducing_temperature of a class that doesn't define it");
189 }
190 }
191
192 // Virial derivatives
193 virtual double get_B2vir(const double T, const EArrayd& z) const override {
194 return VirialDerivatives<decltype(mp.get_cref()), double, EArrayd>::get_B2vir(mp.get_cref(), T, z);
195 };
196 virtual std::map<int, double> get_Bnvir(const int Nderiv, const double T, const EArrayd& z) const override {
197 return VirialDerivatives<decltype(mp.get_cref()), double, EArrayd>::get_Bnvir_runtime(Nderiv, mp.get_cref(), T, z);
198 };
199 virtual double get_B12vir(const double T, const EArrayd& z) const override {
200 return VirialDerivatives<decltype(mp.get_cref()), double, EArrayd>::get_B12vir(mp.get_cref(), T, z);
201 };
202 virtual double get_dmBnvirdTm(const int Nderiv, const int NTderiv, const double T, const EArrayd& molefrac) const override {
203 return VirialDerivatives<decltype(mp.get_cref()), double, EArrayd>::get_dmBnvirdTm_runtime(Nderiv, NTderiv, mp.get_cref(), T, molefrac);
204 };
205
206 // Composition derivatives with temperature and density as the working variables
207 virtual double get_ATrhoXi(const double T, const int NT, const double rhomolar, const int ND, const EArrayd& molefrac, const int i, const int NXi) const override {
208 return TDXDerivatives<decltype(mp.get_cref()), double, EArrayd>::get_ATrhoXi_runtime(mp.get_cref(), T, NT, rhomolar, ND, molefrac, i, NXi);
209 };
210 virtual double get_ATrhoXiXj(const double T, const int NT, const double rhomolar, const int ND, const EArrayd& molefrac, const int i, const int NXi, const int j, const int NXj) const override {
211 return TDXDerivatives<decltype(mp.get_cref()), double, EArrayd>::get_ATrhoXiXj_runtime(mp.get_cref(), T, NT, rhomolar, ND, molefrac, i, NXi, j, NXj);
212 };
213 virtual double get_ATrhoXiXjXk(const double T, const int NT, const double rhomolar, const int ND, const EArrayd& molefrac, const int i, const int NXi, const int j, const int NXj, const int k, const int NXk) const override {
214 return TDXDerivatives<decltype(mp.get_cref()), double, EArrayd>::get_ATrhoXiXjXk_runtime(mp.get_cref(), T, NT, rhomolar, ND, molefrac, i, NXi, j, NXj, k, NXk);
215 };
216
217 // Composition derivatives with tau and delta as the working variables
218 virtual double get_AtaudeltaXi(const double tau, const int NT, const double delta, const int ND, const EArrayd& molefrac, const int i, const int NXi) const override {
219 return TDXDerivatives<decltype(mp.get_cref()), double, EArrayd>::get_AtaudeltaXi_runtime(mp.get_cref(), tau, NT, delta, ND, molefrac, i, NXi);
220 };
221 virtual double get_AtaudeltaXiXj(const double tau, const int NT, const double delta, const int ND, const EArrayd& molefrac, const int i, const int NXi, const int j, const int NXj) const override {
222 return TDXDerivatives<decltype(mp.get_cref()), double, EArrayd>::get_AtaudeltaXiXj_runtime(mp.get_cref(), tau, NT, delta, ND, molefrac, i, NXi, j, NXj);
223 };
224 virtual double get_AtaudeltaXiXjXk(const double tau, const int NT, const double delta, const int ND, const EArrayd& molefrac, const int i, const int NXi, const int j, const int NXj, const int k, const int NXk) const override {
225 return TDXDerivatives<decltype(mp.get_cref()), double, EArrayd>::get_AtaudeltaXiXjXk_runtime(mp.get_cref(), tau, NT, delta, ND, molefrac, i, NXi, j, NXj, k, NXk);
226 };
227
228 // Derivatives from isochoric thermodynamics (all have the same signature within each block), and they differ by their output argument
229#define X(f) virtual double f(const double T, const EArrayd& rhovec) const override { return IsochoricDerivatives<decltype(mp.get_cref()), double, EArrayd>::f(mp.get_cref(), T, rhovec); };
231#undef X
232#define X(f) virtual EArrayd f(const double T, const EArrayd& rhovec) const override { return IsochoricDerivatives<decltype(mp.get_cref()), double, EArrayd>::f(mp.get_cref(), T, rhovec); };
234#undef X
235#define X(f) virtual EMatrixd f(const double T, const EArrayd& rhovec) const override { return IsochoricDerivatives<decltype(mp.get_cref()), double, EArrayd>::f(mp.get_cref(), T, rhovec); };
237#undef X
238#define X(f) virtual std::tuple<double, Eigen::ArrayXd, Eigen::MatrixXd> f(const double T, const EArrayd& rhovec) const override { return IsochoricDerivatives<decltype(mp.get_cref()), double, EArrayd>::f(mp.get_cref(), T, rhovec); };
240#undef X
241 virtual Eigen::ArrayXd get_Psir_sigma_derivs(const double T, const EArrayd& rhovec, const EArrayd& v) const override{
242 return IsochoricDerivatives<decltype(mp.get_cref()), double, EArrayd>::get_Psir_sigma_derivs(mp.get_cref(), T, rhovec, v);
243 };
244
245 virtual EArray33d get_deriv_mat2(const double T, double rho, const EArrayd& z ) const override {
246 return DerivativeHolderSquare<2>(mp.get_cref(), T, rho, z).derivs;
247 };
248};
249
250template<typename TemplatedModel> auto view(const TemplatedModel& tp){
251 ConstViewer cv{tp};
252 return new DerivativeAdapter<decltype(cv)>(internal::tag<decltype(cv)>{}, std::move(cv));
253}
254template<typename TemplatedModel> auto own(const TemplatedModel&& tp){
255 Owner o(std::move(tp));
256 return new DerivativeAdapter<decltype(o)>(internal::tag<decltype(o)>{}, std::move(o));
257}
258
259template<typename TemplatedModel> auto make_owned(const TemplatedModel& tmodel){
260 using namespace teqp::cppinterface;
261 return std::unique_ptr<AbstractModel>(own(std::move(tmodel)));
262};
263
264template<typename TemplatedModel> auto make_cview(const TemplatedModel& tmodel){
265 using namespace teqp::cppinterface;
266 return std::unique_ptr<AbstractModel>(view(tmodel));
267};
268
274template<typename ModelType>
275const ModelType& get_model_cref(const AbstractModel *am)
276{
277 if (am == nullptr){
278 throw teqp::InvalidArgument("Argument to get_model_cref is a nullptr");
279 }
280 const auto* mptr = dynamic_cast<const DerivativeAdapter<ConstViewer<const ModelType>>*>(am);
281 const auto* mptr2 = dynamic_cast<const DerivativeAdapter<Owner<const ModelType>>*>(am);
282 if (mptr != nullptr){
283 return mptr->get_ModelPack_cref().get_cref();
284 }
285 else if (mptr2 != nullptr){
286 return mptr2->get_ModelPack_cref().get_cref();
287 }
288 else{
289 throw teqp::InvalidArgument("Unable to cast model to desired type");
290 }
291}
292
298template<typename ModelType>
300{
301 if (am == nullptr){
302 throw teqp::InvalidArgument("Argument to get_model_ref is a nullptr");
303 }
304 auto* mptr2 = dynamic_cast<DerivativeAdapter<Owner<ModelType>>*>(am);
305 if (mptr2 != nullptr){
306 return mptr2->get_ModelPack_ref().get_ref();
307 }
308 else{
309 throw teqp::InvalidArgument("Unable to cast model to desired type; only the Owner ownership model is allowed");
310 }
311}
312
313}
314}
315}
Eigen::Array< double, Nderivsmax+1, Nderivsmax+1 > derivs
Definition derivs.hpp:1516
virtual ISOCHORIC_multimatrix_args Eigen::ArrayXd get_Psir_sigma_derivs(const double T, const EArrayd &rhovec, const EArrayd &v) const override
virtual double get_AtaudeltaXi(const double tau, const int NT, const double delta, const int ND, const EArrayd &molefrac, const int i, const int NXi) const override
const std::type_index & get_type_index() const override
virtual double get_dmBnvirdTm(const int Nderiv, const int NTderiv, const double T, const EArrayd &molefrac) const override
virtual EArray33d get_deriv_mat2(const double T, double rho, const EArrayd &z) const override
virtual double get_Ar02ep(const double T, const double rho, const EArrayd &molefrac) const override
virtual double get_AtaudeltaXiXjXk(const double tau, const int NT, const double delta, const int ND, const EArrayd &molefrac, const int i, const int NXi, const int j, const int NXj, const int k, const int NXk) const override
virtual double get_ATrhoXiXjXk(const double T, const int NT, const double rhomolar, const int ND, const EArrayd &molefrac, const int i, const int NXi, const int j, const int NXj, const int k, const int NXk) const override
virtual std::map< int, double > get_Bnvir(const int Nderiv, const double T, const EArrayd &z) const override
virtual double get_reducing_density(const EArrayd &molefrac) const override
virtual double get_Arxy(const int NT, const int ND, const double T, const double rhomolar, const EArrayd &molefrac) const override
virtual double get_B2vir(const double T, const EArrayd &z) const override
virtual double get_AtaudeltaXiXj(const double tau, const int NT, const double delta, const int ND, const EArrayd &molefrac, const int i, const int NXi, const int j, const int NXj) const override
virtual double get_R(const EArrayd &molefrac) const override
virtual ARN0_args double get_Ar01ep(const double T, const double rho, const EArrayd &molefrac) const override
virtual double get_B12vir(const double T, const EArrayd &z) const override
virtual double get_ATrhoXiXj(const double T, const int NT, const double rhomolar, const int ND, const EArrayd &molefrac, const int i, const int NXi, const int j, const int NXj) const override
DerivativeAdapter(internal::tag< T >, const T &&mp)
virtual double get_Ar03ep(const double T, const double rho, const EArrayd &molefrac) const override
virtual double get_ATrhoXi(const double T, const int NT, const double rhomolar, const int ND, const EArrayd &molefrac, const int i, const int NXi) const override
virtual double get_reducing_temperature(const EArrayd &molefrac) const override
A collection type that allows you to sum contributions from multiple EOS terms.
auto alphar(const TType &T, const RhoType &rhomolar, const MoleFracType &molefrac) const
The generic alphar function, which sums the contributions coming from the individual models passed in...
auto R(const MoleFracType &molefrac)
The gas constant, obtained from the first model in the tuple.
auto make_cview(const TemplatedModel &tmodel)
auto own(const TemplatedModel &&tp)
auto view(const TemplatedModel &tp)
ModelType & get_model_ref(AbstractModel *am)
Get a mutable reference to the model.
auto make_owned(const TemplatedModel &tmodel)
OwnershipSummer< Args... > make_OwnershipSummer(Args &&... args)
const ModelType & get_model_cref(const AbstractModel *am)
Get a const reference to the model that is being held in a DerivativeAdapter instance.
auto centered_diff(const Function &f, const Scalar x, const Scalar h)
#define AR0N_args
Definition teqpcpp.hpp:39
#define ISOCHORIC_matrix_args
Definition teqpcpp.hpp:70
#define ISOCHORIC_double_args
Definition teqpcpp.hpp:56
Eigen::Array< double, 3, 3 > EArray33d
Definition teqpcpp.hpp:17
#define ISOCHORIC_multimatrix_args
Definition teqpcpp.hpp:74
#define ISOCHORIC_array_args
Definition teqpcpp.hpp:61
Eigen::ArrayX< double > EArrayd
Definition teqpcpp.hpp:16
#define ARN0_args
Definition teqpcpp.hpp:49
#define ARXY_args
Definition teqpcpp.hpp:22