[Matlab] Construct objects directly from input file names

Bypass reading and manipulation of XML files within Matlab, so that XML, CTI,
and YAML input files can all be used.
This commit is contained in:
Ray Speth 2019-01-29 16:17:34 -05:00
parent 6a8c378846
commit 901ec2f12c
9 changed files with 103 additions and 78 deletions

View file

@ -21,19 +21,17 @@ function s = Interface(src, id, p1, p2, p3, p4)
% Instance of class :mat:func:`Interface`
%
doc = XML_Node('doc', src);
node = findByID(doc, id);
t = ThermoPhase(node);
t = ThermoPhase(src, id);
if nargin == 2
k = Kinetics(node, t);
k = Kinetics(t, src, id);
elseif nargin == 3
k = Kinetics(node, t, p1);
k = Kinetics(t, src, id, p1);
elseif nargin == 4
k = Kinetics(node, t, p1, p2);
k = Kinetics(t, src, id, p1, p2);
elseif nargin == 5
k = Kinetics(node, t, p1, p2, p3);
k = Kinetics(t, src, id, p1, p2, p3);
elseif nargin == 6
k = Kinetics(node, t, p1, p2, p3, p4);
k = Kinetics(t, src, id, p1, p2, p3, p4);
end
s.kin = k;

View file

@ -1,4 +1,4 @@
function k = Kinetics(r, ph, neighbor1, neighbor2, neighbor3, neighbor4)
function k = Kinetics(ph, src, id, neighbor1, neighbor2, neighbor3, neighbor4)
% KINETICS Kinetics class constructor.
% k = Kinetics(r, ph, neighbor1, neighbor2, neighbor3, neighbor4)
% Class Kinetics represents kinetics managers, which are classes
@ -8,10 +8,13 @@ function k = Kinetics(r, ph, neighbor1, neighbor2, neighbor3, neighbor4)
% of progress, species production rates, and other quantities pertaining to
% a reaction mechanism.
%
% :param r:
% An instance of class :mat:func:`XML_Node`.
% :param ph:
% An instance of class :mat:func:`ThermoPhase`.
% An instance of class :mat:func:`ThermoPhase` representing the phase
% in which reactions occur
% :param src:
% Input string of YAML, CTI, or XML file name.
% :param id:
% ID of the phase to import as specified in the input file. (optional)
% :param neighbor1:
% Instance of class :mat:func:`ThermoPhase` or :mat:func:`Solution` representing a
% neighboring phase.
@ -34,32 +37,28 @@ ineighbor1 = -1;
ineighbor2 = -1;
ineighbor3 = -1;
ineighbor4 = -1;
% First argument must be an XML_Node instance representing the XML tree
if ~isa(r, 'XML_Node')
error('first argument must be an XML_Node object')
if nargin == 2
id = '-';
end
k.owner = 1;
ixml = xml_hndl(r);
% get the integer indices used to find the stored objects
% representing the phases participating in the mechanism.
iphase = thermo_hndl(ph);
if nargin > 2
if nargin > 3
ineighbor1 = thermo_hndl(neighbor1);
if nargin > 3
if nargin > 4
ineighbor2 = thermo_hndl(neighbor2);
if nargin > 4
if nargin > 5
ineighbor3 = thermo_hndl(neighbor3);
if nargin > 5
if nargin > 6
ineighbor4 = thermo_hndl(neighbor4);
end
end
end
end
k.id = kinetics_get(ixml, 0, iphase, ineighbor1, ineighbor2, ineighbor3, ...
ineighbor4);
k.id = kinetics_get(0, 0, src, id, iphase, ineighbor1, ineighbor2, ...
ineighbor3, ineighbor4);
if k.id < 0
error(geterr);
end

View file

@ -1,4 +1,4 @@
function v = kinetics_get(n, job, a, b, c, d, e, f)
function v = kinetics_get(n, job, a, b, c, d, e, f, g)
% KINETICS_GET - get kinetics attributes
%
if nargin == 2
@ -15,4 +15,6 @@ elseif nargin == 7
v = ctmethods(40, n, job, a, b, c, d, e);
elseif nargin == 8
v = ctmethods(40, n, job, a, b, c, d, e, f);
elseif nargin == 9
v = ctmethods(40, n, job, a, b, c, d, e, f, g);
end

View file

@ -44,24 +44,21 @@ function s = Solution(src, id, trans)
% :return:
% Instance of class :mat:func:`Solution`
%
doc = XML_Node('doc', src);
if nargin == 1
node = findByName(doc, 'phase');
else
node = findByID(doc, id);
id = '-';
end
t = ThermoPhase(node);
k = Kinetics(node, t);
t = ThermoPhase(src, id);
k = Kinetics(t, src, id);
s.kin = k;
s.th = t;
if nargin == 3
if strcmp(trans, 'default') || strcmp(trans, 'Mix') || strcmp(trans, 'Multi')
tr = Transport(node, t, trans, 0);
tr = Transport(t, trans, 0);
else
error('Unknown transport modeling specified.')
end
else
tr = Transport(node, t, 'default', 0);
tr = Transport(t, 'default', 0);
end
s.tr = tr;
s = class(s, 'Solution', t, k, tr);

View file

@ -1,19 +1,24 @@
function t = ThermoPhase(r)
function t = ThermoPhase(src, id)
% THERMOPHASE ThermoPhase class constructor.
% t = ThermoPhase(r)
% :param r:
% An instance of class :mat:func:`XML_Node`.
% t = ThermoPhase(src, id)
% :param src:
% Input string of YAML, CTI, or XML file name.
% :param id:
% ID of the phase to import as specified in the input file. (optional)
% :return:
% Instance of class :mat:func:`ThermoPhase`
%
if nargin ~= 1
error('ThermoPhase expects 1 input argument.');
if nargin > 2
error('ThermoPhase expects 1 or 2 input arguments.');
end
if nargin == 1
id = '-';
end
t.owner = 1;
hr = xml_hndl(r);
t.tp_id = thermo_get(hr, 0);
t.tp_id = thermo_get(0, 0, src, id);
if t.tp_id < 0
error(geterr);
end

View file

@ -1,22 +1,18 @@
function tr = Transport(r, th, model, loglevel)
function tr = Transport(th, model, loglevel)
% TRANSPORT Transport class constructor.
% tr = Transport(r, th, model, loglevel)
% Create a new instance of class :mat:func:`Transport`. Three or four arguments
% may be supplied. The first two must be an instance of class:mat:func:`XML_Node`
% and an instance of class :mat:func:`ThermoPhase` respectively.
% The third argument is the type of modeling desired, specified
% by the string ``'default'``, ``'Mix'`` or ``'Multi'``.
% ``'default'`` uses the default transport specified in the
% :mat:func:`XML_Node`. The fourth argument is
% the logging level desired.
% Create a new instance of class :mat:func:`Transport`. One to three arguments
% may be supplied. The first must be an instance of class
% :mat:func:`ThermoPhase`. The second (optional) argument is the type of
% model desired, specified by the string ``'default'``, ``'Mix'`` or
% ``'Multi'``. ``'default'`` uses the default transport specified in the
% :mat:func:`XML_Node`. The third argument is the logging level desired.
%
% :param r:
% An instance of class :mat:func:`XML_Node`
% :param th:
% Instance of class :mat:func:`ThermoPhase`
% :param model:
% String indicating the transport model to use. Possible values
% are ``'default'``, ``'Mix'``, and ``'Multi'``
% are ``'default'``, ``'Mix'``, and ``'Multi'``. Optional.
% :param loglevel:
% Level of diagnostic logging. Default if not specified is 4.
% :return:
@ -24,25 +20,22 @@ function tr = Transport(r, th, model, loglevel)
%
tr.id = 0;
if nargin == 3
if nargin == 2
model = 'default';
end
if nargin < 3
loglevel = 4;
end
if ~isa(r, 'XML_Node')
error(['The first argument must be an instance of class XML_Node'])
elseif ~isa(th, 'ThermoPhase')
error('The second argument must be an instance of class ThermoPhase')
if ~isa(th, 'ThermoPhase')
error('The first argument must be an instance of class ThermoPhase')
else
tr.th = th;
if strcmp(model, 'default')
try
node = child(r, 'transport');
tr.model = attrib(node, 'model');
catch
tr.model = 'None';
end
tr.id = trans_get(thermo_hndl(th), -2, loglevel);
else
tr.model = model;
tr.id = trans_get(thermo_hndl(th), -1, model, loglevel);
end
tr.id = trans_get(thermo_hndl(th), -1, tr.model, loglevel) ;
tr = class(tr, 'Transport');
end

View file

@ -3,6 +3,7 @@
#include "ctmatutils.h"
#include "cantera/clib/ct.h"
#include "cantera/base/global.h"
void checkNArgs(const int n, const int nrhs)
{
@ -20,14 +21,19 @@ void kineticsmethods(int nlhs, mxArray* plhs[],
// construct a new instance
if (job == 0) {
checkNArgs(8, nrhs);
int root = getInt(prhs[1]);
int iph = getInt(prhs[3]);
int in1 = getInt(prhs[4]);
int in2 = getInt(prhs[5]);
int in3 = getInt(prhs[6]);
int in4 = getInt(prhs[7]);
vv = static_cast<int>(kin_newFromXML(root, iph, in1, in2, in3, in4));
checkNArgs(10, nrhs);
std::string fileName = getString(prhs[3]);
std::string phaseName = getString(prhs[4]);
if (phaseName == "-") {
phaseName = "";
}
int iph = getInt(prhs[5]);
int in1 = getInt(prhs[6]);
int in2 = getInt(prhs[7]);
int in3 = getInt(prhs[8]);
int in4 = getInt(prhs[9]);
vv = static_cast<int>(kin_newFromFile(
fileName.c_str(), phaseName.c_str(), iph, in1, in2, in3, in4));
plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
double* h = mxGetPr(plhs[0]);
*h = vv;

View file

@ -119,12 +119,24 @@ static void thermoget(int nlhs, mxArray* plhs[],
int n = getInt(prhs[1]);
int job = getInt(prhs[2]);
if (job < 30) {
if (job == 0) {
checkNArgs(5, nrhs);
std::string fileName = getString(prhs[3]);
std::string phaseName = getString(prhs[4]);
if (phaseName == "-") {
phaseName = "";
}
vv = (double) thermo_newFromFile(fileName.c_str(), phaseName.c_str());
if (vv == DERR) {
reportError();
}
plhs[0] = mxCreateNumericMatrix(1, 1, mxDOUBLE_CLASS, mxREAL);
double* h = mxGetPr(plhs[0]);
*h = vv;
return;
} else if (job < 30) {
bool ok = true;
switch (job) {
case 0:
vv = (double) thermo_newFromXML(n);
break;
case 2:
vv = thermo_enthalpy_mole(n);
break;

View file

@ -27,6 +27,19 @@ void transportmethods(int nlhs, mxArray* plhs[],
reportError();
}
// Create matrix for the return argument.
plhs[0] = mxCreateDoubleMatrix(1,1, mxREAL);
double* x = mxGetPr(plhs[0]);
*x = m;
return;
} else if (job == -2) {
int loglevel = getInt(prhs[3]);
int m = -2;
m = (int) trans_newDefault(n, loglevel);
if (m < 0) {
reportError();
}
// Create matrix for the return argument.
plhs[0] = mxCreateDoubleMatrix(1,1, mxREAL);
double* x = mxGetPr(plhs[0]);