diff --git a/samples/cxx/NASA_coeffs/NASA_coeffs.cpp b/samples/cxx/NASA_coeffs/NASA_coeffs.cpp index 8c89ca56e..e05c09452 100644 --- a/samples/cxx/NASA_coeffs/NASA_coeffs.cpp +++ b/samples/cxx/NASA_coeffs/NASA_coeffs.cpp @@ -1,6 +1,6 @@ -#include "cantera/IdealGasMix.h" // defines class IdealGasMix +#include "cantera/thermo/IdealGasPhase.h" // defines class IdealGasPhase -#include +#include using namespace Cantera; @@ -11,15 +11,16 @@ void demoprog() { writelog("\n**** Testing modifying NASA polynomial coefficients ****\n"); - IdealGasMix gas("h2o2.cti","ohmech"); - int nsp = gas.nSpecies(); + auto sol = newSolution("h2o2.yaml", "ohmech"); + auto gas = getIdealGasPhasePtr(sol); + int nsp = gas->nSpecies(); int type; doublereal c[15]; doublereal minTemp, maxTemp, refPressure; // get a reference to the species thermo property manager - MultiSpeciesThermo& sp = gas.speciesThermo(); + MultiSpeciesThermo& sp = gas->speciesThermo(); int n, j; @@ -28,7 +29,7 @@ void demoprog() // location, followed by the 7 low-temperature coefficients, then // the seven high-temperature ones. for (n = 0; n < nsp; n++) { - writelog("\n\n {} (original):", gas.speciesName(n)); + writelog("\n\n {} (original):", gas->speciesName(n)); // get the NASA coefficients in array c sp.reportParams(n, type, c, minTemp, maxTemp, refPressure); @@ -50,7 +51,7 @@ void demoprog() writelog("\n "); // print the modified NASA coefficients - writelog("\n\n {} (modified):", gas.speciesName(n).c_str()); + writelog("\n\n {} (modified):", gas->speciesName(n).c_str()); writelog("\n "); for (j = 1; j < 8; j++) { writelog(" A{} ", j); @@ -78,4 +79,3 @@ int main() std::cout << err.what() << std::endl; } } - diff --git a/samples/cxx/combustor/combustor.cpp b/samples/cxx/combustor/combustor.cpp index 11d31f6e5..e07757750 100644 --- a/samples/cxx/combustor/combustor.cpp +++ b/samples/cxx/combustor/combustor.cpp @@ -8,7 +8,7 @@ // turned off, the system approaches the steady burning solution.""" #include "cantera/zerodim.h" -#include "cantera/IdealGasMix.h" +#include "cantera/thermo/IdealGasPhase.h" #include @@ -17,40 +17,42 @@ using namespace Cantera; void runexample() { // use reaction mechanism GRI-Mech 3.0 - IdealGasMix gas("gri30.cti", "gri30"); + auto sol = newSolution("gri30.yaml", "gri30", "None"); + auto gas = getIdealGasPhasePtr(sol); // create a reservoir for the fuel inlet, and set to pure methane. Reservoir fuel_in; - gas.setState_TPX(300.0, OneAtm, "CH4:1.0"); - fuel_in.insert(gas); - double fuel_mw = gas.meanMolecularWeight(); + gas->setState_TPX(300.0, OneAtm, "CH4:1.0"); + fuel_in.insert(sol); + double fuel_mw = gas->meanMolecularWeight(); + + auto air = newSolution("air.cti"); + double air_mw = air->thermo().meanMolecularWeight(); // create a reservoir for the air inlet Reservoir air_in; - IdealGasMix air("air.cti"); - gas.setState_TPX(300.0, OneAtm, "N2:0.78, O2:0.21, AR:0.01"); - double air_mw = air.meanMolecularWeight(); - air_in.insert(gas); + gas->setState_TPX(300.0, OneAtm, "N2:0.78, O2:0.21, AR:0.01"); + air_in.insert(sol); // to ignite the fuel/air mixture, we'll introduce a pulse of radicals. // The steady-state behavior is independent of how we do this, so we'll // just use a stream of pure atomic hydrogen. - gas.setState_TPX(300.0, OneAtm, "H:1.0"); + gas->setState_TPX(300.0, OneAtm, "H:1.0"); Reservoir igniter; - igniter.insert(gas); + igniter.insert(sol); // create the combustor, and fill it in initially with N2 - gas.setState_TPX(300.0, OneAtm, "N2:1.0"); + gas->setState_TPX(300.0, OneAtm, "N2:1.0"); Reactor combustor; - combustor.insert(gas); + combustor.insert(sol); combustor.setInitialVolume(1.0); // create a reservoir for the exhaust. The initial composition // doesn't matter. Reservoir exhaust; - exhaust.insert(gas); + exhaust.insert(sol); // lean combustion, phi = 0.5 @@ -106,14 +108,14 @@ void runexample() std::ofstream f("combustor_cxx.csv"); std::vector k_out { - gas.speciesIndex("CH4"), - gas.speciesIndex("O2"), - gas.speciesIndex("CO2"), - gas.speciesIndex("H2O"), - gas.speciesIndex("CO"), - gas.speciesIndex("OH"), - gas.speciesIndex("H"), - gas.speciesIndex("C2H6") + gas->speciesIndex("CH4"), + gas->speciesIndex("O2"), + gas->speciesIndex("CO2"), + gas->speciesIndex("H2O"), + gas->speciesIndex("CO"), + gas->speciesIndex("OH"), + gas->speciesIndex("H"), + gas->speciesIndex("C2H6") }; while (tnow < tfinal) { diff --git a/samples/cxx/demo.cpp b/samples/cxx/demo.cpp index f11992fb7..7c66d225c 100644 --- a/samples/cxx/demo.cpp +++ b/samples/cxx/demo.cpp @@ -11,7 +11,8 @@ // provide a simplified interface to the Cantera header files. If you need // to include core headers directly, use the format "cantera/module/*.h". -#include "cantera/IdealGasMix.h" // defines class IdealGasMix +#include "cantera/thermo/IdealGasPhase.h" // defines class IdealGasPhase +#include "cantera/kinetics/GasKinetics.h" #include "cantera/transport.h" // transport properties #include @@ -27,10 +28,11 @@ void demoprog() { writelog("\n**** C++ Test Program ****\n"); - IdealGasMix gas("h2o2.cti","ohmech"); + auto sol = newSolution("h2o2.yaml", "ohmech"); + auto gas = getIdealGasPhasePtr(sol); double temp = 1200.0; double pres = OneAtm; - gas.setState_TPX(temp, pres, "H2:1, O2:1, AR:2"); + gas->setState_TPX(temp, pres, "H2:1, O2:1, AR:2"); // Thermodynamic properties @@ -43,12 +45,12 @@ void demoprog() "Molar Enthalpy: {:14.5g} J/kmol\n" "Molar Entropy: {:14.5g} J/kmol-K\n" "Molar cp: {:14.5g} J/kmol-K\n", - gas.temperature(), gas.pressure(), gas.density(), - gas.enthalpy_mole(), gas.entropy_mole(), gas.cp_mole()); + gas->temperature(), gas->pressure(), gas->density(), + gas->enthalpy_mole(), gas->entropy_mole(), gas->cp_mole()); // set the gas to the equilibrium state with the same specific // enthalpy and pressure - gas.equilibrate("HP"); + gas->equilibrate("HP"); writelog("\n\nEquilibrium state:\n\n"); writelog( @@ -58,13 +60,14 @@ void demoprog() "Molar Enthalpy: {:14.5g} J/kmol\n" "Molar Entropy: {:14.5g} J/kmol-K\n" "Molar cp: {:14.5g} J/kmol-K\n", - gas.temperature(), gas.pressure(), gas.density(), - gas.enthalpy_mole(), gas.entropy_mole(), gas.cp_mole()); + gas->temperature(), gas->pressure(), gas->density(), + gas->enthalpy_mole(), gas->entropy_mole(), gas->cp_mole()); // Reaction information - int irxns = gas.nReactions(); + auto kin = getGasKineticsPtr(sol); + int irxns = kin->nReactions(); vector_fp qf(irxns); vector_fp qr(irxns); vector_fp q(irxns); @@ -72,14 +75,14 @@ void demoprog() // since the gas has been set to an equilibrium state, the forward // and reverse rates of progress should be equal for all // reversible reactions, and the net rates should be zero. - gas.getFwdRatesOfProgress(&qf[0]); - gas.getRevRatesOfProgress(&qr[0]); - gas.getNetRatesOfProgress(&q[0]); + kin->getFwdRatesOfProgress(&qf[0]); + kin->getRevRatesOfProgress(&qr[0]); + kin->getNetRatesOfProgress(&q[0]); writelog("\n\n"); for (int i = 0; i < irxns; i++) { writelog("{:30s} {:14.5g} {:14.5g} {:14.5g} kmol/m3/s\n", - gas.reactionString(i), qf[i], qr[i], q[i]); + kin->reactionString(i), qf[i], qr[i], q[i]); } @@ -94,13 +97,13 @@ void demoprog() writelog("\n\nViscosity: {:14.5g} Pa-s\n", tr->viscosity()); writelog("Thermal conductivity: {:14.5g} W/m/K\n", tr->thermalConductivity()); - int nsp = gas.nSpecies(); + int nsp = gas->nSpecies(); vector_fp diff(nsp); tr->getMixDiffCoeffs(&diff[0]); int k; writelog("\n\n{:20s} {:26s}\n", "Species", "Diffusion Coefficient"); for (k = 0; k < nsp; k++) { - writelog("{:20s} {:14.5g} m2/s \n", gas.speciesName(k), diff[k]); + writelog("{:20s} {:14.5g} m2/s \n", gas->speciesName(k), diff[k]); } } diff --git a/samples/cxx/flamespeed/flamespeed.cpp b/samples/cxx/flamespeed/flamespeed.cpp index 96ba18e8d..ce4d6f9af 100644 --- a/samples/cxx/flamespeed/flamespeed.cpp +++ b/samples/cxx/flamespeed/flamespeed.cpp @@ -6,7 +6,7 @@ #include "cantera/oneD/Sim1D.h" #include "cantera/oneD/Inlet1D.h" #include "cantera/oneD/StFlow.h" -#include "cantera/IdealGasMix.h" +#include "cantera/thermo/IdealGasPhase.h" #include "cantera/transport.h" #include @@ -16,34 +16,35 @@ using fmt::print; int flamespeed(double phi) { try { - IdealGasMix gas("gri30.cti","gri30_mix"); + auto sol = newSolution("gri30.yaml", "gri30", "None"); + auto gas = getIdealGasPhasePtr(sol); doublereal temp = 300.0; // K doublereal pressure = 1.0*OneAtm; //atm doublereal uin = 0.3; //m/sec - size_t nsp = gas.nSpecies(); + size_t nsp = gas->nSpecies(); vector_fp x(nsp, 0.0); doublereal C_atoms = 1.0; doublereal H_atoms = 4.0; doublereal ax = C_atoms + H_atoms / 4.0; doublereal fa_stoic = 1.0 / (4.76 * ax); - x[gas.speciesIndex("CH4")] = 1.0; - x[gas.speciesIndex("O2")] = 0.21 / phi / fa_stoic; - x[gas.speciesIndex("N2")] = 0.79 / phi/ fa_stoic; + x[gas->speciesIndex("CH4")] = 1.0; + x[gas->speciesIndex("O2")] = 0.21 / phi / fa_stoic; + x[gas->speciesIndex("N2")] = 0.79 / phi/ fa_stoic; - gas.setState_TPX(temp, pressure, x.data()); - doublereal rho_in = gas.density(); + gas->setState_TPX(temp, pressure, x.data()); + doublereal rho_in = gas->density(); vector_fp yin(nsp); - gas.getMassFractions(&yin[0]); + gas->getMassFractions(&yin[0]); - gas.equilibrate("HP"); + gas->equilibrate("HP"); vector_fp yout(nsp); - gas.getMassFractions(&yout[0]); - doublereal rho_out = gas.density(); - doublereal Tad = gas.temperature(); + gas->getMassFractions(&yout[0]); + doublereal rho_out = gas->density(); + doublereal Tad = gas->temperature(); print("phi = {}, Tad = {}\n", phi, Tad); //============= build each domain ======================== @@ -51,7 +52,7 @@ int flamespeed(double phi) //-------- step 1: create the flow ------------- - StFlow flow(&gas); + StFlow flow(gas.get()); flow.setFreeFlow(); // create an initial grid @@ -68,11 +69,11 @@ int flamespeed(double phi) // specify the objects to use to compute kinetic rates and // transport properties - std::unique_ptr trmix(newTransportMgr("Mix", &gas)); - std::unique_ptr trmulti(newTransportMgr("Multi", &gas)); + std::unique_ptr trmix(newTransportMgr("Mix", sol->thermoPtr().get())); + std::unique_ptr trmulti(newTransportMgr("Multi", sol->thermoPtr().get())); flow.setTransport(*trmix); - flow.setKinetics(gas); + flow.setKinetics(sol->kinetics()); flow.setPressure(pressure); //------- step 2: create the inlet ----------------------- @@ -107,7 +108,7 @@ int flamespeed(double phi) for (size_t i=0; ispeciesName(i),locs,value); } inlet.setMoleFractions(x.data()); diff --git a/samples/cxx/kinetics1/kinetics1.cpp b/samples/cxx/kinetics1/kinetics1.cpp index 36225217b..1b732c4ed 100644 --- a/samples/cxx/kinetics1/kinetics1.cpp +++ b/samples/cxx/kinetics1/kinetics1.cpp @@ -8,7 +8,7 @@ // at https://cantera.org/license.txt for license and copyright information. #include "cantera/zerodim.h" -#include "cantera/IdealGasMix.h" +#include "cantera/thermo/IdealGasPhase.h" #include "example_utils.h" using namespace Cantera; @@ -22,11 +22,12 @@ int kinetics1(int np, void* p) " mixture \nbeginning at T = 1001 K and P = 1 atm." << endl; // create an ideal gas mixture that corresponds to GRI-Mech 3.0 - IdealGasMix gas("gri30.cti", "gri30"); + auto sol = newSolution("gri30.yaml", "gri30", "None"); + auto gas = getIdealGasPhasePtr(sol); // set the state - gas.setState_TPX(1001.0, OneAtm, "H2:2.0, O2:1.0, N2:4.0"); - int nsp = gas.nSpecies(); + gas->setState_TPX(1001.0, OneAtm, "H2:2.0, O2:1.0, N2:4.0"); + int nsp = gas->nSpecies(); // create a reactor IdealGasConstPressureReactor r; @@ -36,7 +37,7 @@ int kinetics1(int np, void* p) // reactors or reservoirs. All this means is that this object // will be used to evaluate thermodynamic or kinetic // quantities needed. - r.insert(gas); + r.insert(sol); double dt = 1.e-5; // interval at which output is written int nsteps = 100; // number of intervals @@ -44,7 +45,7 @@ int kinetics1(int np, void* p) // create a 2D array to hold the output variables, // and store the values for the initial state Array2D soln(nsp+4, 1); - saveSoln(0, 0.0, gas, soln); + saveSoln(0, 0.0, sol->thermo(), soln); // create a container object to run the simulation // and add the reactor to it @@ -57,15 +58,15 @@ int kinetics1(int np, void* p) double tm = i*dt; sim.advance(tm); cout << "time = " << tm << " s" << endl; - saveSoln(tm, gas, soln); + saveSoln(tm, sol->thermo(), soln); } clock_t t1 = clock(); // save end time // make a Tecplot data file and an Excel spreadsheet std::string plotTitle = "kinetics example 1: constant-pressure ignition"; - plotSoln("kin1.dat", "TEC", plotTitle, gas, soln); - plotSoln("kin1.csv", "XL", plotTitle, gas, soln); + plotSoln("kin1.dat", "TEC", plotTitle, sol->thermo(), soln); + plotSoln("kin1.csv", "XL", plotTitle, sol->thermo(), soln); // print final temperature and timing data diff --git a/samples/cxx/openmp_ignition/openmp_ignition.cpp b/samples/cxx/openmp_ignition/openmp_ignition.cpp index d91318b99..d68b22560 100644 --- a/samples/cxx/openmp_ignition/openmp_ignition.cpp +++ b/samples/cxx/openmp_ignition/openmp_ignition.cpp @@ -3,7 +3,7 @@ // Cantera objects for each thread. #include "cantera/zerodim.h" -#include "cantera/IdealGasMix.h" +#include "cantera/thermo/IdealGasPhase.h" #include @@ -19,17 +19,18 @@ void run() // Containers for Cantera objects to be used in different. Each thread needs // to have its own set of linked Cantera objects. Multiple threads accessing // the same objects at the same time will cause errors. - std::vector> gases; + std::vector> sols; std::vector> reactors; std::vector> nets; // Create and link the Cantera objects for each thread. This step should be // done in serial for (int i = 0; i < nThreads; i++) { - gases.emplace_back(new IdealGasMix("gri30.xml", "gri30")); + auto sol = newSolution("gri30.yaml", "gri30", "None"); + sols.emplace_back(sol); reactors.emplace_back(new IdealGasConstPressureReactor()); nets.emplace_back(new ReactorNet()); - reactors.back()->insert(*gases.back()); + reactors.back()->insert(sol); nets.back()->addReactor(*reactors.back()); } @@ -54,12 +55,12 @@ void run() for (int i = 0; i < nPoints; i++) { // Get the Cantera objects that were initialized for this thread size_t j = omp_get_thread_num(); - IdealGasMix& gas = *gases[j]; + auto gas = getIdealGasPhasePtr(sols[j]); Reactor& reactor = *reactors[j]; ReactorNet& net = *nets[j]; // Set up the problem - gas.setState_TPX(T0[i], OneAtm, "CH4:0.5, O2:1.0, N2:3.76"); + gas->setState_TPX(T0[i], OneAtm, "CH4:0.5, O2:1.0, N2:3.76"); reactor.syncState(); net.setInitialTime(0.0); diff --git a/samples/f77/demo_ftnlib.cpp b/samples/f77/demo_ftnlib.cpp index a9c8ccedd..d0467df85 100644 --- a/samples/f77/demo_ftnlib.cpp +++ b/samples/f77/demo_ftnlib.cpp @@ -1,6 +1,7 @@ /*! A simple Fortran 77 interface + This file is an example of how to write an interface to use Cantera in Fortran 77 programs. The basic idea is to store pointers to Cantera objects in global storage, and then create Fortran-callable @@ -8,7 +9,7 @@ This particular example defines functions that return thermodynamic properties, transport properties, and kinetic rates for reacting - ideal gas mixtures. Only a single pointer to an IdealGasMix object is + ideal gas mixtures. Only a single pointer to an IdealGasPhase object is stored, so only one reaction mechanism may be used at any one time in the application. Of course, it is a simple modification to store multiple objects if it is desired to use multiple reaction @@ -26,25 +27,36 @@ */ // add any other Cantera header files you need here -#include "cantera/IdealGasMix.h" +#include "cantera/thermo/IdealGasPhase.h" +#include "cantera/kinetics/GasKinetics.h" +#include "cantera/transport.h" + +#include using namespace Cantera; using std::string; -// store a pointer to an IdealGasMix object -static IdealGasMix* _gas = 0; - +// store a pointer to a Solution object // provides access to the pointers for functions in other libraries -IdealGasMix* _gasptr() +static shared_ptr _sol = NULL; + +// store a pointer to the thermophase object +static shared_ptr _gas = NULL; +shared_ptr _gasptr() { return _gas; } -#include "cantera/transport.h" +// store a pointer to the kinetics object +static shared_ptr _kin = NULL; +shared_ptr _kinptr() +{ + return _kin; +} // store a pointer to a transport manager -static Transport* _trans = 0; -Transport* _transptr() +static shared_ptr _trans = NULL; +shared_ptr _transptr() { return _trans; } @@ -68,10 +80,10 @@ extern "C" { #endif /** - * Read in a reaction mechanism file and create an IdealGasMix - * object. The file may be in Cantera input format or in CTML. (If + * Read in a reaction mechanism file and create a Solution + * object. The file may be in Cantera input format or in YAML. (If * you have a file in Chemkin-compatible format, use utility - * program ck2cti first to convert it into Cantera format.) + * program ck2yaml first to convert it into Cantera format.) */ void newidealgasmix_(char* file, char* id, char* transport, ftnlen lenfile, ftnlen lenid, ftnlen lentr) @@ -81,17 +93,13 @@ extern "C" { string fin = string(file, lenfile); string fth = string(id, lenid); trmodel = string(transport, lentr); - delete _gas; - _gas = new IdealGasMix(fin, fth); + _sol = newSolution(fin, fth, trmodel); + _gas = getIdealGasPhasePtr(_sol); + _kin = getGasKineticsPtr(_sol); + _trans = _sol->transportPtr(); } catch (CanteraError& err) { handleError(err); } - try { - delete _trans; - _trans = newTransportMgr(trmodel,_gas,0); - } catch (CanteraError& err) { - _trans = newTransportMgr("",_gas,0); - } } /// integer function nElements() @@ -109,7 +117,7 @@ extern "C" { /// integer function nReactions() integer nreactions_() { - return _gas->nReactions(); + return _kin->nReactions(); } void getspeciesname_(integer* k, char* name, ftnlen n) @@ -288,7 +296,7 @@ extern "C" { { int irxn = *i - 1; std::fill(eqn, eqn + n, ' '); - string e = _gas->reactionString(irxn); + string e = _kin->reactionString(irxn); int ns = e.size(); unsigned int nmx = (ns > n ? n : ns); copy(e.begin(), e.begin()+nmx, eqn); @@ -296,32 +304,32 @@ extern "C" { void getnetproductionrates_(doublereal* wdot) { - _gas->getNetProductionRates(wdot); + _kin->getNetProductionRates(wdot); } void getcreationrates_(doublereal* cdot) { - _gas->getCreationRates(cdot); + _kin->getCreationRates(cdot); } void getdestructionrates_(doublereal* ddot) { - _gas->getDestructionRates(ddot); + _kin->getDestructionRates(ddot); } void getnetratesofprogress_(doublereal* q) { - _gas->getNetRatesOfProgress(q); + _kin->getNetRatesOfProgress(q); } void getfwdratesofprogress_(doublereal* q) { - _gas->getFwdRatesOfProgress(q); + _kin->getFwdRatesOfProgress(q); } void getrevratesofprogress_(doublereal* q) { - _gas->getRevRatesOfProgress(q); + _kin->getRevRatesOfProgress(q); } //-------------------- transport properties --------------------