8 using namespace Cantera;
29 MultiPhase* mphase, std::vector<size_t>& orderVectorSpecies,
30 std::vector<size_t>& orderVectorElements,
33 size_t j, jj, k=0, kk, l, i, jl, ml;
44 size_t nspecies = mphase->
nSpecies();
46 doublereal
const USEDBEFORE = -1;
51 if (orderVectorElements.size() < ne) {
52 orderVectorElements.resize(ne);
53 for (j = 0; j < ne; j++) {
54 orderVectorElements[j] = j;
61 if (orderVectorSpecies.size() != nspecies) {
62 orderVectorSpecies.resize(nspecies);
63 for (k = 0; k < nspecies; k++) {
64 orderVectorSpecies[k] = k;
70 for (i=0; i<77; i++) {
74 writelog(
" --- Subroutine BASOPT called to ");
75 writelog(
"calculate the number of components and ");
76 writelog(
"evaluate the formation matrix\n");
80 writelog(
" --- Formula Matrix used in BASOPT calculation\n");
82 for (j = 0; j < ne; j++) {
83 jj = orderVectorElements[j];
90 for (k = 0; k < nspecies; k++) {
91 kk = orderVectorSpecies[k];
96 for (j = 0; j < ne; j++) {
97 jj = orderVectorElements[j];
98 double num = mphase->
nAtoms(kk,jj);
112 size_t nComponents = std::min(ne, nspecies);
113 size_t nNonComponents = nspecies - nComponents;
117 *usedZeroedSpecies =
false;
131 if (formRxnMatrix.size() < nspecies*ne) {
132 formRxnMatrix.resize(nspecies*ne, 0.0);
139 if (DEBUG_MODE_ENABLED) {
142 double molSave = 0.0;
159 kk = max_element(molNum.begin(), molNum.end()) - molNum.begin();
160 for (j = 0; j < nspecies; j++) {
161 if (orderVectorSpecies[j] == kk) {
167 throw CanteraError(
"BasisOptimize",
"orderVectorSpecies contains an error");
170 if (molNum[kk] == 0.0) {
171 *usedZeroedSpecies =
true;
176 if (molNum[kk] == USEDBEFORE) {
178 nNonComponents = nspecies - nComponents;
186 molSave = molNum[kk];
188 molNum[kk] = USEDBEFORE;
198 for (j = 0; j < ne; ++j) {
199 jj = orderVectorElements[j];
200 sm[j + jr*ne] = mphase->
nAtoms(kk,jj);
209 for (j = 0; j < jl; ++j) {
211 for (i = 0; i < ne; ++i) {
212 ss[j] += sm[i + jr*ne] * sm[i + j*ne];
220 for (j = 0; j < jl; ++j) {
221 for (l = 0; l < ne; ++l) {
222 sm[l + jr*ne] -= ss[j] * sm[l + j*ne];
231 for (ml = 0; ml < ne; ++ml) {
232 tmp = sm[ml + jr*ne];
238 if (sa[jr] < 1.0e-6) {
249 kk = orderVectorSpecies[k];
251 writelogf(
" --- %-12.12s", sname.c_str());
252 jj = orderVectorSpecies[jr];
254 writelogf(
"(%9.2g) replaces %-12.12s", molSave, ename.c_str());
255 writelogf(
"(%9.2g) as component %3d\n", molNum[jj], jr);
257 std::swap(orderVectorSpecies[jr], orderVectorSpecies[k]);
265 }
while (jr < (nComponents-1));
306 for (k = 0; k < nComponents; ++k) {
307 kk = orderVectorSpecies[k];
308 for (j = 0; j < nComponents; ++j) {
309 jj = orderVectorElements[j];
310 sm[j + k*ne] = mphase->
nAtoms(kk, jj);
314 for (i = 0; i < nNonComponents; ++i) {
316 kk = orderVectorSpecies[k];
317 for (j = 0; j < nComponents; ++j) {
318 jj = orderVectorElements[j];
319 formRxnMatrix[j + i * ne] = - mphase->
nAtoms(kk, jj);
325 ct_dgetrf(nComponents, nComponents, &sm[0], ne, &ipiv[0], info);
327 throw CanteraError(
"BasisOptimize",
"factorization returned an error condition");
329 ct_dgetrs(ctlapack::NoTranspose, nComponents, nNonComponents, &sm[0], ne,
330 &ipiv[0], &formRxnMatrix[0], ne, info);
334 writelogf(
" --- Number of Components = %d\n", nComponents);
337 for (k = 0; k < nComponents; k++) {
338 kk = orderVectorSpecies[k];
341 writelog(
"\n --- Components Moles: ");
342 for (k = 0; k < nComponents; k++) {
343 kk = orderVectorSpecies[k];
346 writelog(
"\n --- NonComponent | Moles | ");
347 for (i = 0; i < nComponents; i++) {
348 kk = orderVectorSpecies[i];
354 for (i = 0; i < nNonComponents; i++) {
356 kk = orderVectorSpecies[k];
364 for (j = 0; j < nComponents; j++) {
365 writelogf(
" %6.2f", - formRxnMatrix[j + i * ne]);
370 for (i=0; i<77; i++) {
396 int len =
static_cast<int>(strlen(str));
397 if ((len) >= space) {
398 for (i = 0; i < space; i++) {
402 if (alignment == 1) {
404 }
else if (alignment == 2) {
407 ls = (space - len) / 2;
408 rs = space - len - ls;
411 for (i = 0; i < ls; i++) {
417 for (i = 0; i < rs; i++) {
426 std::vector<size_t>& orderVectorSpecies,
427 std::vector<size_t>& orderVectorElements)
429 size_t j, k, l, i, jl, ml, jr, ielem, jj, kk=0;
437 size_t nspecies = mphase->
nSpecies();
439 double test = -1.0E10;
442 for (i=0; i<77; i++) {
446 writelog(
" --- Subroutine ElemRearrange() called to ");
447 writelog(
"check stoich. coefficient matrix\n");
448 writelog(
" --- and to rearrange the element ordering once\n");
454 if (orderVectorElements.size() < nelements) {
455 orderVectorElements.resize(nelements);
456 for (j = 0; j < nelements; j++) {
457 orderVectorElements[j] = j;
466 if (orderVectorSpecies.size() != nspecies) {
467 orderVectorSpecies.resize(nspecies);
468 for (k = 0; k < nspecies; k++) {
469 orderVectorSpecies[k] = k;
480 if (elementAbundances.size() != nelements) {
481 for (j = 0; j < nelements; j++) {
483 for (k = 0; k < nspecies; k++) {
484 eAbund[j] += fabs(mphase->
nAtoms(k, j));
488 copy(elementAbundances.begin(), elementAbundances.end(),
515 for (ielem = jr; ielem < nelements; ielem++) {
516 kk = orderVectorElements[ielem];
517 if (eAbund[kk] != test && eAbund[kk] > 0.0) {
522 for (ielem = jr; ielem < nelements; ielem++) {
523 kk = orderVectorElements[ielem];
524 if (eAbund[kk] != test) {
530 if (k == nelements) {
534 writelogf(
"Error exit: returning with nComponents = %d\n", jr);
536 throw CanteraError(
"ElemRearrange",
"Required number of elements not found.");
560 for (j = 0; j < nComponents; ++j) {
561 jj = orderVectorSpecies[j];
562 kk = orderVectorElements[k];
563 sm[j + jr*nComponents] = mphase->
nAtoms(jj,kk);
572 for (j = 0; j < jl; ++j) {
574 for (i = 0; i < nComponents; ++i) {
575 ss[j] += sm[i + jr*nComponents] * sm[i + j*nComponents];
583 for (j = 0; j < jl; ++j) {
584 for (l = 0; l < nComponents; ++l) {
585 sm[l + jr*nComponents] -= ss[j] * sm[l + j*nComponents];
595 for (ml = 0; ml < nComponents; ++ml) {
596 double tmp = sm[ml + jr*nComponents];
602 if (sa[jr] < 1.0e-6) {
613 kk = orderVectorElements[k];
618 kk = orderVectorElements[jr];
623 std::swap(orderVectorElements[jr], orderVectorElements[k]);
631 }
while (jr < (nComponents-1));
size_t BasisOptimize(int *usedZeroedSpecies, bool doFormRxn, MultiPhase *mphase, std::vector< size_t > &orderVectorSpecies, std::vector< size_t > &orderVectorElements, vector_fp &formRxnMatrix)
Choose the optimum basis of species for the equilibrium calculations.
int BasisOptimize_print_lvl
External int that is used to turn on debug printing for the BasisOptimze program. ...
const size_t npos
index returned by functions to indicate "no position"
std::string speciesName(const size_t kGlob) const
Name of species with global index kGlob.
Headers for the MultiPhase object that is used to set up multiphase equilibrium problems (see Equilib...
std::vector< int > vector_int
Vector of ints.
A class for multiphase mixtures.
void writelogf(const char *fmt,...)
Write a formatted message to the screen.
std::string elementName(size_t m) const
Returns the name of the global element m.
Base class for exceptions thrown by Cantera classes.
void getMoles(doublereal *molNum) const
Get the mole numbers of all species in the multiphase object.
doublereal nAtoms(const size_t kGlob, const size_t mGlob) const
Returns the Number of atoms of global element mGlob in global species kGlob.
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
#define DATA_PTR(vec)
Creates a pointer to the start of the raw data for a vector.
static void print_stringTrunc(const char *str, int space, int alignment)
Print a string within a given space limit.
void writelog(const std::string &msg)
Write a message to the screen.
size_t nSpecies() const
Number of species, summed over all phases.
size_t ElemRearrange(size_t nComponents, const vector_fp &elementAbundances, MultiPhase *mphase, std::vector< size_t > &orderVectorSpecies, std::vector< size_t > &orderVectorElements)
Handles the potential rearrangement of the constraint equations represented by the Formula Matrix...
size_t nElements() const
Number of elements.