NEURON
nonlinz.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #include <stdio.h>
3 #include <math.h>
4 #include <InterViews/resource.h>
5 #include "nonlinz.h"
6 #include "nrnoc2iv.h"
7 #include "nrnmpi.h"
8 #include "cspmatrix.h"
9 #include "membfunc.h"
10 
11 extern "C" int structure_change_cnt;
12 extern void v_setup_vectors();
13 extern void nrn_rhs(NrnThread*);
14 extern int nrndae_extra_eqn_count();
17 extern spREAL* spGetElement(char*, int, int);
18 
19 extern void pargap_jacobi_rhs(double*, double*);
20 extern void pargap_jacobi_setup(int mode);
21 
22 class NonLinImpRep {
23  public:
24  NonLinImpRep();
25  virtual ~NonLinImpRep();
26  void delta(double);
27  void didv();
28  void dids();
29  void dsdv();
30  void dsds();
31  int gapsolve();
32 
33  char* m_;
34  int scnt_; // structure_change
36  double** pv_;
37  double** pvdot_;
38  int* v_index_;
39  double* rv_;
40  double* jv_;
41  double** diag_;
42  double* deltavec_; // just like cvode.atol*cvode.atolscale for ode's
43  double delta_; // slightly more efficient and easier for v.
44  void current(int, Memb_list*, int);
45  void ode(int, Memb_list*);
46 
47  double omega_;
48  int iloc_; // current injection site of last solve
49  float* vsymtol_;
50  int maxiter_;
51 };
52 
54  rep_ = NULL;
55 }
57  if (rep_) {
58  delete rep_;
59  }
60 }
61 double NonLinImp::transfer_amp(int curloc, int vloc) {
62  if (nrnmpi_numprocs > 1 && nrnthread_v_transfer_ && curloc != rep_->iloc_) {
64  "current injection site change not allowed with both gap junctions and nhost > 1", 0);
65  }
66  if (curloc != rep_->iloc_) {
67  solve(curloc);
68  }
69  double x = rep_->rv_[vloc];
70  double y = rep_->jv_[vloc];
71  return sqrt(x * x + y * y);
72 }
73 double NonLinImp::input_amp(int curloc) {
75  hoc_execerror("not allowed with both gap junctions and nhost>1", 0);
76  }
77  if (curloc != rep_->iloc_) {
78  solve(curloc);
79  }
80  if (curloc < 0) {
81  return 0.0;
82  }
83  double x = rep_->rv_[curloc];
84  double y = rep_->jv_[curloc];
85  return sqrt(x * x + y * y);
86 }
87 double NonLinImp::transfer_phase(int curloc, int vloc) {
88  if (nrnmpi_numprocs > 1 && nrnthread_v_transfer_ && curloc != rep_->iloc_) {
90  "current injection site change not allowed with both gap junctions and nhost > 1", 0);
91  }
92  if (curloc != rep_->iloc_) {
93  solve(curloc);
94  }
95  double x = rep_->rv_[vloc];
96  double y = rep_->jv_[vloc];
97  return atan2(y, x);
98 }
99 double NonLinImp::input_phase(int curloc) {
101  hoc_execerror("not allowed with both gap junctions and nhost>1", 0);
102  }
103  if (curloc != rep_->iloc_) {
104  solve(curloc);
105  }
106  if (curloc < 0) {
107  return 0.0;
108  }
109  double x = rep_->rv_[curloc];
110  double y = rep_->jv_[curloc];
111  return atan2(y, x);
112 }
113 double NonLinImp::ratio_amp(int clmploc, int vloc) {
115  hoc_execerror("not allowed with both gap junctions and nhost>1", 0);
116  }
117  if (clmploc < 0) {
118  return 0.0;
119  }
120  if (clmploc != rep_->iloc_) {
121  solve(clmploc);
122  }
123  double ax, bx, cx, ay, by, cy, bb;
124  ax = rep_->rv_[vloc];
125  ay = rep_->jv_[vloc];
126  bx = rep_->rv_[clmploc];
127  by = rep_->jv_[clmploc];
128  bb = bx * bx + by * by;
129  cx = (ax * bx + ay * by) / bb;
130  cy = (ay * bx - ax * by) / bb;
131  return sqrt(cx * cx + cy * cy);
132 }
133 void NonLinImp::compute(double omega, double deltafac, int maxiter) {
134  v_setup_vectors();
136  if (rep_ && rep_->scnt_ != structure_change_cnt) {
137  delete rep_;
138  rep_ = NULL;
139  }
140  if (!rep_) {
141  rep_ = new NonLinImpRep();
142  }
143  rep_->maxiter_ = maxiter;
144  if (rep_->neq_ == 0) {
145  return;
146  }
147  if (nrndae_extra_eqn_count() > 0) {
148  hoc_execerror("Impedance calculation with LinearMechanism not implemented", 0);
149  }
151  hoc_execerror("Impedance calculation with extracellular not implemented", 0);
152  }
153 
154  rep_->omega_ = 1000. * omega;
155  rep_->delta(deltafac);
156  // fill matrix
157  cmplx_spClear(rep_->m_);
158  rep_->didv();
159  rep_->dsds();
160 #if 1 // when 0 equivalent to standard method
161  rep_->dids();
162  rep_->dsdv();
163 #endif
164 
165  // cmplx_spPrint(rep_->m_, 0, 1, 1);
166  // for (int i=0; i < rep_->neq_; ++i) {
167  // printf("i=%d %g %g\n", i, rep_->diag_[i][0], rep_->diag_[i][1]);
168  // }
169  int e = cmplx_spFactor(rep_->m_);
170  switch (e) {
171  case spZERO_DIAG:
172  hoc_execerror("cmplx_spFactor error:", "Zero Diagonal");
173  case spNO_MEMORY:
174  hoc_execerror("cmplx_spFactor error:", "No Memory");
175  case spSINGULAR:
176  hoc_execerror("cmplx_spFactor error:", "Singular");
177  }
178 
179  rep_->iloc_ = -2;
180 }
181 
182 int NonLinImp::solve(int curloc) {
183  int rval = 0;
184  NrnThread* _nt = nrn_threads;
185  if (!rep_) {
186  hoc_execerror("Must call Impedance.compute first", 0);
187  }
188  if (rep_->iloc_ != curloc) {
189  int i;
190  rep_->iloc_ = curloc;
191  for (i = 0; i < rep_->neq_; ++i) {
192  rep_->rv_[i] = 0;
193  rep_->jv_[i] = 0;
194  }
195  if (curloc >= 0) {
196  rep_->rv_[curloc] = 1.e2 / NODEAREA(_nt->_v_node[curloc]);
197  }
198  if (nrnthread_v_transfer_) {
199  rval = rep_->gapsolve();
200  } else {
201  assert(rep_->m_);
202  cmplx_spSolve(rep_->m_, rep_->rv_ - 1, rep_->rv_ - 1, rep_->jv_ - 1, rep_->jv_ - 1);
203  }
204  }
205  return rval;
206 }
207 
208 // too bad it is not easy to reuse the cvode/daspk structures. Most of
209 // mapping is already done there.
210 
212  int err;
213  int i, j, ieq, cnt;
214  NrnThread* _nt = nrn_threads;
215  maxiter_ = 500;
216  m_ = NULL;
217 
218  vsymtol_ = NULL;
220  if (vsym->extra) {
222  }
223  // the equation order is the same order as for the fixed step method
224  // for current balance. Remaining ode equation order is
225  // defined by the memb_list.
226 
227 
228  // how many equations
229  n_v_ = _nt->end;
230  n_ext_ = 0;
231  if (_nt->_ecell_memb_list) {
233  }
235  n_ode_ = 0;
236  for (NrnThreadMembList* tml = _nt->tml; tml; tml = tml->next) {
237  Memb_list* ml = tml->ml;
238  i = tml->index;
239  nrn_ode_count_t s = memb_func[i].ode_count;
240  if (s) {
241  cnt = (*s)(i);
242  n_ode_ += cnt * ml->nodecount;
243  }
244  }
245  neq_v_ = n_v_ + n_ext_ + n_lin_;
246  neq_ = neq_v_ + n_ode_;
247  if (neq_ == 0) {
248  return;
249  }
250  m_ = cmplx_spCreate(neq_, 1, &err);
251  assert(err == spOKAY);
252  pv_ = new double*[neq_];
253  pvdot_ = new double*[neq_];
254  v_index_ = new int[n_v_];
255  rv_ = new double[neq_ + 1];
256  rv_ += 1;
257  jv_ = new double[neq_ + 1];
258  jv_ += 1;
259  diag_ = new double*[neq_];
260  deltavec_ = new double[neq_];
261 
262  for (i = 0; i < n_v_; ++i) {
263  // utilize nd->eqn_index in case of use_sparse13 later
264  Node* nd = _nt->_v_node[i];
265  pv_[i] = &NODEV(nd);
266  pvdot_[i] = nd->_rhs;
267  v_index_[i] = i + 1;
268  }
269  for (i = 0; i < n_v_; ++i) {
270  diag_[i] = cmplx_spGetElement(m_, v_index_[i], v_index_[i]);
271  }
272  for (i = neq_v_; i < neq_; ++i) {
273  diag_[i] = cmplx_spGetElement(m_, i + 1, i + 1);
274  }
276 }
277 
279  if (!m_) {
280  return;
281  }
282  cmplx_spDestroy(m_);
283  delete[] pv_;
284  delete[] pvdot_;
285  delete[] v_index_;
286  delete[](rv_ - 1);
287  delete[](jv_ - 1);
288  delete[] diag_;
289  delete[] deltavec_;
290 }
291 
292 void NonLinImpRep::delta(double deltafac) { // also defines pv_,pvdot_ map for ode
293  int i, j, nc, cnt, ieq;
294  NrnThread* nt = nrn_threads;
295  for (i = 0; i < neq_; ++i) {
296  deltavec_[i] = deltafac; // all v's wasted but no matter.
297  }
298  ieq = neq_v_;
299  for (NrnThreadMembList* tml = nt->tml; tml; tml = tml->next) {
300  Memb_list* ml = tml->ml;
301  i = tml->index;
302  nc = ml->nodecount;
303  nrn_ode_count_t s = memb_func[i].ode_count;
304  if (s && (cnt = (*s)(i)) > 0) {
305  nrn_ode_map_t m = memb_func[i].ode_map;
306  for (j = 0; j < nc; ++j) {
307  (*m)(ieq, pv_ + ieq, pvdot_ + ieq, ml->data[j], ml->pdata[j], deltavec_ + ieq, i);
308  ieq += cnt;
309  }
310  }
311  }
312  delta_ = (vsymtol_ && (*vsymtol_ != 0.)) ? *vsymtol_ : 1.;
313  delta_ *= deltafac;
314 }
315 
317  int i, j, ip;
318  Node* nd;
319  NrnThread* _nt = nrn_threads;
320  // d2v/dv2 terms
321  for (i = _nt->ncell; i < n_v_; ++i) {
322  nd = _nt->_v_node[i];
323  ip = _nt->_v_parent[i]->v_node_index;
324  double* a = cmplx_spGetElement(m_, v_index_[ip], v_index_[i]);
325  double* b = cmplx_spGetElement(m_, v_index_[i], v_index_[ip]);
326  *a += NODEA(nd);
327  *b += NODEB(nd);
328  *diag_[i] -= NODEB(nd);
329  *diag_[ip] -= NODEA(nd);
330  }
331  // jwC term
332  Memb_list* mlc = _nt->tml->ml;
333  int n = mlc->nodecount;
334  for (i = 0; i < n; ++i) {
335  double* cd = mlc->data[i];
336  j = mlc->nodelist[i]->v_node_index;
337  diag_[v_index_[j] - 1][1] += .001 * cd[0] * omega_;
338  }
339  // di/dv terms
340  // because there may be several point processes of the same type
341  // at the same location, we have to be careful to neither increment that
342  // nd->v multiple times nor count the rhs multiple times.
343  // So we can't take advantage of vectorized point processes.
344  // To avoid this we do each mechanism item separately.
345  // We assume there is no interaction between
346  // separate locations. Note that interactions such as gap junctions
347  // would not be handled in any case without computing a full jacobian.
348  // i.e. calling nrn_rhs varying every state one at a time (that would
349  // give the d2v/dv2 terms as well), but the expense is unwarranted.
350  for (NrnThreadMembList* tml = _nt->tml; tml; tml = tml->next) {
351  i = tml->index;
352  if (i == CAP) {
353  continue;
354  }
355  if (!memb_func[i].current) {
356  continue;
357  }
358  Memb_list* ml = tml->ml;
359  for (j = 0; j < ml->nodecount; ++j) {
360  Node* nd = ml->nodelist[j];
361  double x1;
362  double x2;
363  // zero rhs
364  // save v
365  NODERHS(nd) = 0;
366  x1 = NODEV(nd);
367  // v+dv
368  NODEV(nd) += delta_;
369  current(i, ml, j);
370  // save rhs
371  // zero rhs
372  // restore v
373  x2 = NODERHS(nd);
374  NODERHS(nd) = 0;
375  NODEV(nd) = x1;
376  current(i, ml, j);
377  // conductance
378  // add to matrix
379  *diag_[v_index_[nd->v_node_index] - 1] -= (x2 - NODERHS(nd)) / delta_;
380  }
381  }
382 }
383 
385  // same strategy as didv but now the innermost loop is over
386  // every state but just for that compartment
387  // outer loop over ode mechanisms in same order as we created the pv_ map // so we can eas
388  int ieq, i, in, is, iis;
389  NrnThread* nt = nrn_threads;
390  ieq = neq_ - n_ode_;
391  for (NrnThreadMembList* tml = nt->tml; tml; tml = tml->next) {
392  Memb_list* ml = tml->ml;
393  i = tml->index;
394  if (memb_func[i].ode_count && ml->nodecount) {
395  int nc = ml->nodecount;
396  nrn_ode_count_t s = memb_func[i].ode_count;
397  int cnt = (*s)(i);
398  if (memb_func[i].current) {
399  double* x1 = rv_; // use as temporary storage
400  double* x2 = jv_;
401  for (in = 0; in < ml->nodecount; ++in) {
402  Node* nd = ml->nodelist[in];
403  // zero rhs
404  NODERHS(nd) = 0;
405  // compute rhs
406  current(i, ml, in);
407  // save rhs
408  x2[in] = NODERHS(nd);
409  // each state incremented separately and restored
410  for (iis = 0; iis < cnt; ++iis) {
411  is = ieq + in * cnt + iis;
412  // save s
413  x1[is] = *pv_[is];
414  // increment s and zero rhs
415  *pv_[is] += deltavec_[is];
416  NODERHS(nd) = 0;
417  current(i, ml, in);
418  *pv_[is] = x1[is]; // restore s
419  double g = (NODERHS(nd) - x2[in]) / deltavec_[is];
420  if (g != 0.) {
421  double* elm =
422  cmplx_spGetElement(m_, v_index_[nd->v_node_index], is + 1);
423  elm[0] = -g;
424  }
425  }
426  // don't know if this is necessary but make sure last
427  // call with respect to original states
428  current(i, ml, in);
429  }
430  }
431  ieq += cnt * nc;
432  }
433  }
434 }
435 
437  int ieq, i, in, is, iis;
438  NrnThread* nt = nrn_threads;
439  ieq = neq_ - n_ode_;
440  for (NrnThreadMembList* tml = nt->tml; tml; tml = tml->next) {
441  Memb_list* ml = tml->ml;
442  i = tml->index;
443  if (memb_func[i].ode_count && ml->nodecount) {
444  int nc = ml->nodecount;
445  nrn_ode_count_t s = memb_func[i].ode_count;
446  int cnt = (*s)(i);
447  if (memb_func[i].current) {
448  double* x1 = rv_; // use as temporary storage
449  double* x2 = jv_;
450  // zero rhs, save v
451  for (in = 0; in < ml->nodecount; ++in) {
452  Node* nd = ml->nodelist[in];
453  for (is = ieq + in * cnt, iis = 0; iis < cnt; ++iis, ++is) {
454  *pvdot_[is] = 0.;
455  }
456  x1[in] = NODEV(nd);
457  }
458  // increment v only once in case there are multiple
459  // point processes at the same location
460  for (in = 0; in < ml->nodecount; ++in) {
461  Node* nd = ml->nodelist[in];
462  if (x1[in] == NODEV(nd)) {
463  NODEV(nd) += delta_;
464  }
465  }
466  // compute rhs. this is the rhs(v+dv)
467  ode(i, ml);
468  // save rhs, restore v, and zero rhs
469  for (in = 0; in < ml->nodecount; ++in) {
470  Node* nd = ml->nodelist[in];
471  for (is = ieq + in * cnt, iis = 0; iis < cnt; ++iis, ++is) {
472  x2[is] = *pvdot_[is];
473  *pvdot_[is] = 0;
474  }
475  NODEV(nd) = x1[in];
476  }
477  // compute the rhs(v)
478  ode(i, ml);
479  // fill the ds/dv elements
480  for (in = 0; in < ml->nodecount; ++in) {
481  Node* nd = ml->nodelist[in];
482  for (is = ieq + in * cnt, iis = 0; iis < cnt; ++iis, ++is) {
483  double ds = (x2[is] - *pvdot_[is]) / delta_;
484  if (ds != 0.) {
485  double* elm =
486  cmplx_spGetElement(m_, is + 1, v_index_[nd->v_node_index]);
487  elm[0] = -ds;
488  }
489  }
490  }
491  }
492  ieq += cnt * nc;
493  }
494  }
495 }
496 
498  int ieq, i, in, is, iis, ks, kks;
499  NrnThread* nt = nrn_threads;
500  // jw term
501  for (i = neq_v_; i < neq_; ++i) {
502  diag_[i][1] += omega_;
503  }
504  ieq = neq_v_;
505  for (NrnThreadMembList* tml = nt->tml; tml; tml = tml->next) {
506  Memb_list* ml = tml->ml;
507  i = tml->index;
508  if (memb_func[i].ode_count && ml->nodecount) {
509  int nc = ml->nodecount;
510  nrn_ode_count_t s = memb_func[i].ode_count;
511  int cnt = (*s)(i);
512  double* x1 = rv_; // use as temporary storage
513  double* x2 = jv_;
514  // zero rhs, save s
515  for (in = 0; in < ml->nodecount; ++in) {
516  for (is = ieq + in * cnt, iis = 0; iis < cnt; ++iis, ++is) {
517  *pvdot_[is] = 0.;
518  x1[is] = *pv_[is];
519  }
520  }
521  // compute rhs. this is the rhs(s)
522  ode(i, ml);
523  // save rhs
524  for (in = 0; in < ml->nodecount; ++in) {
525  for (is = ieq + in * cnt, iis = 0; iis < cnt; ++iis, ++is) {
526  x2[is] = *pvdot_[is];
527  }
528  }
529  // iterate over the states
530  for (kks = 0; kks < cnt; ++kks) {
531  // zero rhs, increment s(ks)
532  for (in = 0; in < ml->nodecount; ++in) {
533  ks = ieq + in * cnt + kks;
534  for (is = ieq + in * cnt, iis = 0; iis < cnt; ++iis, ++is) {
535  *pvdot_[is] = 0.;
536  }
537  *pv_[ks] += deltavec_[ks];
538  }
539  ode(i, ml);
540  // store element and restore s
541  // fill the ds/dv elements
542  for (in = 0; in < ml->nodecount; ++in) {
543  Node* nd = ml->nodelist[in];
544  ks = ieq + in * cnt + kks;
545  for (is = ieq + in * cnt, iis = 0; iis < cnt; ++iis, ++is) {
546  double ds = (*pvdot_[is] - x2[is]) / deltavec_[is];
547  if (ds != 0.) {
548  double* elm = cmplx_spGetElement(m_, is + 1, ks + 1);
549  elm[0] = -ds;
550  }
551  *pv_[ks] = x1[ks];
552  }
553  }
554  // perhaps not necessary but ensures the last computation is with
555  // the base states.
556  ode(i, ml);
557  }
558  ieq += cnt * nc;
559  }
560  }
561 }
562 
563 void NonLinImpRep::current(int im, Memb_list* ml, int in) { // assume there is in fact a current
564  // method
565  Pvmi s = memb_func[im].current;
566  // fake a 1 element memb_list
567  Memb_list mfake;
568 #if CACHEVEC != 0
569  mfake.nodeindices = ml->nodeindices + in;
570 #endif
571  mfake.nodelist = ml->nodelist + in;
572  mfake.data = ml->data + in;
573  mfake.pdata = ml->pdata + in;
574  mfake.prop = ml->prop ? ml->prop + in : nullptr;
575  mfake.nodecount = 1;
576  mfake._thread = ml->_thread;
577  (*s)(nrn_threads, &mfake, im);
578 }
579 
580 void NonLinImpRep::ode(int im, Memb_list* ml) { // assume there is in fact an ode method
581  Pvmi s = memb_func[im].ode_spec;
582  (*s)(nrn_threads, ml, im);
583 }
584 
586  // On entry, rv_ and jv_ contain the complex b for A*x = b.
587  // On return rv_ and jv_ contain complex solution, x.
588  // m_ is the factored matrix for the trees without gap junctions
589  // Jacobi method (easy for parallel)
590  // A = D + R
591  // D*x_(k+1) = (b - R*x_(k))
592  // D is m_ (and includes the gap junction contribution to the diagonal)
593  // R is the off diagonal matrix of the gaps.
594 
595  // one and only one stimulus
596 #if NRNMPI
597  if (nrnmpi_numprocs > 1 && nrnmpi_int_sum_reduce(iloc_ >= 0 ? 1 : 0) != 1) {
598  if (nrnmpi_myid == 0) {
599  hoc_execerror("there can be one and only one impedance stimulus", 0);
600  }
601  }
602 #endif
603 
605 
606  double *rx, *jx, *rx1, *jx1, *rb, *jb;
607  if (neq_) {
608  rx = new double[neq_];
609  jx = new double[neq_];
610  rx1 = new double[neq_];
611  jx1 = new double[neq_];
612  rb = new double[neq_];
613  jb = new double[neq_];
614  }
615 
616  // initialize for first iteration
617  for (int i = 0; i < neq_; ++i) {
618  rx[i] = jx[i] = 0.0;
619  rb[i] = rv_[i];
620  jb[i] = jv_[i];
621  }
622 
623  // iterate till change in x is small
624  double tol = 1e-9;
625  double delta;
626 
627  int success = 0;
628  int iter;
629 
630  for (iter = 1; iter <= maxiter_; ++iter) {
631  if (neq_) {
632  cmplx_spSolve(m_, rb - 1, rx1 - 1, jb - 1, jx1 - 1);
633  }
634 
635  // if any change in x > tol, then do another iteration.
636  success = 1;
637  delta = 0.0;
638  for (int i = 0; i < neq_; ++i) {
639  double err = fabs(rx1[i] - rx[i]) + fabs(jx1[i] - jx[i]);
640  if (err > tol) {
641  success = 0;
642  }
643  if (delta < err) {
644  delta = err;
645  }
646  }
647 #if NRNMPI
648  if (nrnmpi_numprocs > 1) {
649  success = nrnmpi_int_sum_reduce(success) / nrnmpi_numprocs;
650  }
651 #endif
652  if (success) {
653  for (int i = 0; i < neq_; ++i) {
654  rv_[i] = rx1[i];
655  jv_[i] = jx1[i];
656  }
657  break;
658  }
659 
660  // setup for next iteration
661  for (int i = 0; i < neq_; ++i) {
662  rx[i] = rx1[i];
663  jx[i] = jx1[i];
664  rb[i] = rv_[i];
665  jb[i] = jv_[i];
666  }
667  pargap_jacobi_rhs(rb, rx);
668  pargap_jacobi_rhs(jb, jx);
669  }
670 
671  pargap_jacobi_setup(1); // tear down
672 
673  if (neq_) {
674  delete[] rx;
675  delete[] jx;
676  delete[] rx1;
677  delete[] jx1;
678  delete[] rb;
679  delete[] jb;
680  }
681 
682  if (!success) {
683  char buf[256];
684  sprintf(buf,
685  "Impedance calculation did not converge in %d iterations. Max state change on last "
686  "iteration was %g (Iterations stop at %g)\n",
687  maxiter_,
688  delta,
689  tol);
690  execerror(buf, 0);
691  }
692  return iter;
693 }
Memb_func * memb_func
Definition: init.cpp:123
double transfer_amp(int curloc, int vloc)
Definition: nonlinz.cpp:61
virtual ~NonLinImp()
Definition: nonlinz.cpp:56
NonLinImpRep * rep_
Definition: nonlinz.h:19
int solve(int curloc)
Definition: nonlinz.cpp:182
void compute(double omega, double deltafac, int maxiter)
Definition: nonlinz.cpp:133
double ratio_amp(int clmploc, int vloc)
Definition: nonlinz.cpp:113
NonLinImp()
Definition: nonlinz.cpp:53
double input_phase(int curloc)
Definition: nonlinz.cpp:99
double input_amp(int curloc)
Definition: nonlinz.cpp:73
double transfer_phase(int curloc, int vloc)
Definition: nonlinz.cpp:87
int maxiter_
Definition: nonlinz.cpp:50
virtual ~NonLinImpRep()
Definition: nonlinz.cpp:278
double omega_
Definition: nonlinz.cpp:47
void ode(int, Memb_list *)
Definition: nonlinz.cpp:580
double * rv_
Definition: nonlinz.cpp:39
double delta_
Definition: nonlinz.cpp:43
void dids()
Definition: nonlinz.cpp:384
void delta(double)
Definition: nonlinz.cpp:292
double ** pvdot_
Definition: nonlinz.cpp:37
double ** diag_
Definition: nonlinz.cpp:41
char * m_
Definition: nonlinz.cpp:33
void dsdv()
Definition: nonlinz.cpp:436
double * jv_
Definition: nonlinz.cpp:40
float * vsymtol_
Definition: nonlinz.cpp:49
int gapsolve()
Definition: nonlinz.cpp:585
void didv()
Definition: nonlinz.cpp:316
double ** pv_
Definition: nonlinz.cpp:36
int * v_index_
Definition: nonlinz.cpp:38
void dsds()
Definition: nonlinz.cpp:497
double * deltavec_
Definition: nonlinz.cpp:42
void current(int, Memb_list *, int)
Definition: nonlinz.cpp:563
Symbol * hoc_table_lookup(const char *, Symlist *)
Definition: symbol.cpp:61
sprintf(buf, " if (secondorder) {\n" " int _i;\n" " for (_i = 0; _i < %d; ++_i) {\n" " _p[_slist%d[_i]] += dt*_p[_dlist%d[_i]];\n" " }}\n", numeqn, listnum, listnum)
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:754
char buf[512]
Definition: init.cpp:13
#define assert(ex)
Definition: hocassrt.h:32
static double deltafac(void *v)
Definition: impedanc.cpp:137
void
static int ode_count(int type)
Definition: kschan.cpp:111
#define i
Definition: md1redef.h:12
#define CAP
Definition: membfunc.h:64
void(* nrn_ode_map_t)(int, double **, double **, double *, Datum *, double *, int)
Definition: membfunc.h:21
int(* nrn_ode_count_t)(int)
Definition: membfunc.h:20
void(* Pvmi)(struct NrnThread *, Memb_list *, int)
Definition: membfunc.h:18
sqrt
Definition: extdef.h:3
atan2
Definition: extdef.h:4
fabs
Definition: extdef.h:3
NrnThread * nrn_threads
Definition: multicore.cpp:47
void(* nrnthread_v_transfer_)(NrnThread *)
Definition: fadvance.cpp:153
void pargap_jacobi_setup(int mode)
Definition: partrans.cpp:937
int nrndae_extra_eqn_count()
Definition: nrndae.cpp:36
void nrn_rhs(NrnThread *)
Definition: treeset.cpp:357
int structure_change_cnt
Definition: nonlinz.cpp:11
void v_setup_vectors()
Definition: treeset.cpp:1631
void pargap_jacobi_rhs(double *, double *)
Definition: partrans.cpp:1035
spREAL * spGetElement(char *, int, int)
Definition: spbuild.c:195
Symlist * hoc_built_in_symlist
Definition: ivocmac.cpp:76
int const size_t const size_t n
Definition: nrngsl.h:11
size_t j
int nrnmpi_myid
int nrnmpi_numprocs
static Symbol * vsym
Definition: occvode.cpp:49
#define g
Definition: passive0.cpp:21
#define e
Definition: passive0.cpp:22
#define NODEA(n)
Definition: section.h:124
#define NODEB(n)
Definition: section.h:125
#define NODEV(n)
Definition: section.h:115
#define execerror
Definition: section.h:36
#define NODEAREA(n)
Definition: section.h:116
#define NODERHS(n)
Definition: section.h:105
#define nlayer
Definition: section.h:188
#define spNO_MEMORY
Definition: spmatrix.h:101
#define spZERO_DIAG
Definition: spmatrix.h:99
#define spSINGULAR
Definition: spmatrix.h:100
#define spREAL
Definition: spmatrix.h:127
#define spOKAY
Definition: spmatrix.h:97
#define cnt
Definition: spt2queue.cpp:19
#define NULL
Definition: sptree.h:16
float tolerance
Definition: hocdec.h:113
Pvmi current
Definition: membfunc.h:33
int nodecount
Definition: nrnoc_ml.h:18
Node ** nodelist
Definition: nrnoc_ml.h:5
double ** data
Definition: nrnoc_ml.h:14
Datum ** pdata
Definition: nrnoc_ml.h:15
Prop ** prop
Definition: nrnoc_ml.h:16
Datum * _thread
Definition: nrnoc_ml.h:17
Definition: section.h:133
double * _rhs
Definition: section.h:146
int v_node_index
Definition: section.h:175
Represent main neuron object computed by single thread.
Definition: multicore.h:58
NrnThreadMembList * tml
Definition: multicore.h:62
int ncell
Definition: multicore.h:64
int end
Definition: multicore.h:65
Node ** _v_parent
Definition: multicore.h:78
Memb_list * _ecell_memb_list
Definition: multicore.h:80
Node ** _v_node
Definition: multicore.h:77
struct NrnThreadMembList * next
Definition: multicore.h:34
Memb_list * ml
Definition: multicore.h:35
Definition: model.h:57
HocSymExtension * extra
Definition: hocdec.h:160
Definition: hocdec.h:84
Definition: lineq.h:17