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