[clib] Add functions for creating objects directly from input files

These methods work with YAML, CTI, and XML input files.
This commit is contained in:
Ray Speth 2019-01-29 14:18:08 -05:00
parent fd088889cd
commit 6a8c378846
5 changed files with 105 additions and 9 deletions

View file

@ -16,6 +16,7 @@ extern "C" {
CANTERA_CAPI int ct_appdelete();
CANTERA_CAPI int thermo_newFromFile(const char* filename, const char* phasename);
CANTERA_CAPI int thermo_newFromXML(int mxml);
CANTERA_CAPI int thermo_del(int n);
CANTERA_CAPI size_t thermo_nElements(int n);
@ -101,6 +102,9 @@ extern "C" {
CANTERA_CAPI int thermo_setState_Psat(int n, double p, double x);
CANTERA_CAPI int thermo_setState_Tsat(int n, double t, double x);
CANTERA_CAPI int kin_newFromFile(const char* filename, const char* phasename,
int reactingPhase, int neighbor1, int neighbor2,
int neighbor3, int neighbor4);
CANTERA_CAPI int kin_newFromXML(int mxml, int iphase,
int neighbor1, int neighbor2, int neighbor3,
int neighbor4);
@ -136,6 +140,7 @@ extern "C" {
CANTERA_CAPI int kin_advanceCoverages(int n, double tstep);
CANTERA_CAPI size_t kin_phase(int n, size_t i);
CANTERA_CAPI int trans_newDefault(int th, int loglevel);
CANTERA_CAPI int trans_new(const char* model, int th, int loglevel);
CANTERA_CAPI int trans_del(int n);
CANTERA_CAPI double trans_viscosity(int n);

View file

@ -107,6 +107,21 @@ unique_ptr<Kinetics> newKinetics(std::vector<ThermoPhase*>& phases,
const AnyMap& phaseNode,
const AnyMap& rootNode=AnyMap());
/*!
* Create a new kinetics manager, initialize it, and add reactions
*
* @param phases Vector of phases containing species which participate in
* reactions, with the phase where the reactions occur (lowest-dimensional
* phase) listed first.
* @param filename File containing the phase definition for the phase where
* the reactions occur. Searches the Cantera data for this file.
* @param phase_name The name of the reacting phase in the input file (i.e. the
* name of the first phase in the `phases` vector)
*/
unique_ptr<Kinetics> newKinetics(std::vector<ThermoPhase*>& phases,
const std::string& filename,
const std::string& phase_name);
/*!
* Add reactions to a Kinetics object
*

View file

@ -343,6 +343,14 @@ extern "C" {
//-------------- Thermo --------------------//
int thermo_newFromFile(const char* filename, const char* phasename) {
try {
return ThermoCabinet::add(newPhase(filename, phasename));
} catch (...) {
return handleAllExceptions(-1, ERR);
}
}
int thermo_newFromXML(int mxml)
{
try {
@ -856,6 +864,32 @@ extern "C" {
//-------------- Kinetics ------------------//
int kin_newFromFile(const char* filename, const char* phasename,
int reactingPhase, int neighbor1, int neighbor2,
int neighbor3, int neighbor4)
{
try {
vector<thermo_t*> phases;
phases.push_back(&ThermoCabinet::item(reactingPhase));
if (neighbor1 >= 0) {
phases.push_back(&ThermoCabinet::item(neighbor1));
if (neighbor2 >= 0) {
phases.push_back(&ThermoCabinet::item(neighbor2));
if (neighbor3 >= 0) {
phases.push_back(&ThermoCabinet::item(neighbor3));
if (neighbor4 >= 0) {
phases.push_back(&ThermoCabinet::item(neighbor4));
}
}
}
}
unique_ptr<Kinetics> kin = newKinetics(phases, filename, phasename);
return KineticsCabinet::add(kin.release());
} catch (...) {
return handleAllExceptions(-1, ERR);
}
}
int kin_newFromXML(int mxml, int iphase,
int neighbor1, int neighbor2, int neighbor3,
int neighbor4)
@ -1230,6 +1264,17 @@ extern "C" {
//------------------- Transport ---------------------------
int trans_newDefault(int ith, int loglevel)
{
try {
Transport* tr = newDefaultTransportMgr(&ThermoCabinet::item(ith),
loglevel);
return TransportCabinet::add(tr);
} catch (...) {
return handleAllExceptions(-1, ERR);
}
}
int trans_new(const char* model, int ith, int loglevel)
{
try {

View file

@ -67,6 +67,43 @@ unique_ptr<Kinetics> newKinetics(vector<ThermoPhase*>& phases,
return kin;
}
unique_ptr<Kinetics> newKinetics(std::vector<ThermoPhase*>& phases,
const std::string& filename,
const std::string& phase_name)
{
size_t dot = filename.find_last_of(".");
string extension;
if (dot != npos) {
extension = toLowerCopy(filename.substr(dot+1));
}
if (extension == "yml" || extension == "yaml") {
AnyMap root = AnyMap::fromYamlFile(filename);
if (phase_name != "") {
auto phaseNodes = root["phases"].asMap("name");
if (phaseNodes.find(phase_name) == phaseNodes.end()) {
throw CanteraError("newKinetics",
"Couldn't find phase named '{}' in file '{}'.",
phase_name, filename);
}
return newKinetics(phases, *phaseNodes[phase_name], root);
} else {
// Use the first phase definition
auto& phaseNode = root["phases"].asVector<AnyMap>().at(0);
return newKinetics(phases, phaseNode, root);
}
} else {
XML_Node* root = get_XML_File(filename);
XML_Node* xphase = get_XML_NameID("phase", "#"+phase_name, root);
if (!xphase) {
throw CanteraError("newKinetics",
"Couldn't find phase named '{}' in file '{}'.",
phase_name, filename);
}
return unique_ptr<Kinetics>(newKineticsMgr(*xphase, phases));
}
}
void addReactions(Kinetics& kin, const AnyMap& phaseNode, const AnyMap& rootNode)
{
// Find sections containing reactions to add

View file

@ -15,13 +15,7 @@
int main(int argc, char** argv)
{
int ret;
int xml_file = xml_get_XML_File("gri30.xml", 0);
assert(xml_file > 0);
int phase_node = xml_findID(xml_file, "gri30_mix");
assert(phase_node > 0);
int thermo = thermo_newFromXML(phase_node);
int thermo = thermo_newFromFile("gri30.xml", "gri30_mix");
assert(thermo > 0);
size_t nsp = thermo_nSpecies(thermo);
assert(nsp == 53);
@ -41,7 +35,7 @@ int main(int argc, char** argv)
ret = thermo_print(thermo, 1, 0);
assert(ret == 0);
int kin = kin_newFromXML(phase_node, thermo, 0, 0, 0, 0);
int kin = kin_newFromFile("gri30.xml", "gri30_mix", thermo, 0, 0, 0, 0);
assert(kin > 0);
size_t nr = kin_nReactions(kin);
@ -61,7 +55,7 @@ int main(int argc, char** argv)
}
printf("\n Species Mix diff coeff\n");
int tran = trans_new("Mix", thermo, 0);
int tran = trans_newDefault(thermo, 0);
double dkm[53];
trans_getMixDiffCoeffs(tran, 53, dkm);
int k; // declare this here for C89 compatibility