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) {
77 if (massage_list_)
ITERATE(lq, massage_list_) {
79 diag(
"The SOLVE statement must be before the DERIVATIVE block for ",
SYM(lq)->
name);
88 strcmp(
"STEADYSTATE",
SYM(q1->
next)->name) == 0) {
94 if (strcmp(
SYM(q2)->
name,
"derivimplicit") == 0) {
97 if (strcmp(
SYM(q2)->
name,
"cnexp") == 0) {
101 cvode_cnexp_solve = lq;
116 sprintf(
buf,
"if(error){fprintf(stderr,\"%s\\n\"); nrn_complain(_p); abort_run(error);}\n",
121 "if(error){abort_run(error);}\n");
138 int numeqn, listnum, btype, steadystate;
157 if (method && strcmp(method->
name,
"after_cvode") == 0) {
162 if (method && strcmp(method->
name,
"cvode_t") == 0) {
167 if (method && strcmp(method->
name,
"cvode_v") == 0) {
186 Sprintf(
buf,
"Method %s can't be used with Block %s",
194 if (method ==
SYM0) {
195 method =
lookup(
"adrunge");
197 if (btype == BREAKPOINT && !steadystate) {
199 if (strcmp(method->
name,
"cnexp") != 0 && strcmp(method->
name,
"derivimplicit") != 0 && strcmp(method->
name,
"euler") != 0) {
200 fprintf(stderr,
"Notice: %s is not thread safe. Complain to Hines\n", method->
name);
211 if (btype == BREAKPOINT)
whileloop(qsol, (
long)
DERF, steadystate);
212 solv_diffeq(qsol, fun, method, numeqn, listnum, steadystate, btype);
215 if (method ==
SYM0) {
216 method =
lookup(
"_advance");
218 if (btype == BREAKPOINT && (method->
subtype & DERF)) {
220 fprintf(stderr,
"Notice: KINETIC is thread safe only with METHOD sparse. Complain to Hines\n");
229 if (btype == BREAKPOINT) {
230 whileloop(qsol, (
long)DERF, steadystate);
232 if (strcmp(method->
name,
"sparse") == 0) {
239 solv_diffeq(qsol, fun, method, numeqn, listnum, steadystate, btype);
243 fprintf(stderr,
"Notice: NONLINEAR is not thread safe.\n");
246 if (method ==
SYM0) {
247 method =
lookup(
"newton");
253 fprintf(stderr,
"Notice: LINEAR is not thread safe.\n");
256 if (method ==
SYM0) {
259 solv_lineq(qsol, fun, method, numeqn, listnum);
263 fprintf(stderr,
"Notice: DISCRETE is not thread safe.\n");
266 if (btype == BREAKPOINT)
whileloop(qsol, (
long)DISCRETE, 0);
273 if (btype == BREAKPOINT) {
276 if (cvodemethod_ == 1) {
279 if (cvodemethod_ == 2) {
282 cvode_nrn_cur_solve_ = fun;
285 if (cvodemethod_ == 3) {
288 cvode_nrn_current_solve_ = fun;
296 Sprintf(
buf,
"{ %s(_p, _ppvar, _thread, _nt); }\n",
304 fprintf(stderr,
"Notice: PARTIAL is not thread safe.\n");
307 if (btype == BREAKPOINT)
whileloop(qsol, (
long)DERF, 0);
311 diag(
"Illegal or unimplemented SOLVE type: ", fun->
name);
315 if (btype == BREAKPOINT) {
323 if (errstmt->
next == errstmt->
prev) {
327 fprintf(stderr,
"Notice: SOLVE with ERROR is not thread safe.\n");
340 if (btype == BREAKPOINT) {
344 Sprintf(
buf,
"_sav_indep = _p[_indepindex];\n");
386 static int called = 0, firstderf = 1;
398 for (i=0, q=indeplist->
next; i<3; i++, q=q->
next) {
402 Sprintf(sval,
"%g", (d[1]-d[0])/d[2]);
403 }
else if (type == DISCRETE) {
410 Sprintf(
buf,
"_modl_set_dt(_dt) double _dt; { %s = _dt;}\n",
417 }
else if (type == DISCRETE) {
429 if (strcmp(indepsym->
name,
"t") != 0) {
430 diag(
"The independent variable name must be `t'", (
char *)0);
433 Sprintf(
buf,
"_save = _break = %s; %s = _sav_indep;\n",
437 Sprintf(
buf,
"if (_p + _indepindex != &%s) {initmodel(_pp); %s = _sav_indep;}\n",
444 Fprintf(stderr,
"Warning: More than one integrating SOLVE statement in an \ 445 BREAKPOINT block.\nThe simulation will be incorrect if more than one is used \ 455 Sprintf(
buf,
" { int _nstep; double _dt, _y;\n\ 456 _y = _break - %s; _dt = %s;\n", indepsym->
name,
"dt");
458 Insertstr(qsol,
"_nstep = (int)(_y/_dt + .9);\n if (_nstep==0) _nstep = 1;\n");
459 Sprintf(
buf,
"%s = _y/((double)_nstep);\n",
"dt");
473 Sprintf(
buf,
"for (; %s < _break; %s += %s) {\n",
480 }
else if (type == DISCRETE) {
502 Sprintf(
buf,
" _sav_indep = %s; %s = _save;\n",
523 if (fun ==
SYM(qchk)) {
528 strcmp(
"derivimplicit", method->
name)!=0) {
529 diag(
"STEADYSTATE requires all SOLVE's of this DERIVATIVE block to use the\n\ 530 `derivimplicit' method:", fun->
name);
536 strcmp(
"sparse", method->
name) != 0)){
537 diag(
"STEADYSTATE requires all SOLVE's of this KINETIC block to use the\n\ 538 same method (`advance' or `sparse'). :", fun->
name);
542 diag(
"STEADYSTATE only valid for SOLVEing a KINETIC or DERIVATIVE block:", fun->
name);
assert(order==section_count)
char * stralloc(char *buf, char *rel)
void add_deriv_imp_list(char *name)
void solv_diffeq(Item *qsol, Symbol *fun, Symbol *method, int numeqn, int listnum, int steadystate, int btype)
#define ITERATE(itm, lst)
Item * lappendsym(List *list, Symbol *sym)
void solvequeue(Item *q1, Item *q2, int blocktype, Item *qerr)
sprintf(buf," if (secondorder) {\ " int _i;\" " for(_i=0;_i< %d;++_i) {\" " _p[_slist%d[_i]]+=dt *_p[_dlist%d[_i]];\" " }}\", numeqn, listnum, listnum)
Symbol * ifnew_parminstall(char *name, char *num, char *units, char *limits)
void single_channel(Item *qsol, Symbol *fun, int numeqn, int listnum)
void movelist(Item *q1, Item *q2, List *s)
void cvode_interface(Symbol *fun, int num, int neq)
void vectorize_substitute(Item *q, char *str)
Item * linsertstr(List *list, char *str)
fprintf(stderr, "Don't know the location of params at %p\, pp)
void cvode_kinetic(Item *qsol, Symbol *fun, int numeqn, int listnum)
NMODL parser global flags / functions.
void solv_lineq(Item *qsol, Symbol *fun, Symbol *method, int numeqn, int listnum)
void sens_nonlin_out(Item *q, Symbol *fun)
Item * insertstr(Item *item, char *str)
void freelist(List **plist)
void whileloop(Item *, long, int)
void replacstr(Item *q, char *s)
void solv_partial(Item *qsol, Symbol *fun)
void check_ss_consist(Item *)
void solv_nonlin(Item *qsol, Symbol *fun, Symbol *method, int numeqn, int listnum)