From 901ec2f12ca477808f49dddb33b66e48f4fbdf4e Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Tue, 29 Jan 2019 16:17:34 -0500 Subject: [PATCH] [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. --- .../matlab/toolbox/@Interface/Interface.m | 14 +++--- .../matlab/toolbox/@Kinetics/Kinetics.m | 31 +++++++------ .../toolbox/@Kinetics/private/kinetics_get.m | 4 +- .../matlab/toolbox/@Solution/Solution.m | 13 +++--- .../matlab/toolbox/@ThermoPhase/ThermoPhase.m | 21 +++++---- .../matlab/toolbox/@Transport/Transport.m | 43 ++++++++----------- src/matlab/kineticsmethods.cpp | 22 ++++++---- src/matlab/thermomethods.cpp | 20 +++++++-- src/matlab/transportmethods.cpp | 13 ++++++ 9 files changed, 103 insertions(+), 78 deletions(-) diff --git a/interfaces/matlab/toolbox/@Interface/Interface.m b/interfaces/matlab/toolbox/@Interface/Interface.m index a8f73d354..ee95b4eaa 100644 --- a/interfaces/matlab/toolbox/@Interface/Interface.m +++ b/interfaces/matlab/toolbox/@Interface/Interface.m @@ -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; diff --git a/interfaces/matlab/toolbox/@Kinetics/Kinetics.m b/interfaces/matlab/toolbox/@Kinetics/Kinetics.m index e086090ed..3291a702b 100644 --- a/interfaces/matlab/toolbox/@Kinetics/Kinetics.m +++ b/interfaces/matlab/toolbox/@Kinetics/Kinetics.m @@ -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 diff --git a/interfaces/matlab/toolbox/@Kinetics/private/kinetics_get.m b/interfaces/matlab/toolbox/@Kinetics/private/kinetics_get.m index 0131ac66e..d262a9bda 100644 --- a/interfaces/matlab/toolbox/@Kinetics/private/kinetics_get.m +++ b/interfaces/matlab/toolbox/@Kinetics/private/kinetics_get.m @@ -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 diff --git a/interfaces/matlab/toolbox/@Solution/Solution.m b/interfaces/matlab/toolbox/@Solution/Solution.m index 2677648b2..29af2ae59 100644 --- a/interfaces/matlab/toolbox/@Solution/Solution.m +++ b/interfaces/matlab/toolbox/@Solution/Solution.m @@ -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); diff --git a/interfaces/matlab/toolbox/@ThermoPhase/ThermoPhase.m b/interfaces/matlab/toolbox/@ThermoPhase/ThermoPhase.m index cbc8ecb5c..4b45310e4 100644 --- a/interfaces/matlab/toolbox/@ThermoPhase/ThermoPhase.m +++ b/interfaces/matlab/toolbox/@ThermoPhase/ThermoPhase.m @@ -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 diff --git a/interfaces/matlab/toolbox/@Transport/Transport.m b/interfaces/matlab/toolbox/@Transport/Transport.m index f0c26018a..ab92bcc89 100644 --- a/interfaces/matlab/toolbox/@Transport/Transport.m +++ b/interfaces/matlab/toolbox/@Transport/Transport.m @@ -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 diff --git a/src/matlab/kineticsmethods.cpp b/src/matlab/kineticsmethods.cpp index 99d4a9e92..9a9870467 100644 --- a/src/matlab/kineticsmethods.cpp +++ b/src/matlab/kineticsmethods.cpp @@ -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(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(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; diff --git a/src/matlab/thermomethods.cpp b/src/matlab/thermomethods.cpp index 386cf7603..5f8acfdef 100644 --- a/src/matlab/thermomethods.cpp +++ b/src/matlab/thermomethods.cpp @@ -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; diff --git a/src/matlab/transportmethods.cpp b/src/matlab/transportmethods.cpp index 9a4cb0d46..35124802b 100644 --- a/src/matlab/transportmethods.cpp +++ b/src/matlab/transportmethods.cpp @@ -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]);