Cantera  2.1.2
vcs_util.cpp
Go to the documentation of this file.
1 /**
2  * @file vcs_util.cpp
3  * Internal definitions for utility functions for the VCSnonideal package
4  */
5 /*
6  * Copyright (2005) Sandia Corporation. Under the terms of
7  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
8  * U.S. Government retains certain rights in this software.
9  */
10 
12 #include <cassert>
13 
14 using namespace std;
15 
16 namespace VCSnonideal
17 {
18 #ifndef USE_MEMSET
19 void vcs_dzero(double* vector, int length)
20 {
21  int i;
22  for (i = 0; i < length; i++) {
23  vector[i] = 0.0;
24  }
25 }
26 #endif
27 
28 #ifndef USE_MEMSET
29 void vcs_izero(int* vector, int length)
30 {
31  int i;
32  for (i = 0; i < length; i++) {
33  vector[i] = 0;
34  }
35 }
36 #endif
37 
38 #ifndef USE_MEMSET
39 void vcs_dcopy(double* const vec_to, const double* const vec_from, int length)
40 {
41  int i;
42  for (i = 0; i < length; i++) {
43  vec_to[i] = vec_from[i];
44  }
45 }
46 #endif
47 
48 #ifndef USE_MEMSET
49 void vcs_icopy(int* vec_to, int* vec_from, int length)
50 {
51  int i;
52  for (i = 0; i < length; i++) {
53  vec_to[i] = vec_from[i];
54  }
55 }
56 #endif
57 
58 #ifndef USE_MEMSET
59 void vcs_vdzero(std::vector<double> &vvv, int len)
60 {
61  if (len < 0) {
62  std::fill(vvv.begin(), vvv.end(), 0.0);
63  } else {
64  std::fill_n(vvv.begin(), len, 0.0);
65  }
66 }
67 #endif
68 
69 double vcs_l2norm(const std::vector<double> vec)
70 {
71  size_t len = vec.size();
72  if (len == 0) {
73  return 0.0;
74  }
75  double sum = 0.0;
76  std::vector<double>::const_iterator pos;
77  for (pos = vec.begin(); pos != vec.end(); ++pos) {
78  sum += (*pos) * (*pos);
79  }
80  return std::sqrt(sum / len);
81 }
82 
83 #ifndef USE_MEMSET
84 void vcs_vizero(std::vector<int> &vvv, int len)
85 {
86  if (len < 0) {
87  std::fill(vvv.begin(), vvv.end(), 0.0);
88  } else {
89  std::fill_n(vvv.begin(), len, 0.0);
90  }
91 }
92 #endif
93 
94 #ifndef USE_MEMSET
95 void vcs_vdcopy(std::vector<double> &vec_to,
96  const std::vector<double> & vec_from, int length)
97 {
98  std::copy(vec_from.begin(), vec_from.begin() + length, vec_to.begin());
99 }
100 #endif
101 
102 #ifndef USE_MEMSET
103 void vcs_vicopy(std::vector<int> &vec_to,
104  const std::vector<int> & vec_from, int length)
105 {
106  std::copy(vec_from.begin(), vec_from.begin() + length, vec_to.begin());
107 }
108 #endif
109 
110 size_t vcs_optMax(const double* x, const double* xSize, size_t j, size_t n)
111 {
112  size_t i;
113  size_t largest = j;
114  double big = x[j];
115  if (xSize) {
116  assert(xSize[j] > 0.0);
117  big *= xSize[j];
118  for (i = j + 1; i < n; ++i) {
119  assert(xSize[i] > 0.0);
120  if ((x[i] * xSize[i]) > big) {
121  largest = i;
122  big = x[i] * xSize[i];
123  }
124  }
125  } else {
126  for (i = j + 1; i < n; ++i) {
127  if (x[i] > big) {
128  largest = i;
129  big = x[i];
130  }
131  }
132  }
133  return largest;
134 }
135 
136 int vcs_max_int(const int* vector, int length)
137 {
138  int i, retn;
139  if (vector == NULL || length <= 0) {
140  return 0;
141  }
142  retn = vector[0];
143  for (i = 1; i < length; i++) {
144  retn = std::max(retn, vector[i]);
145  }
146  return retn;
147 }
148 
149 #ifdef DEBUG_HKM
150 static void mlequ_matrixDump(double* c, int idem, int n)
151 {
152  int i, j;
153  printf("vcsUtil_mlequ() MATRIX DUMP --------------------------------------------------\n");
154  printf(" ");
155  for (j = 0; j < n; ++j) {
156  printf(" % 3d ", j);
157  }
158  printf("\n");
159  for (j = 0; j < n; ++j) {
160  printf("-----------");
161  }
162  printf("\n");
163  for (i = 0; i < n; ++i) {
164  printf(" %3d | ", i);
165  for (j = 0; j < n; ++j) {
166  printf("% 10.3e ", c[i + j * idem]);
167  }
168  printf("\n");
169  }
170  for (j = 0; j < n; ++j) {
171  printf("-----------");
172  }
173  printf("\n");
174  printf("vcsUtil_mlequ() END MATRIX DUMP --------------------------------------------------\n");
175 
176 }
177 #endif
178 
179 //! Swap rows in the c matrix and the b rhs matrix
180 /*!
181  * @param c Matrix of size nxn, row first
182  * @param idem C storage dimension for the number of rows
183  * @param n Size of the matrix
184  * @param b RHS of the Ax=b problem to solve
185  * @param m Number of rhs to solve
186  * @param irowa first row to swap
187  * @param irowb second row to swap
188  */
189 static void vcsUtil_swapRows(double* c, size_t idem, size_t n, double* b,
190  size_t m, size_t irowa, size_t irowb)
191 {
192  if (irowa == irowb) {
193  return;
194  }
195  for (size_t j = 0; j < n; j++) {
196  std::swap(c[irowa + j * idem], c[irowb + j * idem]);
197  }
198  for (size_t j = 0; j < m; j++) {
199  std::swap(b[irowa + j * idem], b[irowb + j * idem]);
200  }
201 }
202 
203 //! Swap rows in the c matrix and the b rhs matrix to lower the condition number of the matrix
204 /*!
205  * @param c Matrix of size nxn, row first
206  * @param idem C storage dimension for the number of rows
207  * @param n Size of the matrix
208  * @param b RHS of the Ax=b problem to solve
209  * @param m Number of rhs to solve
210  */
211 static void vcsUtil_mlequ_preprocess(double* c, size_t idem, size_t n,
212  double* b, size_t m)
213 {
214  size_t j = 0;
215  std::vector<int> irowUsed(n, 0);
216 
217  for (j = 0; j < n; j++) {
218  int numNonzero = 0;
219  size_t inonzero = npos;
220  for (size_t i = 0; i < n; i++) {
221  if (c[i + j * idem] != 0.0) {
222  numNonzero++;
223  inonzero = i;
224  }
225  }
226  if (numNonzero == 1) {
227  if (inonzero != j) {
228  if (irowUsed[inonzero] == 0) {
229  vcsUtil_swapRows(c, idem, n, b, m, j, inonzero);
230 #ifdef DEBUG_HKM
231  // mlequ_matrixDump(c, idem, n);
232 #endif
233  }
234  }
235  irowUsed[j] = 1;
236  }
237  }
238 
239  for (j = 0; j < n; j++) {
240  if (c[j + j * idem] == 0.0) {
241  int numNonzero = 0;
242  size_t inonzero = npos;
243  for (size_t i = 0; i < n; i++) {
244  if (!irowUsed[i]) {
245  if (c[i + j * idem] != 0.0) {
246  if ((c[i + i * idem] == 0.0)
247  || (c[j + i * idem] != 0.0)) {
248  numNonzero++;
249  inonzero = i;
250  }
251  }
252  }
253  }
254  if (numNonzero == 1) {
255  if (inonzero != j) {
256  if (irowUsed[inonzero] == 0) {
257  vcsUtil_swapRows(c, idem, n, b, m, j, inonzero);
258 #ifdef DEBUG_HKM
259  // mlequ_matrixDump(c, idem, n);
260 #endif
261  }
262  }
263  irowUsed[j] = 1;
264  }
265  }
266  }
267 
268  for (j = 0; j < n; j++) {
269  if (c[j + j * idem] == 0.0) {
270  int numNonzero = 0;
271  size_t inonzero = npos;
272  for (size_t i = 0; i < n; i++) {
273  if (!irowUsed[i]) {
274  if (c[i + j * idem] != 0.0) {
275  if ((c[i + i * idem] == 0.0)
276  || (c[j + i * idem] != 0.0)) {
277  numNonzero++;
278  inonzero = i;
279  }
280  }
281  }
282  }
283  if (inonzero != npos) {
284  if (inonzero != j) {
285  if (irowUsed[inonzero] == 0) {
286  vcsUtil_swapRows(c, idem, n, b, m, j, inonzero);
287 #ifdef DEBUG_HKM
288  // mlequ_matrixDump(c, idem, n);
289 #endif
290  }
291  }
292  }
293  }
294  }
295 }
296 
297 int vcsUtil_mlequ(double* c, size_t idem, size_t n, double* b, size_t m)
298 {
299  size_t k;
300 #ifdef DEBUG_HKM
301  // mlequ_matrixDump(c, idem, n);
302 #endif
303  vcsUtil_mlequ_preprocess(c, idem, n, b, m);
304 #ifdef DEBUG_HKM
305  // mlequ_matrixDump(c, idem, n);
306  static int s_numCalls = 0;
307  s_numCalls++;
308 #endif
309 
310  double R;
311  if (n > idem || n <= 0) {
312  plogf("vcsUtil_mlequ ERROR: badly dimensioned matrix: %d %d\n", n, idem);
313  return 1;
314  }
315 
316 #ifdef DEBUG_HKM
317  int dmatrix = 0;
318  for (size_t i = 0; i < n; ++i) {
319  bool notFound = true;
320  for (size_t j = 0; j < n; ++j) {
321  if (c[i + j * idem] != 0.0) {
322  notFound = false;
323  }
324  }
325  if (notFound) {
326  printf(" vcsUtil_mlequ ERROR(): row %d is identically zero\n", i);
327  }
328  }
329  for (size_t j = 0; j < n; ++j) {
330  bool notFound = true;
331  for (size_t i = 0; i < n; ++i) {
332  if (c[i + j * idem] != 0.0) {
333  notFound = false;
334  }
335  }
336  if (notFound) {
337  printf(" vcsUtil_mlequ ERROR(): column %d is identically zero\n", j);
338  }
339  }
340  // if (s_numCalls >= 32) {
341  // printf("vcsUtil_mlequ: we are here\n");
342  // dmatrix = 1;
343  // }
344 
345  if (dmatrix) {
346  mlequ_matrixDump(c, idem, n);
347  }
348 #endif
349  /*
350  * Loop over the rows
351  * -> At the end of each loop, the only nonzero entry in the column
352  * will be on the diagonal. We can therfore just invert the
353  * diagonal at the end of the program to solve the equation system.
354  */
355  for (size_t i = 0; i < n; ++i) {
356  if (c[i + i * idem] == 0.0) {
357  /*
358  * Do a simple form of row pivoting to find a non-zero pivot
359  */
360  for (k = i + 1; k < n; ++k) {
361  if (c[k + i * idem] != 0.0) {
362  goto FOUND_PIVOT;
363  }
364  }
365  plogf("vcsUtil_mlequ ERROR: Encountered a zero column: %d\n", i);
366 #ifdef DEBUG_HKM
367  plogf(" call # %d\n", s_numCalls);
368 #endif
369 #ifdef DEBUG_HKM
370  mlequ_matrixDump(c, idem, n);
371 #endif
372  return 1;
373 FOUND_PIVOT:
374  ;
375  for (size_t j = 0; j < n; ++j) {
376  c[i + j * idem] += c[k + j * idem];
377  }
378  for (size_t j = 0; j < m; ++j) {
379  b[i + j * idem] += b[k + j * idem];
380  }
381  }
382 
383  for (size_t l = 0; l < n; ++l) {
384  if (l != i && c[l + i * idem] != 0.0) {
385  R = c[l + i * idem] / c[i + i * idem];
386  c[l + i * idem] = 0.0;
387  for (size_t j = i + 1; j < n; ++j) {
388  c[l + j * idem] -= c[i + j * idem] * R;
389  }
390  for (size_t j = 0; j < m; ++j) {
391  b[l + j * idem] -= b[i + j * idem] * R;
392  }
393  }
394  }
395  }
396  /*
397  * The negative in the last expression is due to the form of B upon
398  * input
399  */
400  for (size_t i = 0; i < n; ++i) {
401  for (size_t j = 0; j < m; ++j) {
402  b[i + j * idem] = -b[i + j * idem] / c[i + i * idem];
403  }
404  }
405  return 0;
406 }
407 
408 int vcsUtil_gaussj(double* c, size_t idem, size_t n, double* b, size_t m)
409 {
410  size_t i, j, k, l, ll;
411  size_t irow = npos;
412  size_t icol = npos;
413  bool needInverse = false;
414  double pivinv;
415 #ifdef DEBUG_HKM
416  static int s_numCalls = 0;
417  s_numCalls++;
418 #endif
419 #ifdef DEBUG_HKM
420  // mlequ_matrixDump(c, idem, n);
421 #endif
422  /*
423  * Preprocess the problem
424  */
425  vcsUtil_mlequ_preprocess(c, idem, n, b, m);
426 
427 #ifdef DEBUG_HKM
428  // mlequ_matrixDump(c, idem, n);
429 #endif
430 
431  std::vector<size_t> indxc(n);
432  std::vector<size_t> indxr(n);
433  std::vector<int> ipiv(n, 0);
434  doublereal big = 0.0;
435  /*
436  * This is the main loop over the columns to be reduced.
437  */
438  for (i = 0; i < n; i++) {
439  big = 0.0;
440  for (j = 0; j < n; j++) {
441  if (ipiv[j] != 1) {
442  for (k = 0; k < n; k++) {
443  if (ipiv[k] == 0) {
444  if (fabs(c[j + idem * k]) >= big) {
445  big = fabs(c[j + idem * k]);
446  irow = j;
447  icol = k;
448  }
449  }
450  }
451  }
452  }
453  ++(ipiv[icol]);
454  if (irow != icol) {
455  vcsUtil_swapRows(c, idem, n, b, m, irow, icol);
456  }
457  indxr[i] = irow;
458  indxc[i] = icol;
459  if (c[icol + idem * icol] == 0.0) {
460  plogf("vcsUtil_gaussj ERROR: Encountered a zero column: %d\n", i);
461  return 1;
462  }
463  pivinv = 1.0 / c[icol + idem * icol];
464  c[icol + idem * icol] = 1.0;
465  for (l = 0; l < n; l++) {
466  c[icol + idem * l] *= pivinv;
467  }
468  for (l = 0; l < m; l++) {
469  b[icol + idem * l] *= pivinv;
470  }
471  for (ll = 0; ll < n; ll++) {
472  if (ll != icol) {
473  double dum = c[ll + idem * icol];
474  c[ll + idem * icol] = 0;
475  for (l = 0; l < n; l++) {
476  c[ll + idem * l] -= c[icol + idem * l] * dum;
477  }
478  for (l = 0; l < m; l++) {
479  b[ll + idem * l] -= b[icol + idem * l] * dum;
480  }
481  }
482  }
483  }
484  if (needInverse) {
485  for (l = n - 1; l != npos; l--) {
486  if (indxr[l] != indxc[l]) {
487  for (k = 0; k < n; k++) {
488  std::swap(c[k + idem * indxr[l]], c[k + idem * indxr[l]]);
489  }
490  }
491  }
492  }
493 
494  /*
495  * The negative in the last expression is due to the form of B upon
496  * input
497  */
498  for (i = 0; i < n; ++i) {
499  for (j = 0; j < m; ++j) {
500  b[i + j * idem] = -b[i + j * idem];
501  }
502  }
503  return 0;
504 }
505 
506 double vcsUtil_gasConstant(int mu_units)
507 {
508  double r;
509  switch (mu_units) {
510  case VCS_UNITS_KCALMOL:
511  r = Cantera::GasConst_cal_mol_K * 1e-3;
512  break;
513  case VCS_UNITS_UNITLESS:
514  r = 1.0;
515  break;
516  case VCS_UNITS_KJMOL:
517  r = Cantera::GasConstant * 1e-6;
518  break;
519  case VCS_UNITS_KELVIN:
520  r = 1.0;
521  break;
522  case VCS_UNITS_MKS:
523  /* joules / kg-mol K = kg m2 / s2 kg-mol K */
525  break;
526  default:
527  plogf("vcs_gasConstant error: uknown units: %d\n",
528  mu_units);
529  exit(EXIT_FAILURE);
530  }
531  return r;
532 }
533 
534 void vcs_print_line(const char* string, int num)
535 {
536  if (string) {
537  for (int j = 0; j < num; j++) {
538  plogf("%s", string);
539  }
540  }
541  plogendl();
542 }
543 
544 const char* vcs_speciesType_string(int speciesStatus, int length)
545 {
546  const char* sss;
547  switch (speciesStatus) {
549  sss = "Component Species";
550  break;
551  case VCS_SPECIES_MAJOR:
552  sss = "Major Species";
553  break;
554  case VCS_SPECIES_MINOR:
555  sss = "Minor Species";
556  break;
558  if (length < 48) {
559  sss = "Set Zeroed-Phase";
560  } else {
561  sss = "Purposely Zeroed-Phase Species (not in problem)";
562  }
563  break;
565  if (length < 23) {
566  sss = "Zeroed-MS Phase";
567  } else {
568  sss = "Zeroed-MS Phase Species";
569  }
570  break;
572  if (length < 23) {
573  sss = "Zeroed-SS Phase";
574  } else {
575  sss = "Zeroed-SS Phase Species";
576  }
577  break;
578  case VCS_SPECIES_DELETED:
579  if (length < 22) {
580  sss = "Deleted Species";
581  } else if (length < 40) {
582  sss = "Deleted-Small Species";
583  } else {
584  sss = "Deleted-Small Species in a MS phase";
585  }
586  break;
588  if (length < 47) {
589  sss = "Tmp Zeroed in MS";
590  } else {
591  sss = "Zeroed Species in an active MS phase (tmp)";
592  }
593  break;
595  if (length < 56) {
596  sss = "Stoich Zeroed in MS";
597  } else {
598  sss = "Zeroed Species in an active MS phase (Stoich Constraint)";
599  }
600  break;
602  if (length < 29) {
603  sss = "InterfaceVoltage";
604  } else {
605  sss = "InterfaceVoltage Species";
606  }
607  break;
608  default:
609  sss = "unknown species type";
610  }
611  return sss;
612 }
613 
614 void vcs_print_stringTrunc(const char* str, size_t space, int alignment)
615 {
616  size_t i, ls = 0, rs = 0;
617  size_t len = strlen(str);
618  if ((len) >= space) {
619  for (i = 0; i < space; i++) {
620  plogf("%c", str[i]);
621  }
622  } else {
623  if (alignment == 1) {
624  ls = space - len;
625  } else if (alignment == 2) {
626  rs = space - len;
627  } else {
628  ls = (space - len) / 2;
629  rs = space - len - ls;
630  }
631  if (ls != 0) {
632  for (i = 0; i < ls; i++) {
633  plogf(" ");
634  }
635  }
636  plogf("%s", str);
637  if (rs != 0) {
638  for (i = 0; i < rs; i++) {
639  plogf(" ");
640  }
641  }
642  }
643 }
644 
645 bool vcs_doubleEqual(double d1, double d2)
646 {
647  double denom = fabs(d1) + fabs(d2) + 1.0;
648  double fac = fabs(d1 - d2) / denom;
649  if (fac > 1.0E-10) {
650  return false;
651  }
652  return true;
653 }
654 
655 void vcs_heapsort(std::vector<int> & x)
656 {
657  int n = x.size();
658  if (n < 2) {
659  return;
660  }
661  doublereal rra;
662  int ll = n / 2;
663  int iret = n - 1;
664 
665  while (1 > 0) {
666  if (ll > 0) {
667  ll--;
668  rra = x[ll];
669  } else {
670  rra = x[iret];
671  x[iret] = x[0];
672  iret--;
673  if (iret == 0) {
674  x[0] = rra;
675  return;
676  }
677  }
678 
679  int i = ll;
680  int j = ll + ll + 1;
681 
682  while (j <= iret) {
683  if (j < iret) {
684  if (x[j] < x[j + 1]) {
685  j++;
686  }
687  }
688  if (rra < x[j]) {
689  x[i] = x[j];
690  i = j;
691  j = j + j + 1;
692  } else {
693  j = iret + 1;
694  }
695  }
696  x[i] = rra;
697  }
698 }
699 
700 void vcs_orderedUnique(std::vector<int> & xOrderedUnique, const std::vector<int> & x)
701 {
702  std::vector<int> xordered(x);
703  vcs_heapsort(xordered);
704  int lastV = x[0] - 1;
705  xOrderedUnique.clear();
706  for (int i = 0; i < (int) xordered.size(); i++) {
707  if (lastV != xordered[i]) {
708  xOrderedUnique.push_back(xordered[i]);
709  lastV = xordered[i];
710  }
711  }
712 }
713 
714 }
void vcs_print_stringTrunc(const char *str, size_t space, int alignment)
Print a string within a given space limit.
Definition: vcs_util.cpp:614
double vcsUtil_gasConstant(int mu_units)
Returns the value of the gas constant in the units specified by parameter.
Definition: vcs_util.cpp:506
#define VCS_SPECIES_ZEROEDMS
Species lies in a multicomponent phase with concentration zero.
Definition: vcs_defs.h:166
#define VCS_SPECIES_MINOR
Species is a major species.
Definition: vcs_defs.h:151
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:173
static void vcsUtil_swapRows(double *c, size_t idem, size_t n, double *b, size_t m, size_t irowa, size_t irowb)
Swap rows in the c matrix and the b rhs matrix.
Definition: vcs_util.cpp:189
const char * vcs_speciesType_string(int speciesStatus, int length)
Returns a const char string representing the type of the species given by the first argument...
Definition: vcs_util.cpp:544
#define VCS_SPECIES_INTERFACIALVOLTAGE
Species refers to an electron in the metal.
Definition: vcs_defs.h:189
#define VCS_SPECIES_ZEROEDSS
Species is a SS phase, that is currently zeroed out.
Definition: vcs_defs.h:173
#define VCS_SPECIES_ZEROEDPHASE
Species lies in a multicomponent phase that is zeroed atm.
Definition: vcs_defs.h:198
Internal declarations for the VCSnonideal package.
void vcs_orderedUnique(std::vector< int > &xOrderedUnique, const std::vector< int > &x)
Sorts a vector of ints and eliminates duplicates from the resulting list.
Definition: vcs_util.cpp:700
void vcs_print_line(const char *string, int num)
Prints a line consisting of multiple occurrences of the same string.
Definition: vcs_util.cpp:534
int vcsUtil_mlequ(double *c, size_t idem, size_t n, double *b, size_t m)
Invert an n x n matrix and solve m rhs's.
Definition: vcs_util.cpp:297
static void vcsUtil_mlequ_preprocess(double *c, size_t idem, size_t n, double *b, size_t m)
Swap rows in the c matrix and the b rhs matrix to lower the condition number of the matrix...
Definition: vcs_util.cpp:211
void vcs_heapsort(std::vector< int > &x)
Sorts a vector of ints in place from lowest to the highest values.
Definition: vcs_util.cpp:655
size_t vcs_optMax(const double *x, const double *xSize, size_t j, size_t n)
Finds the location of the maximum component in a double vector.
Definition: vcs_util.cpp:110
#define VCS_SPECIES_ACTIVEBUTZERO
Species lies in a multicomponent phase that is active, but species concentration is zero...
Definition: vcs_defs.h:207
#define VCS_SPECIES_MAJOR
Species is a major species.
Definition: vcs_defs.h:144
void vcs_vicopy(std::vector< int > &vec_to, const std::vector< int > &vec_from, int length)
Copy one std integer vector into another.
Definition: vcs_util.cpp:103
#define VCS_SPECIES_STOICHZERO
Species lies in a multicomponent phase that is active, but species concentration is zero due to stoic...
Definition: vcs_defs.h:218
double vcs_l2norm(const std::vector< double > vec)
determine the l2 norm of a vector of doubles
Definition: vcs_util.cpp:69
bool vcs_doubleEqual(double d1, double d2)
Simple routine to check whether two doubles are equal up to roundoff error.
Definition: vcs_util.cpp:645
#define plogendl()
define this Cantera function to replace cout << endl;
Definition: vcs_internal.h:37
const doublereal GasConstant
Universal Gas Constant. [J/kmol/K].
Definition: ct_defs.h:66
const doublereal GasConst_cal_mol_K
Universal gas constant in cal/mol/K.
Definition: ct_defs.h:75
int vcsUtil_gaussj(double *c, size_t idem, size_t n, double *b, size_t m)
Invert an n x n matrix and solve m rhs's.
Definition: vcs_util.cpp:408
int vcs_max_int(const int *vector, int length)
Returns the maximum integer in a list.
Definition: vcs_util.cpp:136
#define plogf
define this Cantera function to replace printf
Definition: vcs_internal.h:30
#define VCS_SPECIES_COMPONENT
Species is a component which can be nonzero.
Definition: vcs_defs.h:137
#define VCS_SPECIES_DELETED
Species has such a small mole fraction it is deleted even though its phase may possibly exist...
Definition: vcs_defs.h:182