PageRenderTime 85ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/src/sundials/cvodes/cvodea.c

https://bitbucket.org/nrnhines/nrn
C | 2119 lines | 1256 code | 505 blank | 358 comment | 238 complexity | a26ecd4776d59fe6f80384ede80008b6 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * -----------------------------------------------------------------
  3. * $Revision: 855 $
  4. * $Date: 2005-02-10 00:15:46 +0100 (Thu, 10 Feb 2005) $
  5. * -----------------------------------------------------------------
  6. * Programmer(s): Radu Serban @ LLNL
  7. * -----------------------------------------------------------------
  8. * Copyright (c) 2002, The Regents of the University of California.
  9. * Produced at the Lawrence Livermore National Laboratory.
  10. * All rights reserved.
  11. * For details, see sundials/cvodes/LICENSE.
  12. * -----------------------------------------------------------------
  13. * This is the implementation file for the CVODEA adjoint integrator.
  14. * -----------------------------------------------------------------
  15. */
  16. /*=================================================================*/
  17. /*BEGIN Import Header Files */
  18. /*=================================================================*/
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include "cvdiag.h"
  22. #include "cvodea_impl.h"
  23. #include "sundialsmath.h"
  24. #include "sundialstypes.h"
  25. /*=================================================================*/
  26. /*BEGIN Macros */
  27. /*=================================================================*/
  28. /* Macro: loop */
  29. #define loop for(;;)
  30. /*=================================================================*/
  31. /*BEGIN CVODEA Private Constants */
  32. /*=================================================================*/
  33. #define ZERO RCONST(0.0) /* real 0.0 */
  34. #define ONE RCONST(1.0) /* real 1.0 */
  35. #define TWO RCONST(2.0) /* real 2.0 */
  36. #define FUZZ_FACTOR RCONST(1000000.0) /* fuzz factor for CVadjGetY */
  37. /*=================================================================*/
  38. /*BEGIN Private Functions Prototypes */
  39. /*=================================================================*/
  40. static CkpntMem CVAckpntInit(CVodeMem cv_mem);
  41. static CkpntMem CVAckpntNew(CVodeMem cv_mem);
  42. static void CVAckpntDelete(CkpntMem *ck_memPtr);
  43. static DtpntMem *CVAdataMalloc(CVodeMem cv_mem, long int steps);
  44. static void CVAdataFree(DtpntMem *dt_mem, long int steps);
  45. static int CVAdataStore(CVadjMem ca_mem, CkpntMem ck_mem);
  46. static int CVAckpntGet(CVodeMem cv_mem, CkpntMem ck_mem);
  47. static void CVAhermitePrepare(CVadjMem ca_mem, DtpntMem *dt_mem, long int i);
  48. static void CVAhermiteInterpolate(CVadjMem ca_mem, DtpntMem *dt_mem,
  49. long int i, realtype t, N_Vector y);
  50. /* Wrappers */
  51. static void CVArhs(realtype t, N_Vector yB,
  52. N_Vector yBdot, void *cvadj_mem);
  53. static void CVAdenseJac(long int nB, DenseMat JB, realtype t,
  54. N_Vector yB, N_Vector fyB, void *cvadj_mem,
  55. N_Vector tmp1B, N_Vector tmp2B, N_Vector tmp3B);
  56. static void CVAbandJac(long int nB, long int mupperB,
  57. long int mlowerB, BandMat JB, realtype t,
  58. N_Vector yB, N_Vector fyB, void *cvadj_mem,
  59. N_Vector tmp1B, N_Vector tmp2B, N_Vector tmp3B);
  60. static int CVAspgmrPrecSetup(realtype t, N_Vector yB,
  61. N_Vector fyB, booleantype jokB,
  62. booleantype *jcurPtrB, realtype gammaB,
  63. void *cvadj_mem,
  64. N_Vector tmp1B, N_Vector tmp2B, N_Vector tmp3B);
  65. static int CVAspgmrPrecSolve(realtype t, N_Vector yB, N_Vector fyB,
  66. N_Vector rB, N_Vector zB,
  67. realtype gammaB, realtype deltaB,
  68. int lrB, void *cvadj_mem, N_Vector tmpB);
  69. static int CVAspgmrJacTimesVec(N_Vector vB, N_Vector JvB, realtype t,
  70. N_Vector yB, N_Vector fyB,
  71. void *cvadj_mem, N_Vector tmpB);
  72. static void CVArhsQ(realtype t, N_Vector yB,
  73. N_Vector qBdot, void *cvadj_mem);
  74. static void CVAgloc(long int NlocalB, realtype t, N_Vector yB, N_Vector gB,
  75. void *cvadj_mem);
  76. static void CVAcfn(long int NlocalB, realtype t, N_Vector yB,
  77. void *cvadj_mem);
  78. /*=================================================================*/
  79. /*END Private Functions Prototypes */
  80. /*=================================================================*/
  81. /*=================================================================*/
  82. /*BEGIN Readibility Constants */
  83. /*=================================================================*/
  84. #define uround (ca_mem->ca_uround)
  85. #define tinitial (ca_mem->ca_tinitial)
  86. #define tfinal (ca_mem->ca_tfinal)
  87. #define nckpnts (ca_mem->ca_nckpnts)
  88. #define nsteps (ca_mem->ca_nsteps)
  89. #define ckpntData (ca_mem->ca_ckpntData)
  90. #define newData (ca_mem->ca_newData)
  91. #define np (ca_mem->ca_np)
  92. #define delta (ca_mem->ca_delta)
  93. #define Y0 (ca_mem->ca_Y0)
  94. #define Y1 (ca_mem->ca_Y1)
  95. #define ytmp (ca_mem->ca_ytmp)
  96. #define f_B (ca_mem->ca_fB)
  97. #define f_data_B (ca_mem->ca_f_dataB)
  98. #define djac_B (ca_mem->ca_djacB)
  99. #define bjac_B (ca_mem->ca_bjacB)
  100. #define jtimes_B (ca_mem->ca_jtimesB)
  101. #define jac_data_B (ca_mem->ca_jac_dataB)
  102. #define pset_B (ca_mem->ca_psetB)
  103. #define psolve_B (ca_mem->ca_psolveB)
  104. #define P_data_B (ca_mem->ca_P_dataB)
  105. #define fQ_B (ca_mem->ca_fQB)
  106. #define fQ_data_B (ca_mem->ca_fQ_dataB)
  107. #define gloc_B (ca_mem->ca_glocB)
  108. #define cfn_B (ca_mem->ca_cfnB)
  109. #define bbd_data_B (ca_mem->ca_bbd_dataB)
  110. #define bp_data_B (ca_mem->ca_bp_dataB)
  111. #define t_for_quad (ca_mem->ca_t_for_quad)
  112. #define zn (cv_mem->cv_zn)
  113. #define nst (cv_mem->cv_nst)
  114. #define q (cv_mem->cv_q)
  115. #define qprime (cv_mem->cv_qprime)
  116. #define qwait (cv_mem->cv_qwait)
  117. #define L (cv_mem->cv_L)
  118. #define gammap (cv_mem->cv_gammap)
  119. #define h (cv_mem->cv_h)
  120. #define hprime (cv_mem->cv_hprime)
  121. #define hscale (cv_mem->cv_hscale)
  122. #define eta (cv_mem->cv_eta)
  123. #define etamax (cv_mem->cv_etamax)
  124. #define tn (cv_mem->cv_tn)
  125. #define tau (cv_mem->cv_tau)
  126. #define tq (cv_mem->cv_tq)
  127. #define l (cv_mem->cv_l)
  128. #define saved_tq5 (cv_mem->cv_saved_tq5)
  129. #define forceSetup (cv_mem->cv_forceSetup)
  130. #define f (cv_mem->cv_f)
  131. #define lmm (cv_mem->cv_lmm)
  132. #define iter (cv_mem->cv_iter)
  133. #define itol (cv_mem->cv_itol)
  134. #define reltol (cv_mem->cv_reltol)
  135. #define abstol (cv_mem->cv_abstol)
  136. #define f_data (cv_mem->cv_f_data)
  137. #define errfp (cv_mem->cv_errfp)
  138. #define h0u (cv_mem->cv_h0u)
  139. #define quadr (cv_mem->cv_quadr)
  140. #define errconQ (cv_mem->cv_errconQ)
  141. #define znQ (cv_mem->cv_znQ)
  142. #define itolQ (cv_mem->cv_itolQ)
  143. #define reltolQ (cv_mem->cv_reltolQ)
  144. #define abstolQ (cv_mem->cv_abstolQ)
  145. #define fQ (cv_mem->cv_fQ)
  146. #define tempv (cv_mem->cv_tempv)
  147. #define tempvQ (cv_mem->cv_tempvQ)
  148. #define t0_ (ck_mem->ck_t0)
  149. #define t1_ (ck_mem->ck_t1)
  150. #define zn_ (ck_mem->ck_zn)
  151. #define znQ_ (ck_mem->ck_znQ)
  152. #define quadr_ (ck_mem->ck_quadr)
  153. #define zqm_ (ck_mem->ck_zqm)
  154. #define nst_ (ck_mem->ck_nst)
  155. #define q_ (ck_mem->ck_q)
  156. #define qprime_ (ck_mem->ck_qprime)
  157. #define qwait_ (ck_mem->ck_qwait)
  158. #define L_ (ck_mem->ck_L)
  159. #define gammap_ (ck_mem->ck_gammap)
  160. #define h_ (ck_mem->ck_h)
  161. #define hprime_ (ck_mem->ck_hprime)
  162. #define hscale_ (ck_mem->ck_hscale)
  163. #define eta_ (ck_mem->ck_eta)
  164. #define etamax_ (ck_mem->ck_etamax)
  165. #define tau_ (ck_mem->ck_tau)
  166. #define tq_ (ck_mem->ck_tq)
  167. #define l_ (ck_mem->ck_l)
  168. #define saved_tq5_ (ck_mem->ck_saved_tq5)
  169. #define next_ (ck_mem->ck_next)
  170. /*=================================================================*/
  171. /*END Readibility Constants */
  172. /*=================================================================*/
  173. /*=================================================================*/
  174. /*BEGIN Exported Functions */
  175. /*=================================================================*/
  176. /*------------------ CVadjMalloc --------------------------*/
  177. /*
  178. This routine allocates space for the global CVODEA memory
  179. structure.
  180. */
  181. /*-----------------------------------------------------------------*/
  182. void *CVadjMalloc(void *cvode_mem, long int steps)
  183. {
  184. CVadjMem ca_mem;
  185. CVodeMem cv_mem;
  186. /* Check arguments */
  187. if (cvode_mem == NULL) {
  188. fprintf(stderr, MSGAM_NO_MEM);
  189. return(NULL);
  190. }
  191. if (steps <= 0) {
  192. fprintf(stderr, MSGAM_BAD_STEPS);
  193. return(NULL);
  194. }
  195. /* Allocate memory block */
  196. ca_mem = (CVadjMem) malloc(sizeof(struct CVadjMemRec));
  197. if (ca_mem == NULL) {
  198. fprintf(stderr, MSGAM_MEM_FAIL);
  199. return(NULL);
  200. }
  201. /* Attach CVODE memory for forward runs */
  202. cv_mem = (CVodeMem)cvode_mem;
  203. ca_mem->cv_mem = cv_mem;
  204. /* Initialize Check Points linked list */
  205. ca_mem->ck_mem = CVAckpntInit(cv_mem);
  206. if (ca_mem->ck_mem == NULL) {
  207. free(ca_mem);
  208. fprintf(stderr, MSGAM_MEM_FAIL);
  209. return(NULL);
  210. }
  211. /* Allocate Data Points memory */
  212. ca_mem->dt_mem = CVAdataMalloc(cv_mem, steps);
  213. if (ca_mem->dt_mem == NULL) {
  214. CVAckpntDelete(&(ca_mem->ck_mem));
  215. free(ca_mem);
  216. fprintf(stderr, MSGAM_MEM_FAIL);
  217. return(NULL);
  218. }
  219. /* Workspace memory */
  220. Y0 = N_VClone(tempv);
  221. if (Y0 == NULL) {
  222. CVAdataFree(ca_mem->dt_mem, steps);
  223. CVAckpntDelete(&(ca_mem->ck_mem));
  224. free(ca_mem);
  225. fprintf(stderr, MSGAM_MEM_FAIL);
  226. return(NULL);
  227. }
  228. Y1 = N_VClone(tempv);
  229. if (Y1 == NULL) {
  230. N_VDestroy(Y0);
  231. CVAdataFree(ca_mem->dt_mem, steps);
  232. CVAckpntDelete(&(ca_mem->ck_mem));
  233. free(ca_mem);
  234. fprintf(stderr, MSGAM_MEM_FAIL);
  235. return(NULL);
  236. }
  237. ytmp = N_VClone(tempv);
  238. if (ytmp == NULL) {
  239. N_VDestroy(Y0);
  240. N_VDestroy(Y1);
  241. CVAdataFree(ca_mem->dt_mem, steps);
  242. CVAckpntDelete(&(ca_mem->ck_mem));
  243. free(ca_mem);
  244. fprintf(stderr, MSGAM_MEM_FAIL);
  245. return(NULL);
  246. }
  247. /* Other entries in ca_mem */
  248. uround = cv_mem->cv_uround;
  249. nsteps = steps;
  250. tinitial = tn;
  251. /* Initialize nckpnts to ZERO */
  252. nckpnts = 0;
  253. /* Initialize backward cvode memory to NULL */
  254. ca_mem->cvb_mem = NULL;
  255. ca_mem->ca_f_dataB = NULL;
  256. ca_mem->ca_fQ_dataB = NULL;
  257. ca_mem->ca_jac_dataB = NULL;
  258. ca_mem->ca_P_dataB = NULL;
  259. ca_mem->ca_bp_dataB = NULL;
  260. ca_mem->ca_bbd_dataB = NULL;
  261. return((void *)ca_mem);
  262. }
  263. /*=================================================================*/
  264. /*BEGIN Wrappers for CVODEA */
  265. /*=================================================================*/
  266. /*------------------ CVodeF --------------------------*/
  267. /*
  268. This routine integrates to tout and returns solution into yout.
  269. In the same time, it stores check point data every 'steps' steps.
  270. CVodeF can be called repeatedly by the user.
  271. ncheckPtr points to the number of check points stored so far.
  272. */
  273. /*-----------------------------------------------------------------*/
  274. int CVodeF(void *cvadj_mem, realtype tout, N_Vector yout,
  275. realtype *tret, int itask, int *ncheckPtr)
  276. {
  277. CVadjMem ca_mem;
  278. CVodeMem cv_mem;
  279. CkpntMem tmp;
  280. DtpntMem *dt_mem;
  281. int cv_itask, flag;
  282. booleantype iret, istop;
  283. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  284. ca_mem = (CVadjMem) cvadj_mem;
  285. cv_mem = ca_mem->cv_mem;
  286. dt_mem = ca_mem->dt_mem;
  287. iret = TRUE;
  288. cv_itask = CV_ONE_STEP;
  289. /* Interpret itask */
  290. switch (itask) {
  291. case CV_NORMAL:
  292. iret = FALSE;
  293. istop = FALSE;
  294. cv_itask = CV_ONE_STEP;
  295. break;
  296. case CV_ONE_STEP:
  297. iret = TRUE;
  298. istop = FALSE;
  299. cv_itask = CV_ONE_STEP;
  300. break;
  301. case CV_NORMAL_TSTOP:
  302. iret = FALSE;
  303. istop = TRUE;
  304. cv_itask = CV_ONE_STEP_TSTOP;
  305. break;
  306. case CV_ONE_STEP_TSTOP:
  307. iret = TRUE;
  308. istop = TRUE;
  309. cv_itask = CV_ONE_STEP_TSTOP;
  310. break;
  311. }
  312. /* On the first step, load dt_mem[0] */
  313. if ( nst == 0) {
  314. dt_mem[0]->t = ca_mem->ck_mem->ck_t0;
  315. N_VScale(ONE, ca_mem->ck_mem->ck_zn[0], dt_mem[0]->y);
  316. N_VScale(ONE, ca_mem->ck_mem->ck_zn[1], dt_mem[0]->yd);
  317. }
  318. /* Integrate to tout (in CV_ONE_STEP mode) while loading check points */
  319. loop {
  320. /* Perform one step of the integration */
  321. flag = CVode(cv_mem, tout, yout, tret, cv_itask);
  322. if (flag < 0) break;
  323. /* Test if a new check point is needed */
  324. if ( nst % nsteps == 0 ) {
  325. ca_mem->ck_mem->ck_t1 = *tret;
  326. /* Create a new check point, load it, and append it to the list */
  327. tmp = CVAckpntNew(cv_mem);
  328. if (tmp == NULL) {
  329. flag = CV_MEM_FAIL;
  330. break;
  331. }
  332. tmp->ck_next = ca_mem->ck_mem;
  333. ca_mem->ck_mem = tmp;
  334. nckpnts++;
  335. forceSetup = TRUE;
  336. /* Reset i=0 and load dt_mem[0] */
  337. dt_mem[0]->t = ca_mem->ck_mem->ck_t0;
  338. N_VScale(ONE, ca_mem->ck_mem->ck_zn[0], dt_mem[0]->y);
  339. N_VScale(ONE, ca_mem->ck_mem->ck_zn[1], dt_mem[0]->yd);
  340. } else {
  341. /* Load next point in dt_mem */
  342. dt_mem[nst%nsteps]->t = *tret;
  343. N_VScale(ONE, yout, dt_mem[nst%nsteps]->y);
  344. CVodeGetDky(cv_mem, *tret, 1, dt_mem[nst%nsteps]->yd);
  345. }
  346. /* Set t1 field of the current ckeck point structure
  347. for the case in which there will be no future
  348. check points */
  349. ca_mem->ck_mem->ck_t1 = *tret;
  350. /* tfinal is now set to *tret */
  351. tfinal = *tret;
  352. /* Return if in CV_ONE_STEP mode */
  353. if (iret)
  354. break;
  355. /* Return if tout reached */
  356. if ( (*tret - tout)*h >= ZERO ) {
  357. *tret = tout;
  358. CVodeGetDky(cv_mem, tout, 0, yout);
  359. break;
  360. }
  361. } /* end of loop() */
  362. /* Get ncheck from ca_mem */
  363. *ncheckPtr = nckpnts;
  364. /* Data is available for the last interval */
  365. newData = TRUE;
  366. ckpntData = ca_mem->ck_mem;
  367. np = nst % nsteps + 1;
  368. return(flag);
  369. }
  370. /*-- CVodeCreateB, CVodeSet*B, CVodeMallocB, and CVodeReInitB -----*/
  371. /*-----------------------------------------------------------------*/
  372. int CVodeCreateB(void *cvadj_mem, int lmmB, int iterB)
  373. {
  374. CVadjMem ca_mem;
  375. void *cvode_mem;
  376. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  377. ca_mem = (CVadjMem) cvadj_mem;
  378. cvode_mem = CVodeCreate(lmmB, iterB);
  379. if (cvode_mem == NULL) return(CV_MEM_FAIL);
  380. ca_mem->cvb_mem = (CVodeMem) cvode_mem;
  381. return(CV_SUCCESS);
  382. }
  383. /*-----------------------------------------------------------------*/
  384. int CVodeSetIterTypeB(void *cvadj_mem, int iterB)
  385. {
  386. CVadjMem ca_mem;
  387. void *cvode_mem;
  388. int flag;
  389. ca_mem = (CVadjMem) cvadj_mem;
  390. cvode_mem = (void *)ca_mem->cvb_mem;
  391. flag = CVodeSetIterType(cvode_mem, iterB);
  392. return(flag);
  393. }
  394. int CVodeSetFdataB(void *cvadj_mem, void *f_dataB)
  395. {
  396. CVadjMem ca_mem;
  397. ca_mem = (CVadjMem) cvadj_mem;
  398. f_data_B = f_dataB;
  399. return(CV_SUCCESS);
  400. }
  401. int CVodeSetErrFileB(void *cvadj_mem, FILE *errfpB)
  402. {
  403. CVadjMem ca_mem;
  404. void *cvode_mem;
  405. int flag;
  406. ca_mem = (CVadjMem) cvadj_mem;
  407. cvode_mem = (void *)ca_mem->cvb_mem;
  408. flag = CVodeSetErrFile(cvode_mem, errfpB);
  409. return(flag);
  410. }
  411. int CVodeSetMaxOrdB(void *cvadj_mem, int maxordB)
  412. {
  413. CVadjMem ca_mem;
  414. void *cvode_mem;
  415. int flag;
  416. ca_mem = (CVadjMem) cvadj_mem;
  417. cvode_mem = (void *)ca_mem->cvb_mem;
  418. flag = CVodeSetMaxOrd(cvode_mem, maxordB);
  419. return(flag);
  420. }
  421. int CVodeSetMaxNumStepsB(void *cvadj_mem, long int mxstepsB)
  422. {
  423. CVadjMem ca_mem;
  424. void *cvode_mem;
  425. int flag;
  426. ca_mem = (CVadjMem) cvadj_mem;
  427. cvode_mem = (void *)ca_mem->cvb_mem;
  428. flag = CVodeSetMaxNumSteps(cvode_mem, mxstepsB);
  429. return(flag);
  430. }
  431. int CVodeSetStabLimDetB(void *cvadj_mem, booleantype stldetB)
  432. {
  433. CVadjMem ca_mem;
  434. void *cvode_mem;
  435. int flag;
  436. ca_mem = (CVadjMem) cvadj_mem;
  437. cvode_mem = (void *)ca_mem->cvb_mem;
  438. flag = CVodeSetStabLimDet(cvode_mem, stldetB);
  439. return(flag);
  440. }
  441. int CVodeSetInitStepB(void *cvadj_mem, realtype hinB)
  442. {
  443. CVadjMem ca_mem;
  444. void *cvode_mem;
  445. int flag;
  446. ca_mem = (CVadjMem) cvadj_mem;
  447. cvode_mem = (void *)ca_mem->cvb_mem;
  448. flag = CVodeSetInitStep(cvode_mem, hinB);
  449. return(flag);
  450. }
  451. int CVodeSetMinStepB(void *cvadj_mem, realtype hminB)
  452. {
  453. CVadjMem ca_mem;
  454. void *cvode_mem;
  455. int flag;
  456. ca_mem = (CVadjMem) cvadj_mem;
  457. cvode_mem = (void *)ca_mem->cvb_mem;
  458. flag = CVodeSetMinStep(cvode_mem, hminB);
  459. return(flag);
  460. }
  461. int CVodeSetMaxStepB(void *cvadj_mem, realtype hmaxB)
  462. {
  463. CVadjMem ca_mem;
  464. void *cvode_mem;
  465. int flag;
  466. ca_mem = (CVadjMem) cvadj_mem;
  467. cvode_mem = (void *)ca_mem->cvb_mem;
  468. flag = CVodeSetMaxStep(cvode_mem, hmaxB);
  469. return(flag);
  470. }
  471. /*-----------------------------------------------------------------*/
  472. int CVodeMallocB(void *cvadj_mem, CVRhsFnB fB,
  473. realtype tB0, N_Vector yB0,
  474. int itolB, realtype *reltolB, void *abstolB)
  475. {
  476. CVadjMem ca_mem;
  477. void *cvode_mem;
  478. int sign, flag;
  479. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  480. ca_mem = (CVadjMem) cvadj_mem;
  481. sign = (tfinal - tinitial > ZERO) ? 1 : -1;
  482. if ( (sign*(tB0-tinitial) < ZERO) || (sign*(tfinal-tB0) < ZERO) )
  483. return(CV_BAD_TB0);
  484. f_B = fB;
  485. cvode_mem = (void *) ca_mem->cvb_mem;
  486. flag = CVodeMalloc(cvode_mem, CVArhs, tB0, yB0,
  487. itolB, reltolB, abstolB);
  488. if (flag != CV_SUCCESS) return(flag);
  489. CVodeSetMaxHnilWarns(cvode_mem, -1);
  490. CVodeSetFdata(cvode_mem, cvadj_mem);
  491. return(CV_SUCCESS);
  492. }
  493. /*-----------------------------------------------------------------*/
  494. int CVodeReInitB(void *cvadj_mem, CVRhsFnB fB,
  495. realtype tB0, N_Vector yB0,
  496. int itolB, realtype *reltolB, void *abstolB)
  497. {
  498. CVadjMem ca_mem;
  499. void *cvode_mem;
  500. int sign, flag;
  501. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  502. ca_mem = (CVadjMem) cvadj_mem;
  503. sign = (tfinal - tinitial > ZERO) ? 1 : -1;
  504. if ( (sign*(tB0-tinitial) < ZERO) || (sign*(tfinal-tB0) < ZERO) )
  505. return(CV_BAD_TB0);
  506. f_B = fB;
  507. cvode_mem = (void *) ca_mem->cvb_mem;
  508. flag = CVodeReInit(cvode_mem, CVArhs, tB0, yB0,
  509. itolB, reltolB, abstolB);
  510. if (flag != CV_SUCCESS) return(flag);
  511. CVodeSetMaxHnilWarns(cvode_mem, -1);
  512. CVodeSetFdata(cvode_mem, cvadj_mem);
  513. return(CV_SUCCESS);
  514. }
  515. /*-- CVodeSetQuad*B, CVodeQuadMallocB, and CVodeQuadReInitB -------*/
  516. /*-----------------------------------------------------------------*/
  517. int CVodeSetQuadErrConB(void *cvadj_mem, booleantype errconQB)
  518. {
  519. CVadjMem ca_mem;
  520. void *cvode_mem;
  521. int flag;
  522. ca_mem = (CVadjMem) cvadj_mem;
  523. cvode_mem = (void *)ca_mem->cvb_mem;
  524. flag = CVodeSetQuadErrCon(cvode_mem, errconQB);
  525. return(flag);
  526. }
  527. int CVodeSetQuadFdataB(void *cvadj_mem, void *fQ_dataB)
  528. {
  529. CVadjMem ca_mem;
  530. ca_mem = (CVadjMem) cvadj_mem;
  531. fQ_data_B = fQ_dataB;
  532. return(CV_SUCCESS);
  533. }
  534. int CVodeSetQuadTolerancesB(void *cvadj_mem, int itolQB,
  535. realtype *reltolQB, void *abstolQB)
  536. {
  537. CVadjMem ca_mem;
  538. void *cvode_mem;
  539. int flag;
  540. ca_mem = (CVadjMem) cvadj_mem;
  541. cvode_mem = (void *)ca_mem->cvb_mem;
  542. flag = CVodeSetQuadTolerances(cvode_mem, itolQB, reltolQB, abstolQB);
  543. return(flag);
  544. }
  545. /*-----------------------------------------------------------------*/
  546. int CVodeQuadMallocB(void *cvadj_mem, CVQuadRhsFnB fQB, N_Vector yQB0)
  547. {
  548. CVadjMem ca_mem;
  549. void *cvode_mem;
  550. int flag;
  551. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  552. ca_mem = (CVadjMem) cvadj_mem;
  553. fQ_B = fQB;
  554. cvode_mem = (void *) ca_mem->cvb_mem;
  555. flag = CVodeQuadMalloc(cvode_mem, CVArhsQ, yQB0);
  556. if (flag != CV_SUCCESS) return(flag);
  557. flag = CVodeSetQuadFdata(cvode_mem, cvadj_mem);
  558. return(flag);
  559. }
  560. /*-----------------------------------------------------------------*/
  561. int CVodeQuadReInitB(void *cvadj_mem, CVQuadRhsFnB fQB, N_Vector yQB0)
  562. {
  563. CVadjMem ca_mem;
  564. void *cvode_mem;
  565. int flag;
  566. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  567. ca_mem = (CVadjMem) cvadj_mem;
  568. fQ_B = fQB;
  569. cvode_mem = (void *) ca_mem->cvb_mem;
  570. flag = CVodeQuadReInit(cvode_mem, CVArhsQ, yQB0);
  571. return(flag);
  572. }
  573. /*--------- CVDenseB and CVdenseSet*B -------------------------*/
  574. /*-----------------------------------------------------------------*/
  575. int CVDenseB(void *cvadj_mem, long int nB)
  576. {
  577. CVadjMem ca_mem;
  578. void *cvode_mem;
  579. int flag;
  580. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  581. ca_mem = (CVadjMem) cvadj_mem;
  582. cvode_mem = (void *) ca_mem->cvb_mem;
  583. flag = CVDense(cvode_mem, nB);
  584. return(flag);
  585. }
  586. int CVDenseSetJacFnB(void *cvadj_mem, CVDenseJacFnB djacB)
  587. {
  588. CVadjMem ca_mem;
  589. void *cvode_mem;
  590. int flag;
  591. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  592. ca_mem = (CVadjMem) cvadj_mem;
  593. djac_B = djacB;
  594. cvode_mem = (void *) ca_mem->cvb_mem;
  595. flag = CVDenseSetJacData(cvode_mem, cvadj_mem);
  596. if (flag != CVDENSE_SUCCESS) return(flag);
  597. CVDenseSetJacFn(cvode_mem, CVAdenseJac);
  598. return(CVDENSE_SUCCESS);
  599. }
  600. int CVDenseSetJacDataB(void *cvadj_mem, void *jac_dataB)
  601. {
  602. CVadjMem ca_mem;
  603. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  604. ca_mem = (CVadjMem) cvadj_mem;
  605. jac_data_B = jac_dataB;
  606. return(CVDENSE_SUCCESS);
  607. }
  608. /*----------------- CVDiagB -----------------------------------*/
  609. /*-----------------------------------------------------------------*/
  610. int CVDiagB(void *cvadj_mem)
  611. {
  612. CVadjMem ca_mem;
  613. void *cvode_mem;
  614. int flag;
  615. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  616. ca_mem = (CVadjMem) cvadj_mem;
  617. cvode_mem = (void *) ca_mem->cvb_mem;
  618. flag = CVDiag(cvode_mem);
  619. return(flag);
  620. }
  621. /*----------- CVBandB and CVBandSet*B -----------------------*/
  622. /*-----------------------------------------------------------------*/
  623. int CVBandB(void *cvadj_mem, long int nB,
  624. long int mupperB, long int mlowerB)
  625. {
  626. CVadjMem ca_mem;
  627. void *cvode_mem;
  628. int flag;
  629. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  630. ca_mem = (CVadjMem) cvadj_mem;
  631. cvode_mem = (void *) ca_mem->cvb_mem;
  632. flag = CVBand(cvode_mem, nB, mupperB, mlowerB);
  633. return(flag);
  634. }
  635. int CVBandSetJacFnB(void *cvadj_mem, CVBandJacFnB bjacB)
  636. {
  637. CVadjMem ca_mem;
  638. void *cvode_mem;
  639. int flag;
  640. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  641. ca_mem = (CVadjMem) cvadj_mem;
  642. bjac_B = bjacB;
  643. cvode_mem = (void *) ca_mem->cvb_mem;
  644. flag = CVBandSetJacData(cvode_mem, cvadj_mem);
  645. if (flag != CVBAND_SUCCESS) return(flag);
  646. CVBandSetJacFn(cvode_mem, CVAbandJac);
  647. return(CVBAND_SUCCESS);
  648. }
  649. int CVBandSetJacDataB(void *cvadj_mem, void *jac_dataB)
  650. {
  651. CVadjMem ca_mem;
  652. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  653. ca_mem = (CVadjMem) cvadj_mem;
  654. jac_data_B = jac_dataB;
  655. return(CVBAND_SUCCESS);
  656. }
  657. /*------------ CVSpgmrB and CVSpgmrSet*B ---------------------*/
  658. /*-----------------------------------------------------------------*/
  659. int CVSpgmrB(void *cvadj_mem, int pretypeB, int maxlB)
  660. {
  661. CVadjMem ca_mem;
  662. void *cvode_mem;
  663. int flag;
  664. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  665. ca_mem = (CVadjMem) cvadj_mem;
  666. cvode_mem = (void *) ca_mem->cvb_mem;
  667. flag = CVSpgmr(cvode_mem, pretypeB, maxlB);
  668. return(flag);
  669. }
  670. int CVSpgmrSetPrecTypeB(void *cvadj_mem, int pretypeB)
  671. {
  672. CVadjMem ca_mem;
  673. void *cvode_mem;
  674. int flag;
  675. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  676. ca_mem = (CVadjMem) cvadj_mem;
  677. cvode_mem = (void *) ca_mem->cvb_mem;
  678. flag = CVSpgmrSetPrecType(cvode_mem, pretypeB);
  679. return(flag);
  680. }
  681. int CVSpgmrSetGSTypeB(void *cvadj_mem, int gstypeB)
  682. {
  683. CVadjMem ca_mem;
  684. void *cvode_mem;
  685. int flag;
  686. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  687. ca_mem = (CVadjMem) cvadj_mem;
  688. cvode_mem = (void *) ca_mem->cvb_mem;
  689. flag = CVSpgmrSetGSType(cvode_mem,gstypeB);
  690. return(flag);
  691. }
  692. int CVSpgmrSetDeltB(void *cvadj_mem, realtype deltB)
  693. {
  694. CVadjMem ca_mem;
  695. void *cvode_mem;
  696. int flag;
  697. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  698. ca_mem = (CVadjMem) cvadj_mem;
  699. cvode_mem = (void *) ca_mem->cvb_mem;
  700. flag = CVSpgmrSetDelt(cvode_mem,deltB);
  701. return(flag);
  702. }
  703. int CVSpgmrSetPrecSetupFnB(void *cvadj_mem, CVSpgmrPrecSetupFnB psetB)
  704. {
  705. CVadjMem ca_mem;
  706. void *cvode_mem;
  707. int flag;
  708. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  709. ca_mem = (CVadjMem) cvadj_mem;
  710. pset_B = psetB;
  711. cvode_mem = (void *) ca_mem->cvb_mem;
  712. flag = CVSpgmrSetPrecData(cvode_mem, cvadj_mem);
  713. if (flag != CVSPGMR_SUCCESS) return(flag);
  714. CVSpgmrSetPrecSetupFn(cvode_mem, CVAspgmrPrecSetup);
  715. return(CVSPGMR_SUCCESS);
  716. }
  717. int CVSpgmrSetPrecSolveFnB(void *cvadj_mem, CVSpgmrPrecSolveFnB psolveB)
  718. {
  719. CVadjMem ca_mem;
  720. void *cvode_mem;
  721. int flag;
  722. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  723. ca_mem = (CVadjMem) cvadj_mem;
  724. psolve_B = psolveB;
  725. cvode_mem = (void *) ca_mem->cvb_mem;
  726. flag = CVSpgmrSetPrecData(cvode_mem, cvadj_mem);
  727. if (flag != CVSPGMR_SUCCESS) return(flag);
  728. CVSpgmrSetPrecSolveFn(cvode_mem, CVAspgmrPrecSolve);
  729. return(CVSPGMR_SUCCESS);
  730. }
  731. int CVSpgmrSetJacTimesVecFnB(void *cvadj_mem, CVSpgmrJacTimesVecFnB jtimesB)
  732. {
  733. CVadjMem ca_mem;
  734. void *cvode_mem;
  735. int flag;
  736. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  737. ca_mem = (CVadjMem) cvadj_mem;
  738. jtimes_B = jtimesB;
  739. cvode_mem = (void *) ca_mem->cvb_mem;
  740. flag = CVSpgmrSetJacData(cvode_mem, cvadj_mem);
  741. if (flag != CVSPGMR_SUCCESS) return(flag);
  742. CVSpgmrSetJacTimesVecFn(cvode_mem, CVAspgmrJacTimesVec);
  743. return(CVSPGMR_SUCCESS);
  744. }
  745. int CVSpgmrSetPrecDataB(void *cvadj_mem, void *P_dataB)
  746. {
  747. CVadjMem ca_mem;
  748. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  749. ca_mem = (CVadjMem) cvadj_mem;
  750. P_data_B = P_dataB;
  751. return(CVSPGMR_SUCCESS);
  752. }
  753. int CVSpgmrSetJacDataB(void *cvadj_mem, void *jac_dataB)
  754. {
  755. CVadjMem ca_mem;
  756. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  757. ca_mem = (CVadjMem) cvadj_mem;
  758. jac_data_B = jac_dataB;
  759. return(CVSPGMR_SUCCESS);
  760. }
  761. /*- CVBandPrecAllocB, CVBPSpgmrB, CVBandPrecFreeB -*/
  762. /*----------------------------------------------------------------------*/
  763. int CVBandPrecAllocB(void *cvadj_mem, long int nB,
  764. long int muB, long int mlB)
  765. {
  766. CVadjMem ca_mem;
  767. void *cvode_mem;
  768. void *bp_dataB;
  769. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  770. ca_mem = (CVadjMem) cvadj_mem;
  771. cvode_mem = (void *) ca_mem->cvb_mem;
  772. bp_dataB = CVBandPrecAlloc(cvode_mem, nB, muB, mlB);
  773. if (bp_dataB == NULL) return(CV_PDATA_NULL);
  774. bp_data_B = bp_dataB;
  775. return(CV_SUCCESS);
  776. }
  777. /*-----------------------------------------------------------------*/
  778. int CVBPSpgmrB(void *cvadj_mem, int pretypeB, int maxlB)
  779. {
  780. CVadjMem ca_mem;
  781. void *cvode_mem;
  782. int flag;
  783. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  784. ca_mem = (CVadjMem) cvadj_mem;
  785. cvode_mem = (void *) ca_mem->cvb_mem;
  786. flag = CVBPSpgmr(cvode_mem, pretypeB, maxlB, bp_data_B);
  787. return(flag);
  788. }
  789. /*- CVBBDPrecAllocB, CVBPSpgmrB, CVBandPrecFreeB -*/
  790. /*----------------------------------------------------------------------*/
  791. int CVBBDPrecAllocB(void *cvadj_mem, long int NlocalB,
  792. long int mudqB, long int mldqB,
  793. long int mukeepB, long int mlkeepB,
  794. realtype dqrelyB,
  795. CVLocalFnB glocB, CVCommFnB cfnB)
  796. {
  797. CVadjMem ca_mem;
  798. void *cvode_mem;
  799. void *bbd_dataB;
  800. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  801. ca_mem = (CVadjMem) cvadj_mem;
  802. cvode_mem = (void *) ca_mem->cvb_mem;
  803. gloc_B = glocB;
  804. cfn_B = cfnB;
  805. bbd_dataB = CVBBDPrecAlloc(cvode_mem, NlocalB,
  806. mudqB, mldqB,
  807. mukeepB, mlkeepB,
  808. dqrelyB,
  809. CVAgloc, CVAcfn);
  810. if (bbd_dataB == NULL) return(CV_PDATA_NULL);
  811. bbd_data_B = bbd_dataB;
  812. return(CV_SUCCESS);
  813. }
  814. int CVBBDSpgmrB(void *cvadj_mem, int pretypeB, int maxlB)
  815. {
  816. CVadjMem ca_mem;
  817. void *cvode_mem;
  818. int flag;
  819. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  820. ca_mem = (CVadjMem) cvadj_mem;
  821. cvode_mem = (void *) ca_mem->cvb_mem;
  822. flag = CVBBDSpgmr(cvode_mem, pretypeB, maxlB, bbd_data_B);
  823. return(flag);
  824. }
  825. int CVBBDPrecReInitB(void *cvadj_mem, long int mudqB, long int mldqB,
  826. realtype dqrelyB, CVLocalFnB glocB, CVCommFnB cfnB)
  827. {
  828. CVadjMem ca_mem;
  829. void *cvode_mem;
  830. int flag;
  831. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  832. ca_mem = (CVadjMem) cvadj_mem;
  833. cvode_mem = (void *) ca_mem->cvb_mem;
  834. gloc_B = glocB;
  835. cfn_B = cfnB;
  836. flag = CVBBDPrecReInit(bbd_data_B, mudqB, mldqB,
  837. dqrelyB, CVAgloc, CVAcfn);
  838. return(flag);
  839. }
  840. /*------------------ CVodeB --------------------------*/
  841. /*
  842. This routine performs the backward integration towards tBout.
  843. When necessary, it performs a forward integration between two
  844. consecutive check points to update interpolation data.
  845. itask can be CV_NORMAL or CV_ONE_STEP only.
  846. */
  847. /*-----------------------------------------------------------------*/
  848. int CVodeB(void *cvadj_mem, realtype tBout, N_Vector yBout,
  849. realtype *tBret, int itaskB)
  850. {
  851. CVadjMem ca_mem;
  852. CkpntMem ck_mem;
  853. CVodeMem cvb_mem;
  854. int sign, flag, cv_itask;
  855. realtype tBn;
  856. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  857. ca_mem = (CVadjMem) cvadj_mem;
  858. cvb_mem = ca_mem->cvb_mem;
  859. if (cvb_mem == NULL) return(CV_BCKMEM_NULL);
  860. if (itaskB == CV_NORMAL)
  861. cv_itask = CV_NORMAL_TSTOP;
  862. else if (itaskB == CV_ONE_STEP)
  863. cv_itask = CV_ONE_STEP_TSTOP;
  864. else
  865. return(CV_BAD_ITASK);
  866. ck_mem = ca_mem->ck_mem;
  867. sign = (tfinal - tinitial > ZERO) ? 1 : -1;
  868. if ( (sign*(tBout-tinitial) < ZERO) || (sign*(tfinal-tBout) < ZERO) )
  869. return(CV_BAD_TBOUT);
  870. tBn = cvb_mem->cv_tn;
  871. while ( sign*(tBn - t0_) <= ZERO ) ck_mem = next_;
  872. loop {
  873. /* Store interpolation data if not available */
  874. if (ck_mem != ckpntData) {
  875. flag = CVAdataStore(ca_mem, ck_mem);
  876. if (flag != CV_SUCCESS) return(flag);
  877. }
  878. /* Backward integration */
  879. CVodeSetStopTime((void *)cvb_mem, t0_);
  880. flag = CVode(cvb_mem, tBout, yBout, tBret, cv_itask);
  881. /* If an error occured, return now */
  882. if (flag < 0) return(flag);
  883. /* Set the time at which CVodeGetQuadB will evaluate any quadratures */
  884. t_for_quad = *tBret;
  885. /* If in CV_ONE_STEP mode, return now (flag=CV_SUCCESS or flag=CV_TSTOP_RETURN) */
  886. if (itaskB == CV_ONE_STEP) return(flag);
  887. /* If succesfully reached tBout, return now */
  888. if (*tBret == tBout) return(flag);
  889. /* Move check point in linked list to next one */
  890. ck_mem = next_;
  891. }
  892. return(CV_SUCCESS);
  893. }
  894. /*------------------ CVodeGetQuadB ------------------------------*/
  895. /*-----------------------------------------------------------------*/
  896. int CVodeGetQuadB(void *cvadj_mem, N_Vector qB)
  897. {
  898. CVadjMem ca_mem;
  899. void *cvode_mem;
  900. int flag;
  901. if (cvadj_mem == NULL) return(CV_ADJMEM_NULL);
  902. ca_mem = (CVadjMem) cvadj_mem;
  903. cvode_mem = (void *) ca_mem->cvb_mem;
  904. flag = CVodeGetQuad(cvode_mem, t_for_quad, qB);
  905. return(flag);
  906. }
  907. /*=================================================================*/
  908. /*END Wrappers for CVODEA */
  909. /*=================================================================*/
  910. /*------------------ CVAdjFree --------------------------*/
  911. /*
  912. This routine frees the memory allocated by CVadjMalloc.
  913. */
  914. /*-----------------------------------------------------------------*/
  915. void CVadjFree(void *cvadj_mem)
  916. {
  917. CVadjMem ca_mem;
  918. ca_mem = (CVadjMem) cvadj_mem;
  919. /* Delete check points one by one */
  920. while (ca_mem->ck_mem != NULL) {
  921. CVAckpntDelete(&(ca_mem->ck_mem));
  922. }
  923. /* Free vectors at each data point */
  924. CVAdataFree(ca_mem->dt_mem, nsteps);
  925. free(ca_mem->dt_mem);
  926. /* Free vectors in ca_mem */
  927. N_VDestroy(Y0);
  928. N_VDestroy(Y1);
  929. N_VDestroy(ytmp);
  930. /* Free CVODES memory for backward run */
  931. CVodeFree(ca_mem->cvb_mem);
  932. /* Free preconditioner data (the routines below check for non-NULL data) */
  933. CVBandPrecFree(bp_data_B);
  934. CVBBDPrecFree(bbd_data_B);
  935. /* Free CVODEA memory */
  936. free(ca_mem);
  937. }
  938. /*------------------ CVadjGetCVodeBmem --------------------------*/
  939. /*
  940. CVadjGetCVodeBmem returns a (void *) pointer to the CVODES
  941. memory allocated for the backward problem. This pointer can
  942. then be used to call any of the CVodeGet* CVODES routines to
  943. extract optional output for the backward integration phase.
  944. */
  945. /*-----------------------------------------------------------------*/
  946. void *CVadjGetCVodeBmem(void *cvadj_mem)
  947. {
  948. CVadjMem ca_mem;
  949. void *cvode_mem;
  950. if (cvadj_mem == NULL) return(NULL);
  951. ca_mem = (CVadjMem) cvadj_mem;
  952. cvode_mem = (void *) ca_mem->cvb_mem;
  953. return(cvode_mem);
  954. }
  955. /*------------------ CVAdjGetY --------------------------*/
  956. /*
  957. This routine uses cubic piece-wise Hermite interpolation for
  958. the forward solution vector.
  959. It is typically called by the wrapper routines before calling
  960. user provided routines (fB, djacB, bjacB, jtimesB, psolB) but
  961. can be directly called by the user if memory for the bacward
  962. run is allocated through CVODE calls and not through CVODEA
  963. calls.
  964. */
  965. /*-----------------------------------------------------------------*/
  966. int CVadjGetY(void *cvadj_mem, realtype t, N_Vector y)
  967. {
  968. CVadjMem ca_mem;
  969. DtpntMem *dt_mem;
  970. static long int i;
  971. long int inew;
  972. int sign;
  973. booleantype to_left, to_right;
  974. realtype troundoff;
  975. ca_mem = (CVadjMem) cvadj_mem;
  976. dt_mem = ca_mem->dt_mem;
  977. sign = (tfinal - tinitial > ZERO) ? 1 : -1;
  978. if ( newData ) {
  979. i = np-1;
  980. CVAhermitePrepare(ca_mem, dt_mem, i);
  981. newData = FALSE;
  982. }
  983. /* Search for inew starting from last i */
  984. to_left = ( sign*(t - dt_mem[i-1]->t) < ZERO);
  985. to_right = ( sign*(t - dt_mem[i]->t) > ZERO);
  986. /* Test if t is beyond left limit */
  987. if ( (to_left) && (i==1) ) {
  988. /*troundoff = FUZZ_FACTOR*uround*(ABS(dt_mem[0]->t)+ABS(dt_mem[1]->t));*/
  989. troundoff = FUZZ_FACTOR*uround;
  990. if ( ABS(t - dt_mem[0]->t) <= troundoff ) {
  991. N_VScale(ONE, dt_mem[0]->y, y);
  992. return(CV_SUCCESS);
  993. }
  994. else {
  995. printf("\n TROUBLE IN GETY\n ");
  996. #if defined(SUNDIALS_EXTENDED_PRECISION)
  997. printf("%Lg = ABS(t-dt_mem[0]->t) > troundoff = %Lg uround = %Lg\n",
  998. ABS(t - dt_mem[0]->t), troundoff, uround);
  999. #elif defined(SUNDIALS_DOUBLE_PRECISION)
  1000. printf("%lg = ABS(t-dt_mem[0]->t) > troundoff = %lg uround = %lg\n",
  1001. ABS(t - dt_mem[0]->t), troundoff, uround);
  1002. #else
  1003. printf("%g = ABS(t-dt_mem[0]->t) > troundoff = %g uround = %g\n",
  1004. ABS(t - dt_mem[0]->t), troundoff, uround);
  1005. #endif
  1006. return(CV_GETY_BADT);
  1007. }
  1008. }
  1009. inew = i;
  1010. if ( to_left ) {
  1011. /* Search to the left */
  1012. inew--;
  1013. loop {
  1014. if ( inew == 1 ) break;
  1015. if ( sign*(t - dt_mem[inew-1]->t) <= ZERO) inew--;
  1016. else break;
  1017. }
  1018. } else if ( to_right ) {
  1019. /* Search to the right */
  1020. inew++;
  1021. loop {
  1022. if ( sign*(t - dt_mem[inew]->t) > ZERO) inew++;
  1023. else break;
  1024. }
  1025. }
  1026. if ( inew != i )
  1027. CVAhermitePrepare(ca_mem, dt_mem, inew);
  1028. CVAhermiteInterpolate(ca_mem, dt_mem, inew, t, y);
  1029. i = inew;
  1030. return(CV_SUCCESS);
  1031. }
  1032. /*------------------ CVAdjGetCheckPointsList ---------------------*/
  1033. /*
  1034. This routine lists the linked list of check point structures.
  1035. For debugging....
  1036. */
  1037. /*-----------------------------------------------------------------*/
  1038. void CVadjGetCheckPointsList(void *cvadj_mem)
  1039. {
  1040. CVadjMem ca_mem;
  1041. CkpntMem ck_mem;
  1042. int i;
  1043. ca_mem = (CVadjMem) cvadj_mem;
  1044. ck_mem = ca_mem->ck_mem;
  1045. i = 0;
  1046. while (ck_mem != NULL) {
  1047. #if defined(SUNDIALS_EXTENDED_PRECISION)
  1048. printf("%2d addr: %p time = [ %9.3Le %9.3Le ] next: %p\n",
  1049. nckpnts-i, (void *)ck_mem, t0_, t1_, (void *)next_ );
  1050. #elif defined(SUNDIALS_DOUBLE_PRECISION)
  1051. printf("%2d addr: %p time = [ %9.3le %9.3le ] next: %p\n",
  1052. nckpnts-i, (void *)ck_mem, t0_, t1_, (void *)next_ );
  1053. #else
  1054. printf("%2d addr: %p time = [ %9.3e %9.3e ] next: %p\n",
  1055. nckpnts-i, (void *)ck_mem, t0_, t1_, (void *)next_ );
  1056. #endif
  1057. ck_mem = next_;
  1058. i++;
  1059. }
  1060. }
  1061. /*------------------ CVAdjGetStoredData ------------------------*/
  1062. /*
  1063. This routine returns the solution stored in the data structure
  1064. at the 'which' data point.
  1065. For debugging....
  1066. */
  1067. /*-----------------------------------------------------------------*/
  1068. void CVadjGetStoredData(void *cvadj_mem, long int which,
  1069. realtype *t, N_Vector yout, N_Vector ydout)
  1070. {
  1071. CVadjMem ca_mem;
  1072. DtpntMem *dt_mem;
  1073. ca_mem = (CVadjMem) cvadj_mem;
  1074. dt_mem = ca_mem->dt_mem;
  1075. *t = dt_mem[which]->t;
  1076. if (yout != NULL)
  1077. N_VScale(ONE, dt_mem[which]->y, yout);
  1078. if (ydout != NULL)
  1079. N_VScale(ONE, dt_mem[which]->yd, ydout);
  1080. }
  1081. /*=================================================================*/
  1082. /*BEGIN Exported Functions */
  1083. /*=================================================================*/
  1084. /*=================================================================*/
  1085. /*BEGIN Private Functions Implementation */
  1086. /*=================================================================*/
  1087. /*------------------ CVAckpntInit --------------------------*/
  1088. /*
  1089. This routine initializes the check point linked list with
  1090. information from the initial time.
  1091. */
  1092. /*-----------------------------------------------------------------*/
  1093. static CkpntMem CVAckpntInit(CVodeMem cv_mem)
  1094. {
  1095. CkpntMem ck_mem;
  1096. /* Allocate space for ckdata */
  1097. ck_mem = (CkpntMem) malloc(sizeof(struct CkpntMemRec));
  1098. zn_[0] = N_VClone(tempv);
  1099. zn_[1] = N_VClone(tempv);
  1100. /* zn_[qmax] was not allocated */
  1101. zqm_ = 0;
  1102. /* Load ckdata from cv_mem */
  1103. N_VScale(ONE, zn[0], zn_[0]);
  1104. t0_ = tn;
  1105. q_ = 1;
  1106. /* Compute zn_[1] by calling the user f routine */
  1107. f(t0_, zn_[0], zn_[1], f_data);
  1108. /* Do we need to carry quadratures */
  1109. quadr_ = quadr && errconQ;
  1110. if (quadr_) {
  1111. znQ_[0] = N_VClone(tempvQ);
  1112. N_VScale(ONE, znQ[0], znQ_[0]);
  1113. }
  1114. /* Next in list */
  1115. next_ = NULL;
  1116. return(ck_mem);
  1117. }
  1118. /*------------------ CVAckpntNew --------------------------*/
  1119. /*
  1120. This routine allocates space for a new check point and sets
  1121. its data from current values in cv_mem.
  1122. */
  1123. /*-----------------------------------------------------------------*/
  1124. static CkpntMem CVAckpntNew(CVodeMem cv_mem)
  1125. {
  1126. CkpntMem ck_mem;
  1127. int j;
  1128. int qmax;
  1129. /* Allocate space for ckdata */
  1130. ck_mem = (CkpntMem) malloc(sizeof(struct CkpntMemRec));
  1131. if (ck_mem == NULL) return(NULL);
  1132. /* Test if we need to allocate space for the last zn.
  1133. NOTE: zn(qmax) may be needed for a hot restart, if an order
  1134. increase is deemed necessary at the first step after a check
  1135. point */
  1136. qmax = cv_mem->cv_qmax;
  1137. zqm_ = (q < qmax) ? qmax : 0;
  1138. for (j=0; j<=q; j++) {
  1139. zn_[j] = N_VClone(tempv);
  1140. if(zn_[j] == NULL) return(NULL);
  1141. }
  1142. if ( q < qmax) {
  1143. zn_[qmax] = N_VClone(tempv);
  1144. if ( zn_[qmax] == NULL ) return(NULL);
  1145. }
  1146. /* Test if we need to carry quadratures */
  1147. quadr_ = quadr && errconQ;
  1148. if (quadr_) {
  1149. for (j=0; j<=q; j++) {
  1150. znQ_[j] = N_VClone(tempvQ);
  1151. if(znQ_[j] == NULL) return(NULL);
  1152. }
  1153. if ( q < qmax) {
  1154. znQ_[qmax] = N_VClone(tempvQ);
  1155. if ( znQ_[qmax] == NULL ) return(NULL);
  1156. }
  1157. }
  1158. /* Load check point data from cv_mem */
  1159. for (j=0; j<=q; j++) N_VScale(ONE, zn[j], zn_[j]);
  1160. if ( q < qmax ) N_VScale(ONE, zn[qmax], zn_[qmax]);
  1161. if(quadr_) {
  1162. for (j=0; j<=q; j++) N_VScale(ONE, znQ[j], znQ_[j]);
  1163. if ( q < qmax ) N_VScale(ONE, znQ[qmax], znQ_[qmax]);
  1164. }
  1165. for (j=0; j<=L_MAX; j++) tau_[j] = tau[j];
  1166. for (j=0; j<=NUM_TESTS; j++) tq_[j] = tq[j];
  1167. for (j=0; j<=q; j++) l_[j] = l[j];
  1168. nst_ = nst;
  1169. q_ = q;
  1170. qprime_ = qprime;
  1171. qwait_ = qwait;
  1172. L_ = L;
  1173. gammap_ = gammap;
  1174. h_ = h;
  1175. hprime_ = hprime;
  1176. hscale_ = hscale;
  1177. eta_ = eta;
  1178. etamax_ = etamax;
  1179. t0_ = tn;
  1180. saved_tq5_ = saved_tq5;
  1181. return(ck_mem);
  1182. }
  1183. /*------------------ CVAckpntDelete --------------------------*/
  1184. /*
  1185. This routine deletes the first check point in list.
  1186. */
  1187. /*-----------------------------------------------------------------*/
  1188. static void CVAckpntDelete(CkpntMem *ck_memPtr)
  1189. {
  1190. CkpntMem tmp;
  1191. int j;
  1192. if (*ck_memPtr != NULL) {
  1193. /* store head of list */
  1194. tmp = *ck_memPtr;
  1195. /* move head of list */
  1196. *ck_memPtr = (*ck_memPtr)->ck_next;
  1197. /* free N_Vectors in tmp */
  1198. for (j=0;j<=tmp->ck_q;j++) N_VDestroy(tmp->ck_zn[j]);
  1199. if (tmp->ck_zqm != 0) N_VDestroy(tmp->ck_zn[tmp->ck_zqm]);
  1200. /* free N_Vectors for quadratures in tmp
  1201. Note that at the check point at t_initial, only znQ_[0]
  1202. was allocated*/
  1203. if(tmp->ck_quadr) {
  1204. if(tmp->ck_next != NULL) {
  1205. for (j=0;j<=tmp->ck_q;j++) N_VDestroy(tmp->ck_znQ[j]);
  1206. if (tmp->ck_zqm != 0) N_VDestroy(tmp->ck_znQ[tmp->ck_zqm]);
  1207. } else {
  1208. N_VDestroy(tmp->ck_znQ[0]);
  1209. }
  1210. }
  1211. free(tmp);
  1212. }
  1213. }
  1214. /*------------------ CVAdataMalloc --------------------------*/
  1215. /*
  1216. This routine allocates memory for storing information at all
  1217. intermediate points between two consecutive check points.
  1218. This data is then used to interpolate the forward solution
  1219. at any other time.
  1220. */
  1221. /*-----------------------------------------------------------------*/
  1222. static DtpntMem *CVAdataMalloc(CVodeMem cv_mem, long int steps)
  1223. {
  1224. DtpntMem *dt_mem;
  1225. long int i;
  1226. dt_mem = (DtpntMem *)malloc((steps+1)*sizeof(struct DtpntMemRec *));
  1227. for (i=0; i<=steps; i++) {
  1228. dt_mem[i] = (DtpntMem)malloc(sizeof(struct DtpntMemRec));
  1229. dt_mem[i]->y = N_VClone(tempv);
  1230. dt_mem[i]->yd = N_VClone(tempv);
  1231. }
  1232. return(dt_mem);
  1233. }
  1234. /*------------------ CVAdataFree --------------------------*/
  1235. /*
  1236. This routine frees the memeory allocated for data storage.
  1237. */
  1238. /*-----------------------------------------------------------------*/
  1239. static void CVAdataFree(DtpntMem *dt_mem, long int steps)
  1240. {
  1241. long int i;
  1242. for (i=0; i<=steps; i++) {
  1243. N_VDestroy(dt_mem[i]->y);
  1244. N_VDestroy(dt_mem[i]->yd);
  1245. free(dt_mem[i]);
  1246. }
  1247. }
  1248. /*------------------ CVAdataStore --------------------------*/
  1249. /*
  1250. This routine integrates the forward model starting at the check
  1251. point ck_mem and stores y and yprime at all intermediate steps.
  1252. Return values:
  1253. CV_SUCCESS
  1254. CV_REIFWD_FAIL
  1255. CV_FWD_FAIL
  1256. */
  1257. /*-----------------------------------------------------------------*/
  1258. int CVAdataStore(CVadjMem ca_mem, CkpntMem ck_mem)
  1259. {
  1260. CVodeMem cv_mem;
  1261. DtpntMem *dt_mem;
  1262. realtype t;
  1263. long int i;
  1264. int flag;
  1265. cv_mem = ca_mem->cv_mem;
  1266. dt_mem = ca_mem->dt_mem;
  1267. /* Initialize cv_mem with data from ck_mem */
  1268. flag = CVAckpntGet(cv_mem, ck_mem);
  1269. if (flag != CV_SUCCESS) return(CV_REIFWD_FAIL);
  1270. /* Set first structure in dt_mem[0] */
  1271. dt_mem[0]->t = t0_;
  1272. N_VScale(ONE, zn_[0], dt_mem[0]->y);
  1273. N_VScale(ONE, zn_[1], dt_mem[0]->yd);
  1274. /* Run CVode to set following structures in dt_mem[i] */
  1275. i = 1;
  1276. do {
  1277. flag = CVode(cv_mem, t1_, dt_mem[i]->y, &t, CV_ONE_STEP);
  1278. if (flag < 0) return(CV_FWD_FAIL);
  1279. dt_mem[i]->t = t;
  1280. flag = CVodeGetDky(cv_mem, t, 1, dt_mem[i]->yd);
  1281. if (flag != CV_SUCCESS) return(CV_FWD_FAIL);
  1282. i++;
  1283. } while (t<t1_);
  1284. /* New data is now available */
  1285. ckpntData = ck_mem;
  1286. newData = TRUE;
  1287. np = i;
  1288. return(CV_SUCCESS);
  1289. }
  1290. /*------------------ CVAckpntGet --------------------------*/
  1291. /*
  1292. This routine extracts data from the check point structure at
  1293. ck_mem and sets cv_mem for a hot start.
  1294. */
  1295. /*-----------------------------------------------------------------*/
  1296. static int CVAckpntGet(CVodeMem cv_mem, CkpntMem ck_mem)
  1297. {
  1298. int j;
  1299. int flag;
  1300. int qmax;
  1301. if (next_ == NULL) {
  1302. /* In this case, we just call the reinitialization routine,
  1303. but make sure we use the same initial stepsize as on
  1304. the first run. */
  1305. CVodeSetInitStep(cv_mem, h0u);
  1306. flag = CVodeReInit(cv_mem, f, t0_, zn_[0], itol, reltol, abstol);
  1307. if (flag != CV_SUCCESS) return(flag);
  1308. if(quadr_) {
  1309. flag = CVodeQuadReInit(cv_mem, fQ, znQ_[0]);
  1310. if (flag != CV_SUCCESS) return(flag);
  1311. }
  1312. } else {
  1313. qmax = cv_mem->cv_qmax;
  1314. /* Copy parameters from check point data structure */
  1315. nst = nst_;
  1316. q = q_;
  1317. qprime = qprime_;
  1318. qwait = qwait_;
  1319. L = L_;
  1320. gammap = gammap_;
  1321. h = h_;
  1322. hprime = hprime_;
  1323. hscale = hscale_;
  1324. eta = eta_;
  1325. etamax = etamax_;
  1326. tn = t0_;
  1327. saved_tq5 = saved_tq5_;
  1328. /* Copy the arrays from check point data structure */
  1329. for (j=0; j<=q; j++) N_VScale(ONE, zn_[j], zn[j]);
  1330. if ( q < qmax ) N_VScale(ONE, zn_[qmax], zn[qmax]);
  1331. if(quadr_) {
  1332. for (j=0; j<=q; j++) N_VScale(ONE, znQ_[j], znQ[j]);
  1333. if ( q < qmax ) N_VScale(ONE, znQ_[qmax], znQ[qmax]);
  1334. }
  1335. for (j=0; j<=L_MAX; j++) tau[j] = tau_[j];
  1336. for (j=0; j<=NUM_TESTS; j++) tq[j] = tq_[j];
  1337. for (j=0; j<=q; j++) l[j] = l_[j];
  1338. /* Force a call to setup */
  1339. forceSetup = TRUE;
  1340. }
  1341. return(CV_SUCCESS);
  1342. }
  1343. /*------------------ CVAhermitePrepare --------------------------*/
  1344. /*
  1345. This routine computes quantities required by the Hermite
  1346. interpolation that are independent of the interpolation point.
  1347. */
  1348. /*-----------------------------------------------------------------*/
  1349. static void CVAhermitePrepare(CVadjMem ca_mem, DtpntMem *dt_mem, long int i)
  1350. {
  1351. realtype t0, t1;
  1352. N_Vector y0, y1, yd0, yd1;
  1353. t0 = dt_mem[i-1]->t;
  1354. y0 = dt_mem[i-1]->y;
  1355. yd0 = dt_mem[i-1]->yd;
  1356. t1 = dt_mem[i]->t;
  1357. y1 = dt_mem[i]->y;
  1358. yd1 = dt_mem[i]->yd;
  1359. delta = t1 - t0;
  1360. N_VLinearSum(ONE, y1, -ONE, y0, Y0);
  1361. N_VLinearSum(ONE, yd1, ONE, yd0, Y1);
  1362. N_VLinearSum(delta, Y1, -TWO, Y0, Y1);
  1363. N_VLinearSum(ONE, Y0, -delta, yd0, Y0);
  1364. }
  1365. /*------------------ CVAhermiteInterpolate ----------------------*/
  1366. /*
  1367. This routine performs the Hermite interpolation.
  1368. */
  1369. /*-----------------------------------------------------------------*/
  1370. static void CVAhermiteInterpolate(CVadjMem ca_mem, DtpntMem *dt_mem,
  1371. long int i, realtype t, N_Vector y)
  1372. {
  1373. realtype t0, t1;
  1374. N_Vector y0, yd0;
  1375. realtype factor;
  1376. t0 = dt_mem[i-1]->t;
  1377. t1 = dt_mem[i]->t;
  1378. y0 = dt_mem[i-1]->y;
  1379. yd0 = dt_mem[i-1]->yd;
  1380. factor = t - t0;
  1381. N_VLinearSum(ONE, y0, factor, yd0, y);
  1382. factor = factor/delta;
  1383. factor = factor*factor;
  1384. N_VLinearSum(ONE, y, factor, Y0, y);
  1385. factor = factor*(t-t1)/delta;
  1386. N_VLinearSum(ONE, y, factor, Y1, y);
  1387. }
  1388. /*=================================================================*/
  1389. /*BEGIN Wrappers for adjoint system */
  1390. /*=================================================================*/
  1391. /*------------------ CVArhs --------------------------*/
  1392. /*
  1393. This routine interfaces to the CVRhsFnB routine provided by
  1394. the user.
  1395. NOTE: f_data actually contains cvadj_mem
  1396. */
  1397. /*-----------------------------------------------------------------*/
  1398. static void CVArhs(realtype t, N_Vector yB,
  1399. N_Vector yBdot, void *cvadj_mem)
  1400. {
  1401. CVadjMem ca_mem;
  1402. int flag;
  1403. ca_mem = (CVadjMem) cvadj_mem;
  1404. /* Forward solution from Hermite interpolation */
  1405. flag = CVadjGetY(ca_mem, t, ytmp);
  1406. if (flag != CV_SUCCESS) {
  1407. printf("\n\nBad t in interpolation\n\n");
  1408. exit(1);
  1409. }
  1410. /* Call user's adjoint RHS routine */
  1411. f_B(t, ytmp, yB, yBdot, f_data_B);
  1412. }
  1413. /*------------------ CVArhsQ --------------------------*/
  1414. /*
  1415. This routine interfaces to the CVQuadRhsFnB routine provided by
  1416. the user.
  1417. NOTE: fQ_data actually contains cvadj_mem
  1418. */
  1419. /*-----------------------------------------------------------------*/
  1420. static void CVArhsQ(realtype t, N_Vector yB,
  1421. N_Vector qBdot, void *cvadj_mem)
  1422. {
  1423. CVadjMem ca_mem;
  1424. int flag;
  1425. ca_mem = (CVadjMem) cvadj_mem;
  1426. /* Forward solution from Hermite interpolation */
  1427. flag = CVadjGetY(ca_mem, t, ytmp);
  1428. if (flag != CV_SUCCESS) {
  1429. printf("\n\nBad t in interpolation\n\n");
  1430. exit(1);
  1431. }
  1432. /* Call user's adjoint RHS routine */
  1433. fQ_B(t, ytmp, yB, qBdot, fQ_data_B);
  1434. }
  1435. /*------------------ CVAdenseJac --------------------------*/
  1436. /*
  1437. This routine interfaces to the CVDenseJacFnB routine provided
  1438. by the user.
  1439. NOTE: jac_data actually contains cvadj_mem
  1440. */
  1441. /*-----------------------------------------------------------------*/
  1442. static void CVAdenseJac(long int nB, DenseMat JB, realtype t,
  1443. N_Vector yB, N_Vector fyB, void *cvadj_mem,
  1444. N_Vector tmp1B, N_Vector tmp2B, N_Vector tmp3B)
  1445. {
  1446. CVadjMem ca_mem;
  1447. int flag;
  1448. ca_mem = (CVadjMem) cvadj_mem;
  1449. /* Forward solution from Hermite interpolation */
  1450. flag = CVadjGetY(ca_mem, t, ytmp);
  1451. if (flag != CV_SUCCESS) {
  1452. printf("\n\nBad t in interpolation\n\n");
  1453. exit(1);
  1454. }
  1455. /* Call user's adjoint dense djacB routine */
  1456. djac_B(nB, JB, t, ytmp, yB, fyB, jac_data_B,
  1457. tmp1B, tmp2B, tmp3B);
  1458. }
  1459. /*------------------ CVAbandJac --------------------------*/
  1460. /*
  1461. This routine interfaces to the CVBandJacFnB routine provided
  1462. by the user.
  1463. NOTE: jac_data actually contains cvadj_mem
  1464. */
  1465. /*-----------------------------------------------------------------*/
  1466. static void CVAbandJac(long int nB, long int mupperB,
  1467. long int mlowerB, BandMat JB, realtype t,
  1468. N_Vector yB, N_Vector fyB, void *cvadj_mem,
  1469. N_Vector tmp1B, N_Vector tmp2B, N_Vector tmp3B)
  1470. {
  1471. CVadjMem ca_mem;
  1472. int flag;
  1473. ca_mem = (CVadjMem) cvadj_mem;
  1474. /* Forward solution from Hermite interpolation */
  1475. flag = CVadjGetY(ca_mem, t, ytmp);
  1476. if (flag != CV_SUCCESS) {
  1477. printf("\n\nBad t in interpolation\n\n");
  1478. exit(1)

Large files files are truncated, but you can click here to view the full file