Cantera  3.1.0a1
BinarySolutionTabulatedThermo.cpp
Go to the documentation of this file.
1 /**
2  * @file BinarySolutionTabulatedThermo.cpp Implementation file for an binary
3  * solution model with tabulated standard state thermodynamic data (see
4  * @ref thermoprops and class
5  * @link Cantera::BinarySolutionTabulatedThermo BinarySolutionTabulatedThermo@endlink).
6  */
7 
8 // This file is part of Cantera. See License.txt in the top-level directory or
9 // at https://cantera.org/license.txt for license and copyright information.
10 
12 #include "cantera/thermo/PDSS.h"
14 #include "cantera/thermo/Species.h"
18 
19 namespace Cantera
20 {
21 
23  const string& id_)
24 {
25  initThermoFile(inputFile, id_);
26 }
27 
29 {
31  _updateThermo();
32 }
33 
35 {
36  static const int cacheId = m_cache.getId();
37  CachedScalar cached = m_cache.getScalar(cacheId);
38  bool x_changed = !cached.validate(stateMFNumber());
39 
40  if (x_changed) {
41  double x_tab = moleFraction(m_kk_tab);
42  double x_other = moleFraction(1 - m_kk_tab);
43  m_h0_tab = interpolate(x_tab, m_enthalpy_tab);
44  m_s0_tab = interpolate(x_tab, m_entropy_tab);
45  if (x_tab == 0) {
47  } else if (x_other == 0) {
49  } else {
50  m_s0_tab += GasConstant*std::log(x_tab / x_other) +
53  }
54  }
55 
56  double tnow = temperature();
57  if (x_changed || m_tlast != tnow) {
58  // Update the thermodynamic functions of the reference state.
59  m_spthermo.update(tnow, m_cp0_R.data(), m_h0_RT.data(), m_s0_R.data());
60  double rrt = 1.0 / RT();
61  m_h0_RT[m_kk_tab] += m_h0_tab * rrt;
63  for (size_t k = 0; k < m_kk; k++) {
64  m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k];
65  }
66  m_tlast = tnow;
67  }
68 }
69 
70 bool BinarySolutionTabulatedThermo::addSpecies(shared_ptr<Species> spec)
71 {
72  if (m_kk == 2) {
73  throw CanteraError("BinarySolutionTabulatedThermo::addSpecies",
74  "No. of species should be equal to 2");
75  }
76  bool added = IdealSolidSolnPhase::addSpecies(spec);
77  return added;
78 }
79 
81 {
82  if (m_input.hasKey("tabulated-thermo")) {
83  m_kk_tab = speciesIndex(m_input["tabulated-species"].asString());
84  if (nSpecies() != 2) {
85  throw InputFileError("BinarySolutionTabulatedThermo::initThermo",
86  m_input["species"],
87  "No. of species should be equal to 2 in phase '{}'!",name());
88  }
89  if (m_kk_tab == npos) {
90  throw InputFileError("BinarySolutionTabulatedThermo::initThermo",
91  m_input["tabulated-species"],
92  "Species '{}' is not in phase '{}'",
93  m_input["tabulated-species"].asString(), name());
94  }
95  const AnyMap& table = m_input["tabulated-thermo"].as<AnyMap>();
96  vector<double> x = table["mole-fractions"].asVector<double>();
97  size_t N = x.size();
98  vector<double> h = table.convertVector("enthalpy", "J/kmol", N);
99  vector<double> s = table.convertVector("entropy", "J/kmol/K", N);
100  vector<double> vmol(N);
101  // Check for molar-volume key in tabulatedThermo table,
102  // otherwise calculate molar volume from pure species molar volumes
103  if (table.hasKey("molar-volume")) {
104  vmol = table.convertVector("molar-volume", "m^3/kmol", N);
105  } else {
106  for(size_t i = 0; i < N; i++) {
107  vmol[i] = x[i] * m_speciesMolarVolume[m_kk_tab] + (1-x[i])
109  }
110  }
111 
112  // Sort the x, h, s, vmol data in the order of increasing x
113  vector<pair<double,double>> x_h(N), x_s(N), x_vmol(N);
114  for(size_t i = 0; i < N; i++) {
115  x_h[i] = {x[i], h[i]};
116  x_s[i] = {x[i], s[i]};
117  x_vmol[i] = {x[i], vmol[i]};
118  }
119  std::sort(x_h.begin(), x_h.end());
120  std::sort(x_s.begin(), x_s.end());
121  std::sort(x_vmol.begin(), x_vmol.end());
122 
123  // Store the sorted values in different arrays
124  m_molefrac_tab.resize(N);
125  m_enthalpy_tab.resize(N);
126  m_entropy_tab.resize(N);
127  m_molar_volume_tab.resize(N);
128  m_derived_molar_volume_tab.resize(N);
129 
130  for (size_t i = 0; i < N; i++) {
131  m_molefrac_tab[i] = x_h[i].first;
132  m_enthalpy_tab[i] = x_h[i].second;
133  m_entropy_tab[i] = x_s[i].second;
134  m_molar_volume_tab[i] = x_vmol[i].second;
135  }
136 
137  diff(m_molar_volume_tab, m_derived_molar_volume_tab);
138  }
140 }
141 
143 {
144  return !m_molefrac_tab.empty();
145 }
146 
148 {
150  phaseNode["tabulated-species"] = speciesName(m_kk_tab);
151  AnyMap tabThermo;
152  tabThermo["mole-fractions"] = m_molefrac_tab;
153  tabThermo["enthalpy"].setQuantity(m_enthalpy_tab, "J/kmol");
154  tabThermo["entropy"].setQuantity(m_entropy_tab, "J/kmol/K");
155  tabThermo["molar-volume"].setQuantity(m_molar_volume_tab, "m^3/kmol");
156  phaseNode["tabulated-thermo"] = std::move(tabThermo);
157 }
158 
160  const vector<double>& inputData) const
161 {
162  double c;
163  // Check if x is out of bound
164  if (x > m_molefrac_tab.back()) {
165  c = inputData.back();
166  return c;
167  }
168  if (x < m_molefrac_tab.front()) {
169  c = inputData.front();
170  return c;
171  }
172  size_t i = std::distance(m_molefrac_tab.begin(),
173  std::lower_bound(m_molefrac_tab.begin(), m_molefrac_tab.end(), x));
174  c = inputData[i-1] + (inputData[i] - inputData[i-1])
175  * (x - m_molefrac_tab[i-1]) / (m_molefrac_tab[i] - m_molefrac_tab[i-1]);
176  return c;
177 }
178 
179 void BinarySolutionTabulatedThermo::diff(const vector<double>& inputData,
180  vector<double>& derivedData) const
181 {
182  if (inputData.size() > 1) {
183  derivedData[0] = (inputData[1] - inputData[0]) /
184  (m_molefrac_tab[1] - m_molefrac_tab[0]);
185  derivedData.back() = (inputData.back() - inputData[inputData.size()-2]) /
186  (m_molefrac_tab.back() - m_molefrac_tab[m_molefrac_tab.size()-2]);
187 
188  if (inputData.size() > 2) {
189  for (size_t i = 1; i < inputData.size()-1; i++) {
190  derivedData[i] = (inputData[i+1] - inputData[i-1]) /
191  (m_molefrac_tab[i+1] - m_molefrac_tab[i-1]);
192  }
193  }
194  } else {
195  derivedData.front() = 0;
196  }
197 }
198 
200 {
201  std::copy(m_speciesMolarVolume.begin(), m_speciesMolarVolume.end(), vbar);
202 }
203 
205 {
206  double Xtab = moleFraction(m_kk_tab);
207  double Vm = interpolate(Xtab, m_molar_volume_tab);
208  double dVdX_tab = interpolate(Xtab, m_derived_molar_volume_tab);
209  m_speciesMolarVolume[m_kk_tab] = Vm + (1 - Xtab) * dVdX_tab;
210  m_speciesMolarVolume[1-m_kk_tab] = Vm - Xtab * dVdX_tab;
211 
212  double dens = meanMolecularWeight() / Vm;
213 
214  // Set the density in the parent State object directly, by calling the
215  // Phase::assignDensity() function.
216  Phase::assignDensity(dens);
217 }
218 }
Header file for an binary solution model with tabulated standard state thermodynamic data (see Thermo...
Header for a general species thermodynamic property manager for a phase (see MultiSpeciesThermo).
Declarations for the virtual base class PDSS (pressure dependent standard state) which handles calcul...
Header for factory functions to build instances of classes that manage the standard-state thermodynam...
Declaration for class Cantera::Species.
Headers for the factory class that can create known ThermoPhase objects (see Thermodynamic Properties...
A map of string keys to values whose type can vary at runtime.
Definition: AnyMap.h:427
size_t size() const
Returns the number of elements in this map.
Definition: AnyMap.h:622
bool hasKey(const string &key) const
Returns true if the map contains an item named key.
Definition: AnyMap.cpp:1423
vector< double > convertVector(const string &key, const string &units, size_t nMin=npos, size_t nMax=npos) const
Convert a vector of dimensional values.
Definition: AnyMap.cpp:1555
vector< double > m_molefrac_tab
Vector for storing tabulated thermo.
double m_s0_tab
Tabulated contribution to s0[m_kk_tab] at the current composition.
void getParameters(AnyMap &phaseNode) const override
Store the parameters of a ThermoPhase object such that an identical one could be reconstructed using ...
void initThermo() override
Initialize the ThermoPhase object after all species have been set up.
void getPartialMolarVolumes(double *vbar) const override
returns an array of partial molar volumes of the species in the solution.
double interpolate(const double x, const vector< double > &inputData) const
Species thermodynamics linear interpolation function.
size_t m_kk_tab
Current tabulated species index.
void diff(const vector< double > &inputData, vector< double > &derivedData) const
Numerical derivative of the molar volume table.
void calcDensity() override
Overloads the calcDensity() method of IdealSolidSoln to also consider non-ideal behavior.
BinarySolutionTabulatedThermo(const string &infile="", const string &id="")
Construct and initialize an BinarySolutionTabulatedThermo ThermoPhase object directly from an input f...
double m_h0_tab
Tabulated contribution to h0[m_kk_tab] at the current composition.
void compositionChanged() override
If the compositions have changed, update the tabulated thermo lookup.
bool ready() const override
Returns a bool indicating whether the object is ready for use.
bool addSpecies(shared_ptr< Species > spec) override
Add a Species to this Phase.
void _updateThermo() const override
This function gets called for every call to functions in this class.
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:66
vector< double > m_g0_RT
Vector containing the species reference Gibbs functions at T = m_tlast.
vector< double > m_h0_RT
Vector containing the species reference enthalpies at T = m_tlast.
void getParameters(AnyMap &phaseNode) const override
Store the parameters of a ThermoPhase object such that an identical one could be reconstructed using ...
void initThermo() override
Initialize the ThermoPhase object after all species have been set up.
double standardConcentration(size_t k) const override
The standard concentration used to normalize the generalized concentration.
vector< double > m_s0_R
Vector containing the species reference entropies at T = m_tlast.
vector< double > m_speciesMolarVolume
Vector of molar volumes for each species in the solution.
void compositionChanged() override
Apply changes to the state which are needed after the composition changes.
vector< double > m_cp0_R
Vector containing the species reference constant pressure heat capacities at T = m_tlast.
bool addSpecies(shared_ptr< Species > spec) override
Add a Species to this Phase.
Error thrown for problems processing information contained in an AnyMap or AnyValue.
Definition: AnyMap.h:738
virtual void update(double T, double *cp_R, double *h_RT, double *s_R) const
Compute the reference-state properties for all species.
void assignDensity(const double density_)
Set the internally stored constant density (kg/m^3) of the phase.
Definition: Phase.cpp:597
ValueCache m_cache
Cached for saved calculations within each ThermoPhase.
Definition: Phase.h:822
size_t nSpecies() const
Returns the number of species in the phase.
Definition: Phase.h:231
size_t m_kk
Number of species in the phase.
Definition: Phase.h:842
double temperature() const
Temperature (K).
Definition: Phase.h:562
double meanMolecularWeight() const
The mean molecular weight. Units: (kg/kmol)
Definition: Phase.h:655
string speciesName(size_t k) const
Name of the species with index k.
Definition: Phase.cpp:142
size_t speciesIndex(const string &name) const
Returns the index of a species named 'name' within the Phase object.
Definition: Phase.cpp:129
double moleFraction(size_t k) const
Return the mole fraction of a single species.
Definition: Phase.cpp:439
int stateMFNumber() const
Return the State Mole Fraction Number.
Definition: Phase.h:761
string name() const
Return the name of the phase.
Definition: Phase.cpp:20
double RT() const
Return the Gas Constant multiplied by the current temperature.
Definition: ThermoPhase.h:1062
double m_tlast
last value of the temperature processed by reference state
Definition: ThermoPhase.h:1985
void initThermoFile(const string &inputFile, const string &id)
Initialize a ThermoPhase object using an input file.
MultiSpeciesThermo m_spthermo
Pointer to the calculation manager for species reference-state thermodynamic properties.
Definition: ThermoPhase.h:1962
AnyMap m_input
Data supplied via setParameters.
Definition: ThermoPhase.h:1966
CachedScalar getScalar(int id)
Get a reference to a CachedValue object representing a scalar (double) with the given id.
Definition: ValueCache.h:161
int getId()
Get a unique id for a cached value.
Definition: ValueCache.cpp:21
const double Faraday
Faraday constant [C/kmol].
Definition: ct_defs.h:131
const double GasConstant
Universal Gas Constant [J/kmol/K].
Definition: ct_defs.h:120
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:564
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:180
const double BigNumber
largest number to compare to inf.
Definition: ct_defs.h:160
Contains declarations for string manipulation functions within Cantera.
A cached property value and the state at which it was evaluated.
Definition: ValueCache.h:33
bool validate(double state1New)
Check whether the currently cached value is valid based on a single state variable.
Definition: ValueCache.h:39