@@ -222,55 +222,56 @@ where
222
222
msg : "could not attach linear solver"
223
223
} )
224
224
}
225
- if let Some ( maxord) = self . maxord {
226
- unsafe { CVodeSetMaxOrd (
227
- cvode_mem. 0 ,
228
- maxord as _ ) ; }
229
- }
230
- if let Some ( mxsteps) = self . mxsteps {
231
- let n: c_long =
232
- if mxsteps <= c_long:: MAX as usize { mxsteps as _ }
233
- else { c_long:: MAX } ;
234
- unsafe { CVodeSetMaxNumSteps ( cvode_mem. 0 , n) } ;
235
- }
236
- if let Some ( tstop) = self . tstop {
237
- if tstop. is_nan ( ) {
238
- // unsafe { CVodeClearStopTime(self.cvode_mem.0); }
239
- ( )
240
- } else {
241
- let ret = unsafe { CVodeSetStopTime (
242
- cvode_mem. 0 ,
243
- tstop) } ;
244
- if ret == CV_ILL_INPUT {
245
- // FIXME: should not happen in this configuration
246
- // as it is fixed ahead of execution.
247
- let msg = "The 'tstop' time is not is not beyond \
248
- the current time value.";
249
- return Err ( Error :: Failure { name : self . name , msg } ) ;
250
- }
251
- }
252
- }
253
- unsafe { CVodeSetMaxHnilWarns ( cvode_mem. 0 , self . max_hnil_warns ) } ;
254
- let mut rootsfound;
255
- if M > 0 {
256
- let r = unsafe {
257
- CVodeRootInit ( cvode_mem. 0 , M as _ ,
258
- Some ( Self :: cvroot1) ) } ;
259
- if r == CV_MEM_FAIL {
260
- panic ! ( "Sundials::cvode::CVode::root: memory allocation \
261
- failed.") ;
262
- }
263
- rootsfound = Vec :: with_capacity ( M ) ;
264
- rootsfound. resize ( M , 0 ) ;
265
- } else {
266
- rootsfound = vec ! [ ] ;
267
- }
225
+ // if let Some(maxord) = self.maxord {
226
+ // unsafe { CVodeSetMaxOrd(
227
+ // cvode_mem.0,
228
+ // maxord as _); }
229
+ // }
230
+ // if let Some(mxsteps) = self.mxsteps {
231
+ // let n: c_long =
232
+ // if mxsteps <= c_long::MAX as usize { mxsteps as _ }
233
+ // else { c_long::MAX };
234
+ // unsafe { CVodeSetMaxNumSteps(cvode_mem.0, n) };
235
+ // }
236
+ // if let Some(tstop) = self.tstop {
237
+ // if tstop.is_nan() {
238
+ // // unsafe { CVodeClearStopTime(cvode_mem.0); }
239
+ // ()
240
+ // } else {
241
+ // let ret = unsafe { CVodeSetStopTime(
242
+ // cvode_mem.0,
243
+ // tstop) };
244
+ // if ret == CV_ILL_INPUT {
245
+ // // FIXME: should not happen in this configuration
246
+ // // as it is fixed ahead of execution.
247
+ // let msg = "The 'tstop' time is not is not beyond \
248
+ // the current time value.";
249
+ // return Err(Error::Failure { name: self.name, msg });
250
+ // }
251
+ // }
252
+ // }
253
+ // unsafe { CVodeSetMaxHnilWarns(cvode_mem.0, self.max_hnil_warns) };
254
+ // let mut rootsfound;
255
+ // let n_roots = self.cb.n_roots();
256
+ // if n_roots > 0 {
257
+ // let r = unsafe {
258
+ // CVodeRootInit(cvode_mem.0, n_roots as _,
259
+ // Some(Self::cvroot1)) };
260
+ // if r == CV_MEM_FAIL {
261
+ // panic!("Sundials::cvode::CVode::root: memory allocation \
262
+ // failed.");
263
+ // }
264
+ // rootsfound = Vec::with_capacity(n_roots);
265
+ // rootsfound.resize(n_roots, 0);
266
+ // } else {
267
+ // rootsfound = vec![];
268
+ // }
268
269
Ok ( CVode {
269
270
ctx, cvode_mem,
270
271
t0 : self . t0 , len, vec : PhantomData ,
271
272
_matrix : None , _linsolver : Some ( linsolver) ,
272
- rootsfound,
273
273
user_data : UserData { f : self . f , g : self . g }
274
+ rootsfound: vec ! [ ] ,
274
275
} )
275
276
}
276
277
@@ -316,13 +317,21 @@ where
316
317
}
317
318
}
318
319
319
- // Implement the Drop trait only on the pointer to be able to move
320
- // values out of the structure `CVode`.
320
+ // `cvode` depends on the context, so store it alongside.
321
321
#[ derive( Debug ) ]
322
322
struct CVodeMem ( * mut c_void ) ;
323
323
324
+
325
+ // Implement the Drop trait only on the pointer to be able to move
326
+ // values out of the structure `CVode`.
324
327
impl Drop for CVodeMem {
325
- fn drop ( & mut self ) { unsafe { CVodeFree ( & mut self . 0 ) } }
328
+ fn drop ( & mut self ) {
329
+ println ! ( "drop(CVodeMem) {:?}" , self . 0 ) ;
330
+ unsafe { CVodeFree ( & mut self . 0 ) }
331
+ println ! ( "drop(CVodeMem) done" ) ;
332
+ }
333
+ }
334
+
326
335
impl CVodeMem {
327
336
/// Return a new [`CVodeMem`] structure.
328
337
fn new (
@@ -368,19 +377,23 @@ pub enum CVStatus {
368
377
/// context, `V` is the type of vectors and `M` the number of
369
378
/// functions we want to seek roots of.
370
379
pub struct CVode < Ctx , V , F , G >
371
- where V : Vector {
372
- // One must take ownership of the context because it can only be
373
- // used in a single ODE solver.
374
- ctx : Ctx ,
375
- cvode_mem : CVodeMem ,
380
+ where V : Vector ,
381
+ {
382
+ // "The fields of a struct are dropped in declaration order"
383
+ // (https://doc.rust-lang.org/reference/destructors.html). This is
384
+ // important here because of the dependencies between the fields.
376
385
t0 : f64 ,
377
386
len : usize , // length of vectors
378
387
vec : PhantomData < V > ,
379
388
// We hold `Matrix` and `LinSolver` so they are freed when `CVode`
380
389
// is dropped.
381
390
_matrix : Option < Matrix > ,
382
- _linsolver : Option < LinSolver > ,
391
+ _linsolver : Option < LinSolver > , // depends on `ctx`
383
392
rootsfound : Vec < c_int > , // cache, with len() == number of eq
393
+ cvode_mem : CVodeMem , // depends on `ctx`.
394
+ // One must take ownership of the context because it can only be
395
+ // used in a single ODE solver.
396
+ ctx : Ctx ,
384
397
user_data : UserData < F , G > ,
385
398
}
386
399
0 commit comments