1 #include <../../nmodlconf.h> 31 static int cvode_flag;
32 static void cvode_kin_remove();
33 static Item* cvode_sbegin, *cvode_send;
34 static List* kin_items_;
35 #define CVODE_FLAG if(cvode_flag) 36 #define NOT_CVODE_FLAG if(!cvode_flag) 38 #define CVODE_FLAG if(0) 39 #define NOT_CVODE_FLAG if(1) 110 static char* instance_loop() {
111 extern char* cray_pragma();
113 Sprintf(buf1,
"\n#ifdef WANT_PRAGMA%s#endif\n _INSTANCE_LOOP {\n",
127 char *cp, *ovrfl, *cs, *
n;
128 cp =
buf; ovrfl =
buf+400;
129 while (q1 != q2->
next) {
144 for (cs = n; *cs; cs++) {
170 diag(s->
name,
"must be a STATE, CONSTANT, ASSIGNED, STEPPED, or INDEPENDENT");
173 rterm->
num = atoi(
STR(q2));
179 diag(
"REACTION: MUST be scalar or array", (
char *)0);
187 rterm->
str = (
char *)0;
233 if (
SYM(qdir)->
name[0] ==
'-') {
235 reactlist->
krate[1] = (
char *)0;
239 if (rterm->
rnext || (rterm->
num != 1)) {
240 diag(
"flux equations involve only one state", (
char *)0);
242 reactlist->
krate[0] = (
char *)0;
252 if (s->nrntype & 02 ) {
260 if (sr == rterm->
sym) {
263 sprintf(
buf,
"nrn_nernst_coef(_type_%s)*(%s _ion_d%sdv %s)",
271 diag(sr->
name,
"gets a flux from more than one current");
299 Item *
q, *qs, *afterbrace;
308 diag(
"Merging kinetic blocks not implemented", (
char *)0);
321 vectorize_substitute(qv,
"(void* _so, double* _rhs, double* _p, Datum* _ppvar, Datum* _thread, NrnThread* _nt)\n");
329 afterbrace = q3->
next;
334 !strcmp(afterbrace->
element.str,
"double")){
335 for(afterbrace = afterbrace->
next ;
337 strcmp(afterbrace->
element.str,
";\n") ;
338 afterbrace=afterbrace->
next);
340 !strcmp(afterbrace->
element.str,
";\n"))
341 afterbrace=afterbrace->
next;
345 qv =
insertstr(afterbrace,
"double b_flux, f_flux, _term; int _i;\n");
363 for (r1 = conslist; r1; r1 = r1->
reactnext) {
370 for (r1 = reactlist; r1; r1 = r1->
reactnext) {
384 for (r1 = conslist; r1; r1 = r1->
reactnext) {
393 diag(
"Failed to diagonalize the Kinetic matrix", (
char *)0);
410 diag(
"KINETIC contains no reactions", (
char *)0);
413 Sprintf(
buf,
"static int _slist%d[%d], _dlist%d[%d]; static double *_temp%d;\n",
462 Item *
q, *qexp, *qb, *qend, *q1;
467 for (q1 = qb->
next; q1 != qend; q1 = q1->
next) {
484 for (q = cvode_sbegin; q != cvode_send->
next; q = q->
next) {
512 Fprintf(stderr,
"%s method ignores conservation\n", meth);
515 Sprintf(
buf,
"{int _i; for(_i=0;_i<%d;_i++) _p[_dlist%d[_i]] = 0.0;}\n",
525 for (i = 0; i < rlst->
nsym; i++) {
528 Sprintf(
buf,
"for (_i=0; _i < %d; _i++) { _p[_dlist%d[_i + %d]] /= %s;}\n",
553 for (j=0; j<2; j++) {
565 for (i=0; i<rt->
num; i++) {
576 for (j=0; j<2; j++) {
626 diag(rt->
sym->
name,
"must be (solved) STATE in flux reaction");
631 diag(rt->
sym->
name,
"is conserved and has a flux");
665 if (type && r->
krate[0]) {
689 int i,
nstate, flag, sparsedec, firsttrans, firsttrans1;
699 Sprintf(
buf,
"static void* _cvsparseobj%d;\n", fun->
u.
i);
703 sprintf(
buf,
" _nrn_destroy_sparseobj_thread(_thread[_cvspth%d]._pvoid);\n", fun->
u.
i);
730 sprintf(
buf,
" _nrn_destroy_sparseobj_thread(_thread[_spth%d]._pvoid);\n", fun->
u.
i);
735 diag(
" SENS unimplemented for default kinetic integration",
746 Sprintf(
buf,
"{int _i; double _dt1 = 1.0/%s;\n\ 747 for(_i=%d;_i<%d;_i++){\n",
758 _RHS%d(_i) = -_dt1*(_p[_slist%d[_i]] - _p[_dlist%d[_i]]);\n\ 759 _MATELM%d(_i, _i) = _dt1;\n",
760 fun->
u.
i, fun->
u.
i, fun->
u.
i, fun->
u.
i);
764 _RHS%d(_i) = -_dt1*(_p[_ix][_slist%d[_i]] - _p[_ix][_dlist%d[_i]]);\n\ 765 _MATELM%d(_i, _i) = _dt1;\n",
766 fun->
u.
i, fun->
u.
i, fun->
u.
i, fun->
u.
i);
772 _RHS%d(_i) = _dt1*(_p[_dlist%d[_i]]);\n\ 773 _MATELM%d(_i, _i) = _dt1;\n",
774 fun->
u.
i, fun->
u.
i, fun->
u.
i);
778 _RHS%d(_i) = _dt1*(_p[_ix][_dlist%d[_i]]);\n\ 779 _MATELM%d(_i, _i) = _dt1;\n",
780 fun->
u.
i, fun->
u.
i, fun->
u.
i);
873 if (strcmp(mname,
"_advance") == 0) {
874 Sprintf(
buf,
"\n#define _RHS%d(arg) _coef%d[arg][%d]\n",
875 fun->
u.
i, fun->
u.
i, nstate);
877 Sprintf(
buf,
"\n#define _MATELM%d(arg1,arg2) _coef%d[arg1][arg2]\n",
890 Sprintf(
buf,
"\n#define _RHS%d(_arg) _coef%d[_arg + 1]\n",
894 Sprintf(
buf,
"\n#define _RHS%d(_arg) _rhs[_arg+1]\n",
899 *(_getelm(_row + 1, _col + 1))\n", fun->
u.
i);
902 Sprintf(
buf,
"\n#define _MATELM%d(_row,_col) *(_nrn_thread_getelm(_so, _row + 1, _col + 1))\n", fun->
u.
i);
905 {
static int first = 1;
if (first) {
910 Sprintf(
buf,
"extern double *_nrn_thread_getelm(SparseObj*, int, int);\n");
931 for (j=0; j < 2; j++)
944 for (rt1 = r->
rterm[j]; rt1; rt1 = rt1->
rnext) {
949 for (i=0; i<
n; i++) {
961 for (j1=0; j1<2; j1++)
962 for (rt1 = r->
rterm[j1]; rt1; rt1=rt1->
rnext) {
1012 conslist->
krate[1] = (
char *)0;
1046 Sprintf(eqstr,
"%d(%d + %s", fn, eqnum, rtdiag->
str);
1052 Sprintf(eqstr,
"%d(%d", fn, eqnum);
1065 diag(rt->
sym->
name,
": only (solved) STATE are allowed in CONSERVE equations.");
1072 Sprintf(
buf,
"_MATELM%s, %d + %s) = %d%s;\n",
1103 for (rlst = rlist; rlst && (rlst->
sym != fun); rlst = rlst->
rlistnext)
1111 for (i=0, istate=0; i<rlst->nsym; i++) {
1112 s = rlst->symorder[
i];
1121 ncons = rlst->ncons;
1123 diag(
"too many solve blocks", (
char*)0);
1140 for (i=0; i < rlst->
nsym; i++) {
1146 Sprintf(
buf,
"for(_i=0;_i<%d;_i++){_slist%d[%d+_i] = (%s + _i) - _p;" 1151 Sprintf(
buf,
"for(_i=0;_i<%d;_i++){_slist%d[%d+_i] = (%s + _i) - _p[_ix];" 1156 Sprintf(
buf,
" _dlist%d[%d+_i] = (D%s + _i) - _p;}\n" 1161 Sprintf(
buf,
" _dlist%d[%d+_i] = (D%s + _i) - _p[_ix];}\n" 1172 Sprintf(
buf,
"_slist%d[%d] = &(%s) - _p[_ix];",
1177 Sprintf(
buf,
" _dlist%d[%d] = &(D%s) - _p;\n",
1182 Sprintf(
buf,
" _dlist%d[%d] = &(D%s) - _p[_ix];\n",
1195 if (standard != actual) {
1196 diag(mes,
"not allowed in this kind of block");
1232 for (q = qexp; q != qb1; q = q->
next) {
1243 for (q = qb1->
next; q != qb2; q = qs) {
1248 diag(
SYM(q)->
name,
"must be a (solved) STATE in a COMPARTMENT statement");
1271 for (q = qexp; q != qb1; q = q->
next) {
1285 for (q = qb1->
next; q != qb2; q = qs) {
1291 diag(
SYM(q)->
name,
"must be a (solved) STATE in a LONGITUDINAL_DIFFUSION statement");
1298 if (q1)
ITERATE(q1, compartlist) {
1299 Item *qexp, *qb1, *qb2, *
q;
1300 qexp =
ITM(q1); q1 = q1->
next;
1303 for (q = qb1; q != qb2; q = q->
next) {
1316 diag(
SYM(q)->
name,
"must be declared in COMPARTMENT");
1336 Item *
q, *q1, *q2, *q4;
1355 first =
insertstr(last,
"\n/*copy of previous function */\n");
1356 for (q = q1; q != q4->
next; q = q->
next) {
1364 Sprintf(
buf,
"\n#undef WANT_PRAGMA\n#define WANT_PRAGMA 1\ 1365 \n#undef _INSTANCE_LOOP\n#define _INSTANCE_LOOP \ 1366 for (_ix = _base; _ix < _bound; ++_ix) ");
1368 Sprintf(
buf,
"\n#undef _RHS%d\n#define _RHS%d(arg) \ 1369 _coef%d[arg][_ix]\n",
1370 fun->
u.
i, fun->
u.
i, fun->
u.
i);
1372 Sprintf(
buf,
"\n#undef _MATELM%d\n#define _MATELM%d(row,col) \ 1373 _jacob%d[(row)*%d + (col)][_ix]\n",
1414 if (blocktype == KINETIC &&
vectorize) {
1416 fprintf(stderr,
"Notice: Can't vectorize a kinetic block if it contains\n\ 1417 an if...else... statement.\n");
1423 static void cvode_kin_remove() {
1426 prn(kin_items_, kin_items_->
prev);
1427 prn(cvode_sbegin, cvode_send);
1431 while (
ITM(q) != q2) {
1432 assert(q2 != cvode_send);
1442 for (qq = q1; qq != q2; qq=qq->
next) {
1451 fprintf(stderr,
"%p STRING |%s|\n", q,
STR(q));
1457 fprintf(stderr,
"%p ITEM\n", q);
1471 Item*
q, *pbeg, *pend, *qnext;
1475 if (done_list)
for (q = done_list->
next; q != done_list; q = qn) {
1477 if (
SYM(q) == fun) {
1483 sprintf(
buf,
"static int _ode_spec%d() {_reset=0;{\n", fun->
u.
i);
1485 sprintf(
buf,
"static int _ode_spec%d(double* _p, Datum* _ppvar, Datum* _thread, NrnThread* _nt) {int _reset=0;{\n", fun->
u.
i);
1490 sprintf(
buf,
"static int _ode_matsol%d() {_reset=0;{\n", fun->
u.
i);
1492 sprintf(
buf,
"static int _ode_matsol%d(void* _so, double* _rhs, double* _p, Datum* _ppvar, Datum* _thread, NrnThread* _nt) {int _reset=0;{\n", fun->
u.
i);
1502 for (q = pbeg; q != pend; q = qnext) {
1505 (strcmp(
SYM(q)->
name,
"f_flux") == 0 ||
1506 strcmp(
SYM(q)->
name,
"b_flux") == 0 )) {
1513 if (strchr(
STR(q),
';')) {
1550 Item*
q, *pbeg, *pend, *qnext;
1558 if (!r1->
rterm[0]) {
1562 if (!r1->
rterm[1]) {
1566 for (i=0; i < 2; ++
i) {
1578 for (i=0; i < rlst->
nsym; ++
i) {
1579 if (rlst->
capacity[i][0] !=
'\0') {
1588 for (i=0; i<2; ++
i) {
1606 sprintf(
buf,
"static int _singlechan%d(_v, _pp, _ppd) double _v; double* _pp; Datum* _ppd;{\n\ 1607 _p = _pp; _ppvar = _ppd; v = _v; _reset=0;\n{\n", fun->
u.
i);
1614 for (q = pbeg; q != pend; q = qnext) {
1617 (strcmp(
SYM(q)->
name,
"f_flux") == 0 ||
1618 strcmp(
SYM(q)->
name,
"b_flux") == 0 )) {
1625 if (strchr(
STR(q),
';')) {
1652 sprintf(
buf,
"\nstatic _singlechan_declare%d() {\n\ 1653 _singlechan_declare(_singlechan%d, _slist%d, %d);\n\ 1655 listnum, listnum, listnum, numeqn);
1659 singlechan_=listnum;
char * stralloc(char *buf, char *rel)
void see_astmt(Item *q1, Item *q2)
void reactname(Item *q1, Item *lastok, Item *q2)
#define ITERATE(itm, lst)
Item * lappendsym(List *list, Symbol *sym)
void kinetic_implicit(Symbol *fun, char *dt, char *mname)
void massagekinetic(Item *q1, Item *q2, Item *q3, Item *q4, int sensused)
void sensmassage(int type, Item *qfun, int fn)
void kin_vect1(Item *q1, Item *q2, Item *q4)
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 List * compartlist
void massagereaction(Item *qREACTION, Item *qREACT1, Item *qlpar, Item *qcomma, Item *qrpar)
void kin_vect3(Item *q1, Item *q2, Item *q4)
void genfluxterm(Reaction *r, int type, int n)
static int sparse_declared_[10]
char * qconcat(Item *q1, Item *q2)
void single_channel(Item *qsol, Symbol *fun, int numeqn, int listnum)
void genderivterms(Reaction *r, int type, int n)
int in_solvefor(Symbol *)
int const size_t const size_t n
void kinlist(Symbol *fun, Rlist *rlst)
static Reaction * conslist
void movelist(Item *q1, Item *q2, List *s)
void check_block(int standard, int actual, char *mes)
Item * lappendstr(List *list, char *str)
Item * insertitem(Item *item, Item *itm)
void vectorize_substitute(Item *q, char *str)
static int nstate_[MAXKINBLK]
int number_states(Symbol *fun, Rlist **prlst, Rlist **pclst)
Item * linsertstr(List *list, char *str)
void vectorize_if_else_stmt(int blocktype)
fprintf(stderr, "Don't know the location of params at %p\, pp)
void cvode_kinetic(Item *qsol, Symbol *fun, int numeqn, int listnum)
void fixrlst(Rlist *rlst)
char * emalloc(unsigned n)
NMODL parser global flags / functions.
void massageldifus(Item *qexp, Item *qb1, Item *qb2, Symbol *indx)
int genconservterms(int eqnum, Reaction *r, int fn, Rlist *rlst)
Item * lappenditem(List *list, Item *item)
List * thread_cleanup_list
void genmatterms(Reaction *r, int fn)
Item * insertstr(Item *item, char *str)
void flux(Item *qREACTION, Item *qdir, Item *qlast)
void freelist(List **plist)
static int sparsedeclared(int i)
static Reaction * reactlist
void copyitems(Item *q1, Item *q2, Item *qdest)
void replacstr(Item *q, char *s)
void slist_data(Symbol *s, int indx, int findx)
void add_sens_statelist(Symbol *)
struct Reaction * reactnext
void massagecompart(Item *qexp, Item *qb1, Item *qb2, Symbol *indx)
void kinetic_intmethod(Symbol *fun, char *meth)
void massageconserve(Item *q1, Item *q3, Item *q5)
void prn(Item *q1, Item *q2)