NEURON
eion.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 /* /local/src/master/nrn/src/nrnoc/eion.cpp,v 1.10 1998/02/26 16:42:50 hines Exp */
3 
4 #include <stdlib.h>
5 #include "section.h"
6 #include "neuron.h"
7 #include "membfunc.h"
8 #include "parse.hpp"
9 #include "membdef.h"
10 #include "nrniv_mf.h"
11 #include "nrnunits_modern.h"
12 
13 #undef hoc_retpushx
14 
15 extern double chkarg(int, double low, double high);
16 
17 extern Section *nrn_noerr_access();
18 
19 extern void hoc_register_prop_size(int, int, int);
20 
21 #define nparm 5
22 static const char *mechanism[] = { /*just a template*/
23  "0",
24  "na_ion",
25  "ena", "nao", "nai", 0,
26  "ina", "dina_dv_", 0,
27  0
28 };
29 static DoubScal scdoub[] = { /* just a template*/
30  "ci0_na_ion", 0,
31  "co0_na_ion", 0,
32  0, 0
33 };
34 
35 static void ion_alloc(Prop *);
36 
37 static void ion_cur(NrnThread *, Memb_list *, int);
38 
39 static void ion_init(NrnThread *, Memb_list *, int);
40 
41 extern "C" double nrn_nernst(double, double, double), nrn_ghk(double, double, double, double);
42 
43 static int na_ion, k_ion, ca_ion; /* will get type for these special ions */
44 
45 int nrn_is_ion(int type) {
46  return (memb_func[type].alloc == ion_alloc);
47 }
48 
50 static double **ion_global_map;
51 #define global_conci(type) ion_global_map[type][0]
52 #define global_conco(type) ion_global_map[type][1]
53 #define global_charge(type) ion_global_map[type][2]
54 
55 double nrn_ion_charge(Symbol *sym) {
56  return global_charge(sym->subtype);
57 }
58 
59 void ion_register(void) {
60  /* hoc level registration of ion name. Return -1 if name already
61  in use and not an ion; and the mechanism subtype otherwise.
62  */
63  char *name;
64  char *buf;
65  Symbol *s;
66  Symlist *sav;
67  int fail;
68  fail = 0;
69  sav = hoc_symlist;
71  name = gargstr(1);
72  buf = static_cast<char *>(emalloc(strlen(name) + 10));
73  sprintf(buf, "%s_ion", name);
74  s = hoc_lookup(buf);
75  if (s && s->type == MECHANISM && memb_func[s->subtype].alloc == ion_alloc) {
76  hoc_symlist = sav;
77  free(buf);
78  if (*getarg(2) != global_charge(s->subtype)) {
79  hoc_execerr_ext("%s already defined with charge %g, cannot redefine with charge %g", s->name, global_charge(s->subtype), *getarg(2));
80  }
81  hoc_retpushx((double) s->subtype);
82  return;
83  }
84  if (s) { fail = 1; }
85  sprintf(buf, "e%s", name);
86  if (hoc_lookup(buf)) { fail = 1; }
87  sprintf(buf, "%si", name);
88  if (hoc_lookup(buf)) { fail = 1; }
89  sprintf(buf, "%so", name);
90  if (hoc_lookup(buf)) { fail = 1; }
91  sprintf(buf, "i%s", name);
92  if (hoc_lookup(buf)) { fail = 1; }
93  sprintf(buf, "di%s_dv_", name);
94  if (hoc_lookup(buf)) { fail = 1; }
95  if (fail) {
96  hoc_symlist = sav;
97  free(buf);
98  hoc_retpushx(-1.);
99  return;
100  }
101  double charge = *getarg(2);
103  if (strcmp(name, "ca") == 0 && charge != 2.0) {
104  // In the very rare edge case that ca is not yet defined
105  // define with charge 2.0
106  ion_reg(name, 2.0);
107  // and emit a recoverable error as above to avoid an exit in ion_reg
108  free(buf);
109  hoc_execerr_ext("ca_ion already defined with charge 2, cannot redefine with charge %g\n", charge);
110  }
111  ion_reg(name, charge);
112  hoc_symlist = sav;
113  sprintf(buf, "%s_ion", name);
114  s = hoc_lookup(buf);
115  hoc_retpushx((double) s->subtype);
116  free(buf);
117 }
118 
119 void ion_charge(void) {
120  Symbol *s;
121  s = hoc_lookup(gargstr(1));
122  if (!s || s->type != MECHANISM || memb_func[s->subtype].alloc != ion_alloc) {
123  hoc_execerror(gargstr(1), "is not an ion mechanism");
124  }
126 }
127 
128 extern "C" {
129 void register_mech(const char **, Pvmp, Pvmi, Pvmi, Pvmi, Pvmi, int, int);
130 
131 
132 void ion_reg(const char *name, double valence) {
133  int i, mechtype;
134  Symbol *s;
135  char *buf[7];
136  double val;
137 #define VAL_SENTINAL -10000.
138 
139  {
140  int n = 2 * strlen(name) + 10; /*name used twice in initialization name */
141  for (i = 0; i < 7; ++i) {
142  buf[i] = static_cast<char *>(emalloc(n));
143  }
144  }
145  Sprintf(buf[0], "%s_ion", name);
146  Sprintf(buf[1], "e%s", name);
147  Sprintf(buf[2], "%si", name);
148  Sprintf(buf[3], "%so", name);
149  Sprintf(buf[5], "i%s", name);
150  Sprintf(buf[6], "di%s_dv_", name);
151  for (i = 0; i < 7; i++) {
152  mechanism[i + 1] = buf[i];
153  }
154  mechanism[5] = (char *) 0; /* buf[4] not used above */
155  s = hoc_lookup(buf[0]);
156  if (!s || s->type != MECHANISM
157  || memb_func[s->subtype].alloc != ion_alloc) {
158  register_mech(mechanism, ion_alloc, ion_cur, nullptr, nullptr, ion_init, -1, 1);
159  hoc_symbol_limits(hoc_lookup(buf[2]), 1e-12, 1e9);
160  hoc_symbol_limits(hoc_lookup(buf[3]), 1e-12, 1e9);
161  hoc_symbol_units(hoc_lookup(buf[1]), "mV");
162  hoc_symbol_units(hoc_lookup(buf[2]), "mM");
163  hoc_symbol_units(hoc_lookup(buf[3]), "mM");
164  hoc_symbol_units(hoc_lookup(buf[5]), "mA/cm2");
165  hoc_symbol_units(hoc_lookup(buf[6]), "S/cm2");
166  s = hoc_lookup(buf[0]);
167  mechtype = nrn_get_mechtype(mechanism[1]);
168  hoc_register_prop_size(mechtype, nparm, 1);
169  hoc_register_dparam_semantics(mechtype, 0, "iontype");
170  nrn_writes_conc(mechtype, 1);
171  if (ion_global_map_size <= s->subtype) {
172  ion_global_map_size = s->subtype + 1;
173  ion_global_map = (double **) erealloc(ion_global_map,
174  sizeof(double *) * ion_global_map_size);
175  }
176  ion_global_map[s->subtype] = (double *) emalloc(3 * sizeof(double));
177  Sprintf(buf[0], "%si0_%s", name, s->name);
178  scdoub[0].name = buf[0];
179  scdoub[0].pdoub = ion_global_map[s->subtype];
180  Sprintf(buf[1], "%so0_%s", name, s->name);
181  scdoub[1].name = buf[1];
182  scdoub[1].pdoub = ion_global_map[s->subtype] + 1;
183  hoc_register_var(scdoub, (DoubVec *) 0, (VoidFunc *) 0);
184  hoc_symbol_units(hoc_lookup(scdoub[0].name), "mM");
185  hoc_symbol_units(hoc_lookup(scdoub[1].name), "mM");
186  if (strcmp("na", name) == 0) {
187  na_ion = s->subtype;
190  global_charge(s->subtype) = 1.;
191  } else if (strcmp("k", name) == 0) {
192  k_ion = s->subtype;
195  global_charge(s->subtype) = 1.;
196  } else if (strcmp("ca", name) == 0) {
197  ca_ion = s->subtype;
200  global_charge(s->subtype) = 2.;
201  } else {
205  }
206  for (i = 0; i < 3; ++i) { /* used to be nrnocCONST */
207  s->u.ppsym[i]->subtype = _AMBIGUOUS;
208  }
209  }
210  val = global_charge(s->subtype);
211  if (valence != VAL_SENTINAL && val != VAL_SENTINAL && valence != val) {
212  fprintf(stderr, "%s ion charge defined differently in\n\
213 two USEION statements (%g and %g)\n",
214  s->name, valence, global_charge(s->subtype));
215  nrn_exit(1);
216  } else if (valence == VAL_SENTINAL && val == VAL_SENTINAL) {
217  /* Not defined now but could be defined by
218  a subsequent ion_reg from another model.
219  The list of ion mechanisms will be checked
220  after all mod files have been dealt with to verify
221  that they all have a defined valence.
222  */
223  } else if (valence != VAL_SENTINAL) {
224  global_charge(s->subtype) = valence;
225  }
226  for (i = 0; i < 7; ++i) {
227  free(buf[i]);
228  }
229 }
230 } // extern "C"
231 
233  int i;
234  for (i = 3; i < n_memb_func; ++i)
235  if (nrn_is_ion(i)) {
236  if (global_charge(i) == VAL_SENTINAL) {
237  Symbol *s = memb_func[i].sym;
238  Fprintf(stderr, "%s USEION CHARGE (or VALENCE) must be defined in\n\
239 at least one model using this ion\n", s->name);
240  nrn_exit(1);
241  }
242  }
243 }
244 
245 #define FARADAY _faraday_[_nrnunit_use_legacy_]
246 static double _faraday_[2] = {_faraday_codata2018, 96485.309};
247 #define gasconstant _gasconstant_[_nrnunit_use_legacy_]
248 static double _gasconstant_[2] = {_gasconstant_codata2018, 8.3134};
249 
250 #define ktf (1000.*gasconstant*(celsius + 273.15)/FARADAY)
251 double nrn_nernst(double ci, double co, double z) {
252 /*printf("nrn_nernst %g %g %g\n", ci, co, z);*/
253  if (z == 0) {
254  return 0.;
255  }
256  if (ci <= 0.) {
257  return 1e6;
258  } else if (co <= 0.) {
259  return -1e6;
260  } else {
261  return ktf / z * log(co / ci);
262  }
263 }
264 
265 extern "C" void nrn_wrote_conc(Symbol *sym, double *pe, int it) {
266  if (it & 040) {
267  pe[0] = nrn_nernst(pe[1], pe[2], nrn_ion_charge(sym));
268  }
269 }
270 
271 void nernst(void) {
272  double val = 0.0;
273 
274  if (hoc_is_str_arg(1)) {
275  Symbol *s = hoc_lookup(gargstr(1));
276  if (s && ion_global_map[s->u.rng.type]) {
277  Section *sec = chk_access();
278  Symbol *ion = memb_func[s->u.rng.type].sym;
279  double z = global_charge(s->u.rng.type);
280  double *ci, *co, *e, x;
281  if (ifarg(2)) {
282  x = chkarg(2, 0., 1.);
283  } else {
284  x = .5;
285  }
286  ci = nrn_rangepointer(sec, ion->u.ppsym[1], x);
287  co = nrn_rangepointer(sec, ion->u.ppsym[2], x);
288  e = nrn_rangepointer(sec, ion->u.ppsym[0], x);
289  switch (s->u.rng.index) {
290  case 0:
291  val = nrn_nernst(*ci, *co, z);
292  hoc_retpushx(val);
293  return;
294  case 1:
295  val = *co * exp(-z / ktf * *e);
296  hoc_retpushx(val);
297  return;
298  case 2:
299  val = *ci * exp(z / ktf * *e);
300  hoc_retpushx(val);
301  return;
302  }
303  }
304  hoc_execerror(gargstr(1), " not a reversal potential or concentration");
305  } else {
306  val = nrn_nernst(*getarg(1), *getarg(2), *getarg(3));
307 /*printf("nernst=%g\n", val);*/
308  }
309  hoc_retpushx(val);
310  return;
311 }
312 
313 static double efun(double x) {
314  if (fabs(x) < 1e-4) {
315  return 1. - x / 2.;
316  } else {
317  return x / (exp(x) - 1);
318  }
319 }
320 
321 extern "C" double nrn_ghk(double v, double ci, double co, double z) {
322  double eco, eci, temp;
323  temp = z * v / ktf;
324  eco = co * efun(temp);
325  eci = ci * efun(-temp);
326  return (.001) * z * FARADAY * (eci - eco);
327 }
328 
329 void ghk(void) {
330  double val = nrn_ghk(*getarg(1), *getarg(2), *getarg(3), *getarg(4));
331  hoc_retpushx(val);
332 }
333 
334 #if VECTORIZE
335 #define erev pd[i][0] /* From Eion */
336 #define conci pd[i][1]
337 #define conco pd[i][2]
338 #define cur pd[i][3]
339 #define dcurdv pd[i][4]
340 
341 /*
342  handle erev, conci, conc0 "in the right way" according to ion_style
343  default. See nrn/lib/help/nrnoc.help.
344 ion_style("name_ion", [c_style, e_style, einit, eadvance, cinit])
345 
346  ica is assigned
347  eca is parameter but if conc exists then eca is assigned
348  if conc is nrnocCONST then eca calculated on finitialize
349  if conc is STATE then eca calculated on fadvance and conc finitialize
350  with global nai0, nao0
351 
352  nernst(ci, co, charge) and ghk(v, ci, co, charge) available to hoc
353  and models.
354 */
355 
356 #define iontype ppd[i][0].i /* how _AMBIGUOUS is to be handled */
357 /*the bitmap is
358 03 concentration unused, nrnocCONST, DEP, STATE
359 04 initialize concentrations
360 030 reversal potential unused, nrnocCONST, DEP, STATE
361 040 initialize reversal potential
362 0100 calc reversal during fadvance
363 0200 ci being written by a model
364 0400 co being written by a model
365 */
366 
367 #define charge global_charge(type)
368 #define conci0 global_conci(type)
369 #define conco0 global_conco(type)
370 
371 extern "C" double nrn_nernst_coef(int type) {
372  /* for computing jacobian element dconc'/dconc */
373  return ktf / charge;
374 }
375 
376 /*
377 It is generally an error for two models to WRITE the same concentration
378 */
379 extern "C" void nrn_check_conc_write(Prop *p_ok, Prop *pion, int i) {
380  static long *chk_conc_, *ion_bit_, size_;
381  Prop *p;
382  int flag, j, k;
383  if (i == 1) {
384  flag = 0200;
385  } else {
386  flag = 0400;
387  }
388  /* an embarassing hack */
389  /* up to 32 possible ions */
390  /* continuously compute a bitmap that allows determination
391  of which models WRITE which ion concentrations */
392  if (n_memb_func > size_) {
393  if (!chk_conc_) {
394  chk_conc_ = (long *) ecalloc(2 * n_memb_func, sizeof(long));
395  ion_bit_ = (long *) ecalloc(n_memb_func, sizeof(long));
396  } else {
397  chk_conc_ = (long *) erealloc(chk_conc_, 2 * n_memb_func * sizeof(long));
398  ion_bit_ = (long *) erealloc(ion_bit_, n_memb_func * sizeof(long));
399  for (j = size_; j < n_memb_func; ++j) {
400  chk_conc_[2 * j] = 0;
401  chk_conc_[2 * j + 1] = 0;
402  ion_bit_[j] = 0;
403  }
404  }
405  size_ = n_memb_func;
406  }
407  for (k = 0, j = 0; j < n_memb_func; ++j) {
408  if (nrn_is_ion(j)) {
409  ion_bit_[j] = (1 << k);
410  ++k;
411  assert(k < sizeof(long) * 8);
412  }
413  }
414 
415  chk_conc_[2 * p_ok->type + i] |= ion_bit_[pion->type];
416  if (pion->dparam[0].i & flag) {
417  /* now comes the hard part. Is the possibility in fact actual.*/
418  for (p = pion->next; p; p = p->next) {
419  if (p == p_ok) {
420  continue;
421  }
422  if (chk_conc_[2 * p->type + i] & ion_bit_[pion->type]) {
423  char buf[300];
424  sprintf(buf, "%.*s%c is being written at the same location by %s and %s",
425  (int) strlen(memb_func[pion->type].sym->name) - 4,
426  memb_func[pion->type].sym->name,
427  ((i == 1) ? 'i' : 'o'),
428  memb_func[p_ok->type].sym->name,
429  memb_func[p->type].sym->name);
430  hoc_warning(buf, (char *) 0);
431  }
432  }
433  }
434  pion->dparam[0].i |= flag;
435 }
436 
437 void ion_style(void) {
438  Symbol *s;
439  int istyle, i, oldstyle;
440  Section *sec;
441  Prop *p;
442 
443  s = hoc_lookup(gargstr(1));
444  if (!s || s->type != MECHANISM || !nrn_is_ion(s->subtype)) {
445  hoc_execerror(gargstr(1), " is not an ion");
446  }
447 
448  sec = chk_access();
449  p = nrn_mechanism(s->subtype, sec->pnode[0]);
450  oldstyle = -1;
451  if (p) {
452  oldstyle = p->dparam[0].i;
453  }
454 
455  if (ifarg(2)) {
456  istyle = (int) chkarg(2, 0., 3.); /* c_style */
457  istyle += 010 * (int) chkarg(3, 0., 3.); /* e_style */
458  istyle += 040 * (int) chkarg(4, 0., 1.); /* einit */
459  istyle += 0100 * (int) chkarg(5, 0., 1.); /* eadvance */
460  istyle += 04 * (int) chkarg(6, 0., 1.); /* cinit*/
461 
462 #if 0 /* global effect */
463  {
464  int count;
465  Datum** ppd;
466  v_setup_vectors();
467  count = memb_list[s->subtype].nodecount;
468  ppd = memb_list[s->subtype].pdata;
469  for (i=0; i < count; ++i) {
470  iontype = (iontype&(0200+0400)) + istyle;
471  }
472  }
473 #else /* currently accessed section */
474  {
475  for (i = 0; i < sec->nnode; ++i) {
476  p = nrn_mechanism(s->subtype, sec->pnode[i]);
477  if (p) {
478  p->dparam[0].i &= (0200 + 0400);
479  p->dparam[0].i += istyle;
480  }
481  }
482  }
483 #endif
484  }
485  hoc_retpushx((double) oldstyle);
486 }
487 
488 int nrn_vartype(Symbol *sym) {
489  int i;
490  i = sym->subtype;
491  if (i == _AMBIGUOUS) {
492  Section *sec;
493  Prop *p;
494  sec = nrn_noerr_access();
495  if (!sec) {
496  return nrnocCONST;
497  }
498  p = nrn_mechanism(sym->u.rng.type, sec->pnode[0]);
499  if (p) {
500  int it = p->dparam[0].i;
501  if (sym->u.rng.index == 0) { /* erev */
502  i = (it & 030) >> 3; /* unused, nrnocCONST, DEP, or STATE */
503  } else { /* concentration */
504  i = (it & 03);
505  }
506  }
507  }
508  return i;
509 }
510 
511 /* the ion mechanism it flag defines how _AMBIGUOUS is to be interpreted */
512 extern "C" void nrn_promote(Prop *p, int conc, int rev) {
513  int oldconc, oldrev;
514  int *it = &p->dparam[0].i;
515  oldconc = (*it & 03);
516  oldrev = (*it & 030) >> 3;
517  /* precedence */
518  if (oldconc < conc) {
519  oldconc = conc;
520  }
521  if (oldrev < rev) {
522  oldrev = rev;
523  }
524  /* promote type */
525  if (oldconc > 0 && oldrev < 2) {
526  oldrev = 2;
527  }
528  *it &= ~0177; /* clear the bitmap */
529  *it += oldconc + 010 * oldrev;
530  if (oldconc == 3) { /* if state then cinit */
531  *it += 4;
532  if (oldrev == 2) { /* if not state (WRITE) then eadvance */
533  *it += 0100;
534  }
535  }
536  if (oldconc > 0 && oldrev == 2) { /*einit*/
537  *it += 040;
538  }
539 }
540 
541 /* Must be called prior to any channels which update the currents */
542 static void ion_cur(NrnThread *nt, Memb_list *ml, int type) {
543  int count = ml->nodecount;
544  Node **vnode = ml->nodelist;
545  double **pd = ml->data;
546  Datum **ppd = ml->pdata;
547  int i;
548 /*printf("ion_cur %s\n", memb_func[type].sym->name);*/
549 #if _CRAY
550 #pragma _CRI ivdep
551 #endif
552  for (i = 0; i < count; ++i) {
553  dcurdv = 0.;
554  cur = 0.;
555  if (iontype & 0100) {
557  }
558  };
559 }
560 
561 /* Must be called prior to other models which possibly also initialize
562  concentrations based on their own states
563 */
564 static void ion_init(NrnThread *nt, Memb_list *ml, int type) {
565  int count = ml->nodecount;
566  Node **vnode = ml->nodelist;
567  double **pd = ml->data;
568  Datum **ppd = ml->pdata;
569  int i;
570 /*printf("ion_init %s\n", memb_func[type].sym->name);*/
571 #if _CRAY
572 #pragma _CRI ivdep
573 #endif
574  for (i = 0; i < count; ++i) {
575  if (iontype & 04) {
576  conci = conci0;
577  conco = conco0;
578  }
579  }
580 #if _CRAY
581 #pragma _CRI ivdep
582 #endif
583  for (i = 0; i < count; ++i) {
584  if (iontype & 040) {
586  }
587  }
588 }
589 
590 static void ion_alloc(Prop *p) {
591  double *pd[1];
592  int i = 0;
593 
594  pd[0] = nrn_prop_data_alloc(p->type, nparm, p);
595  p->param_size = nparm;
596 
597  cur = 0.;
598  dcurdv = 0.;
599  if (p->type == na_ion) {
600  erev = DEF_ena;
601  conci = DEF_nai;
602  conco = DEF_nao;
603  } else if (p->type == k_ion) {
604  erev = DEF_ek;
605  conci = DEF_ki;
606  conco = DEF_ko;
607  } else if (p->type == ca_ion) {
608  erev = DEF_eca;
609  conci = DEF_cai;
610  conco = DEF_cao;
611  } else {
612  erev = DEF_eion;
613  conci = DEF_ioni;
614  conco = DEF_iono;
615  }
616  p->param = pd[0];
617 
618  p->dparam = nrn_prop_datum_alloc(p->type, 1, p);
619  p->dparam->i = 0;
620 }
621 
623  extern int secondorder;
624  NrnThreadMembList *tml;
625  Memb_list *ml;
626  int j, i, i2;
627 #define c 3
628 #define dc 4
629  if (secondorder == 2) {
630  for (tml = nt->tml; tml; tml = tml->next)
631  if (memb_func[tml->index].alloc == ion_alloc) {
632  ml = tml->ml;
633  i2 = ml->nodecount;
634  for (i = 0; i < i2; ++i) {
635  ml->data[i][c] += ml->data[i][dc]
636  * (NODERHS(ml->nodelist[i]));
637  }
638  }
639  }
640 }
641 
642 #endif
643 
void ghk(void)
Definition: eion.cpp:329
Definition: hocdec.h:84
void ion_charge(void)
Definition: eion.cpp:119
int param_size
Definition: section.h:217
void * ecalloc(size_t n, size_t size)
Definition: symbol.cpp:221
double * param
Definition: section.h:218
#define assert(ex)
Definition: hocassrt.h:26
short type
Definition: cabvars.h:10
void nrn_verify_ion_charge_defined()
Definition: eion.cpp:232
short nnode
Definition: section.h:41
int hoc_is_str_arg(int narg)
Definition: code.cpp:741
void * erealloc(void *ptr, size_t n)
Definition: symbol.cpp:267
#define nrnocCONST
Definition: membfunc.h:69
void hoc_symbol_limits(Symbol *sym, float low, float high)
Definition: code2.cpp:99
static int ion_global_map_size
Definition: eion.cpp:49
#define dc
struct NrnThreadMembList * next
Definition: multicore.h:34
short type
Definition: model.h:58
void nrn_writes_conc(int type, int unused)
Definition: init.cpp:706
Symbol * hoc_lookup(const char *)
size_t p
Represent main neuron object computed by single thread.
Definition: multicore.h:58
log
Definition: extdef.h:3
void hoc_register_prop_size(int, int, int)
Definition: init.cpp:721
int nrn_is_ion(int type)
Definition: eion.cpp:45
#define DEF_ek
Definition: membdef.h:42
#define VAL_SENTINAL
void nrn_promote(Prop *p, int conc, int rev)
Definition: eion.cpp:512
char * name
Definition: model.h:72
Memb_func * memb_func
Definition: init.cpp:161
#define Fprintf
Definition: model.h:249
static double ** ion_global_map
Definition: eion.cpp:50
#define v
Definition: md1redef.h:4
double ** data
Definition: nrnoc_ml.h:14
#define conci0
Definition: eion.cpp:368
int i
Definition: hocdec.h:179
static philox4x32_key_t k
Definition: nrnran123.cpp:11
sprintf(buf," if (secondorder) {\ " int _i;\" " for(_i=0;_i< %d;++_i) {\" " _p[_slist%d[_i]]+=dt *_p[_dlist%d[_i]];\" " }}\", numeqn, listnum, listnum)
static int na_ion
Definition: eion.cpp:43
double nrn_nernst_coef(int type)
Definition: eion.cpp:371
#define cur
Definition: eion.cpp:338
#define e
Definition: passive0.cpp:24
#define gargstr
Definition: hocdec.h:14
short type
Definition: section.h:215
#define DEF_cai
Definition: membdef.h:45
static const char * mechanism[]
Definition: eion.cpp:22
double * pdoub
Definition: hocdec.h:254
void nrn_wrote_conc(Symbol *sym, double *pe, int it)
Definition: eion.cpp:265
Symlist * hoc_top_level_symlist
Definition: code2.cpp:662
Symbol * sym
Definition: membfunc.h:38
#define charge
Definition: eion.cpp:367
int nrn_vartype(Symbol *sym)
Definition: eion.cpp:488
void hoc_execerr_ext(const char *fmt,...)
printf style specification of hoc_execerror message.
Definition: fileio.cpp:958
static void ion_init(NrnThread *, Memb_list *, int)
Definition: eion.cpp:564
int nrn_get_mechtype(const char *mechname)
Definition: cabcode.cpp:2017
int const size_t const size_t n
Definition: nrngsl.h:12
HocStruct Symbol ** ppsym
Definition: hocdec.h:149
Memb_list * ml
Definition: multicore.h:35
int nodecount
Definition: nrnoc_ml.h:18
#define DEF_eca
Definition: membdef.h:48
_CONST char * s
Definition: system.cpp:74
#define DEF_ko
Definition: membdef.h:41
Memb_list * memb_list
Definition: init.cpp:162
int val
Definition: dll.cpp:167
#define global_charge(type)
Definition: eion.cpp:53
void(* Pvmp)(Prop *)
Definition: membfunc.h:19
void(* Pvmi)(struct NrnThread *, Memb_list *, int)
Definition: membfunc.h:18
char * hoc_symbol_units(Symbol *, const char *)
Definition: code2.cpp:128
int
Definition: nrnmusic.cpp:71
void hoc_warning(const char *, const char *)
Pvmp alloc
Definition: membfunc.h:32
#define ktf
Definition: eion.cpp:250
#define FARADAY
Definition: eion.cpp:245
static void ion_cur(NrnThread *, Memb_list *, int)
Definition: eion.cpp:542
int n_memb_func
Definition: init.cpp:471
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:741
void nernst(void)
Definition: eion.cpp:271
Symlist * hoc_symlist
void v_setup_vectors()
Definition: treeset.cpp:1623
const char * name
Definition: hocdec.h:253
#define erev
Definition: eion.cpp:335
hoc_retpushx(1.0)
#define DEF_cao
Definition: membdef.h:46
static double _gasconstant_[2]
Definition: eion.cpp:248
size_t j
Datum ** pdata
Definition: nrnoc_ml.h:15
#define conci
Definition: eion.cpp:336
fprintf(stderr, "Don't know the location of params at %p\, pp)
exp
Definition: extdef.h:3
Definition: model.h:57
static double _faraday_[2]
Definition: eion.cpp:246
#define iontype
Definition: eion.cpp:356
Definition: section.h:213
char * name
Definition: init.cpp:16
#define _gasconstant_codata2018
Prop * nrn_mechanism(int type, Node *nd)
Definition: cabcode.cpp:1079
#define global_conco(type)
Definition: eion.cpp:52
char * emalloc(unsigned n)
Definition: list.cpp:189
double nrn_nernst(double, double, double)
Definition: eion.cpp:251
#define DEF_eion
Definition: membdef.h:53
#define DEF_ki
Definition: membdef.h:40
#define DEF_ena
Definition: membdef.h:37
Symlist * hoc_built_in_symlist
Definition: symbol.cpp:39
void ion_reg(const char *name, double valence)
Definition: eion.cpp:132
void hoc_register_dparam_semantics(int type, int ix, const char *name)
Definition: init.cpp:732
static double efun(double x)
Definition: eion.cpp:313
int ifarg(int)
Definition: code.cpp:1562
Datum * dparam
Definition: section.h:219
static DoubScal scdoub[]
Definition: eion.cpp:29
long subtype
Definition: model.h:59
#define DEF_iono
Definition: membdef.h:52
struct Symbol::@52::@53 rng
#define global_conci(type)
Definition: eion.cpp:51
#define NODERHS(n)
Definition: section.h:104
double nrn_ion_charge(Symbol *sym)
Definition: eion.cpp:55
double nrn_ghk(double, double, double, double)
Definition: eion.cpp:321
void register_mech(const char **, Pvmp, Pvmi, Pvmi, Pvmi, Pvmi, int, int)
Definition: init.cpp:688
Node ** nodelist
Definition: nrnoc_ml.h:5
void hoc_register_var(DoubScal *scdoub, DoubVec *vdoub, VoidFunc *fn)
Definition: hocusr.cpp:110
#define _AMBIGUOUS
Definition: membfunc.h:101
#define DEF_nao
Definition: membdef.h:36
#define conco
Definition: eion.cpp:337
double * nrn_prop_data_alloc(int type, int count, Prop *p)
Definition: cxprop.cpp:262
#define _faraday_codata2018
#define getarg
Definition: hocdec.h:15
long subtype
Definition: init.cpp:122
#define i
Definition: md1redef.h:12
#define c
#define conco0
Definition: eion.cpp:369
struct Prop * next
Definition: section.h:214
void nrn_exit(int)
Definition: hoc.cpp:219
sec
Definition: solve.cpp:885
#define DEF_ioni
Definition: membdef.h:51
Datum * nrn_prop_datum_alloc(int type, int count, Prop *p)
Definition: cxprop.cpp:273
char buf[512]
Definition: init.cpp:13
fabs
Definition: extdef.h:3
#define nparm
Definition: eion.cpp:21
void nrn_check_conc_write(Prop *p_ok, Prop *pion, int i)
Definition: eion.cpp:379
struct Node ** pnode
Definition: section.h:51
static int ca_ion
Definition: eion.cpp:43
double * nrn_rangepointer(Section *sec, Symbol *s, double d)
Definition: cabcode.cpp:1334
NrnThreadMembList * tml
Definition: multicore.h:62
static void ion_alloc(Prop *)
Definition: eion.cpp:590
#define Sprintf
Definition: model.h:248
static int k_ion
Definition: eion.cpp:43
union Symbol::@18 u
void ion_register(void)
Definition: eion.cpp:59
Definition: section.h:132
Section * nrn_noerr_access()
Definition: cabcode.cpp:464
#define DEF_nai
Definition: membdef.h:35
Definition: hocdec.h:176
void ion_style(void)
Definition: eion.cpp:437
Section * chk_access(void)
Definition: cabcode.cpp:437
double chkarg(int, double low, double high)
Definition: code2.cpp:608
void second_order_cur(NrnThread *nt)
Definition: eion.cpp:622
int secondorder
Definition: init.cpp:120
#define dcurdv
Definition: eion.cpp:339