Mercurial > hg > octave-nkf
comparison liboctave/DASSL.cc @ 4049:a35a3c5d4740
[project @ 2002-08-16 08:54:31 by jwe]
author | jwe |
---|---|
date | Fri, 16 Aug 2002 08:54:31 +0000 |
parents | 7b0c139ac8af |
children | b79da8779a0e |
comparison
equal
deleted
inserted
replaced
4048:c9991c59cf5c | 4049:a35a3c5d4740 |
---|---|
54 static DAEFunc::DAERHSFunc user_fun; | 54 static DAEFunc::DAERHSFunc user_fun; |
55 static DAEFunc::DAEJacFunc user_jac; | 55 static DAEFunc::DAEJacFunc user_jac; |
56 | 56 |
57 static int nn; | 57 static int nn; |
58 | 58 |
59 DASSL::DASSL (void) : DAE () | 59 static int |
60 { | |
61 liw = 0; | |
62 lrw = 0; | |
63 | |
64 sanity_checked = false; | |
65 | |
66 info.resize (15); | |
67 | |
68 for (int i = 0; i < 15; i++) | |
69 info.elem (i) = 0; | |
70 } | |
71 | |
72 DASSL::DASSL (const ColumnVector& state, double time, DAEFunc& f) | |
73 : DAE (state, time, f) | |
74 { | |
75 n = size (); | |
76 | |
77 liw = 20 + n; | |
78 lrw = 40 + 9*n + n*n; | |
79 | |
80 sanity_checked = false; | |
81 | |
82 info.resize (15, 0); | |
83 } | |
84 | |
85 DASSL::DASSL (const ColumnVector& state, const ColumnVector& deriv, | |
86 double time, DAEFunc& f) | |
87 : DAE (state, deriv, time, f) | |
88 { | |
89 n = size (); | |
90 | |
91 DAEFunc::set_function (f.function ()); | |
92 DAEFunc::set_jacobian_function (f.jacobian_function ()); | |
93 | |
94 liw = 20 + n; | |
95 lrw = 40 + 9*n + n*n; | |
96 | |
97 sanity_checked = false; | |
98 | |
99 info.resize (15); | |
100 | |
101 for (int i = 0; i < 15; i++) | |
102 info.elem (i) = 0; | |
103 } | |
104 | |
105 int | |
106 ddassl_f (const double& time, const double *state, const double *deriv, | 60 ddassl_f (const double& time, const double *state, const double *deriv, |
107 double *delta, int& ires, double *, int *) | 61 double *delta, int& ires, double *, int *) |
108 { | 62 { |
109 // XXX FIXME XXX -- would be nice to avoid copying the data. | 63 // XXX FIXME XXX -- would be nice to avoid copying the data. |
110 | 64 |
132 } | 86 } |
133 | 87 |
134 return 0; | 88 return 0; |
135 } | 89 } |
136 | 90 |
137 int | 91 static int |
138 ddassl_j (const double& time, const double *state, const double *deriv, | 92 ddassl_j (const double& time, const double *state, const double *deriv, |
139 double *pd, const double& cj, double *, int *) | 93 double *pd, const double& cj, double *, int *) |
140 { | 94 { |
141 // XXX FIXME XXX -- would be nice to avoid copying the data. | 95 // XXX FIXME XXX -- would be nice to avoid copying the data. |
142 | 96 |
159 } | 113 } |
160 | 114 |
161 ColumnVector | 115 ColumnVector |
162 DASSL::do_integrate (double tout) | 116 DASSL::do_integrate (double tout) |
163 { | 117 { |
164 // XXX FIXME XXX -- should handle all this option stuff just once | |
165 // for each new problem. | |
166 | |
167 ColumnVector retval; | 118 ColumnVector retval; |
168 | 119 |
169 if (restart) | 120 if (! initialized || restart || DAEFunc::reset|| DASSL_options::reset) |
170 { | 121 { |
122 integration_error = false; | |
123 | |
124 initialized = true; | |
125 | |
126 info.resize (15); | |
127 | |
128 for (int i = 0; i < 15; i++) | |
129 info(i) = 0; | |
130 | |
131 pinfo = info.fortran_vec (); | |
132 | |
133 int n = size (); | |
134 | |
135 liw = 20 + n; | |
136 lrw = 40 + 9*n + n*n; | |
137 | |
138 nn = n; | |
139 | |
140 iwork.resize (liw); | |
141 rwork.resize (lrw); | |
142 | |
143 info(0) = 0; | |
144 | |
145 if (stop_time_set) | |
146 { | |
147 rwork(0) = stop_time; | |
148 info(3) = 1; | |
149 } | |
150 else | |
151 info(3) = 0; | |
152 | |
153 px = x.fortran_vec (); | |
154 pxdot = xdot.fortran_vec (); | |
155 | |
156 piwork = iwork.fortran_vec (); | |
157 prwork = rwork.fortran_vec (); | |
158 | |
171 restart = false; | 159 restart = false; |
172 info.elem (0) = 0; | 160 |
173 } | 161 // DAEFunc |
174 | 162 |
175 if (iwork.length () != liw) | 163 user_fun = DAEFunc::function (); |
176 iwork.resize (liw); | 164 user_jac = DAEFunc::jacobian_function (); |
177 | 165 |
178 if (rwork.length () != lrw) | 166 if (user_fun) |
179 rwork.resize (lrw); | 167 { |
180 | 168 int ires = 0; |
181 integration_error = false; | 169 |
182 | 170 ColumnVector res = (*user_fun) (x, xdot, t, ires); |
183 user_fun = DAEFunc::fun; | 171 |
184 user_jac = DAEFunc::jac; | 172 if (res.length () != x.length ()) |
185 | 173 { |
186 if (user_jac) | 174 (*current_liboctave_error_handler) |
187 info.elem (4) = 1; | 175 ("dassl: inconsistent sizes for state and residual vectors"); |
188 else | 176 |
189 info.elem (4) = 0; | 177 integration_error = true; |
190 | 178 return retval; |
191 double *px = x.fortran_vec (); | 179 } |
192 double *pxdot = xdot.fortran_vec (); | 180 } |
193 | 181 else |
194 nn = n; | |
195 | |
196 if (! sanity_checked) | |
197 { | |
198 int ires = 0; | |
199 | |
200 ColumnVector res = (*user_fun) (x, xdot, t, ires); | |
201 | |
202 if (res.length () != x.length ()) | |
203 { | 182 { |
204 (*current_liboctave_error_handler) | 183 (*current_liboctave_error_handler) |
205 ("dassl: inconsistent sizes for state and residual vectors"); | 184 ("dassl: no user supplied RHS subroutine!"); |
206 | 185 |
207 integration_error = true; | 186 integration_error = true; |
208 return retval; | 187 return retval; |
209 } | 188 } |
210 | 189 |
211 sanity_checked = true; | 190 info(4) = user_jac ? 1 : 0; |
212 } | |
213 | 191 |
214 if (stop_time_set) | 192 DAEFunc::reset = false; |
215 { | 193 |
216 rwork.elem (0) = stop_time; | 194 // DASSL_options |
217 info.elem (3) = 1; | 195 |
218 } | 196 double hmax = maximum_step_size (); |
219 else | 197 if (hmax >= 0.0) |
220 info.elem (3) = 0; | 198 { |
221 | 199 rwork(1) = hmax; |
222 Array<double> abs_tol = absolute_tolerance (); | 200 info(6) = 1; |
223 Array<double> rel_tol = relative_tolerance (); | 201 } |
224 | 202 else |
225 int abs_tol_len = abs_tol.length (); | 203 info(6) = 0; |
226 int rel_tol_len = rel_tol.length (); | 204 |
227 | 205 double h0 = initial_step_size (); |
228 if (abs_tol_len == 1 && rel_tol_len == 1) | 206 if (h0 >= 0.0) |
229 { | 207 { |
230 info.elem (1) = 0; | 208 rwork(2) = h0; |
231 } | 209 info(7) = 1; |
232 else if (abs_tol_len == n && rel_tol_len == n) | 210 } |
233 { | 211 else |
234 info.elem (1) = 1; | 212 info(7) = 0; |
235 } | 213 |
236 else | 214 int maxord = maximum_order (); |
237 { | 215 if (maxord >= 0) |
238 (*current_liboctave_error_handler) | 216 { |
239 ("dassl: inconsistent sizes for tolerance arrays"); | 217 if (maxord > 0 && maxord < 6) |
240 | 218 { |
241 integration_error = true; | 219 info(8) = 1; |
242 return retval; | 220 iwork(2) = maxord; |
243 } | 221 } |
244 | 222 else |
245 double hmax = maximum_step_size (); | 223 { |
246 if (hmax >= 0.0) | 224 (*current_liboctave_error_handler) |
247 { | 225 ("dassl: invalid value for maximum order"); |
248 rwork.elem (1) = hmax; | 226 integration_error = true; |
249 info.elem (6) = 1; | 227 return retval; |
250 } | 228 } |
251 else | 229 } |
252 info.elem (6) = 0; | 230 |
253 | 231 int enc = enforce_nonnegativity_constraints (); |
254 double h0 = initial_step_size (); | 232 info(9) = enc ? 1 : 0; |
255 if (h0 >= 0.0) | 233 |
256 { | 234 int ccic = compute_consistent_initial_condition (); |
257 rwork.elem (2) = h0; | 235 info(10) = ccic ? 1 : 0; |
258 info.elem (7) = 1; | 236 |
259 } | 237 abs_tol = absolute_tolerance (); |
260 else | 238 rel_tol = relative_tolerance (); |
261 info.elem (7) = 0; | 239 |
262 | 240 int abs_tol_len = abs_tol.length (); |
263 int maxord = maximum_order (); | 241 int rel_tol_len = rel_tol.length (); |
264 if (maxord >= 0) | 242 |
265 { | 243 if (abs_tol_len == 1 && rel_tol_len == 1) |
266 if (maxord > 0 && maxord < 6) | 244 { |
267 { | 245 info(1) = 0; |
268 info(8) = 1; | 246 } |
269 iwork(2) = maxord; | 247 else if (abs_tol_len == n && rel_tol_len == n) |
248 { | |
249 info(1) = 1; | |
270 } | 250 } |
271 else | 251 else |
272 { | 252 { |
273 (*current_liboctave_error_handler) | 253 (*current_liboctave_error_handler) |
274 ("dassl: invalid value for maximum order"); | 254 ("dassl: inconsistent sizes for tolerance arrays"); |
255 | |
275 integration_error = true; | 256 integration_error = true; |
276 return retval; | 257 return retval; |
277 } | 258 } |
278 } | 259 |
279 | 260 pabs_tol = abs_tol.fortran_vec (); |
280 int enc = enforce_nonnegativity_constraints (); | 261 prel_tol = rel_tol.fortran_vec (); |
281 info (9) = enc ? 1 : 0; | 262 |
282 | 263 DASSL_options::reset = false; |
283 int ccic = compute_consistent_initial_condition (); | 264 } |
284 info(10) = ccic ? 1 : 0; | 265 |
285 | 266 static double *dummy = 0; |
286 double *dummy = 0; | 267 static int *idummy = 0; |
287 int *idummy = 0; | 268 |
288 | 269 F77_XFCN (ddassl, DDASSL, (ddassl_f, nn, t, px, pxdot, tout, pinfo, |
289 int *pinfo = info.fortran_vec (); | |
290 int *piwork = iwork.fortran_vec (); | |
291 double *prwork = rwork.fortran_vec (); | |
292 double *pabs_tol = abs_tol.fortran_vec (); | |
293 double *prel_tol = rel_tol.fortran_vec (); | |
294 | |
295 // again: | |
296 | |
297 F77_XFCN (ddassl, DDASSL, (ddassl_f, n, t, px, pxdot, tout, pinfo, | |
298 prel_tol, pabs_tol, istate, prwork, lrw, | 270 prel_tol, pabs_tol, istate, prwork, lrw, |
299 piwork, liw, dummy, idummy, ddassl_j)); | 271 piwork, liw, dummy, idummy, ddassl_j)); |
300 | 272 |
301 if (f77_exception_encountered) | 273 if (f77_exception_encountered) |
302 { | 274 { |
364 | 336 |
365 Matrix | 337 Matrix |
366 DASSL::integrate (const ColumnVector& tout, Matrix& xdot_out) | 338 DASSL::integrate (const ColumnVector& tout, Matrix& xdot_out) |
367 { | 339 { |
368 Matrix retval; | 340 Matrix retval; |
341 | |
369 int n_out = tout.capacity (); | 342 int n_out = tout.capacity (); |
343 int n = size (); | |
370 | 344 |
371 if (n_out > 0 && n > 0) | 345 if (n_out > 0 && n > 0) |
372 { | 346 { |
373 retval.resize (n_out, n); | 347 retval.resize (n_out, n); |
374 xdot_out.resize (n_out, n); | 348 xdot_out.resize (n_out, n); |
407 Matrix | 381 Matrix |
408 DASSL::integrate (const ColumnVector& tout, Matrix& xdot_out, | 382 DASSL::integrate (const ColumnVector& tout, Matrix& xdot_out, |
409 const ColumnVector& tcrit) | 383 const ColumnVector& tcrit) |
410 { | 384 { |
411 Matrix retval; | 385 Matrix retval; |
386 | |
412 int n_out = tout.capacity (); | 387 int n_out = tout.capacity (); |
388 int n = size (); | |
413 | 389 |
414 if (n_out > 0 && n > 0) | 390 if (n_out > 0 && n > 0) |
415 { | 391 { |
416 retval.resize (n_out, n); | 392 retval.resize (n_out, n); |
417 xdot_out.resize (n_out, n); | 393 xdot_out.resize (n_out, n); |