Cantera  2.0
MultiJac.cpp
Go to the documentation of this file.
1 /**
2  * @file MultiJac.cpp
3  *
4  * Implementation file for class MultiJac
5  */
6 
7 /*
8  * Copyright 2002 California Institute of Technology
9  */
10 
11 #include "cantera/oneD/MultiJac.h"
12 using namespace std;
13 
14 namespace Cantera
15 {
16 
17 MultiJac::MultiJac(OneDim& r)
18  : BandMatrix(r.size(),r.bandwidth(),r.bandwidth())
19 {
20  m_size = r.size();
21  m_points = r.points();
22  m_resid = &r;
23  m_r1.resize(m_size);
24  m_ssdiag.resize(m_size);
25  m_mask.resize(m_size);
26  m_elapsed = 0.0;
27  m_nevals = 0;
28  m_age = 100000;
29  doublereal ff = 1.0;
30  while (1.0 + ff != 1.0) {
31  ff *= 0.5;
32  }
33  m_atol = sqrt(ff);
34  m_rtol = 1.0e-5;
35 }
36 
37 void MultiJac::updateTransient(doublereal rdt, integer* mask)
38 {
39  for (size_t n = 0; n < m_size; n++) {
40  value(n,n) = m_ssdiag[n] - mask[n]*rdt;
41  }
42 }
43 
44 void MultiJac::incrementDiagonal(int j, doublereal d)
45 {
46  m_ssdiag[j] += d;
47  value(j,j) = m_ssdiag[j];
48 }
49 
50 /**
51  * Evaluate the Jacobian at x0. The array of residual values at x0
52  * is supplied as an input.
53  */
54 void MultiJac::eval(doublereal* x0, doublereal* resid0, doublereal rdt)
55 {
56  m_nevals++;
57  clock_t t0 = clock();
58  bfill(0.0);
59  size_t n, m, ipt=0, j, nv, mv, iloc;
60  doublereal rdx, dx, xsave;
61 
62  for (j = 0; j < m_points; j++) {
63  nv = m_resid->nVars(j);
64  for (n = 0; n < nv; n++) {
65 
66  // perturb x(n)
67  xsave = x0[ipt];
68  dx = m_atol + fabs(xsave)*m_rtol;
69  x0[ipt] = xsave + dx;
70  dx = x0[ipt] - xsave;
71  rdx = 1.0/dx;
72 
73  // calculate perturbed residual
74  m_resid->eval(j, x0, DATA_PTR(m_r1), rdt, 0);
75 
76  // compute nth column of Jacobian
77  for (size_t i = j - 1; i != j+2; i++) {
78  if (i != npos && i < m_points) {
79  mv = m_resid->nVars(i);
80  iloc = m_resid->loc(i);
81  for (m = 0; m < mv; m++) {
82  value(m+iloc,ipt) = (m_r1[m+iloc]
83  - resid0[m+iloc])*rdx;
84  }
85  }
86  }
87  x0[ipt] = xsave;
88  ipt++;
89  }
90 
91  }
92 
93  for (n = 0; n < m_size; n++) {
94  m_ssdiag[n] = value(n,n);
95  }
96 
97  m_elapsed += double(clock() - t0)/CLOCKS_PER_SEC;
98  m_age = 0;
99 }
100 
101 } // namespace
102 
103 // $Log: MultiJac.cpp,v