teqp 0.22.0
Loading...
Searching...
No Matches
derivs.hpp
Go to the documentation of this file.
1#pragma once
2
3namespace teqp{
4namespace cppinterface{
5
10 std::vector<char> vars;
11 Eigen::Array22d J;
12 Eigen::Array2d v;
13};
14
25template<typename Array>
26auto build_iteration_Jv(const std::vector<char>& vars, const Eigen::Array<double, 3, 3>& A, const double R, const double T, const double rho, const Array &z){
27 IterationMatrices im; im.vars = vars;
28
29 Eigen::Array2d& v = im.v;
30 Eigen::Array22d& J = im.J;
31 auto Trecip = 1.0/T;
32 auto dTrecipdT = -Trecip*Trecip;
33
34 // Define some lambda functions for things that *might* be needed
35 // The lambdas are used to get a sort of lazy evaluation. The lambdas are
36 // only evaluated on an as-needed basis. If the lambda is not called,
37 // no cost is incurred.
38 //
39 // Probably the compiler will inline these functions anyhow.
40 //
41 // Derivatives of total alpha; alpha = a/(R*T) = a*R/Trecip
42 auto alpha = [&](){ return A(0,0); };
43 auto dalphadTrecip = [&](){ return A(1,0)/Trecip; };
44 auto dalphadrho = [&](){ return A(0,1)/rho; };
45 auto d2alphadTrecip2 = [&](){ return A(2,0)/(Trecip*Trecip); };
46 auto d2alphadTrecipdrho = [&](){ return A(1,1)/(Trecip*rho); };
47 auto d2alphadrho2 = [&](){ return A(0,2)/(rho*rho); };
48 //
49 // Derivatives of total Helmholtz energy a in terms of derivatives of alpha
50 auto a = [&](){ return alpha()*R*T; };
51 auto dadTrecip = [&](){ return R/(Trecip*Trecip)*(Trecip*dalphadTrecip()-alpha());};
52 auto d2adTrecip2 = [&](){ return R/(Trecip*Trecip*Trecip)*(Trecip*Trecip*d2alphadTrecip2()-2*Trecip*dalphadTrecip()+2*alpha());};
53 auto dadrho = [&](){return R/Trecip*(dalphadrho());};
54 auto d2adrho2 = [&](){return R/Trecip*(d2alphadrho2());};
55 auto d2adTrecipdrho = [&](){ return R/(Trecip*Trecip)*(Trecip*d2alphadTrecipdrho()-dalphadrho());};
56
57 for (auto i = 0; i < vars.size(); ++i){
58 switch(vars[i]){
59 case 'T':
60 v(i) = T;
61 J(i, 0) = 1.0;
62 J(i, 1) = 0.0;
63 break;
64 case 'D':
65 v(i) = rho;
66 J(i, 0) = 0.0;
67 J(i, 1) = 1.0;
68 break;
69 case 'P':
70 v(i) = rho*rho*dadrho();
71 J(i, 0) = rho*rho*d2adTrecipdrho()*dTrecipdT;
72 J(i, 1) = rho*rho*d2adrho2() + 2*rho*dadrho();
73 break;
74 case 'S':
75 v(i) = Trecip*Trecip*dadTrecip();
76 J(i, 0) = (Trecip*Trecip*d2adTrecip2() + 2*Trecip*dadTrecip())*dTrecipdT;
77 J(i, 1) = Trecip*Trecip*d2adTrecipdrho();
78 break;
79 case 'H':
80 v(i) = a() + Trecip*dadTrecip() + rho*dadrho();
81 J(i, 0) = (Trecip*d2adTrecip2() + rho*d2adTrecipdrho() + 2*dadTrecip())*dTrecipdT;
82 J(i, 1) = Trecip*d2adTrecipdrho() + rho*d2adrho2() + 2*dadrho();
83 break;
84 case 'U':
85 v(i) = a() + Trecip*dadTrecip();
86 J(i, 0) = (Trecip*d2adTrecip2() + 2*dadTrecip())*dTrecipdT;
87 J(i, 1) = Trecip*d2adTrecipdrho() + dadrho();
88 break;
89 default:
90 throw std::invalid_argument("bad var: " + std::to_string(vars[i]));
91 }
92 }
93 return im;
94}
95
96}
97};
auto build_iteration_Jv(const std::vector< char > &vars, const Eigen::Array< double, 3, 3 > &A, const double R, const double T, const double rho, const Array &z)
A convenience function for calculation of Jacobian terms of the form and where is one of the therm...
Definition derivs.hpp:26
std::vector< char > vars
The set of variables matching the rows in the Jacobian.
Definition derivs.hpp:10
Eigen::Array22d J
The Jacobian.
Definition derivs.hpp:11
Eigen::Array2d v
The values of the thermodynamic variables matching the variables in vars.
Definition derivs.hpp:12