1 #include <../../nmodlconf.h>
16 extern List* nrnstate;
19 extern char* cray_pragma();
25 Item* cvode_cnexp_solve;
26 Symbol* cvode_nrn_cur_solve_;
27 Symbol* cvode_nrn_current_solve_;
62 if (blocktype == BREAKPOINT) {
80 diag(
"The SOLVE statement must be before the DERIVATIVE block for ",
SYM(lq)->
name);
94 if (strcmp(
SYM(q2)->
name,
"derivimplicit") == 0) {
97 if (strcmp(
SYM(q2)->
name,
"cnexp") == 0) {
101 cvode_cnexp_solve = lq;
117 "if(error){fprintf(stderr,\"%s\\n\"); nrn_complain(_p); abort_run(error);}\n",
121 qtemp = qerr =
insertstr(qtemp,
"if(error){abort_run(error);}\n");
137 int numeqn, listnum, btype, steadystate;
156 if (method && strcmp(method->
name,
"after_cvode") == 0) {
161 if (method && strcmp(method->
name,
"cvode_t") == 0) {
166 if (method && strcmp(method->
name,
"cvode_v") == 0) {
191 if (method ==
SYM0) {
192 method =
lookup(
"adrunge");
194 if (btype == BREAKPOINT && !steadystate) {
196 if (strcmp(method->
name,
"cnexp") != 0 &&
197 strcmp(method->
name,
"derivimplicit") != 0 &&
198 strcmp(method->
name,
"euler") != 0) {
200 "Notice: %s is not thread safe. Complain to Hines\n",
212 if (btype == BREAKPOINT)
214 solv_diffeq(qsol, fun, method, numeqn, listnum, steadystate, btype);
217 if (method ==
SYM0) {
218 method =
lookup(
"_advance");
220 if (btype == BREAKPOINT && (method->
subtype &
DERF)) {
224 "Notice: KINETIC is thread safe only with METHOD sparse. Complain to Hines\n");
233 if (btype == BREAKPOINT) {
236 if (strcmp(method->
name,
"sparse") == 0) {
243 solv_diffeq(qsol, fun, method, numeqn, listnum, steadystate, btype);
247 fprintf(stderr,
"Notice: NONLINEAR is not thread safe.\n");
250 if (method ==
SYM0) {
251 method =
lookup(
"newton");
257 fprintf(stderr,
"Notice: LINEAR is not thread safe.\n");
260 if (method ==
SYM0) {
263 solv_lineq(qsol, fun, method, numeqn, listnum);
267 fprintf(stderr,
"Notice: DISCRETE is not thread safe.\n");
270 if (btype == BREAKPOINT)
277 if (btype == BREAKPOINT) {
280 if (cvodemethod_ == 1) {
283 if (cvodemethod_ == 2) {
286 cvode_nrn_cur_solve_ = fun;
289 if (cvodemethod_ == 3) {
292 cvode_nrn_current_solve_ = fun;
307 fprintf(stderr,
"Notice: PARTIAL is not thread safe.\n");
310 if (btype == BREAKPOINT)
315 diag(
"Illegal or unimplemented SOLVE type: ", fun->
name);
319 if (btype == BREAKPOINT) {
327 if (errstmt->
next == errstmt->
prev) {
331 fprintf(stderr,
"Notice: SOLVE with ERROR is not thread safe.\n");
344 if (btype == BREAKPOINT) {
348 Sprintf(
buf,
"_sav_indep = _p[_indepindex];\n");
389 static int called = 0, firstderf = 1;
405 Sprintf(sval,
"%g", (d[1] - d[0]) / d[2]);
406 }
else if (
type == DISCRETE) {
419 }
else if (
type == DISCRETE) {
432 diag(
"The independent variable name must be `t'", (
char*) 0);
439 "if (_p + _indepindex != &%s) {initmodel(_pp); %s = _sav_indep;}\n",
448 "Warning: More than one integrating SOLVE statement in an \
449 BREAKPOINT block.\nThe simulation will be incorrect if more than one is used \
460 " { int _nstep; double _dt, _y;\n\
461 _y = _break - %s; _dt = %s;\n",
465 Insertstr(qsol,
"_nstep = (int)(_y/_dt + .9);\n if (_nstep==0) _nstep = 1;\n");
466 Sprintf(
buf,
"%s = _y/((double)_nstep);\n",
"dt");
485 }
else if (
type == DISCRETE) {
523 if (fun ==
SYM(qchk)) {
524 method =
SYM(
q->next);
525 switch (
q->itemtype) {
527 if (!method || strcmp(
"derivimplicit", method->
name) != 0) {
529 "STEADYSTATE requires all SOLVE's of this DERIVATIVE block to use the\n\
530 `derivimplicit' method:",
535 if (
SYM(qchk->
next) != method || (method && strcmp(
"sparse", method->
name) != 0)) {
537 "STEADYSTATE requires all SOLVE's of this KINETIC block to use the\n\
538 same method (`advance' or `sparse'). :",
543 diag(
"STEADYSTATE only valid for SOLVEing a KINETIC or DERIVATIVE block:",
void solv_diffeq(Item *qsol, Symbol *fun, Symbol *method, int numeqn, int listnum, int steadystate, int btype)
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 add_deriv_imp_list(char *name)
Symbol * ifnew_parminstall(char *name, char *num, char *units, char *limits)
#define ITERATE(itm, lst)
NMODL parser global flags / functions.
Item * linsertstr(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 * stralloc(char *buf, char *rel)
Item * lappendsym(List *list, Symbol *sym)
void solvequeue(Item *q1, Item *q2, int blocktype, Item *qerr)
void check_ss_consist(Item *)
void whileloop(Item *, long, int)
void solv_partial(Item *qsol, Symbol *fun)
void single_channel(Item *qsol, Symbol *fun, int numeqn, int listnum)
void vectorize_substitute(Item *q, char *str)
void sens_nonlin_out(Item *q, Symbol *fun)
void cvode_kinetic(Item *qsol, Symbol *fun, int numeqn, int listnum)
void cvode_interface(Symbol *fun, int num, int neq)
void solv_lineq(Item *qsol, Symbol *fun, Symbol *method, int numeqn, int listnum)
void solv_nonlin(Item *qsol, Symbol *fun, Symbol *method, int numeqn, int listnum)
static double remove(void *v)