From 626ca33e46fec2cbb3ea8c83a3068645e903d9a2 Mon Sep 17 00:00:00 2001 From: George Dan Miron <44091914+gdmiron@users.noreply.github.com> Date: Wed, 6 Jan 2021 20:28:33 +0100 Subject: [PATCH] Fixes for formula parser and CpfT for phase transition (#24) * fix for Cp=f(T) phase transition, problems with the derivatives * added default valences and fixed formula parser bug * tests for formula parser and CpfT with phase transition --- CMakeLists.txt | 2 +- ThermoFun/Common/formuladata.cpp | 14 +- ThermoFun/Common/formuladata.h | 105 +++ ThermoFun/Database.cpp | 3 + ThermoFun/Element.cpp | 2 +- .../Substances/EmpiricalCpIntegration.cpp | 79 ++- pytests/Fe-O_system.json | 644 ++++++++++++++++++ pytests/Substances/Solids/Mo(s).json | 477 +++++++++++++ .../Solids/test_CpfT_phase_transition.py | 23 + pytests/test_database.py | 12 + 10 files changed, 1356 insertions(+), 5 deletions(-) create mode 100644 pytests/Fe-O_system.json create mode 100644 pytests/Substances/Solids/Mo(s).json create mode 100644 pytests/Substances/Solids/test_CpfT_phase_transition.py diff --git a/CMakeLists.txt b/CMakeLists.txt index a9167e69..c9b8cfad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.9) # Set the name of the project -project(ThermoFun VERSION 0.3.5 LANGUAGES CXX) +project(ThermoFun VERSION 0.3.6 LANGUAGES CXX) # Set the cmake module path of the project set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") diff --git a/ThermoFun/Common/formuladata.cpp b/ThermoFun/Common/formuladata.cpp index abfb1188..c6b320ba 100644 --- a/ThermoFun/Common/formuladata.cpp +++ b/ThermoFun/Common/formuladata.cpp @@ -166,7 +166,10 @@ void FormulaToken::unpack( list& itt_ ) } datamap.push_back( FormulaValues( key, itr->stoich, itr->val )); elements.insert(key); - elements_map.insert(pair(key,itr->stoich)); + if (elements_map.find(key) != elements_map.end()) + elements_map.at(key) += itr->stoich; + else + elements_map.insert(pair(key,itr->stoich)); // coefficients.push_back(itr->stoich); itr++; } @@ -407,9 +410,16 @@ void ChemicalFormula::addOneElement(Element e) eldata.entropy = e.entropy(); eldata.heat_capacity = e.heatCapacity(); eldata.volume = e.volume(); + if (e.valence()==777) + { + if (elements_valences.find(e.symbol()) != elements_valences.end()) + e.setValence(elements_valences.at(e.symbol())); + else + e.setValence(0); + } eldata.valence = e.valence(); eldata.number = e.number(); - eldata.name = e.name(); + eldata.name = e.symbol(); // was e.name(); dbElements[elkey] = eldata; } diff --git a/ThermoFun/Common/formuladata.h b/ThermoFun/Common/formuladata.h index 49e212fd..5cb337cf 100644 --- a/ThermoFun/Common/formuladata.h +++ b/ThermoFun/Common/formuladata.h @@ -10,6 +10,111 @@ namespace ThermoFun { class Element; +const std::map elements_valences = { + {"Ac", 3}, + {"Ag", 1}, + {"Al", 3}, + {"Ar", 0}, + {"Am", 3}, + {"As", 5}, + {"Au", 1}, + {"B", 3}, + {"Ba", 2}, + {"Be", 2}, + {"Bi", 3}, + {"Br", -1}, + {"C", 4}, + {"Ca", 2}, + {"Cd", 2}, + {"Ce", 3}, + {"Cf", 3}, + {"Cit", -3}, + {"Cl", -1}, + {"Co", 2}, + {"Cr", 3}, + {"Cm", 3}, + {"Cs", 1}, + {"Cu", 2}, + {"Dy", 3}, + {"Edta", -4}, + {"Er", 3}, + {"Eu", 3}, + {"F", -1}, + {"Fr", 1}, + {"Fe", 2}, + {"Ga", 3}, + {"Gd", 3}, + {"Ge", 4}, + {"H", 1}, + {"He", 0}, + {"Hf", 4}, + {"Hg", 2}, + {"Ho", 3}, + {"I", -1}, + {"In", 3}, + {"Isa", -4}, + {"Ir", 4}, + {"K", 1}, + {"Kr", 0}, + {"La", 3}, + {"Li", 1}, + {"Lu", 3}, + {"Mg", 2}, + {"Mn", 2}, + {"Mo", 6}, + {"N", 5}, + {"N_atm", 0}, + {"Na", 1}, + {"Nb", 5}, + {"Nd", 3}, + {"Ne", 0}, + {"Ni", 2}, + {"Np", 6}, + {"O", -2}, + {"Os", 4}, + {"Ox", -2}, + {"P", 5}, + {"Pa", 5}, + {"Pb", 2}, + {"Pd", 2}, + {"Po", 4}, + {"Pu", 6}, + {"Pr", 3}, + {"Pm", 3}, + {"Pt", 2}, + {"Ra", 2}, + {"Rb", 1}, + {"Re", 4}, + {"Rh", 2}, + {"Rn", 0}, + {"Ru", 2}, + {"S", 6}, + {"Sb", 3}, + {"Sc", 3}, + {"Se", 4}, + {"Si", 4}, + {"Sm", 3}, + {"Sn", 2}, + {"Sr", 2}, + {"Ta", 5}, + {"Tb", 3}, + {"Tc", 7}, + {"Te", 6}, + {"Th", 4}, + {"Ti", 4}, + {"Tl", 1}, + {"Tm", 3}, + {"U", 6}, + {"V", 5}, + {"W", 6}, + {"Xe", 0}, + {"Y", 3}, + {"Yb", 3}, + {"Zn", 2}, + {"Zr", 4}, + {"Zz", 0} +}; + /// Key fields of Element vertex class ElementKey diff --git a/ThermoFun/Database.cpp b/ThermoFun/Database.cpp index bf85883b..9923a9d5 100644 --- a/ThermoFun/Database.cpp +++ b/ThermoFun/Database.cpp @@ -485,6 +485,9 @@ auto Database::parseSubstanceFormula(std::string formula_) const -> std::map Ti; + + const auto& Tr = substance.referenceT(); + + std::vector dHt; + std::vector dVt; + + Ti.push_back(substance.referenceT()); + + for(int i = 0; i < thermo_parameters.phase_transition_prop.size(); ++i) + { + if(TK_ > thermo_parameters.temperature_intervals[i][1]) + {Ti.push_back(thermo_parameters.temperature_intervals[i][1]); + dHt.push_back(thermo_parameters.phase_transition_prop[i][2]); + dVt.push_back(thermo_parameters.phase_transition_prop[i][3]);} + } + + + Ti.push_back(TK_); + + Reaktoro_::ThermoScalar xCp; + for(unsigned i = 0; i+1 < Ti.size(); ++i) + if(Ti[i] <= TK_ && TK_ <= Ti[i+1]) + xCp = thermo_parameters.Cp_coeff[i][0] + thermo_parameters.Cp_coeff[i][1]*TK_ + thermo_parameters.Cp_coeff[i][2]/(TK_*TK_); + + + // Calculate the integrals of the heat capacity function of the mineral from Tr to T at constant pressure Pr + Reaktoro_::ThermoScalar CpdT; + Reaktoro_::ThermoScalar CpdlnT; + for(unsigned i = 0; i+1 < Ti.size(); ++i) + { + const auto T0 = Ti[i]; + const auto T1 = Ti[i+1]; + + for (unsigned j = 0; j < thermo_parameters.Cp_coeff[i].size(); j++) + { + if (j == 16) + break; + ac[j] = thermo_parameters.Cp_coeff[i][j]; + } + + + CpdT += ac[0]*(T1 - T0) + 0.5*ac[1]*(T1*T1 - T0*T0) - ac[2]*(1.0/T1 - 1.0/T0); + CpdlnT += ac[0]*log(T1/T0) + ac[1]*(T1 - T0) - 0.5*ac[2]*(1.0/(T1*T1) - 1.0/(T0*T0)); + } + + // Calculate the volume and other auxiliary quantities for the thermodynamic properties of the mineral + Reaktoro_::ThermoScalar xV(0.0); + Reaktoro_::ThermoScalar GdH; + Reaktoro_::ThermoScalar HdH; + Reaktoro_::ThermoScalar SdH; + for(unsigned i = 1; i+1 < Ti.size(); ++i) + { + GdH += dHt[i-1]*(TK_ - Ti[i])/Ti[i]; + HdH += dHt[i-1]; + SdH += dHt[i-1]/Ti[i]; + + xV += dVt[i-1]; + } + + // Calculate the standard molal thermodynamic properties of the mineral + auto xG = Gr - Sr * (TK_ - Tr) + CpdT - TK_ * CpdlnT - GdH; // + VdP + auto xH = Hr + CpdT + HdH; // + VdP + auto xS = Sr + CpdlnT + SdH; +// auto xU = xH - Pb*V; +// auto xA = xU - TK_*S; + + */ + return thermo_properties_PT; } diff --git a/pytests/Fe-O_system.json b/pytests/Fe-O_system.json new file mode 100644 index 00000000..2d0303dc --- /dev/null +++ b/pytests/Fe-O_system.json @@ -0,0 +1,644 @@ +{ + "elements": [ + { + "symbol": "O", + "class_": { + "0": "ELEMENT" + }, + "entropy": { + "values": [ + 102.569000244141 + ], + "name": "S0i" + }, + "atomic_mass": { + "values": [ + 15.999400138855 + ], + "name": "M0i" + }, + "datasources": [ + "PSI-Nagra-12-07" + ] + }, + { + "symbol": "Fe", + "class_": { + "0": "ELEMENT" + }, + "entropy": { + "values": [ + 27.2800006866455 + ], + "name": "S0i" + }, + "atomic_mass": { + "values": [ + 55.8450012207031 + ], + "name": "M0i" + }, + "datasources": [ + "PSI-Nagra-12-07" + ] + } +], + "substances": [ + { + "name": "O2, oxygen", + "symbol": "O2", + "formula": "O|0|2", + "formula_charge": 0, + "aggregate_state": { + "0": "AS_GAS" + }, + "class_": { + "1": "SC_GASFLUID" + }, + "Tst": 298.15, + "Pst": 100000, + "TPMethods": [ + { + "method": { + "0": "cp_ft_equation" + }, + "limitsTP": { + "range": true, + "lowerT": 273.15, + "upperT": 1500.15 + }, + "m_heat_capacity_ft_coeffs": { + "values": [ + 49.987899780273, + -0.00086758099496365, + 572421, + -462.03500366211, + -2.2271200350588e-7, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "units": [ + "J/(mol*K)", + "J/(mol*K^2)", + "(J*K)/mol", + "J/(mol*K^0.5)", + "J/(mol*K^3)", + "J/(mol*K^4)", + "J/(mol*K^5)", + "(J*K^2)/mol", + "J/mol", + "J/(mol*K^1.5)", + "J/(mol*K)" + ], + "names": [ + "a0", + "a1", + "a2", + "a3", + "a4", + "a5", + "a6", + "a7", + "a8", + "a9", + "a10" + ] + } + }, + { + "method": { + "9": "fluid_prsv" + }, + "eos_gas_crit_props": { + "values": [ + 154.77000427246, + 50.900001525879, + 0.021279999986291, + 0.01511999964714, + 0, + 0, + 0 + ], + "units": [ + "K", + "bar", + "", + "" + ], + "names": [ + "Tcr", + "Pcr", + "W", + "k1" + ] + } + } + ], + "sm_heat_capacity_p": { + "values": [ + 29.390605926514 + ], + "errors": [ + 0 + ], + "units": [ + "J/(mol*K)" + ] + }, + "sm_gibbs_energy": { + "values": [ + 0 + ], + "units": [ + "J/mol" + ] + }, + "sm_enthalpy": { + "values": [ + 0 + ], + "units": [ + "J/mol" + ] + }, + "sm_entropy_abs": { + "values": [ + 205.19000244141 + ], + "units": [ + "J/(mol*K)" + ] + }, + "sm_volume": { + "values": [ + 2476.7026367188 + ], + "errors": [ + 0 + ], + "units": [ + "J/bar" + ] + }, + "datasources": [ + "Frenkel_al:1994:compil:", + "Stryjek_Vera:1986:model:" + ] + }, + { + "name": "Magnetite", + "symbol": "Magnetite_charge_specified", + "formula": "FeFe|3|2O4", + "formula_charge": 0, + "aggregate_state": { + "3": "AS_CRYSTAL" + }, + "class_": { + "0": "SC_COMPONENT" + }, + "Tst": 298.15, + "Pst": 100000, + "TPMethods": [ + { + "method": { + "0": "cp_ft_equation" + }, + "limitsTP": { + "range": true, + "lowerT": 273.15, + "upperT": 1273.15 + }, + "m_heat_capacity_ft_coeffs": { + "values": [ + 262.5, + -0.0072039999067783, + -1926200, + -1655.6999511719, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "units": [ + "J/(mol*K)", + "J/(mol*K^2)", + "(J*K)/mol", + "J/(mol*K^0.5)", + "J/(mol*K^3)", + "J/(mol*K^4)", + "J/(mol*K^5)", + "(J*K^2)/mol", + "J/mol", + "J/(mol*K^1.5)", + "J/(mol*K)" + ], + "names": [ + "a0", + "a1", + "a2", + "a3", + "a4", + "a5", + "a6", + "a7", + "a8", + "a9", + "a10" + ] + } + }, + { + "method": { + "5": "landau_holland_powell98" + }, + "m_landau_phase_trans_props": { + "values": [ + 574.84997558594, + 35, + 0 + ] + } + }, + { + "method": { + "38": "mv_eos_murnaghan_hp98" + } + } + ], + "sm_heat_capacity_p": { + "values": [ + 142.79548645019 + ], + "errors": [ + 0 + ], + "units": [ + "J/(mol*K)" + ] + }, + "sm_gibbs_energy": { + "values": [ + -1012310 + ], + "units": [ + "J/mol" + ] + }, + "sm_enthalpy": { + "values": [ + -1115550 + ], + "units": [ + "J/mol" + ] + }, + "sm_entropy_abs": { + "values": [ + 146.10000610352 + ], + "units": [ + "J/(mol*K)" + ] + }, + "sm_volume": { + "values": [ + 4.4520001411438 + ], + "errors": [ + 0 + ], + "units": [ + "J/bar" + ] + }, + "m_compressibility": { + "values": [ + 1850 + ], + "units": [ + "1e-05/K" + ] + }, + "m_expansivity": { + "values": [ + 0.000069599998823833 + ], + "units": [ + "kbar" + ] + }, + "datasources": [ + "H&P:1998:phaseq:" + ] + }, + { + "name": "Magnetite", + "symbol": "Magnetite", + "formula": "Fe3O4", + "formula_charge": 0, + "aggregate_state": { + "3": "AS_CRYSTAL" + }, + "class_": { + "0": "SC_COMPONENT" + }, + "Tst": 298.15, + "Pst": 100000, + "TPMethods": [ + { + "method": { + "0": "cp_ft_equation" + }, + "limitsTP": { + "range": true, + "lowerT": 273.15, + "upperT": 1273.15 + }, + "m_heat_capacity_ft_coeffs": { + "values": [ + 262.5, + -0.0072039999067783, + -1926200, + -1655.6999511719, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "units": [ + "J/(mol*K)", + "J/(mol*K^2)", + "(J*K)/mol", + "J/(mol*K^0.5)", + "J/(mol*K^3)", + "J/(mol*K^4)", + "J/(mol*K^5)", + "(J*K^2)/mol", + "J/mol", + "J/(mol*K^1.5)", + "J/(mol*K)" + ], + "names": [ + "a0", + "a1", + "a2", + "a3", + "a4", + "a5", + "a6", + "a7", + "a8", + "a9", + "a10" + ] + } + }, + { + "method": { + "5": "landau_holland_powell98" + }, + "m_landau_phase_trans_props": { + "values": [ + 574.84997558594, + 35, + 0 + ] + } + }, + { + "method": { + "38": "mv_eos_murnaghan_hp98" + } + } + ], + "sm_heat_capacity_p": { + "values": [ + 142.79548645019 + ], + "errors": [ + 0 + ], + "units": [ + "J/(mol*K)" + ] + }, + "sm_gibbs_energy": { + "values": [ + -1012310 + ], + "units": [ + "J/mol" + ] + }, + "sm_enthalpy": { + "values": [ + -1115550 + ], + "units": [ + "J/mol" + ] + }, + "sm_entropy_abs": { + "values": [ + 146.10000610352 + ], + "units": [ + "J/(mol*K)" + ] + }, + "sm_volume": { + "values": [ + 4.4520001411438 + ], + "errors": [ + 0 + ], + "units": [ + "J/bar" + ] + }, + "m_compressibility": { + "values": [ + 1850 + ], + "units": [ + "1e-05/K" + ] + }, + "m_expansivity": { + "values": [ + 0.000069599998823833 + ], + "units": [ + "kbar" + ] + }, + "datasources": [ + "H&P:1998:phaseq:" + ] + }, + { + "name": "Hematite", + "symbol": "Hematite", + "formula": "Fe|3|2O3", + "formula_charge": 0, + "aggregate_state": { + "3": "AS_CRYSTAL" + }, + "class_": { + "0": "SC_COMPONENT" + }, + "Tst": 298.15, + "Pst": 100000, + "TPMethods": [ + { + "method": { + "0": "cp_ft_equation" + }, + "limitsTP": { + "range": true, + "lowerT": 273.15, + "upperT": 1273.15 + }, + "m_heat_capacity_ft_coeffs": { + "values": [ + 163.89999389648, + 0, + -2257200, + -657.59997558594, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "units": [ + "J/(mol*K)", + "J/(mol*K^2)", + "(J*K)/mol", + "J/(mol*K^0.5)", + "J/(mol*K^3)", + "J/(mol*K^4)", + "J/(mol*K^5)", + "(J*K^2)/mol", + "J/mol", + "J/(mol*K^1.5)", + "J/(mol*K)" + ], + "names": [ + "a0", + "a1", + "a2", + "a3", + "a4", + "a5", + "a6", + "a7", + "a8", + "a9", + "a10" + ] + } + }, + { + "method": { + "5": "landau_holland_powell98" + }, + "m_landau_phase_trans_props": { + "values": [ + 681.84997558594, + 15.60000038147, + 0 + ] + } + }, + { + "method": { + "38": "mv_eos_murnaghan_hp98" + } + } + ], + "sm_heat_capacity_p": { + "values": [ + 100.42362976074 + ], + "errors": [ + 0 + ], + "units": [ + "J/(mol*K)" + ] + }, + "sm_gibbs_energy": { + "values": [ + -743730 + ], + "units": [ + "J/mol" + ] + }, + "sm_enthalpy": { + "values": [ + -825730 + ], + "units": [ + "J/mol" + ] + }, + "sm_entropy_abs": { + "values": [ + 87.400001525879 + ], + "units": [ + "J/(mol*K)" + ] + }, + "sm_volume": { + "values": [ + 3.0269999504089 + ], + "errors": [ + 0 + ], + "units": [ + "J/bar" + ] + }, + "m_compressibility": { + "values": [ + 1996 + ], + "units": [ + "1e-05/K" + ] + }, + "m_expansivity": { + "values": [ + 0.000059900001360802 + ], + "units": [ + "kbar" + ] + }, + "datasources": [ + "H&P:1998:phaseq:" + ] + } + ] +} diff --git a/pytests/Substances/Solids/Mo(s).json b/pytests/Substances/Solids/Mo(s).json new file mode 100644 index 00000000..ebe2624f --- /dev/null +++ b/pytests/Substances/Solids/Mo(s).json @@ -0,0 +1,477 @@ +{ + "substances": [ + { + "name": "Mo solid", + "symbol": "Mo", + "formula": "Mo|0|", + "formula_charge": 0, + "aggregate_state": { + "3": "AS_CRYSTAL" + }, + "class_": { + "0": "SC_COMPONENT" + }, + "Tst": 298.15, + "Pst": 100000, + "TPMethods": [ + { + "method": { + "0": "cp_ft_equation" + }, + "limitsTP": { + "range": true, + "lowerT": 273.15, + "upperT": 1899.9999755859 + }, + "m_heat_capacity_ft_coeffs": { + "values": [ + 24.729999542236, + 0.0039599998854101, + -170000, + 0, + -0.000001269999984288, + 1.1499999841291e-9, + 0, + 0, + 0, + 0, + 0 + ], + "units": [ + "J/(mol*K)", + "J/(mol*K^2)", + "(J*K)/mol", + "J/(mol*K^0.5)", + "J/(mol*K^3)", + "J/(mol*K^4)", + "J/(mol*K^5)", + "(J*K^2)/mol", + "J/mol", + "J/(mol*K^1.5)", + "J/(mol*K)" + ], + "names": [ + "a0", + "a1", + "a2", + "a3", + "a4", + "a5", + "a6", + "a7", + "a8", + "a9", + "a10" + ] + }, + "m_phase_trans_props": { + "values": [ + 1899.9999755859, + 0, + 0, + 0, + 0 + ], + "units": [ + "K", + "J/(mol*K)", + "J/mol", + "J/bar", + "K/bar" + ], + "names": [ + "Temperature", + "dS", + "dH", + "dV", + "dT/dP" + ] + } + }, + { + "method": { + "0": "cp_ft_equation" + }, + "limitsTP": { + "range": true, + "lowerT": 1899.9999755859, + "upperT": 2896.0000976563 + }, + "m_heat_capacity_ft_coeffs": { + "values": [ + 1231.1899414062, + -0.96299999952316, + -712000000, + 0, + 0.00028400000883266, + -2.8000000540373e-8, + 0, + 0, + 0, + 0, + 0 + ], + "units": [ + "J/(mol*K)", + "J/(mol*K^2)", + "(J*K)/mol", + "J/(mol*K^0.5)", + "J/(mol*K^3)", + "J/(mol*K^4)", + "J/(mol*K^5)", + "(J*K^2)/mol", + "J/mol", + "J/(mol*K^1.5)", + "J/(mol*K)" + ], + "names": [ + "a0", + "a1", + "a2", + "a3", + "a4", + "a5", + "a6", + "a7", + "a8", + "a9", + "a10" + ] + } + }, + { + "method": { + "34": "mv_constant" + } + } + ], + "sm_heat_capacity_p": { + "values": [ + 23.915855407715 + ], + "errors": [ + 0 + ], + "units": [ + "J/(mol*K)" + ] + }, + "sm_gibbs_energy": { + "values": [ + 0 + ], + "errors": [ + 0 + ], + "units": [ + "J/mol" + ] + }, + "sm_enthalpy": { + "values": [ + 0 + ], + "errors": [ + 0 + ], + "units": [ + "J/mol" + ] + }, + "sm_entropy_abs": { + "values": [ + 28.604999542236 + ], + "errors": [ + 0.050000000745058 + ], + "units": [ + "J/(mol*K)" + ] + }, + "sm_volume": { + "values": [ + 0.93900001049042 + ], + "errors": [ + 0 + ], + "units": [ + "J/bar" + ] + }, + "datasources": [ + "ACSEPT:2009:1:" + ] + }, + { + "Pst": 100000, + "TPMethods": [ + { + "limitsTP": { + "lowerT": 273.15, + "range": true, + "upperT": 368.60000457764 + }, + "m_heat_capacity_ft_coeffs": { + "names": [ + "a0", + "a1", + "a2", + "a3", + "a4", + "a5", + "a6", + "a7", + "a8", + "a9", + "a10" + ], + "units": [ + "J/(mol*K)", + "J/(mol*K^2)", + "(J*K)/mol", + "J/(mol*K^0.5)", + "J/(mol*K^3)", + "J/(mol*K^4)", + "J/(mol*K^5)", + "(J*K^2)/mol", + "J/mol", + "J/(mol*K^1.5)", + "J/(mol*K)" + ], + "values": [ + 14.978719711304, + 0.026108158752322, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "m_phase_trans_props": { + "names": [ + "Temperature", + "dS", + "dH", + "dV", + "dT/dP" + ], + "units": [ + "K", + "J/(mol*K)", + "J/mol", + "J/bar", + "K/bar" + ], + "values": [ + 368.60000457764, + 0.96483993530273, + 355.64001464844, + 0, + 0 + ] + }, + "method": { + "0": "cp_ft_equation" + } + }, + { + "limitsTP": { + "lowerT": 368.60000457764, + "range": true, + "upperT": 391.99999847412 + }, + "m_heat_capacity_ft_coeffs": { + "names": [ + "a0", + "a1", + "a2", + "a3", + "a4", + "a5", + "a6", + "a7", + "a8", + "a9", + "a10" + ], + "units": [ + "J/(mol*K)", + "J/(mol*K^2)", + "(J*K)/mol", + "J/(mol*K^0.5)", + "J/(mol*K^3)", + "J/(mol*K^4)", + "J/(mol*K^5)", + "(J*K^2)/mol", + "J/mol", + "J/(mol*K^1.5)", + "J/(mol*K)" + ], + "values": [ + 25.940799713135, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "m_phase_trans_props": { + "names": [ + "Temperature", + "dS", + "dH", + "dV", + "dT/dP" + ], + "units": [ + "K", + "J/(mol*K)", + "J/mol", + "J/bar", + "K/bar" + ], + "values": [ + 391.99999847412, + 3.5756123065948, + 1401.6400146484, + 0, + 0 + ] + }, + "method": { + "0": "cp_ft_equation" + } + }, + { + "limitsTP": { + "lowerT": 391.99999847412, + "range": true, + "upperT": 717.79999389648 + }, + "m_heat_capacity_ft_coeffs": { + "names": [ + "a0", + "a1", + "a2", + "a3", + "a4", + "a5", + "a6", + "a7", + "a8", + "a9", + "a10" + ], + "units": [ + "J/(mol*K)", + "J/(mol*K^2)", + "(J*K)/mol", + "J/(mol*K^0.5)", + "J/(mol*K^3)", + "J/(mol*K^4)", + "J/(mol*K^5)", + "(J*K^2)/mol", + "J/mol", + "J/(mol*K^1.5)", + "J/(mol*K)" + ], + "values": [ + 36.526317596435, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "method": { + "0": "cp_ft_equation" + } + }, + { + "method": { + "34": "mv_constant" + } + } + ], + "Tst": 298.15, + "aggregate_state": { + "3": "AS_CRYSTAL" + }, + "class_": { + "0": "SC_COMPONENT" + }, + "datasources": [ + "Slop98_dat:1998:data:" + ], + "formula": "S|0|", + "formula_charge": 0, + "name": "SULFUR", + "sm_enthalpy": { + "units": [ + "J/mol" + ], + "values": [ + 0 + ] + }, + "sm_entropy_abs": { + "units": [ + "J/(mol*K)" + ], + "values": [ + 31.798398971558 + ] + }, + "sm_gibbs_energy": { + "units": [ + "J/mol" + ], + "values": [ + 0 + ] + }, + "sm_heat_capacity_p": { + "errors": [ + 0 + ], + "units": [ + "J/(mol*K)" + ], + "values": [ + 22.762866973877 + ] + }, + "sm_volume": { + "errors": [ + 0 + ], + "units": [ + "J/bar" + ], + "values": [ + 1.5609999895096 + ] + }, + "symbol": "Sulfur" + } + ] +} diff --git a/pytests/Substances/Solids/test_CpfT_phase_transition.py b/pytests/Substances/Solids/test_CpfT_phase_transition.py new file mode 100644 index 00000000..3fc01aad --- /dev/null +++ b/pytests/Substances/Solids/test_CpfT_phase_transition.py @@ -0,0 +1,23 @@ +import thermofun as thermofun +import pytest as pytest +import unittest + + +class TestCpfT(unittest.TestCase): + + def setUp(self): + self.engine = thermofun.ThermoEngine('pytests/Substances/Solids/Mo(s).json') + + def test_properties_substance(self): + assert self.engine.thermoPropertiesSubstance(50+273.15, 1e5, "Sulfur").gibbs_energy.val == pytest.approx(-818.39713, 1e-5, 1e-14) + assert self.engine.thermoPropertiesSubstance(50+273.15, 1e5, "Sulfur").enthalpy.val == pytest.approx(577.23048, 1e-5, 1e-14) + assert self.engine.thermoPropertiesSubstance(50+273.15, 1e5, "Sulfur").entropy.val == pytest.approx(33.65718, 1e-5, 1e-14) + assert self.engine.thermoPropertiesSubstance(50+273.15, 1e5, "Sulfur").heat_capacity_cp.val == pytest.approx(23.41557, 1e-5, 1e-14) + assert self.engine.thermoPropertiesSubstance(100+273.15, 1e5, "Sulfur").gibbs_energy.val == pytest.approx(-2593.4817, 1e-5, 1e-14) + assert self.engine.thermoPropertiesSubstance(100+273.15, 1e5, "Sulfur").enthalpy.val == pytest.approx(2142.10468, 1e-5, 1e-14) + assert self.engine.thermoPropertiesSubstance(100+273.15, 1e5, "Sulfur").entropy.val == pytest.approx(38.098027, 1e-5, 1e-14) + assert self.engine.thermoPropertiesSubstance(100+273.15, 1e5, "Sulfur").heat_capacity_cp.val == pytest.approx(25.940799, 1e-5, 1e-14) + assert self.engine.thermoPropertiesSubstance(200+273.15, 1e5, "Sulfur").gibbs_energy.val == pytest.approx(-7096.92410, 1e-5, 1e-14) + assert self.engine.thermoPropertiesSubstance(200+273.15, 1e5, "Sulfur").enthalpy.val == pytest.approx(6996.83946, 1e-5, 1e-14) + assert self.engine.thermoPropertiesSubstance(200+273.15, 1e5, "Sulfur").entropy.val == pytest.approx(49.82448, 1e-5, 1e-14) + assert self.engine.thermoPropertiesSubstance(200+273.15, 1e5, "Sulfur").heat_capacity_cp.val == pytest.approx(36.52631, 1e-5, 1e-14) \ No newline at end of file diff --git a/pytests/test_database.py b/pytests/test_database.py index 64ba2a3a..881bc153 100644 --- a/pytests/test_database.py +++ b/pytests/test_database.py @@ -48,3 +48,15 @@ def test_append_element(self): self.database.appendData('pytests/test-element-Co-thermofun.json') assert self.database.parseSubstanceFormula('Co+2') assert self.database.numberOfElements() == 5 + + def test_formula_parser(self): + self.database.appendData('pytests/Fe-O_system.json') + assert self.database.parseSubstanceFormula('FeFe|3|2O4') + elements = self.database.parseSubstanceFormula('FeFe|3|2O4') + assert len(elements) == 2 + assert elements[list(elements.keys())[0]] == 3 + assert elements[list(elements.keys())[1]] == 4 + elements = self.database.parseSubstanceFormula('C|-4|H4@') + assert elements[list(elements.keys())[0]] == 1 + assert elements[list(elements.keys())[1]] == 4 + assert elements[list(elements.keys())[2]] == 0