[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.
This commit is contained in:
Ray Speth 2019-01-29 22:57:54 -05:00
parent 901ec2f12c
commit 9ffab53a17
5 changed files with 137 additions and 10 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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<thermo_t*> 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 {

View file

@ -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