16
16
use std:: {
17
17
borrow:: Borrow ,
18
18
ffi:: { c_int, c_void, c_long} ,
19
- marker:: PhantomData , ptr ,
19
+ marker:: PhantomData ,
20
20
} ;
21
21
use sundials_sys:: * ;
22
22
use super :: {
@@ -231,81 +231,82 @@ where
231
231
cvode_mem. 0 ,
232
232
Some ( Self :: cvrhs) ,
233
233
self . t0 ,
234
- y0 as * mut _ ) } ;
235
- if r == CV_MEM_FAIL {
236
- let msg = "a memory allocation request has failed" ;
237
- return Err ( Error :: Failure { name : self . name , msg} )
238
- }
239
- if r == CV_ILL_INPUT {
240
- let msg = "An input argument has an illegal value" ;
241
- return Err ( Error :: Failure { name : self . name , msg} )
242
- }
234
+ V :: as_ptr ( & y0) ) // `CVodeInit` does not modify `y0`.
235
+ } ;
236
+ // if r == CV_MEM_FAIL {
237
+ // let msg = "a memory allocation request has failed";
238
+ // return Err(Error::Failure{name: self.name, msg})
239
+ // }
240
+ // if r == CV_ILL_INPUT {
241
+ // let msg = "An input argument has an illegal value";
242
+ // return Err(Error::Failure{name: self.name, msg})
243
+ // }
243
244
// Set default tolerances (otherwise the solver will complain).
244
- unsafe { CVodeSStolerances (
245
- cvode_mem. 0 , self . rtol , self . atol ) ; }
245
+ // unsafe { CVodeSStolerances(
246
+ // cvode_mem.0, self.rtol, self.atol); }
246
247
// Set the default linear solver to one that does not require
247
248
// the `…nvgetarraypointer` on vectors (FIXME: configurable)
248
- let linsolver = unsafe { LinSolver :: spgmr (
249
- self . name ,
250
- ctx. as_ptr ( ) ,
251
- y0 as * mut _ ) ? } ;
252
- let r = unsafe { CVodeSetLinearSolver (
253
- cvode_mem. 0 , linsolver. as_ptr ( ) , ptr:: null_mut ( ) ) } ;
254
- if r != CVLS_SUCCESS as i32 {
255
- return Err ( Error :: Failure {
256
- name : self . name ,
257
- msg : "could not attach linear solver"
258
- } )
259
- }
260
- if let Some ( maxord) = self . maxord {
261
- unsafe { CVodeSetMaxOrd (
262
- cvode_mem. 0 ,
263
- maxord as _ ) ; }
264
- }
265
- if let Some ( mxsteps) = self . mxsteps {
266
- let n: c_long =
267
- if mxsteps <= c_long:: MAX as usize { mxsteps as _ }
268
- else { c_long:: MAX } ;
269
- unsafe { CVodeSetMaxNumSteps ( cvode_mem. 0 , n) } ;
270
- }
271
- if let Some ( tstop) = self . tstop {
272
- if tstop. is_nan ( ) {
273
- // unsafe { CVodeClearStopTime(cvode_mem.0); }
274
- ( )
275
- } else {
276
- let ret = unsafe { CVodeSetStopTime (
277
- cvode_mem. 0 ,
278
- tstop) } ;
279
- if ret == CV_ILL_INPUT {
280
- // FIXME: should not happen in this configuration
281
- // as it is fixed ahead of execution.
282
- let msg = "The 'tstop' time is not is not beyond \
283
- the current time value.";
284
- return Err ( Error :: Failure { name : self . name , msg } ) ;
285
- }
286
- }
287
- }
288
- unsafe { CVodeSetMaxHnilWarns ( cvode_mem. 0 , self . max_hnil_warns ) } ;
289
- let mut rootsfound;
290
- let n_roots = self . cb . n_roots ;
291
- if n_roots > 0 {
292
- let r = unsafe {
293
- CVodeRootInit ( cvode_mem. 0 , M as _ ,
294
- Some ( Self :: cvroot1) ) } ;
295
- if r == CV_MEM_FAIL {
296
- panic ! ( "Sundials::cvode::CVode::root: memory allocation \
297
- failed.") ;
298
- }
299
- rootsfound = Vec :: with_capacity ( M ) ;
300
- rootsfound. resize ( M , 0 ) ;
301
- } else {
302
- rootsfound = vec ! [ ] ;
303
- }
249
+ // let linsolver = unsafe { LinSolver::spgmr(
250
+ // self.name,
251
+ // ctx.as_ptr(),
252
+ // y0 as *mut _)? };
253
+ // let r = unsafe { CVodeSetLinearSolver(
254
+ // cvode_mem.0, linsolver.as_ptr(), ptr::null_mut()) };
255
+ // if r != CVLS_SUCCESS as i32 {
256
+ // return Err(Error::Failure {
257
+ // name: self.name,
258
+ // msg: "could not attach linear solver"
259
+ // })
260
+ // }
261
+ // if let Some(maxord) = self.maxord {
262
+ // unsafe { CVodeSetMaxOrd(
263
+ // cvode_mem.0,
264
+ // maxord as _); }
265
+ // }
266
+ // if let Some(mxsteps) = self.mxsteps {
267
+ // let n: c_long =
268
+ // if mxsteps <= c_long::MAX as usize { mxsteps as _ }
269
+ // else { c_long::MAX };
270
+ // unsafe { CVodeSetMaxNumSteps(cvode_mem.0, n) };
271
+ // }
272
+ // if let Some(tstop) = self.tstop {
273
+ // if tstop.is_nan() {
274
+ // // unsafe { CVodeClearStopTime(cvode_mem.0); }
275
+ // ()
276
+ // } else {
277
+ // let ret = unsafe { CVodeSetStopTime(
278
+ // cvode_mem.0,
279
+ // tstop) };
280
+ // if ret == CV_ILL_INPUT {
281
+ // // FIXME: should not happen in this configuration
282
+ // // as it is fixed ahead of execution.
283
+ // let msg = "The 'tstop' time is not is not beyond \
284
+ // the current time value.";
285
+ // return Err(Error::Failure { name: self.name, msg });
286
+ // }
287
+ // }
288
+ // }
289
+ // unsafe { CVodeSetMaxHnilWarns(cvode_mem.0, self.max_hnil_warns) };
290
+ // let mut rootsfound;
291
+ // let n_roots = self.cb.n_roots;
292
+ // if n_roots > 0 {
293
+ // let r = unsafe {
294
+ // CVodeRootInit(cvode_mem.0, n_roots as _,
295
+ // Some(Self::cvroot1)) };
296
+ // if r == CV_MEM_FAIL {
297
+ // panic!("Sundials::cvode::CVode::root: memory allocation \
298
+ // failed.");
299
+ // }
300
+ // rootsfound = Vec::with_capacity(n_roots );
301
+ // rootsfound.resize(n_roots , 0);
302
+ // } else {
303
+ // rootsfound = vec![];
304
+ // }
304
305
Ok ( CVode {
305
306
ctx, cvode_mem,
306
307
t0 : self . t0 , len, vec : PhantomData ,
307
- _matrix : None , _linsolver : Some ( linsolver) ,
308
- rootsfound,
308
+ _matrix : None , _linsolver : None , // Some(linsolver),
309
+ rootsfound : vec ! [ ] ,
309
310
cb : self . cb ,
310
311
} )
311
312
}
@@ -352,13 +353,18 @@ where
352
353
}
353
354
}
354
355
355
- // Implement the Drop trait only on the pointer to be able to move
356
- // values out of the structure `CVode`.
356
+ // `cvode` depends on the context, so store it alongside.
357
357
#[ derive( Debug ) ]
358
358
struct CVodeMem ( * mut c_void ) ;
359
359
360
+ // Implement the Drop trait only on the pointer to be able to move
361
+ // values out of the structure `CVode`.
360
362
impl Drop for CVodeMem {
361
- fn drop ( & mut self ) { unsafe { CVodeFree ( & mut self . 0 ) } }
363
+ fn drop ( & mut self ) {
364
+ println ! ( "drop(CVodeMem) {:?}" , self . 0 ) ;
365
+ unsafe { CVodeFree ( & mut self . 0 ) }
366
+ println ! ( "drop(CVodeMem) done" ) ;
367
+ }
362
368
}
363
369
364
370
impl CVodeMem {
@@ -417,7 +423,7 @@ where V: Vector,
417
423
// We hold `Matrix` and `LinSolver` so they are freed when `CVode`
418
424
// is dropped.
419
425
_matrix : Option < Matrix > ,
420
- _linsolver : Option < LinSolver > ,
426
+ _linsolver : Option < LinSolver > , // depends on `ctx`
421
427
rootsfound : Vec < c_int > , // cache, with len() == number of eq
422
428
cb : CB ,
423
429
cvode_mem : CVodeMem , // depends on `ctx`.
@@ -546,7 +552,7 @@ where
546
552
// Reinitialize to allow any time `t`, even if not monotonic
547
553
// w.r.t. previous calls.
548
554
let ret = unsafe {
549
- CVodeReInit ( self . cvode_mem . 0 , t0, y0 as * mut _ )
555
+ CVodeReInit ( self . cvode_mem . 0 , t0, V :: as_ptr ( & y0 ) )
550
556
} ;
551
557
if ret != CV_SUCCESS {
552
558
panic ! ( "CVodeReInit returned code {ret}. Please report." ) ;
@@ -584,7 +590,7 @@ where Ctx: Context,
584
590
// Safety: `yout` does not escape this function and so will
585
591
// not outlive `self.ctx` and `y` will not move while `yout`
586
592
// is in use.
587
- let yout =
593
+ let mut yout =
588
594
match unsafe { V :: as_mut_nvector ( y, self . ctx . as_ptr ( ) ) } {
589
595
Some ( yout) => yout,
590
596
None => panic ! ( "The context of the output vector y is not \
@@ -594,7 +600,7 @@ where Ctx: Context,
594
600
let r = unsafe { CVode (
595
601
self . cvode_mem . 0 ,
596
602
t,
597
- yout,
603
+ V :: as_mut_ptr ( & mut yout) ,
598
604
& mut tret, itask) } ;
599
605
let status = match r {
600
606
CV_SUCCESS => CVStatus :: Ok ,
0 commit comments