1 #include <../../nmodlconf.h>
70 #define GETWD(buf) getcwd(buf, NRN_BUFSIZE)
92 #define NRNPRANGEIN 020
93 #define NRNPRANGEOUT 040
94 #define NRNGLOBAL 0100
95 #define NRNSTATIC 0200
100 #define NRNSECTION 02000
101 #define NRNPOINTER 04000
102 #define IONCONC 010000
103 #define NRNBBCOREPOINTER 020000
160 int iontype(
char* s1,
char* s2);
176 List* state_discon_list_;
178 static int cvode_emit, cvode_ieq_index;
179 static int cond_index;
180 static int tqitem_index;
181 static int watch_index;
182 static int cvode_index;
183 static List* ion_synonym;
184 extern int singlechan_;
191 static Item* net_send_delivered_;
195 #define SYMITER(arg) \
196 ITERATE(q, syminorder) { \
200 #define SYMLISTITER \
201 for (i = 'A'; i <= 'z'; i++) \
202 ITERATE(q, symlist[i])
204 #define IFTYPE(arg) if ((s->subtype & arg) && ((s->usage & EXPLICIT_DECL) != automatic))
213 extern int using_default_indep;
220 using_default_indep = 0;
222 using_default_indep = 1;
229 int i,
j, ioncount, pointercount, gind, emit_check_table_thread;
241 #if 1 || defined(__MINGW32__)
249 if (*modbase ==
'\\' || *modbase ==
'/') {
257 }
else if (strcmp(
mechname,
"nothing") == 0) {
267 "Notice: ARTIFICIAL_CELL models that would require thread specific data are not "
279 \n#if METHOD3\nextern int _method3;\n#endif\n\
282 \n#define exp hoc_Exp\nextern double hoc_Exp(double);\
293 #define nrn_init _nrn_init_%s\n\
294 #define _nrn_initial _nrn_initial_%s\n\
295 #define nrn_cur _nrn_cur_%s\n\
296 #define _nrn_current _nrn_current_%s\n\
297 #define nrn_jacob _nrn_jacob_%s\n\
298 #define nrn_state _nrn_state_%s\n\
299 #define _net_receive _net_receive_%s\
323 #define _threadargscomma_ _p, _ppvar, _thread, _nt,\n\
324 #define _threadargsprotocomma_ double* _p, Datum* _ppvar, Datum* _thread, NrnThread* _nt,\n\
325 #define _threadargs_ _p, _ppvar, _thread, _nt\n\
326 #define _threadargsproto_ double* _p, Datum* _ppvar, Datum* _thread, NrnThread* _nt\n\
331 #define _threadargscomma_ /**/\n\
332 #define _threadargsprotocomma_ /**/\n\
333 #define _threadargs_ /**/\n\
334 #define _threadargsproto_ /**/\n\
347 Sprintf(
buf,
"/* Thread safe. No static _p or _ppvar. */\n");
351 Sprintf(
buf,
"static double *_p; static Datum *_ppvar;\n");
358 ioncount =
iondef(&pointercount);
360 "\n#if MAC\n#if !defined(v)\n#define v _mlhv\n#endif\n#if !defined(h)\n#define h "
361 "_mlhh\n#endif\n#endif\n");
389 if (strcmp(s->
name,
"dt") == 0) {
392 if (strcmp(s->
name,
"t") == 0) {
418 "static int _mechtype;\n\
419 extern void _nrn_cacheloop_reg(int, int);\n\
420 extern void hoc_register_prop_size(int, int, int);\n\
421 extern void hoc_register_limits(int, HocParmLimits*);\n\
422 extern void hoc_register_units(int, HocParmUnits*);\n\
423 extern void nrn_promote(Prop*, int, int);\n\
424 extern Memb_func* memb_func;\n\
430 "#define NMODL_TEXT 1\n"
432 "static const char* nmodl_file_text;\n"
433 "static const char* nmodl_filename;\n"
434 "extern void hoc_reg_nmodl_text(int, const char*);\n"
435 "extern void hoc_reg_nmodl_filename(int, const char*);\n"
444 "static void* _hoc_create_pnt(Object* _ho) { void* create_point_process(int, "
450 "static double _hoc_loc_pnt(void* _vptr) {double loc_point_process(int, void*);\n");
453 "static double _hoc_has_loc(void* _vptr) {double has_loc_point(void*);\n");
458 "double get_loc_point_process(void*); return (get_loc_point_process(_vptr));\n}\n");
478 "static void _hoc_setdata() {\n Prop *_prop, *hoc_getdata_range(int);\n");
479 Sprintf(
buf,
"_prop = hoc_getdata_range(_mechtype);\n");
499 Sprintf(
buf,
"\"get_loc\", _hoc_get_loc_pnt,\n");
552 emit_check_table_thread = 0;
554 emit_check_table_thread = 1;
563 if (
SYM(
q)->assigned_to_ != 2) {
572 " _thread[%d]._pval = (double*)ecalloc(%d, sizeof(double));\n",
580 if (
SYM(
q)->assigned_to_ != 2) {
583 "#define %s (_thread[%d]._pval + %d)\n",
590 "#define %s _thread[%d]._pval[%d]\n",
612 if (s->nrntype & (
NRNGLOBAL) && s->assigned_to_ == 1) {
624 "static int _thread1data_inuse = 0;\nstatic double _thread1data[%d];\n#define _gth "
630 " if (_thread1data_inuse) {_thread[_gth]._pval = (double*)ecalloc(%d, "
631 "sizeof(double));\n }else{\n _thread[_gth]._pval = _thread1data; "
632 "_thread1data_inuse = 1;\n }\n",
636 " if (_thread[_gth]._pval == _thread1data) {\n _thread1data_inuse = 0;\n "
637 "}else{\n free((void*)_thread[_gth]._pval);\n }\n");
647 "#define %s%s (_thread1data + %d)\n\
648 #define %s (_thread[_gth]._pval + %d)\n",
656 "#define %s%s _thread1data[%d]\n\
657 #define %s _thread[_gth]._pval[%d]\n",
693 double d1 = 0., d2 = 0.;
713 diag(
"No statics allowed for thread safe models:", s->
name);
750 "static void _ba1(Node*_nd, double* _pp, Datum* _ppd, Datum* _thread, NrnThread* _nt)");
753 ", _ba%d(Node*_nd, double* _pp, Datum* _ppd, Datum* _thread, NrnThread* _nt)",
765 "static void nrn_alloc(Prop*);\nstatic void nrn_init(NrnThread*, _Memb_list*, int);\nstatic void nrn_state(NrnThread*, _Memb_list*, int);\n\
769 "static void nrn_cur(NrnThread*, _Memb_list*, int);\nstatic void "
770 "nrn_jacob(NrnThread*, _Memb_list*, int);\n");
775 if (net_send_seen_) {
782 for (
i = 0;
i < watch_seen_; ++
i) {
786 sprintf(
buf,
"\n#define _watch_array _ppvar + %d", watch_index);
807 " if (_prop) { _nrn_free_watch(_prop->dparam, %d, %d);}\n",
814 " if (_prop) { _nrn_free_fornetcon(&(_prop->dparam[_fnc_index]._pvoid));}\n");
828 diag(
"DESTRUCTOR only permitted for POINT_PROCESS", (
char*) 0);
838 "/* connect range variables in _p that hoc is supposed to know about */\n");
841 static const char *_mechanism[] = {\n\
905 q =
q->next->next->next;
910 extern Prop* need_memb(Symbol*);\n\n\
911 static void nrn_alloc(Prop* _prop) {\n\
913 double *_p; Datum *_ppvar;\n\
917 " if (nrn_point_prop_) {\n\
918 _prop->_alloc_seq = nrn_point_prop_->_alloc_seq;\n\
919 _p = nrn_point_prop_->param;\n\
920 _ppvar = nrn_point_prop_->dparam;\n }else{\n");
953 Sprintf(
buf,
"prop_ion = need_memb(_morphology_sym);\n");
956 "\t_ppvar[%d]._pval = &prop_ion->param[0]; /* diam */\n",
957 ioncount + pointercount),
963 "\t_ppvar[%d]._pval = &nrn_alloc_node_->_area; /* diam */\n",
964 ioncount + pointercount +
diamdec),
989 "\t_ppvar[%d]._pval = &prop_ion->param[%d]; /* %s */\n",
1003 "\t_ppvar[%d]._pval = &prop_ion->param[%d]; /* %s */\n",
1012 "\t_ppvar[%d]._pval = &prop_ion->param[%d]; /* _ion_di%sdv */\n",
1025 "\t_ppvar[%d]._pvoid = (void*)(&(prop_ion->dparam[0]._i)); /* iontype for %s */\n",
1033 "\t_ppvar[%d]._pval = &prop_ion->param[%d]; /* _ion_di%sdv */\n",
1046 static void _constructor(Prop* _prop) {\n\
1047 double* _p; Datum* _ppvar; Datum* _thread;\n\
1048 _thread = (Datum*)0;\n\
1049 _p = _prop->param; _ppvar = _prop->dparam;\n\
1055 static void _constructor(Prop* _prop) {\n\
1056 _p = _prop->param; _ppvar = _prop->dparam;\n\
1086 sprintf(
buf,
"static _singlechan_declare%d();\n", singlechan_);
1092 if (net_send_seen_) {
1094 diag(
"can't use net_send if there is no NET_RECEIVE block", (
char*) 0);
1096 sprintf(
buf,
"\n#define _tqitem &(_ppvar[%d]._pvoid)\n", tqitem_index);
1098 if (net_send_delivered_) {
1099 insertstr(net_send_delivered_,
" if (_lflag == 1. ) {*(_tqitem) = 0;}\n");
1122 "static void bbcore_write(double*, int*, int*, int*, _threadargsproto_);\n");
1124 "extern void hoc_reg_bbcore_write(int, void(*)(double*, int*, int*, int*, "
1125 "_threadargsproto_));\n");
1127 "static void bbcore_read(double*, int*, int*, int*, _threadargsproto_);\n");
1129 "extern void hoc_reg_bbcore_read(int, void(*)(double*, int*, int*, int*, "
1130 "_threadargsproto_));\n");
1134 extern Symbol* hoc_lookup(const char*);\n\
1135 extern void _nrn_thread_reg(int, int, void(*)(Datum*));\n\
1136 extern void _nrn_thread_table_reg(int, void(*)(double*, Datum*, Datum*, NrnThread*, int));\n\
1137 extern void hoc_register_tolerance(int, HocStateTolerance*, Symbol***);\n\
1138 extern void _cvode_abstol( Symbol**, double*, int);\n\n\
1141 "void _%s_reg() {\n\
1142 int _vectorized = %d;\n",
1149 Sprintf(
buf,
"void _%s_reg() {\n _initlists();\n", modbase);
1158 q =
q->next->next->next;
1166 q =
q->next->next->next;
1172 _pointtype = point_register_mech(_mechanism,\n\
1173 nrn_alloc,%s, nrn_init,\n\
1174 hoc_nrnpointerindex, %d,\n\
1175 _hoc_create_pnt, _hoc_destroy_pnt, _member_func);\n",
1185 register_mech(_mechanism, nrn_alloc,%s, nrn_init, hoc_nrnpointerindex, %d);\n",
1192 " _extcall_thread = (Datum*)ecalloc(%d, sizeof(Datum));\n",
1214 if (emit_check_table_thread) {
1223 "#if NMODL_TEXT\n hoc_reg_nmodl_text(_mechtype, nmodl_file_text);\n "
1224 "hoc_reg_nmodl_filename(_mechtype, nmodl_filename);\n#endif\n");
1234 " hoc_register_dparam_semantics(_mechtype, %d, \"%s\");\n",
1250 q =
q->next->next->next;
1260 hoc_register_cvode(_mechtype, _ode_count, _ode_map, _ode_spec, _ode_matsol);\n");
1263 hoc_register_tolerance(_mechtype, _hoc_state_tol, &_atollist);\n");
1270 hoc_register_cvode(_mechtype, _ode_count, 0, 0, 0);\n");
1273 sprintf(
buf,
"hoc_reg_singlechan(_mechtype, _singlechan_declare%d);\n", singlechan_);
1281 "Notice: ARTIFICIAL_CELL is a synonym for POINT_PROCESS which hints that it\n\
1282 only affects and is affected by discrete events. As such it is not\n\
1283 located in a section and is not associated with an integrator\n");
1285 sprintf(
buf,
"add_nrn_artcell(_mechtype, %d);\n", tqitem_index);
1288 if (net_event_seen_) {
1300 sprintf(
buf,
"add_nrn_fornetcons(_mechtype, _fnc_index);\n");
1310 #if EXTRACELLULAR\n\
1311 if (_nd->_extnode) {\n\
1312 v = NODEV(_nd) +_nd->_extnode->_v[0];\n\
1343 hoc_register_var(hoc_scdoub, hoc_vdoub, hoc_intfunc);\n");
1347 #if HAVE_REALPATH && !defined(NRN_AVOID_ABSOLUTE_PATHS)
1378 static void _destructor(Prop* _prop) {\n\
1379 double* _p; Datum* _ppvar; Datum* _thread;\n\
1380 _thread = (Datum*)0;\n\
1381 _p = _prop->param; _ppvar = _prop->dparam;\n\
1387 static void _destructor(Prop* _prop) {\n\
1388 _p = _prop->param; _ppvar = _prop->dparam;\n\
1412 if (strcmp(s->
name,
"v") == 0)
1419 printf(
"Warning: Default %g of PARAMETER %s will be ignored and set by NEURON.\n",
1426 Item *
q, *qdexp, *qb1, *qvexp, *qb2, *q1;
1427 char *cfindex, *dfdcur;
1450 "static void* _difspace%d;\nextern double nrn_nernst_coef();\n\
1451 static double _difcoef%d(int _i, double* _p, Datum* _ppvar, double* _pdvol, double* _pdfcdc, Datum* _thread, NrnThread* _nt) {\n \
1456 for (q1 = qvexp; q1 != qb2; q1 = q1->
next) {
1462 if (_i == %s) {\n *_pdfcdc = %s;\n }else{ *_pdfcdc=0.;}\n",
1470 for (q1 = qdexp; q1 != qb1; q1 = q1->
next) {
1475 lappendstr(
procfunc,
"static void _difusfunc(ldifusfunc2_t _f, NrnThread* _nt) {int _i;\n");
1496 " for (_i=0; _i < %d; ++_i) mac_difusfunc(_f, _mechtype, _difcoef%d, "
1497 "&_difspace%d, _i, ",
1503 " for (_i=0; _i < %d; ++_i) (*_f)(_mechtype, _difcoef%d, &_difspace%d, _i, ",
1510 sprintf(
buf,
" mac_difusfunc(_f,_mechtype, _difcoef%d, &_difspace%d, 0, ",
n,
n);
1512 sprintf(
buf,
" (*_f)(_mechtype, _difcoef%d, &_difspace%d, 0, ",
n,
n);
1538 for (
n = 0, cp = sym->
u.
str; *cp; ++cp) {
1547 i = sscanf(cp,
"%lf %lf\n", pg1, pg2);
1561 for (
n = 0, cp = sym->
u.
str; *cp; ++cp) {
1570 i = sscanf(cp,
"%lf\n", pg1);
1589 i = sscanf(sym->
u.
str,
"[%*d]\n%lf%*c%lf", pg1, pg2);
1591 i = sscanf(sym->
u.
str,
"%lf%*c%lf", pg1, pg2);
1594 for (
n = 0, cp = sym->
u.
str;
n < 2;) {
1595 if (*cp++ ==
'\n') {
1599 for (cp1 = s; *cp !=
'\n';) {
1608 i = sscanf(sym->
u.
str,
"[%*d]\n%lf\n%s", pg1, s);
1610 i = sscanf(sym->
u.
str,
"%lf\n%s", pg1, s);
1619 diag(sym->
name,
" does not have a proper declaration");
1694 "#define %s (_p + %d)\n#define %s_columnindex %d\n",
1702 "#define %s _p[%d]\n#define %s_columnindex %d\n",
1709 q->itemtype = VERBATIM;
1716 switch (
SYM(q1)->type) {
1726 if (strcmp(
SYM(q1)->
name,
"POINT_PROCESS") == 0) {
1728 }
else if (strcmp(
SYM(q1)->
name,
"ARTIFICIAL_CELL") == 0) {
1733 case ELECTRODE_CURRENT:
1742 diag(
"NEURON SECTION variables not implemented", (
char*) 0);
1752 threadsafe(
"Use of EXTERNAL is not thread safe.");
1760 threadsafe(
"Use of POINTER is not thread safe.");
1767 threadsafe(
"Use of BBCOREPOINTER is not thread safe.");
1793 "static void _ba%d(Node*_nd, double* _pp, Datum* _ppd, Datum* _thread, NrnThread* _nt) ",
1798 qv =
insertstr(
q,
"_p = _pp; _ppvar = _ppd;\n");
1801 ba = (ba == BEFORE) ? 10 : 20;
1802 ba += (
type == BREAKPOINT) ? 1 : 0;
1803 ba += (
type == SOLVE) ? 2 : 0;
1804 ba += (
type == INITIAL1) ? 3 : 0;
1805 ba += (
type == STEP) ? 4 : 0;
1819 q =
q->next->next->next;
1827 List *readlist, *writelist;
1834 diag(
"mergeing of neuron models not supported yet", (
char*) 0);
1847 LST(qw) = writelist;
1886 int iontype(
char* s1,
char* s2)
1889 if (strcmp(
buf, s1) == 0) {
1893 if (strcmp(
buf, s1) == 0) {
1897 if (strcmp(
buf, s1) == 0) {
1901 if (strcmp(
buf, s1) == 0) {
1904 Sprintf(
buf,
"%s is not a valid ionic variable for %s", s1, s2);
1926 diag(s->
name,
"cannot be a RANGE or GLOBAL variable for this mechanism");
1934 diag(s->
name,
"cannot be a RANGE or GLOBAL variable for this mechanism");
1954 "\n#define t nrn_threads->_t\n#define dt nrn_threads->_dt\n"),
1955 "\n#define t _nt->_t\n#define dt _nt->_dt\n");
1967 diag(
"celcius should be spelled celsius", (
char*) 0);
1971 if (s->
type == NAME || s->
type == PRIME) {
1980 if (s !=
indepsym && !s->nrntype) {
2054 Item *
q, *q1, *qconc;
2101 if (block == 2 && qconc) {
2105 }
else if (ic ==
IONOUT) {
2112 " nrn_wrote_conc(_%s_sym, (&(_ion_%s)) - %d, _style_%s);\n",
2142 "WARNING: Dimensions may be wrong for READ %s with POINT_PROCESS\n",
2158 "WARNING: WRITE %s with it a STATE may not be translated correctly\n",
2168 int iondef(
int* p_pointercount) {
2169 int ioncount, it, need_style;
2178 q->itemtype = VERBATIM;
2186 lappendstr(
uip,
"extern void nrn_update_ion_pointer(Symbol*, Datum*, int, int);\n");
2187 lappendstr(
uip,
"static void _update_ion_pointer(Datum* _ppvar) {\n");
2199 " nrn_update_ion_pointer(_%s_sym, _ppvar, %d, %d);\n",
2204 SYM(q1)->ioncount_ = ioncount;
2217 " nrn_update_ion_pointer(_%s_sym, _ppvar, %d, %d);\n",
2222 SYM(q1)->ioncount_ = ioncount;
2229 Sprintf(
buf,
"#define _ion_di%sdv\t*_ppvar[%d]._pval\n", sion->
name, ioncount);
2233 " nrn_update_ion_pointer(_%s_sym, _ppvar, %d, 4);\n",
2245 Sprintf(
buf,
"#define _style_%s\t*((int*)_ppvar[%d]._pvoid)\n", sion->
name, ioncount);
2254 Sprintf(
buf,
"#define _ion_di%sdv\t*_ppvar[%d]._pval\n", sion->
name, ioncount);
2258 " nrn_update_ion_pointer(_%s_sym, _ppvar, %d, 4);\n",
2266 *p_pointercount = 0;
2269 Sprintf(
buf,
"#define %s *_ppvar[%d]._pval\n", sion->
name, ioncount + *p_pointercount);
2270 sion->
used = ioncount + *p_pointercount;
2273 Sprintf(
buf,
"#define _p_%s _ppvar[%d]._pval\n", sion->
name, ioncount + *p_pointercount);
2274 sion->
used = ioncount + *p_pointercount;
2282 (*p_pointercount)++;
2286 Sprintf(
buf,
"#define diam *_ppvar[%d]._pval\n", ioncount + *p_pointercount);
2292 Sprintf(
buf,
"#define area *_ppvar[%d]._pval\n", ioncount + *p_pointercount +
diamdec);
2308 q->itemtype = (short)
i;
2312 Item *
q, *q1, *qbrak;
2319 strion =
SYM(
q)->name;
2342 strion =
SYM(
q)->name;
2348 buf,
" _ion_di%sdv += (_di%s - %s)/%s", strion, strion,
SYM(q1)->
name, strdel);
2370 in =
SYM(qion)->name;
2395 Sprintf(
buf,
"nrn_promote(prop_ion, %d, %d);\n", conc, rev);
2400 #define NRNFIX(arg) \
2401 if (strcmp(n, arg) == 0) \
2407 if (s->assigned_to_ == 0) {
2408 s->assigned_to_ = 1;
2411 s->assigned_to_ = 2;
2422 "is a special NEURON variable that should not be\n assigned a value\
2423 in a model description file\n");
2429 static int cvode_valid_, using_cvode;
2430 static int cvode_num_, cvode_neq_;
2431 static Symbol* cvode_fun_;
2437 if (s->slist_info_) {
2440 n = s->slist_info_[0] + 1;
2441 pi = (
int*)
emalloc((1 + 2 *
n) *
sizeof(int));
2442 for (
i = 2 * (
n - 1);
i > 0; --
i) {
2443 pi[
i] = s->slist_info_[
i];
2445 free(s->slist_info_);
2446 s->slist_info_ = pi;
2448 pi[2 *
n - 1] = findx;
2451 s->slist_info_ = pi = (
int*)
emalloc(3 *
sizeof(
int));
2460 pi = s->slist_info_;
2461 if (pi == (
int*) 0) {
2462 diag(s->
name,
"not really a STATE; Ie. No differential equation for it.\n");
2465 for (
i = 0;
i < pi[0]; ++
i) {
2466 if (pi[1 + 2 *
i] ==
n) {
2467 return pi[2 + 2 *
i];
2474 static void cvode_conc_map() {
2486 Item *
q, *q1, *q2, *q3;
2536 "is WRITE but is not a STATE and has no assignment statement");
2547 " double* _p; Datum* _ppvar; Datum* _thread;\n");
2549 " Node* _nd; double _v; int _iml, _cntml;\n\
2550 _cntml = _ml->_nodecount;\n\
2551 _thread = _ml->_thread;\n\
2552 for (_iml = 0; _iml < _cntml; ++_iml) {\n\
2553 _p = _ml->_data[_iml]; _ppvar = _ml->_pdata[_iml];\n\
2554 _nd = _ml->_nodelist[_iml];\n\
2565 static int _ode_count(int);\n");
2568 static int _ode_count(int _type){ hoc_execerror(\"%s\", \"cannot be used with CVODE\"); return 0;}\n",
2571 }
else if (cvode_emit) {
2574 static int _ode_count(int);\n\
2575 static void _ode_map(int, double**, double**, double*, Datum*, double*, int);\n\
2576 static void _ode_spec(NrnThread*, _Memb_list*, int);\n\
2577 static void _ode_matsol(NrnThread*, _Memb_list*, int);\n\
2581 static int _ode_count(int _type){ return %d;}\n",
2584 sprintf(
buf,
"\n#define _cvode_ieq _ppvar[%d]._i\n", cvode_ieq_index);
2591 "\nstatic void _ode_spec(NrnThread* _nt, _Memb_list* _ml, int _type) {\n");
2606 static void _ode_map(int _ieq, double** _pv, double** _pvdot, double* _pp, Datum* _ppd, double* _atol, int _type) {");
2609 double* _p; Datum* _ppvar;\n");
2612 int _i; _p = _pp; _ppvar = _ppd;\n\
2613 _cvode_ieq = _ieq;\n\
2614 for (_i=0; _i < %d; ++_i) {\n\
2615 _pv[_i] = _pp + _slist%d[_i]; _pvdot[_i] = _pp + _dlist%d[_i];\n\
2616 _cvode_abstol(_atollist, _atol, _i);\n\
2630 static void _ode_synonym(int _cnt, double** _pp, Datum** _ppd) {");
2633 double* _p; Datum* _ppvar;\n");
2637 for (_i=0; _i < _cnt; ++_i) {_p = _pp[_i]; _ppvar = _ppd[_i];\n");
2642 sprintf(
buf,
"static void _ode_matsol_instance%d(_threadargsproto_);\n", cvode_num_);
2644 sprintf(
buf,
"\nstatic void _ode_matsol_instance%d(_threadargsproto_) {\n", cvode_num_);
2650 "_cvode_sparse(&_cvsparseobj%d, %d, _dlist%d, _p, _ode_matsol%d, &_coef%d);\n",
2658 "_cvode_sparse_thread(&_thread[_cvspth%d]._pvoid, %d, _dlist%d, _p, "
2659 "_ode_matsol%d, _ppvar, _thread, _nt);\n",
2669 "(_p, _ppvar, _thread, _nt);\n");
2673 "\nstatic void _ode_matsol(NrnThread* _nt, _Memb_list* _ml, int _type) {\n");
2678 sprintf(
buf,
"_ode_matsol_instance%d(_threadargs_);\n", cvode_num_);
2683 if (state_discon_list_)
2701 static void _ode_spec(Node* _nd, double* _pp, Datum* _ppd) {\n\
2702 _p = _pp; _ppvar = _ppd; v = NODEV(_nd);\n\
2709 static void _ode_map(int _ieq, double** _pv, doubl** _pvdot, double* _pp){}\n");
2714 static void _ode_matsol(Node* _nd, double* _pp, Datum* _ppd){}\n");
2731 static int _ode_spec%d(_threadargsproto_);\n\
2732 /*static int _ode_matsol%d(_threadargsproto_);*/\n\
2741 if (!cvode_valid_ && !once++) {
2742 Fprintf(stderr,
"Notice: This mechanism cannot be used with CVODE\n");
2764 "if (_nt->_vcv) { _ode_spec%d(_p, _ppvar, _thread, _nt); }\n",
2767 sprintf(b,
"if (_nt->_vcv) { _ode_spec%d(); }\n", cvode_num_);
2785 diag(
"Only one NET_RECEIVE block allowed", (
char*) 0);
2788 diag(
"NET_RECEIVE can only exist in a POINT_PROCESS", (
char*) 0);
2792 insertstr(qstmt,
"(Point_process* _pnt, double* _args, double _lflag)");
2798 for (
q = qstmt;
q != qend;
q =
q->next) {
2804 net_send_delivered_ = qstmt;
2808 insertstr(qstmt,
" int _watch_rm = 0;\n");
2810 q =
insertstr(qstmt,
" _p = _pnt->_prop->param; _ppvar = _pnt->_prop->dparam;\n");
2814 insertstr(qstmt,
" assert(_tsav <= t); _tsav = t;");
2817 " if (_tsav > t){ extern char* hoc_object_name(); "
2818 "hoc_execerror(hoc_object_name(_pnt->ob), \":Event arrived out of order. "
2819 "Must call ParallelContext.set_maxstep AFTER assigning minimum "
2820 "NetCon.delay\");}\n _tsav = t;");
2833 for (
q = qstmt;
q != qend;
q =
q->next) {
2835 insertstr(qstmt,
" v = NODEV(_pnt->node);\n");
2836 insertstr(qend,
"\n NODEV(_pnt->node) = v;\n");
2846 for (
q = qstmt;
q != qend;
q =
q->next) {
2852 if ((s->nrntype &
IONCONC) == 0) {
2853 diag(s->
name,
":only concentrations can be mentioned in a NET_RECEIVE block");
2856 for (
j = 0;
j < nion; ++
j) {
2863 diag(
"too many ions mentioned in NET_RECEIVE block (limit 10", (
char*) 0);
2870 for (
j = 0;
j < nion; ++
j) {
2872 buf,
"%s %s = _ion_%s;\n", (
j == 0) ?
"\n" :
"", ions[
j]->
name, ions[
j]->
name);
2875 for (
j = 0;
j < nion; ++
j) {
2878 "%s _ion_%s = %s;\n",
2879 (
j == 0) ?
"\n" :
"",
2896 replacstr(qinit,
"\nstatic void _net_init(Point_process* _pnt, double* _args, double _lflag)");
2897 sprintf(
buf,
" _p = _pnt->_prop->param; _ppvar = _pnt->_prop->dparam;\n");
2900 double* _p = _pnt->_prop->param;\n\
2901 Datum* _ppvar = _pnt->_prop->dparam;\n\
2902 Datum* _thread = (Datum*)0;\n\
2903 NrnThread* _nt = (NrnThread*)_pnt->_vnt;\n\
2906 diag(
"NET_RECEIVE block can contain only one INITIAL block", (
char*) 0);
2922 "{int _ifn%d, _nfn%d; double* _fnargs%d, **_fnargslist%d;\n\
2923 \t_nfn%d = _nrn_netcon_args(_ppvar[_fnc_index]._pvoid, &_fnargslist%d);\n\
2924 \tfor (_ifn%d = 0; _ifn%d < _nfn%d; ++_ifn%d) {\n",
2936 sprintf(
buf,
"\t _fnargs%d = _fnargslist%d[_ifn%d];\n",
i,
i,
i);
2944 for (
q = stmt;
q != qend;
q =
q->next) {
2958 if (s->nrntype & (
NRNGLOBAL) && s->assigned_to_ == 1) {
2959 sprintf(
buf,
"Assignment to the GLOBAL variable, \"%s\", is not thread safe", s->
name);
2972 diag(s->
name,
" is a STATE variable and hence cannot be declared as GLOBAL");
2983 SYM(
q)->assigned_to_ = 2;
2990 if (blocktype != BREAKPOINT) {
2991 diag(
"CONDUCTANCE can only appear in BREAKPOINT block", (
char*) 0);
2997 if (q2 != q1->
next) {
3000 diag(s->
name,
"not declared as USEION in NEURON block");
3012 if (blocktype != BREAKPOINT) {
3017 char*
n =
SYM(q2)->name + 2;
3034 return SYM(
q->next);
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)
#define ITERATE(itm, lst)
NMODL parser global flags / functions.
Item * lappendstr(List *list, char *str)
void movelist(Item *q1, Item *q2, List *s)
void freelist(List **plist)
Item * insertstr(Item *item, char *str)
void replacstr(Item *q, char *s)
char * emalloc(unsigned n)
char * stralloc(char *buf, char *rel)
void deltokens(Item *q1, Item *q2)
Item * lappenditem(List *list, Item *item)
Item * lappendsym(List *list, Symbol *sym)
void slist_data(Symbol *s, int indx, int findx)
void out_nt_ml_frag(List *)
void vectorize_substitute(Item *q, char *str)
int slist_search(int listnum, Symbol *s)
void cvode_rw_cur(char *)
void parminstall(Symbol *n, char *num, char *units, char *limits)
void cvode_interface(Symbol *fun, int num, int neq)
void indepinstall(Symbol *n, char *from, char *to, char *with, Item *qstart, char *units, int scop)
void cvode_emit_interface()
static void var_count(Symbol *s)
void possible_local_current(int blocktype, List *symlist)
static Symbol * ifnew_install(char *name)
List * get_ion_variables(int)
static int use_bbcorepointer
int decode_tolerance(Symbol *sym, double *pg1)
List * thread_cleanup_list
Symbol * breakpoint_current(Symbol *s)
int check_tables_threads(List *)
void nrn_list(Item *q1, Item *q2)
void nrn_use(Item *q1, Item *q2, Item *q3, Item *q4)
void net_receive(Item *qarg, Item *qp1, Item *qp2, Item *qstmt, Item *qend)
int iontype(char *s1, char *s2)
static char * brkpnt_str_
List * set_ion_variables(int)
static Item * net_init_q1_
List * thread_mem_init_list
void net_init(Item *qinit, Item *qp2)
void threadsafe_seen(Item *q1, Item *q2)
void bablk(int ba, int type, Item *q1, Item *q2)
int ion_declared(Symbol *s)
void nrn_var_assigned(Symbol *s)
static Item * net_init_q2_
static void ppvar_semantics(int, const char *)
List * end_dion_stmt(char *strdel)
void conductance_hint(int blocktype, Item *q1, Item *q2)
static List * ppvar_semantics_
void decode_ustr(Symbol *sym, double *pg1, double *pg2, char *s)
int decode_limits(Symbol *sym, double *pg1, double *pg2)
static List * nrnpointers
void fornetcon(Item *keyword, Item *par1, Item *args, Item *par2, Item *stmt, Item *qend)
List * breakpoint_local_current_
void warn_ignore(Symbol *s)
int const size_t const size_t n
static double remove(void *v)