Cantera  2.0
Domain1D.cpp
Go to the documentation of this file.
1 /**
2  * @file Domain1D.cpp
3  *
4  */
5 
7 
8 #include <cstdio>
9 
10 using namespace std;
11 
12 namespace Cantera
13 {
14 
15 void Domain1D::
16 setTolerances(size_t nr, const doublereal* rtol,
17  size_t na, const doublereal* atol, int ts)
18 {
19  if (nr < m_nv || na < m_nv)
20  throw CanteraError("Domain1D::setTolerances",
21  "wrong array size for solution error tolerances. "
22  "Size should be at least "+int2str(m_nv));
23  if (ts >= 0) {
24  copy(rtol, rtol + m_nv, m_rtol_ss.begin());
25  copy(atol, atol + m_nv, m_atol_ss.begin());
26  }
27  if (ts <= 0) {
28  copy(rtol, rtol + m_nv, m_rtol_ts.begin());
29  copy(atol, atol + m_nv, m_atol_ts.begin());
30  }
31 }
32 
33 void Domain1D::
34 setTolerances(size_t n, doublereal rtol, doublereal atol, int ts)
35 {
36  if (ts >= 0) {
37  m_rtol_ss[n] = rtol;
38  m_atol_ss[n] = atol;
39  }
40  if (ts <= 0) {
41  m_rtol_ts[n] = rtol;
42  m_atol_ts[n] = atol;
43  }
44 }
45 
46 void Domain1D::
47 setTolerances(doublereal rtol, doublereal atol,int ts)
48 {
49  for (size_t n = 0; n < m_nv; n++) {
50  if (ts >= 0) {
51  m_rtol_ss[n] = rtol;
52  m_atol_ss[n] = atol;
53  }
54  if (ts <= 0) {
55  m_rtol_ts[n] = rtol;
56  m_atol_ts[n] = atol;
57  }
58  }
59 }
60 
61 void Domain1D::
62 setTolerancesTS(doublereal rtol, doublereal atol)
63 {
64  for (size_t n = 0; n < m_nv; n++) {
65  m_rtol_ts[n] = rtol;
66  m_atol_ts[n] = atol;
67  }
68 }
69 
70 void Domain1D::
71 setTolerancesSS(doublereal rtol, doublereal atol)
72 {
73  for (size_t n = 0; n < m_nv; n++) {
74  m_rtol_ss[n] = rtol;
75  m_atol_ss[n] = atol;
76  }
77 }
78 
79 void Domain1D::
80 eval(size_t jg, doublereal* xg, doublereal* rg,
81  integer* mask, doublereal rdt)
82 {
83 
84  if (jg != npos && (jg + 1 < firstPoint() || jg > lastPoint() + 1)) {
85  return;
86  }
87 
88  // if evaluating a Jacobian, compute the steady-state residual
89  if (jg != npos) {
90  rdt = 0.0;
91  }
92 
93  // start of local part of global arrays
94  doublereal* x = xg + loc();
95  doublereal* rsd = rg + loc();
96  integer* diag = mask + loc();
97 
98  size_t jmin, jmax, jpt, j, i;
99  jpt = jg - firstPoint();
100 
101  if (jg == npos) { // evaluate all points
102  jmin = 0;
103  jmax = m_points - 1;
104  } else { // evaluate points for Jacobian
105  jmin = std::max<size_t>(jpt, 1) - 1;
106  jmax = std::min(jpt+1,m_points-1);
107  }
108 
109  for (j = jmin; j <= jmax; j++) {
110  if (j == 0 || j == m_points - 1) {
111  for (i = 0; i < m_nv; i++) {
112  rsd[index(i,j)] = residual(x,i,j);
113  diag[index(i,j)] = 0;
114  }
115  } else {
116  for (i = 0; i < m_nv; i++) {
117  rsd[index(i,j)] = residual(x,i,j)
118  - timeDerivativeFlag(i)*rdt*(value(x,i,j) - prevSoln(i,j));
119  diag[index(i,j)] = timeDerivativeFlag(i);
120  }
121  }
122  }
123 }
124 
125 
126 // called to set up initial grid, and after grid refinement
127 void Domain1D::setupGrid(size_t n, const doublereal* z)
128 {
129  if (n > 1) {
130  resize(m_nv, n);
131  for (size_t j = 0; j < m_points; j++) {
132  m_z[j] = z[j];
133  }
134  }
135 }
136 
137 
138 void drawline()
139 {
140  writelog("\n-------------------------------------"
141  "------------------------------------------");
142 }
143 
144 
145 /**
146  * Print the solution.
147  */
148 void Domain1D::showSolution(const doublereal* x)
149 {
150  size_t nn = m_nv/5;
151  size_t i, j, n;
152  //char* buf = new char[100];
153  char buf[100];
154  doublereal v;
155  for (i = 0; i < nn; i++) {
156  drawline();
157  sprintf(buf, "\n z ");
158  writelog(buf);
159  for (n = 0; n < 5; n++) {
160  sprintf(buf, " %10s ",componentName(i*5 + n).c_str());
161  writelog(buf);
162  }
163  drawline();
164  for (j = 0; j < m_points; j++) {
165  sprintf(buf, "\n %10.4g ",m_z[j]);
166  writelog(buf);
167  for (n = 0; n < 5; n++) {
168  v = value(x, i*5+n, j);
169  sprintf(buf, " %10.4g ",v);
170  writelog(buf);
171  }
172  }
173  writelog("\n");
174  }
175  size_t nrem = m_nv - 5*nn;
176  drawline();
177  sprintf(buf, "\n z ");
178  writelog(buf);
179  for (n = 0; n < nrem; n++) {
180  sprintf(buf, " %10s ", componentName(nn*5 + n).c_str());
181  writelog(buf);
182  }
183  drawline();
184  for (j = 0; j < m_points; j++) {
185  sprintf(buf, "\n %10.4g ",m_z[j]);
186  writelog(buf);
187  for (n = 0; n < nrem; n++) {
188  v = value(x, nn*5+n, j);
189  sprintf(buf, " %10.4g ", v);
190  writelog(buf);
191  }
192  }
193  writelog("\n");
194 }
195 
196 
197 // initial solution
198 void Domain1D::_getInitialSoln(doublereal* x)
199 {
200  for (size_t j = 0; j < m_points; j++) {
201  for (size_t n = 0; n < m_nv; n++) {
202  x[index(n,j)] = initialValue(n,j);
203  }
204  }
205 }
206 
207 doublereal Domain1D::initialValue(size_t n, size_t j)
208 {
209  throw CanteraError("Domain1D::initialValue",
210  "base class method called!");
211  return 0.0;
212 }
213 
214 
215 } // namespace