Loading [MathJax]/extensions/TeX/AMSsymbols.js
CoolProp 6.8.1dev
An open-source fluid property and humid air property database
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Helmholtz.h
Go to the documentation of this file.
1
2#ifndef HELMHOLTZ_H
3#define HELMHOLTZ_H
4
5#include <vector>
6#include "rapidjson_include.h"
7//#include "Eigen/Core"
8#include "time.h"
9#include "CachedElement.h"
12
13#if ENABLE_CATCH
14# include "MultiComplex/MultiComplex.hpp"
15#endif
16
17namespace CoolProp {
18
19// #############################################################################
20// #############################################################################
21// #############################################################################
22// RESIDUAL TERMS
23// #############################################################################
24// #############################################################################
25// #############################################################################
26
27#define LIST_OF_DERIVATIVE_VARIABLES \
28 X(alphar) \
29 X(dalphar_ddelta) \
30 X(dalphar_dtau) \
31 X(d2alphar_ddelta2) \
32 X(d2alphar_dtau2) \
33 X(d2alphar_ddelta_dtau) \
34 X(d3alphar_ddelta3) \
35 X(d3alphar_ddelta_dtau2) \
36 X(d3alphar_ddelta2_dtau) \
37 X(d3alphar_dtau3) \
38 X(d4alphar_ddelta4) \
39 X(d4alphar_ddelta3_dtau) \
40 X(d4alphar_ddelta2_dtau2) \
41 X(d4alphar_ddelta_dtau3) \
42 X(d4alphar_dtau4) \
43 X(delta_x_dalphar_ddelta) \
44 X(tau_x_dalphar_dtau) \
45 X(delta2_x_d2alphar_ddelta2) \
46 X(deltatau_x_d2alphar_ddelta_dtau) \
47 X(tau2_x_d2alphar_dtau2)
48
50{
51#define X(name) CoolPropDbl name;
53#undef X
55
57#define X(name) name = v;
59#undef X
60 }
63#define X(name) _new.name = name + other.name;
65#undef X
66 return _new;
67 }
70#define X(name) _new.name = name * other;
72#undef X
73 return _new;
74 }
76 reset(0.0);
77 T_red = _HUGE;
78 rhomolar_red = _HUGE;
79 };
81 double get(std::size_t itau, std::size_t idelta) {
82 if (itau == 0) {
83 if (idelta == 0) {
84 return alphar;
85 } else if (idelta == 1) {
86 return dalphar_ddelta;
87 } else if (idelta == 2) {
88 return d2alphar_ddelta2;
89 } else if (idelta == 3) {
90 return d3alphar_ddelta3;
91 } else if (idelta == 4) {
92 return d4alphar_ddelta4;
93 } else {
94 throw ValueError();
95 }
96 } else if (itau == 1) {
97 if (idelta == 0) {
98 return dalphar_dtau;
99 } else if (idelta == 1) {
100 return d2alphar_ddelta_dtau;
101 } else if (idelta == 2) {
102 return d3alphar_ddelta2_dtau;
103 } else if (idelta == 3) {
104 return d4alphar_ddelta3_dtau;
105 } else {
106 throw ValueError();
107 }
108 } else if (itau == 2) {
109 if (idelta == 0) {
110 return d2alphar_dtau2;
111 } else if (idelta == 1) {
112 return d3alphar_ddelta_dtau2;
113 } else if (idelta == 2) {
114 return d4alphar_ddelta2_dtau2;
115 } else {
116 throw ValueError();
117 }
118 } else if (itau == 3) {
119 if (idelta == 0) {
120 return d3alphar_dtau3;
121 } else if (idelta == 1) {
122 return d4alphar_ddelta_dtau3;
123 } else {
124 throw ValueError();
125 }
126 } else if (itau == 4) {
127 if (idelta == 0) {
128 return d4alphar_dtau4;
129 } else {
130 throw ValueError();
131 }
132 } else {
133 throw ValueError();
134 }
135 }
136};
137#undef LIST_OF_DERIVATIVE_VARIABLES
138
140
166{
167 public:
170
172
175 virtual CoolPropDbl base(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
177 all(tau, delta, deriv);
178 return deriv.alphar;
179 };
181
184 virtual CoolPropDbl dTau(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
186 all(tau, delta, deriv);
187 return deriv.dalphar_dtau;
188 };
190
193 virtual CoolPropDbl dTau2(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
195 all(tau, delta, deriv);
196 return deriv.d2alphar_dtau2;
197 };
199
202 virtual CoolPropDbl dDelta_dTau(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
204 all(tau, delta, deriv);
205 return deriv.d2alphar_ddelta_dtau;
206 };
208
211 virtual CoolPropDbl dDelta(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
213 all(tau, delta, deriv);
214 return deriv.dalphar_ddelta;
215 };
217
220 virtual CoolPropDbl dDelta2(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
222 all(tau, delta, deriv);
223 return deriv.d2alphar_ddelta2;
224 };
226
229 virtual CoolPropDbl dDelta2_dTau(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
231 all(tau, delta, deriv);
232 return deriv.d3alphar_ddelta2_dtau;
233 };
235
238 virtual CoolPropDbl dDelta_dTau2(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
240 all(tau, delta, deriv);
241 return deriv.d3alphar_ddelta_dtau2;
242 };
244
247 virtual CoolPropDbl dTau3(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
249 all(tau, delta, deriv);
250 return deriv.d3alphar_dtau3;
251 };
253
256 virtual CoolPropDbl dDelta3(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
258 all(tau, delta, deriv);
259 return deriv.d3alphar_ddelta3;
260 };
262
265 virtual CoolPropDbl dTau4(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
267 all(tau, delta, deriv);
268 return deriv.d4alphar_dtau4;
269 };
270 virtual CoolPropDbl dDelta_dTau3(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
272 all(tau, delta, deriv);
273 return deriv.d4alphar_ddelta_dtau3;
274 };
275 virtual CoolPropDbl dDelta2_dTau2(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
277 all(tau, delta, deriv);
278 return deriv.d4alphar_ddelta2_dtau2;
279 };
280 virtual CoolPropDbl dDelta3_dTau(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
282 all(tau, delta, deriv);
283 return deriv.d4alphar_ddelta3_dtau;
284 };
285 virtual CoolPropDbl dDelta4(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
287 all(tau, delta, deriv);
288 return deriv.d4alphar_ddelta4;
289 };
290
291 virtual void all(const CoolPropDbl& tau, const CoolPropDbl& delta, HelmholtzDerivatives& derivs) = 0;
292 #if ENABLE_CATCH
293 virtual mcx::MultiComplex<double> one_mcx(const mcx::MultiComplex<double>& tau, const mcx::MultiComplex<double>& delta) const {
294 throw CoolProp::NotImplementedError("The mcx derivative function was not implemented");
295 }
296 #endif
297};
298
300{
310
312 n = 0;
313 d = 0;
314 t = 0;
315 c = 0;
316 l_double = 0;
317 omega = 0;
318 m_double = 0;
319 eta1 = 0;
320 epsilon1 = 0;
321 eta2 = 0;
322 epsilon2 = 0;
323 beta1 = 0;
324 gamma1 = 0;
325 beta2 = 0;
326 gamma2 = 0;
327 l_int = 0;
328 m_int = 0;
329 l_is_int = false;
330 m_is_int = true;
331 };
332};
342{
343
344 public:
346 std::vector<CoolPropDbl> s;
347 std::size_t N;
348
349 // These variables are for the exp(u) part
350 // u is given by -c*delta^l_i-omega*tau^m_i-eta1*(delta-epsilon1)-eta2*(delta-epsilon2)^2-beta1*(tau-gamma1)-beta2*(tau-gamma2)^2
351 std::vector<double> n, d, t, c, l_double, omega, m_double, eta1, epsilon1, eta2, epsilon2, beta1, gamma1, beta2, gamma2;
352 // If l_i or m_i are integers, we will store them as integers in order to call pow(double, int) rather than pow(double, double)
353 std::vector<int> l_int, m_int;
354
355 //Eigen::ArrayXd uE, du_ddeltaE, du_dtauE, d2u_ddelta2E, d2u_dtau2E, d3u_ddelta3E, d3u_dtau3E;
356
357 std::vector<ResidualHelmholtzGeneralizedExponentialElement> elements;
358 // Default Constructor
360 : delta_li_in_u(false), tau_mi_in_u(false), eta1_in_u(false), eta2_in_u(false), beta1_in_u(false), beta2_in_u(false), finished(false), N(0){};
366 void add_Power(const std::vector<CoolPropDbl>& n, const std::vector<CoolPropDbl>& d, const std::vector<CoolPropDbl>& t,
367 const std::vector<CoolPropDbl>& l) {
368 for (std::size_t i = 0; i < n.size(); ++i) {
370 el.n = n[i];
371 el.d = d[i];
372 el.t = t[i];
373 el.l_double = l[i];
374 el.l_int = (int)el.l_double;
375 if (el.l_double > 0)
376 el.c = 1.0;
377 else
378 el.c = 0.0;
379 elements.push_back(el);
380 }
381 delta_li_in_u = true;
382 };
388 void add_Exponential(const std::vector<CoolPropDbl>& n, const std::vector<CoolPropDbl>& d, const std::vector<CoolPropDbl>& t,
389 const std::vector<CoolPropDbl>& g, const std::vector<CoolPropDbl>& l) {
390 for (std::size_t i = 0; i < n.size(); ++i) {
392 el.n = n[i];
393 el.d = d[i];
394 el.t = t[i];
395 el.c = g[i];
396 el.l_double = l[i];
397 el.l_int = (int)el.l_double;
398 elements.push_back(el);
399 }
400 delta_li_in_u = true;
401 }
407 void add_Gaussian(const std::vector<CoolPropDbl>& n, const std::vector<CoolPropDbl>& d, const std::vector<CoolPropDbl>& t,
408 const std::vector<CoolPropDbl>& eta, const std::vector<CoolPropDbl>& epsilon, const std::vector<CoolPropDbl>& beta,
409 const std::vector<CoolPropDbl>& gamma) {
410 for (std::size_t i = 0; i < n.size(); ++i) {
412 el.n = n[i];
413 el.d = d[i];
414 el.t = t[i];
415 el.eta2 = eta[i];
416 el.epsilon2 = epsilon[i];
417 el.beta2 = beta[i];
418 el.gamma2 = gamma[i];
419 elements.push_back(el);
420 }
421 eta2_in_u = true;
422 beta2_in_u = true;
423 };
429 void add_GERG2008Gaussian(const std::vector<CoolPropDbl>& n, const std::vector<CoolPropDbl>& d, const std::vector<CoolPropDbl>& t,
430 const std::vector<CoolPropDbl>& eta, const std::vector<CoolPropDbl>& epsilon, const std::vector<CoolPropDbl>& beta,
431 const std::vector<CoolPropDbl>& gamma) {
432 for (std::size_t i = 0; i < n.size(); ++i) {
434 el.n = n[i];
435 el.d = d[i];
436 el.t = t[i];
437 el.eta2 = eta[i];
438 el.epsilon2 = epsilon[i];
439 el.eta1 = beta[i];
440 el.epsilon1 = gamma[i];
441 elements.push_back(el);
442 }
443 eta2_in_u = true;
444 eta1_in_u = true;
445 };
451 void add_Lemmon2005(const std::vector<CoolPropDbl>& n, const std::vector<CoolPropDbl>& d, const std::vector<CoolPropDbl>& t,
452 const std::vector<CoolPropDbl>& l, const std::vector<CoolPropDbl>& m) {
453 for (std::size_t i = 0; i < n.size(); ++i) {
455 el.n = n[i];
456 el.d = d[i];
457 el.t = t[i];
458 el.c = 1.0;
459 el.omega = 1.0;
460 el.l_double = l[i];
461 el.m_double = m[i];
462 el.l_int = (int)el.l_double;
463 el.m_int = (int)el.m_double;
464 elements.push_back(el);
465 }
466 delta_li_in_u = true;
467 tau_mi_in_u = true;
468 };
469
470 void finish() {
471 n.resize(elements.size());
472 d.resize(elements.size());
473 t.resize(elements.size());
474 c.resize(elements.size());
475 omega.resize(elements.size());
476 l_double.resize(elements.size());
477 l_int.resize(elements.size());
478 m_double.resize(elements.size());
479 m_int.resize(elements.size());
480 epsilon2.resize(elements.size());
481 eta2.resize(elements.size());
482 gamma2.resize(elements.size());
483 beta2.resize(elements.size());
484
485 for (std::size_t i = 0; i < elements.size(); ++i) {
486 n[i] = elements[i].n;
487 d[i] = elements[i].d;
488 t[i] = elements[i].t;
489 c[i] = elements[i].c;
490 omega[i] = elements[i].omega;
491 l_double[i] = elements[i].l_double;
492 l_int[i] = elements[i].l_int;
493 m_double[i] = elements[i].m_double;
494 m_int[i] = elements[i].m_int;
495 epsilon2[i] = elements[i].epsilon2;
496 eta2[i] = elements[i].eta2;
497 gamma2[i] = elements[i].gamma2;
498 beta2[i] = elements[i].beta2;
499
500 // See if l is an integer, and store a flag if it is
501 elements[i].l_is_int = (std::abs(static_cast<long>(elements[i].l_double) - elements[i].l_double) < 1e-14);
502 }
503 // uE.resize(elements.size());
504 // du_ddeltaE.resize(elements.size());
505 // du_dtauE.resize(elements.size());
506 // d2u_ddelta2E.resize(elements.size());
507 // d2u_dtau2E.resize(elements.size());
508 // d3u_ddelta3E.resize(elements.size());
509 // d3u_dtau3E.resize(elements.size());
510
511 finished = true;
512 };
513
514 void to_json(rapidjson::Value& el, rapidjson::Document& doc);
515
516 void all(const CoolPropDbl& tau, const CoolPropDbl& delta, HelmholtzDerivatives& derivs) override;
517 //void allEigen(const CoolPropDbl &tau, const CoolPropDbl &delta, HelmholtzDerivatives &derivs) throw();
518
519 #if ENABLE_CATCH
520 virtual mcx::MultiComplex<double> one_mcx(const mcx::MultiComplex<double>& tau, const mcx::MultiComplex<double>& delta) const override;
521 #endif
522};
523
525{
527};
529{
530
531 public:
532 std::size_t N;
533 std::vector<CoolPropDbl> s;
534 std::vector<ResidualHelmholtzNonAnalyticElement> elements;
537 N = 0;
538 };
542 ResidualHelmholtzNonAnalytic(const std::vector<CoolPropDbl>& n, const std::vector<CoolPropDbl>& a, const std::vector<CoolPropDbl>& b,
543 const std::vector<CoolPropDbl>& beta, const std::vector<CoolPropDbl>& A, const std::vector<CoolPropDbl>& B,
544 const std::vector<CoolPropDbl>& C, const std::vector<CoolPropDbl>& D) {
545 N = n.size();
546 s.resize(N);
547 for (std::size_t i = 0; i < n.size(); ++i) {
549 el.n = n[i];
550 el.a = a[i];
551 el.b = b[i];
552 el.beta = beta[i];
553 el.A = A[i];
554 el.B = B[i];
555 el.C = C[i];
556 el.D = D[i];
557 elements.push_back(el);
558 }
559 };
560 void to_json(rapidjson::Value& el, rapidjson::Document& doc);
561 void all(const CoolPropDbl& tau, const CoolPropDbl& delta, HelmholtzDerivatives& derivs) override;
562#if ENABLE_CATCH
563 virtual mcx::MultiComplex<double> one_mcx(const mcx::MultiComplex<double>& tau, const mcx::MultiComplex<double>& delta) const override;
564#endif
565};
566
568{
569 protected:
570 shared_ptr<AbstractCubic> m_abstractcubic;
571 std::vector<double> z;
572 public:
574
577 enabled = false;
578 };
580 ResidualHelmholtzGeneralizedCubic(shared_ptr<AbstractCubic>& ac) : m_abstractcubic(ac) {
581 enabled = true;
582 z = std::vector<double>(1, 1); // Init the vector to [1.0]
583 };
584
585 void to_json(rapidjson::Value& el, rapidjson::Document& doc);
586 void all(const CoolPropDbl& tau, const CoolPropDbl& delta, HelmholtzDerivatives& derivs) throw();
587};
588
590{
591 protected:
592 std::vector<double> n, t, d, eta, beta, gamma, epsilon, b;
593
594 public:
596
599 enabled = false;
600 };
601
603 ResidualHelmholtzGaoB(const std::vector<CoolPropDbl>& n, const std::vector<CoolPropDbl>& t, const std::vector<CoolPropDbl>& d,
604 const std::vector<CoolPropDbl>& eta, const std::vector<CoolPropDbl>& beta, const std::vector<CoolPropDbl>& gamma,
605 const std::vector<CoolPropDbl>& epsilon, const std::vector<CoolPropDbl>& b)
606 : n(n), t(t), d(d), eta(eta), beta(beta), gamma(gamma), epsilon(epsilon), b(b) {
607 enabled = true;
608 };
609
610 void to_json(rapidjson::Value& el, rapidjson::Document& doc);
611 void all(const CoolPropDbl& tau, const CoolPropDbl& delta, HelmholtzDerivatives& derivs) override;
612
613 #if ENABLE_CATCH
614 virtual mcx::MultiComplex<double> one_mcx(const mcx::MultiComplex<double>& tau, const mcx::MultiComplex<double>& delta) const override;
615 #endif
616};
617
620{
621
622 public:
627 ResidualHelmholtzXiangDeiters() : Tc(_HUGE), pc(_HUGE), rhomolarc(_HUGE), acentric(_HUGE), R(_HUGE), theta(_HUGE) {
628 enabled = false;
629 };
632 const CoolPropDbl R);
633 void all(const CoolPropDbl& tau, const CoolPropDbl& delta, HelmholtzDerivatives& derivs) override;
634#if ENABLE_CATCH
635 virtual mcx::MultiComplex<double> one_mcx(const mcx::MultiComplex<double>& tau, const mcx::MultiComplex<double>& delta) const override;
636#endif
637};
638
640{
641
642 protected:
644
645 CoolPropDbl Deltabar(const CoolPropDbl& tau, const CoolPropDbl& delta) const;
646 CoolPropDbl dDeltabar_ddelta__consttau(const CoolPropDbl& tau, const CoolPropDbl& delta) const;
647 CoolPropDbl d2Deltabar_ddelta2__consttau(const CoolPropDbl& tau, const CoolPropDbl& delta) const;
648 CoolPropDbl dDeltabar_dtau__constdelta(const CoolPropDbl& tau, const CoolPropDbl& delta) const;
649 CoolPropDbl d2Deltabar_dtau2__constdelta(const CoolPropDbl& tau, const CoolPropDbl& delta) const;
650 CoolPropDbl d2Deltabar_ddelta_dtau(const CoolPropDbl& tau, const CoolPropDbl& delta) const;
651 CoolPropDbl d3Deltabar_dtau3__constdelta(const CoolPropDbl& tau, const CoolPropDbl& delta) const;
652 CoolPropDbl d3Deltabar_ddelta_dtau2(const CoolPropDbl& tau, const CoolPropDbl& delta) const;
653 CoolPropDbl d3Deltabar_ddelta3__consttau(const CoolPropDbl& tau, const CoolPropDbl& delta) const;
654 CoolPropDbl d3Deltabar_ddelta2_dtau(const CoolPropDbl& tau, const CoolPropDbl& delta) const;
655
656 CoolPropDbl X(const CoolPropDbl& delta, const CoolPropDbl& Deltabar) const;
659 CoolPropDbl dX_dtau(const CoolPropDbl& tau, const CoolPropDbl& delta) const;
660 CoolPropDbl dX_ddelta(const CoolPropDbl& tau, const CoolPropDbl& delta) const;
661 CoolPropDbl d2X_dtau2(const CoolPropDbl& tau, const CoolPropDbl& delta) const;
662 CoolPropDbl d2X_ddeltadtau(const CoolPropDbl& tau, const CoolPropDbl& delta) const;
663 CoolPropDbl d2X_ddelta2(const CoolPropDbl& tau, const CoolPropDbl& delta) const;
664
665 CoolPropDbl d3X_dtau3(const CoolPropDbl& tau, const CoolPropDbl& delta) const;
666 CoolPropDbl d3X_ddelta3(const CoolPropDbl& tau, const CoolPropDbl& delta) const;
667 CoolPropDbl d3X_ddeltadtau2(const CoolPropDbl& tau, const CoolPropDbl& delta) const;
668 CoolPropDbl d3X_ddelta2dtau(const CoolPropDbl& tau, const CoolPropDbl& delta) const;
669
670 CoolPropDbl g(const CoolPropDbl& eta) const;
671 CoolPropDbl dg_deta(const CoolPropDbl& eta) const;
672 CoolPropDbl d2g_deta2(const CoolPropDbl& eta) const;
673 CoolPropDbl d3g_deta3(const CoolPropDbl& eta) const;
674 CoolPropDbl eta(const CoolPropDbl& delta) const;
675
676 public:
678 ResidualHelmholtzSAFTAssociating() : a(_HUGE), m(_HUGE), epsilonbar(_HUGE), vbarn(_HUGE), kappabar(_HUGE) {
679 disabled = true;
680 };
681
682 // Constructor
683 ResidualHelmholtzSAFTAssociating(double a, double m, double epsilonbar, double vbarn, double kappabar)
685 disabled = false;
686 };
687
689
690 //Destructor. No Implementation
692
693 void to_json(rapidjson::Value& el, rapidjson::Document& doc);
694
695 CoolPropDbl dTau4(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
696 return 1e99;
697 };
698 CoolPropDbl dDelta_dTau3(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
699 return 1e99;
700 };
701 CoolPropDbl dDelta2_dTau2(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
702 return 1e99;
703 };
704 CoolPropDbl dDelta3_dTau(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
705 return 1e99;
706 };
707 CoolPropDbl dDelta4(const CoolPropDbl& tau, const CoolPropDbl& delta) throw() {
708 return 1e99;
709 };
710
711 void all(const CoolPropDbl& tau, const CoolPropDbl& delta, HelmholtzDerivatives& deriv) throw();
712};
713
715{
716 protected:
719
720 public:
721 void clear() {
722 _base.clear();
723 _dDelta.clear();
724 _dTau.clear();
725 _dDelta2.clear();
726 _dTau2.clear();
728 _dDelta3.clear();
729 _dTau3.clear();
732 _dDelta4.clear();
736 _dTau4.clear();
737 };
738
739 virtual void empty_the_EOS() = 0;
740 virtual HelmholtzDerivatives all(const CoolPropDbl tau, const CoolPropDbl delta, bool cache_values) = 0;
741
742 CoolPropDbl base(CoolPropDbl tau, CoolPropDbl delta, const bool dont_use_cache = false) {
743 if (!_base || dont_use_cache)
744 return all(tau, delta, false).alphar;
745 else
746 return _base;
747 };
748 CoolPropDbl dDelta(CoolPropDbl tau, CoolPropDbl delta, const bool dont_use_cache = false) {
749 if (!_dDelta || dont_use_cache)
750 return all(tau, delta, false).dalphar_ddelta;
751 else
752 return _dDelta;
753 };
754 CoolPropDbl dTau(CoolPropDbl tau, CoolPropDbl delta, const bool dont_use_cache = false) {
755 if (!_dTau || dont_use_cache)
756 return all(tau, delta, false).dalphar_dtau;
757 else
758 return _dTau;
759 };
760 CoolPropDbl dDelta2(CoolPropDbl tau, CoolPropDbl delta, const bool dont_use_cache = false) {
761 if (!_dDelta2 || dont_use_cache)
762 return all(tau, delta, false).d2alphar_ddelta2;
763 else
764 return _dDelta2;
765 };
766 CoolPropDbl dDelta_dTau(CoolPropDbl tau, CoolPropDbl delta, const bool dont_use_cache = false) {
767 if (!_dDelta_dTau || dont_use_cache)
768 return all(tau, delta, false).d2alphar_ddelta_dtau;
769 else
770 return _dDelta_dTau;
771 };
772 CoolPropDbl dTau2(CoolPropDbl tau, CoolPropDbl delta, const bool dont_use_cache = false) {
773 if (!_dTau2 || dont_use_cache)
774 return all(tau, delta, false).d2alphar_dtau2;
775 else
776 return _dTau2;
777 };
778 CoolPropDbl dDelta3(CoolPropDbl tau, CoolPropDbl delta, const bool dont_use_cache = false) {
779 if (!_dDelta3 || dont_use_cache)
780 return all(tau, delta, false).d3alphar_ddelta3;
781 else
782 return _dDelta3;
783 };
784 CoolPropDbl dDelta2_dTau(CoolPropDbl tau, CoolPropDbl delta, const bool dont_use_cache = false) {
785 if (!_dDelta2_dTau || dont_use_cache)
786 return all(tau, delta, false).d3alphar_ddelta2_dtau;
787 else
788 return _dDelta2_dTau;
789 };
790 CoolPropDbl dDelta_dTau2(CoolPropDbl tau, CoolPropDbl delta, const bool dont_use_cache = false) {
791 if (!_dDelta_dTau2 || dont_use_cache)
792 return all(tau, delta, false).d3alphar_ddelta_dtau2;
793 else
794 return _dDelta_dTau2;
795 };
796 CoolPropDbl dTau3(CoolPropDbl tau, CoolPropDbl delta, const bool dont_use_cache = false) {
797 if (!_dTau3 || dont_use_cache)
798 return all(tau, delta, false).d3alphar_dtau3;
799 else
800 return _dTau3;
801 };
802 CoolPropDbl dDelta4(CoolPropDbl tau, CoolPropDbl delta, const bool dont_use_cache = false) {
803 return all(tau, delta, false).d4alphar_ddelta4;
804 };
805 CoolPropDbl dDelta3_dTau(CoolPropDbl tau, CoolPropDbl delta, const bool dont_use_cache = false) {
806 return all(tau, delta, false).d4alphar_ddelta3_dtau;
807 };
808 CoolPropDbl dDelta2_dTau2(CoolPropDbl tau, CoolPropDbl delta, const bool dont_use_cache = false) {
809 return all(tau, delta, false).d4alphar_ddelta2_dtau2;
810 };
811 CoolPropDbl dDelta_dTau3(CoolPropDbl tau, CoolPropDbl delta, const bool dont_use_cache = false) {
812 return all(tau, delta, false).d4alphar_ddelta_dtau3;
813 };
814 CoolPropDbl dTau4(CoolPropDbl tau, CoolPropDbl delta, const bool dont_use_cache = false) {
815 return all(tau, delta, false).d4alphar_dtau4;
816 };
817};
818
820{
821 public:
828
836 };
837
838 HelmholtzDerivatives all(const CoolPropDbl tau, const CoolPropDbl delta, bool cache_values = false) {
839 HelmholtzDerivatives derivs; // zeros out the elements
840 GenExp.all(tau, delta, derivs);
841 NonAnalytic.all(tau, delta, derivs);
842 SAFT.all(tau, delta, derivs);
843 cubic.all(tau, delta, derivs);
844 XiangDeiters.all(tau, delta, derivs);
845 GaoB.all(tau, delta, derivs);
846 if (cache_values) {
847 _base = derivs.alphar;
848 _dDelta = derivs.dalphar_ddelta;
849 _dTau = derivs.dalphar_dtau;
850 _dDelta2 = derivs.d2alphar_ddelta2;
851 _dTau2 = derivs.d2alphar_dtau2;
852 _dDelta_dTau = derivs.d2alphar_ddelta_dtau;
853 _dDelta3 = derivs.d3alphar_ddelta3;
854 _dTau3 = derivs.d3alphar_dtau3;
855 _dDelta2_dTau = derivs.d3alphar_ddelta2_dtau;
856 _dDelta_dTau2 = derivs.d3alphar_ddelta_dtau2;
857 }
858 return derivs;
859 };
860};
861
862// #############################################################################
863// #############################################################################
864// #############################################################################
865// IDEAL GAS TERMS
866// #############################################################################
867// #############################################################################
868// #############################################################################
869
871
877{
878
879 private:
880 CoolPropDbl a1, a2;
881 bool enabled;
882
883 public:
884 // Default constructor
885 IdealHelmholtzLead() : a1(_HUGE), a2(_HUGE), enabled(false) {}
886
887 // Constructor
888 IdealHelmholtzLead(CoolPropDbl a1, CoolPropDbl a2) : a1(a1), a2(a2), enabled(true) {}
889
890 bool is_enabled() const {
891 return enabled;
892 }
893
894 void to_json(rapidjson::Value& el, rapidjson::Document& doc) {
895 el.AddMember("type", "IdealHelmholtzLead", doc.GetAllocator());
896 el.AddMember("a1", static_cast<double>(a1), doc.GetAllocator());
897 el.AddMember("a2", static_cast<double>(a2), doc.GetAllocator());
898 };
899
900 void all(const CoolPropDbl& tau, const CoolPropDbl& delta, HelmholtzDerivatives& derivs) throw();
901};
902
904
910{
911 private:
912 CoolPropDbl a1, a2; // Use these variables internally
913 std::string reference;
914 bool enabled;
915
916 public:
917 IdealHelmholtzEnthalpyEntropyOffset() : a1(_HUGE), a2(_HUGE), enabled(false) {}
918
919 // Constructor
920 IdealHelmholtzEnthalpyEntropyOffset(CoolPropDbl a1, CoolPropDbl a2, const std::string& ref) : a1(a1), a2(a2), reference(ref), enabled(true) {}
921
922 // Set the values in the class
923 void set(CoolPropDbl a1, CoolPropDbl a2, const std::string& ref) {
924 // If it doesn't already exist, just set the values
925 if (enabled == false) {
926 this->a1 = a1;
927 this->a2 = a2;
928 enabled = true;
929 } else if (ref == "DEF") {
930 this->a1 = 0.0;
931 this->a2 = 0.0;
932 enabled = false;
933 } else {
934 // Otherwise, increment the values
935 this->a1 += a1;
936 this->a2 += a2;
937 enabled = true;
938 }
939 this->reference = ref;
940 }
941
942 bool is_enabled() const {
943 return enabled;
944 };
945
946 void to_json(rapidjson::Value& el, rapidjson::Document& doc) {
947 el.AddMember("type", "IdealHelmholtzEnthalpyEntropyOffset", doc.GetAllocator());
948 el.AddMember("a1", static_cast<double>(a1), doc.GetAllocator());
949 el.AddMember("a2", static_cast<double>(a2), doc.GetAllocator());
950 };
951 void all(const CoolPropDbl& tau, const CoolPropDbl& delta, HelmholtzDerivatives& derivs) throw();
952};
953
960{
961 private:
962 CoolPropDbl a1;
963 bool enabled;
964
965 public:
967 IdealHelmholtzLogTau() : a1(_HUGE), enabled(false) {}
968
969 // Constructor
970 IdealHelmholtzLogTau(CoolPropDbl a1) : a1(a1), enabled(true) {}
971
972 bool is_enabled() const {
973 return enabled;
974 };
975
976 void to_json(rapidjson::Value& el, rapidjson::Document& doc) {
977 el.AddMember("type", "IdealHelmholtzLogTau", doc.GetAllocator());
978 el.AddMember("a1", static_cast<double>(a1), doc.GetAllocator());
979 };
980 void all(const CoolPropDbl& tau, const CoolPropDbl& delta, HelmholtzDerivatives& derivs) throw();
981};
982
989{
990
991 private:
992 std::vector<CoolPropDbl> n, t; // Use these variables internally
993 std::size_t N;
994 bool enabled;
995
996 public:
997 IdealHelmholtzPower() : N(0), enabled(false){};
998 // Constructor
999 IdealHelmholtzPower(const std::vector<CoolPropDbl>& n, const std::vector<CoolPropDbl>& t) : n(n), t(t), N(n.size()), enabled(true){};
1000
1001 bool is_enabled() const {
1002 return enabled;
1003 };
1004
1005 void to_json(rapidjson::Value& el, rapidjson::Document& doc) {
1006 el.AddMember("type", "IdealHelmholtzPower", doc.GetAllocator());
1007 cpjson::set_long_double_array("n", n, el, doc);
1008 cpjson::set_long_double_array("t", t, el, doc);
1009 };
1010 void all(const CoolPropDbl& tau, const CoolPropDbl& delta, HelmholtzDerivatives& derivs) throw();
1011};
1012
1060{
1061
1062 private:
1063 std::vector<CoolPropDbl> n, theta, c, d; // Use these variables internally
1064 std::size_t N;
1065 bool enabled;
1066
1067 public:
1069 // Constructor with std::vector instances
1070 IdealHelmholtzPlanckEinsteinGeneralized(const std::vector<CoolPropDbl>& n, const std::vector<CoolPropDbl>& theta,
1071 const std::vector<CoolPropDbl>& c, const std::vector<CoolPropDbl>& d)
1072 : n(n), theta(theta), c(c), d(d), N(n.size()), enabled(true) {}
1073
1074 // Extend the vectors to allow for multiple instances feeding values to this function
1075 void extend(const std::vector<CoolPropDbl>& n, const std::vector<CoolPropDbl>& theta, const std::vector<CoolPropDbl>& c,
1076 const std::vector<CoolPropDbl>& d) {
1077 this->n.insert(this->n.end(), n.begin(), n.end());
1078 this->theta.insert(this->theta.end(), theta.begin(), theta.end());
1079 this->c.insert(this->c.end(), c.begin(), c.end());
1080 this->d.insert(this->d.end(), d.begin(), d.end());
1081 N += n.size();
1082 }
1083
1084 bool is_enabled() const {
1085 return enabled;
1086 };
1087
1088 void to_json(rapidjson::Value& el, rapidjson::Document& doc) {
1089 el.AddMember("type", "IdealHelmholtzPlanckEinsteinGeneralized", doc.GetAllocator());
1090 cpjson::set_long_double_array("n", n, el, doc);
1091 cpjson::set_long_double_array("theta", theta, el, doc);
1092 };
1093 void all(const CoolPropDbl& tau, const CoolPropDbl& delta, HelmholtzDerivatives& derivs) throw();
1094};
1095
1097{
1098
1099 private:
1100 double cp_over_R, Tc, T0, tau0; // Use these variables internally
1101 bool enabled;
1102
1103 public:
1105 IdealHelmholtzCP0Constant() : cp_over_R(_HUGE), Tc(_HUGE), T0(_HUGE), tau0(_HUGE) {
1106 enabled = false;
1107 };
1108
1110 IdealHelmholtzCP0Constant(CoolPropDbl cp_over_R, CoolPropDbl Tc, CoolPropDbl T0) : cp_over_R(cp_over_R), Tc(Tc), T0(T0) {
1111 enabled = true;
1112 tau0 = Tc / T0;
1113 };
1114
1117
1118 bool is_enabled() const {
1119 return enabled;
1120 };
1121
1122 void to_json(rapidjson::Value& el, rapidjson::Document& doc) {
1123 el.AddMember("type", "IdealGasHelmholtzCP0Constant", doc.GetAllocator());
1124 el.AddMember("cp_over_R", cp_over_R, doc.GetAllocator());
1125 el.AddMember("Tc", Tc, doc.GetAllocator());
1126 el.AddMember("T0", T0, doc.GetAllocator());
1127 };
1128
1129 void all(const CoolPropDbl& tau, const CoolPropDbl& delta, HelmholtzDerivatives& derivs) throw();
1130};
1131
1133{
1134 private:
1135 std::vector<CoolPropDbl> c, t;
1136 CoolPropDbl Tc, T0, tau0; // Use these variables internally
1137 std::size_t N;
1138 bool enabled;
1139
1140 public:
1141 IdealHelmholtzCP0PolyT() : Tc(_HUGE), T0(_HUGE), tau0(_HUGE), N(0), enabled(false) {}
1142
1144 IdealHelmholtzCP0PolyT(const std::vector<CoolPropDbl>& c, const std::vector<CoolPropDbl>& t, double Tc, double T0)
1145 : c(c), t(t), Tc(Tc), T0(T0), tau0(Tc / T0), N(c.size()), enabled(true) {
1146 assert(c.size() == t.size());
1147 }
1148
1149 void extend(const std::vector<CoolPropDbl>& c, const std::vector<CoolPropDbl>& t) {
1150 this->c.insert(this->c.end(), c.begin(), c.end());
1151 this->t.insert(this->t.end(), t.begin(), t.end());
1152 N += c.size();
1153 }
1154
1155 bool is_enabled() const {
1156 return enabled;
1157 };
1158
1159 void to_json(rapidjson::Value& el, rapidjson::Document& doc);
1160 void all(const CoolPropDbl& tau, const CoolPropDbl& delta, HelmholtzDerivatives& derivs) override;
1161#if ENABLE_CATCH
1162 virtual mcx::MultiComplex<double> one_mcx(const mcx::MultiComplex<double>& tau, const mcx::MultiComplex<double>& delta) const override;
1163#endif
1164};
1169{
1170 private:
1171 std::vector<CoolPropDbl> n, theta;
1172 CoolPropDbl Tc, _Tr;
1173 std::size_t N;
1174 bool enabled;
1175
1176 public:
1177 IdealHelmholtzGERG2004Sinh() : Tc(_HUGE), _Tr(_HUGE), N(0), enabled(false) {}
1178
1180 IdealHelmholtzGERG2004Sinh(const std::vector<CoolPropDbl>& n, const std::vector<CoolPropDbl>& theta, double Tc)
1181 : n(n), theta(theta), Tc(Tc), _Tr(_HUGE), N(n.size()), enabled(true) {
1182 assert(n.size() == theta.size());
1183 }
1184
1185 void extend(const std::vector<CoolPropDbl>& c, const std::vector<CoolPropDbl>& t) {
1186 this->n.insert(this->n.end(), n.begin(), n.end());
1187 this->theta.insert(this->theta.end(), theta.begin(), theta.end());
1188 N += c.size();
1189 }
1191 this->_Tr = Tr;
1192 }
1193
1194 bool is_enabled() const {
1195 return enabled;
1196 };
1197 void all(const CoolPropDbl& tau, const CoolPropDbl& delta, HelmholtzDerivatives& derivs) override;
1198
1199 #if ENABLE_CATCH
1200 virtual mcx::MultiComplex<double> one_mcx(const mcx::MultiComplex<double>& tau, const mcx::MultiComplex<double>& delta) const override;
1201 #endif
1202};
1203
1205{
1206 private:
1207 std::vector<CoolPropDbl> n, theta;
1208 CoolPropDbl Tc, _Tr;
1209 std::size_t N;
1210 bool enabled;
1211
1212 public:
1213 IdealHelmholtzGERG2004Cosh() : Tc(_HUGE), _Tr(_HUGE), N(0), enabled(false) {}
1214
1216 IdealHelmholtzGERG2004Cosh(const std::vector<CoolPropDbl>& n, const std::vector<CoolPropDbl>& theta, double Tc)
1217 : n(n), theta(theta), Tc(Tc), _Tr(_HUGE), N(n.size()), enabled(true) {
1218 assert(n.size() == theta.size());
1219 }
1220
1221 void extend(const std::vector<CoolPropDbl>& n, const std::vector<CoolPropDbl>& theta) {
1222 this->n.insert(this->n.end(), n.begin(), n.end());
1223 this->theta.insert(this->theta.end(), theta.begin(), theta.end());
1224 N += n.size();
1225 }
1227 this->_Tr = Tr;
1228 }
1229
1230 bool is_enabled() const {
1231 return enabled;
1232 };
1233 void all(const CoolPropDbl& tau, const CoolPropDbl& delta, HelmholtzDerivatives& derivs) override;
1234
1235 #if ENABLE_CATCH
1236 virtual mcx::MultiComplex<double> one_mcx(const mcx::MultiComplex<double>& tau, const mcx::MultiComplex<double>& delta) const override;
1237 #endif
1238
1239};
1240
1243//\f[
1244//\frac{c_p^0}{R_u} = A + B\left(\frac{C/T}{\sinh(C/T)}\right)^2 + D\left(\frac{E/T}{\cosh(E/T)}\right)^2
1245//\f]
1246//Second partial of ideal-gas Helmholtz energy given directly by specific heat (\f$\displaystyle\alpha_{\tau\tau}^0=-\frac{1}{\tau^2}\frac{c_p^0}{R_u} \f$) - this is obtained by real gas \f$c_p\f$ relationship, and killing off residual Helmholtz terms
1247//\f[
1248//\alpha^0_{\tau\tau} = -\frac{A}{\tau^2} - \frac{B}{\tau^2}\left(\frac{C/T}{\sinh(C/T)}\right)^2 - \frac{D}{\tau^2}\left(\frac{E/T}{\cosh(E/T)}\right)^2
1249//\f]
1250//or in terms of \f$ \tau \f$:
1251//\f[
1252//\alpha^0_{\tau\tau} = -\frac{A}{\tau^2} - \frac{BC^2}{T_c^2}\left(\frac{1}{\sinh(C\tau/T_c)}\right)^2 - \frac{DE^2}{T_c^2}\left(\frac{1}{\cosh(E\tau/T_c)}\right)^2
1253//\f]
1254//Third partial:
1255//\f[
1256//\alpha^0_{\tau\tau\tau} = 2\frac{A}{\tau^3} + 2\frac{BC^3}{T_c^3}\frac{\cosh(C\tau/T_c)}{\sinh^3(C\tau/T_c)} +2 \frac{DE^3}{T_c^3}\frac{\sinh(E\tau/T_c)}{\cosh^3(E\tau/T_c)}
1257//\f]
1258//Now coming back to the ideal gas Helmholtz energy definition:
1259//\f[
1260//\alpha^0 = -\tau\displaystyle\int_{\tau_0}^{\tau} \frac{1}{\tau^2}\frac{c_p^0}{R_u}d\tau+\displaystyle\int_{\tau_0}^{\tau} \frac{1}{\tau}\frac{c_p^0}{R_u}d\tau
1261//\f]
1262//Applying derivative
1263//\f[
1264//\alpha^0_{\tau} = -\displaystyle\int_{\tau_0}^{\tau} \frac{1}{\tau^2}\frac{c_p^0}{R_u}d\tau-\tau\frac{\partial}{\partial \tau}\left[\displaystyle\int_{\tau_0}^{\tau} \frac{1}{\tau^2}\frac{c_p^0}{R_u}d\tau \right]+\frac{\partial}{\partial \tau}\left[\displaystyle\int_{\tau_0}^{\tau} \frac{1}{\tau}\frac{c_p^0}{R_u}d\tau \right]
1265//\f]
1266//Fundamental theorem of calculus
1267//\f[
1268//\alpha^0_{\tau} = -\int_{\tau_0}^{\tau} \frac{1}{\tau^2}\frac{c_p^0}{R_u}d\tau-\tau \frac{1}{\tau^2}\frac{c_p^0}{R_u}d\tau+\frac{1}{\tau}\frac{c_p^0}{R_u}
1269//\f]
1270//Last two terms cancel, leaving
1271//\f[
1272//\alpha^0_{\tau} = -\int_{\tau_0}^{\tau} \frac{1}{\tau^2}\frac{c_p^0}{R_u}d\tau
1273//\f]
1274//Another derivative yields (from fundamental theorem of calculus)
1275//\f[
1276//\alpha^0_{\tau\tau} = - \frac{1}{\tau^2}\frac{c_p^0}{R_u}
1277//\f]
1278//
1279//see also Jaeschke and Schley, 1995, (http://link.springer.com/article/10.1007%2FBF02083547#page-1)
1280//*/
1282//class IdealHelmholtzCP0AlyLee : public BaseHelmholtzTerm{
1283//private:
1284// std::vector<CoolPropDbl> c;
1285// CoolPropDbl Tc, tau0, T0; // Use these variables internally
1286// bool enabled;
1287//public:
1288// IdealHelmholtzCP0AlyLee(){enabled = false;};
1289//
1290// /// Constructor with std::vectors
1291// IdealHelmholtzCP0AlyLee(const std::vector<CoolPropDbl> &c, double Tc, double T0)
1292// :c(c), Tc(Tc), T0(T0)
1293// {
1294// tau0=Tc/T0;
1295// enabled = true;
1296// };
1297//
1298// /// Destructor
1299// ~IdealHelmholtzCP0AlyLee(){};
1300//
1301// bool is_enabled() const {return enabled;};
1302//
1303// void to_json(rapidjson::Value &el, rapidjson::Document &doc);
1304//
1305//
1306// /// The antiderivative given by \f$ \displaystyle\int \frac{1}{\tau^2}\frac{c_p^0}{R_u}d\tau \f$
1307// /**
1308// sympy code for this derivative:
1309//
1310// from sympy import *
1311// a1,a2,a3,a4,a5,Tc,tau = symbols('a1,a2,a3,a4,a5,Tc,tau', real = True)
1312// integrand = a1 + a2*(a3/Tc/sinh(a3*tau/Tc))**2 + a4*(a5/Tc/cosh(a5*tau/Tc))**2
1313// integrand = integrand.rewrite(exp)
1314// antideriv = trigsimp(integrate(integrand,tau))
1315// display(antideriv)
1316// print latex(antideriv)
1317// print ccode(antideriv)
1318//
1319// \f[
1320// \displaystyle\int \frac{1}{\tau^2}\frac{c_p^0}{R_u}d\tau = -\frac{a_0}{\tau}+\frac{2a_1a_2}{T_c\left[\exp\left(-\frac{2a_2\tau}{T_c}\right)-1\right]}+\frac{2a_3a_4}{T_c\left[\exp\left(-\frac{2a_4\tau}{T_c}\right)+1\right]}
1321// \f]
1322// */
1323// CoolPropDbl anti_deriv_cp0_tau2(const CoolPropDbl &tau);
1324//
1325// /// The antiderivative given by \f$ \displaystyle\int \frac{1}{\tau}\frac{c_p^0}{R_u}d\tau \f$
1326// /**
1327// sympy code for this derivative:
1328//
1329// a_0,a_1,a_2,a_3,a_4,Tc,tau = symbols('a_0,a_1,a_2,a_3,a_4,Tc,tau', real = True)
1330// integrand = a_0/tau + a_1/tau*(a_2*tau/Tc/sinh(a_2*tau/Tc))**2 + a_3/tau*(a_4*tau/Tc/cosh(a_4*tau/Tc))**2
1331//
1332// term2 = a_1/tau*(a_2*tau/Tc/sinh(a_2*tau/Tc))**2
1333// term2 = term2.rewrite(exp) # Unpack the sinh to exp functions
1334// antideriv2 = trigsimp(integrate(term2,tau))
1335// display(antideriv2)
1336// print latex(antideriv2)
1337// print ccode(antideriv2)
1338//
1339// term3 = a_3/tau*(a_4*tau/Tc/cosh(a_4*tau/Tc))**2
1340// term3 = term3.rewrite(exp) # Unpack the cosh to exp functions
1341// antideriv3 = factor(trigsimp(integrate(term3,tau).rewrite(exp)))
1342// display(antideriv3)
1343// print latex(antideriv3)
1344// print ccode(antideriv3)
1345//
1346// Can be broken into three parts (trick is to express \f$sinh\f$ and \f$cosh\f$ in terms of \f$exp\f$ function)
1347//
1348// Term 2:
1349// \f[
1350// \displaystyle\int \frac{a_1a_2^2}{T_c^2}\frac{\tau}{\sinh\left(\displaystyle\frac{a_2\tau}{T_c}\right)^2} d\tau = \frac{2 a_{1} a_{2} \tau}{- Tc + Tc e^{- \frac{2 a_{2}}{Tc} \tau}} + a_{1} \log{\left (-1 + e^{- \frac{2 a_{2}}{Tc} \tau} \right )} + \frac{2 a_{1}}{Tc} a_{2} \tau
1351// \f]
1352//
1353// Term 3:
1354// \f[
1355// \displaystyle\int \frac{a_1a_2^2}{T_c^2}\frac{\tau}{\cosh\left(\displaystyle\frac{a_2\tau}{T_c}\right)^2} d\tau = - \frac{a_{3}}{Tc \left(e^{\frac{2 a_{4}}{Tc} \tau} + 1\right)} \left(Tc e^{\frac{2 a_{4}}{Tc} \tau} \log{\left (e^{\frac{2 a_{4}}{Tc} \tau} + 1 \right )} + Tc \log{\left (e^{\frac{2 a_{4}}{Tc} \tau} + 1 \right )} - 2 a_{4} \tau e^{\frac{2 a_{4}}{Tc} \tau}\right)
1356// \f]
1357// */
1358// CoolPropDbl anti_deriv_cp0_tau(const CoolPropDbl &tau);
1359//
1360// CoolPropDbl base(const CoolPropDbl &tau, const CoolPropDbl &delta) throw();
1361// CoolPropDbl dDelta(const CoolPropDbl &tau, const CoolPropDbl &delta) throw(){return 0.0;};
1362// CoolPropDbl dTau(const CoolPropDbl &tau, const CoolPropDbl &delta) throw();
1363// CoolPropDbl dDelta2(const CoolPropDbl &tau, const CoolPropDbl &delta) throw(){return 0.0;};
1364// CoolPropDbl dDelta_dTau(const CoolPropDbl &tau, const CoolPropDbl &delta) throw(){return 0.0;};
1365// CoolPropDbl dTau2(const CoolPropDbl &tau, const CoolPropDbl &delta) throw();
1366// CoolPropDbl dDelta3(const CoolPropDbl &tau, const CoolPropDbl &delta) throw(){return 0.0;};
1367// CoolPropDbl dDelta2_dTau(const CoolPropDbl &tau, const CoolPropDbl &delta) throw(){return 0.0;};
1368// CoolPropDbl dDelta_dTau2(const CoolPropDbl &tau, const CoolPropDbl &delta) throw(){return 0.0;};
1369// CoolPropDbl dTau3(const CoolPropDbl &tau, const CoolPropDbl &delta) throw();
1370// CoolPropDbl dTau4(const CoolPropDbl &tau, const CoolPropDbl &delta) throw();
1371//
1372//};
1373
1375{
1376 private:
1377 double _prefactor;
1378
1379 public:
1385
1390
1391 IdealHelmholtzContainer() : _prefactor(1.0){};
1392
1393 void set_prefactor(double prefactor) {
1394 _prefactor = prefactor;
1395 }
1396
1397 void set_Tred(double T_red) {
1398 GERG2004Cosh.set_Tred(T_red);
1399 GERG2004Sinh.set_Tred(T_red);
1400 }
1401
1413 };
1414
1415 HelmholtzDerivatives all(const CoolPropDbl tau, const CoolPropDbl delta, bool cache_values = false) {
1416 HelmholtzDerivatives derivs; // zeros out the elements
1417 Lead.all(tau, delta, derivs);
1418 EnthalpyEntropyOffsetCore.all(tau, delta, derivs);
1419 EnthalpyEntropyOffset.all(tau, delta, derivs);
1420 LogTau.all(tau, delta, derivs);
1421 Power.all(tau, delta, derivs);
1422 PlanckEinstein.all(tau, delta, derivs);
1423 CP0Constant.all(tau, delta, derivs);
1424 CP0PolyT.all(tau, delta, derivs);
1425 GERG2004Cosh.all(tau, delta, derivs);
1426 GERG2004Sinh.all(tau, delta, derivs);
1427
1428 if (cache_values) {
1429 _base = derivs.alphar * _prefactor;
1430 _dDelta = derivs.dalphar_ddelta * _prefactor;
1431 _dTau = derivs.dalphar_dtau * _prefactor;
1432 _dDelta2 = derivs.d2alphar_ddelta2 * _prefactor;
1433 _dTau2 = derivs.d2alphar_dtau2 * _prefactor;
1434 _dDelta_dTau = derivs.d2alphar_ddelta_dtau * _prefactor;
1435 _dDelta3 = derivs.d3alphar_ddelta3 * _prefactor;
1436 _dTau3 = derivs.d3alphar_dtau3 * _prefactor;
1437 _dDelta2_dTau = derivs.d3alphar_ddelta2_dtau * _prefactor;
1438 _dDelta_dTau2 = derivs.d3alphar_ddelta_dtau2 * _prefactor;
1439 }
1440 return derivs * _prefactor;
1441 };
1442};
1443}; /* namespace CoolProp */
1444
1445#endif