[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` % Instance of class :mat:func:`Interface`
% %
doc = XML_Node('doc', src); t = ThermoPhase(src, id);
node = findByID(doc, id);
t = ThermoPhase(node);
if nargin == 2 if nargin == 2
k = Kinetics(node, t); k = Kinetics(t, src, id);
elseif nargin == 3 elseif nargin == 3
k = Kinetics(node, t, p1); k = Kinetics(t, src, id, p1);
elseif nargin == 4 elseif nargin == 4
k = Kinetics(node, t, p1, p2); k = Kinetics(t, src, id, p1, p2);
elseif nargin == 5 elseif nargin == 5
k = Kinetics(node, t, p1, p2, p3); k = Kinetics(t, src, id, p1, p2, p3);
elseif nargin == 6 elseif nargin == 6
k = Kinetics(node, t, p1, p2, p3, p4); k = Kinetics(t, src, id, p1, p2, p3, p4);
end end
s.kin = k; 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. % KINETICS Kinetics class constructor.
% k = Kinetics(r, ph, neighbor1, neighbor2, neighbor3, neighbor4) % k = Kinetics(r, ph, neighbor1, neighbor2, neighbor3, neighbor4)
% Class Kinetics represents kinetics managers, which are classes % 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 % of progress, species production rates, and other quantities pertaining to
% a reaction mechanism. % a reaction mechanism.
% %
% :param r:
% An instance of class :mat:func:`XML_Node`.
% :param ph: % :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: % :param neighbor1:
% Instance of class :mat:func:`ThermoPhase` or :mat:func:`Solution` representing a % Instance of class :mat:func:`ThermoPhase` or :mat:func:`Solution` representing a
% neighboring phase. % neighboring phase.
@ -34,32 +37,28 @@ ineighbor1 = -1;
ineighbor2 = -1; ineighbor2 = -1;
ineighbor3 = -1; ineighbor3 = -1;
ineighbor4 = -1; ineighbor4 = -1;
if nargin == 2
% First argument must be an XML_Node instance representing the XML tree id = '-';
if ~isa(r, 'XML_Node')
error('first argument must be an XML_Node object')
end end
k.owner = 1; k.owner = 1;
ixml = xml_hndl(r);
% get the integer indices used to find the stored objects % get the integer indices used to find the stored objects
% representing the phases participating in the mechanism. % representing the phases participating in the mechanism.
iphase = thermo_hndl(ph); iphase = thermo_hndl(ph);
if nargin > 2 if nargin > 3
ineighbor1 = thermo_hndl(neighbor1); ineighbor1 = thermo_hndl(neighbor1);
if nargin > 3 if nargin > 4
ineighbor2 = thermo_hndl(neighbor2); ineighbor2 = thermo_hndl(neighbor2);
if nargin > 4 if nargin > 5
ineighbor3 = thermo_hndl(neighbor3); ineighbor3 = thermo_hndl(neighbor3);
if nargin > 5 if nargin > 6
ineighbor4 = thermo_hndl(neighbor4); ineighbor4 = thermo_hndl(neighbor4);
end end
end end
end end
end end
k.id = kinetics_get(ixml, 0, iphase, ineighbor1, ineighbor2, ineighbor3, ... k.id = kinetics_get(0, 0, src, id, iphase, ineighbor1, ineighbor2, ...
ineighbor4); ineighbor3, ineighbor4);
if k.id < 0 if k.id < 0
error(geterr); error(geterr);
end 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 % KINETICS_GET - get kinetics attributes
% %
if nargin == 2 if nargin == 2
@ -15,4 +15,6 @@ elseif nargin == 7
v = ctmethods(40, n, job, a, b, c, d, e); v = ctmethods(40, n, job, a, b, c, d, e);
elseif nargin == 8 elseif nargin == 8
v = ctmethods(40, n, job, a, b, c, d, e, f); 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 end

View file

@ -44,24 +44,21 @@ function s = Solution(src, id, trans)
% :return: % :return:
% Instance of class :mat:func:`Solution` % Instance of class :mat:func:`Solution`
% %
doc = XML_Node('doc', src);
if nargin == 1 if nargin == 1
node = findByName(doc, 'phase'); id = '-';
else
node = findByID(doc, id);
end end
t = ThermoPhase(node); t = ThermoPhase(src, id);
k = Kinetics(node, t); k = Kinetics(t, src, id);
s.kin = k; s.kin = k;
s.th = t; s.th = t;
if nargin == 3 if nargin == 3
if strcmp(trans, 'default') || strcmp(trans, 'Mix') || strcmp(trans, 'Multi') if strcmp(trans, 'default') || strcmp(trans, 'Mix') || strcmp(trans, 'Multi')
tr = Transport(node, t, trans, 0); tr = Transport(t, trans, 0);
else else
error('Unknown transport modeling specified.') error('Unknown transport modeling specified.')
end end
else else
tr = Transport(node, t, 'default', 0); tr = Transport(t, 'default', 0);
end end
s.tr = tr; s.tr = tr;
s = class(s, 'Solution', t, k, 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. % THERMOPHASE ThermoPhase class constructor.
% t = ThermoPhase(r) % t = ThermoPhase(src, id)
% :param r: % :param src:
% An instance of class :mat:func:`XML_Node`. % 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: % :return:
% Instance of class :mat:func:`ThermoPhase` % Instance of class :mat:func:`ThermoPhase`
% %
if nargin ~= 1 if nargin > 2
error('ThermoPhase expects 1 input argument.'); error('ThermoPhase expects 1 or 2 input arguments.');
end
if nargin == 1
id = '-';
end end
t.owner = 1; t.owner = 1;
hr = xml_hndl(r); t.tp_id = thermo_get(0, 0, src, id);
t.tp_id = thermo_get(hr, 0);
if t.tp_id < 0 if t.tp_id < 0
error(geterr); error(geterr);
end end

View file

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

View file

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

View file

@ -119,12 +119,24 @@ static void thermoget(int nlhs, mxArray* plhs[],
int n = getInt(prhs[1]); int n = getInt(prhs[1]);
int job = getInt(prhs[2]); 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; bool ok = true;
switch (job) { switch (job) {
case 0:
vv = (double) thermo_newFromXML(n);
break;
case 2: case 2:
vv = thermo_enthalpy_mole(n); vv = thermo_enthalpy_mole(n);
break; break;

View file

@ -27,6 +27,19 @@ void transportmethods(int nlhs, mxArray* plhs[],
reportError(); 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. // Create matrix for the return argument.
plhs[0] = mxCreateDoubleMatrix(1,1, mxREAL); plhs[0] = mxCreateDoubleMatrix(1,1, mxREAL);
double* x = mxGetPr(plhs[0]); double* x = mxGetPr(plhs[0]);