diff --git a/include/cantera/thermo/MolalityVPSSTP.h b/include/cantera/thermo/MolalityVPSSTP.h index cd6da08c9..482377c40 100644 --- a/include/cantera/thermo/MolalityVPSSTP.h +++ b/include/cantera/thermo/MolalityVPSSTP.h @@ -698,8 +698,11 @@ public: /*! * @param show_thermo If true, extra information is printed out * about the thermodynamic state of the system. + * @param threshold Show information about species with mole fractions + * greater than *threshold*. */ - virtual std::string report(bool show_thermo = true) const; + virtual std::string report(bool show_thermo=true, + doublereal threshold=1e-14) const; protected: diff --git a/include/cantera/thermo/MolarityIonicVPSSTP.h b/include/cantera/thermo/MolarityIonicVPSSTP.h index fc35b9d6b..791448db8 100644 --- a/include/cantera/thermo/MolarityIonicVPSSTP.h +++ b/include/cantera/thermo/MolarityIonicVPSSTP.h @@ -276,8 +276,11 @@ public: /*! * @param show_thermo If true, extra information is printed out * about the thermodynamic state of the system. + * @param threshold Show information about species with mole fractions + * greater than *threshold*. */ - virtual std::string report(bool show_thermo = true) const; + virtual std::string report(bool show_thermo=true, + doublereal threshold=1e-14) const; private: //! Initialize lengths of local variables after all species have been identified. diff --git a/include/cantera/thermo/PseudoBinaryVPSSTP.h b/include/cantera/thermo/PseudoBinaryVPSSTP.h index b7e4108b5..f759f7976 100644 --- a/include/cantera/thermo/PseudoBinaryVPSSTP.h +++ b/include/cantera/thermo/PseudoBinaryVPSSTP.h @@ -187,7 +187,8 @@ public: * @param show_thermo If true, extra information is printed out * about the thermodynamic state of the system. */ - virtual std::string report(bool show_thermo = true) const; + virtual std::string report(bool show_thermo=true, + doublereal threshold=1e-14) const; private: //! Initialize lengths of local variables after all species have diff --git a/include/cantera/thermo/PureFluidPhase.h b/include/cantera/thermo/PureFluidPhase.h index a2ec3bd28..7f875c640 100644 --- a/include/cantera/thermo/PureFluidPhase.h +++ b/include/cantera/thermo/PureFluidPhase.h @@ -499,8 +499,10 @@ public: /*! * @param show_thermo If true, extra information is printed out * about the thermodynamic state of the system. + * @param threshold Unused in this subclass */ - virtual std::string report(bool show_thermo = true) const; + virtual std::string report(bool show_thermo=true, + doublereal threshold=1e-14) const; protected: diff --git a/include/cantera/thermo/ThermoPhase.h b/include/cantera/thermo/ThermoPhase.h index 3f4636b0f..3882f88a1 100644 --- a/include/cantera/thermo/ThermoPhase.h +++ b/include/cantera/thermo/ThermoPhase.h @@ -1535,8 +1535,11 @@ public: /*! * @param show_thermo If true, extra information is printed out * about the thermodynamic state of the system. + * @param threshold Show information about species with mole fractions + * greater than *threshold*. */ - virtual std::string report(bool show_thermo = true) const; + virtual std::string report(bool show_thermo=true, + doublereal threshold=1e-14) const; //! returns a summary of the state of the phase to a comma separated file. //! To customize the data included in the report, derived classes should diff --git a/interfaces/cython/cantera/_cantera.pxd b/interfaces/cython/cantera/_cantera.pxd index d58b6616c..f5d92111d 100644 --- a/interfaces/cython/cantera/_cantera.pxd +++ b/interfaces/cython/cantera/_cantera.pxd @@ -46,7 +46,7 @@ cdef extern from "cantera/thermo/ThermoPhase.h" namespace "Cantera": # miscellaneous int eosType() - string report(cbool) except + + string report(cbool, double) except + string name() void setName(string) string id() diff --git a/interfaces/cython/cantera/mixture.pyx b/interfaces/cython/cantera/mixture.pyx index 7d7c069e0..0dd7c5396 100644 --- a/interfaces/cython/cantera/mixture.pyx +++ b/interfaces/cython/cantera/mixture.pyx @@ -48,7 +48,7 @@ cdef class Mixture: def __dealloc__(self): del self.mix - def report(self): + def report(self, threshold=1e-14): """ Generate a report describing the thermodynamic state of this mixture. To print the report to the screen, simply call the mixture object. The @@ -61,7 +61,7 @@ cdef class Mixture: for i,phase in enumerate(self._phases): s.append('************ Phase {0} ************'.format(phase.name)) s.append('Moles: {0}'.format(self.phase_moles(i))) - s.append(phase.report()) + s.append(phase.report(threshold=threshold)) return '\n'.join(s) diff --git a/interfaces/cython/cantera/test/test_thermo.py b/interfaces/cython/cantera/test/test_thermo.py index 6cc862d9f..7cf3250e4 100644 --- a/interfaces/cython/cantera/test/test_thermo.py +++ b/interfaces/cython/cantera/test/test_thermo.py @@ -114,12 +114,22 @@ class TestThermoPhase(utilities.CanteraTest): with self.assertRaises(ValueError): self.phase['H2','O2'].Y = [0.1, 0.2, 0.3] - def test_report(self): - report = self.phase.report() - self.assertTrue(self.phase.name in report) - self.assertTrue('temperature' in report) + def test_full_report(self): + report = self.phase.report(threshold=0.0) + self.assertIn(self.phase.name, report) + self.assertIn('temperature', report) + self.assertNotIn('minor', report) for name in self.phase.species_names: - self.assertTrue(name in report) + self.assertIn(name, report) + + def test_default_report(self): + self.phase.X = 'H2:0.1, O2:0.9, HO2:1e-10, H2O2:1e-20' + report = self.phase.report() + self.assertIn('minor', report) + for name in (' H2 ', ' O2 ', ' HO2 '): + self.assertIn(name, report) + for name in (' H2O2 ', ' OH ', ' AR '): + self.assertNotIn(name, report) def test_name(self): self.assertEqual(self.phase.name, 'ohmech') diff --git a/interfaces/cython/cantera/thermo.pyx b/interfaces/cython/cantera/thermo.pyx index 4f40a1977..a317a7cfe 100644 --- a/interfaces/cython/cantera/thermo.pyx +++ b/interfaces/cython/cantera/thermo.pyx @@ -27,7 +27,7 @@ cdef class ThermoPhase(_SolutionBase): if 'source' not in kwargs: self.thermo_basis = mass_basis - def report(self, show_thermo=True): + def report(self, show_thermo=True, float threshold=1e-14): """ Generate a report describing the thermodynamic state of this phase. To print the report to the terminal, simply call the phase object. The @@ -36,10 +36,10 @@ cdef class ThermoPhase(_SolutionBase): >>> phase() >>> print(phase.report()) """ - return pystr(self.thermo.report(bool(show_thermo))) + return pystr(self.thermo.report(bool(show_thermo), threshold)) - def __call__(self): - print(self.report()) + def __call__(self, *args, **kwargs): + print(self.report(*args, **kwargs)) property name: """ diff --git a/interfaces/matlab/toolbox/@ThermoPhase/display.m b/interfaces/matlab/toolbox/@ThermoPhase/display.m index c54572ff3..fa0c126c5 100644 --- a/interfaces/matlab/toolbox/@ThermoPhase/display.m +++ b/interfaces/matlab/toolbox/@ThermoPhase/display.m @@ -1,2 +1,5 @@ -function display(self) -phase_get(thermo_hndl(self), 15, 1); +function display(self, threshold) +if nargin < 2 + threshold = 1e-14 +end +phase_get(thermo_hndl(self), 15, 1, threshold); diff --git a/src/clib/ct.cpp b/src/clib/ct.cpp index d999a596d..476ad56c4 100644 --- a/src/clib/ct.cpp +++ b/src/clib/ct.cpp @@ -1336,11 +1336,11 @@ extern "C" { } } - int write_phase(int nth, int show_thermo) + int write_phase(int nth, int show_thermo, double threshold) { try { bool stherm = (show_thermo != 0); - writelog(ThermoCabinet::item(nth).report(stherm)+"\n"); + writelog(ThermoCabinet::item(nth).report(stherm, threshold)+"\n"); return 0; } catch (...) { return handleAllExceptions(-1, ERR); diff --git a/src/clib/ct.h b/src/clib/ct.h index 390bc715e..4da53876c 100644 --- a/src/clib/ct.h +++ b/src/clib/ct.h @@ -38,7 +38,7 @@ extern "C" { CANTERA_CAPI size_t phase_speciesIndex(int n, char* nm); CANTERA_CAPI int phase_report(int nth, int ibuf, char* buf, int show_thermo); - CANTERA_CAPI int write_phase(int nth, int show_thermo); + CANTERA_CAPI int write_phase(int nth, int show_thermo, double threshold); CANTERA_CAPI double phase_nAtoms(int n, size_t k, size_t m); diff --git a/src/matlab/phasemethods.cpp b/src/matlab/phasemethods.cpp index 2a369eff1..a246a71cc 100644 --- a/src/matlab/phasemethods.cpp +++ b/src/matlab/phasemethods.cpp @@ -110,6 +110,7 @@ void phasemethods(int nlhs, mxArray* plhs[], } else if (job < 20) { + double threshold; switch (job) { case 0: @@ -152,7 +153,8 @@ void phasemethods(int nlhs, mxArray* plhs[], break; case 15: show_thermo = getInt(prhs[3]); - vv = write_phase(ph,show_thermo); + threshold = getDouble(prhs[4]); + vv = write_phase(ph,show_thermo,threshold); break; default: mexErrMsgTxt("Unknown job number"); diff --git a/src/thermo/MolalityVPSSTP.cpp b/src/thermo/MolalityVPSSTP.cpp index 581a72185..c7fca1384 100644 --- a/src/thermo/MolalityVPSSTP.cpp +++ b/src/thermo/MolalityVPSSTP.cpp @@ -502,7 +502,7 @@ void MolalityVPSSTP::initThermoXML(XML_Node& phaseNode, const std::string& id_) /** * Format a summary of the mixture state for output. */ -std::string MolalityVPSSTP::report(bool show_thermo) const +std::string MolalityVPSSTP::report(bool show_thermo, doublereal threshold) const { char p[800]; string s = ""; @@ -580,6 +580,8 @@ std::string MolalityVPSSTP::report(bool show_thermo) const sprintf(p, " \n"); s += p; + int nMinor = 0; + doublereal xMinor = 0.0; if (show_thermo) { sprintf(p, " X " " Molalities Chem.Pot. ChemPotSS ActCoeffMolal\n"); @@ -591,14 +593,19 @@ std::string MolalityVPSSTP::report(bool show_thermo) const " ------------ ------------ ------------ ------------\n"); s += p; for (size_t k = 0; k < kk; k++) { - if (x[k] > SmallNumber) { - sprintf(p, "%18s %12.6g %12.6g %12.6g %12.6g %12.6g\n", - speciesName(k).c_str(), x[k], molal[k], mu[k], muss[k], acMolal[k]); + if (x[k] > threshold) { + if (x[k] > SmallNumber) { + sprintf(p, "%18s %12.6g %12.6g %12.6g %12.6g %12.6g\n", + speciesName(k).c_str(), x[k], molal[k], mu[k], muss[k], acMolal[k]); + } else { + sprintf(p, "%18s %12.6g %12.6g N/A %12.6g %12.6g \n", + speciesName(k).c_str(), x[k], molal[k], muss[k], acMolal[k]); + } + s += p; } else { - sprintf(p, "%18s %12.6g %12.6g N/A %12.6g %12.6g \n", - speciesName(k).c_str(), x[k], molal[k], muss[k], acMolal[k]); + nMinor++; + xMinor += x[k]; } - s += p; } } else { sprintf(p, " X" @@ -608,11 +615,20 @@ std::string MolalityVPSSTP::report(bool show_thermo) const " ------------\n"); s += p; for (size_t k = 0; k < kk; k++) { - sprintf(p, "%18s %12.6g %12.6g\n", - speciesName(k).c_str(), x[k], molal[k]); - s += p; + if (x[k] > threshold) { + sprintf(p, "%18s %12.6g %12.6g\n", + speciesName(k).c_str(), x[k], molal[k]); + s += p; + } else { + nMinor++; + xMinor += x[k]; + } } } + if (nMinor) { + sprintf(p, " [%+5i minor] %12.6g\n", nMinor, xMinor); + s += p; + } } catch (CanteraError& err) { err.save(); } diff --git a/src/thermo/MolarityIonicVPSSTP.cpp b/src/thermo/MolarityIonicVPSSTP.cpp index d8d5c9f30..e77cc1615 100644 --- a/src/thermo/MolarityIonicVPSSTP.cpp +++ b/src/thermo/MolarityIonicVPSSTP.cpp @@ -457,7 +457,7 @@ void MolarityIonicVPSSTP::readXMLBinarySpecies(XML_Node& xmLBinarySpecies) std::string xname = xmLBinarySpecies.name(); } -std::string MolarityIonicVPSSTP::report(bool show_thermo) const +std::string MolarityIonicVPSSTP::report(bool show_thermo, doublereal threshold) const { char p[800]; string s = ""; diff --git a/src/thermo/PseudoBinaryVPSSTP.cpp b/src/thermo/PseudoBinaryVPSSTP.cpp index 078834720..b07023206 100644 --- a/src/thermo/PseudoBinaryVPSSTP.cpp +++ b/src/thermo/PseudoBinaryVPSSTP.cpp @@ -175,7 +175,7 @@ void PseudoBinaryVPSSTP::initThermoXML(XML_Node& phaseNode, const std::string& i GibbsExcessVPSSTP::initThermoXML(phaseNode, id_); } -std::string PseudoBinaryVPSSTP::report(bool show_thermo) const +std::string PseudoBinaryVPSSTP::report(bool show_thermo, doublereal threshold) const { char p[800]; string s = ""; diff --git a/src/thermo/PureFluidPhase.cpp b/src/thermo/PureFluidPhase.cpp index 2464d2723..e09090c1f 100644 --- a/src/thermo/PureFluidPhase.cpp +++ b/src/thermo/PureFluidPhase.cpp @@ -362,7 +362,7 @@ void PureFluidPhase::setState_Psat(doublereal p, doublereal x) setDensity(1.0/m_sub->v()); } -std::string PureFluidPhase::report(bool show_thermo) const +std::string PureFluidPhase::report(bool show_thermo, doublereal threshold) const { char p[800]; string s = ""; diff --git a/src/thermo/ThermoPhase.cpp b/src/thermo/ThermoPhase.cpp index edfebc5b4..88bbc97ce 100644 --- a/src/thermo/ThermoPhase.cpp +++ b/src/thermo/ThermoPhase.cpp @@ -845,7 +845,7 @@ void ThermoPhase::getdlnActCoeffdlnN_numderiv(const size_t ld, doublereal* const setState_PX(pres, DATA_PTR(Xmol_Base)); } -std::string ThermoPhase::report(bool show_thermo) const +std::string ThermoPhase::report(bool show_thermo, doublereal threshold) const { char p[800]; string s = ""; @@ -910,6 +910,9 @@ std::string ThermoPhase::report(bool show_thermo) const getChemPotentials(&mu[0]); doublereal rt = GasConstant * temperature(); + int nMinor = 0; + doublereal xMinor = 0.0; + doublereal yMinor = 0.0; if (show_thermo) { sprintf(p, " \n X " " Y Chem. Pot. / RT \n"); @@ -918,14 +921,20 @@ std::string ThermoPhase::report(bool show_thermo) const "------------ ------------\n"); s += p; for (size_t k = 0; k < kk; k++) { - if (x[k] > SmallNumber) { - sprintf(p, "%18s %12.6g %12.6g %12.6g\n", - speciesName(k).c_str(), x[k], y[k], mu[k]/rt); + if (x[k] >= threshold) { + if (x[k] > SmallNumber) { + sprintf(p, "%18s %12.6g %12.6g %12.6g\n", + speciesName(k).c_str(), x[k], y[k], mu[k]/rt); + } else { + sprintf(p, "%18s %12.6g %12.6g \n", + speciesName(k).c_str(), x[k], y[k]); + } + s += p; } else { - sprintf(p, "%18s %12.6g %12.6g \n", - speciesName(k).c_str(), x[k], y[k]); + nMinor++; + xMinor += x[k]; + yMinor += y[k]; } - s += p; } } else { sprintf(p, " \n X " @@ -935,11 +944,22 @@ std::string ThermoPhase::report(bool show_thermo) const " ------------\n"); s += p; for (size_t k = 0; k < kk; k++) { - sprintf(p, "%18s %12.6g %12.6g\n", - speciesName(k).c_str(), x[k], y[k]); - s += p; + if (x[k] >= threshold) { + sprintf(p, "%18s %12.6g %12.6g\n", + speciesName(k).c_str(), x[k], y[k]); + s += p; + } else { + nMinor++; + xMinor += x[k]; + yMinor += y[k]; + } } } + if (nMinor) { + sprintf(p, " [%+5i minor] %12.6g %12.6g\n", + nMinor, xMinor, yMinor); + s += p; + } } catch (CanteraError& err) { err.save(); diff --git a/test_problems/ChemEquil_gri_matrix/gri_matrix.cpp b/test_problems/ChemEquil_gri_matrix/gri_matrix.cpp index 5dcc7852d..9b1ed5e68 100644 --- a/test_problems/ChemEquil_gri_matrix/gri_matrix.cpp +++ b/test_problems/ChemEquil_gri_matrix/gri_matrix.cpp @@ -39,7 +39,7 @@ int main(int argc, char** argv) g.setState_TPX(T, pres, DATA_PTR(Xmol)); try { retnSub = equilibrate(g, "TP", solver); - cout << g; + cout << g.report(true, 0.0); if (retnSub != 1) { cerr << "ERROR: ChemEquil equilibration step failed at " << " T = " << T @@ -52,7 +52,7 @@ int main(int argc, char** argv) exit(-1); } } catch (CanteraError& err) { - cout << g; + cout << g.report(true, 0.0); std::cerr << err.what() << std::endl; cerr << "ERROR: equilibration step failed at " << " T = " << T @@ -75,7 +75,7 @@ int main(int argc, char** argv) g.setState_TPX(T, pres, DATA_PTR(Xmol)); try { retnSub = equilibrate(g, "TP", solver); - cout << g; + cout << g.report(true, 0.0); if (retnSub != 1) { cerr << "ERROR: ChemEquil equilibration step failed at " << " T = " << T @@ -88,7 +88,7 @@ int main(int argc, char** argv) exit(-1); } } catch (CanteraError& err) { - cout << g; + cout << g.report(true, 0.0); std::cerr << err.what() << std::endl; cerr << "ERROR: equilibration step failed at " << " T = " << T @@ -113,7 +113,7 @@ int main(int argc, char** argv) g.setState_TPX(T, pres, DATA_PTR(Xmol)); try { retnSub = equilibrate(g, "TP", solver); - cout << g; + cout << g.report(true, 0.0); if (retnSub != 1) { cerr << "ERROR: ChemEquil equilibration step failed at " << " T = " << T @@ -126,7 +126,7 @@ int main(int argc, char** argv) exit(-1); } } catch (CanteraError& err) { - cout << g; + cout << g.report(true, 0.0); std::cerr << err.what() << std::endl; cerr << "ERROR: equilibration step failed at " << " T = " << T @@ -151,7 +151,7 @@ int main(int argc, char** argv) g.setState_TPX(T, pres, DATA_PTR(Xmol)); try { retnSub = equilibrate(g, "TP", solver); - cout << g; + cout << g.report(true, 0.0); if (retnSub != 1) { cerr << "ERROR: ChemEquil equilibration step failed at " << " T = " << T @@ -164,7 +164,7 @@ int main(int argc, char** argv) exit(-1); } } catch (CanteraError& err) { - cout << g; + cout << g.report(true, 0.0); std::cerr << err.what() << std::endl; cerr << "ERROR: equilibration step failed at " << " T = " << T @@ -219,7 +219,7 @@ int main(int argc, char** argv) << endl; } if (showResults) { - cout << g; + cout << g.report(true, 0.0); } if (retnSub ==1) { numSucc++; diff --git a/test_problems/VCSnonideal/NaCl_equil/good_out.txt b/test_problems/VCSnonideal/NaCl_equil/good_out.txt index 6b3ab6b94..3beec2d53 100644 --- a/test_problems/VCSnonideal/NaCl_equil/good_out.txt +++ b/test_problems/VCSnonideal/NaCl_equil/good_out.txt @@ -359,13 +359,11 @@ Moles: 4.09718 X Y Chem. Pot. / RT ------------- ------------ ------------ - O2 2.18341e-69 2.51533e-69 -182.771 H2 4.57268e-08 3.31864e-09 -32.6178 - CO2 0 0 H2O 0.0237153 0.0153814 -124.003 - NaCl 9.76108e-33 2.05377e-32 -174.517 N2 0.976285 0.984619 -23.0692 OH 9.14536e-08 5.59966e-08 -107.694 + [ +3 minor] 9.76108e-33 2.05377e-32 *************** NaCl(S) ***************** Moles: 4.7877 diff --git a/test_problems/VPsilane_test/silane_equil.cpp b/test_problems/VPsilane_test/silane_equil.cpp index 1de41c7ed..b4cea5d1a 100644 --- a/test_problems/VPsilane_test/silane_equil.cpp +++ b/test_problems/VPsilane_test/silane_equil.cpp @@ -23,9 +23,7 @@ int main(int argc, char** argv) g->setState_TPX(1500.0, 100.0, "SIH4:0.01, H2:0.99"); //g.setState_TPX(1500.0, 1.0132E5, "SIH4:0.01, H2:0.99"); equilibrate(*g, "TP"); - std::string r = g->report(true); - cout << r; - cout << endl; + cout << g->report(true, 0.0) << endl; return 0; } catch (CanteraError& err) { std::cerr << err.what() << std::endl;