NEURON
fadvance.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 
3 #include <nrnmpi.h>
4 #include <stdlib.h>
5 #include <errno.h>
6 #include "neuron.h"
7 #include "section.h"
8 #include "nrniv_mf.h"
9 #include "multisplit.h"
10 #define nrnoc_fadvance_c
12 #include "nonvintblock.h"
13 #include "nrncvode.h"
14 #include "spmatrix.h"
15 #include <vector>
16 
17 /*
18  after an fadvance from t-dt to t, v is defined at t
19  states that depend on v are defined at t+dt/2
20  states, such as concentration that depend on current are defined at t
21  and currents are defined at t-dt/2.
22  */
23 /*
24  fcurrent is used to set up all assigned variables without changing any
25  states. It assumes all states have their values at time t which is
26  only first order correct. It determines the nonvint assignments first
27  so that ena, etc. are correct for the current determinations. We
28  demand that nonvint assignments can be done without changing states when
29  dt is temporarily set to 0.
30 
31  It turned out to be a bad idea to do this. Many methods (KINETIC, PROCEDURE)
32  for solving are not even called when dt =0. Also it plays havoc with tables
33  that are recomputed several times when dt is changed then changed back.
34  Therefore we are no longer trying to initialize assigned variables within
35  SOLVE'd blocks. Instead we are making initialization more convenient,
36  at least within the normal situations, by introducing a finitialize()
37  with an optional argument vinit. finitialize will call the INITIALIZE block
38  for all mechanisms in all segments. (Default initialization sets all states
39  to state0.) The user can set things up specially in a models INITIAL
40  block. INITIAL blocks can make use of v. With care they can make use of
41  ionic concentrations just like breakpoint and solve blocks. When the argument
42  is present, v for all segments are set to that value.
43  */
44 
45 #if !defined(NRNMPI) || NRNMPI == 0
46 extern double nrnmpi_wtime();
47 #endif
48 extern double* nrn_mech_wtime_;
49 extern double t, dt;
50 extern double chkarg(int, double low, double high);
51 extern void nrn_fixed_step();
52 extern void nrn_fixed_step_group(int);
53 static void* nrn_fixed_step_thread(NrnThread*);
54 static void* nrn_fixed_step_group_thread(NrnThread* nth);
55 static void* nrn_fixed_step_lastpart(NrnThread*);
56 extern void* setup_tree_matrix(NrnThread*);
57 extern void nrn_solve(NrnThread*);
58 extern void nonvint(NrnThread* nt);
59 extern void nrncvode_set_t(double t);
60 
62 static void* nrn_ms_reduce_solve(NrnThread*);
63 static void* nrn_ms_bksub(NrnThread*);
65 extern void* nrn_multisplit_triang(NrnThread*);
67 extern void* nrn_multisplit_bksub(NrnThread*);
68 extern void (*nrn_multisplit_setup_)();
70 
71 extern int tree_changed;
72 extern int diam_changed;
73 extern int state_discon_allowed_;
74 extern double hoc_epsilon;
75 
76 static void update(NrnThread*);
77 
78 #if 0
79 /*
80  1 to save space, but must worry about other uses of the memb_list
81  such as in netcvode.cpp in fornetcon_prepare
82 */
83 extern short* nrn_is_artificial_;
85 #endif
86 
87 #define NRNCTIME 1
88 #define NONVINT_ODE_COUNT 5
89 
90 #if NRNCTIME
91 #define CTBEGIN double wt = nrnmpi_wtime();
92 #define CTADD nth->_ctime += nrnmpi_wtime() - wt;
93 #else
94 #define CTBEGIN /**/
95 #define CTADD /**/
96 #endif
97 
98 #define ELIMINATE_T_ROUNDOFF 0
99 #if ELIMINATE_T_ROUNDOFF
100 /* in order to simplify and as much as possible avoid the handling
101 of round-off error due to repeated t += dt, we use
102 t = nrn_tbase_ + nrn_ndt_ * nrn_dt_;
103 to advance time. The problems that must be overcome are when the
104 user changes dt in the middle of a run or switches from cvode or
105 abruptly and arbitrarily sets a new value of t and continues from
106 there (hence nrn_tbase_)
107 */
108 double nrn_ndt_, nrn_tbase_, nrn_dt_;
109 void nrn_chk_ndt() {
110  if (dt != nrn_dt_ || t != nrn_tbase_ + nrn_ndt_ * nrn_dt_) {
111 if (nrnmpi_myid == 0) Printf("nrn_chk_ndt t=%g dt=%g old nrn_tbase_=%g nrn_ndt_=%g nrn_dt_=%g\n",
112 t, dt, nrn_tbase_, nrn_ndt_, nrn_dt_);
113  nrn_dt_ = dt;
114  nrn_tbase_ = t;
115  nrn_ndt_ = 0.;
116  }
117 }
118 #endif /* ELIMINATE_T_ROUNDOFF */
119 
120 /*
121 There are (too) many variants of nrn_fixed_step depending on
122 nrnmpi_numprocs 1 or > 1, nrn_nthread 1 or > 1,
123 nrnmpi_v_transfer nil or callable, nrn_multisplit_setup nil or callable,
124 and whether one step with fadvance
125 or possibly many with ParallelContext.psolve before synchronizing with
126 NetParEvent. The combination of simultaneous nrnmpi_numprocs > 1 and
127 nrn_nthread > 1 with parallel transfer
128 requires some refactoring of the use of the old
129 (*nrnmpi_v_transfer_)() from within nonvint(nt) which handled either mpi
130 or threads but cannot handle both simultaneously. (Unless the first
131 thread that arrives in nrnmpi_v_transfer is the one that accomplishes
132 the mpi transfer). Instead, we replace with
133 nrnthread_v_transfer(nt) to handle the per thread copying of source
134 data into the target space owned by the thread. Between update (called by
135 nrn_fixed_step_thread and nrn_ms_bksub), and nonvint (called by
136 nrn_fixed_step_lastpart, we need to have thread 0 do the interprocessor
137 transfer of source voltages to a either a staging area for later
138 copying to the target by a thread (or directly to the target if only one
139 thread). This will happen with (*nrnmpi_v_transfer_)(). (Look Ma, no threads).
140 This deals properly with the necessary mpi synchronization. And leaves
141 thread handling where it was before. Also, writing to the staging area
142 is only done by thread 0. Fixed step and global variable step
143 logic is limited to the case where an nrnmpi_v_transfer requires
144 existence of nrnthread_v_transfer (even if one thread).
145 */
146 #if 1 || PARANEURON
147 void (*nrnmpi_v_transfer_)(); /* called by thread 0 */
149 /* if at least one gap junction has a source voltage with extracellular inserted */
151 #endif
152 
153 #if VECTORIZE
154 extern "C" int v_structure_change;
155 #endif
156 
157 #if CVODE
159 #endif
160 
163 
164 #define PROFILE 0
165 #include "profile.h"
166 
167 void fadvance(void) {
168  nrn::Instrumentor::phase p_fadvance("fadvance");
169  tstopunset;
170 #if CVODE
171  if (cvode_active_) {
172  cvode_fadvance(-1.);
173  tstopunset;
174  hoc_retpushx(1.);
175  return;
176  }
177 #endif
178  if (tree_changed) {
179  setup_topology();
180  }
181  if (v_structure_change) {
182  v_setup_vectors();
183  }
184  if (diam_changed) {
185  recalc_diam();
186  }
187  nrn_fixed_step();
188  tstopunset;
189  hoc_retpushx(1.);
190 }
191 
192 /*
193  batch_save() initializes list of variables
194  batch_save(&varname, ...) adds variable names to list for saving
195  batch_save("varname", ...) adds variable names to the list and name
196  will appear in header.
197  batch_run(tstop, tstep, "file") saves variables in file every tstep
198 */
199 
200 static void batch_out(), batch_open(), batch_close();
201 
202 static FILE* batch_file;
203 static int batch_size;
204 static int batch_n;
205 static double** batch_var;
206 
207 static void batch_open(char* name, double tstop, double tstep, char* comment){
208  if (batch_file) {
209  batch_close();
210  }
211  if (!name) {
212  return;
213  }
214  batch_file = fopen(name, "w");
215  if (!batch_file) {
216  hoc_execerror("Couldn't open batch file", name);
217  }
218  fprintf(batch_file, "%s\nbatch_run from t = %g to %g in steps of %g with dt = %g\n", comment, t, tstop, tstep, dt);
219  #if 0
220  fprintf(batch_file, "variable names --\n");
221  if (!batch_var) {
222  batch_var = hoc_newlist();
223  }
224  count = 0;
225  ITERATE(q, batch_varname) {
226  fprintf(batch_file, "%s\n", STR(q));
227  ++count;
228  }
229  if (count != batch_n) {
230  if (batch_var) {
231  free(batch_var);
232  }
233  batch_n = count;
234  batch_var = (double**)ecalloc(batch_n, sizeof(double*));
235  }
236  count = 0;
237  ITERATE(q, batch_varname) {
238  batch_var[count++] = hoc_val_pointer(STR(q));
239  }
240  #endif
241 }
242 
243 void batch_run(void) /* avoid interpreter overhead */
244 {
245  double tstop, tstep, tnext;
246  char* filename;
247  char* comment;
248 
249  tstopunset;
250  tstop = chkarg(1,0.,1e20);
251  tstep = chkarg(2, 0., 1e20);
252  if (ifarg(3)) {
253  filename = gargstr(3);
254  }else{
255  filename = 0;
256  }
257  if (ifarg(4)) {
258  comment = gargstr(4);
259  }else{
260  comment = "";
261  }
262 
263  if (tree_changed) {
264  setup_topology();
265  }
266 #if VECTORIZE
267  if (v_structure_change) {
268  v_setup_vectors();
269  }
270 #endif
271  batch_open(filename, tstop, tstep, comment);
272  batch_out();
273  if (cvode_active_) {
274  while (t < tstop) {
275  cvode_fadvance(t+tstep);
276  batch_out();
277  }
278  }else{
279  tstep -= dt/4.;
280  tstop -= dt/4.;
281  tnext = t + tstep;
282  while (t < tstop) {
283  nrn_fixed_step();
284  if (t > tnext) {
285  batch_out();
286  tnext = t + tstep;
287  }
288  if (stoprun) { tstopunset; break; }
289  }
290  }
291  batch_close();
292  hoc_retpushx(1.);
293 }
294 
295 static void dt2thread(double adt) {
296  if (adt != nrn_threads[0]._dt) {
297  int i;
298  for (i=0; i < nrn_nthread; ++i) {
299  NrnThread* nt = nrn_threads + i;
300  nt->_t = t;
301  nt->_dt = dt;
302  if (secondorder) {
303  nt->cj = 2.0/dt;
304  }else{
305  nt->cj = 1.0/dt;
306  }
307  }
308  }
309 }
310 
311 static int _upd;
313  setup_tree_matrix(nt);
314  nrn_solve(nt);
315  if (_upd) {
316  update(nt);
317  }
318  return nullptr;
319 }
320 
321 void nrn_daspk_init_step(double tt, double dteps, int upd){
322  int i;
323  double dtsav = nrn_threads->_dt;
324  int so = secondorder;
325  dt = dteps;
326  t = tt;
327  secondorder = 0;
328  dt2thread(dteps);
330  _upd = upd;
332  dt = dtsav;
333  secondorder = so;
334  dt2thread(dtsav);
336 }
337 
339  nrn::Instrumentor::phase p_timestep("timestep");
340  int i;
341 #if ELIMINATE_T_ROUNDOFF
342  nrn_chk_ndt();
343 #endif
344  if (t != nrn_threads->_t) {
345  dt2thread(-1.);
346  }else{
347  dt2thread(dt);
348  }
350  if (nrn_multisplit_setup_) {
352  // remove to avoid possible deadlock where some ranks do a
353  // v transfer and others do a spike exchange.
354  // i.e. must complete the full multisplit time step.
355  //if (!nrn_allthread_handle) {
358  /* see comment below */
359  if (nrnthread_v_transfer_) {
360  if (nrnmpi_v_transfer_) {
361  nrn::Instrumentor::phase p_gap("gap-v-transfer");
362  (*nrnmpi_v_transfer_)();
363  }
365  }
366  //}
367  }else{
369 /* if there is no nrnthread_v_transfer then there cannot be
370  a nrnmpi_v_transfer and lastpart
371  will be done in above call.
372 */
373  if (nrnthread_v_transfer_) {
374  if (nrnmpi_v_transfer_) {
375  nrn::Instrumentor::phase p_gap("gap-v-transfer");
376  (*nrnmpi_v_transfer_)();
377  }
379  }
380  }
381  t = nrn_threads[0]._t;
382  if (nrn_allthread_handle) { (*nrn_allthread_handle)(); }
383 }
384 
385 /* better cache efficiency since a thread can do an entire minimum delay
386 integration interval before joining
387 */
388 static int step_group_n;
389 static int step_group_begin;
390 static int step_group_end;
391 
393  int i;
394 #if ELIMINATE_T_ROUNDOFF
395  nrn_chk_ndt();
396 #endif
397  dt2thread(dt);
399  if (nrn_multisplit_setup_) {
400  int b = 0;
402  step_group_n = 0; /* abort at bksub flag */
403  for (i=1; i < n; ++i) {
406  if (step_group_n) {
407  step_group_n = 0;
408  if (nrn_allthread_handle) {
409  (*nrn_allthread_handle)();
410  }
411  /* aborted step at bksub, so if not stopped
412  must do the triang*/
413  b = 1;
414  if (!stoprun) {
416  }
417  }
418  if (stoprun) { break; }
419  b = 0;
420  }
421  if (!b) {
424  }
425  if (nrn_allthread_handle) { (*nrn_allthread_handle)(); }
426  }else{
427  step_group_n = n;
428  step_group_begin = 0;
429  step_group_end = 0;
430  while(step_group_end < step_group_n) {
431 /*printf("step_group_end=%d step_group_n=%d\n", step_group_end, step_group_n);*/
433  if (nrn_allthread_handle) { (*nrn_allthread_handle)(); }
434  if (stoprun) { break; }
436  }
437  }
438  t = nrn_threads[0]._t;
439 }
440 
442  int i;
443  nth->_stop_stepping = 0;
444  for (i = step_group_begin; i < step_group_n; ++i) {
445  nrn::Instrumentor::phase p_timestep("timestep");
447  if (nth->_stop_stepping) {
448  if (nth->id == 0) { step_group_end = i + 1; }
449  nth->_stop_stepping = 0;
450  return nullptr;
451  }
452  }
453  if (nth->id == 0) { step_group_end = step_group_n; }
454  return nullptr;
455 }
456 
458  double wt;
459  {
460  nrn::Instrumentor::phase p("deliver-events");
461  deliver_net_events(nth);
462  }
463 
464  wt = nrnmpi_wtime();
465  nrn_random_play();
466 #if ELIMINATE_T_ROUNDOFF
467  nth->nrn_ndt_ += .5;
468  nth->_t = nrn_tbase_ + nth->nrn_ndt_ * nrn_dt_;
469 #else
470  nth->_t += .5 * nth->_dt;
471 #endif
473  setup_tree_matrix(nth);
474  {
475  nrn::Instrumentor::phase p("matrix-solver");
476  nrn_solve(nth);
477  }
478  {
479  nrn::Instrumentor::phase p("second-order-cur");
480  second_order_cur(nth);
481  }
482  {
483  nrn::Instrumentor::phase p("update");
484  update(nth);
485  }
486  CTADD
487 /*
488  To simplify the logic,
489  if there is no nrnthread_v_transfer then there cannot be an nrnmpi_v_transfer.
490 */
491  if (!nrnthread_v_transfer_) {
493  }
494  return nullptr;
495 }
496 
497 extern void nrn_extra_scatter_gather(int direction, int tid);
498 extern void nrn_ba(NrnThread*, int);
499 
501  CTBEGIN
502 #if ELIMINATE_T_ROUNDOFF
503  nth->nrn_ndt_ += .5;
504  nth->_t = nrn_tbase_ + nth->nrn_ndt_ * nrn_dt_;
505 #else
506  nth->_t += .5 * nth->_dt;
507 #endif
509  nrn_extra_scatter_gather(0, nth->id);
510  nonvint(nth);
511  nrn_ba(nth, AFTER_SOLVE);
513  CTADD
514  {
515  nrn::Instrumentor::phase p("deliver-events");
516  nrn_deliver_events(nth); /* up to but not past texit */
517  }
518  return nullptr;
519 }
520 
521 /* nrn_fixed_step_thread is split into three pieces */
522 
524  double wt;
525  deliver_net_events(nth);
526  wt = nrnmpi_wtime();
527  nrn_random_play();
528 #if ELIMINATE_T_ROUNDOFF
529  nth->nrn_ndt_ += .5;
530  nth->_t = nrn_tbase_ + nth->nrn_ndt_ * nrn_dt_;
531 #else
532  nth->_t += .5 * nth->_dt;
533 #endif
535  setup_tree_matrix(nth);
537  CTADD
538  return nullptr;
539 }
542  return nullptr;
543 }
544 void* nrn_ms_bksub(NrnThread* nth) {
545  CTBEGIN
547  second_order_cur(nth);
548  update(nth);
549  CTADD
550 /* see above comment in nrn_fixed_step_thread */
551  if (!nrnthread_v_transfer_) {
553  }
554  return nullptr;
555 }
557  nrn_ms_bksub(nth);
558  if (nth->_stop_stepping) {
559  nth->_stop_stepping = 0;
560  if (nth == nrn_threads) {
561  step_group_n = 1;
562  }
563  return nullptr;
564  }
566  return nullptr;
567 }
568 
569 
570 static void update(NrnThread* _nt)
571 {
572  int i, i1, i2;
573  i1 = 0;
574  i2 = _nt->end;
575 #if CACHEVEC
576  if (use_cachevec) {
577  /* do not need to worry about linmod or extracellular*/
578  if (secondorder) {
579  for (i=i1; i < i2; ++i) {
580  VEC_V(i) += 2.*VEC_RHS(i);
581  }
582  }else{
583  for (i=i1; i < i2; ++i) {
584  VEC_V(i) += VEC_RHS(i);
585  }
586  }
587  }else
588 #endif
589  { /* use original non-vectorized update */
590  if (secondorder) {
591 #if _CRAY
592 #pragma _CRI ivdep
593 #endif
594  for (i=i1; i < i2; ++i) {
595  NODEV(_nt->_v_node[i]) += 2.*NODERHS(_nt->_v_node[i]);
596  }
597  }else{
598 #if _CRAY
599 #pragma _CRI ivdep
600 #endif
601  for (i=i1; i < i2; ++i) {
602  NODEV(_nt->_v_node[i]) += NODERHS(_nt->_v_node[i]);
603  }
604  if (use_sparse13) {
605  nrndae_update();
606  }
607  }
608  } /* end of non-vectorized update */
609 
610 #if EXTRACELLULAR
611  nrn_update_2d(_nt);
612 #endif
613  if (nrnthread_vi_compute_) { (*nrnthread_vi_compute_)(_nt); }
614 #if I_MEMBRANE
615  if (_nt->tml) {
616  assert(_nt->tml->index == CAP);
617  nrn_capacity_current(_nt, _nt->tml->ml);
618  }
619 #endif
621 }
622 
624  int i;
625  int i1 = 0;
626  int i3 = _nt->end;
627  double* pd = _nt->_nrn_fast_imem->_nrn_sav_d;
628  double* prhs = _nt->_nrn_fast_imem->_nrn_sav_rhs;
629  if (use_cachevec) {
630  for (i = i1; i < i3 ; ++i) {
631  prhs[i] = (pd[i]*VEC_RHS(i) + prhs[i])*VEC_AREA(i)*0.01;
632  }
633  }else{
634  for (i = i1; i < i3 ; ++i) {
635  Node* nd = _nt->_v_node[i];
636  prhs[i] = (pd[i]*NODERHS(nd) + prhs[i])*NODEAREA(nd)*0.01;
637  }
638  }
639 }
640 
642  // nrn_rhs() is called near end of nrn_finitialize() via setup_tree_matrix()
643  // and nrn_rhs() sets up _nrn_sav_rhs as -total ionic_current (without
644  // ELECTRODE_CURRENT contributions) and RHS as axial + ionic + stim currents
645  // So sum, scaled by area, is i_membrane_ in nA.
646  // (Note: capacitance does not appear on rhs because delta_v is the
647  // variable in the current balance equations set up by setup_tree_matrix.)
648  // Warning: Have not thought deeply about extracellular or LinearMechanism.
649  // But there is a good chance things are ok. But needs testing.
650  // I don't believe this is used by Cvode or IDA.
651  int i;
652  int i1 = 0;
653  int i3 = _nt->end;
654  double* prhs = _nt->_nrn_fast_imem->_nrn_sav_rhs;
655  if (use_cachevec) {
656  for (i = i1; i < i3 ; ++i) {
657  prhs[i] = (VEC_RHS(i) + prhs[i])*VEC_AREA(i)*0.01;
658  }
659  }else{
660  for (i = i1; i < i3 ; ++i) {
661  Node* nd = _nt->_v_node[i];
662  prhs[i] = (NODERHS(nd) + prhs[i])*NODEAREA(nd)*0.01;
663  }
664  }
665 }
666 
667 void fcurrent(void)
668 {
669  int i;
670  if (tree_changed) {
671  setup_topology();
672  }
673  if (v_structure_change) {
674  v_setup_vectors();
675  }
676  if (diam_changed) {
677  recalc_diam();
678  }
679 
680  dt2thread(-1.);
685  hoc_retpushx(1.);
686 }
687 
689  extern int section_count;
690  extern Section** secorder;
691  int isec, inode;
692  Section* sec;
693  Node* nd;
694  if (use_sparse13) {
695  if(ifarg(1) && chkarg(1, 0., 1.) == 0.) {
696  spPrint(_nt->_sp13mat, 1, 0, 1);
697  }else{
698  int i, n = spGetSize(_nt->_sp13mat, 0);
699  spPrint(_nt->_sp13mat, 1, 1, 1);
700  for (i=1; i <= n; ++i) {
701  Printf("%d %g\n", i, _nt->_actual_rhs[i]);
702  }
703  }
704  }else if (_nt) {
705  for (inode = 0; inode < _nt->end; ++inode) {
706  nd = _nt->_v_node[inode];
707 Printf("%d %g %g %g %g\n", inode, ClassicalNODEB(nd), ClassicalNODEA(nd), NODED(nd), NODERHS(nd));
708  }
709  }else{
710  for (isec = 0; isec < section_count; ++isec) {
711  sec = secorder[isec];
712  for (inode = 0; inode < sec->nnode; ++inode) {
713  nd = sec->pnode[inode];
714 Printf("%d %d %g %g %g %g\n", isec, inode, ClassicalNODEB(nd), ClassicalNODEA(nd), NODED(nd), NODERHS(nd));
715  }
716  }
717  }
718 }
719 
720 void fmatrix(void) {
721  if (ifarg(1)) {
722  double x;
723  Section* sec;
724  int id;
725  Node* nd;
726  NrnThread* _nt;
727  nrn_seg_or_x_arg(1, &sec, &x);
728  id = (int)chkarg(2, 1., 4.);
729  nd = node_exact(sec, x);
730  _nt = nd->_nt;
731  switch (id) {
732  case 1: hoc_retpushx(NODEA(nd)); break;
733  case 2: hoc_retpushx(NODED(nd)); break;
734  case 3: hoc_retpushx(NODEB(nd)); break;
735  case 4: hoc_retpushx(NODERHS(nd)); break;
736  }
737  return;
738  }
740  hoc_retpushx(1.);
741  return;
742 }
743 
744 void nonvint(NrnThread* _nt)
745 {
746 #if VECTORIZE
747  int i=0;
748  double w;
749  int measure = 0;
750  NrnThreadMembList* tml;
751 #if 1 || PARANEURON
752  /* nrnmpi_v_transfer if needed was done earlier */
753  if (nrnthread_v_transfer_) {
754  nrn::Instrumentor::phase p_gap("gap-v-transfer");
755  (*nrnthread_v_transfer_)(_nt);
756  }
757 #endif
758  nrn::Instrumentor::phase_begin("state-update");
759  if (_nt->id == 0 && nrn_mech_wtime_) { measure = 1; }
760  errno = 0;
761  for (tml = _nt->tml; tml; tml = tml->next) if (memb_func[tml->index].state) {
762  std::string mechname("state-");
763  mechname += memb_func[tml->index].sym->name;
764  nrn::Instrumentor::phase_begin(mechname.c_str());
765  Pvmi s = memb_func[tml->index].state;
766  nrn::Instrumentor::phase_end(mechname.c_str());
767  if (measure) {
768  w = nrnmpi_wtime(); }
769  (*s)(_nt, tml->ml, tml->index);
770  if (measure) { nrn_mech_wtime_[tml->index] += nrnmpi_wtime() - w; }
771  if (errno) {
772  if (nrn_errno_check(i)) {
773 hoc_warning("errno set during calculation of states", (char*)0);
774  }
775  }
776  }
777  long_difus_solve(0, _nt); /* if any longitudinal diffusion */
779  nrn::Instrumentor::phase_end("state-update");
780 #endif
781 }
782 
783 #if VECTORIZE
785 {
786  int ierr;
787  ierr = hoc_errno_check();
788  if (ierr) {
789  fprintf(stderr,
790 "%d errno=%d at t=%g during call to mechanism %s\n", nrnmpi_myid, ierr, t, memb_func[i].sym->name);
791  }
792  return ierr;
793 }
794 #else
795 int nrn_errno_check(Prop* p, int inode, Section* sec)
796 {
797  int ierr;
798  char* secname();
799  ierr = hoc_errno_check();
800  if (ierr) {
801  fprintf(stderr,
802 "%d errno set at t=%g during call to mechanism %s at node %d in section %s\n",
803 nrnmpi_myid, t, memb_func[p->type].sym->name, inode, secname(sec));
804  }
805  return ierr;
806 }
807 #endif
808 
809 void frecord_init(void) { /* useful when changing states after an finitialize() */
810  int i;
811  dt2thread(-1);
812  nrn_record_init();
813  if (!cvode_active_) {
814  for (i=0; i < nrn_nthread; ++i) {
816  }
817  }
818  hoc_retpushx(1.);
819 }
820 
821 void verify_structure(void) {
822  if (tree_changed) {
823  setup_topology();
824  }
825  if (v_structure_change) {
826  v_setup_vectors();
827  }
828  if (diam_changed) {
829  recalc_diam();
830  }
831  nrn_solver_prepare(); /* cvode ready to be used */
832 }
833 
834 void nrn_finitialize(int setv, double v) {
835  int iord, i;
836  NrnThread *_nt;
837  extern int _ninits;
838  extern short *nrn_is_artificial_;
839  ++_ninits;
840 
841  nrn::Instrumentor::phase_begin("finitialize");
842  nrn_fihexec(3); /* model structure changes can be made */
844 #if ELIMINATE_T_ROUNDOFF
845  nrn_ndt_ = 0.; nrn_dt_ = dt; nrn_tbase_ = 0.;
846 #else
847  t = 0.;
848  dt2thread(-1.);
849 #endif
850  if (cvode_active_) {
851  nrncvode_set_t(t);
852  }
856  nrn_random_play();
857 #if VECTORIZE
858  nrn_play_init(); /* Vector.play */
859  for (i = 0; i < nrn_nthread; ++i) {
860  nrn_deliver_events(nrn_threads + i); /* The play events at t=0 */
861  }
862  if (setv) {
863 #if _CRAY
864 #pragma _CRI ivdep
865 #endif
866  FOR_THREADS(_nt)
867  for (i = 0; i < _nt->end; ++i) {
868  NODEV(_nt->_v_node[i]) = v;
869  }
870  }
871 #if 1 || PARANEURON
873  {
874  (*nrnthread_vi_compute_)(_nt);
875  }
876  {
877  nrn::Instrumentor::phase p_gap("gap-v-transfer");
878  if (nrnmpi_v_transfer_) {
879  (nrnmpi_v_transfer_)();
880  }
882  FOR_THREADS(_nt) {
883  (*nrnthread_v_transfer_)(_nt);
884  }
885  }
886 #endif
887  nrn_fihexec(0); /* after v is set but before INITIAL blocks are called*/
888  for (i = 0; i < nrn_nthread; ++i) {
890  }
891 #if _CRAY
892  cray_node_init();
893 #endif
894  /* the INITIAL blocks are ordered so that mechanisms that write
895  concentrations are after ions and before mechanisms that read
896  concentrations.
897  */
898  /* the memblist list in NrnThread is already so ordered */
899 #if MULTICORE
900  for (i = 0; i < nrn_nthread; ++i) {
901  NrnThread *nt = nrn_threads + i;
903  NrnThreadMembList *tml;
904  for (tml = nt->tml; tml; tml = tml->next) {
905  Pvmi s = memb_func[tml->index].initialize;
906  if (s) {
907  (*s)(nt, tml->ml, tml->index);
908  }
909  }
910  }
911 #endif
912  for (iord = 0; iord < n_memb_func; ++iord) {
913  i = memb_order_[iord];
914  /* first clause due to MULTICORE */
915  if (nrn_is_artificial_[i])
916  if (memb_func[i].initialize) {
918 #if 0
919  if (nrn_is_artificial_[i]) {
920  /*
921  I hope the space saving of the memb_list arrays is worth
922  doing this specifically. And if art cells are needed
923  in the memb_list anywhere else we will have do do something
924  similar to this. This gives up vectorization but this is only
925  initialization and all the other use of artcell should be
926  event driven.
927  */
928  Prop* p;
929  hoc_Item* q;
930  hoc_List* list = nrn_pnt_template_[i]->olist;
931  ITERATE(q, list) {
932  Object* obj = OBJ(q);
933  Prop* p = ((Point_process*)obj->u.this_pointer)->prop;
934  (*s)((Node*)0, p->param, p->dparam);
935  }
936  }else if (memb_list[i].nodecount){
937 #else
938  if (memb_list[i].nodecount) {
939 #endif
940  (*s)(nrn_threads, memb_list + i, i);
941  }
942  if (errno) {
943  if (nrn_errno_check(i)) {
944  hoc_warning("errno set during call to INITIAL block", (char *) 0);
945  }
946  }
947  }
948  }
949 #endif
950  if (use_sparse13) {
951  nrndae_init();
952  }
953 
954  init_net_events();
955  for (i = 0; i < nrn_nthread; ++i) {
957  }
958  nrn_fihexec(1); /* after INITIAL blocks, before fcurrent*/
959 
960  for (i = 0; i < nrn_nthread; ++i) {
961  nrn_deliver_events(nrn_threads + i); /* The INITIAL sent events at t=0 */
962  }
963  if (cvode_active_) {
965  nrn_record_init();
966  } else {
968  for (i = 0; i < nrn_nthread; ++i) {
970  if (nrn_use_fast_imem) {
972  }
973  }
975  nrn_record_init();
976  for (i = 0; i < nrn_nthread; ++i) {
978  }
979  }
980  for (i = 0; i < nrn_nthread; ++i) {
981  nrn_deliver_events(nrn_threads + i); /* The record events at t=0 */
982  }
983 #if NRNMPI
985 #endif
986  if (nrn_allthread_handle) { (*nrn_allthread_handle)(); }
987 
988  nrn_fihexec(2); /* just before return */
989  nrn::Instrumentor::phase_end("finitialize");
990 }
991 
992 void finitialize(void) {
993  int setv;
994  double v = 0.0;
995  setv = 0;
996  if (ifarg(1)) {
997  v = *getarg(1);
998  setv = 1;
999  }
1000  tstopunset;
1001  nrn_finitialize(setv, v);
1002  tstopunset;
1003  hoc_retpushx(1.);
1004 }
1005 
1006 
1007 static void batch_close() {
1008  if (batch_file) {
1009  fclose(batch_file);
1010  batch_file = 0;
1011  }
1012 }
1013 
1014 static void batch_out() {
1015  if (batch_file) {
1016  int i;
1017  for (i = 0; i < batch_n; ++i) {
1018  fprintf(batch_file, " %g", *batch_var[i]);
1019  }
1020  fprintf(batch_file, "\n");
1021  }
1022 }
1023 
1024 void batch_save(void) {
1025  int i;
1026  if (!ifarg(1)) {
1027  batch_n = 0;
1028  } else {
1029  for (i = 1; ifarg(i); ++i) {
1030  if (batch_size <= batch_n) {
1031  batch_size += 20;
1032  batch_var = (double **) erealloc(batch_var, batch_size * sizeof(double *));
1033  }
1035  ++batch_n;
1036  }
1037  }
1038  hoc_retpushx(1.);
1039 }
1040 
1041 void nrn_ba(NrnThread *nt, int bat) {
1042  NrnThreadBAList *tbl;
1043  int i;
1044  for (tbl = nt->tbl[bat]; tbl; tbl = tbl->next) {
1045  nrn_bamech_t f = tbl->bam->f;
1046  int type = tbl->bam->type;
1047  Memb_list *ml = tbl->ml;
1048  for (i = 0; i < ml->nodecount; ++i) {
1049  (*f)(ml->nodelist[i], ml->data[i], ml->pdata[i], ml->_thread, nt);
1050  }
1051  }
1052 }
1053 
1054 typedef int (*NonVintBlockItem)(int method, int size, double *pd1, double *pd2, int tid);
1055 /* list to store the nrn_nonvint_block functions */
1056 static std::vector<NonVintBlockItem> nonvint_block_list;
1057 
1058 int nrn_nonvint_block_exe(int method, int size, double *pd1, double *pd2, int tid) {
1059  /* execute all functions in nonvint_block_list and return the sum of the
1060  * return values
1061  */
1062  int rval, sum = 0;
1063 
1064  for (auto& func: nonvint_block_list) {
1065  rval = (*func)(method, size, pd1, pd2, tid);
1066  if (rval == -1) {
1067  hoc_execerror("nrn_nonvint_block error", 0);
1068  } else {
1069  sum += rval;
1070  }
1071  if (method == NONVINT_ODE_COUNT) {
1072  size += rval;
1073  }
1074  }
1075 
1076  return sum;
1077 }
1078 
1080 
1081  /* store new_nrn_nonvint_block functions in a list */
1082  nonvint_block_list.push_back(func);
1083 
1084  /* could this be set directly in nrn_nonvint_block_helper? */
1086 
1087  return 0;
1088 }
1089 
1091  // remove new_nrn_nonvint_block functions from the list
1092  // in c++-20 one could say std::erase(nonvint_block_list, func);
1093  auto n = nonvint_block_list.size();
1094  for (size_t i = 0; i < n; ++i) {
1095  if (func == nonvint_block_list[i]) {
1096  nonvint_block_list.erase(nonvint_block_list.begin() + i);
1097  break;
1098  }
1099  }
1100  if (nonvint_block_list.empty()) {
1102  }
1103  return 0;
1104 }
1105 
1106 int nrn_nonvint_block_helper(int method, int size, double *pd1, double *pd2, int tid) {
1108  int rval = (*nrn_nonvint_block)(method, size, pd1, pd2, tid);
1109  if (rval == -1) {
1110  hoc_execerror("nrn_nonvint_block error", 0);
1111  }
1112  return rval;
1113 }
1114 
1115 /*
1116  Derived from scopmath/euler.cpp. Here because scopmath does not know
1117  about NrnThread
1118 */
1119 #include "nrniv_mf.h"
1120 
1121 #undef SUCCESS
1122 #define SUCCESS 0
1123 #define der_(arg) p[der[arg]]
1124 #define var_(arg) p[var[arg]]
1125 
1126 /* ARGSUSED */
1127 extern "C" int euler_thread(int neqn, int *var, int *der, double *p,
1128  int (*func)(double *, Datum *, Datum *, NrnThread *),
1129  Datum *ppvar, Datum *thread, NrnThread *nt) {
1130  int i;
1131  double dt = nt->_dt;
1132 
1133  /* Calculate the derivatives */
1134 
1135  (*func)(p, ppvar, thread, nt);
1136 
1137  /* Update dependent variables --- note defines in euler above*/
1138 
1139  for (i = 0; i < neqn; i++)
1140  var_(i) += dt * (der_(i));
1141 
1142  return (SUCCESS);
1143 }
1144 
void nrn_solve(NrnThread *)
Definition: solve.cpp:328
int nrn_use_fast_imem
Definition: fadvance.cpp:162
void(* nrn_allthread_handle)()
Definition: fadvance.cpp:69
void clear_event_queue()
Definition: cvodestb.cpp:57
#define Printf
Definition: model.h:252
FOR_THREADS(_nt)
Definition: multicore.cpp:887
static std::vector< NonVintBlockItem > nonvint_block_list
Definition: fadvance.cpp:1056
static int step_group_end
Definition: fadvance.cpp:390
void * ecalloc(size_t n, size_t size)
Definition: symbol.cpp:221
double * param
Definition: section.h:218
int _stop_stepping
Definition: multicore.h:67
#define assert(ex)
Definition: hocassrt.h:26
static void batch_out()
Definition: fadvance.cpp:1014
void long_difus_solve(int, NrnThread *)
Definition: ldifus.cpp:98
short type
Definition: cabvars.h:10
short nnode
Definition: section.h:41
int euler_thread(int neqn, int *var, int *der, double *p, int(*func)(double *, Datum *, Datum *, NrnThread *), Datum *ppvar, Datum *thread, NrnThread *nt)
Definition: fadvance.cpp:1127
void nrn_capacity_current(NrnThread *_nt, Memb_list *ml)
Definition: capac.cpp:62
void nrn_multithread_job(void *(*job)(NrnThread *))
Definition: multicore.cpp:1081
void nrn_fixed_step_group(int)
Definition: fadvance.cpp:392
void * erealloc(void *ptr, size_t n)
Definition: symbol.cpp:267
void(* nrn_multisplit_setup_)()
Definition: treeset.cpp:46
Memb_list * ml
Definition: multicore.h:40
ClassicalNODEB(nd)
#define NODEV(n)
Definition: section.h:114
struct NrnThreadMembList * next
Definition: multicore.h:34
int v_structure_change
Definition: fadvance.cpp:154
short * nrn_is_artificial_
Definition: cell_group.cpp:18
#define NODED(n)
Definition: section.h:103
double * _nrn_sav_d
Definition: multicore.h:47
#define CTBEGIN
Definition: fadvance.cpp:91
void nrn_extra_scatter_gather(int direction, int tid)
Definition: cvodeobj.cpp:536
void nrn_daspk_init_step(double tt, double dteps, int upd)
Definition: fadvance.cpp:321
void fmatrix(void)
Definition: fadvance.cpp:720
void nrn_thread_table_check()
Definition: multicore.cpp:1050
#define ITERATE(itm, lst)
Definition: model.h:25
int set_nonvint_block(NonVintBlockItem func)
Definition: fadvance.cpp:1079
int nrn_nonvint_block_exe(int method, int size, double *pd1, double *pd2, int tid)
Definition: fadvance.cpp:1058
void batch_save(void)
Definition: fadvance.cpp:1024
void
int diam_changed
Definition: cabcode.cpp:23
void * this_pointer
Definition: hocdec.h:231
size_t p
Represent main neuron object computed by single thread.
Definition: multicore.h:58
double * _actual_rhs
Definition: multicore.h:70
void setup_topology()
NrnThreadBAList * tbl[BEFORE_AFTER_SIZE]
Definition: multicore.h:89
double chkarg(int, double low, double high)
Definition: code2.cpp:608
static void update(NrnThread *)
Definition: fadvance.cpp:570
void batch_run(void)
Definition: fadvance.cpp:243
char * name
Definition: model.h:72
static int step_group_n
Definition: fadvance.cpp:388
static void dt2thread(double adt)
Definition: fadvance.cpp:295
Memb_func * memb_func
Definition: init.cpp:161
nd
Definition: treeset.cpp:893
double hoc_epsilon
Definition: hoc_init.cpp:260
void nrn_print_matrix(NrnThread *_nt)
Definition: fadvance.cpp:688
#define v
Definition: md1redef.h:4
double ** data
Definition: nrnoc_ml.h:14
void verify_structure(void)
Definition: fadvance.cpp:821
void nrn_ba(NrnThread *, int)
Definition: fadvance.cpp:1041
void(* nrnthread_vi_compute_)(NrnThread *nt)
Definition: fadvance.cpp:150
#define AFTER_INITIAL
Definition: membfunc.h:74
void nrn_spike_exchange_init()
Definition: netpar.cpp:441
double nrnmpi_wtime()
Definition: nrnmpi.cpp:171
static void * nrn_ms_bksub_through_triang(NrnThread *)
Definition: fadvance.cpp:556
#define AFTER_SOLVE
Definition: membfunc.h:76
inode
Definition: multicore.cpp:985
int type
Definition: membfunc.h:81
void * nrn_multisplit_reduce_solve(NrnThread *)
void fadvance(void)
Definition: fadvance.cpp:167
hoc_List * olist
Definition: hocdec.h:203
_nrn_Fast_Imem * _nrn_fast_imem
Definition: multicore.h:82
Datum * _thread
Definition: nrnoc_ml.h:17
#define gargstr
Definition: hocdec.h:14
#define der_(arg)
Definition: fadvance.cpp:1123
int nrn_errno_check(int i)
Definition: fadvance.cpp:784
double * hoc_pgetarg(int narg)
Definition: code.cpp:1604
short type
Definition: section.h:215
static int step_group_begin
Definition: fadvance.cpp:389
int use_sparse13
Definition: treeset.cpp:69
int id
Definition: multicore.h:66
static int batch_n
Definition: fadvance.cpp:204
#define NONVINT_ODE_COUNT
Definition: fadvance.cpp:88
double _dt
Definition: multicore.h:60
double dt
Definition: init.cpp:123
void fcurrent(void)
Definition: fadvance.cpp:667
Symbol * sym
Definition: membfunc.h:38
void nrn_record_init()
Definition: cvodestb.cpp:69
int nrn_nthread
Definition: multicore.cpp:44
Node ** _v_node
Definition: multicore.h:77
void(* nrnthread_v_transfer_)(NrnThread *nt)
Definition: fadvance.cpp:148
int const size_t const size_t n
Definition: nrngsl.h:12
Memb_list * ml
Definition: multicore.h:35
void(* nrnmpi_v_transfer_)()
Definition: fadvance.cpp:147
double t
Definition: init.cpp:123
int nodecount
Definition: nrnoc_ml.h:18
_CONST char * s
Definition: system.cpp:74
NrnThread * nrn_threads
Definition: multicore.cpp:45
void nonvint(NrnThread *nt)
Definition: fadvance.cpp:744
static void * nrn_ms_bksub(NrnThread *)
Definition: fadvance.cpp:544
#define NODEA(n)
Definition: section.h:123
void(* nrn_bamech_t)(Node *, double *, Datum *, Datum *, struct NrnThread *)
Definition: membfunc.h:24
Pvmi state
Definition: membfunc.h:35
double * _nrn_sav_rhs
Definition: multicore.h:46
Section ** secorder
Definition: solve.cpp:77
Memb_list * memb_list
Definition: init.cpp:162
#define VEC_AREA(i)
Definition: section.h:122
int tree_changed
Definition: cabcode.cpp:19
void(* Pvmi)(struct NrnThread *, Memb_list *, int)
Definition: membfunc.h:18
#define spPrint
Definition: cspredef.h:33
void * nrn_multisplit_triang(NrnThread *)
int
Definition: nrnmusic.cpp:71
void nrn_solver_prepare()
Definition: cvodestb.cpp:93
const char * secname(Section *sec)
Definition: cabcode.cpp:1787
int use_cachevec
Definition: treeset.cpp:61
void hoc_warning(const char *, const char *)
int hoc_errno_check(void)
Definition: math.cpp:109
void nrndae_init()
Definition: nrndae.cpp:64
#define nrn_nonvint_block_init(tid)
Definition: nonvintblock.h:39
struct NrnThread * _nt
Definition: section.h:157
short * memb_order_
Definition: init.cpp:163
#define SUCCESS
Definition: fadvance.cpp:1122
#define BEFORE_INITIAL
Definition: membfunc.h:73
void init_net_events()
Definition: cvodestb.cpp:63
int n_memb_func
Definition: init.cpp:471
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:741
nrn_bamech_t f
Definition: membfunc.h:80
void fixed_record_continuous(NrnThread *nt)
Definition: cvodestb.cpp:87
void v_setup_vectors()
Definition: treeset.cpp:1623
errno
Definition: system.cpp:98
#define tstopunset
Definition: section.h:329
hoc_retpushx(1.0)
static void * nrn_ms_reduce_solve(NrnThread *)
Definition: fadvance.cpp:540
char * _sp13mat
Definition: multicore.h:79
void nrn_calc_fast_imem(NrnThread *_nt)
Definition: fadvance.cpp:623
void nrn_finitialize(int setv, double v)
Definition: fadvance.cpp:834
Datum ** pdata
Definition: nrnoc_ml.h:15
void cvode_finitialize()
fprintf(stderr, "Don't know the location of params at %p\, pp)
Pvmi initialize
Definition: membfunc.h:36
int section_count
Definition: solve.cpp:76
#define spGetSize
Definition: cspredef.h:23
Definition: section.h:213
int unset_nonvint_block(NonVintBlockItem func)
Definition: fadvance.cpp:1090
char * name
Definition: init.cpp:16
double * nrn_mech_wtime_
Definition: treeset.cpp:29
static void batch_open()
static int _upd
Definition: fadvance.cpp:311
#define NODEB(n)
Definition: section.h:124
int _ninits
Definition: init.cpp:864
void finitialize(void)
Definition: fadvance.cpp:992
#define CAP
Definition: membfunc.h:64
int cvode_active_
Definition: fadvance.cpp:158
#define CTADD
Definition: fadvance.cpp:92
double(* func)(double)
Definition: hoc_init.cpp:111
void fixed_play_continuous(NrnThread *nt)
Definition: cvodestb.cpp:81
int ifarg(int)
Definition: code.cpp:1562
#define VEC_V(i)
Definition: section.h:121
void nrn_fixed_step()
Definition: fadvance.cpp:338
int end
Definition: multicore.h:65
Datum * dparam
Definition: section.h:219
static void * nrn_fixed_step_group_thread(NrnThread *nth)
Definition: fadvance.cpp:441
void nrn_fihexec(int type)
Definition: finithnd.cpp:36
void nrn_seg_or_x_arg(int iarg, Section **psec, double *px)
Definition: point.cpp:191
#define NODERHS(n)
Definition: section.h:104
#define OBJ(q)
Definition: hoclist.h:67
void frecord_init(void)
Definition: fadvance.cpp:809
void nrncvode_set_t(double t)
Definition: cvodestb.cpp:143
static double ** batch_var
Definition: fadvance.cpp:205
Node ** nodelist
Definition: nrnoc_ml.h:5
double _t
Definition: multicore.h:59
BAMech * bam
Definition: multicore.h:41
static void phase_end(const char *name)
void nrndae_update()
Definition: nrndae.cpp:44
static char * mechname
Definition: nocpout.cpp:151
#define STR(q)
Definition: model.h:87
void nrn_deliver_events(NrnThread *)
Definition: cvodestb.cpp:49
static void phase_begin(const char *name)
int nrnmpi_myid
void nrn_spike_exchange(NrnThread *nt)
nonvintblock_extern int(* nrn_nonvint_block)(int method, int length, double *pd1, double *pd2, int tid)
Definition: nonvintblock.h:30
Definition: hocdec.h:226
int stoprun
Definition: fadvance.cpp:161
static void * nrn_fixed_step_lastpart(NrnThread *)
Definition: fadvance.cpp:500
nrn_random_play
Definition: extdef.h:3
void * setup_tree_matrix(NrnThread *)
Definition: treeset.cpp:614
static void * nrn_fixed_step_thread(NrnThread *)
Definition: fadvance.cpp:457
#define getarg
Definition: hocdec.h:15
void cvode_fadvance()
double * hoc_val_pointer(const char *s)
Definition: code2.cpp:699
#define nodecount
Definition: md1redef.h:30
static void * daspk_init_step_thread(NrnThread *nt)
Definition: fadvance.cpp:312
#define i
Definition: md1redef.h:12
#define id
Definition: md1redef.h:33
void recalc_diam()
Definition: treeset.cpp:940
static void batch_close()
Definition: fadvance.cpp:1007
#define neqn
Definition: lineq.h:3
double cj
Definition: multicore.h:61
void deliver_net_events(NrnThread *)
Definition: cvodestb.cpp:40
void nrn_play_init()
Definition: cvodestb.cpp:75
sec
Definition: solve.cpp:885
struct Node ** pnode
Definition: section.h:51
int state_discon_allowed_
Definition: init.cpp:121
NrnThreadMembList * tml
Definition: multicore.h:62
static FILE * batch_file
Definition: fadvance.cpp:202
static int batch_size
Definition: fadvance.cpp:203
#define nrn_nonvint_block_fixed_step_solve(tid)
Definition: nonvintblock.h:51
void nrn_update_2d(NrnThread *nt)
Definition: extcelln.cpp:96
union Object::@54 u
int nrn_nonvint_block_helper(int method, int size, double *pd1, double *pd2, int tid)
Definition: fadvance.cpp:1106
Definition: section.h:132
size_t q
Definition: hocdec.h:176
ClassicalNODEA(nd)
#define VEC_RHS(i)
Definition: section.h:120
FILE * fopen()
double var(InputIterator begin, InputIterator end)
Definition: ivocvect.h:93
return NULL
Definition: cabcode.cpp:461
Node * node_exact(Section *sec, double x)
Definition: cabcode.cpp:1956
int(* NonVintBlockItem)(int method, int size, double *pd1, double *pd2, int tid)
Definition: fadvance.cpp:1054
void second_order_cur(NrnThread *nt)
Definition: eion.cpp:622
static void * nrn_ms_treeset_through_triang(NrnThread *)
Definition: fadvance.cpp:523
void * nrn_multisplit_bksub(NrnThread *)
#define NODEAREA(n)
Definition: section.h:115
cTemplate ** nrn_pnt_template_
Definition: init.cpp:169
void nrn_calc_fast_imem_fixedstep_init(NrnThread *_nt)
Definition: fadvance.cpp:641
#define var_(arg)
Definition: fadvance.cpp:1124
struct NrnThreadBAList * next
Definition: multicore.h:42
int secondorder
Definition: init.cpp:120