1 #include <../../nrnconf.h>
30 #define CVODE_FLAG if (cvode_flag)
31 #define NOT_CVODE_FLAG if (!cvode_flag)
87 char *cp, *ovrfl, *cs, *
n;
90 while (q1 != q2->
next) {
105 for (cs =
n; *cs; cs++) {
131 diag(
s->name,
"must be a STATE, CONSTANT, ASSIGNED, or INDEPENDENT");
139 if (!(
s->subtype &
ARRAY)) {
140 diag(
"REACTION: MUST be scalar or array", (
char*) 0);
192 if (
SYM(qdir)->
name[0] ==
'-') {
199 diag(
"flux equations involve only one state", (
char*) 0);
209 if (
s->nrntype & 02 ) {
221 "nrn_nernst_coef(_type_%s)*(%s _ion_d%sdv %s)",
232 diag(sr->
name,
"gets a flux from more than one current");
260 Item *
q, *qs, *afterbrace;
269 diag(
"Merging kinetic blocks not implemented", (
char*) 0);
276 "(void* _so, double* _rhs, _internalthreadargsproto_);\n");
289 afterbrace = q3->
next;
294 for (afterbrace = afterbrace->
next;
296 afterbrace = afterbrace->
next)
299 afterbrace = afterbrace->
next;
303 qv =
insertstr(afterbrace,
"double b_flux, f_flux, _term; int _i;\n");
314 if ((
s->subtype &
STAT) &&
s->used) {
348 diag(
"Failed to diagonalize the Kinetic matrix", (
char*) 0);
354 if ((
s->subtype &
STAT) &&
s->used == -1) {
358 int dim =
s->araydim;
366 diag(
"KINETIC contains no reactions", (
char*) 0);
370 "static neuron::container::field_index _slist%d[%d], _dlist%d[%d]; static double "
389 if ((
s->subtype &
STAT) &&
s->used) {
414 Item *
q, *qexp, *qb, *qend, *q1;
421 for (q1 = qb->
next; q1 != qend; q1 = q1->
next) {
424 if (!
SYM(q1)->used) {
435 if ((
s->subtype &
STAT) &&
s->used) {
467 Fprintf(stderr,
"%s method ignores conservation\n", meth);
471 "{int _i; for(_i=0;_i<%d;_i++) _ml->data(_iml, _dlist%d[_i]) = 0.0;}\n",
482 for (
i = 0;
i < rlst->
nsym;
i++) {
486 "for (_i=0; _i < %d; _i++) { _ml->data(_iml, _dlist%d[_i + %d]) /= %s;}\n",
494 "_ml->data(_iml, _dlist%d[%d]) /= %s;\n",
516 for (
j = 0;
j < 2;
j++) {
528 for (
i = 0;
i < rt->
num;
i++) {
539 for (
j = 0;
j < 2;
j++) {
588 diag(rt->
sym->
name,
"must be (solved) STATE in flux reaction");
593 diag(rt->
sym->
name,
"is conserved and has a flux");
648 int i,
nstate, flag, firsttrans, firsttrans1;
658 Sprintf(
buf,
"static void* _cvsparseobj%d;\n", fun->
u.
i);
664 "_nrn_destroy_sparseobj_thread(static_cast<SparseObj*>(_thread[_cvspth%d].get<void*"
695 "_nrn_destroy_sparseobj_thread(static_cast<SparseObj*>(_thread[_spth%d].get<"
710 "{int _i; double _dt1 = 1.0/%s;\n\
711 for(_i=%d;_i<%d;_i++){\n",
722 _RHS%d(_i) = -_dt1*(_ml->data(_iml, _slist%d[_i]) - _ml->data(_iml, _dlist%d[_i]));\n\
723 _MATELM%d(_i, _i) = _dt1;\n",
733 _RHS%d(_i) = _dt1*(_ml->data(_iml, _dlist%d[_i]));\n\
734 _MATELM%d(_i, _i) = _dt1;\n",
755 "\n_RHS%d(%d) *= %s",
761 ";\n_MATELM%d(%d, %d) *= %s;",
782 " _RHS%d(_i + %d) *= %s",
788 ";\n_MATELM%d(_i + %d, _i + %d) *= %s;",
822 if (strcmp(mname,
"_advance") == 0) {
824 buf,
"\n#define _RHS%d(arg) _coef%d[arg][%d]\n", fun->
u.
i, fun->
u.
i,
nstate);
827 "\n#define _MATELM%d(arg1,arg2) _coef%d[arg1][arg2]\n",
837 static int first = 1;
845 Sprintf(
buf,
"\n#define _RHS%d(_arg) _coef%d[_arg + 1]\n", fun->
u.
i, fun->
u.
i);
847 Sprintf(
buf,
"\n#define _RHS%d(_arg) _rhs[_arg+1]\n", fun->
u.
i);
850 "\n#define _MATELM%d(_row,_col)\
851 *(_getelm(_row + 1, _col + 1))\n",
855 "\n#define _MATELM%d(_row,_col) "
856 "*(_nrn_thread_getelm(static_cast<SparseObj*>(_so), _row + 1, _col + 1))\n",
875 for (
j = 0;
j < 2;
j++)
893 for (
i = 0;
i <
n;
i++) {
905 for (j1 = 0; j1 < 2; j1++)
906 for (rt1 = r->
rterm[j1]; rt1; rt1 = rt1->
rnext) {
981 Sprintf(eqstr,
"%d(%d + %s", fn, eqnum, rtdiag->
str);
987 Sprintf(eqstr,
"%d(%d", fn, eqnum);
1000 diag(rt->
sym->
name,
": only (solved) STATE are allowed in CONSERVE equations.");
1008 "_MATELM%s, %d + %s) = %d%s;\n",
1049 for (
i = 0, istate = 0;
i < rlst->
nsym;
i++) {
1053 if (
s->subtype &
ARRAY) {
1054 istate +=
s->araydim;
1061 diag(
"too many solve blocks", (
char*) 0);
1076 for (
i = 0;
i < rlst->
nsym;
i++) {
1079 if (
s->subtype &
ARRAY) {
1080 int dim =
s->araydim;
1082 "for(_i=0;_i<%d;_i++){_slist%d[%d+_i] = {%s_columnindex, _i};",
1089 buf,
" _dlist%d[%d+_i] = {D%s_columnindex, _i};}\n", fun->
u.
i,
s->varnum,
s->name);
1092 Sprintf(
buf,
"_slist%d[%d] = {%s_columnindex, 0};", fun->
u.
i,
s->varnum,
s->name);
1094 Sprintf(
buf,
" _dlist%d[%d] = {D%s_columnindex, 0};\n", fun->
u.
i,
s->varnum,
s->name);
1103 if (standard != actual) {
1104 diag(mes,
"not allowed in this kind of block");
1139 for (
q = qexp;
q != qb1;
q =
q->next) {
1150 for (
q = qb1->
next;
q != qb2;
q = qs) {
1155 diag(
SYM(
q)->
name,
"must be a (solved) STATE in a COMPARTMENT statement");
1177 for (
q = qexp;
q != qb1;
q =
q->next) {
1191 for (
q = qb1->
next;
q != qb2;
q = qs) {
1197 diag(
SYM(
q)->
name,
"must be a (solved) STATE in a LONGITUDINAL_DIFFUSION statement");
1206 Item *qexp, *qb1, *qb2, *
q;
1212 for (
q = qb1;
q != qb2;
q =
q->next) {
1245 Item *
q, *q1, *q2, *q4;
1264 first =
insertstr(last,
"\n/*copy of previous function */\n");
1265 for (
q = q1;
q != q4->
next;
q =
q->next) {
1274 "\n#undef WANT_PRAGMA\n#define WANT_PRAGMA 1\
1275 \n#undef _INSTANCE_LOOP\n#define _INSTANCE_LOOP \
1276 for (_ix = _base; _ix < _bound; ++_ix) ");
1279 "\n#undef _RHS%d\n#define _RHS%d(arg) \
1280 _coef%d[arg][_ix]\n",
1286 "\n#undef _MATELM%d\n#define _MATELM%d(row,col) \
1287 _jacob%d[(row)*%d + (col)][_ix]\n",
1304 while (
ITM(
q) != q2) {
1315 for (qq = q1; qq != q2; qq = qq->
next) {
1317 fprintf(stderr,
"itm ");
1322 switch (
q->itemtype) {
1324 fprintf(stderr,
"%p STRING |%s|\n",
q,
STR(
q));
1327 fprintf(stderr,
"%p SYMBOL |%s|\n",
q,
SYM(
q)->
name);
1330 fprintf(stderr,
"%p ITEM\n",
q);
1333 fprintf(stderr,
"%p type %d\n",
q,
q->itemtype);
1343 Item *
q, *pbeg, *pend, *qnext;
1350 if (
SYM(
q) == fun) {
1356 Sprintf(
buf,
"static int _ode_spec%d() {_reset=0;{\n", fun->
u.
i);
1359 "static int _ode_spec%d(_internalthreadargsproto_) {\n"
1367 Sprintf(
buf,
"static int _ode_matsol%d() {_reset=0;{\n", fun->
u.
i);
1370 "static int _ode_matsol%d(void* _so, double* _rhs, _internalthreadargsproto_) {int "
1382 for (
q = pbeg;
q != pend;
q = qnext) {
1385 (strcmp(
SYM(
q)->
name,
"f_flux") == 0 || strcmp(
SYM(
q)->
name,
"b_flux") == 0)) {
1389 switch (
q->itemtype) {
1391 if (strchr(
STR(
q),
';')) {
static double order(void *v)
void copyitems(Item *q1, Item *q2, Item *qdest)
void check_block(int standard, int actual, const char *mes)
void massagekinetic(Item *q1, Item *q2, Item *q3, Item *q4)
void massagecompart(Item *qexp, Item *qb1, Item *qb2, Symbol *indx)
void reactname(Item *q1, Item *lastok, Item *q2)
static int nstate_[MAXKINBLK]
List * thread_cleanup_list
void prn(Item *q1, Item *q2)
void massageconserve(Item *q1, Item *q3, Item *q5)
int number_states(Symbol *fun, Rlist **prlst, Rlist **pclst)
static Reaction * reactlist
void genfluxterm(Reaction *r, int type, int n)
static Item * cvode_sbegin
static void cvode_kin_remove()
char * qconcat(Item *q1, Item *q2)
void massageldifus(Item *qexp, Item *qb1, Item *qb2, Symbol *indx)
void flux(Item *qREACTION, Item *qdir, Item *qlast)
void cvode_kinetic(Item *qsol, Symbol *fun, int numeqn, int listnum)
void kinlist(Symbol *fun, Rlist *rlst)
void massagereaction(Item *qREACTION, Item *qREACT1, Item *qlpar, Item *qcomma, Item *qrpar)
void genderivterms(Reaction *r, int type, int n)
int genconservterms(int eqnum, Reaction *r, int fn, Rlist *rlst)
static Reaction * conslist
void kin_vect1(Item *q1, Item *q2, Item *q4)
void kinetic_intmethod(Symbol *fun, const char *meth)
void fixrlst(Rlist *rlst)
void kin_vect3(Item *q1, Item *q2, Item *q4)
void kinetic_implicit(Symbol *fun, const char *dt, const char *mname)
void genmatterms(Reaction *r, int fn)
static List * compartlist
#define ITERATE(itm, lst)
Symbol * lookup(const char *)
char * stralloc(const char *buf, char *rel)
void movelist(Item *q1, Item *q2, List *s)
Item * linsertstr(List *list, const char *str)
void replacstr(Item *q, const char *s)
Item * lappenditem(List *list, Item *item)
Item * insertitem(Item *item, Item *itm)
Item * insertstr(Item *item, const char *str)
Item * lappendsym(List *list, Symbol *sym)
Item * lappendstr(List *list, const char *str)
void freelist(List *list)
List * newlist()
The following routines support the concept of a list.
static void * emalloc(size_t size)
void SprintfAsrt(char(&buf)[N], const char *fmt, Args &&... args)
assert if the Sprintf format data does not fit into buf
int Sprintf(char(&buf)[N], const char *fmt, Args &&... args)
Redirect sprintf to snprintf if the buffer size can be deduced.
void slist_data(Symbol *s, int indx, int findx)
int in_solvefor(Symbol *)
void vectorize_substitute(Item *q, const char *str)
NMODL parser global flags / functions.
int const size_t const size_t n
static double remove(void *v)
struct Reaction * reactnext
int Fprintf(FILE *stream, const char *fmt, Args... args)