From 9ffab53a174ffdee3010255017dc0ecbdc77913a Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Tue, 29 Jan 2019 22:57:54 -0500 Subject: [PATCH] [Fortran] Add functions for constructing objects based on filenames Bypass reading and manipulation of XML files in Fortran, so that XML, CTI, and YAML input files can all be used. --- src/fortran/cantera_funcs.f90 | 15 ++++------ src/fortran/cantera_kinetics.f90 | 43 +++++++++++++++++++++++++++ src/fortran/cantera_thermo.f90 | 19 ++++++++++++ src/fortran/fct.cpp | 50 ++++++++++++++++++++++++++++++++ src/fortran/fct_interface.f90 | 20 +++++++++++++ 5 files changed, 137 insertions(+), 10 deletions(-) diff --git a/src/fortran/cantera_funcs.f90 b/src/fortran/cantera_funcs.f90 index a8bf32132..d1847fa2f 100644 --- a/src/fortran/cantera_funcs.f90 +++ b/src/fortran/cantera_funcs.f90 @@ -18,25 +18,20 @@ module cantera_funcs integer, intent(in), optional :: loglevel character(20) :: model - type(XML_Node) root, s, str type(phase_t) self - root = new_XML_Node(src = src) if (present(id)) then - s = ctxml_child(root, id = id) + self = ctthermo_newFromFile(src, id) else - s = ctxml_child(root, 'phase') + self = ctthermo_newFromFile(src) end if - self = newThermoPhase(s) - call newKinetics(s, self) + call ctkin_newFromFile(self, src, id) - str = ctxml_child(s, 'transport') - call ctxml_getAttrib(str, 'model', model) if (present(loglevel)) then - self%tran_id = newTransport(model, self%thermo_id, loglevel) + self%tran_id = trans_newdefault(self%thermo_id, loglevel) else - self%tran_id = newTransport(model, self%thermo_id, 0) + self%tran_id = trans_newdefault(self%thermo_id, 0) end if ctfunc_importPhase = self diff --git a/src/fortran/cantera_kinetics.f90 b/src/fortran/cantera_kinetics.f90 index 637c7c4cd..cd74d4b1d 100644 --- a/src/fortran/cantera_kinetics.f90 +++ b/src/fortran/cantera_kinetics.f90 @@ -9,6 +9,49 @@ module cantera_kinetics contains + subroutine ctkin_newFromFile(phase, filename, id, neighbor1, neighbor2, & + neighbor3, neighbor4) + implicit none + type(phase_t), intent(inout) :: phase + character*(*), intent(in) :: filename + character*(*), intent(in), optional :: id + type(phase_t), intent(in), optional :: neighbor1 + type(phase_t), intent(in), optional :: neighbor2 + type(phase_t), intent(in), optional :: neighbor3 + type(phase_t), intent(in), optional :: neighbor4 + integer :: n1, n2, n3, n4 + + if (present(neighbor1)) then + n1 = neighbor1%thermo_id + else + n1 = -1 + end if + if (present(neighbor2)) then + n2 = neighbor2%thermo_id + else + n2 = -1 + end if + if (present(neighbor3)) then + n3 = neighbor3%thermo_id + else + n3 = -1 + end if + if (present(neighbor4)) then + n4 = neighbor4%thermo_id + else + n4 = -1 + end if + + if (present(id)) then + phase%kin_id = kin_newfromfile(filename, id, phase%thermo_id, & + n1, n2, n3, n4) + else + phase%kin_id = kin_newfromfile(filename, '', phase%thermo_id, & + n1, n2, n3, n4) + end if + phase%nrxn = kin_nreactions(phase%kin_id) + end subroutine ctkin_newFromFile + subroutine newKinetics(xml_phase, phase, & neighbor1, neighbor2, neighbor3, neighbor4) implicit none diff --git a/src/fortran/cantera_thermo.f90 b/src/fortran/cantera_thermo.f90 index d5bf5cb96..d8659b4ca 100644 --- a/src/fortran/cantera_thermo.f90 +++ b/src/fortran/cantera_thermo.f90 @@ -35,6 +35,25 @@ module cantera_thermo contains + type(phase_t) function ctthermo_newFromFile(filename, id) + implicit none + character*(*), intent(in) :: filename + character*(*), intent(in), optional :: id + type(phase_t) :: self + if (present(id)) then + self%thermo_id = th_newfromfile(filename, id) + else + self%thermo_id = th_newfromfile(filename, '') + end if + self%nel = phase_nelements(self%thermo_id) + self%nsp = phase_nspecies(self%thermo_id) + self%nrxn = 0 + self%err = 0 + self%kin_id = -1 + self%tran_id = -1 + ctthermo_newFromFile = self + end function ctthermo_newFromFile + type(phase_t) function newThermoPhase(xml_phase, index) implicit none type(XML_Node), intent(inout), optional :: xml_phase diff --git a/src/fortran/fct.cpp b/src/fortran/fct.cpp index 1eb8d398f..9d573d53f 100644 --- a/src/fortran/fct.cpp +++ b/src/fortran/fct.cpp @@ -356,6 +356,17 @@ extern "C" { //-------------- Thermo --------------------// + integer th_newfromfile_(char* filename, char* phasename, ftnlen lenf, ftnlen lenp) + { + try { + thermo_t* th = newPhase(f2string(filename, lenf), + f2string(phasename, lenp)); + return ThermoCabinet::add(th); + } catch (...) { + return handleAllExceptions(-1, ERR); + } + } + integer newthermofromxml_(integer* mxml) { try { @@ -626,6 +637,34 @@ extern "C" { //-------------- Kinetics ------------------// + integer kin_newfromfile_(const char* filename, const char* phasename, + integer* reactingPhase, const integer* neighbor1, + const integer* neighbor2, const integer* neighbor3, + const integer* neighbor4, ftnlen nlen, ftnlen plen) + { + try { + std::vector phases; + phases.push_back(_fth(reactingPhase)); + if (*neighbor1 >= 0) { + phases.push_back(_fth(neighbor1)); + if (*neighbor2 >= 0) { + phases.push_back(_fth(neighbor2)); + if (*neighbor3 >= 0) { + phases.push_back(_fth(neighbor3)); + if (*neighbor4 >= 0) { + phases.push_back(_fth(neighbor4)); + } + } + } + } + auto kin = newKinetics(phases, f2string(filename, nlen), + f2string(phasename, plen)); + return KineticsCabinet::add(kin.release()); + } catch (...) { + return handleAllExceptions(999, ERR); + } + } + integer newkineticsfromxml_(integer* mxml, integer* iphase, const integer* neighbor1, const integer* neighbor2, const integer* neighbor3, const integer* neighbor4) @@ -904,6 +943,17 @@ extern "C" { } } + integer trans_newdefault_(integer* ith, integer* loglevel, ftnlen lenmodel) + { + try { + thermo_t* t = _fth(ith); + Transport* tr = newDefaultTransportMgr(t, *loglevel); + return TransportCabinet::add(tr); + } catch (...) { + return handleAllExceptions(-1, ERR); + } + } + doublereal trans_viscosity_(const integer* n) { try { diff --git a/src/fortran/fct_interface.f90 b/src/fortran/fct_interface.f90 index 4a9046f35..1a50917e2 100644 --- a/src/fortran/fct_interface.f90 +++ b/src/fortran/fct_interface.f90 @@ -123,6 +123,11 @@ interface integer, intent(in) :: m end function phase_natoms + integer function th_newfromfile(filename, id) + character*(*), intent(in) :: filename + character*(*), intent(in) :: id + end function th_newfromfile + integer function newthermofromxml(mxml) integer, intent(in) :: mxml end function newthermofromxml @@ -253,6 +258,16 @@ interface double precision, intent(out) :: cp_r(*) end function th_getcp_r + integer function kin_newfromfile(filename, id, reactingPhase, neighbor1, neighbor2, neighbor3, neighbor4) + character*(*), intent(in) :: filename + character*(*), intent(in) :: id + integer, intent(in) :: reactingPhase + integer, intent(in) :: neighbor1 + integer, intent(in) :: neighbor2 + integer, intent(in) :: neighbor3 + integer, intent(in) :: neighbor4 + end function kin_newfromfile + integer function newkineticsfromxml(mxml, iphase, neighbor1, neighbor2, neighbor3, neighbor4) integer, intent(in) :: mxml integer, intent(in) :: iphase @@ -380,6 +395,11 @@ interface integer, intent(in) :: loglevel end function newtransport + integer function trans_newdefault(ith, loglevel) + integer, intent(in) :: ith + integer, intent(in) :: loglevel + end function trans_newdefault + double precision function trans_viscosity(n) integer, intent(in) :: n end function trans_viscosity