added thread safety option

This commit is contained in:
Dave Goodwin 2007-05-10 03:28:30 +00:00
parent 1b3da91d15
commit ba5928083f
40 changed files with 2138 additions and 1510 deletions

View file

@ -50,7 +50,7 @@ LIB_DEPS = $(CANTERA_LIBDIR)/libctbase.a \
$(CANTERA_LIBDIR)/liboneD.a
# the directory where Cantera include files may be found.
CXX_INCLUDES = -I../../src/base -I../../src/thermo -I../../src/kinetics -I../../src/transport -I../../src/numerics -I../../src/oneD -I../../src/zeroD -I../../src/equil -I../../src/converters
CXX_INCLUDES = -I../../src/base -I../../src/thermo -I../../src/kinetics -I../../src/transport -I../../src/numerics -I../../src/oneD -I../../src/zeroD -I../../src/equil -I../../src/converters @CXX_INCLUDES@
# flags passed to the C++ compiler/linker for the linking step
LCXX_FLAGS = -L$(CANTERA_LIBDIR) @CXXFLAGS@

View file

@ -45,13 +45,17 @@ endlibstr1 = "@LCXX_END_LIBS@"
endlib1 = endlibstr1.replace('-l', ' ')
endlib = endlib1.split()
locallibstr = "@LOCAL_LIBS@"
local1 = locallibstr.replace('-l', ' ')
locallibs = local1.split()
if platform == "win32":
libs = ["clib", "zeroD","oneD","kinetics", "transport",
"cantera"] + bllist + cvlist + ["ctbase", "ctmath", "tpx"]
else:
libs = ["clib", "zeroD","oneD", "kinetics", "transport",
"equil", "ctnumerics", "converters"] + thermolib + bllist + cvlist + ["ctbase", "ctmath", "tpx"]
libs = ["clib"] + locallibs
#libs = ["clib", "zeroD","oneD", "kinetics", "transport",
# "equil", "ctnumerics", "converters"] + thermolib + bllist + cvlist + ["ctbase", "ctmath", "tpx", "boost_thread-mt-1_34"]
if @build_with_f2c@ == 1:
libs.append("ctf2c")

View file

@ -26,13 +26,13 @@ PIC_FLAG=@PIC@
CXX_FLAGS = @CXXFLAGS@ $(LOCAL_DEFS) $(CXX_OPT) $(PIC_FLAG) $(DEBUG_FLAG)
BASE_OBJ = misc.o ct2ctml.o ctml.o plots.o stringUtils.o xml.o
BASE_OBJ = ct2ctml.o ctml.o misc.o plots.o stringUtils.o xml.o
BASE_H = ct_defs.h ctexceptions.h global.h logger.h XML_Writer.h \
BASE_H = ct_defs.h ctexceptions.h logger.h XML_Writer.h \
ctml.h plots.h stringUtils.h xml.h config.h utilities.h \
Array.h vec_functions.h
Array.h vec_functions.h global.h FactoryBase.h
CXX_INCLUDES = -I.
CXX_INCLUDES = -I. @CXX_INCLUDES@
LIB = @buildlib@/libctbase.a
DEPENDS = $(BASE_OBJ:.o=.d)

View file

@ -191,6 +191,14 @@ namespace Cantera {
*/
void appdelete();
//! Delete and free memory allocated per thread in multithreaded applications
/*!
* Delete the memory allocated per thread by Cantera. It should be called from
* within the thread just before the thread terminates. If your version of Cantera has not
* been specifically compiled for thread safety this function does nothing.
*/
void thread_complete() ;
//! Returns root directory where %Cantera where installed
/*!
* @return
@ -279,6 +287,16 @@ namespace Cantera {
* @ingroup textlogs
*/
void writelog(const char* msg);
//! Write a formated message to the screen
/*!
* Using the printf formatting of C write a message to the screen
* with variable values.
*
* @param fmt c format string for the following arguments
* @ingroup textlogs
*/
void writelogf(const char* fmt,...);
//! Write an error message and terminate execution.
/*!
@ -452,104 +470,12 @@ namespace Cantera {
inline void write_logfile(std::string file = "log.html") {}
#endif
XML_Node* get_XML_Node(const std::string& file_ID, XML_Node* root);
//! Search for an XML_Node either wiithin an existing XML tree structure, or in another file,
//! based on the file name or the XML id attribute.
/*!
* This routine will locate an XML node in either the input
* XML tree or in another input file specified by the file
* part of the file_ID string. Searches are based on the
* ID attribute of the XML element only.
*
* @param file_ID This is a concatenation of two strings seperated
* by the "#" character. The string before the
* pound character is the file name of an xml
* file to carry out the search. The string after
* the # character is the ID attribute
* of the xml element to search for.
* The string is interpreted as a file string if
* no # character is in the string.
*
* @param root If the file string is empty, searches for the
* xml element with matching ID attribute are
* carried out from this XML node.
*
* @return
* This routine will process the XML file, creating an XML
* tree structure. It returns a pointer to the top of the tree.
*
*
* For example,
* @code
*
* XML_Node* xn = get_XML_Node("phase", "gri30.xml#gri30_mix", 0);
*
* @endcode
*
* will search in the file gri30.xml for an XML element of the following form, where
* the XML element name, phase, is an optional hit:
* @verbatim
<phase id="gri30_mix>
. . .
</phase>
* @endverbatim
*
* It will return a pointer to an xml tree for the XML phase element.
*
* @ingroup inputfiles
*/
XML_Node* get_XML_Node(const std::string& file_ID, XML_Node* root);
//! Search for an XML node based on the XML element name, file name, or XML id attribute.
/**
* This routine will locate an XML node in either the input
* XML tree or in another input file specified by the file
* part of the file_ID string. Searches are based on the
* XML element name and the ID attribute of the XML element.
* An exact match of both is usually required. However, the
* ID attribute may be set to "", in which case the first
* xml element with the correct XML element name will be returned.
*
* @param nameTarget This is the XML element name to look for.
*
* @param file_ID This is a concatenation of two strings seperated
* by the "#" character. The string before the
* pound character is the file name of an xml
* file to carry out the search. The string after
* the # character is the ID attribute
* of the xml element to search for.
* The string is interpreted as a file string if
* no # character is in the string.
*
* @param root If the file string is empty, searches for the
* xml element with matching ID attribute are
* carried out from this XML node.
*
* @return
* This routine will process the XML file, possibly creating an XML
* tree structure. It returns a pointer to the XML node searched for.
*
* For example,
* @code
*
* XML_Node* xn = get_XML_NameID("phase", "gri30.xml#gri30_mix", 0);
*
* @endcode
*
* will search in the file gri30.xml for an XML element of the following form:
* @verbatim
* <phase id="gri30_mix>
* . . .
* </phase>
* @endverbatim
*
* It will return a pointer to an xml tree for the XML phase element.
*
* @ingroup inputfiles
*/
XML_Node* get_XML_NameID(const std::string& nameTarget,
const std::string& file_ID, XML_Node* root);
XML_Node* get_XML_NameID(const std::string& nameTarget,
const std::string& file_ID,
XML_Node* root);
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -17,6 +17,12 @@
#include "ct_defs.h"
#include "ctexceptions.h"
#include <string>
#if defined(THREAD_SAFE_CANTERA)
#include <boost/thread/mutex.hpp>
#endif
namespace Cantera {
//! Unit conversion utility
@ -29,6 +35,9 @@ namespace Cantera {
//! Initialize the static Unit class.
static Unit* units() {
#if defined(THREAD_SAFE_CANTERA)
boost::mutex::scoped_lock lock(units_mutex) ;
#endif
if (!s_u) s_u = new Unit;
return s_u;
}
@ -38,9 +47,12 @@ namespace Cantera {
* Note this can't be done in a destructor.
*/
static void deleteUnit() {
#if defined(THREAD_SAFE_CANTERA)
boost::mutex::scoped_lock lock(units_mutex) ;
#endif
if (s_u) {
delete s_u;
s_u = 0;
delete s_u;
s_u = 0;
}
}
@ -54,10 +66,10 @@ namespace Cantera {
*/
doublereal actEnergyToSI(std::string units) {
if (m_act_u.find(units) != m_act_u.end()) {
return m_act_u[units];
return m_act_u[units];
}
else {
return toSI(units);
return toSI(units);
}
}
@ -83,55 +95,55 @@ namespace Cantera {
while (1 > 0) {
// get token consisting of all characters up to the next
// dash, slash, or the end of the string
k = u.find_first_of("/-");
if (k != std::string::npos)
tok = u.substr(0,k);
else
tok = u;
tsize = static_cast<int>(tok.size());
if (tsize == 0)
fctr = 1.0;
else if (tok[tsize - 1] == '2') {
tsub = tok.substr(0,tsize-1);
fctr = m_u[tsub];
fctr *= fctr;
}
else if (tok[tsize - 1] == '3') {
tsub = tok.substr(0,tsize-1);
fctr = m_u[tsub];
fctr *= fctr*fctr;
}
else if (tok[tsize - 1] == '4') {
tsub = tok.substr(0,tsize-1);
fctr = m_u[tsub];
fctr *= fctr*fctr*fctr;
}
else if (tok[tsize - 1] == '5') {
tsub = tok.substr(0,tsize-1);
fctr = m_u[tsub];
fctr *= fctr*fctr*fctr*fctr;
}
else if (tok[tsize - 1] == '6') {
tsub = tok.substr(0,tsize-1);
fctr = m_u[tsub];
fctr *= fctr*fctr*fctr*fctr*fctr;
}
else {
tsub = tok;
fctr = m_u[tok];
}
// get token consisting of all characters up to the next
// dash, slash, or the end of the string
k = u.find_first_of("/-");
if (k != std::string::npos)
tok = u.substr(0,k);
else
tok = u;
tsize = static_cast<int>(tok.size());
if (tsize == 0)
fctr = 1.0;
else if (tok[tsize - 1] == '2') {
tsub = tok.substr(0,tsize-1);
fctr = m_u[tsub];
fctr *= fctr;
}
else if (tok[tsize - 1] == '3') {
tsub = tok.substr(0,tsize-1);
fctr = m_u[tsub];
fctr *= fctr*fctr;
}
else if (tok[tsize - 1] == '4') {
tsub = tok.substr(0,tsize-1);
fctr = m_u[tsub];
fctr *= fctr*fctr*fctr;
}
else if (tok[tsize - 1] == '5') {
tsub = tok.substr(0,tsize-1);
fctr = m_u[tsub];
fctr *= fctr*fctr*fctr*fctr;
}
else if (tok[tsize - 1] == '6') {
tsub = tok.substr(0,tsize-1);
fctr = m_u[tsub];
fctr *= fctr*fctr*fctr*fctr*fctr;
}
else {
tsub = tok;
fctr = m_u[tok];
}
// tok is not one of the entries in map m_u, then
// m_u[tok] returns 0.0. Check for this.
if (fctr == 0)
throw CanteraError("toSI","unknown unit: "+tsub);
if (action == '-') f *= fctr;
else if (action == '/') f /= fctr;
if (k == std::string::npos) break;
action = u[k];
u = u.substr(k+1,u.size());
// tok is not one of the entries in map m_u, then
// m_u[tok] returns 0.0. Check for this.
if (fctr == 0)
throw CanteraError("toSI","unknown unit: "+tsub);
if (action == '-') f *= fctr;
else if (action == '/') f /= fctr;
if (k == std::string::npos) break;
action = u[k];
u = u.substr(k+1,u.size());
}
return f;
}
@ -156,6 +168,10 @@ namespace Cantera {
*/
std::map<std::string, doublereal> m_act_u;
#if defined(THREAD_SAFE_CANTERA)
static boost::mutex units_mutex;
#endif
/*!
* Units class constructor, containing the default mappings between
* strings and units.
@ -215,3 +231,4 @@ namespace Cantera {
}
#endif

View file

@ -5,6 +5,7 @@
* stoichiometric coefficient matrix (see /ref equil functions)
*/
/*
/*
* $Author$
* $Date$
* $Revision$
@ -19,7 +20,7 @@ using namespace std;
#ifdef DEBUG_HKM
namespace Cantera {
int Cantera::BasisOptimize_print_lvl = 0;
static char sbuf[1024];
//static char sbuf[1024];
}
static void print_stringTrunc(const char *str, int space, int alignment);
#endif
@ -79,9 +80,9 @@ static int mlequ(double *c, int idem, int n, double *b, int m);
*
*/
int Cantera::BasisOptimize(int *usedZeroedSpecies, bool doFormRxn,
MultiPhase *mphase, vector_int & orderVectorSpecies,
vector_int & orderVectorElements,
vector_fp & formRxnMatrix) {
MultiPhase *mphase, vector_int & orderVectorSpecies,
vector_int & orderVectorElements,
vector_fp & formRxnMatrix) {
int j, jj, k=0, kk, l, i, jl, ml;
bool lindep;
@ -131,25 +132,25 @@ int Cantera::BasisOptimize(int *usedZeroedSpecies, bool doFormRxn,
writelog(" --- Formula Matrix used in BASOPT calculation\n");
writelog(" --- Species | Order | ");
for (j = 0; j < ne; j++) {
jj = orderVectorElements[j];
writelog(" ");
ename = mphase->elementName(jj);
print_stringTrunc(ename.c_str(), 4, 1);
sprintf(sbuf,"(%1d)", j); writelog(sbuf);
jj = orderVectorElements[j];
writelog(" ");
ename = mphase->elementName(jj);
print_stringTrunc(ename.c_str(), 4, 1);
writelogf("(%1d)", j);
}
writelog("\n");
for (k = 0; k < nspecies; k++) {
kk = orderVectorSpecies[k];
writelog(" --- ");
sname = mphase->speciesName(kk);
print_stringTrunc(sname.c_str(), 11, 1);
sprintf(sbuf," | %4d |", k); writelog(sbuf);
for (j = 0; j < ne; j++) {
jj = orderVectorElements[j];
double num = mphase->nAtoms(kk,jj);
sprintf(sbuf,"%6.1g ", num); writelog(sbuf);
}
writelog("\n");
kk = orderVectorSpecies[k];
writelog(" --- ");
sname = mphase->speciesName(kk);
print_stringTrunc(sname.c_str(), 11, 1);
writelogf(" | %4d |", k);
for (j = 0; j < ne; j++) {
jj = orderVectorElements[j];
double num = mphase->nAtoms(kk,jj);
writelogf("%6.1g ", num);
}
writelog("\n");
}
writelog(" --- \n");
}
@ -209,13 +210,13 @@ int Cantera::BasisOptimize(int *usedZeroedSpecies, bool doFormRxn,
*/
kk = amax(DATA_PTR(molNum), 0, nspecies);
for (j = 0; j < nspecies; j++) {
if (orderVectorSpecies[j] == kk) {
k = j;
break;
}
if (orderVectorSpecies[j] == kk) {
k = j;
break;
}
}
if (j == nspecies) {
throw CanteraError("BasisOptimize", "orderVectorSpecies contains an error");
throw CanteraError("BasisOptimize", "orderVectorSpecies contains an error");
}
if (molNum[kk] == 0.0) *usedZeroedSpecies = true;
@ -223,9 +224,9 @@ int Cantera::BasisOptimize(int *usedZeroedSpecies, bool doFormRxn,
* If the largest molNum is negative, then we are done.
*/
if (molNum[kk] == USEDBEFORE) {
nComponents = jr;
nNonComponents = nspecies - nComponents;
goto L_END_LOOP;
nComponents = jr;
nNonComponents = nspecies - nComponents;
goto L_END_LOOP;
}
/*
* Assign a small negative number to the component that we have
@ -245,32 +246,32 @@ int Cantera::BasisOptimize(int *usedZeroedSpecies, bool doFormRxn,
*/
jl = jr;
for (j = 0; j < ne; ++j) {
jj = orderVectorElements[j];
sm[j + jr*ne] = mphase->nAtoms(kk,jj);
jj = orderVectorElements[j];
sm[j + jr*ne] = mphase->nAtoms(kk,jj);
}
if (jl > 0) {
/*
* Compute the coefficients of JA column of the
* the upper triangular R matrix, SS(J) = R_J_JR
* (this is slightly different than Dalquist)
* R_JA_JA = 1
*/
for (j = 0; j < jl; ++j) {
ss[j] = 0.0;
for (i = 0; i < ne; ++i) {
ss[j] += sm[i + jr*ne] * sm[i + j*ne];
}
ss[j] /= sa[j];
}
/*
* Now make the new column, (*,JR), orthogonal to the
* previous columns
*/
for (j = 0; j < jl; ++j) {
for (l = 0; l < ne; ++l) {
sm[l + jr*ne] -= ss[j] * sm[l + j*ne];
}
}
/*
* Compute the coefficients of JA column of the
* the upper triangular R matrix, SS(J) = R_J_JR
* (this is slightly different than Dalquist)
* R_JA_JA = 1
*/
for (j = 0; j < jl; ++j) {
ss[j] = 0.0;
for (i = 0; i < ne; ++i) {
ss[j] += sm[i + jr*ne] * sm[i + j*ne];
}
ss[j] /= sa[j];
}
/*
* Now make the new column, (*,JR), orthogonal to the
* previous columns
*/
for (j = 0; j < jl; ++j) {
for (l = 0; l < ne; ++l) {
sm[l + jr*ne] -= ss[j] * sm[l + j*ne];
}
}
}
/*
* Find the new length of the new column in Q.
@ -278,8 +279,8 @@ int Cantera::BasisOptimize(int *usedZeroedSpecies, bool doFormRxn,
*/
sa[jr] = 0.0;
for (ml = 0; ml < ne; ++ml) {
tmp = sm[ml + jr*ne];
sa[jr] += tmp * tmp;
tmp = sm[ml + jr*ne];
sa[jr] += tmp * tmp;
}
/* **************************************************** */
/* **** IF NORM OF NEW ROW .LT. 1E-3 REJECT ********** */
@ -293,15 +294,13 @@ int Cantera::BasisOptimize(int *usedZeroedSpecies, bool doFormRxn,
if (jr != k) {
#ifdef DEBUG_HKM
if (BasisOptimize_print_lvl >= 1) {
kk = orderVectorSpecies[k];
sname = mphase->speciesName(kk);
sprintf(sbuf," --- %-12.12s", sname.c_str()); writelog(sbuf);
jj = orderVectorSpecies[jr];
ename = mphase->speciesName(jj);
sprintf(sbuf,"(%9.2g) replaces %-12.12s", molSave, ename.c_str());
writelog(sbuf);
sprintf(sbuf,"(%9.2g) as component %3d\n", molNum[jj], jr);
writelog(sbuf);
kk = orderVectorSpecies[k];
sname = mphase->speciesName(kk);
writelogf(" --- %-12.12s", sname.c_str());
jj = orderVectorSpecies[jr];
ename = mphase->speciesName(jj);
writelogf("(%9.2g) replaces %-12.12s", molSave, ename.c_str());
writelogf("(%9.2g) as component %3d\n", molNum[jj], jr);
}
#endif
switch_pos(orderVectorSpecies, jr, k);
@ -381,40 +380,38 @@ int Cantera::BasisOptimize(int *usedZeroedSpecies, bool doFormRxn,
#ifdef DEBUG_HKM
if (Cantera::BasisOptimize_print_lvl >= 1) {
writelog(" ---\n");
sprintf(sbuf," --- Number of Components = %d\n", nComponents);
writelog(sbuf);
writelogf(" --- Number of Components = %d\n", nComponents);
writelog(" --- Formula Matrix:\n");
writelog(" --- Components: ");
for (k = 0; k < nComponents; k++) {
kk = orderVectorSpecies[k];
sprintf(sbuf," %3d (%3d) ", k, kk); writelog(sbuf);
writelogf(" %3d (%3d) ", k, kk);
}
writelog("\n --- Components Moles: ");
for (k = 0; k < nComponents; k++) {
kk = orderVectorSpecies[k];
sprintf(sbuf,"%-11.3g", molNumBase[kk]); writelog(sbuf);
writelogf("%-11.3g", molNumBase[kk]);
}
writelog("\n --- NonComponent | Moles | ");
for (i = 0; i < nComponents; i++) {
kk = orderVectorSpecies[i];
sname = mphase->speciesName(kk);
sprintf(sbuf,"%-11.10s", sname.c_str()); writelog(sbuf);
writelogf("%-11.10s", sname.c_str());
}
writelog("\n");
for (i = 0; i < nNonComponents; i++) {
k = i + nComponents;
kk = orderVectorSpecies[k];
sprintf(sbuf," --- %3d (%3d) ", k, kk); writelog(sbuf);
writelogf(" --- %3d (%3d) ", k, kk);
sname = mphase->speciesName(kk);
sprintf(sbuf,"%-10.10s", sname.c_str()); writelog(sbuf);
sprintf(sbuf,"|%10.3g|", molNumBase[kk]); writelog(sbuf);
writelogf("%-10.10s", sname.c_str());
writelogf("|%10.3g|", molNumBase[kk]);
/*
* Print the negative of formRxnMatrix[]; it's easier to interpret.
*/
for (j = 0; j < nComponents; j++) {
sprintf(sbuf," %6.2f", - formRxnMatrix[j + i * ne]);
writelog(sbuf);
writelogf(" %6.2f", - formRxnMatrix[j + i * ne]);
}
writelog("\n");
}
@ -448,7 +445,7 @@ static void print_stringTrunc(const char *str, int space, int alignment)
int len = strlen(str);
if ((len) >= space) {
for (i = 0; i < space; i++) {
sprintf(sbuf,"%c", str[i]); writelog(sbuf);
writelogf("%c", str[i]);
}
} else {
if (alignment == 1) {
@ -462,7 +459,7 @@ static void print_stringTrunc(const char *str, int space, int alignment)
if (ls != 0) {
for (i = 0; i < ls; i++) writelog(" ");
}
sprintf(sbuf,"%s", str); writelog(sbuf);
writelogf("%s", str);
if (rs != 0) {
for (i = 0; i < rs; i++) writelog(" ");
}
@ -540,14 +537,13 @@ static int amax(double *x, int j, int n) {
for (i = 0; i < n; ++i) {
if (c[i + i * idem] == 0.0) {
/*
* Do a simple form of row pivoting to find a non-zero pivot
*/
* Do a simple form of row pivoting to find a non-zero pivot
*/
for (k = i + 1; k < n; ++k) {
if (c[k + i * idem] != 0.0) goto FOUND_PIVOT;
if (c[k + i * idem] != 0.0) goto FOUND_PIVOT;
}
#ifdef DEBUG_HKM
sprintf(sbuf,"vcs_mlequ ERROR: Encountered a zero column: %d\n", i);
writelog(sbuf);
writelogf("vcs_mlequ ERROR: Encountered a zero column: %d\n", i);
#endif
return 1;
FOUND_PIVOT: ;
@ -557,10 +553,10 @@ static int amax(double *x, int j, int n) {
for (l = 0; l < n; ++l) {
if (l != i && c[l + i * idem] != 0.0) {
R = c[l + i * idem] / c[i + i * idem];
c[l + i * idem] = 0.0;
for (j = i+1; j < n; ++j) c[l + j * idem] -= c[i + j * idem] * R;
for (j = 0; j < m; ++j) b[l + j * idem] -= b[i + j * idem] * R;
R = c[l + i * idem] / c[i + i * idem];
c[l + i * idem] = 0.0;
for (j = i+1; j < n; ++j) c[l + j * idem] -= c[i + j * idem] * R;
for (j = 0; j < m; ++j) b[l + j * idem] -= b[i + j * idem] * R;
}
}
}
@ -612,9 +608,9 @@ static int amax(double *x, int j, int n) {
* nonsingular matrix to invert.
*/
int Cantera::ElemRearrange(int nComponents, const vector_fp & elementAbundances,
MultiPhase *mphase,
vector_int & orderVectorSpecies,
vector_int & orderVectorElements) {
MultiPhase *mphase,
vector_int & orderVectorSpecies,
vector_int & orderVectorElements) {
int j, k, l, i, jl, ml, jr, ielem, jj, kk=0;
@ -669,12 +665,12 @@ int Cantera::ElemRearrange(int nComponents, const vector_fp & elementAbundances,
for (j = 0; j < nelements; j++) {
eAbund[j] = 0.0;
for (k = 0; k < nspecies; k++) {
eAbund[j] += fabs(mphase->nAtoms(k, j));
eAbund[j] += fabs(mphase->nAtoms(k, j));
}
}
} else {
copy(elementAbundances.begin(), elementAbundances.end(),
eAbund.begin());
eAbund.begin());
}
vector_fp sa(nelements,0.0);
@ -701,39 +697,38 @@ int Cantera::ElemRearrange(int nComponents, const vector_fp & elementAbundances,
*/
k = nelements;
for (ielem = jr; ielem < nelements; ielem++) {
kk = orderVectorElements[ielem];
if (eAbund[kk] != test && eAbund[kk] > 0.0) {
k = ielem;
break;
}
kk = orderVectorElements[ielem];
if (eAbund[kk] != test && eAbund[kk] > 0.0) {
k = ielem;
break;
}
}
for (ielem = jr; ielem < nelements; ielem++) {
kk = orderVectorElements[ielem];
if (eAbund[kk] != test) {
k = ielem;
break;
}
kk = orderVectorElements[ielem];
if (eAbund[kk] != test) {
k = ielem;
break;
}
}
if (k == nelements) {
// When we are here, there is an error usually.
// We haven't found the number of elements necessary.
// This is signalled by returning jr != nComponents.
// When we are here, there is an error usually.
// We haven't found the number of elements necessary.
// This is signalled by returning jr != nComponents.
#ifdef DEBUG_HKM
if (BasisOptimize_print_lvl > 0) {
sprintf(sbuf,"Error exit: returning with nComponents = %d\n", jr);
writelog(sbuf);
writelogf("Error exit: returning with nComponents = %d\n", jr);
}
#endif
return jr;
return jr;
}
/*
* Assign a large negative number to the element that we have
* just found, in order to take it out of further consideration.
*/
eAbund[kk] = test;
/* *********************************************************** */
/* **** CHECK LINEAR INDEPENDENCE OF CURRENT FORMULA MATRIX */
/* **** LINE WITH PREVIOUS LINES OF THE FORMULA MATRIX ****** */
@ -750,43 +745,43 @@ int Cantera::ElemRearrange(int nComponents, const vector_fp & elementAbundances,
* (note j and k indecises are flipped compared to the previous routine)
*/
for (j = 0; j < nComponents; ++j) {
jj = orderVectorSpecies[j];
kk = orderVectorElements[k];
sm[j + jr*nComponents] = mphase->nAtoms(jj,kk);
jj = orderVectorSpecies[j];
kk = orderVectorElements[k];
sm[j + jr*nComponents] = mphase->nAtoms(jj,kk);
}
if (jl > 0) {
/*
* Compute the coefficients of JA column of the
* the upper triangular R matrix, SS(J) = R_J_JR
* (this is slightly different than Dalquist)
* R_JA_JA = 1
*/
for (j = 0; j < jl; ++j) {
ss[j] = 0.0;
for (i = 0; i < nComponents; ++i) {
ss[j] += sm[i + jr*nComponents] * sm[i + j*nComponents];
}
ss[j] /= sa[j];
}
/*
* Now make the new column, (*,JR), orthogonal to the
* previous columns
*/
for (j = 0; j < jl; ++j) {
for (l = 0; l < nComponents; ++l) {
sm[l + jr*nComponents] -= ss[j] * sm[l + j*nComponents];
}
}
/*
* Compute the coefficients of JA column of the
* the upper triangular R matrix, SS(J) = R_J_JR
* (this is slightly different than Dalquist)
* R_JA_JA = 1
*/
for (j = 0; j < jl; ++j) {
ss[j] = 0.0;
for (i = 0; i < nComponents; ++i) {
ss[j] += sm[i + jr*nComponents] * sm[i + j*nComponents];
}
ss[j] /= sa[j];
}
/*
* Now make the new column, (*,JR), orthogonal to the
* previous columns
*/
for (j = 0; j < jl; ++j) {
for (l = 0; l < nComponents; ++l) {
sm[l + jr*nComponents] -= ss[j] * sm[l + j*nComponents];
}
}
}
/*
* Find the new length of the new column in Q.
* It will be used in the denominator in future row calcs.
*/
sa[jr] = 0.0;
for (ml = 0; ml < nComponents; ++ml) {
double tmp = sm[ml + jr*nComponents];
sa[jr] += tmp * tmp;
double tmp = sm[ml + jr*nComponents];
sa[jr] += tmp * tmp;
}
/* **************************************************** */
/* **** IF NORM OF NEW ROW .LT. 1E-6 REJECT ********** */
@ -800,15 +795,15 @@ int Cantera::ElemRearrange(int nComponents, const vector_fp & elementAbundances,
if (jr != k) {
#ifdef DEBUG_HKM
if (BasisOptimize_print_lvl > 0) {
kk = orderVectorElements[k];
ename = mphase->elementName(kk);
writelog(" --- ");
sprintf(sbuf,"%-2.2s", ename.c_str()); writelog(sbuf);
writelog("replaces ");
kk = orderVectorElements[jr];
ename = mphase->elementName(kk);
sprintf(sbuf,"%-2.2s", ename.c_str()); writelog(sbuf);
sprintf(sbuf," as element %3d\n", jr); writelog(sbuf);
kk = orderVectorElements[k];
ename = mphase->elementName(kk);
writelog(" --- ");
writelogf("%-2.2s", ename.c_str());
writelog("replaces ");
kk = orderVectorElements[jr];
ename = mphase->elementName(kk);
writelogf("%-2.2s", ename.c_str());
writelogf(" as element %3d\n", jr);
}
#endif
switch_pos(orderVectorElements, jr, k);
@ -822,3 +817,4 @@ int Cantera::ElemRearrange(int nComponents, const vector_fp & elementAbundances,
} while (jr < (nComponents-1));
return nComponents;
} /* vcs_elem_rearrange() ****************************************************/

File diff suppressed because it is too large Load diff

View file

@ -112,9 +112,9 @@ namespace Cantera {
virtual ~ChemEquil();
int equilibrate(thermo_t& s, const char* XY,
bool useThermoPhaseElementPotentials = false);
bool useThermoPhaseElementPotentials = false, int loglevel = 0);
int equilibrate(thermo_t& s, const char* XY, vector_fp& elMoles,
bool useThermoPhaseElementPotentials = false);
bool useThermoPhaseElementPotentials = false, int loglevel = 0);
const vector_fp& elementPotentials() const { return m_lambda; }
/**
@ -144,10 +144,10 @@ namespace Cantera {
void setToEquilState(thermo_t& s,
const vector_fp& x, doublereal t);
int setInitialMoles(thermo_t& s, vector_fp& elMoleGoal);
int setInitialMoles(thermo_t& s, vector_fp& elMoleGoal, int loglevel = 0);
int estimateElementPotentials(thermo_t& s, vector_fp& lambda,
vector_fp& elMolesGoal);
vector_fp& elMolesGoal, int loglevel = 0);
int estimateEP_Brinkley(thermo_t&s, vector_fp& lambda, vector_fp& elMoles);
@ -157,11 +157,11 @@ namespace Cantera {
void equilResidual(thermo_t& s, const vector_fp& x,
const vector_fp& elmtotal, vector_fp& resid,
double xval, double yval);
double xval, double yval, int loglevel = 0);
void equilJacobian(thermo_t& s, vector_fp& x,
const vector_fp& elmols, DenseMatrix& jac,
double xval, double yval);
double xval, double yval, int loglevel = 0);
void adjustEloc(thermo_t& s, vector_fp & elMolesGoal);

View file

@ -491,13 +491,15 @@ namespace Cantera {
MultiPhaseEquil* e = 0;
if (!m_init) init();
beginLogGroup("MultiPhase::equilibrate", loglevel);
if (loglevel > 0)
beginLogGroup("MultiPhase::equilibrate", loglevel);
if (XY == TP) {
addLogEntry("problem type","fixed T,P");
addLogEntry("Temperature",temperature());
addLogEntry("Pressure", pressure());
if (loglevel > 0) {
addLogEntry("problem type","fixed T,P");
addLogEntry("Temperature",temperature());
addLogEntry("Pressure", pressure());
}
// create an equilibrium manager
e = new MultiPhaseEquil(this);
@ -505,7 +507,8 @@ namespace Cantera {
error = e->equilibrate(XY, err, maxsteps);
}
catch (CanteraError err) {
endLogGroup();
if (loglevel > 0)
endLogGroup();
delete e;
e = 0;
throw err;
@ -517,9 +520,10 @@ namespace Cantera {
h0 = enthalpy();
Tlow = 0.5*m_Tmin; // lower bound on T
Thigh = 2.0*m_Tmax; // upper bound on T
addLogEntry("problem type","fixed H,P");
addLogEntry("H target",fp2str(h0));
if (loglevel > 0) {
addLogEntry("problem type","fixed H,P");
addLogEntry("H target",fp2str(h0));
}
for (n = 0; n < maxiter; n++) {
// if 'strt' is false, the current composition will be used as
@ -531,7 +535,8 @@ namespace Cantera {
e = new MultiPhaseEquil(this, strt);
// start with a loose error tolerance, but tighten it as we get
// close to the final temperature
beginLogGroup("iteration "+int2str(n));
if (loglevel > 0)
beginLogGroup("iteration "+int2str(n));
try {
error = e->equilibrate(TP, err, maxsteps);
@ -567,18 +572,22 @@ namespace Cantera {
}
herr = fabs((h0 - hnow)/h0);
addLogEntry("T",fp2str(temperature()));
addLogEntry("H",fp2str(hnow));
addLogEntry("H rel error",fp2str(herr));
addLogEntry("lower T bound",fp2str(Tlow));
addLogEntry("upper T bound",fp2str(Thigh));
endLogGroup(); // iteration
if (loglevel > 0) {
addLogEntry("T",fp2str(temperature()));
addLogEntry("H",fp2str(hnow));
addLogEntry("H rel error",fp2str(herr));
addLogEntry("lower T bound",fp2str(Tlow));
addLogEntry("upper T bound",fp2str(Thigh));
endLogGroup(); // iteration
}
if (herr < err) { // || dta < 1.0e-4) {
addLogEntry("T iterations",int2str(n));
addLogEntry("Final T",fp2str(temperature()));
addLogEntry("H rel error",fp2str(herr));
if (loglevel > 0) {
addLogEntry("T iterations",int2str(n));
addLogEntry("Final T",fp2str(temperature()));
addLogEntry("H rel error",fp2str(herr));
}
goto done;
}
tnew = m_temp + dt;
@ -593,25 +602,30 @@ namespace Cantera {
}
catch (CanteraError err) {
if (!strt) {
addLogEntry("no convergence",
"try estimating starting composition");
if (!strt) {
if (loglevel > 0)
addLogEntry("no convergence",
"try estimating starting composition");
strt = true;
}
else {
tnew = 0.5*(m_temp + Thigh);
if (fabs(tnew - m_temp) < 1.0) tnew = m_temp + 1.0;
setTemperature(tnew);
addLogEntry("no convergence",
"trying T = "+fp2str(m_temp));
if (loglevel > 0)
addLogEntry("no convergence",
"trying T = "+fp2str(m_temp));
}
endLogGroup();
if (loglevel > 0)
endLogGroup();
}
delete e;
e = 0;
}
addLogEntry("reached max number of T iterations",int2str(maxiter));
endLogGroup();
if (loglevel > 0) {
addLogEntry("reached max number of T iterations",int2str(maxiter));
endLogGroup();
}
throw CanteraError("MultiPhase::equilibrate",
"No convergence for T");
}
@ -620,18 +634,20 @@ namespace Cantera {
start = true;
Tlow = 1.0; // m_Tmin; // lower bound on T
Thigh = 1.0e6; // m_Tmax; // upper bound on T
addLogEntry("problem type","fixed S,P");
addLogEntry("S target",fp2str(s0));
addLogEntry("min T",fp2str(Tlow));
addLogEntry("max T",fp2str(Thigh));
if (loglevel > 0) {
addLogEntry("problem type","fixed S,P");
addLogEntry("S target",fp2str(s0));
addLogEntry("min T",fp2str(Tlow));
addLogEntry("max T",fp2str(Thigh));
}
for (n = 0; n < maxiter; n++) {
if (e) delete e;
e = new MultiPhaseEquil(this, strt);
ferr = 0.1;
if (fabs(dt) < 1.0) ferr = err;
//start = false;
beginLogGroup("iteration "+int2str(n));
if (loglevel > 0)
beginLogGroup("iteration "+int2str(n));
try {
error = e->equilibrate(TP, err, maxsteps);
@ -643,20 +659,23 @@ namespace Cantera {
if (m_temp < Thigh) Thigh = m_temp;
}
serr = fabs((s0 - snow)/s0);
addLogEntry("T",fp2str(temperature()));
addLogEntry("S",fp2str(snow));
addLogEntry("S rel error",fp2str(serr));
endLogGroup();
if (loglevel > 0) {
addLogEntry("T",fp2str(temperature()));
addLogEntry("S",fp2str(snow));
addLogEntry("S rel error",fp2str(serr));
endLogGroup();
}
dt = (s0 - snow)*m_temp/cp();
dtmax = 0.5*fabs(Thigh - Tlow);
dtmax = (dtmax > 500.0 ? 500.0 : dtmax);
dta = fabs(dt);
if (dta > dtmax) dt *= dtmax/dta;
if (herr < err || dta < 1.0e-4) {
addLogEntry("T iterations",int2str(n));
addLogEntry("Final T",fp2str(temperature()));
addLogEntry("S rel error",fp2str(serr));
if (loglevel > 0) {
addLogEntry("T iterations",int2str(n));
addLogEntry("Final T",fp2str(temperature()));
addLogEntry("S rel error",fp2str(serr));
}
goto done;
}
tnew = m_temp + dt;
@ -669,24 +688,30 @@ namespace Cantera {
catch (CanteraError err) {
if (!strt) {
addLogEntry("no convergence",
"setting strt to True");
if (loglevel > 0) {
addLogEntry("no convergence",
"setting strt to True");
}
strt = true;
}
else {
tnew = 0.5*(m_temp + Thigh);
setTemperature(tnew);
addLogEntry("no convergence",
"trying T = "+fp2str(m_temp));
if (loglevel > 0) {
addLogEntry("no convergence",
"trying T = "+fp2str(m_temp));
}
}
endLogGroup();
if (loglevel > 0)
endLogGroup();
}
delete e;
e = 0;
}
addLogEntry("reached max number of T iterations",int2str(maxiter));
endLogGroup();
if (loglevel > 0) {
addLogEntry("reached max number of T iterations",int2str(maxiter));
endLogGroup();
}
throw CanteraError("MultiPhase::equilibrate",
"No convergence for T");
}
@ -785,14 +810,16 @@ namespace Cantera {
}
else {
endLogGroup();
if (loglevel > 0)
endLogGroup();
throw CanteraError("MultiPhase::equilibrate","unknown option");
}
return -1.0;
done:
delete e;
e = 0;
endLogGroup();
if (loglevel > 0)
endLogGroup();
return err;
}

View file

@ -39,7 +39,7 @@ namespace Cantera {
/// @param start If true, the initial composition will be
/// determined by a linear Gibbs minimization, otherwise the
/// initial mixture composition will be used.
MultiPhaseEquil::MultiPhaseEquil(mix_t* mix, bool start) : m_mix(mix)
MultiPhaseEquil::MultiPhaseEquil(mix_t* mix, bool start, int loglevel) : m_mix(mix)
{
// the multi-phase mixture
// m_mix = mix;
@ -165,7 +165,7 @@ namespace Cantera {
// only the elemental composition of the initial mixture state
// matters.
if (start) {
setInitialMoles();
setInitialMoles(loglevel-1);
}
computeN();
@ -198,28 +198,37 @@ namespace Cantera {
int i;
m_iter = 0;
string iterstr;
beginLogGroup("MultiPhaseEquil::equilibrate", loglevel);
if (loglevel > 0)
beginLogGroup("MultiPhaseEquil::equilibrate", loglevel);
for (i = 0; i < maxsteps; i++) {
iterstr = "iteration "+int2str(i);
beginLogGroup(iterstr);
stepComposition();
addLogEntry("error",fp2str(error()));
endLogGroup(iterstr);
if (loglevel > 0) {
iterstr = "iteration "+int2str(i);
beginLogGroup(iterstr);
}
stepComposition(loglevel-1);
if (loglevel > 0) {
addLogEntry("error",fp2str(error()));
endLogGroup(iterstr);
}
if (error() < err) break;
}
if (i >= maxsteps) {
addLogEntry("Error","no convergence in "+int2str(maxsteps)
+" iterations");
endLogGroup("MultiPhaseEquil::equilibrate");
if (loglevel > 0) {
addLogEntry("Error","no convergence in "+int2str(maxsteps)
+" iterations");
endLogGroup("MultiPhaseEquil::equilibrate");
}
throw CanteraError("MultiPhaseEquil::equilibrate",
"no convergence in " + int2str(maxsteps) +
" iterations. Error = " + fp2str(error()));
}
addLogEntry("iterations",int2str(iterations()));
addLogEntry("error tolerance",fp2str(err));
addLogEntry("error",fp2str(error()));
endLogGroup("MultiPhaseEquil::equilibrate");
if (loglevel > 0) {
addLogEntry("iterations",int2str(iterations()));
addLogEntry("error tolerance",fp2str(err));
addLogEntry("error",fp2str(error()));
endLogGroup("MultiPhaseEquil::equilibrate");
}
finish();
return error();
}
@ -256,11 +265,12 @@ namespace Cantera {
/// to solving the linear programming problem of minimizing the
/// linear Gibbs function subject to the element and
/// non-negativity constraints.
int MultiPhaseEquil::setInitialMoles() {
int MultiPhaseEquil::setInitialMoles(int loglevel) {
index_t ik, j;
double not_mu = 1.0e12;
beginLogGroup("MultiPhaseEquil::setInitialMoles");
if (loglevel > 0)
beginLogGroup("MultiPhaseEquil::setInitialMoles");
m_mix->getValidChemPotentials(not_mu, DATA_PTR(m_mu), true);
doublereal dg_rt;
@ -275,7 +285,8 @@ namespace Cantera {
// choose a set of components based on the current
// composition
computeN();
addLogEntry("iteration",iter);
if (loglevel > 0)
addLogEntry("iteration",iter);
redo = false;
iter++;
if (iter > 4) break;
@ -300,7 +311,8 @@ namespace Cantera {
// if a component has nearly zero moles, redo
// with a new set of components
if (!redo && delta_xi < 1.0e-10 && ik < m_nel) {
addLogEntry("component too small",speciesName(ik));
if (loglevel > 0)
addLogEntry("component too small",speciesName(ik));
redo = true;
}
if (delta_xi < dxi_min) dxi_min = delta_xi;
@ -316,8 +328,8 @@ namespace Cantera {
}
for (ik = 0; ik < m_nsp; ik++)
if (moles(ik) != 0.0) addLogEntry(speciesName(ik), moles(ik));
endLogGroup("MultiPhaseEquil::setInitialMoles");
if (loglevel > 0)
endLogGroup("MultiPhaseEquil::setInitialMoles");
return 0;
}
@ -477,30 +489,41 @@ namespace Cantera {
}
#if defined(WITH_HTML_LOGS)
void MultiPhaseEquil::printInfo() {
void MultiPhaseEquil::printInfo(int loglevel) {
index_t m, ik, k;
beginLogGroup("info");
beginLogGroup("components");
if (loglevel > 0) {
beginLogGroup("info");
beginLogGroup("components");
}
for (m = 0; m < m_nel; m++) {
ik = m_order[m];
k = m_species[ik];
addLogEntry(m_mix->speciesName(k), fp2str(m_moles[ik]));
if (loglevel > 0)
addLogEntry(m_mix->speciesName(k), fp2str(m_moles[ik]));
}
if (loglevel > 0) {
endLogGroup("components");
beginLogGroup("non-components");
}
endLogGroup("components");
beginLogGroup("non-components");
for (m = m_nel; m < m_nsp; m++) {
ik = m_order[m];
k = m_species[ik];
addLogEntry(m_mix->speciesName(k), fp2str(m_moles[ik]));
if (loglevel > 0)
addLogEntry(m_mix->speciesName(k), fp2str(m_moles[ik]));
}
if (loglevel > 0) {
endLogGroup("non-components");
addLogEntry("Error",fp2str(error()));
beginLogGroup("Delta G / RT");
}
endLogGroup("non-components");
addLogEntry("Error",fp2str(error()));
beginLogGroup("Delta G / RT");
for (k = 0; k < m_nsp - m_nel; k++) {
addLogEntry(reactionString(k), fp2str(m_deltaG_RT[k]));
if (loglevel > 0)
addLogEntry(reactionString(k), fp2str(m_deltaG_RT[k]));
}
if (loglevel > 0) {
endLogGroup("Delta G / RT");
endLogGroup("info");
}
endLogGroup("Delta G / RT");
endLogGroup("info");
}
/// Return a string specifying the jth reaction.
@ -526,19 +549,23 @@ namespace Cantera {
}
#endif
void MultiPhaseEquil::step(doublereal omega, vector_fp& deltaN) {
void MultiPhaseEquil::step(doublereal omega, vector_fp& deltaN,
int loglevel) {
index_t k, ik;
beginLogGroup("MultiPhaseEquil::step");
if (loglevel > 0)
beginLogGroup("MultiPhaseEquil::step");
if (omega < 0.0)
throw CanteraError("step","negative omega");
for (ik = 0; ik < m_nel; ik++) {
k = m_order[ik];
m_lastmoles[k] = m_moles[k];
addLogEntry("component "+m_mix->speciesName(m_species[k])+" moles",
if (loglevel > 0) {
addLogEntry("component "+m_mix->speciesName(m_species[k])+" moles",
m_moles[k]);
addLogEntry("component "+m_mix->speciesName(m_species[k])+" step",
addLogEntry("component "+m_mix->speciesName(m_species[k])+" step",
omega*deltaN[k]);
}
m_moles[k] += omega * deltaN[k];
}
@ -554,16 +581,17 @@ namespace Cantera {
}
}
updateMixMoles();
endLogGroup("MultiPhaseEquil::step");
if (loglevel > 0)
endLogGroup("MultiPhaseEquil::step");
}
/// Take one step in composition, given the gradient of G at the
/// starting point, and a vector of reaction steps dxi.
doublereal MultiPhaseEquil::
stepComposition() {
beginLogGroup("MultiPhaseEquil::stepComposition");
stepComposition(int loglevel) {
if (loglevel > 0)
beginLogGroup("MultiPhaseEquil::stepComposition");
m_iter++;
index_t ik, k = 0;
@ -619,15 +647,17 @@ namespace Cantera {
}
}
if (m_moles[k] < -Tiny) {
addLogEntry("Negative moles for "
+m_mix->speciesName(m_species[k]), fp2str(m_moles[k]));
if (loglevel > 0)
addLogEntry("Negative moles for "
+m_mix->speciesName(m_species[k]), fp2str(m_moles[k]));
}
m_majorsp[k] = true;
}
}
// now take a step with this scaled omega
addLogEntry("Stepping by ", fp2str(omegamax));
if (loglevel > 0)
addLogEntry("Stepping by ", fp2str(omegamax));
step(omegamax, m_work);
// compute the gradient of G at this new position in the
// current direction. If it is positive, then we have overshot
@ -643,11 +673,13 @@ namespace Cantera {
if (grad1 > 0.0) {
omega *= fabs(grad0) / (grad1 + fabs(grad0));
for (k = 0; k < m_nsp; k++) m_moles[k] = m_lastmoles[k];
addLogEntry("Stepped over minimum. Take smaller step ", fp2str(omega));
if (loglevel > 0)
addLogEntry("Stepped over minimum. Take smaller step ", fp2str(omega));
step(omega, m_work);
}
printInfo();
endLogGroup("MultiPhaseEquil::stepComposition");
printInfo(loglevel);
if (loglevel > 0)
endLogGroup("MultiPhaseEquil::stepComposition");
return omega;
}

View file

@ -36,7 +36,7 @@ namespace Cantera {
typedef size_t index_t;
typedef DenseMatrix matrix_t;
MultiPhaseEquil(mix_t* mix, bool start=true);
MultiPhaseEquil(mix_t* mix, bool start=true, int loglevel = 0);
virtual ~MultiPhaseEquil() {}
@ -62,14 +62,14 @@ namespace Cantera {
#if defined(WITH_HTML_LOGS)
std::string reactionString(index_t j);
void printInfo();
void printInfo(int loglevel);
#else
inline std::string reactionString(index_t j) { return std::string(""); }
inline void printInfo() {}
inline void printInfo(int loglevel) {}
#endif
void setInitialMixMoles() {
setInitialMoles();
void setInitialMixMoles(int loglevel = 0) {
setInitialMoles(loglevel);
finish();
}
@ -78,12 +78,12 @@ namespace Cantera {
protected:
void getComponents(const vector_int& order);
int setInitialMoles();
int setInitialMoles(int loglevel = 0);
void computeN();
doublereal stepComposition();
doublereal stepComposition(int loglevel = 0);
//void sort(vector_fp& x);
void unsort(vector_fp& x);
void step(doublereal omega, vector_fp& deltaN);
void step(doublereal omega, vector_fp& deltaN, int loglevel = 0);
doublereal computeReactionSteps(vector_fp& dxi);
void updateMixMoles();
void finish();

View file

@ -23,35 +23,42 @@ namespace Cantera {
doublereal equilibrate(MultiPhase& s, const char* XY,
doublereal tol, int maxsteps, int maxiter,
int loglevel) {
if (loglevel > 0) {
beginLogGroup("equilibrate",loglevel);
addLogEntry("multiphase equilibrate function");
beginLogGroup("arguments");
addLogEntry("XY",XY);
addLogEntry("tol",tol);
addLogEntry("maxsteps",maxsteps);
addLogEntry("maxiter",maxiter);
addLogEntry("loglevel",loglevel);
endLogGroup("arguments");
}
s.init();
int ixy = _equilflag(XY);
if (ixy == TP || ixy == HP || ixy == SP || ixy == TV) {
try {
double err = s.equilibrate(ixy, tol, maxsteps, maxiter, loglevel);
if (loglevel > 0) {
addLogEntry("Success. Error",err);
endLogGroup("equilibrate");
beginLogGroup("equilibrate",loglevel);
addLogEntry("multiphase equilibrate function");
beginLogGroup("arguments");
addLogEntry("XY",XY);
addLogEntry("tol",tol);
addLogEntry("maxsteps",maxsteps);
addLogEntry("maxiter",maxiter);
addLogEntry("loglevel",loglevel);
endLogGroup("arguments");
s.init();
int ixy = _equilflag(XY);
if (ixy == TP || ixy == HP || ixy == SP || ixy == TV) {
try {
double err = s.equilibrate(ixy, tol, maxsteps, maxiter);
addLogEntry("Success. Error",err);
endLogGroup("equilibrate");
return err;
}
return err;
}
catch (CanteraError e) {
if (loglevel > 0) {
addLogEntry("Failure.",lastErrorMessage());
endLogGroup("equilibrate");
}
throw e;
}
}
catch (CanteraError e) {
addLogEntry("Failure.",lastErrorMessage());
endLogGroup("equilibrate");
throw e;
}
}
else {
addLogEntry("multiphase equilibrium can be done only for TP, HP, SP, or TV");
endLogGroup("equilibrate");
else {
if (loglevel > 0) {
addLogEntry("multiphase equilibrium can be done only for TP, HP, SP, or TV");
endLogGroup("equilibrate");
}
throw CanteraError("equilibrate","unsupported option");
return -1.0;
}
@ -97,18 +104,20 @@ namespace Cantera {
int nAttempts = 0;
int retnSub = 0;
beginLogGroup("equilibrate", loglevel);
addLogEntry("Single-phase equilibrate function");
{
beginLogGroup("arguments");
addLogEntry("phase",s.id());
addLogEntry("XY",XY);
addLogEntry("solver",solver);
addLogEntry("rtol",rtol);
addLogEntry("maxsteps",maxsteps);
addLogEntry("maxiter",maxiter);
addLogEntry("loglevel",loglevel);
endLogGroup("arguments");
if (loglevel > 0) {
beginLogGroup("equilibrate", loglevel);
addLogEntry("Single-phase equilibrate function");
{
beginLogGroup("arguments");
addLogEntry("phase",s.id());
addLogEntry("XY",XY);
addLogEntry("solver",solver);
addLogEntry("rtol",rtol);
addLogEntry("maxsteps",maxsteps);
addLogEntry("maxiter",maxiter);
addLogEntry("loglevel",loglevel);
endLogGroup("arguments");
}
}
while (redo) {
if (solver > 0) {
@ -117,22 +126,27 @@ namespace Cantera {
m->addPhase(&s, 1.0);
m->init();
nAttempts++;
(void) equilibrate(*m, XY, rtol, maxsteps, maxiter, loglevel);
(void) equilibrate(*m, XY, rtol, maxsteps, maxiter, loglevel-1);
redo = false;
addLogEntry("MultiPhaseEquil solver succeeded.");
if (loglevel > 0)
addLogEntry("MultiPhaseEquil solver succeeded.");
delete m;
retn = nAttempts;
}
catch (CanteraError err) {
addLogEntry("MultiPhaseEquil solver failed.");
if (loglevel > 0)
addLogEntry("MultiPhaseEquil solver failed.");
delete m;
if (nAttempts < 2) {
addLogEntry("Trying single phase ChemEquil solver.");
if (loglevel > 0)
addLogEntry("Trying single phase ChemEquil solver.");
solver = -1;
} else {
endLogGroup("equilibrate");
throw err;
}
}
else {
if (loglevel > 0)
endLogGroup("equilibrate");
throw err;
}
}
}
else { // solver <= 0
@ -144,12 +158,14 @@ namespace Cantera {
e->options.maxIterations = maxsteps;
e->options.relTolerance = rtol;
nAttempts++;
retnSub = e->equilibrate(s,XY);
retnSub = e->equilibrate(s,XY,loglevel-1);
if (retnSub < 0) {
addLogEntry("ChemEquil solver failed.");
if (loglevel > 0)
addLogEntry("ChemEquil solver failed.");
if (nAttempts < 2) {
addLogEntry("Trying MultiPhaseEquil solver.");
solver = 1;
if (loglevel > 0)
addLogEntry("Trying MultiPhaseEquil solver.");
solver = 1;
} else {
throw CanteraError("equilibrate",
"Both equilibrium solvers failed");
@ -159,20 +175,24 @@ namespace Cantera {
s.setElementPotentials(e->elementPotentials());
redo = false;
delete e;
addLogEntry("ChemEquil solver succeeded.");
if (loglevel > 0)
addLogEntry("ChemEquil solver succeeded.");
}
catch (CanteraError err) {
delete e;
addLogEntry("ChemEquil solver failed.");
if (loglevel > 0)
addLogEntry("ChemEquil solver failed.");
// If ChemEquil fails, try the MultiPhase solver
if (solver < 0) {
addLogEntry("Trying MultiPhaseEquil solver.");
if (loglevel > 0)
addLogEntry("Trying MultiPhaseEquil solver.");
solver = 1;
}
else {
redo = false;
endLogGroup("equilibrate");
if (loglevel > 0)
endLogGroup("equilibrate");
throw err;
}
}
@ -181,7 +201,8 @@ namespace Cantera {
/*
* We are here only for a success
*/
endLogGroup("equilibrate");
if (loglevel > 0)
endLogGroup("equilibrate");
return retn;
}
}

View file

@ -21,6 +21,9 @@
namespace Cantera {
FalloffFactory* FalloffFactory::s_factory = 0;
#if defined(THREAD_SAFE_CANTERA)
boost::mutex FalloffFactory::falloff_mutex ;
#endif
/**
* The 3-parameter Troe falloff parameterization.
@ -286,3 +289,4 @@ namespace Cantera {
}
}

View file

@ -20,6 +20,11 @@
#include "ct_defs.h"
#include "reaction_defs.h"
#include "FactoryBase.h"
#if defined(THREAD_SAFE_CANTERA)
#include <boost/thread/mutex.hpp>
#endif
namespace Cantera {
@ -87,7 +92,7 @@ namespace Cantera {
* @endcode
* @ingroup falloffGroup
*/
class FalloffFactory {
class FalloffFactory : public FactoryBase {
public:
/**
@ -97,23 +102,29 @@ namespace Cantera {
* to the existing factory is returned.
*/
static FalloffFactory* factory() {
#if defined(THREAD_SAFE_CANTERA)
boost::mutex::scoped_lock lock(falloff_mutex) ;
#endif
if (!s_factory) s_factory = new FalloffFactory;
return s_factory;
}
static void deleteFalloffFactory() {
if (s_factory) {
delete s_factory;
s_factory = 0;
}
}
virtual void deleteFactory() {
#if defined(THREAD_SAFE_CANTERA)
boost::mutex::scoped_lock lock(falloff_mutex) ;
#endif
if (s_factory) {
delete s_factory;
s_factory = 0;
}
}
/**
* Destructor doesn't do anything. We do not delete statically
* created single instance of this class here, because it would
* create an infinite loop if destructor is called for that
* single instance. Instead, to delete single instance, we
* call delete[] from FalloffMng's destructor.
* created single instance of this class here, because it would
* create an infinite loop if destructor is called for that
* single instance. Instead, to delete single instance, we
* call delete[] from FalloffMng's destructor.
*/
virtual ~FalloffFactory() {
}
@ -129,8 +140,12 @@ namespace Cantera {
private:
static FalloffFactory* s_factory;
FalloffFactory(){}
#if defined(THREAD_SAFE_CANTERA)
static boost::mutex falloff_mutex ;
#endif
};
}
#endif

View file

@ -30,10 +30,12 @@ namespace Cantera {
* falloff function calculators. If omitted, the standard factory
* will be used.
*/
FalloffMgr(FalloffFactory* f = 0) :
m_n(0), m_n0(0), m_worksize(0) {
if (f == 0) m_factory = FalloffFactory::factory();
else m_factory = f;
FalloffMgr(/*FalloffFactory* f = 0*/) :
m_n(0), m_n0(0), m_worksize(0) {
//if (f == 0)
m_factory = FalloffFactory::factory(); // RFB:TODO This raw pointer should be encapsulated
// because accessing a 'Singleton Factory'
//else m_factory = f;
}
/**
@ -43,10 +45,10 @@ namespace Cantera {
virtual ~FalloffMgr(){
int i;
for (i = 0; i < m_n; i++) delete m_falloff[i];
if (m_factory) {
FalloffFactory::deleteFalloffFactory();
m_factory = 0;
}
//if (m_factory) {
//FalloffFactory::deleteFalloffFactory();
//m_factory = 0;
//}
}
/**
@ -58,7 +60,7 @@ namespace Cantera {
* @param c vector of coefficients for the falloff function.
*/
void install(int rxn, int type,
const vector_fp& c) {
const vector_fp& c) {
if (type != SIMPLE_FALLOFF) {
m_rxn.push_back(rxn);
Falloff* f = m_factory->newFalloff(type,c);
@ -121,3 +123,4 @@ namespace Cantera {
}
#endif

View file

@ -28,6 +28,9 @@ using namespace std;
namespace Cantera {
KineticsFactory* KineticsFactory::s_factory = 0;
#if defined(THREAD_SAFE_CANTERA)
boost::mutex KineticsFactory::kinetics_mutex ;
#endif
static int ntypes = 5;
static string _types[] = {"none", "GasKinetics", "GRI30", "Interface", "Edge"};
@ -58,28 +61,28 @@ namespace Cantera {
Kinetics* KineticsFactory::
newKinetics(XML_Node& phaseData, vector<ThermoPhase*> th) {
/*
* Look for a child of the xml element phase called
* "kinetics". It has an attribute name "model".
* Store the value of that attribute in the variable kintype
*/
/*
* Look for a child of the xml element phase called
* "kinetics". It has an attribute name "model".
* Store the value of that attribute in the variable kintype
*/
string kintype = phaseData.child("kinetics")["model"];
/*
* look up the string kintype in the list of known
* kinetics managers (list is kept at the top of this file).
* Translate it to an integer value, ikin.
*/
/*
* look up the string kintype in the list of known
* kinetics managers (list is kept at the top of this file).
* Translate it to an integer value, ikin.
*/
int ikin=-1;
int n;
for (n = 0; n < ntypes; n++) {
if (kintype == _types[n]) ikin = _itypes[n];
if (kintype == _types[n]) ikin = _itypes[n];
}
/*
* Assign the kinetics manager based on the value of ikin.
* Kinetics managers are classes derived from the base
* Kinetics class. Unknown kinetics managers will throw a
* CanteraError here.
*/
/*
* Assign the kinetics manager based on the value of ikin.
* Kinetics managers are classes derived from the base
* Kinetics class. Unknown kinetics managers will throw a
* CanteraError here.
*/
Kinetics* k=0;
switch (ikin) {
@ -104,8 +107,8 @@ namespace Cantera {
break;
default:
throw UnknownKineticsModel("KineticsFactory::newKinetics",
kintype);
throw UnknownKineticsModel("KineticsFactory::newKinetics",
kintype);
}
// Now that we have the kinetics manager, we can
@ -143,10 +146,11 @@ namespace Cantera {
break;
default:
throw UnknownKineticsModel("KineticsFactory::newKinetics",
model);
throw UnknownKineticsModel("KineticsFactory::newKinetics",
model);
}
return k;
}
}

View file

@ -16,35 +16,53 @@
#include "Kinetics.h"
#include "xml.h"
#include "FactoryBase.h"
#if defined(THREAD_SAFE_CANTERA)
#include <boost/thread/mutex.hpp>
#endif
namespace Cantera {
class UnknownKineticsModel : public CanteraError {
public:
UnknownKineticsModel(std::string proc, std::string kineticsModel) :
CanteraError(proc, "Specified Kinetics model "
+ kineticsModel +
" does not match any known type.") {}
virtual ~UnknownKineticsModel() {}
UnknownKineticsModel(std::string proc, std::string kineticsModel) :
CanteraError(proc, "Specified Kinetics model "
+ kineticsModel +
" does not match any known type.") {}
virtual ~UnknownKineticsModel() {}
};
/**
* Factory for kinetics managers.
*/
class KineticsFactory {
class KineticsFactory : public FactoryBase {
public:
static KineticsFactory* factory() {
#if defined(THREAD_SAFE_CANTERA)
boost::mutex::scoped_lock lock(kinetics_mutex) ;
#endif
if (!s_factory) s_factory = new KineticsFactory;
return s_factory;
}
virtual ~KineticsFactory() {
delete s_factory;
s_factory = 0;
//delete s_factory;
//s_factory = 0;
}
virtual void deleteFactory() {
#if defined(THREAD_SAFE_CANTERA)
boost::mutex::scoped_lock lock(kinetics_mutex) ;
#endif
if ( s_factory ) {
delete s_factory ;
s_factory = 0 ;
}
}
/**
@ -59,6 +77,9 @@ namespace Cantera {
static KineticsFactory* s_factory;
KineticsFactory(){}
#if defined(THREAD_SAFE_CANTERA)
static boost::mutex kinetics_mutex ;
#endif
};
@ -89,3 +110,4 @@ namespace Cantera {
#endif

View file

@ -25,6 +25,7 @@
#include "importKinetics.h"
#include "mix_defs.h"
#include <time.h>
#include <memory>
// Cantera includes
#include "speciesThermoTypes.h"
@ -45,36 +46,47 @@
using namespace ctml;
using namespace std;
namespace Cantera {
//! these are all used to check for duplicate reactions
class rxninfo {
public:
//! rdata
std::vector< std::map<int, doublereal> > rdata;
std::vector< std::map<int, doublereal> > m_rdata;
//! string name
std::vector<std::string> eqn;
std::vector<std::string> m_eqn;
//! string vector of ints
std::vector<int> dup;
std::vector<int> m_dup;
//! string vector of ints
std::vector<int> nr;
std::vector<int> m_nr;
//! string vector of ints
std::vector<int> typ;
std::vector<int> m_typ;
//! vector of bools.
std::vector<bool> rev;
std::vector<bool> m_rev;
~rxninfo() {
m_eqn.clear();
m_dup.clear();
m_nr.clear();
m_typ.clear();
m_rdata.clear();
}
bool installReaction(int i, const XML_Node& r, Kinetics* k,
std::string default_phase, int rule,
bool validate_rxn) ;
};
//! Temporary storage of rxninfo
rxninfo* _rxns = 0;
//rxninfo* _rxns = 0;
//! @name utilitydefines.
//@{
#define _reactiondata _rxns->rdata
#define _eqn _rxns->eqn
#define _dup _rxns->dup
#define _nr _rxns->nr
#define _typ _rxns->typ
#define _rev _rxns->rev
#define _reactiondata m_rdata
#define _eqn m_eqn
#define _dup m_dup
#define _nr m_nr
#define _typ m_typ
#define _rev m_rev
//@}
namespace Cantera {
/*
* First we define a couple of typedefs that will
@ -588,7 +600,7 @@ namespace Cantera {
*
* @ingroup kineticsmgr
*/
static bool installReaction(int i, const XML_Node& r, Kinetics* k,
bool rxninfo::installReaction(int i, const XML_Node& r, Kinetics* k,
string default_phase, int rule,
bool validate_rxn) {
@ -732,12 +744,12 @@ namespace Cantera {
string msg = string("Undeclared duplicate reactions detected: \n")
+"Reaction "+int2str(nn+1)+": "+_eqn[nn]
+"\nReaction "+int2str(i+1)+": "+eqn+"\n";
_reactiondata.clear();
_eqn.clear();
_rev.clear();
_nr.clear();
_typ.clear();
_dup.clear();
//_reactiondata.clear();
//_eqn.clear();
//_rev.clear();
//_nr.clear();
//_typ.clear();
//_dup.clear();
throw CanteraError("installReaction",msg);
}
}
@ -795,15 +807,16 @@ namespace Cantera {
bool installReactionArrays(const XML_Node& p, Kinetics& kin,
std::string default_phase, bool check_for_duplicates) {
if (_rxns == 0) {
_rxns = new rxninfo;
}
_eqn.clear();
_dup.clear();
_nr.clear();
_typ.clear();
_reactiondata.clear();
_rev.clear();
std::auto_ptr< rxninfo > _rxns( new rxninfo ) ;
//if (_rxns == 0) {
//_rxns = new rxninfo;
//}
//_eqn.clear();
//_dup.clear();
//_nr.clear();
//_typ.clear();
//_reactiondata.clear();
//_rev.clear();
vector<XML_Node*> rarrays;
int itot = 0;
@ -870,7 +883,7 @@ namespace Cantera {
for (i = 0; i < nrxns; i++) {
const XML_Node* r = allrxns[i];
if (r) {
if (installReaction(itot, *r, &kin,
if (_rxns->installReaction(itot, *r, &kin,
default_phase, rxnrule, check_for_duplicates)) ++itot;
}
}
@ -904,7 +917,7 @@ namespace Cantera {
* sometimes has surprising results.
*/
if ((rxid >= imin) && (rxid <= imax)) {
if (installReaction(itot, *r, &kin,
if (_rxns->installReaction(itot, *r, &kin,
default_phase, rxnrule, check_for_duplicates)) ++itot;
}
}
@ -919,13 +932,13 @@ namespace Cantera {
*/
kin.finalize();
//writer = 0;
_eqn.clear();
_dup.clear();
_nr.clear();
_typ.clear();
_reactiondata.clear();
delete _rxns;
_rxns = 0;
//_eqn.clear();
//_dup.clear();
//_nr.clear();
//_typ.clear();
//_reactiondata.clear();
//delete _rxns;
//_rxns = 0;
return true;
}

View file

@ -36,6 +36,10 @@ using namespace ctml;
namespace Cantera {
SpeciesThermoFactory* SpeciesThermoFactory::s_factory = 0;
#if defined(THREAD_SAFE_CANTERA)
boost::mutex SpeciesThermoFactory::species_thermo_mutex ;
#endif
/**
* Examine the types of species thermo parameterizations,
@ -48,8 +52,8 @@ namespace Cantera {
* @todo Make sure that spDadta_node is species Data XML node by checking its name is speciesData
*/
static void getSpeciesThermoTypes(XML_Node* spData_node,
int& has_nasa, int& has_shomate, int& has_simple,
int &has_other) {
int& has_nasa, int& has_shomate, int& has_simple,
int &has_other) {
const XML_Node& sparray = *spData_node;
std::vector<XML_Node*> sp;
@ -59,19 +63,19 @@ namespace Cantera {
for (n = 0; n < ns; n++) {
XML_Node* spNode = sp[n];
if (spNode->hasChild("thermo")) {
const XML_Node& th = sp[n]->child("thermo");
if (th.hasChild("NASA")) has_nasa = 1;
if (th.hasChild("Shomate")) has_shomate = 1;
if (th.hasChild("const_cp")) has_simple = 1;
if (th.hasChild("poly")) {
if (th.child("poly")["order"] == "1") has_simple = 1;
else throw CanteraError("newSpeciesThermo",
"poly with order > 1 not yet supported");
}
if (th.hasChild("Mu0")) has_other = 1;
const XML_Node& th = sp[n]->child("thermo");
if (th.hasChild("NASA")) has_nasa = 1;
if (th.hasChild("Shomate")) has_shomate = 1;
if (th.hasChild("const_cp")) has_simple = 1;
if (th.hasChild("poly")) {
if (th.child("poly")["order"] == "1") has_simple = 1;
else throw CanteraError("newSpeciesThermo",
"poly with order > 1 not yet supported");
}
if (th.hasChild("Mu0")) has_other = 1;
} else {
throw UnknownSpeciesThermoModel("getSpeciesThermoTypes:",
spNode->attrib("name"), "missing");
throw UnknownSpeciesThermoModel("getSpeciesThermoTypes:",
spNode->attrib("name"), "missing");
}
}
}
@ -94,7 +98,7 @@ namespace Cantera {
return new GeneralSpeciesThermo();
}
return newSpeciesThermo(NASA*inasa
+ SHOMATE*ishomate + SIMPLE*isimple);
+ SHOMATE*ishomate + SIMPLE*isimple);
}
SpeciesThermo* SpeciesThermoFactory::
@ -103,17 +107,17 @@ namespace Cantera {
int inasa = 0, ishomate = 0, isimple = 0, iother = 0;
for (int j = 0; j < n; j++) {
try {
getSpeciesThermoTypes(spData_nodes[j], inasa, ishomate, isimple, iother);
getSpeciesThermoTypes(spData_nodes[j], inasa, ishomate, isimple, iother);
} catch (UnknownSpeciesThermoModel) {
iother = 1;
popError();
iother = 1;
popError();
}
}
if (iother) {
return new GeneralSpeciesThermo();
}
return newSpeciesThermo(NASA*inasa
+ SHOMATE*ishomate + SIMPLE*isimple);
+ SHOMATE*ishomate + SIMPLE*isimple);
}
@ -126,17 +130,17 @@ namespace Cantera {
int inasa = 0, ishomate = 0, isimple = 0, iother = 0;
for (int j = 0; j < n; j++) {
try {
getSpeciesThermoTypes(nodes[j], inasa, ishomate, isimple, iother);
getSpeciesThermoTypes(nodes[j], inasa, ishomate, isimple, iother);
} catch (UnknownSpeciesThermoModel) {
iother = 1;
popError();
iother = 1;
popError();
}
}
if (iother) {
return new GeneralSpeciesThermo();
}
return newSpeciesThermo(NASA*inasa
+ SHOMATE*ishomate + SIMPLE*isimple);
+ SHOMATE*ishomate + SIMPLE*isimple);
}
@ -158,7 +162,7 @@ namespace Cantera {
return new SpeciesThermoDuo<ShomateThermo, SimpleThermo>;
default:
throw UnknownSpeciesThermo(
"SpeciesThermoFactory::newSpeciesThermo",type);
"SpeciesThermoFactory::newSpeciesThermo",type);
return 0;
}
}
@ -169,7 +173,7 @@ namespace Cantera {
* temperature.
*/
void NasaThermo::checkContinuity(std::string name, double tmid, const doublereal* clow,
doublereal* chigh) {
doublereal* chigh) {
// heat capacity
doublereal cplow = poly4(tmid, clow);
@ -269,7 +273,7 @@ namespace Cantera {
}
else {
throw CanteraError("installNasaThermo",
"non-continuous temperature ranges.");
"non-continuous temperature ranges.");
}
// The NasaThermo species property manager expects the
@ -331,7 +335,7 @@ namespace Cantera {
}
else {
throw CanteraError("installNasaThermo",
"non-continuous temperature ranges.");
"non-continuous temperature ranges.");
}
array_fp c(15);
c[0] = tmid;
@ -378,9 +382,9 @@ namespace Cantera {
if (dualRange)
getFloatArray(f1ptr->child("floatArray"), c1, false);
else {
c1.resize(7,0.0);
copy(c0.begin(), c0.begin()+7, c1.begin());
}
c1.resize(7,0.0);
copy(c0.begin(), c0.begin()+7, c1.begin());
}
}
else if (fabs(tmax1 - tmin0) < 0.01) {
tmin = tmin1;
@ -391,7 +395,7 @@ namespace Cantera {
}
else {
throw CanteraError("installShomateThermo",
"non-continuous temperature ranges.");
"non-continuous temperature ranges.");
}
array_fp c(15);
c[0] = tmid;
@ -434,18 +438,18 @@ namespace Cantera {
void SpeciesThermoFactory::
installThermoForSpecies(int k, const XML_Node& s,
SpeciesThermo& spthermo) {
/*
* Check to see that the species block has a thermo block
* before processing. Throw an error if not there.
*/
if (!(s.hasChild("thermo"))) {
throw UnknownSpeciesThermoModel("installSpecies",
s["name"], "<nonexistent>");
}
const XML_Node& thermo = s.child("thermo");
const std::vector<XML_Node*>& tp = thermo.children();
int nc = static_cast<int>(tp.size());
if (nc == 1) {
/*
* Check to see that the species block has a thermo block
* before processing. Throw an error if not there.
*/
if (!(s.hasChild("thermo"))) {
throw UnknownSpeciesThermoModel("installSpecies",
s["name"], "<nonexistent>");
}
const XML_Node& thermo = s.child("thermo");
const std::vector<XML_Node*>& tp = thermo.children();
int nc = static_cast<int>(tp.size());
if (nc == 1) {
const XML_Node* f = tp[0];
if (f->name() == "Shomate") {
installShomateThermoFromXML(s["name"], spthermo, k, f, 0);
@ -456,15 +460,15 @@ namespace Cantera {
else if (f->name() == "NASA") {
installNasaThermoFromXML(s["name"], spthermo, k, f, 0);
}
else if (f->name() == "Mu0") {
installMu0ThermoFromXML(s["name"], spthermo, k, f);
}
else if (f->name() == "Mu0") {
installMu0ThermoFromXML(s["name"], spthermo, k, f);
}
else {
throw UnknownSpeciesThermoModel("installSpecies",
s["name"], f->name());
s["name"], f->name());
}
}
else if (nc == 2) {
}
else if (nc == 2) {
const XML_Node* f0 = tp[0];
const XML_Node* f1 = tp[1];
if (f0->name() == "NASA" && f1->name() == "NASA") {
@ -475,14 +479,16 @@ namespace Cantera {
}
else {
throw UnknownSpeciesThermoModel("installSpecies", s["name"],
f0->name() + " and "
+ f1->name());
f0->name() + " and "
+ f1->name());
}
}
else {
throw UnknownSpeciesThermoModel("installSpecies", s["name"],
"multiple");
}
}
else {
throw UnknownSpeciesThermoModel("installSpecies", s["name"],
"multiple");
}
}
}

View file

@ -19,6 +19,8 @@
#include "SpeciesThermo.h"
#include "ctexceptions.h"
#include "FactoryBase.h"
namespace Cantera {
@ -59,7 +61,7 @@ namespace Cantera {
*
* @ingroup thermoprops
*/
class SpeciesThermoFactory {
class SpeciesThermoFactory : public FactoryBase {
public:
@ -73,6 +75,9 @@ namespace Cantera {
* instance.
*/
static SpeciesThermoFactory* factory() {
#if defined(THREAD_SAFE_CANTERA)
boost::mutex::scoped_lock lock(species_thermo_mutex);
#endif
if (!s_factory) s_factory = new SpeciesThermoFactory;
return s_factory;
}
@ -83,7 +88,10 @@ namespace Cantera {
* the process terminates (for example, when checking for
* memory leaks) then this method can be called to delete it.
*/
static void deleteFactory() {
virtual void deleteFactory() {
#if defined(THREAD_SAFE_CANTERA)
boost::mutex::scoped_lock lock(species_thermo_mutex);
#endif
if (s_factory) {
delete s_factory;
s_factory = 0;
@ -154,6 +162,10 @@ namespace Cantera {
//! pointer to the sole instance of this class
static SpeciesThermoFactory* s_factory;
#if defined(THREAD_SAFE_CANTERA)
static boost::mutex species_thermo_mutex;
#endif
//! Constructor. This is made private, so that only the static
//! method factory() can instantiate the class.
SpeciesThermoFactory(){}

View file

@ -62,6 +62,9 @@ using namespace std;
namespace Cantera {
ThermoFactory* ThermoFactory::s_factory = 0;
#if defined(THREAD_SAFE_CANTERA)
boost::mutex ThermoFactory::thermo_mutex;
#endif
static int ntypes = 10;
static string _types[] = {"IdealGas", "Incompressible",

View file

@ -19,10 +19,17 @@
#include "ThermoPhase.h"
#include "xml.h"
#include "SpeciesThermoFactory.h"
#if defined(THREAD_SAFE_CANTERA)
#include <boost/thread/mutex.hpp>
#endif
//#include "SpeciesThermoFactory.h"
#include "FactoryBase.h"
namespace Cantera {
class SpeciesThermoFactory;
/*!
* @addtogroup thermoprops
@ -55,33 +62,38 @@ namespace Cantera {
//! Factory class for thermodynamic property managers.
/*!
* This class keeps a list of the known ThermoPhase classes, and is used
* to create new instances of these classes.
* This class keeps a list of the known ThermoPhase classes, and is
* used to create new instances of these classes.
*/
class ThermoFactory {
class ThermoFactory : public FactoryBase {
public:
//! Static function that creates a static instance of the factor.
//! Static function that creates a static instance of the factory.
static ThermoFactory* factory() {
#if defined(THREAD_SAFE_CANTERA)
boost::mutex::scoped_lock lock(thermo_mutex);
#endif
if (!s_factory) s_factory = new ThermoFactory;
return s_factory;
}
//! delete the static instance of this factory
static void deleteFactory() {
if (s_factory) {
delete s_factory;
s_factory = 0;
}
//! delete the static instance of this factory
virtual void deleteFactory() {
#if defined(THREAD_SAFE_CANTERA)
boost::mutex::scoped_lock lock(thermo_mutex);
#endif
if (s_factory) {
delete s_factory;
s_factory = 0;
}
}
//! Destructor doesn't do anything.
/*!
* We do not delete statically
* created single instance of this class here, because it would
* create an infinite loop if destructor is called for that
* single instance.
* We do not delete statically created single instance of this
* class here, because it would create an infinite loop if
* destructor is called for that single instance.
*/
virtual ~ThermoFactory() { }
@ -103,6 +115,11 @@ namespace Cantera {
//! Private constructor prevents usage
ThermoFactory(){}
#if defined(THREAD_SAFE_CANTERA)
static boost::mutex thermo_mutex;
#endif
};
//! Create a new thermo manager instance.

View file

@ -46,6 +46,9 @@ using namespace std;
namespace Cantera {
TransportFactory* TransportFactory::s_factory = 0;
#if defined(THREAD_SAFE_CANTERA)
boost::mutex TransportFactory::transport_mutex;
#endif
////////////////////////// exceptions /////////////////////////
@ -259,20 +262,23 @@ namespace Cantera {
* explicitly deleted.
*/
TransportFactory::~TransportFactory() {
if (m_integrals) {
if (m_integrals) {
delete m_integrals;
m_integrals = 0;
}
}
}
/**
* This static function deletes the statically allocated instance.
*/
void TransportFactory::deleteTransportFactory() {
if (s_factory) {
delete s_factory;
s_factory = 0;
}
void TransportFactory::deleteFactory() {
#if defined(THREAD_SAFE_CANTERA)
boost::mutex::scoped_lock lock(transport_mutex) ;
#endif
if (s_factory) {
delete s_factory;
s_factory = 0;
}
}
/**
@ -527,7 +533,7 @@ namespace Cantera {
tr.astar_poly.push_back(ca);
tr.bstar_poly.push_back(cb);
tr.cstar_poly.push_back(cc);
tr.poly[i][j] = static_cast<int>(tr.astar_poly.size()) - 1;
tr.poly[i][j] = static_cast<int>(tr.astar_poly.size()) - 1;
tr.fitlist.push_back(dstar);
}
@ -990,3 +996,4 @@ namespace Cantera {
tr.xml->XML_close(logfile, "binary_diffusion_coefficients");
}
}

View file

@ -35,6 +35,11 @@ using namespace std;
// Cantera includes
#include "ct_defs.h"
#include "TransportBase.h"
#include "FactoryBase.h"
#if defined(THREAD_SAFE_CANTERA)
#include <boost/thread/mutex.hpp>
#endif
namespace Cantera {
@ -43,11 +48,11 @@ namespace Cantera {
*/
struct GasTransportData {
GasTransportData() : speciesName("-"),
geometry(-1), wellDepth(-1.0),
diameter(-1.0),
dipoleMoment(-1.0),
polarizability(-1.0),
rotRelaxNumber(-1.0) {}
geometry(-1), wellDepth(-1.0),
diameter(-1.0),
dipoleMoment(-1.0),
polarizability(-1.0),
rotRelaxNumber(-1.0) {}
string speciesName;
int geometry;
@ -73,7 +78,7 @@ namespace Cantera {
* created in other ways. @ingroup transportgroup
* @ingroup transportProps
*/
class TransportFactory {
class TransportFactory : FactoryBase {
public:
@ -91,27 +96,30 @@ namespace Cantera {
* @endcode
*/
static TransportFactory* factory() {
if (!s_factory) {
s_factory = new TransportFactory();
}
#if defined(THREAD_SAFE_CANTERA)
boost::mutex::scoped_lock lock(transport_mutex) ;
#endif
if (!s_factory) {
s_factory = new TransportFactory();
}
return s_factory;
}
/**
* Deletes the statically malloced instance.
*/
static void deleteTransportFactory();
/**
* Deletes the statically malloced instance.
*/
virtual void deleteFactory();
/**
* Destructor
*
* We do not delete statically
* created single instance of this class here, because it would
* create an infinite loop if destructor is called for that
* single instance.
*
* We do not delete statically
* created single instance of this class here, because it would
* create an infinite loop if destructor is called for that
* single instance.
*/
virtual ~TransportFactory();
/// Build a new transport manager
virtual Transport*
@ -125,6 +133,9 @@ namespace Cantera {
private:
static TransportFactory* s_factory;
#if defined(THREAD_SAFE_CANTERA)
static boost::mutex transport_mutex ;
#endif
// The constructor is private; use static method factory() to
// get a pointer to a factory instance
@ -190,14 +201,14 @@ namespace Cantera {
f = TransportFactory::factory();
}
Transport* ptr = f->newTransport(transportModel, thermo, loglevel);
/*
* Note: We delete the static s_factory instance here, instead of in
* appdelete() in misc.cpp, to avoid linking problems involving
* the need for multiple cantera and transport library statements
* for applications that don't have transport in them.
*/
TransportFactory::deleteTransportFactory();
return ptr;
/*
* Note: We delete the static s_factory instance here, instead of in
* appdelete() in misc.cpp, to avoid linking problems involving
* the need for multiple cantera and transport library statements
* for applications that don't have transport in them.
*/
//TransportFactory::deleteFactory();
return ptr;
}
@ -209,3 +220,4 @@ namespace Cantera {

View file

@ -26,7 +26,7 @@ ZEROD_H = Reactor.h ReactorBase.h FlowDevice.h Wall.h ReactorNet.h \
flowControllers.h PID_Controller.h Reservoir.h FlowReactor.h \
ConstPressureReactor.h ReactorFactory.h
CXX_INCLUDES = -I../base -I../thermo -I../kinetics -I../numerics
CXX_INCLUDES = -I../base -I../thermo -I../kinetics -I../numerics @CXX_INCLUDES@
ZEROD_LIB = @buildlib@/libzeroD.a
DEPENDS = $(OBJS:.o=.d)

View file

@ -26,6 +26,9 @@ using namespace std;
namespace CanteraZeroD {
ReactorFactory* ReactorFactory::s_factory = 0;
#ifdef THREAD_SAFE_CANTERA
boost::mutex ReactorFactory::reactor_mutex ;
#endif
static int ntypes = 4;
static string _types[] = {"Reservoir", "Reactor", "ConstPressureReactor",
@ -67,3 +70,4 @@ namespace CanteraZeroD {
}
}

View file

@ -15,27 +15,38 @@
#define REACTOR_FACTORY_H
#include "ReactorBase.h"
#include "FactoryBase.h"
#if defined(THREAD_SAFE_CANTERA)
#include <boost/thread/mutex.hpp>
#endif
namespace CanteraZeroD {
class ReactorFactory {
class ReactorFactory : FactoryBase {
public:
static ReactorFactory* factory() {
#if defined(THREAD_SAFE_CANTERA)
boost::mutex::scoped_lock lock(reactor_mutex) ;
#endif
if (!s_factory) s_factory = new ReactorFactory;
return s_factory;
}
static void deleteFactory() {
if (s_factory) {
delete s_factory;
s_factory = 0;
}
}
virtual void deleteFactory() {
#if defined(THREAD_SAFE_CANTERA)
boost::mutex::scoped_lock lock(reactor_mutex) ;
#endif
if (s_factory) {
delete s_factory;
s_factory = 0;
}
}
/**
/**
* Destructor doesn't do anything.
*/
virtual ~ReactorFactory() {}
@ -50,6 +61,9 @@ namespace CanteraZeroD {
private:
static ReactorFactory* s_factory;
#if defined(THREAD_SAFE_CANTERA)
static boost::mutex reactor_mutex ;
#endif
ReactorFactory(){}
};
@ -66,3 +80,4 @@ namespace CanteraZeroD {
#endif

View file

@ -100,7 +100,7 @@ typedef int ftnlen; // Fortran hidden string length type
#undef CANTERA_DATA
#define WITH_HTML_LOGS
#undef WITH_HTML_LOGS
// define STORE_MOLE_FRACTIONS if you want Cantera to internally
// represent the composition of a mixture as mole fractions. Usually
@ -116,6 +116,8 @@ typedef int ftnlen; // Fortran hidden string length type
//--------------------- compile options ----------------------------
#undef USE_PCH
#define THREAD_SAFE_CANTERA
//--------------------- optional phase models ----------------------
// This define indicates the enabling of the inclusion of
// accurate liquid/vapor equations

51
configure vendored
View file

@ -308,7 +308,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS BITCOMPILE BITHARDWARE BITCHANGE ldemulationarg CVF_LIBDIR USE_CLIB_DLL local_inst local_python_inst python_prefix python_win_prefix ctversion homedir ct_libdir ct_bindir ct_incdir ct_incroot ct_datadir ct_demodir ct_templdir ct_tutdir ct_docdir ct_dir ct_mandir COMPACT_INSTALL build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os username ctroot buildinc buildlib buildbin MAKE GRAPHVIZDIR ARCHIVE DO_RANLIB RANLIB CXX_DEPENDS USERDIR INCL_USER_CODE CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT use_sundials CVODE_LIBS IDA_LIBS sundials_include CANTERA_DEBUG_MODE COMPILE_PURE_FLUIDS phase_object_files phase_header_files COMPILE_IDEAL_SOLUTIONS COMPILE_ELECTROLYTES NEED_CATHERMO COMPILE_KINETICS COMPILE_HETEROKIN COMPILE_RXNPATH WITH_REACTORS KERNEL KERNEL_OBJ BUILD_CK LIB_DIR build_lapack build_blas BLAS_LAPACK_LIBS BLAS_LAPACK_DIR build_with_f2c build_f2c_lib LOCAL_LIB_DIRS LOCAL_LIBS CT_SHARED_LIB PYTHON_CMD BUILD_PYTHON NUMARRAY_INC_DIR NUMARRAY_HOME CANTERA_PYTHON_HOME CVSTAG MATLAB_CMD BUILD_MATLAB BUILD_CLIB export_name INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CC CFLAGS ac_ct_CC CXXCPP EGREP SOEXT SHARED PIC CXX_INCLUDES LCXX_FLAGS LCXX_END_LIBS HAVE_STRIPSYMBOLS F77 FFLAGS ac_ct_F77 F90 BUILD_F90 F90FLAGS F90BUILDFLAGS precompile_headers FLIBS OS_IS_DARWIN OS_IS_WIN OS_IS_CYGWIN SHARED_CTLIB mex_ext F77_EXT CXX_EXT OBJ_EXT EXE_EXT math_libs SO LDSHARED EXTRA_LINK TSCOMPARE_abs INSTALL_abs INSTALL_VERBOSE LIBOBJS LTLIBOBJS'
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS BITCOMPILE BITHARDWARE BITCHANGE ldemulationarg CVF_LIBDIR USE_CLIB_DLL local_inst local_python_inst python_prefix python_win_prefix ctversion homedir ct_libdir ct_bindir ct_incdir ct_incroot ct_datadir ct_demodir ct_templdir ct_tutdir ct_docdir ct_dir ct_mandir COMPACT_INSTALL build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os username ctroot buildinc buildlib buildbin MAKE GRAPHVIZDIR ARCHIVE DO_RANLIB RANLIB CXX_DEPENDS USERDIR INCL_USER_CODE CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT use_sundials CVODE_LIBS IDA_LIBS sundials_include CANTERA_DEBUG_MODE COMPILE_PURE_FLUIDS phase_object_files phase_header_files COMPILE_IDEAL_SOLUTIONS COMPILE_ELECTROLYTES NEED_CATHERMO COMPILE_KINETICS COMPILE_HETEROKIN COMPILE_RXNPATH WITH_REACTORS KERNEL KERNEL_OBJ BUILD_CK LIB_DIR BOOST_INCLUDE BOOST_LIB build_lapack build_blas BLAS_LAPACK_LIBS BLAS_LAPACK_DIR build_with_f2c build_f2c_lib LOCAL_LIB_DIRS LOCAL_LIBS CT_SHARED_LIB PYTHON_CMD BUILD_PYTHON NUMARRAY_INC_DIR NUMARRAY_HOME CANTERA_PYTHON_HOME CVSTAG MATLAB_CMD BUILD_MATLAB BUILD_CLIB export_name INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CC CFLAGS ac_ct_CC CXXCPP EGREP SOEXT SHARED PIC CXX_INCLUDES LCXX_FLAGS LCXX_END_LIBS HAVE_STRIPSYMBOLS F77 FFLAGS ac_ct_F77 F90 BUILD_F90 F90FLAGS F90BUILDFLAGS precompile_headers FLIBS OS_IS_DARWIN OS_IS_WIN OS_IS_CYGWIN SHARED_CTLIB mex_ext F77_EXT CXX_EXT OBJ_EXT EXE_EXT math_libs SO LDSHARED EXTRA_LINK TSCOMPARE_abs INSTALL_abs INSTALL_VERBOSE LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@ -1705,6 +1705,7 @@ GRAPHVIZDIR=" "
fi
#----------- ARCHIVE --------------------
if test "x${OS_IS_DARWIN}" = "x1"; then
@ -2644,6 +2645,27 @@ fi
if test "$WITH_HTML_LOG_FILES" = "y"; then
cat >>confdefs.h <<\_ACEOF
#define WITH_HTML_LOGS 1
_ACEOF
fi
BOOST_INCLUDE=
BOOST_LIB=
if test "$BUILD_THREAD_SAFE" = "y" ; then
cat >>confdefs.h <<\_ACEOF
#define THREAD_SAFE_CANTERA 1
_ACEOF
BOOST_INCLUDE=-I$BOOST_INC_DIR
BOOST_LIB=$BOOST_THREAD_LIB
fi
#
# Report to the user what has been included/excluded from the compilation
#
@ -2655,6 +2677,11 @@ if test "$CANTERA_DEBUG_MODE" = "1" ; then
else
echo " Cantera Debug Mode = OFF"
fi
if test "$BUILD_THREAD_SAFE" = "y" ; then
echo " Thread Safe = YES"
else
echo " Thread Safe = NO"
fi
if test "$NEED_TRANSPORT" = "1" ; then
echo " Calculation of Transport Props = ON"
else
@ -2805,10 +2832,6 @@ fi
LOCAL_LIBS=$LOCAL_LIBS' '-lequil
if test -n "$NEED_CATHERMO"
then LOCAL_LIBS=$LOCAL_LIBS' '-lthermo
fi
if test -n "$COMPILE_KINETICS"
then LOCAL_LIBS=$LOCAL_LIBS' '-lkinetics
fi
@ -2817,6 +2840,10 @@ if test -n "$NEED_TRANSPORT"
then LOCAL_LIBS=$LOCAL_LIBS' '-ltransport
fi
if test -n "$NEED_CATHERMO"
then LOCAL_LIBS=$LOCAL_LIBS' '-lthermo
fi
LOCAL_LIBS=$LOCAL_LIBS' '-lctnumerics
if test -n "$NEED_CVODE"; then
@ -2859,6 +2886,12 @@ if test ${use_sundials} = 1; then
LOCAL_LIB_DIRS=$LOCAL_LIB_DIRS' -L'$SUNDIALS_LIB_DIR
fi
if test ${BUILD_THREAD_SAFE} = "y"; then
LOCAL_LIBS=$LOCAL_LIBS' '-l$BOOST_LIB
LOCAL_LIB_DIRS=$LOCAL_LIB_DIRS' -L'$BOOST_LIB_DIR
fi
@ -8178,6 +8211,7 @@ if test -z "$SHARED"; then SHARED='-shared'; fi
if test -z "$PIC"; then PIC='-fPIC'; fi
CXX_INCLUDES=$BOOST_INCLUDE
#
# LCXX_FLAGS: Flags that get attached to the CXX loader
@ -8339,7 +8373,7 @@ fi
# Provide some information about the compiler.
echo "$as_me:8342:" \
echo "$as_me:8376:" \
"checking for Fortran 77 compiler version" >&5
ac_compiler=`set X $ac_compile; echo $2`
{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
@ -8806,7 +8840,7 @@ fi
ac_config_files="$ac_config_files Makefile Cantera/Makefile Cantera/src/Makefile Cantera/src/base/Makefile Cantera/src/zeroD/Makefile Cantera/src/oneD/Makefile Cantera/src/converters/Makefile Cantera/src/transport/Makefile Cantera/src/thermo/Makefile Cantera/src/kinetics/Makefile Cantera/src/numerics/Makefile Cantera/src/equil/Makefile Cantera/clib/src/Makefile Cantera/fortran/src/Makefile Cantera/fortran/f77demos/f77demos.mak Cantera/fortran/f77demos/isentropic.dsp Cantera/matlab/Makefile Cantera/matlab/setup_matlab.py Cantera/matlab/setup_winmatlab.py Cantera/python/Makefile Cantera/python/setup.py Cantera/cxx/Makefile Cantera/cxx/src/Makefile Cantera/cxx/demos/Makefile Cantera/user/Makefile Cantera/python/src/Makefile ext/lapack/Makefile ext/blas/Makefile ext/cvode/Makefile ext/math/Makefile ext/recipes/Makefile ext/tpx/Makefile ext/Makefile ext/f2c_libs/Makefile ext/f2c_blas/Makefile ext/f2c_lapack/Makefile ext/f2c_math/Makefile examples/Makefile examples/cxx/Makefile tools/Makefile tools/doc/Cantera.cfg tools/doc/Makefile tools/src/Makefile tools/src/sample.mak tools/src/finish_install.py tools/src/package4mac tools/templates/f77/demo.mak tools/templates/f90/demo.mak tools/templates/cxx/demo.mak tools/testtools/Makefile data/inputs/Makefile test_problems/Makefile test_problems/cxx_ex/Makefile test_problems/silane_equil/Makefile test_problems/surfkin/Makefile test_problems/diamondSurf/Makefile test_problems/ChemEquil_gri_matrix/Makefile test_problems/ChemEquil_gri_pairs/Makefile test_problems/ChemEquil_ionizedGas/Makefile test_problems/ChemEquil_red1/Makefile test_problems/fracCoeff/Makefile test_problems/negATest/Makefile test_problems/ck2cti_test/Makefile test_problems/ck2cti_test/runtest test_problems/min_python/Makefile test_problems/min_python/minDiamond/Makefile test_problems/min_python/negATest/Makefile test_problems/pureFluidTest/Makefile test_problems/python/Makefile test_problems/cathermo/Makefile test_problems/cathermo/issp/Makefile test_problems/cathermo/ims/Makefile test_problems/cathermo/stoichSubSSTP/Makefile test_problems/cathermo/testIAPWS/Makefile test_problems/cathermo/testIAPWSPres/Makefile test_problems/cathermo/testIAPWSTripP/Makefile test_problems/cathermo/testWaterPDSS/Makefile test_problems/cathermo/testWaterTP/Makefile test_problems/cathermo/HMW_test_1/Makefile test_problems/cathermo/HMW_test_3/Makefile test_problems/cathermo/HMW_graph_GvT/Makefile test_problems/cathermo/HMW_graph_GvI/Makefile test_problems/cathermo/HMW_graph_HvT/Makefile test_problems/cathermo/HMW_graph_CpvT/Makefile test_problems/cathermo/HMW_graph_VvT/Makefile test_problems/cathermo/DH_graph_1/Makefile test_problems/cathermo/DH_graph_acommon/Makefile test_problems/cathermo/DH_graph_NM/Makefile test_problems/cathermo/DH_graph_Pitzer/Makefile test_problems/cathermo/DH_graph_bdotak/Makefile bin/install_tsc"
ac_config_files="$ac_config_files Makefile Cantera/Makefile Cantera/src/Makefile Cantera/src/app/Makefile Cantera/src/base/Makefile Cantera/src/zeroD/Makefile Cantera/src/oneD/Makefile Cantera/src/converters/Makefile Cantera/src/transport/Makefile Cantera/src/thermo/Makefile Cantera/src/kinetics/Makefile Cantera/src/numerics/Makefile Cantera/src/equil/Makefile Cantera/clib/src/Makefile Cantera/fortran/src/Makefile Cantera/fortran/f77demos/f77demos.mak Cantera/fortran/f77demos/isentropic.dsp Cantera/matlab/Makefile Cantera/matlab/setup_matlab.py Cantera/matlab/setup_winmatlab.py Cantera/python/Makefile Cantera/python/setup.py Cantera/cxx/Makefile Cantera/cxx/src/Makefile Cantera/cxx/demos/Makefile Cantera/user/Makefile Cantera/python/src/Makefile ext/lapack/Makefile ext/blas/Makefile ext/cvode/Makefile ext/math/Makefile ext/recipes/Makefile ext/tpx/Makefile ext/Makefile ext/f2c_libs/Makefile ext/f2c_blas/Makefile ext/f2c_lapack/Makefile ext/f2c_math/Makefile examples/Makefile examples/cxx/Makefile tools/Makefile tools/doc/Cantera.cfg tools/doc/Makefile tools/src/Makefile tools/src/sample.mak tools/src/finish_install.py tools/src/package4mac tools/templates/f77/demo.mak tools/templates/f90/demo.mak tools/templates/cxx/demo.mak tools/testtools/Makefile data/inputs/Makefile test_problems/Makefile test_problems/cxx_ex/Makefile test_problems/silane_equil/Makefile test_problems/surfkin/Makefile test_problems/diamondSurf/Makefile test_problems/ChemEquil_gri_matrix/Makefile test_problems/ChemEquil_gri_pairs/Makefile test_problems/ChemEquil_ionizedGas/Makefile test_problems/ChemEquil_red1/Makefile test_problems/fracCoeff/Makefile test_problems/negATest/Makefile test_problems/ck2cti_test/Makefile test_problems/ck2cti_test/runtest test_problems/min_python/Makefile test_problems/min_python/minDiamond/Makefile test_problems/min_python/negATest/Makefile test_problems/pureFluidTest/Makefile test_problems/python/Makefile test_problems/cathermo/Makefile test_problems/cathermo/issp/Makefile test_problems/cathermo/ims/Makefile test_problems/cathermo/stoichSubSSTP/Makefile test_problems/cathermo/testIAPWS/Makefile test_problems/cathermo/testIAPWSPres/Makefile test_problems/cathermo/testIAPWSTripP/Makefile test_problems/cathermo/testWaterPDSS/Makefile test_problems/cathermo/testWaterTP/Makefile test_problems/cathermo/HMW_test_1/Makefile test_problems/cathermo/HMW_test_3/Makefile test_problems/cathermo/HMW_graph_GvT/Makefile test_problems/cathermo/HMW_graph_GvI/Makefile test_problems/cathermo/HMW_graph_HvT/Makefile test_problems/cathermo/HMW_graph_CpvT/Makefile test_problems/cathermo/HMW_graph_VvT/Makefile test_problems/cathermo/DH_graph_1/Makefile test_problems/cathermo/DH_graph_acommon/Makefile test_problems/cathermo/DH_graph_NM/Makefile test_problems/cathermo/DH_graph_Pitzer/Makefile test_problems/cathermo/DH_graph_bdotak/Makefile bin/install_tsc"
test "x$prefix" = xNONE && prefix=$ac_default_prefix
@ -9282,6 +9316,7 @@ do
"Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"Cantera/Makefile" ) CONFIG_FILES="$CONFIG_FILES Cantera/Makefile" ;;
"Cantera/src/Makefile" ) CONFIG_FILES="$CONFIG_FILES Cantera/src/Makefile" ;;
"Cantera/src/app/Makefile" ) CONFIG_FILES="$CONFIG_FILES Cantera/src/app/Makefile" ;;
"Cantera/src/base/Makefile" ) CONFIG_FILES="$CONFIG_FILES Cantera/src/base/Makefile" ;;
"Cantera/src/zeroD/Makefile" ) CONFIG_FILES="$CONFIG_FILES Cantera/src/zeroD/Makefile" ;;
"Cantera/src/oneD/Makefile" ) CONFIG_FILES="$CONFIG_FILES Cantera/src/oneD/Makefile" ;;
@ -9530,6 +9565,8 @@ s,@KERNEL@,$KERNEL,;t t
s,@KERNEL_OBJ@,$KERNEL_OBJ,;t t
s,@BUILD_CK@,$BUILD_CK,;t t
s,@LIB_DIR@,$LIB_DIR,;t t
s,@BOOST_INCLUDE@,$BOOST_INCLUDE,;t t
s,@BOOST_LIB@,$BOOST_LIB,;t t
s,@build_lapack@,$build_lapack,;t t
s,@build_blas@,$build_blas,;t t
s,@BLAS_LAPACK_LIBS@,$BLAS_LAPACK_LIBS,;t t

View file

@ -276,6 +276,7 @@ GRAPHVIZDIR=" "
fi
AC_SUBST(GRAPHVIZDIR)
#----------- ARCHIVE --------------------
if test "x${OS_IS_DARWIN}" = "x1"; then
@ -539,6 +540,21 @@ AC_SUBST(KERNEL_OBJ)
AC_SUBST(BUILD_CK)
AC_SUBST(LIB_DIR)
if test "$WITH_HTML_LOG_FILES" = "y"; then
AC_DEFINE(WITH_HTML_LOGS)
fi
BOOST_INCLUDE=
BOOST_LIB=
if test "$BUILD_THREAD_SAFE" = "y" ; then
AC_DEFINE(THREAD_SAFE_CANTERA)
BOOST_INCLUDE=-I$BOOST_INC_DIR
BOOST_LIB=$BOOST_THREAD_LIB
fi
AC_SUBST(BOOST_INCLUDE)
AC_SUBST(BOOST_LIB)
#
# Report to the user what has been included/excluded from the compilation
#
@ -550,6 +566,11 @@ if test "$CANTERA_DEBUG_MODE" = "1" ; then
else
echo " Cantera Debug Mode = OFF"
fi
if test "$BUILD_THREAD_SAFE" = "y" ; then
echo " Thread Safe = YES"
else
echo " Thread Safe = NO"
fi
if test "$NEED_TRANSPORT" = "1" ; then
echo " Calculation of Transport Props = ON"
else
@ -754,6 +775,12 @@ if test ${use_sundials} = 1; then
LOCAL_LIB_DIRS=$LOCAL_LIB_DIRS' -L'$SUNDIALS_LIB_DIR
fi
if test ${BUILD_THREAD_SAFE} = "y"; then
LOCAL_LIBS=$LOCAL_LIBS' '-l$BOOST_LIB
LOCAL_LIB_DIRS=$LOCAL_LIB_DIRS' -L'$BOOST_LIB_DIR
fi
AC_SUBST(LOCAL_LIB_DIRS)
AC_SUBST(LOCAL_LIBS)
@ -1028,6 +1055,7 @@ AC_SUBST(SHARED)
if test -z "$PIC"; then PIC='-fPIC'; fi
AC_SUBST(PIC)
CXX_INCLUDES=$BOOST_INCLUDE
AC_SUBST(CXX_INCLUDES)
#
# LCXX_FLAGS: Flags that get attached to the CXX loader
@ -1358,6 +1386,7 @@ dnl Checks for library functions.
AC_OUTPUT(Makefile \
Cantera/Makefile \
Cantera/src/Makefile \
Cantera/src/app/Makefile \
Cantera/src/base/Makefile \
Cantera/src/zeroD/Makefile \
Cantera/src/oneD/Makefile \

View file

@ -1,3 +1,4 @@
#define IEEE_8087
#define Arith_Kind_ASL 1
#define IEEE_MC68k
#define Arith_Kind_ASL 2
#define Double_Align
#define NANCHECK

View file

@ -244,6 +244,12 @@ ENABLE_RXNPATH='y'
# two phase pure fluids
ENABLE_TPX='y'
# write HTMl log files. Some multiphase equilibrium procedures can
# write copious diagnostic log messages. Set this to anything but 'y'
# to remove this capability (results in slightly faster equilibrium
# calculations)
WITH_HTML_LOG_FILES='y'
#-----------------------------------------------------------------
# CVODE / CVODES
#-----------------------------------------------------------------
@ -343,6 +349,18 @@ PIC=${PIC:=-fPIC}
# the compiler option to create a shared library from object files
SHARED=${SHARED:="-dynamic"}
#-------------------------------------------------------------------
# Thread Safety
#-------------------------------------------------------------------
# Cantera can be built so that it is thread safe. Doing so requires
# using procedures from the boost library, so if you want thread
# safety then you need to get and install boost if you don't have it.
BUILD_THREAD_SAFE=${BUILD_THREAD_SAFE:="y"}
BOOST_INC_DIR=${BOOST_INC_DIR:="/usr/local/include/boost-1_34"}
BOOST_LIB_DIR=${BOOST_LIB_DIR:="/usr/local/lib"}
BOOST_THREAD_LIB=${BOOST_THREAD_LIB:="boost_thread-mt-1_34"}
#-------------------------------------------------------------------
# External procedures
@ -497,6 +515,13 @@ export WITH_IDEAL_SOLUTIONS
export WITH_ELECTROLYTES
export WITH_PRIME
export BUILD_THREAD_SAFE
export BOOST_INC_DIR
export BOOST_LIB_DIR
export BOOST_THREAD_LIB
export WITH_HTML_LOG_FILES
#cd config
chmod +x ./configure
chmod +x config/config.guess

View file

@ -64,7 +64,7 @@ LCXX_FLAGS = -L$(CANTERA_LIBDIR) @LOCAL_LIB_DIRS@ @CXXFLAGS@
# How to compile C++ source files to object files
.@CXX_EXT@.@OBJ_EXT@: Interface.h
$(CXX) -c $< -I$(CANTERA_INCDIR) $(CXX_FLAGS)
$(CXX) -c $< -I$(CANTERA_INCDIR) @CXX_INCLUDES@ $(CXX_FLAGS)
# How to compile the dependency file
.cpp.d:

View file

@ -64,7 +64,7 @@ LCXX_FLAGS = -L$(CANTERA_LIBDIR) @LOCAL_LIB_DIRS@ @CXXFLAGS@
# How to compile C++ source files to object files
.@CXX_EXT@.@OBJ_EXT@: Interface.h
$(CXX) -c $< -I$(CANTERA_INCDIR) $(CXX_FLAGS)
$(CXX) -c $< -I$(CANTERA_INCDIR) @CXX_INCLUDES@ $(CXX_FLAGS)
# How to compile the dependency file
.cpp.d:

View file

@ -64,7 +64,7 @@ LCXX_FLAGS = -L$(CANTERA_LIBDIR) @LOCAL_LIB_DIRS@ @CXXFLAGS@
# How to compile C++ source files to object files
.@CXX_EXT@.@OBJ_EXT@: Interface.h
$(CXX) -c $< -I$(CANTERA_INCDIR) $(CXX_FLAGS)
$(CXX) -c $< -I$(CANTERA_INCDIR) @CXX_INCLUDES@ $(CXX_FLAGS)
# How to compile the dependency file
.cpp.d:

View file

@ -64,7 +64,7 @@ LCXX_FLAGS = -L$(CANTERA_LIBDIR) @LOCAL_LIB_DIRS@ @CXXFLAGS@
# How to compile C++ source files to object files
.@CXX_EXT@.@OBJ_EXT@: Interface.h
$(CXX) -c $< -I$(CANTERA_INCDIR) $(CXX_FLAGS)
$(CXX) -c $< -I$(CANTERA_INCDIR) @CXX_INCLUDES@ $(CXX_FLAGS)
# How to compile the dependency file
.cpp.d:

View file

@ -58,7 +58,7 @@ CANTERA_INCDIR=../../Cantera/src
INCLUDES=-I$(CANTERA_INCDIR) -I$(CANTERA_INCDIR)/thermo
else
CANTERA_INCDIR=@ctroot@/build/include/cantera
INCLUDES=-I$(CANTERA_INCDIR) -I$(CANTERA_INCDIR)/kernel
INCLUDES=-I$(CANTERA_INCDIR) -I$(CANTERA_INCDIR)/kernel @CXX_INCLUDES@
endif
# flags passed to the C++ compiler/linker for the linking step

View file

@ -64,7 +64,7 @@ LCXX_FLAGS = -L$(CANTERA_LIBDIR) @LOCAL_LIB_DIRS@ @CXXFLAGS@
# How to compile C++ source files to object files
.@CXX_EXT@.@OBJ_EXT@:
$(CXX) -c $< -I$(CANTERA_INCDIR) $(CXX_FLAGS)
$(CXX) -c $< -I$(CANTERA_INCDIR) @CXX_INCLUDES@ $(CXX_FLAGS)
# How to compile the dependency file
.cpp.d:

View file

@ -65,7 +65,7 @@ LCXX_FLAGS = -L$(CANTERA_LIBDIR) @LOCAL_LIB_DIRS@ @CXXFLAGS@
# how to compile C++ source files to object files
.@CXX_EXT@.@OBJ_EXT@: Interface.h
$(CXX) -c $< -I$(CANTERA_INCDIR) $(CXX_FLAGS)
$(CXX) -c $< -I$(CANTERA_INCDIR) @CXX_INCLUDES@ $(CXX_FLAGS)
DEPENDS=$(OBJS:.o=.d)