From 14864e840bb89a43e3ad1b2572d4315eae7161b4 Mon Sep 17 00:00:00 2001 From: Steven DeCaluwe Date: Fri, 6 Nov 2015 06:42:39 -0700 Subject: [PATCH] Extend NoNorm option for setCoverages to the Matlab toolbox Because normalizing the species coverages leads to incorrect Jacobian calculations, it is sometimes necessary to not normalize the coverages. As for bulk species mass/mole fractions, this option is currently only available when passing the coverages as a vector (i.e., not available for string identifiers). --- .../matlab/toolbox/@Interface/setCoverages.m | 19 ++++++++++++++++--- src/clib/ctsurf.cpp | 8 ++++++-- src/clib/ctsurf.h | 2 +- src/matlab/surfmethods.cpp | 6 ++++-- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/interfaces/matlab/toolbox/@Interface/setCoverages.m b/interfaces/matlab/toolbox/@Interface/setCoverages.m index d2985684d..7b45acbb1 100644 --- a/interfaces/matlab/toolbox/@Interface/setCoverages.m +++ b/interfaces/matlab/toolbox/@Interface/setCoverages.m @@ -1,18 +1,31 @@ -function setCoverages(s, cov) +function setCoverages(s, cov, norm) % SETCOVERAGES Set surface coverages of the species on an interface. -% setCoverages(s, cov) +% setCoverages(s, cov, norm) % :param s: % Instance of class :mat:func:`Interface` % :param cov: % Coverage of the species. ``cov`` can be either a vector of % length ``n_surf_species``, or a string in the format % ``'Species:Coverage, Species:Coverage'`` +% :param norm: +% Optional flag that denotes whether or not to normalize the species +% coverages. ``norm`` is either of the two strings ``'nonorm'``` or +% ``'norm'``. If left unset, the default is `norm`. This only works if +% ``s`` is a vector, not a string. Since unnormalized coverages can lead to +% unphysical results, ``'nonorm'`` should be used only in rare cases, such +% as computing partial derivatives with respect to a species coverage. % +if nargin == 3 && strcmp(norm,'nonorm') + norm_flag = 0; +else + norm_flag = 1; +end + if isa(cov, 'double') sz = length(cov); if sz == nSpecies(s) - surfmethods(thermo_hndl(s), 3, cov); + surfmethods(thermo_hndl(s), 3, cov, norm_flag); else error('wrong size for coverage array'); end diff --git a/src/clib/ctsurf.cpp b/src/clib/ctsurf.cpp index d3d6a82bc..eb76ef89d 100644 --- a/src/clib/ctsurf.cpp +++ b/src/clib/ctsurf.cpp @@ -35,10 +35,14 @@ extern "C" { } } - int surf_setcoverages(int i, double* c) + int surf_setcoverages(int i, double* c, int norm) { try { - ThermoCabinet::get(i).setCoverages(c); + if(norm){ + ThermoCabinet::get(i).setCoverages(c); + } else { + ThermoCabinet::get(i).setCoveragesNoNorm(c); + } return 0; } catch (...) { return handleAllExceptions(-1, ERR); diff --git a/src/clib/ctsurf.h b/src/clib/ctsurf.h index 377228bb9..bb1298b80 100644 --- a/src/clib/ctsurf.h +++ b/src/clib/ctsurf.h @@ -8,7 +8,7 @@ #include "cantera/base/config.h" extern "C" { - CANTERA_CAPI int surf_setcoverages(int i, double* c); + CANTERA_CAPI int surf_setcoverages(int i, double* c, int norm); CANTERA_CAPI int surf_getcoverages(int i, double* c); CANTERA_CAPI int surf_setconcentrations(int i, double* c); CANTERA_CAPI int surf_getconcentrations(int i, double* c); diff --git a/src/matlab/surfmethods.cpp b/src/matlab/surfmethods.cpp index 15d7b29d4..e4e71c393 100644 --- a/src/matlab/surfmethods.cpp +++ b/src/matlab/surfmethods.cpp @@ -14,6 +14,7 @@ void surfmethods(int nlhs, mxArray* plhs[], double vv; int job = getInt(prhs[2]); int iok = 0; + int norm = 0; double* ptr; char* str; size_t nsp, n, m; @@ -28,13 +29,14 @@ void surfmethods(int nlhs, mxArray* plhs[], iok = surf_setsitedensity(surf, vv); break; case 3: - checkNArgs(4, nrhs); + checkNArgs(5, nrhs); ptr = mxGetPr(prhs[3]); m = mxGetM(prhs[3]); n = mxGetN(prhs[3]); nsp = phase_nSpecies(surf); + norm = getInt(prhs[4]); if ((m == nsp && n == 1) || (m == 1 && n == nsp)) { - iok = surf_setcoverages(surf, ptr); + iok = surf_setcoverages(surf, ptr, norm); } else { mexErrMsgTxt("wrong array size for coverages"); }