NEURON
cvodeobj.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 // solver interface to CVode
3 #include <InterViews/resource.h>
4 
5 #include "nrnmpi.h"
6 
7 extern "C" void cvode_fadvance();
8 void cvode_finitialize();
9 extern void (*nrn_multisplit_setup_)();
10 
11 extern int hoc_return_type_code;
12 
13 #include <math.h>
14 #include <stdlib.h>
15 #include "classreg.h"
16 #include "nrnoc2iv.h"
17 #include "datapath.h"
18 #include "cvodeobj.h"
19 #include "netcvode.h"
20 #include "membfunc.h"
21 #include "nrndaspk.h"
22 #include "tqueue.h"
23 #include "mymath.h"
24 #include "htlist.h"
25 #include <OS/list.h>
26 #include <nrnmutdec.h>
27 
28 #if USE_PTHREAD
29 static MUTDEC
30 #endif
31 
32 // Use of the above static mutex was broken by changeset 7ffd95c in 2014
33 // when a MUTDEC was added explicitly to the NetCvode class namespace to
34 // handle interthread send events.
35 static void static_mutex_for_at_time(bool b) {
36  if (b) {
37  MUTCONSTRUCT(1)
38  } else {
40  }
41 }
42 
43 //I have no idea why this is necessary
44 // but it stops codewarrior from complaining
45 // about illegal overloading in math.h
46 // and math.h alone just moves the problem
47 // to these
48 //#include "shared/sundialstypes.h"
49 //#include "shared/nvector_serial.h"
50 #include "cvodes/cvodes.h"
51 #include "cvodes/cvodes_impl.h"
52 #include "cvodes/cvdense.h"
53 #include "cvodes/cvdiag.h"
54 #include "shared/dense.h"
55 #include "ida/ida.h"
56 #include "nonvintblock.h"
57 
58 extern double dt, t;
59 #define nt_dt nrn_threads->_dt
60 #define nt_t nrn_threads->_t
61 extern int diam_changed;
62 extern int secondorder;
63 extern int linmod_extra_eqn_count();
64 extern int nrn_modeltype();
65 extern int nrn_use_selfqueue_;
66 extern int use_cachevec;
67 extern void nrn_cachevec(int);
68 extern "C" Point_process* ob2pntproc(Object*);
70 extern void (*nrnmpi_v_transfer_)();
71 
72 extern int cvode_active_;
74 extern short* nrn_is_artificial_;
75 extern "C" int structure_change_cnt;
76 extern "C" int diam_change_cnt;
77 #if USENCS
78 extern void nrn2ncs_netcons();
79 #endif //USENCS
80 #if PARANEURON
81 extern "C" {
82 extern N_Vector N_VNew_Parallel(int comm, long int local_length,
83  long int global_length);
84 extern N_Vector N_VNew_NrnParallelLD(int comm,
85  long int local_length, long int global_length);
86 } // extern "C"
87 #endif
88 
89 extern bool nrn_use_fifo_queue_;
90 #if BBTQ == 5
91 extern bool nrn_use_bin_queue_;
92 #endif
93 
94 #undef SUCCESS
95 #define SUCCESS CV_SUCCESS
96 
97 // interface to oc
98 
99 static double solve(void* v) {
100  NetCvode* d = (NetCvode*)v;
101  double tstop = -1.;
102  if (ifarg(1)) {
103  tstop = *getarg(1);
104  }
105  tstopunset;
106  int i = d->solve(tstop);
107  tstopunset;
108  if (i != SUCCESS) {
109  hoc_execerror("variable step integrator error", 0);
110  }
111  t = nt_t;
112  dt = nt_dt;
113  return double(i);
114 }
115 static double statistics(void* v) {
116  NetCvode* d = (NetCvode*)v;
117  int i = -1;
118  if (ifarg(1)) {
119  i = (int)chkarg(1, -1, 1e6);
120  }
121  d->statistics(i);
122  return 0.;
123 }
124 static double spikestat(void* v) {
125  NetCvode* d = (NetCvode*)v;
126  d->spike_stat();
127  return 0;
128 }
129 static double queue_mode(void* v) {
130  hoc_return_type_code = 1; // integer
131 #if BBTQ == 3 || BBTQ == 4
132  if (ifarg(1)) {
133  nrn_use_fifo_queue_ = chkarg(1, 0, 1) ? true : false;
134  }
135  return double(nrn_use_fifo_queue_);
136 #endif
137 #if BBTQ == 5
138  if (ifarg(1)) {
139  nrn_use_bin_queue_ = chkarg(1, 0, 1) ? true : false;
140  }
141  if (ifarg(2)) {
142 #if NRNMPI
143  nrn_use_selfqueue_ = chkarg(2, 0, 1) ? 1 : 0;
144 #else
145  if (chkarg(2, 0, 1)) {
146  hoc_warning("CVode.queue_mode with second arg == 1 requires",
147  "configuration --with-mpi or related");
148  }
149 #endif
150  }
151  return double(nrn_use_bin_queue_ + 2*nrn_use_selfqueue_);
152 #endif
153  return 0.;
154 }
155 
156 void nrn_extra_scatter_gather(int direction, int tid);
157 
158 static double re_init(void* v) {
159  if (cvode_active_) {
160  NetCvode* d = (NetCvode*)v;
161  d->re_init(t);
162  }else{
164  }
165  return 0.;
166 }
167 static double rtol(void* v) {
168  NetCvode* d = (NetCvode*)v;
169  if (ifarg(1)) {
170  d->rtol(chkarg(1, 0., 1e9));
171  }
172  return d->rtol();
173 }
174 static double nrn_atol(void* v) {
175  NetCvode* d = (NetCvode*)v;
176  if (ifarg(1)) {
177  d->atol(chkarg(1, 0., 1e9));
178  d->structure_change();
179  }
180  return d->atol();
181 }
183 extern void hoc_symbol_tolerance(Symbol*, double);
184 
185 static double abstol(void* v) {
186  NetCvode* d = (NetCvode*)v;
187  Symbol* sym;
188  if (hoc_is_str_arg(1)) {
189  sym = d->name2sym(gargstr(1));
190  }else{
191  hoc_pgetarg(1);
193  if (!sym) {
194 hoc_execerror("Cannot find the symbol associated with the pointer when called from Python", "Use a string instead of pointer argument");
195  }
196  if (nrn_vartype(sym) != STATE && sym->u.rng.type != VINDEX) {
197  hoc_execerror(sym->name, "is not a STATE");
198  }
199  }
200  if (ifarg(2)) {
201  hoc_symbol_tolerance(sym, chkarg(2, 1e-30, 1e30));
202  d->structure_change();
203  }
204  if (sym->extra && sym->extra->tolerance > 0.) {
205  return sym->extra->tolerance;
206  }else{
207  return 1.;
208  }
209 }
210 
211 static double active(void* v) {
212  if (ifarg(1)) {
213  cvode_active_ = (int)chkarg(1, 0, 1);
214  if (cvode_active_) {
215  NetCvode* d = (NetCvode*)v;
216  d->re_init(nt_t);
217  }
218  }
219  hoc_return_type_code = 2; // boolean
220  return cvode_active_;
221 }
222 static double stiff(void* v) {
223  NetCvode* d = (NetCvode*)v;
224  if (ifarg(1)) {
225  d->stiff((int)chkarg(1, 0, 2));
226  }
227  hoc_return_type_code = 1; // integer
228  return double(d->stiff());
229 }
230 static double maxorder(void* v) {
231  NetCvode* d = (NetCvode*)v;
232  if (ifarg(1)) {
233  d->maxorder((int)chkarg(1, 0, 5));
234  }
235  hoc_return_type_code = 1; // integer
236  return d->maxorder();
237 }
238 static double order(void* v) {
239  NetCvode* d = (NetCvode*)v;
240  int i = 0;
241  hoc_return_type_code = 1; // integer
242  if (ifarg(1)) {
243  // only thread 0
244  i = int(chkarg(1, 0, d->p->nlcv_ - 1));
245  }
246  int o = d->order(i);
247  return double(o);
248 }
249 static double minstep(void* v) {
250  NetCvode* d = (NetCvode*)v;
251  if (ifarg(1)) {
252  d->minstep(chkarg(1, 0., 1e9));
253  }
254  return d->minstep();
255 }
256 
257 static double maxstep(void* v) {
258  NetCvode* d = (NetCvode*)v;
259  if (ifarg(1)) {
260  d->maxstep(chkarg(1, 0., 1e9));
261  }
262  return d->maxstep();
263 }
264 
265 static double jacobian(void* v) {
266  NetCvode* d = (NetCvode*)v;
267  if (ifarg(1)) {
268  d->jacobian((int)chkarg(1, 0, 2));
269  }
270  hoc_return_type_code = 1; // int
271  return double(d->jacobian());
272 }
273 
274 static double states(void* v) {
275  NetCvode* d = (NetCvode*)v;
276  d->states();
277  return 0.;
278 }
279 
280 static double dstates(void* v) {
281  NetCvode* d = (NetCvode*)v;
282  d->dstates();
283  return 0.;
284 }
285 
286 extern double nrn_hoc2fun(void* v);
287 extern double nrn_hoc2scatter_y(void* v);
288 extern double nrn_hoc2gather_y(void* v);
289 extern double nrn_hoc2fixed_step(void* v);
290 
291 static double error_weights(void* v) {
292  NetCvode* d = (NetCvode*)v;
293  d->error_weights();
294  return 0.;
295 }
296 
297 static double acor(void* v) {
298  NetCvode* d = (NetCvode*)v;
299  d->acor();
300  return 0.;
301 }
302 
303 static double statename(void* v) {
304  NetCvode* d = (NetCvode*)v;
305  int i = (int)chkarg(1,0,1e9);
306  int style = 1;
307  if (ifarg(3)) {
308  style = (int)chkarg(3, 0, 2);
309  }
310  hoc_assign_str(hoc_pgargstr(2), d->statename(i, style));
311  return 0.;
312 }
313 
314 static double use_local_dt(void* v) {
315  NetCvode* d = (NetCvode*)v;
316  hoc_return_type_code = 2; // boolean
317  if (ifarg(1)) {
318  int i = (int)chkarg(1, 0, 1);
319  d->localstep(i);
320  }
321  return (double)d->localstep();
322 }
323 
324 static double use_daspk(void* v) {
325  NetCvode* d = (NetCvode*)v;
326  hoc_return_type_code = 2; // boolean
327  if (ifarg(1)) {
328  int i = (int)chkarg(1, 0, 1);
329  if ((i != 0) != d->use_daspk()) {
330  d->use_daspk(i);
331  }
332  }
333  return (double)d->use_daspk();
334 }
335 
336 static double dae_init_dteps(void* v) {
337  if (ifarg(1)) {
338  Daspk::dteps_ = chkarg(1, 1e-100, 1);
339  }
340  if (ifarg(2)) {
341  Daspk::init_failure_style_ = (int)chkarg(2, 0, 013);
342  }
343  return Daspk::dteps_;
344 }
345 
346 static double use_mxb(void* v) {
347  NetCvode* d = (NetCvode*)v;
348  hoc_return_type_code = 2; // boolean
349  if (ifarg(1)) {
350  int i = (int)chkarg(1,0,1);
351  if (use_sparse13 != i) {
352  use_sparse13 = i;
353  recalc_diam();
354  }
355  }
356  return (double) use_sparse13;
357 }
358 
359 static double cache_efficient(void* v) {
360  NetCvode* d = (NetCvode*)v;
361  if (ifarg(1)) {
362  int i = (int)chkarg(1,0,1);
363  nrn_cachevec(i);
364  }
365  hoc_return_type_code = 2; // boolean
366  return (double) use_cachevec;
367 }
368 
369 static double use_long_double(void* v) {
370  NetCvode* d = (NetCvode*)v;
371  hoc_return_type_code = 2; // boolean
372  if (ifarg(1)) {
373  int i = (int)chkarg(1,0,1);
374  d->use_long_double_ = i;
375  recalc_diam();
376  }
377  return (double)d->use_long_double_;
378 }
379 
380 static double condition_order(void* v) {
381  NetCvode* d = (NetCvode*)v;
382  if (ifarg(1)) {
383  int i = (int)chkarg(1,1,2);
384  d->condition_order(i);
385  }
386  hoc_return_type_code = 1; // integer
387  return (double) d->condition_order();
388 }
389 
390 static double debug_event(void* v) {
391  NetCvode* d = (NetCvode*)v;
392  if (ifarg(1)) {
393  int i = (int)chkarg(1, 0, 10);
394  d->print_event_ = i;
395  }
396  hoc_return_type_code = 1; // integer
397  return (double)d->print_event_;
398 }
399 
400 static double n_record(void* v) {
401  NetCvode* d = (NetCvode*)v;
402  d->vecrecord_add();
403  return 0.;
404 }
405 
406 static double n_remove(void* v) {
407  NetCvode* d = (NetCvode*)v;
408  d->vec_remove();
409  return 0.;
410 }
411 
412 static double simgraph_remove(void* v) {
413  NetCvode* d = (NetCvode*)v;
414  d->simgraph_remove();
415  return 0.;
416 }
417 
418 static double state_magnitudes(void* v) {
419  NetCvode* d = (NetCvode*)v;
420  return d->state_magnitudes();
421 }
422 
423 static double tstop_event(void* v) {
424  NetCvode* d = (NetCvode*)v;
425  double x = *getarg(1);
426  if (!cvode_active_) { // watch out for fixed step roundoff if x
427  // close to n*dt
428  double y = x/nrn_threads->_dt;
429  if (y > 1 && fabs(floor(y + 1e-6) - y) < 1e-6) {
430  //printf("reduce %g to avoid fixed step roundoff\n", x);
431  x -= nrn_threads->_dt/4.;
432  }
433  }
434  if (ifarg(2)) {
435  Object* ppobj = nil;
436  int reinit = 0;
437  if (ifarg(3)) {
438  ppobj = *hoc_objgetarg(3);
439  if (!ppobj || ppobj->ctemplate->is_point_ <= 0
440  || nrn_is_artificial_[ob2pntproc(ppobj)->prop->type]
441  ){
442  hoc_execerror(hoc_object_name(ppobj), "is not a POINT_PROCESS");
443  }
444  reinit = int(chkarg(4, 0, 1));
445  }
446  if (hoc_is_object_arg(2)) {
447  d->hoc_event(x, nil, ppobj, reinit, *hoc_objgetarg(2));
448  }else{
449  d->hoc_event(x, gargstr(2), ppobj, reinit);
450  }
451  }else{
452  //d->tstop_event(x);
453  d->hoc_event(x, 0, 0, 0);
454  }
455  return x;
456 }
457 
458 static double current_method(void* v) {
459  NetCvode* d = (NetCvode*)v;
460  hoc_return_type_code = 1; // integer
461  int modeltype = nrn_modeltype();
462  int methodtype = secondorder; // 0, 1, or 2
463  int localtype = 0;
464  if (cvode_active_) {
465  methodtype = 3;
466  if (d->use_daspk()) {
467  methodtype = 4;
468  }else{
469  localtype = d->localstep();
470  }
471  }
472  return double( modeltype + 10*use_sparse13 + 100*methodtype + 1000*localtype );
473 }
474 static double peq(void* v) {
475  NetCvode* d = (NetCvode*)v;
476  d->print_event_queue();
477  return 1.;
478 }
479 
480 static double event_queue_info(void* v) {
481  NetCvode* d = (NetCvode*)v;
482  d->event_queue_info();
483  return 1.;
484 }
485 
486 static double store_events(void* v) {
487  NetCvode* d = (NetCvode*)v;
488  d->vec_event_store();
489  return 1.;
490 }
491 
492 static Object** netconlist(void* v) {
493  NetCvode* d = (NetCvode*)v;
494  return d->netconlist();
495 }
496 
497 static double ncs_netcons(void* v) {
498 #if USENCS
499  nrn2ncs_netcons();
500 #endif
501  return 0.;
502 }
503 
504 // for testing when there is actually no pc.transfer or pc.multisplit present
505 // forces the global step to be truly global across processors.
506 static double use_parallel(void* v) {
507 #if PARANEURON
508  // assume single thread and global step
509  NetCvode* d = (NetCvode*)v;
510  assert(d->gcv_);
511  d->gcv_->use_partrans_ = true;
512  d->structure_change();
513  return 1.0;
514 #else
515  return 0.0;
516 #endif
517 }
518 
519 static double nrn_structure_change_count(void* v) {
520  hoc_return_type_code = 1; // integer
521  return double(structure_change_cnt);
522 }
523 
524 static double nrn_diam_change_count(void* v) {
525  hoc_return_type_code = 1; // integer
526  return double(diam_change_cnt);
527 }
528 
530 extern int (*nrnpy_hoccommand_exec)(Object*);
531 
532 declarePtrList(ExtraScatterList, Object)
533 implementPtrList(ExtraScatterList, Object)
534 static ExtraScatterList* extra_scatterlist[2]; // 0 scatter, 1 gather
535 
536 void nrn_extra_scatter_gather(int direction, int tid) {
537  ExtraScatterList* esl = extra_scatterlist[direction];
538  if (esl) {
539  nrn_thread_error("extra_scatter_gather not allowed with multiple threads");
540  for (int i=0; i < esl->count(); ++i) {
541  Object* callable = esl->item(i);
542  if (!(*nrnpy_hoccommand_exec)(callable)) {
543  hoc_execerror("extra_scatter_gather runtime error", 0);
544  }
545  }
546  }
547 }
548 
549 static double extra_scatter_gather(void* v) {
550  int direction = int(chkarg(1, 0, 1));
551  Object* o = *hoc_objgetarg(2);
552  check_obj_type(o, "PythonObject");
553  ExtraScatterList* esl = extra_scatterlist[direction];
554  if (!esl) {
555  esl = new ExtraScatterList(2);
556  extra_scatterlist[direction] = esl;
557  }
558  esl->append(o);
559  hoc_obj_ref(o);
560  return 0.;
561 }
562 
563 static double extra_scatter_gather_remove(void* v) {
564  Object* o = *hoc_objgetarg(1);
565  for (int direction=0; direction < 2; ++direction) {
566  ExtraScatterList* esl = extra_scatterlist[direction];
567  if (esl) for (int i = esl->count()-1; i >= 0; --i) {
568  Object* o1 = esl->item(i);
569  // if esl exists then python exists
570  if ((*nrnpy_pysame)(o, o1)) {
571  esl->remove(i);
572  hoc_obj_unref(o1);
573  }
574  }
575  }
576  return 0.;
577 }
578 
579 static double use_fast_imem(void* v) {
580  int i = nrn_use_fast_imem;
581  hoc_return_type_code = 2; // boolean
582  if (ifarg(1)) {
583  nrn_use_fast_imem = int(chkarg(1, 0., 1.));
585  }
586  return double(i);
587 }
588 
589 static Member_func members[] = {
590  "solve", solve,
591  "atol", nrn_atol,
592  "rtol", rtol,
593  "re_init", re_init,
594  "stiff", stiff,
595  "active", active,
596  "maxorder", maxorder,
597  "minstep", minstep,
598  "maxstep", maxstep,
599  "jacobian", jacobian,
600  "states", states,
601  "dstates", dstates,
602  "error_weights", error_weights,
603  "acor", acor,
604  "statename", statename,
605  "atolscale", abstol,
606  "use_local_dt", use_local_dt,
607  "record", n_record,
608  "record_remove", n_remove,
609  "debug_event", debug_event,
610  "order", order,
611  "use_daspk", use_daspk,
612  "event", tstop_event,
613  "current_method", current_method,
614  "use_mxb", use_mxb,
615  "print_event_queue", peq,
616  "event_queue_info", event_queue_info,
617  "store_events", store_events,
618  "condition_order", condition_order,
619  "dae_init_dteps", dae_init_dteps,
620  "simgraph_remove", simgraph_remove,
621  "state_magnitudes", state_magnitudes,
622  "ncs_netcons", ncs_netcons,
623  "statistics", statistics,
624  "spike_stat", spikestat,
625  "queue_mode", queue_mode,
626  "cache_efficient", cache_efficient,
627  "use_long_double", use_long_double,
628  "use_parallel", use_parallel,
629  "f", nrn_hoc2fun,
630  "yscatter", nrn_hoc2scatter_y,
631  "ygather", nrn_hoc2gather_y,
632  "fixed_step", nrn_hoc2fixed_step,
633  "structure_change_count", nrn_structure_change_count,
634  "diam_change_count", nrn_diam_change_count,
635  "extra_scatter_gather", extra_scatter_gather,
636  "extra_scatter_gather_remove", extra_scatter_gather_remove,
637  "use_fast_imem", use_fast_imem,
638  0,0
639 };
640 
642  "netconlist", netconlist,
643  0, 0
644 };
645 
646 static void* cons(Object*) {
647 #if 0
648  NetCvode* d;
649  if (net_cvode_instance) {
650  hoc_execerror("Only one CVode instance allowed", 0);
651  }else{
652  d = new NetCvode(1);
653  net_cvode_instance = d;
654  }
655  active(nil);
656  return (void*) d;
657 #else
658  return (void*)net_cvode_instance;
659 #endif
660 }
661 static void destruct(void* v) {
662 #if 0
663  NetCvode* d = (NetCvode*)v;
664  cvode_active_ = 0;
665  delete d;
666 #endif
667 }
668 void Cvode_reg() {
669  class2oc("CVode", cons, destruct, members, NULL, omembers, NULL);
670  net_cvode_instance = new NetCvode(1);
671  Daspk::dteps_ = 1e-9; // change with cvode.dae_init_dteps(newval)
672 }
673 
674 /* Functions Called by the CVODE Solver */
675 
676 static int minit(CVodeMem cv_mem);
677 static int msetup(CVodeMem cv_mem, int convfail, N_Vector ypred,
678  N_Vector fpred, booleantype *jcurPtr, N_Vector vtemp,
679  N_Vector vtemp2, N_Vector vtemp3);
680 static int msolve(CVodeMem cv_mem, N_Vector b, N_Vector weight, N_Vector ycur,
681  N_Vector fcur);
682 static int msolve_lvardt(CVodeMem cv_mem, N_Vector b, N_Vector weight, N_Vector ycur,
683  N_Vector fcur);
684 static void mfree(CVodeMem cv_mem);
685 static void f_gvardt(realtype t, N_Vector y, N_Vector ydot, void *f_data);
686 static void f_lvardt(realtype t, N_Vector y, N_Vector ydot, void *f_data);
687 static CVRhsFn pf_;
688 
689 static void* msetup_thread(NrnThread*);
690 static void* msolve_thread(NrnThread*);
691 static void* msolve_thread_part1(NrnThread*);
692 static void* msolve_thread_part2(NrnThread*);
693 static void* msolve_thread_part3(NrnThread*);
694 static void* f_thread(NrnThread*);
695 static void* f_thread_transfer_part1(NrnThread*);
696 static void* f_thread_transfer_part2(NrnThread*);
697 static void* f_thread_ms_part1(NrnThread*);
698 static void* f_thread_ms_part2(NrnThread*);
699 static void* f_thread_ms_part3(NrnThread*);
700 static void* f_thread_ms_part4(NrnThread*);
701 static void* f_thread_ms_part34(NrnThread*);
702 
705  ncv_ = ncv;
706 }
709 }
711  nthsizes_ = nil;
712  nth_ = nil;
713  ncv_ = nil;
714  ctd_ = nil;
715  tqitem_ = nil;
716  mem_ = nil;
717 #if NEOSIMorNCS
718  neosim_self_events_ = nil;
719 #endif
720  initialize_ = false;
721  can_retreat_ = false;
722  tstop_begin_ = 0.;
723  tstop_end_ = 0.;
724  use_daspk_ = false;
725  daspk_ = nil;
726 
727  mem_ = nil;
728  y_ = nil;
729  atolnvec_ = nil;
730  maxstate_ = nil;
731  maxacor_ = nil;
732  neq_ = 0;
733  structure_change_ = true;
734 #if PARANEURON
735  use_partrans_ = false;
736  global_neq_ = 0;
737  opmode_ = 0;
738 #endif
739 }
740 
741 double Cvode::gam() {
742  if (mem_) {
743  return ((CVodeMem)mem_)->cv_gamma;
744  }else{
745  return 1.;
746  }
747 }
748 
749 double Cvode::h() {
750  if (mem_) {
751  return ((CVodeMem)mem_)->cv_h;
752  }else{
753  return 0.;
754  }
755 }
756 
757 bool Cvode::at_time(double te, NrnThread* nt) {
758  if (initialize_) {
759 //printf("%d at_time initialize te=%g te-t0_=%g next_at_time_=%g\n", nt->id, te, te-t0_, next_at_time_);
760  MUTLOCK
761  if (t0_ < te && te < next_at_time_) {
762 //printf("%d next_at_time_=%g since te-t0_=%15.10g and next_at_time_-te=%g\n", nt->id, te, te-nt->_t, next_at_time_-te);
763  next_at_time_ = te;
764  }
765  MUTUNLOCK
766  if (MyMath::eq(te, t0_, NetCvode::eps(t0_))) {
767 //printf("at_time te=%g t-te=%g return 1\n", te, t - te);
768  return 1;
769  }
770  return 0;
771  }
772  // No at_time event is inside our allowed integration interval.
773  // such an event would be unhandled. It would be an error for
774  // a model description to dynamically compute such an event.
775  // The policy is strict that during at_time
776  // event handling the next at_time event is known so that
777  // the stop time can be set. This could be relaxed
778  // only to the extent that whatever at_time is computed is
779  // beyond the current step.
780  if (nt->_vcv) {
781 if (te <= tstop_ && te > t0_) {
782 Printf("te=%g t0_=%g tn_=%g t_=%g t=%g\n", te, t0_, tn_, t_, nt_t);
783 Printf("te-t0_=%g tstop_-te=%g\n", te - t0_, tstop_ - te);
784 }
785  assert( te > tstop_ || te <= t0_);
786  }
787  return 0;
788 }
789 
791 //printf("set_init_flag t_=%g prior2init_=%d\n", t_, prior2init_);
792  initialize_ = true;
793  if (cvode_active_ && ++prior2init_ == 1) {
795  }
796 }
797 
798 N_Vector Cvode::nvnew(long int n) {
799 #if PARANEURON
800  if (use_partrans_) {
801  if (net_cvode_instance->use_long_double_) {
802  return N_VNew_NrnParallelLD(0, n, global_neq_);
803  }else{
804  return N_VNew_Parallel(0, n, global_neq_);
805  }
806  }
807 #endif
808  if (nctd_ > 1) {
809  assert(n == neq_);
810  if (!nthsizes_) {
811  nthsizes_ = new long int[nrn_nthread];
812  for (int i = 0; i < nrn_nthread; ++i) {
813  nthsizes_[i] = ctd_[i].nvsize_;
814  }
815  }
816 #if 1
817  int sum = 0;
818  for (int i=0; i < nctd_; ++i) { sum += nthsizes_[i];}
819  assert(sum == neq_);
820 #endif
821  if (net_cvode_instance->use_long_double_) {
822  return N_VNew_NrnThreadLD(n, nctd_, nthsizes_);
823  }else{
824  return N_VNew_NrnThread(n, nctd_, nthsizes_);
825  }
826  }
827  if (net_cvode_instance->use_long_double_) {
828  return N_VNew_NrnSerialLD(n);
829  }else{
830  return N_VNew_Serial(n);
831  }
832 }
833 
835  if (i > 0) {
836  // too bad the machEnv has to be done here but this is
837  // the first and it depends on size
838  // the call chain is init_prepare (frees) -> init_eqn -> here
839  atolnvec_ = nvnew(i);
840  }
841 }
842 
844 #if NEOSIMorNCS
845  if (neosim_self_events_) {
846  delete neosim_self_events_;
847  }
848 #endif
849  if (daspk_) {
850  delete daspk_;
851  }
852  if (y_) {
853  N_VDestroy(y_);
854  }
855  if (atolnvec_) {
856  N_VDestroy(atolnvec_);
857  }
858  if (mem_) {
859  CVodeFree(mem_);
860  }
861  if (maxstate_) {
862  N_VDestroy(maxstate_);
863  N_VDestroy(maxacor_);
864  }
865  if (nthsizes_) {
866  delete [] nthsizes_;
867  }
868 // delete [] iopt_;
869 // delete [] ropt_;
870 
871 }
872 
877 }
878 
880  if (init_global()) {
881  if (y_) {
882  N_VDestroy(y_);
883  y_ = nil;
884  }
885  if (mem_) {
886  CVodeFree(mem_);
887  mem_ = nil;
888  }
889  if (atolnvec_) {
890  N_VDestroy(atolnvec_);
891  atolnvec_ = nil;
892  }
893  if (daspk_) {
894  delete daspk_;
895  daspk_ = nil;
896  }
897  init_eqn();
898  if (neq_ > 0) {
899  y_ = nvnew(neq_);
900  if (use_daspk_) {
901  alloc_daspk();
902  }else{
903  alloc_cvode();
904  }
905  if (maxstate_) {
906  activate_maxstate(false);
907  activate_maxstate(true);
908  }
909  }
910  }
911 }
912 
914  if (maxstate_) {
915  N_VDestroy(maxstate_);
916  N_VDestroy(maxacor_);
917  maxstate_ = nil;
918  maxacor_ = nil;
919  }
920  if (on && neq_ > 0) {
921  int i;
922  maxstate_ = nvnew(neq_);
923  maxacor_ = nvnew(neq_);
924  N_VConst(0.0, maxstate_);
925  N_VConst(0.0, maxacor_);
926  }
927 }
928 
929 static bool maxstate_b;
931 static void* maxstate_thread(NrnThread* nt) {
932  maxstate_cv->maxstate(maxstate_b, nt);
933  return 0;
934 }
935 void Cvode::maxstate(bool b, NrnThread* nt) {
936  if (!maxstate_) { return; }
937  if (!nt) {
938  if (nrn_nthread > 1) {
939  maxstate_cv = this;
940  maxstate_b = b;
942  return;
943  }
944  nt = nrn_threads;
945  }
946  CvodeThreadData& z = ctd_[nt->id];
947  int i;
948  double x;
949  double* y = n_vector_data(y_, nt->id);
950  double* m = n_vector_data(maxstate_, nt->id);
951  for (i=0; i < z.nvsize_; ++i) {
952  x = Math::abs(y[i]);
953  if (m[i] < x) {
954  m[i] = x;
955  }
956  }
957  if (b) {
958  y = n_vector_data(acorvec(), nt->id);
959  m = n_vector_data(maxacor_, nt->id);
960  for (i=0; i < z.nvsize_; ++i) {
961  x = Math::abs(y[i]);
962  if (m[i] < x) {
963  m[i] = x;
964  }
965  }
966  }
967 }
968 
969 void Cvode::maxstate(double* pd) {
970  int i;
971  NrnThread* nt;
972  if (maxstate_) {
973  FOR_THREADS(nt) {
974  double* m = n_vector_data(maxstate_, nt->id);
975  int n = ctd_[nt->id].nvsize_;
976  int o = ctd_[nt->id].nvoffset_;
977  for (i=0; i < n; ++i) {
978  pd[i+o] = m[i];
979  }
980  }
981  }
982 }
983 
984 void Cvode::maxacor(double* pd) {
985  int i;
986  NrnThread* nt;
987  if (maxacor_) {
988  FOR_THREADS(nt) {
989  double* m = n_vector_data(maxacor_, nt->id);
990  int n = ctd_[nt->id].nvsize_;
991  int o = ctd_[nt->id].nvoffset_;
992  for (i=0; i < n; ++i) {
993  pd[i+o] = m[i];
994  }
995  }
996  }
997 }
998 
1000 }
1001 
1003  int i = 0;
1004  if (use_daspk_) {
1005  if (daspk_->mem_) { IDAGetLastOrder(daspk_->mem_, &i); }
1006  }else{
1007  if (mem_) { CVodeGetLastOrder(mem_, &i); }
1008  }
1009  return i;
1010 }
1011 void Cvode::maxorder(int maxord) {
1012  if (use_daspk_) {
1013  if (daspk_->mem_) { IDASetMaxOrd(daspk_->mem_, maxord); }
1014  }else{
1015  if (mem_) { CVodeSetMaxOrd(mem_, maxord); }
1016  }
1017 }
1018 void Cvode::minstep(double x) {
1019  if (mem_) {
1020  if (x > 0.) {
1021  CVodeSetMinStep(mem_, x);
1022  }else{
1023  // CVodeSetMinStep requires x > 0 but
1024  // HMIN_DEFAULT is ZERO in cvodes.cpp
1025  ((CVodeMem)mem_)->cv_hmin = 0.;
1026  }
1027  }
1028 }
1029 void Cvode::maxstep(double x) {
1030  if (use_daspk_) {
1031  if (daspk_->mem_) { IDASetMaxStep(daspk_->mem_, x); }
1032  }else{
1033  if (mem_) { CVodeSetMaxStep(mem_, x); }
1034  }
1035 }
1036 
1038  if (mem_) {
1039  CVodeFree(mem_);
1040  mem_ = nil;
1041  }
1042 }
1043 
1045  MUTDESTRUCT
1046  static_mutex_for_at_time(false);
1047  if (single_) {
1048  pf_ = f_gvardt;
1049  if (nrn_nthread > 1) {
1050  MUTCONSTRUCT(1)
1052  }
1053  }else{
1054  pf_ = f_lvardt;
1055  }
1056 }
1057 
1058 int Cvode::cvode_init(double) {
1059  int iter;
1060  int err = SUCCESS;
1061  // note, a change in stiff_ due to call of stiff() destroys mem_
1062  gather_y(y_);
1063  // TODO: this needs changed if want to support more than one thread or local variable timestep
1064  nrn_nonvint_block_ode_reinit(neq_, N_VGetArrayPointer(y_), 0);
1065  if (mem_) {
1066  err = CVodeReInit(mem_, pf_, t0_, y_, CV_SV, &ncv_->rtol_, atolnvec_);
1067  CVodeSetFdata(mem_, (void*)this);
1068  //printf("CVodeReInit\n");
1069  if (err != SUCCESS){
1070  Printf("Cvode %p %s CVReInit error %d\n", this, secname(ctd_[0].v_node_[ctd_[0].rootnodecount_]->sec), err);
1071  return err;
1072  }
1073  }else{
1074  mem_ = CVodeCreate(CV_BDF, ncv_->stiff() ? CV_NEWTON : CV_FUNCTIONAL);
1075  if (!mem_){
1076  hoc_execerror ("CVodeCreate error", 0);
1077  }
1078  CVodeMalloc(mem_, pf_, t0_, y_, CV_SV, &ncv_->rtol_, atolnvec_);
1079  CVodeSetFdata(mem_, (void*)this);
1080  if (err != SUCCESS){
1081  Printf("Cvode %p %s CVodeMalloc error %d\n", this, secname(ctd_[0].v_node_[ctd_[0].rootnodecount_]->sec), err);
1082  return err;
1083  }
1084  maxorder(ncv_->maxorder());
1085  minstep(ncv_->minstep());
1086  maxstep(ncv_->maxstep());
1087 // CVodeSetInitStep(mem_, .01);
1088  }
1089  matmeth();
1090  ((CVodeMem)mem_)->cv_gamma = 0.;
1091  ((CVodeMem)mem_)->cv_h = 0.; // fun called before cvode sets this (though fun does not need it really)
1092  //fun(t_, N_VGetArrayPointer(y_), nil);
1093  (*pf_)(t_, y_, nil, (void*)this);
1094  can_retreat_ = false;
1095  return err;
1096 }
1097 
1098 int Cvode::daspk_init(double tout) {
1099  return daspk_->init();
1100 }
1101 
1103 //printf("Cvode::alloc_daspk\n");
1104  daspk_ = new Daspk(this, neq_);
1105  // we do our own initialization since it is hard to
1106  // figure out which equations are algebraic and which
1107  // differential. eg. the no cap nodes can have a
1108  // circuit with capacitance connection. Extracellular
1109  // nodes may or may not have capacitors to ground.
1110 
1111 }
1112 
1114  int err = SUCCESS;
1115  if (neq_ == 0) {
1116  t_ += 1e9;
1117  if (nth_) { nth_->_t = t_; } else { nt_t = t_; }
1118  tn_ = t_;
1119  return err;
1120  }
1121 //printf("%d Cvode::advance_tn enter t_=%.20g t0_=%.20g tstop_=%.20g\n", nrnmpi_myid, t_, t0_, tstop_);
1122  if (t_ >= tstop_ - NetCvode::eps(t_)) {
1123 //printf("init\n");
1124  ++ts_inits_;
1125  tstop_begin_ = tstop_;
1127  err = init(tstop_end_);
1128  // the above 1.5 is due to the fact that at_time will check
1129  // to see if the time is greater but not greater than eps*t0_
1130  // of the at_time for a return of 1.
1131  can_retreat_ = false;
1132  }else{
1133  ++advance_calls_;
1134  // SOLVE after_cvode now interpreted as before cvode since
1135  // a step may be abandoned in part by interpolate in response
1136  // to events. Now at least the value of t is monotonic
1137  if (nth_) { nth_->_t = t_; } else { nt_t = t_; }
1138  do_nonode(nth_);
1139 #if PARANEURON
1140  opmode_ = 1;
1141 #endif
1142  if (use_daspk_) {
1143  err = daspk_advance_tn();
1144  }else{
1145  err = cvode_advance_tn();
1146  }
1147  can_retreat_ = true;
1148  maxstate(true);
1149  }
1150 //printf("%d Cvode::advance_tn exit t_=%.20g t0_=%.20g tstop_=%.20g\n", nrnmpi_myid, t_, t0_, tstop_);
1151  return err;
1152 }
1153 
1155 //printf("%d Cvode::solve %p initialize = %d current_time=%g tn=%g\n", nrnmpi_myid, this, initialize_, t_, tn());
1156  int err = SUCCESS;
1157  if (initialize_) {
1158  if (t_ >= tstop_ - NetCvode::eps(t_)) {
1159  ++ts_inits_;
1160  tstop_begin_ = tstop_;
1162  err = init(tstop_end_);
1163  can_retreat_ = false;
1164  }else{
1165  err = init(t_);
1166  }
1167  }else{
1168  err = advance_tn();
1169  }
1170 //printf("Cvode::solve exit %p current_time=%g tn=%g\n", this, t_, tn());
1171  return err;
1172 }
1173 
1174 int Cvode::init(double tout) {
1175  int err = SUCCESS;
1176  ++init_calls_;
1177 //printf("%d Cvode_%p::init tout=%g\n", nrnmpi_myid, this, tout);
1178  initialize_ = true;
1179  t_ = tout;
1180  t0_ = t_;
1181  tn_ = t_;
1182  next_at_time_ = t_ + 1e5;
1183  init_prepare();
1184  if (neq_) {
1185 #if PARANEURON
1186  opmode_ = 3;
1187 #endif
1188  if (use_daspk_) {
1189  err = daspk_init(t_);
1190  }else{
1191  err = cvode_init(t_);
1192  }
1193  }
1195 #if PARANEURON
1196  if (use_partrans_) {
1197  tstop_ = nrnmpi_dbl_allmin(tstop_);
1198  }
1199 #endif
1200 //printf("Cvode::init next_at_time_=%g tstop_=%.15g\n", next_at_time_, tstop_);
1201  initialize_ = false;
1202  prior2init_ = 0;
1203  maxstate(false);
1204  return err;
1205 }
1206 
1207 int Cvode::interpolate(double tout) {
1208  NrnThread* _nt;
1209  if (neq_ == 0) {
1210  t_ = tout;
1211  if (nth_) {
1212  nth_->_t = t_;
1213  }else{
1214  FOR_THREADS(_nt) {
1215  _nt->_t = t_;
1216  }
1217  }
1218  return SUCCESS;
1219  }
1220 //printf("Cvode::interpolate t_=%.15g t0_=%.15g tn_=%.15g tstop_=%.15g\n", t_, t0_, tn_, tstop_);
1221  if (!can_retreat_) {
1222  // but must be within the initialization domain
1223  assert (MyMath::le(tout, t_, 2.*NetCvode::eps(t_)));
1224  if (nth_) { // lvardt
1225  nth_->_t = tout;
1226  }else{
1227  FOR_THREADS(_nt) {
1228  _nt->_t = tout; // but leave t_ at the initialization point.
1229  }
1230  }
1231 // printf("no interpolation for event in the initialization interval t=%15g t_=%15g\n", nrn_threads->t, t_);
1232  return SUCCESS;
1233  }
1234  if (MyMath::eq(tout, t_, NetCvode::eps(t_))) {
1235  t_ = tout;
1236  return SUCCESS;
1237  }
1238 //if (initialize_) {
1239 //printf("Cvode_%p::interpolate assert error when initialize_ is true.\n t_=%g tout=%g tout-t_ = %g\n", this, t_, tout, tout-t_);
1240 //}
1241 assert(initialize_ == false); // or state discontinuity can be lost
1242 //printf("interpolate t_=%g tout=%g delta t_-tout=%g\n", t_, tout, t_-tout);
1243 #if 1
1244 if (tout < t0_) {
1245 // if (tout < t0_ - NetCvode::eps(t0_)) { // t0_ not always == tn_ - h
1246  // after a CV_ONESTEP_TSTOP
1247  // so allow some fudge before printing error
1248  // The fudge case was avoided by returning from the
1249  // Cvode::handle_step when a first order condition check
1250  // puts an event on the queue equal to t_
1251 Printf("Cvode::interpolate assert error t0=%g tout-t0=%g eps*t_=%g\n", t0_, tout-t0_, NetCvode::eps(t_));
1252 // }
1253  tout = t0_;
1254 }
1255 if (tout > tn_) {
1256 Printf("Cvode::interpolate assert error tn=%g tn-tout=%g eps*t_=%g\n", tn_, tn_-tout, NetCvode::eps(t_));
1257  tout = tn_;
1258 }
1259 #endif
1260 // if there is a problem here it may be due to the at_time skipping interval
1261 // since the integration will not go past tstop_ and will take up at tstop+2eps
1262 // see the Cvode::advance_tn() implementation
1263  assert( tout >= t0() && tout <= tn());
1264 
1266 #if PARANEURON
1267  opmode_ = 2;
1268 #endif
1269  if (use_daspk_) {
1270  return daspk_->interpolate(tout);
1271  }else{
1272  return cvode_interpolate(tout);
1273  }
1274 }
1275 
1277 #if PRINT_EVENT
1278 if (net_cvode_instance->print_event_ > 1) {
1279 Printf("Cvode::cvode_advance_tn %p %d initialize_=%d tstop=%.20g t_=%.20g to ",
1280 this, nth_?nth_->id:0, initialize_, tstop_, t_);
1281 }
1282 #endif
1283  CVodeSetStopTime(mem_, tstop_);
1284 //printf("cvode_advance_tn begin t0_=%g t_=%g tn_=%g tstop=%g\n", t0_, t_, tn_, tstop_);
1285  int err = CVode(mem_, tstop_, y_, &t_, CV_ONE_STEP_TSTOP);
1286 #if PRINT_EVENT
1287 if (net_cvode_instance->print_event_ > 1) {
1288 Printf("t_=%.20g\n", t_);
1289 }
1290 #endif
1291  if (err < 0 ) {
1292  Printf("CVode %p %s advance_tn failed, err=%d.\n", this, secname(ctd_[0].v_node_[ctd_[0].rootnodecount_]->sec), err);
1293  (*pf_)(t_, y_, nil, (void*)this);
1294  return err;
1295  }
1296  // this is very bad, performance-wise. However cvode modifies its states
1297  // after a call to fun with the proper t.
1298 #if 1
1299  (*pf_)(t_, y_, nil, (void*)this);
1300 #else
1301  NrnThread* _nt;
1302  scatter_y(y_);
1303 #endif
1304  tn_ = ((CVodeMem)mem_)->cv_tn;
1305  t0_ = tn_ - ((CVodeMem)mem_)->cv_h;
1306 //printf("t=%.15g t_=%.15g tn()=%.15g tstop_=%.15g t0_=%.15g\n", nrn_threads->t, t_, tn(), tstop_, t0_);
1307 // printf("t_=%g h=%g q=%d y=%g\n", t_, ((CVodeMem)mem_)->cv_h, ((CVodeMem)mem_)->cv_q, N_VIth(y_,0));
1308 //printf("cvode_advance_tn end t0_=%g t_=%g tn_=%g\n", t0_, t_, tn_);
1309  return SUCCESS;
1310 }
1311 
1312 int Cvode::cvode_interpolate(double tout) {
1313 #if PRINT_EVENT
1314 if (net_cvode_instance->print_event_ > 1) {
1315 Printf("Cvode::cvode_interpolate %p %d initialize_%d t=%.20g to ",
1316 this, nth_?nth_->id:0, initialize_, t_);
1317 }
1318 #endif
1319  // avoid CVode-- tstop = 0.5 is behind current t = 0.5
1320  // is this really necessary anymore. Maybe NORMAL mode ignores tstop
1321  CVodeSetStopTime(mem_, tstop_ + tstop_);
1322  int err = CVode(mem_, tout, y_, &t_, CV_NORMAL);
1323 #if PRINT_EVENT
1324 if (net_cvode_instance->print_event_ > 1) {
1325 Printf("%.20g\n", t_);
1326 }
1327 #endif
1328  if (err < 0) {
1329  Printf("CVode %p %s interpolate failed, err=%d.\n", this, secname(ctd_[0].v_node_[ctd_[0].rootnodecount_]->sec), err);
1330  return err;
1331  }
1332  (*pf_)(t_, y_, nil, (void*)this);
1333 // printf("t_=%g h=%g q=%d y=%g\n", t_, ((CVodeMem)mem_)->cv_h, ((CVodeMem)mem_)->cv_q, N_VIth(y_,0));
1334  return SUCCESS;
1335 }
1336 
1338  int flag, err;
1339  double tin;
1340 //printf("Cvode::solve test stop time t=%.20g tstop-t=%g\n", t, tstop_-t);
1341 //printf("in Cvode::solve t_=%g tstop=%g calling daspk_->solve(%g)\n", t_, tstop_, daspk_->tout_);
1342  err = daspk_->advance_tn(tstop_);
1343 //printf("in Cvode::solve returning from daspk_->solve t_=%g initialize_=%d tstop=%g\n", t_, initialize__, tstop_);
1344  if (err < 0) {
1345  return err;
1346  }
1347  return SUCCESS;
1348 }
1349 
1350 N_Vector Cvode::ewtvec() {
1351  if (use_daspk_) {
1352  return daspk_->ewtvec();
1353  }else{
1354  return ((CVodeMem)mem_)->cv_ewt;
1355  }
1356 }
1357 
1358 N_Vector Cvode::acorvec() {
1359  if (use_daspk_) {
1360  return daspk_->acorvec();
1361  }else{
1362  return ((CVodeMem)mem_)->cv_acor;
1363  }
1364 }
1365 
1367 #if 1
1368  Printf("\nCvode instance %p %s statistics : %d %s states\n",
1369  this, secname(ctd_[0].v_node_[ctd_[0].rootnodecount_]->sec), neq_,
1370  (use_daspk_ ? "IDA" : "CVode"));
1371  Printf(" %d advance_tn, %d interpolate, %d init (%d due to at_time)\n", advance_calls_, interpolate_calls_, init_calls_, ts_inits_);
1372  Printf(" %d function evaluations, %d mx=b solves, %d jacobian setups\n", f_calls_, mxb_calls_, jac_calls_);
1373  if (use_daspk_) {
1374  daspk_->statistics();
1375  return;
1376  }
1377 #else
1378  Printf("\nCVode Statistics.. \n\n");
1379  Printf("internal steps = %d\nfunction evaluations = %d\n",
1380  iopt_[NST], iopt_[NFE]);
1381  Printf("newton iterations = %d setups = %d\n nonlinear convergence failures = %d\n\
1382  local error test failures = %ld\n",
1383  iopt_[NNI], iopt_[NSETUPS], iopt_[NCFN], iopt_[NETF]);
1384  Printf("order=%d stepsize=%g\n", iopt_[QU], h());
1385 #endif
1386 }
1387 
1389  switch ( ncv_->jacobian() ) {
1390  case 1:
1391  CVDense(mem_, neq_);
1392  break;
1393  case 2:
1394  CVDiag(mem_);
1395  break;
1396  default:
1397  ((CVodeMem)mem_)->cv_linit = minit;
1398  ((CVodeMem)mem_)->cv_lsetup = msetup;
1399  ((CVodeMem)mem_)->cv_setupNonNull = TRUE; // but since our's does not do anything...
1400  if (nth_) { // lvardt
1401  ((CVodeMem)mem_)->cv_lsolve = msolve_lvardt;
1402  }else{
1403  ((CVodeMem)mem_)->cv_lsolve = msolve;
1404  }
1405  ((CVodeMem)mem_)->cv_lfree = mfree;
1406  break;
1407  }
1408 }
1409 
1410 static int minit(CVodeMem) {
1411 // printf("minit\n");
1412  return CV_NO_FAILURES;
1413 }
1414 
1415 static int msetup(CVodeMem m, int convfail,
1416  N_Vector yp, N_Vector fp, booleantype* jcurPtr,
1417  N_Vector, N_Vector, N_Vector)
1418 {
1419 // printf("msetup\n");
1420  *jcurPtr = true;
1421  Cvode* cv = (Cvode*)m->cv_f_data;
1422  return cv->setup(yp, fp);
1423 }
1424 
1425 static N_Vector msolve_b_;
1426 static N_Vector msolve_ycur_;
1428 static int msolve(CVodeMem m, N_Vector b, N_Vector weight, N_Vector ycur, N_Vector fcur) {
1429 // printf("msolve gamma=%g gammap=%g gamrat=%g\n", m->cv_gamma, m->cv_gammap, m->cv_gamrat);
1430 // N_VIth(b, 0) /= (1. + m->cv_gamma);
1431 // N_VIth(b, 0) /= (1. + m->cv_gammap);
1432 // N_VIth(b,0) *= 2./(1. + m->cv_gamrat);
1433  msolve_cv_ = (Cvode*)m->cv_f_data;
1434  Cvode& cv = *msolve_cv_;
1435  ++cv.mxb_calls_;
1436  if (cv.ncv_->stiff() == 0) { return 0; }
1437  if (cv.gam() == 0.) { return 0; } // i.e. (I - gamma * J)*x = b means x = b
1438  msolve_b_ = b;
1439  msolve_ycur_ = ycur;
1440  if (nrn_multisplit_setup_ && nrn_nthread > 1) {
1444  }else{
1446  }
1447  return 0;
1448 }
1449 static int msolve_lvardt(CVodeMem m, N_Vector b, N_Vector weight, N_Vector ycur, N_Vector fcur) {
1450  Cvode* cv = (Cvode*)m->cv_f_data;
1451  ++cv->mxb_calls_;
1452  if (cv->ncv_->stiff() == 0) { return 0; }
1453  if (cv->gam() == 0.) { return 0; }
1454  cv->nth_->_vcv = cv;
1455  cv->solvex_thread(cv->n_vector_data(b, 0),
1456  cv->n_vector_data(ycur, 0), cv->nth_);
1457  cv->nth_->_vcv = 0;
1458  return 0;
1459 }
1460 static void* msolve_thread(NrnThread* nt) {
1461  int i = nt->id;
1462  Cvode* cv = msolve_cv_;
1463  nt->_vcv = cv;
1465  cv->n_vector_data(msolve_ycur_, i), nt);
1466  nt->_vcv = 0;
1467  return 0;
1468 }
1469 static void* msolve_thread_part1(NrnThread* nt) {
1470  int i = nt->id;
1471  Cvode* cv = msolve_cv_;
1472  nt->_vcv = cv;
1473  cv->solvex_thread_part1(cv->n_vector_data(msolve_b_, i), nt);
1474  return 0;
1475 }
1476 static void* msolve_thread_part2(NrnThread* nt) {
1477  int i = nt->id;
1478  Cvode* cv = msolve_cv_;
1479  cv->solvex_thread_part2(nt);
1480  return 0;
1481 }
1482 static void* msolve_thread_part3(NrnThread* nt) {
1483  int i = nt->id;
1484  Cvode* cv = msolve_cv_;
1485  cv->solvex_thread_part3(cv->n_vector_data(msolve_b_, i), nt);
1486  nt->_vcv = 0;
1487  return 0;
1488 }
1489 
1490 static void mfree(CVodeMem) {
1491 // printf("mfree\n");
1492 }
1493 
1494 static realtype f_t_;
1495 static N_Vector f_y_;
1496 static N_Vector f_ydot_;
1497 static Cvode* f_cv_;
1498 static void f_gvardt(realtype t, N_Vector y, N_Vector ydot, void *f_data) {
1499  //ydot[0] = -y[0];
1500 // N_VIth(ydot, 0) = -N_VIth(y, 0);
1501 //printf("f(%g, %p, %p)\n", t, y, ydot);
1502  f_cv_ = (Cvode*)f_data;
1503  ++f_cv_->f_calls_;
1504  f_t_ = t;
1505  f_y_ = y;
1506  f_ydot_ = ydot;
1507  if (nrn_nthread > 1 || nrnmpi_numprocs > 1) {
1508  if (nrn_multisplit_setup_) {
1511  if (nrnthread_v_transfer_) {
1513  if (nrnmpi_v_transfer_) {
1514  (*nrnmpi_v_transfer_)();
1515  }
1517  }else{
1519  }
1520  }else if (nrnthread_v_transfer_) {
1522  if (nrnmpi_v_transfer_) {
1523  (*nrnmpi_v_transfer_)();
1524  }
1526  }else{
1528  }
1529  }else{
1531  }
1532 }
1533 static void f_lvardt(realtype t, N_Vector y, N_Vector ydot, void *f_data) {
1534  Cvode* cv = (Cvode*)f_data;
1535  ++cv->f_calls_;
1536  cv->nth_->_vcv = cv;
1537  cv->fun_thread(t, cv->n_vector_data(y, 0),
1538  cv->n_vector_data(ydot, 0), cv->nth_);
1539  cv->nth_->_vcv = 0;
1540 }
1541 
1542 static void* f_thread(NrnThread* nt) {
1543  int i = nt->id;
1544  Cvode* cv = f_cv_;
1545  nt->_vcv = cv;
1546  cv->fun_thread(f_t_, cv->n_vector_data(f_y_, i),
1547  cv->n_vector_data(f_ydot_, i), nt);
1548  nt->_vcv = 0;
1549  return 0;
1550 }
1552  int i = nt->id;
1553  Cvode* cv = f_cv_;
1554  nt->_vcv = cv;
1556  return 0;
1557 }
1559  int i = nt->id;
1560  Cvode* cv = f_cv_;
1562  nt->_vcv = 0;
1563  return 0;
1564 }
1565 static void* f_thread_ms_part1(NrnThread* nt) {
1566  int i = nt->id;
1567  Cvode* cv = f_cv_;
1568  nt->_vcv = cv;
1569  cv->fun_thread_ms_part1(f_t_, cv->n_vector_data(f_y_, i), nt);
1570  return 0;
1571 }
1572 static void* f_thread_ms_part2(NrnThread* nt) {
1573  int i = nt->id;
1574  Cvode* cv = f_cv_;
1575  cv->fun_thread_ms_part2(nt);
1576  return 0;
1577 }
1578 static void* f_thread_ms_part3(NrnThread* nt) {
1579  int i = nt->id;
1580  Cvode* cv = f_cv_;
1581  cv->fun_thread_ms_part3(nt);
1582  return 0;
1583 }
1584 static void* f_thread_ms_part4(NrnThread* nt) {
1585  int i = nt->id;
1586  Cvode* cv = f_cv_;
1587  cv->fun_thread_ms_part4(cv->n_vector_data(f_ydot_, i), nt);
1588  return 0;
1589 }
1590 static void* f_thread_ms_part34(NrnThread* nt) {
1591  int i = nt->id;
1592  Cvode* cv = f_cv_;
1593  cv->fun_thread_ms_part34(cv->n_vector_data(f_ydot_, i), nt);
1594  nt->_vcv = 0;
1595  return 0;
1596 }
static double tstop_event(void *v)
Definition: cvodeobj.cpp:423
int nrn_use_fast_imem
Definition: fadvance.cpp:162
o
Definition: seclist.cpp:180
void error_weights()
Definition: netcvode.cpp:4268
static void * f_thread_transfer_part2(NrnThread *)
Definition: cvodeobj.cpp:1558
int(* nrnpy_hoccommand_exec)(Object *)
Definition: objcmd.cpp:17
static double use_fast_imem(void *v)
Definition: cvodeobj.cpp:579
bool initialize_
Definition: cvodeobj.h:98
#define Printf
Definition: model.h:252
int nrn_use_selfqueue_
Definition: netcvode.cpp:92
FOR_THREADS(_nt)
Definition: multicore.cpp:887
void(* nrnthread_v_transfer_)(NrnThread *)
Definition: fadvance.cpp:148
void fun_thread_ms_part4(double *ydot, NrnThread *nt)
Definition: occvode.cpp:721
#define assert(ex)
Definition: hocassrt.h:26
int prior2init_
Definition: cvodeobj.h:226
static void * msetup_thread(NrnThread *)
int hoc_is_str_arg(int narg)
Definition: code.cpp:741
void alloc_daspk()
Definition: cvodeobj.cpp:1102
return true
Definition: savstate.cpp:357
void nrn_multithread_job(void *(*job)(NrnThread *))
Definition: multicore.cpp:1081
int solvex_thread_part3(double *b, NrnThread *nt)
Definition: occvode.cpp:599
static double n_remove(void *v)
Definition: cvodeobj.cpp:406
void re_init(double t0=0.)
Definition: netcvode.cpp:3968
int f_calls_
Definition: cvodeobj.h:103
void record_continuous()
Definition: occvode.cpp:991
#define prop
Definition: md1redef.h:29
void(* nrn_multisplit_setup_)()
Definition: treeset.cpp:46
double nrn_hoc2fun(void *v)
Definition: netcvode.cpp:4235
void atol(double)
Definition: netcvode.cpp:4455
void statistics(int)
Definition: netcvode.cpp:3880
float tolerance
Definition: hocdec.h:113
N_Vector acorvec()
Definition: cvodeobj.cpp:1358
void cvode_constructor()
Definition: cvodeobj.cpp:710
void set_CVRhsFn()
Definition: cvodeobj.cpp:1044
int solvex_thread_part1(double *b, NrnThread *nt)
Definition: occvode.cpp:575
int init()
Definition: nrndaspk.cpp:229
virtual ~Cvode()
Definition: cvodeobj.cpp:843
if(status)
N_Vector acorvec()
Definition: nrndaspk.cpp:679
static double extra_scatter_gather(void *v)
Definition: cvodeobj.cpp:549
static Object ** netconlist(void *v)
Definition: cvodeobj.cpp:492
static void * f_thread_ms_part4(NrnThread *)
Definition: cvodeobj.cpp:1584
short * nrn_is_artificial_
Definition: cell_group.cpp:18
void atolvec_alloc(int)
Definition: cvodeobj.cpp:834
void maxstep(double)
Definition: cvodeobj.cpp:1029
double * n_vector_data(N_Vector, int)
Definition: occvode.cpp:434
int use_long_double_
Definition: netcvode.h:213
CvodeThreadData * ctd_
Definition: cvodeobj.h:199
void minstep(double)
Definition: netcvode.cpp:4496
TQItem * tqitem_
Definition: cvodeobj.h:224
static void * msolve_thread_part3(NrnThread *)
Definition: cvodeobj.cpp:1482
static double states(void *v)
Definition: cvodeobj.cpp:274
#define MUTLOCK
Definition: nrnmutdec.h:32
int cvode_init(double)
Definition: cvodeobj.cpp:1058
void
double rtol_
Definition: netcvode.h:137
char * hoc_object_name(Object *ob)
Definition: hoc_oop.cpp:84
void * mem_
Definition: nrndaspk.h:25
static N_Vector msolve_b_
Definition: cvodeobj.cpp:1425
static double rtol(void *v)
Definition: cvodeobj.cpp:167
Represent main neuron object computed by single thread.
Definition: multicore.h:58
int nctd_
Definition: cvodeobj.h:201
static double use_long_double(void *v)
Definition: cvodeobj.cpp:369
int cvode_advance_tn()
Definition: cvodeobj.cpp:1276
void fun_thread_ms_part1(double t, double *y, NrnThread *nt)
Definition: occvode.cpp:692
#define STATE
Definition: membfunc.h:71
static double minstep(void *v)
Definition: cvodeobj.cpp:249
#define TRUE
Definition: err.c:57
virtual double t0()
Definition: cvodeobj.h:86
#define VINDEX
Definition: membfunc.h:61
static void * cons(Object *)
Definition: cvodeobj.cpp:646
int neq_
Definition: cvodeobj.h:204
int diam_changed
Definition: cabcode.cpp:23
check_obj_type(o, "SectionList")
static double dstates(void *v)
Definition: cvodeobj.cpp:280
char * name
Definition: model.h:72
#define MUTUNLOCK
Definition: nrnmutdec.h:33
void nrn_thread_error(const char *)
Definition: multicore.cpp:453
void free_cvodemem()
Definition: cvodeobj.cpp:1037
static void * f_thread_ms_part1(NrnThread *)
Definition: cvodeobj.cpp:1565
#define v
Definition: md1redef.h:4
void fun_thread_ms_part2(NrnThread *nt)
Definition: occvode.cpp:710
NetCvode * ncv_
Definition: cvodeobj.h:203
void vec_event_store()
Definition: netcvode.cpp:2566
char ** hoc_pgargstr(int narg)
Definition: code.cpp:1580
Object ** netconlist()
Definition: netcvode.cpp:947
static int abs(int)
Definition: math.cpp:43
int condition_order()
Definition: netcvode.h:129
static int init_failure_style_
Definition: nrndaspk.h:33
bool nrn_use_fifo_queue_
Definition: netcvode.cpp:248
static double dae_init_dteps(void *v)
Definition: cvodeobj.cpp:336
void init_prepare()
Definition: cvodeobj.cpp:879
void scatter_y(double *, int)
Definition: occvode.cpp:445
void fun_thread(double t, double *y, double *ydot, NrnThread *nt)
Definition: occvode.cpp:635
int daspk_advance_tn()
Definition: cvodeobj.cpp:1337
static double abstol(void *v)
Definition: cvodeobj.cpp:185
static double condition_order(void *v)
Definition: cvodeobj.cpp:380
#define e
Definition: passive0.cpp:24
#define gargstr
Definition: hocdec.h:14
int order()
Definition: cvodeobj.cpp:1002
void maxstate(double *)
Definition: cvodeobj.cpp:969
static double use_parallel(void *v)
Definition: cvodeobj.cpp:506
static double order(void *v)
Definition: cvodeobj.cpp:238
int diam_change_cnt
Definition: cvodeobj.cpp:76
void minstep(double)
Definition: cvodeobj.cpp:1018
double * hoc_pgetarg(int narg)
Definition: code.cpp:1604
void fun_thread_transfer_part1(double t, double *y, NrnThread *nt)
Definition: occvode.cpp:642
void matmeth()
Definition: cvodeobj.cpp:1388
static double statistics(void *v)
Definition: cvodeobj.cpp:115
static double dteps_
Definition: nrndaspk.h:34
static double re_init(void *v)
Definition: cvodeobj.cpp:158
void nrn_extra_scatter_gather(int direction, int tid)
Definition: cvodeobj.cpp:536
static double stiff(void *v)
Definition: cvodeobj.cpp:222
void fun_thread_ms_part3(NrnThread *nt)
Definition: occvode.cpp:717
double dt
Definition: init.cpp:123
void dstates()
Definition: netcvode.cpp:4196
int use_sparse13
Definition: treeset.cpp:69
virtual int init(double t)
Definition: cvodeobj.cpp:1174
int id
Definition: multicore.h:66
double _dt
Definition: multicore.h:60
void stiff(int)
Definition: netcvode.cpp:4458
virtual int advance_tn()
Definition: cvodeobj.cpp:1113
#define implementPtrList(PtrList, T)
static double queue_mode(void *v)
Definition: cvodeobj.cpp:129
bool use_daspk_
Definition: cvodeobj.h:168
void hoc_assign_str(char **cpp, const char *buf)
Definition: code.cpp:2337
int jac_calls_
Definition: cvodeobj.h:103
Symbol * hoc_get_last_pointer_symbol()
Definition: code.cpp:1761
void(* nrnmpi_v_transfer_)()
Definition: fadvance.cpp:147
N_Vector maxstate_
Definition: cvodeobj.h:191
void localstep(bool)
Definition: netcvode.cpp:1282
#define nt_t
Definition: cvodeobj.cpp:60
static Member_func members[]
Definition: cvodeobj.cpp:589
int nrn_vartype(Symbol *sym)
Definition: eion.cpp:488
void gather_y(N_Vector)
Definition: occvode.cpp:471
static Frame * fp
Definition: code.cpp:154
int nrn_nthread
Definition: multicore.cpp:44
static Cvode * f_cv_
Definition: cvodeobj.cpp:1497
int linmod_extra_eqn_count()
static Cvode * maxstate_cv
Definition: cvodeobj.cpp:930
static double use_mxb(void *v)
Definition: cvodeobj.cpp:346
static void * f_thread_ms_part3(NrnThread *)
Definition: cvodeobj.cpp:1578
int const size_t const size_t n
Definition: nrngsl.h:12
int hoc_return_type_code
Definition: code.cpp:41
#define SUCCESS
Definition: cvodeobj.cpp:95
int nrn_modeltype()
Definition: treeset.cpp:1934
int cvode_interpolate(double)
Definition: cvodeobj.cpp:1312
static CVRhsFn pf_
Definition: cvodeobj.cpp:687
static double ncs_netcons(void *v)
Definition: cvodeobj.cpp:497
int nrnmpi_numprocs
static N_Vector f_y_
Definition: cvodeobj.cpp:1495
NrnThread * nrn_threads
Definition: multicore.cpp:45
Definition: nrndaspk.h:11
void class2oc(const char *, void *(*cons)(Object *), void(*destruct)(void *), Member_func *, int(*checkpoint)(void **), Member_ret_obj_func *, Member_ret_str_func *)
Definition: hoc_oop.cpp:1581
void hoc_obj_unref(Object *obj)
Definition: hoc_oop.cpp:1998
int structure_change_cnt
Definition: cvodeobj.cpp:75
#define MUTDEC
Definition: nrnmutdec.h:28
int advance_tn(double tstop)
Definition: nrndaspk.cpp:329
void hoc_event(double, const char *hoc_stmt, Object *ppobj=nil, int reinit=0, Object *pyact=nil)
Definition: netcvode.cpp:2671
double t_
Definition: cvodeobj.h:97
#define nrn_nonvint_block_ode_reinit(size, y, tid)
Definition: nonvintblock.h:57
double next_at_time_
Definition: cvodeobj.h:206
void states()
Definition: netcvode.cpp:4167
static double n_record(void *v)
Definition: cvodeobj.cpp:400
int
Definition: nrnmusic.cpp:71
const char * secname(Section *sec)
Definition: cabcode.cpp:1787
void maxacor(double *)
Definition: cvodeobj.cpp:984
int use_cachevec
Definition: treeset.cpp:61
void hoc_warning(const char *, const char *)
int solvex_thread(double *b, double *y, NrnThread *nt)
Definition: occvode.cpp:534
N_Vector N_VNew_NrnSerialLD(long int length)
static void * f_thread(NrnThread *)
Definition: cvodeobj.cpp:1542
#define nt_dt
Definition: cvodeobj.cpp:59
static double acor(void *v)
Definition: cvodeobj.cpp:297
void activate_maxstate(bool)
Definition: cvodeobj.cpp:913
void structure_change()
Definition: netcvode.cpp:4521
N_Vector atolnvec_
Definition: cvodeobj.h:190
bool at_time(double, NrnThread *)
Definition: cvodeobj.cpp:757
static void * msolve_thread_part1(NrnThread *)
Definition: cvodeobj.cpp:1469
void vec_remove()
Definition: netcvode.cpp:6275
static bool le(double x, double y, double e)
Definition: mymath.h:79
void maxorder(int)
Definition: cvodeobj.cpp:1011
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:741
void jacobian(int)
Definition: netcvode.cpp:4518
double t0_
Definition: cvodeobj.h:97
static double use_daspk(void *v)
Definition: cvodeobj.cpp:324
int init_calls_
Definition: cvodeobj.h:102
#define tstopunset
Definition: section.h:329
static double peq(void *v)
Definition: cvodeobj.cpp:474
void nrn_fast_imem_alloc()
Definition: multicore.cpp:614
static double event_queue_info(void *v)
Definition: cvodeobj.cpp:480
void acor()
Definition: netcvode.cpp:4297
void use_daspk(bool)
Definition: netcvode.cpp:1301
MUTDEC int nlcv_
Definition: netcvode.h:55
static double error_weights(void *v)
Definition: cvodeobj.cpp:291
void cvode_finitialize()
bool can_retreat_
Definition: cvodeobj.h:99
Definition: model.h:57
int solve()
Definition: cvodeobj.cpp:1154
static bool maxstate_b
Definition: cvodeobj.cpp:929
static void mfree(CVodeMem cv_mem)
Definition: cvodeobj.cpp:1490
HocSymExtension * extra
Definition: hocdec.h:159
static double nrn_atol(void *v)
Definition: cvodeobj.cpp:174
#define nil
Definition: enter-scope.h:36
virtual double tn()
Definition: cvodeobj.h:85
static double nrn_diam_change_count(void *v)
Definition: cvodeobj.cpp:524
static void * msolve_thread(NrnThread *)
Definition: cvodeobj.cpp:1460
void hoc_obj_ref(Object *obj)
Definition: hoc_oop.cpp:1980
double gam()
Definition: cvodeobj.cpp:741
declarePtrList(ExtraScatterList, Object) implementPtrList(ExtraScatterList
NetCvodeThreadData * p
Definition: netcvode.h:211
void Cvode_reg()
Definition: cvodeobj.cpp:668
double state_magnitudes()
Definition: netcvode.cpp:6423
static bool eq(double x, double y, double e)
Definition: mymath.h:80
static double debug_event(void *v)
Definition: cvodeobj.cpp:390
int ifarg(int)
Definition: code.cpp:1562
static int msolve(CVodeMem cv_mem, N_Vector b, N_Vector weight, N_Vector ycur, N_Vector fcur)
Definition: cvodeobj.cpp:1428
static realtype f_t_
Definition: cvodeobj.cpp:1494
int interpolate_calls_
Definition: cvodeobj.h:102
static double current_method(void *v)
Definition: cvodeobj.cpp:458
int mxb_calls_
Definition: cvodeobj.h:103
double nrn_hoc2gather_y(void *v)
Definition: netcvode.cpp:4258
static double simgraph_remove(void *v)
Definition: cvodeobj.cpp:412
static void * f_thread_transfer_part1(NrnThread *)
Definition: cvodeobj.cpp:1551
static double nrn_structure_change_count(void *v)
Definition: cvodeobj.cpp:519
struct Symbol::@52::@53 rng
static void f_lvardt(realtype t, N_Vector y, N_Vector ydot, void *f_data)
Definition: cvodeobj.cpp:1533
#define MUTCONSTRUCT(mkmut)
Definition: nrnmutdec.h:30
static N_Vector msolve_ycur_
Definition: cvodeobj.cpp:1426
static double solve(void *v)
Definition: cvodeobj.cpp:99
static double spikestat(void *v)
Definition: cvodeobj.cpp:124
void do_nonode(NrnThread *nt=0)
Definition: occvode.cpp:889
Cvode * gcv_
Definition: netcvode.h:205
void nrn_cachevec(int)
Definition: treeset.cpp:2108
static Object ExtraScatterList * extra_scatterlist[2]
Definition: cvodeobj.cpp:534
double nrn_hoc2scatter_y(void *v)
Definition: netcvode.cpp:4248
Daspk * daspk_
Definition: cvodeobj.h:169
double _t
Definition: multicore.h:59
void * mem_
Definition: cvodeobj.h:188
double nrn_hoc2fixed_step(void *v)
Definition: netcvode.cpp:4230
const char * statename(int, int style=1)
Definition: netcvode.cpp:4326
static double statename(void *v)
Definition: cvodeobj.cpp:303
static double eps(double x)
Definition: netcvode.h:128
static int msolve_lvardt(CVodeMem cv_mem, N_Vector b, N_Vector weight, N_Vector ycur, N_Vector fcur)
Definition: cvodeobj.cpp:1449
N_Vector maxacor_
Definition: cvodeobj.h:192
void maxorder(int)
Definition: netcvode.cpp:4471
int advance_calls_
Definition: cvodeobj.h:102
static N_Vector f_ydot_
Definition: cvodeobj.cpp:1496
static void destruct(void *v)
Definition: cvodeobj.cpp:661
int print_event_
Definition: netcvode.h:145
double tstop_begin_
Definition: cvodeobj.h:208
void fun_thread_transfer_part2(double *ydot, NrnThread *nt)
Definition: occvode.cpp:662
int daspk_init(double)
Definition: cvodeobj.cpp:1098
Definition: hocdec.h:226
Definition: cvodeobj.h:75
Symbol * name2sym(const char *)
Definition: netcvode.cpp:4422
NrnThread * nth_
Definition: cvodeobj.h:200
#define getarg
Definition: hocdec.h:15
N_Vector N_VNew_NrnThreadLD(long int length, int nthread, long int *sizes)
void cvode_fadvance()
void * _vcv
Definition: multicore.h:83
Cvode()
Definition: cvodeobj.cpp:707
N_Vector y_
Definition: cvodeobj.h:189
virtual int interpolate(double t)
Definition: cvodeobj.cpp:1207
void fun_thread_ms_part34(double *ydot, NrnThread *nt)
Definition: occvode.cpp:713
Point_process * ob2pntproc(Object *)
Definition: hocmech.cpp:88
#define i
Definition: md1redef.h:12
void set_init_flag()
Definition: cvodeobj.cpp:790
#define MUTDESTRUCT
Definition: nrnmutdec.h:31
double tn_
Definition: cvodeobj.h:97
long int * nthsizes_
Definition: cvodeobj.h:202
void recalc_diam()
Definition: treeset.cpp:940
static void * maxstate_thread(NrnThread *nt)
Definition: cvodeobj.cpp:931
static double maxorder(void *v)
Definition: cvodeobj.cpp:230
static double state_magnitudes(void *v)
Definition: cvodeobj.cpp:418
bool nrn_use_bin_queue_
Definition: netcvode.cpp:251
void maxstep(double)
Definition: netcvode.cpp:4507
sec
Definition: solve.cpp:885
double h()
Definition: cvodeobj.cpp:749
floor
Definition: extdef.h:3
static void * f_thread_ms_part34(NrnThread *)
Definition: cvodeobj.cpp:1590
static void * msolve_thread_part2(NrnThread *)
Definition: cvodeobj.cpp:1476
fabs
Definition: extdef.h:3
void statistics()
Definition: cvodeobj.cpp:1366
N_Vector N_VNew_NrnParallelLD(MPI_Comm comm, long int local_length, long int global_length)
void stat_init()
Definition: cvodeobj.cpp:873
void hoc_symbol_tolerance(Symbol *, double)
Definition: code2.cpp:109
N_Vector ewtvec()
Definition: nrndaspk.cpp:675
int hoc_is_object_arg(int narg)
Definition: code.cpp:745
void print_event_queue()
Definition: netcvode.cpp:2997
static int msetup(CVodeMem cv_mem, int convfail, N_Vector ypred, N_Vector fpred, booleantype *jcurPtr, N_Vector vtemp, N_Vector vtemp2, N_Vector vtemp3)
Definition: cvodeobj.cpp:1415
void event_queue_info()
Definition: netcvode.cpp:3051
int order(int)
Definition: netcvode.cpp:4482
static double store_events(void *v)
Definition: cvodeobj.cpp:486
static int minit(CVodeMem cv_mem)
Definition: cvodeobj.cpp:1410
N_Vector nvnew(long)
Definition: cvodeobj.cpp:798
static Member_ret_obj_func omembers[]
Definition: cvodeobj.cpp:641
static double cache_efficient(void *v)
Definition: cvodeobj.cpp:359
bool init_global()
Definition: occvode.cpp:83
void simgraph_remove()
Definition: glinerec.cpp:251
union Symbol::@18 u
void rtol(double)
Definition: netcvode.cpp:4452
double t
Definition: init.cpp:123
static Cvode * msolve_cv_
Definition: cvodeobj.cpp:1427
static void static_mutex_for_at_time(bool b)
Definition: cvodeobj.cpp:35
void init_eqn()
Definition: occvode.cpp:109
int ts_inits_
Definition: cvodeobj.h:103
void alloc_cvode()
Definition: cvodeobj.cpp:999
void statistics()
Definition: nrndaspk.cpp:374
Object ** hoc_objgetarg(int)
Definition: code.cpp:1568
int(* nrnpy_pysame)(Object *, Object *)
Definition: cvodeobj.cpp:529
static int first_try_init_failures_
Definition: nrndaspk.h:36
bool structure_change_
Definition: cvodeobj.h:194
return NULL
Definition: cabcode.cpp:461
NetCvode * net_cvode_instance
Definition: cvodestb.cpp:27
double chkarg(int, double low, double high)
Definition: code2.cpp:608
int setup(N_Vector ypred, N_Vector fpred)
Definition: occvode.cpp:522
int solvex_thread_part2(NrnThread *nt)
Definition: occvode.cpp:595
double tstop_end_
Definition: cvodeobj.h:208
int cvode_active_
Definition: fadvance.cpp:158
static double extra_scatter_gather_remove(void *v)
Definition: cvodeobj.cpp:563
double tstop_
Definition: cvodeobj.h:207
static double active(void *v)
Definition: cvodeobj.cpp:211
static void * f_thread_ms_part2(NrnThread *)
Definition: cvodeobj.cpp:1572
static double jacobian(void *v)
Definition: cvodeobj.cpp:265
N_Vector ewtvec()
Definition: cvodeobj.cpp:1350
void vecrecord_add()
Definition: netcvode.cpp:6253
static double maxstep(void *v)
Definition: cvodeobj.cpp:257
int interpolate(double tout)
Definition: nrndaspk.cpp:355
int solve(double t)
Definition: netcvode.cpp:2040
static double use_local_dt(void *v)
Definition: cvodeobj.cpp:314
N_Vector N_VNew_NrnThread(long int length, int nthread, long int *sizes)
static void f_gvardt(realtype t, N_Vector y, N_Vector ydot, void *f_data)
Definition: cvodeobj.cpp:1498
void spike_stat()
Definition: netcvode.cpp:3910
int secondorder
Definition: init.cpp:120