Skip to content

Commit e3c2458

Browse files
authored
Origin bucket (#18)
* Database object can now be constructed using a file or a string containing a ThermoDataSet in valid JSON * fixed division by zero problem in the propagation of derivatives * fix calculation of derivatives in Cp f(T) method at reference T-P * example properties reaction * bug-fix entropy of reaction
1 parent ae8feb6 commit e3c2458

File tree

7 files changed

+157
-129
lines changed

7 files changed

+157
-129
lines changed

ThermoFun/Common/ThermoScalar.hpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ inline auto sqrt(const ThermoScalarBase<V>& l) -> ThermoScalarBase<double>
403403
const double tmp1 = std::sqrt(l.val);
404404
const double tmp2 = 0.5 * tmp1/l.val;
405405
if (l.val == 0)
406-
return {tmp1, tmp2 * l.ddt, tmp2 * l.ddp, 0, status(l)};
406+
return {tmp1, /*tmp2 * l.ddt, tmp2 * l.ddp,*/ 0.0,0.0,0.0, status(l)};
407407
return {tmp1, tmp2 * l.ddt, tmp2 * l.ddp, 0.5*(l.err/l.val), status(l)};
408408
}
409409

@@ -414,7 +414,7 @@ inline auto pow(const ThermoScalarBase<V>& l, double power) -> ThermoScalarBase<
414414
const double tmp1 = std::pow(l.val, power);
415415
const double tmp2 = power * tmp1/l.val;
416416
if (l.val == 0)
417-
return {tmp1, tmp2 * l.ddt, tmp2 * l.ddp, 0.0, status(l)};
417+
return {tmp1, /*tmp2 * l.ddt, tmp2 * l.ddp,*/0.0,0.0, 0.0, status(l)};
418418
return {tmp1, tmp2 * l.ddt, tmp2 * l.ddp, std::fabs(power)*(l.err/l.val), status(l)};
419419
}
420420

@@ -426,7 +426,7 @@ inline auto pow(const ThermoScalarBase<VL>& l, const ThermoScalarBase<VR>& power
426426
const double powl = std::pow(l.val, power.val);
427427
const double tmp = power.val/l.val;
428428
if (l.val == 0)
429-
return {powl, powl * (logl * power.ddt + tmp * l.ddt), powl * (logl * power.ddp + tmp * l.ddp), 0.0, status(l,power)};
429+
return {powl, powl * (logl * power.ddt + /*tmp * l.ddt*/0.0), powl * (logl * power.ddp + /*tmp * l.ddp*/0.0), 0.0, status(l,power)};
430430
return {powl, powl * (logl * power.ddt + tmp * l.ddt), powl * (logl * power.ddp + tmp * l.ddp), powl*(l.err/l.val), status(l,power)};
431431
}
432432

@@ -445,7 +445,7 @@ inline auto log(const ThermoScalarBase<V>& l) -> ThermoScalarBase<double>
445445
const double tmp1 = std::log(l.val);
446446
const double tmp2 = 1.0/l.val;
447447
if (l.val == 0)
448-
return {tmp1, tmp2 * l.ddt, tmp2 * l.ddp, 0.0, status(l)};
448+
return {tmp1, /*tmp2 * l.ddt, tmp2 * l.ddp,*/ 0.0,0.0, 0.0, status(l)};
449449
return {tmp1, tmp2 * l.ddt, tmp2 * l.ddp, 0.434*(l.err/l.val), status(l)};
450450
}
451451

ThermoFun/Database.cpp

+15-5
Original file line numberDiff line numberDiff line change
@@ -259,16 +259,26 @@ struct Database::Impl
259259
}
260260
}
261261

262-
/// Parses the JSON file and puts the data into the internal data structure
262+
/// Parses the JSON file (or string) and puts the data into the internal data structure
263263
/// @param filename name of the file (in the working directory)
264264
auto fromFile(std::string filename) -> void
265265
{
266266
try {
267-
std::ifstream ifs(filename);
268-
if (!ifs.good())
269-
funError("File reading error", std::string("Database file "+ filename +" not found!"), __LINE__, __FILE__);
270267

271-
json j = json::parse(ifs);
268+
json j;
269+
270+
try
271+
{
272+
// trying to see if the string is a valid json
273+
j = json::parse(filename);
274+
}
275+
catch (json::parse_error &e)
276+
{
277+
std::ifstream ifs(filename);
278+
if (!ifs.good())
279+
funError("File reading error", std::string("Database file " + filename + " not found!"), __LINE__, __FILE__);
280+
j = json::parse(ifs);
281+
}
272282

273283
if (j.contains("elements"))
274284
addRecords(j["elements"], "element");

ThermoFun/Database.h

+7-4
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,18 @@ class Database
2929
/// Construct default database instance
3030
Database();
3131

32-
/// Construct a database instance by parsing a "json" file
33-
/// containg the exported substances and reactions
32+
/**
33+
* @brief Construct a new Database object
34+
*
35+
* @param filename name/path of the file or a string containing a ThermoDataSet in JSON format
36+
*/
3437
explicit Database(std::string filename);
3538

3639
/**
3740
* @brief Database constructs a database instace from a vector of records in json format
3841
* Records with the same symbol will be overwritten!
3942
* @param jsonRecords vector of records in JSON string format
40-
* @param _label, oprional, (element, substance, reactions),
43+
* @param _label, optional, (element, substance, reactions),
4144
* used when the vector of records are of one type and do not contain themselves the key "_label"
4245
*/
4346
Database(std::vector<std::string> jsonRecords, std::string _label);
@@ -51,7 +54,7 @@ class Database
5154
/**
5255
* @brief appendData append records to the database from a file.
5356
* Records with the same symbol will be overwritten!
54-
* @param filename path to the file with recors
57+
* @param filename name/path of the file or a string containing a ThermoDataSet in JSON format
5558
*/
5659
auto appendData(std::string filename) -> void;
5760

ThermoFun/Substances/EmpiricalCpIntegration.cpp

+114-107
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,26 @@
55
#include "Substance.h"
66
#include <iomanip>
77

8-
namespace ThermoFun {
8+
namespace ThermoFun
9+
{
910

1011
auto thermoPropertiesEmpCpIntegration(Reaktoro_::Temperature TK, Reaktoro_::Pressure /*Pbar*/, Substance substance) -> ThermoPropertiesSubstance
1112
{
12-
ThermoPropertiesSubstance thermo_properties_PT = substance.thermoProperties();
13-
ThermoPropertiesSubstance thermo_properties_PrTr = substance.thermoReferenceProperties();
14-
SubstanceClass::type substance_class = substance.substanceClass();
15-
ThermoParametersSubstance thermo_parameters = substance.thermoParameters();
13+
ThermoPropertiesSubstance thermo_properties_PT = substance.thermoProperties();
14+
ThermoPropertiesSubstance thermo_properties_PrTr = substance.thermoReferenceProperties();
15+
SubstanceClass::type substance_class = substance.substanceClass();
16+
ThermoParametersSubstance thermo_parameters = substance.thermoParameters();
1617

1718
Reaktoro_::ThermoScalar V;
18-
int k=-1;
19+
int k = -1;
1920
vector<double> ac;
20-
auto TK_=TK;
21-
for (unsigned i = 0; i <16; i++)
21+
auto TK_ = TK;
22+
for (unsigned i = 0; i < 16; i++)
2223
{
2324
ac.push_back(0.0);
2425
}
2526

26-
auto TrK = substance.referenceT()/* + C_to_K*/;
27+
auto TrK = substance.referenceT() /* + C_to_K*/;
2728

2829
auto S = thermo_properties_PrTr.entropy;
2930
auto G = thermo_properties_PrTr.gibbs_energy;
@@ -35,16 +36,8 @@ auto thermoPropertiesEmpCpIntegration(Reaktoro_::Temperature TK, Reaktoro_::Pres
3536
return thermo_properties_PrTr;
3637
}
3738

38-
// aW.twp->devG = dc[q].Gs[1];
39-
// ??????????????????????????????????????'
40-
// if( !dc[q].Cp )
41-
// {
42-
// aW.twp->Cp = (double)dc[q].Cps[0];
43-
// goto NEXT;
44-
// }
45-
4639
// get Cp interval -> this has to go!!!!
47-
for (size_t i=0; i<thermo_parameters.temperature_intervals.size(); i++)
40+
for (size_t i = 0; i < thermo_parameters.temperature_intervals.size(); i++)
4841
{
4942
if (thermo_parameters.temperature_intervals[i].size() > 0)
5043
{
@@ -60,120 +53,134 @@ auto thermoPropertiesEmpCpIntegration(Reaktoro_::Temperature TK, Reaktoro_::Pres
6053
}
6154
}
6255

63-
if (k<0)
56+
if (k < 0)
6457
{
6558
if (TK_ < thermo_parameters.temperature_intervals[0][0])
6659
k = 0;
67-
if (TK_ > thermo_parameters.temperature_intervals[thermo_parameters.temperature_intervals.size()-1][1])
68-
k = thermo_parameters.temperature_intervals.size()-1;
69-
std::cout << "The given temperature: "<< TK_ <<" is not inside the specified interval/s for the Cp calculation.";
70-
std::cout << "The temperature is not inside the specified interval for the substance "<< substance.symbol() << "." << std::endl << __FILE__ << std::endl << __LINE__;
71-
// Exception exception;
72-
// exception.error << "The given temperature: "<< TK_ <<" is not inside the specified interval/s for the Cp calculation.";
73-
// exception.reason << "The temperature is not inside the specified interval for the substance "<< substance.symbol() << ".";
74-
// exception.file = __FILE__;
75-
// exception.line = __LINE__;
76-
// RaiseError(exception)
60+
if (TK_ > thermo_parameters.temperature_intervals[thermo_parameters.temperature_intervals.size() - 1][1])
61+
k = thermo_parameters.temperature_intervals.size() - 1;
62+
std::cout << "The given temperature: " << TK_ << " is not inside the specified interval/s for the Cp calculation.";
63+
std::cout << "The temperature is not inside the specified interval for the substance " << substance.symbol() << "." << std::endl
64+
<< __FILE__ << std::endl
65+
<< __LINE__;
7766
}
7867

68+
k = 0;
7969

80-
81-
k=0;
82-
83-
for (unsigned i=0; i<thermo_parameters.Cp_coeff[k].size(); i++)
70+
for (unsigned i = 0; i < thermo_parameters.Cp_coeff[k].size(); i++)
8471
{
85-
if (i== 16) break;
72+
if (i == 16)
73+
break;
8674
ac[i] = thermo_parameters.Cp_coeff[k][i];
8775
}
8876

89-
// ac = thermo_parameters.Cp_coeff[k];
90-
91-
auto Cp = ( ac[0] + ac[1]*TK + ac[2]/(TK*TK) + ac[3]/(pow(TK,0.5)) + ac[4]*(TK*TK)
92-
+ ac[5]*(TK*TK*TK) + ac[6]*(TK*TK*TK*TK) + ac[7]/(TK*TK*TK) + ac[8]/TK + ac[9]*(pow(TK,(1/2))) /*+ ac[10]*log(T)*/);
93-
94-
// Phase transitions
95-
if (fabs(TK.val-TrK) > TEMPER_PREC)
77+
auto Cp = (ac[0] +
78+
ac[1] * TK +
79+
ac[2] / (TK * TK) +
80+
ac[3] / (pow(TK, 0.5)) +
81+
ac[4] * (TK * TK) +
82+
ac[5] * (TK * TK * TK) +
83+
ac[6] * (TK * TK * TK * TK) +
84+
ac[7] / (TK * TK * TK) +
85+
ac[8] / TK +
86+
ac[9] * (pow(TK, (1 / 2))) /*+ ac[10]*log(T)*/);
87+
88+
for (unsigned j = 0, ft = 0; j <= k; j++)
9689
{
97-
for (unsigned j=0, ft = 0; j<=k; j++)
98-
{
99-
if ( j == k )
100-
TK = TK_.val/* + C_to_K*/; // current T is the end T for phase transition Cp calculations
101-
else TK = thermo_parameters.temperature_intervals[j][1] /*+ C_to_K*/; // takes the upper bound from the j-th Tinterval
102-
103-
if( !j )
104-
TrK = substance.referenceT() /*+ C_to_K*/; // if j=0 the first interval should contain the reference T (Tcr)
105-
else TrK = thermo_parameters.temperature_intervals[j][0] /*+ C_to_K*/; // if j>0 then we are in a different Tinterval and the reference T becomes the lower bound of the interval
106-
107-
auto Tst2 = TrK * TrK;
108-
auto Tst3 = Tst2 * TrK;
109-
auto Tst4 = Tst3 * TrK;
110-
auto Tst05 = std::sqrt( TrK );
111-
112-
// going trough the phase transitions parameters in FtP
113-
// for (unsigned ft = 0; ft < thermo_parameters.phase_transition_prop.size(); ft++)
114-
115-
if (j && thermo_parameters.phase_transition_prop.size() == 0)
116-
{
117-
Exception exception;
118-
exception.error << "No phase transition properties present in the record.";
119-
exception.reason << "For substance "<< substance.symbol() << ".";
120-
exception.line = __LINE__;
121-
RaiseError(exception);
122-
}
90+
if (j == k)
91+
TK = TK_.val /* + C_to_K*/; // current T is the end T for phase transition Cp calculations
92+
else
93+
TK = thermo_parameters.temperature_intervals[j][1] /*+ C_to_K*/; // takes the upper bound from the j-th Tinterval
12394

124-
if ( j && thermo_parameters.phase_transition_prop[ft][0] <= TrK/*-C_to_K*/ )
125-
{ // Adding parameters of phase transition
126-
if ( thermo_parameters.phase_transition_prop[ft].size() > 1 ) // dS
127-
S += thermo_parameters.phase_transition_prop[ft][1];
128-
if ( thermo_parameters.phase_transition_prop[ft].size() > 2 ) // dH
129-
H += thermo_parameters.phase_transition_prop[ft][2];
130-
if ( thermo_parameters.phase_transition_prop[ft].size() > 3 ) // dV
131-
V += thermo_parameters.phase_transition_prop[ft][3];
132-
// More to be added ?
133-
ft++;
134-
}
95+
if (!j)
96+
TrK = substance.referenceT() /*+ C_to_K*/; // if j=0 the first interval should contain the reference T (Tcr)
97+
else
98+
TrK = thermo_parameters.temperature_intervals[j][0] /*+ C_to_K*/; // if j>0 then we are in a different Tinterval and the reference T becomes the lower bound of the interval
13599

136-
G -= S * (TK - TrK);
100+
auto Tst2 = TrK * TrK;
101+
auto Tst3 = Tst2 * TrK;
102+
auto Tst4 = Tst3 * TrK;
103+
auto Tst05 = std::sqrt(TrK);
137104

138-
for (unsigned i=0; i<thermo_parameters.Cp_coeff[j].size(); i++)
139-
{
140-
if (i== 16) break;
141-
ac[i] = thermo_parameters.Cp_coeff[j][i];
142-
}
105+
// going trough the phase transitions parameters in FtP
106+
// for (unsigned ft = 0; ft < thermo_parameters.phase_transition_prop.size(); ft++)
143107

108+
if (j && thermo_parameters.phase_transition_prop.size() == 0)
109+
{
110+
Exception exception;
111+
exception.error << "No phase transition properties present in the record.";
112+
exception.reason << "For substance " << substance.symbol() << ".";
113+
exception.line = __LINE__;
114+
RaiseError(exception)
115+
}
144116

145-
S += ( ac[0] * log( (TK/TrK) ) + ac[1] * (TK - TrK) + ac[2] * ( 1./Tst2 - 1./(TK*TK) ) / 2.
146-
+ ac[3] * 2. * ( 1./Tst05 - 1./(pow(TK,0.5)) ) + ac[4] * ( (TK*TK) - Tst2 ) / 2.
147-
+ ac[5] * ( (pow(TK,3)) - Tst3 ) / 3. + ac[6] * ( (pow(TK,4)) - Tst4 ) / 4.
148-
+ ac[7] * ( 1./ Tst3 - 1./ (pow(TK,3)) ) / 3. + ac[8] * (1. / TrK - 1. / TK )
149-
+ ac[9] * 2.* ( (pow(TK,0.5)) - Tst05 ) );
117+
if (j && thermo_parameters.phase_transition_prop[ft][0] <= TrK /*-C_to_K*/)
118+
{ // Adding parameters of phase transition
119+
if (thermo_parameters.phase_transition_prop[ft].size() > 1) // dS
120+
S += thermo_parameters.phase_transition_prop[ft][1];
121+
if (thermo_parameters.phase_transition_prop[ft].size() > 2) // dH
122+
H += thermo_parameters.phase_transition_prop[ft][2];
123+
if (thermo_parameters.phase_transition_prop[ft].size() > 3) // dV
124+
V += thermo_parameters.phase_transition_prop[ft][3];
125+
// More to be added ?
126+
ft++;
127+
}
150128

151-
G -= ( ac[0] * ( TK * log( (TK/TrK) ) - (TK - TrK) ) + ac[1] * (pow((TK - TrK),2)) / 2. + ac[2] * (pow((TK - TrK),2)) / TK / Tst2 / 2.
152-
+ ac[3] * 2. * ((pow(TK,0.5)) - Tst05)*((pow(TK,0.5)) - Tst05) / Tst05 + ac[4] * ( (pow(TK,3)) + 2.*Tst3 - 3.* TK * Tst2 ) / 6.
153-
+ ac[5] * ( (pow(TK,4)) + 3.*Tst4 - 4.*TK * Tst3 ) / 12. + ac[6] * ( (pow(TK,4))*TK + 4.*Tst4*TrK - 5.*TK*Tst4 ) / 20.
154-
+ ac[7] * ( Tst3 - 3.* (pow(TK,2)) * TrK + 2.*(pow(TK,3)) ) / 6./ (pow(TK,2)) / Tst3 + ac[8] * ( (TK/TrK) - 1. - log( (TK/TrK) ))
155-
+ ac[9] * 2.* ( 2.* TK * (pow(TK,0.5)) - 3.* TK * Tst05 + TrK * Tst05 ) / 3. );
129+
G -= S * (TK - TrK);
156130

157-
H += ( ac[0] * (TK - TrK) + ac[1] * ( (pow(TK,2)) - Tst2 ) / 2. + ac[2] * ( 1./TrK - 1./TK )
158-
+ ac[3] * 2. * ( (pow(TK,0.5)) - Tst05 ) + ac[4] * ( (pow(TK,3)) - Tst3 ) / 3.
159-
+ ac[5] * ( (pow(TK,4)) - Tst4 ) / 4. + ac[6] * ( (pow(TK,4)) * TK - Tst4 * TrK ) / 5
160-
+ ac[7] * ( 1./ Tst2 - 1./ (pow(TK,2)) ) / 2. + ac[8] * log( (TK/TrK) )
161-
+ ac[9] * 2.* ( TK * (pow(TK,0.5)) - TrK * Tst05 ) / 3. );
131+
for (unsigned i = 0; i < thermo_parameters.Cp_coeff[j].size(); i++)
132+
{
133+
if (i == 16)
134+
break;
135+
ac[i] = thermo_parameters.Cp_coeff[j][i];
162136
}
137+
138+
S += (ac[0] * log((TK / TrK)) +
139+
ac[1] * (TK - TrK) +
140+
ac[2] * (1. / Tst2 - 1. / (TK * TK)) / 2. +
141+
ac[3] * 2. * (1. / Tst05 - 1. / (pow(TK, 0.5))) +
142+
ac[4] * ((TK * TK) - Tst2) / 2. +
143+
ac[5] * ((pow(TK, 3)) - Tst3) / 3. +
144+
ac[6] * ((pow(TK, 4)) - Tst4) / 4. +
145+
ac[7] * (1. / Tst3 - 1. / (pow(TK, 3))) / 3. +
146+
ac[8] * (1. / TrK - 1. / TK) +
147+
ac[9] * 2. * ((pow(TK, 0.5)) - Tst05));
148+
149+
G -= (ac[0] * (TK * log((TK / TrK)) - (TK - TrK)) +
150+
ac[1] * (pow((TK - TrK), 2)) / 2. +
151+
ac[2] * (pow((TK - TrK), 2)) / TK / Tst2 / 2. +
152+
ac[3] * 2. * ((pow(TK, 0.5)) - Tst05) * ((pow(TK, 0.5)) - Tst05) / Tst05 +
153+
ac[4] * ((pow(TK, 3)) + 2. * Tst3 - 3. * TK * Tst2) / 6. +
154+
ac[5] * ((pow(TK, 4)) + 3. * Tst4 - 4. * TK * Tst3) / 12. +
155+
ac[6] * ((pow(TK, 4)) * TK + 4. * Tst4 * TrK - 5. * TK * Tst4) / 20. +
156+
ac[7] * (Tst3 - 3. * (pow(TK, 2)) * TrK + 2. * (pow(TK, 3))) / 6. / (pow(TK, 2)) / Tst3 +
157+
ac[8] * ((TK / TrK) - 1. - log((TK / TrK))) +
158+
ac[9] * 2. * (2. * TK * (pow(TK, 0.5)) - 3. * TK * Tst05 + TrK * Tst05) / 3.);
159+
160+
H += (ac[0] * (TK - TrK) +
161+
ac[1] * ((pow(TK, 2)) - Tst2) / 2. +
162+
ac[2] * (1. / TrK - 1. / TK) +
163+
ac[3] * 2. * ((pow(TK, 0.5)) - Tst05) +
164+
ac[4] * ((pow(TK, 3)) - Tst3) / 3. +
165+
ac[5] * ((pow(TK, 4)) - Tst4) / 4. +
166+
ac[6] * ((pow(TK, 4)) * TK - Tst4 * TrK) / 5 +
167+
ac[7] * (1. / Tst2 - 1. / (pow(TK, 2))) / 2. +
168+
ac[8] * log((TK / TrK)) +
169+
ac[9] * 2. * (TK * (pow(TK, 0.5)) - TrK * Tst05) / 3.);
163170
}
164171

165-
thermo_properties_PT.heat_capacity_cp = Cp;
166-
thermo_properties_PT.gibbs_energy = G;
167-
thermo_properties_PT.enthalpy = H;
168-
thermo_properties_PT.entropy = S;
169-
thermo_properties_PT.volume = V;
172+
thermo_properties_PT.heat_capacity_cp = Cp;
173+
thermo_properties_PT.gibbs_energy = G;
174+
thermo_properties_PT.enthalpy = H;
175+
thermo_properties_PT.entropy = S;
176+
thermo_properties_PT.volume = V;
170177

171-
if (k<0)
178+
if (k < 0)
172179
{
173-
setMessage(Reaktoro_::Status::calculated,"Empirical Cp integration: Outside temperature bounds", thermo_properties_PT );
180+
setMessage(Reaktoro_::Status::calculated, "Empirical Cp integration: Outside temperature bounds", thermo_properties_PT);
174181
}
175182

176183
return thermo_properties_PT;
177184
}
178185

179-
}
186+
} // namespace ThermoFun

ThermoFun/ThermoEngine.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ struct ThermoEngine::Impl
605605
tpr.reaction_enthalpy += VP;
606606
auto Vref = pref.workReaction.thermo_ref_prop().reaction_volume;
607607
tpr.log_equilibrium_constant -= Vref *(P_-Pref)/(R_CONSTANT*T)/lg_to_ln;
608-
tpr.reaction_entropy = tpr.reaction_gibbs_energy - T*tpr.reaction_entropy;
608+
tpr.reaction_entropy = (tpr.reaction_enthalpy - tpr.reaction_gibbs_energy)/T;
609609
tpr.reaction_internal_energy = tpr.reaction_enthalpy - P_*tpr.reaction_volume;
610610
tpr.reaction_helmholtz_energy = tpr.reaction_internal_energy - T*tpr.reaction_entropy;
611611

0 commit comments

Comments
 (0)