NEURON
cout.cpp
Go to the documentation of this file.
1 #include <../../nmodlconf.h>
2 /* /local/src/master/nrn/src/nmodl/cout.c,v 4.1 1997/08/30 20:45:16 hines Exp */
3 /*
4 cout.c,v
5  * Revision 4.1 1997/08/30 20:45:16 hines
6  * cvs problem with branches. Latest nmodl stuff should now be a top level
7  *
8  * Revision 4.0.1.1 1997/08/08 17:23:39 hines
9  * nocmodl version 4.0.1
10  *
11  * Revision 4.0 1997/08/08 17:06:04 hines
12  * proper nocmodl version number
13  *
14  * Revision 1.1.1.1 1994/10/12 17:21:34 hines
15  * NEURON 3.0 distribution
16  *
17  * Revision 9.170 93/05/17 11:06:36 hines
18  * PI defined by some <math.h> so undefing it
19  *
20  * Revision 9.158 93/02/02 10:32:17 hines
21  * create static func before usage
22  *
23  * Revision 9.157 93/02/01 15:17:09 hines
24  * static functions should be declared before use.
25  * inline is keyword for some compilers.
26  *
27  * Revision 9.154 92/11/10 11:52:16 hines
28  * when compiling a translated model on the CRAY (with _CRAY defined as 1)
29  * the check table functions are taken out of the loops. This is
30  * not entirely safe if tables are used (and dependencies have changed)
31  * in direct calls to functions that call functions with tables. It is
32  * reasonably safe for finitialize(), fadvance(), fcurrent(), and
33  * calling the hoc_function itself.
34  *
35  * Revision 9.147 92/09/27 17:45:43 hines
36  * vectorized channel densities with _method3 fill thisnode.GC,EC instead
37  * of rhs,d
38  *
39  * Revision 9.144 92/08/06 09:57:51 hines
40  * put cray pragmas at appropriate places
41  * get rid of initmodel references to saveing t and incrementing ninit
42  *
43  * Revision 9.142 92/08/05 16:22:43 hines
44  * can vectorize hh. need work on tables though.
45  *
46  * Revision 9.140 92/07/27 11:33:06 hines
47  * some bugs fixed. no vectorizing except for SOLVE procedure (and that not done yet)
48  *
49  * Revision 9.139 92/07/27 10:11:21 hines
50  * Can do some limited vectorization. Much remains. Often fails
51  *
52  * Revision 9.133 92/03/19 15:14:20 hines
53  * creates a nrn_initialize function that will be called from finitialize().
54  *
55  * Revision 9.128 92/02/05 14:47:46 hines
56  * saber warning free
57  * FUNCTION made global for use by other models. #define GLOBFUNC 1
58  *
59  * Revision 9.122 91/10/28 09:09:24 hines
60  * wathey's improvements. different binary architectures in different
61  * directories.
62  *
63  * Revision 9.92 91/01/03 07:54:43 hines
64  * nparout.c version comment moved to beginning of file
65  *
66  * Revision 9.89 90/12/14 15:43:33 hines
67  * nmodl: point process working with proper current dimensions. tested with
68  * stim.mod and pascab1.hoc
69  *
70  * Revision 9.83 90/12/12 09:01:51 hines
71  * nmodl: nparout allocates the p-array
72  *
73  * Revision 9.73 90/12/04 11:59:50 hines
74  * model version displayed only as comment in generated c file
75  * format of plot lines for scalar in .var file is
76  * name nl vindex pindex 1 nl
77  * for vector with specific index:
78  * name[index] vindex pindex 1
79  * for vector without index
80  * name[size] vindex pindex size
81  *
82  * Revision 9.72 90/11/30 13:09:35 hines
83  * dcurdv calculated for ionic currents.
84  *
85  * Revision 9.71 90/11/30 08:22:04 hines
86  * modl_set_dt should only be created for time dependent models
87  *
88  * Revision 9.70 90/11/28 15:34:53 hines
89  * much work on case when ion is a state
90  *
91  * Revision 9.61 90/11/23 10:01:14 hines
92  * STEADYSTATE of kinetic and derivative blocks
93  *
94  * Revision 9.53 90/11/13 13:09:08 hines
95  * nmodl: cachan works pretty well. ions generating current works.
96  *
97  * Revision 9.52 90/11/10 15:44:50 hines
98  * nmodl: uses new NEURON { USEION ... format
99  * passive.c works
100  *
101  * Revision 9.46 90/10/30 14:27:25 hines
102  * calc_dt is gone. Not needed because due to scopfit, dt needs to be
103  * calculated at every break point.
104  * _reset no longer used to say that dt has changed. The integrator will
105  * have to check that itself.
106  *
107  * Revision 9.45 90/10/30 13:55:45 hines
108  * derivative blocks (this impacts kinetic and sens as well) now return
109  * _reset which can be set with RESET statement. _reset is static in the
110  * file and set to 0 on entry to a derivative or kinetic block.
111  *
112  * Revision 9.41 90/10/30 08:36:37 hines
113  * saber warning free except for ytab.c and lex.cpp
114  *
115  * Revision 9.40 90/10/30 08:06:00 hines
116  * nmodl: Passive.mod working with index vectors. No longer copying
117  * doubles. Just copying two pointers.
118  *
119  * Revision 9.35 90/10/15 12:12:53 hines
120  * mistake with checkin
121  *
122  * Revision 9.33 90/10/11 15:44:34 hines
123  * bugs fixed with respect to conversion from pointer vector to index vector.
124  *
125  * Revision 9.32 90/10/08 14:12:15 hines
126  * index vector instead of pointer vector for slist and dlist
127  *
128  * Revision 9.31 90/10/08 11:33:45 hines
129  * simsys prototype
130  *
131  * Revision 9.18 90/08/07 15:35:44 hines
132  * computation of rhs was bad
133  *
134  * Revision 9.16 90/08/02 08:58:02 hines
135  * NMODL can use more than one mechanism. Integrators that use ninits and
136  * reset will not work, though.
137  *
138  * Revision 9.14 90/07/31 17:03:03 hines
139  * NMODL getting close. Compiles but multiple .mod files cause
140  * multiple definitions.
141  *
142  * Revision 9.13 90/07/30 14:36:40 hines
143  * NMODL looks pretty good. Ready to start testing. Have not yet tried
144  * to compile the .c file.
145  *
146  * Revision 9.11 90/07/30 11:50:43 hines
147  * NMODL getting better, almost done
148  *
149  * Revision 9.5 90/07/18 07:58:00 hines
150  * define for arrays now (p + n) instead of &p[n]. This allows the c file
151  * to have arrays that look like a[i] instead of *(a + i).
152  *
153  * Revision 8.9 90/04/03 07:44:29 mlh
154  * for turbo-c defs.h stuff must appear after inclusion of scoplib.h
155  * This is done by now saving defs.h stuff in defs_list and printing
156  * it in cout.c. Note that each item is type VERBATIM so that there
157  * is no prepended space.
158  *
159  * Revision 8.8 90/02/15 10:09:26 mlh
160  * defs.h removed. Those defines now come from parout()
161  *
162  * Revision 8.7 90/01/16 11:05:43 mlh
163  * error checking and cleanup after error and call to abort_run()
164  *
165  * Revision 8.6 89/11/21 07:36:19 mlh
166  * _calc_dt used in scopcore and therefore must be declared even for
167  * time independent models.
168  *
169  * Revision 8.5 89/11/17 16:07:45 mlh
170  * _ninits tells how many times initmodel() is called. Used by
171  * scopmath routines that need to know when to self_initialize.
172  *
173  * Revision 8.4 89/11/17 14:53:57 nfh
174  * Changed modl_version string printed by SCoP to read: "Language version..."
175  *
176  * Revision 8.3 89/11/14 16:37:20 mlh
177  * _reset set to true whenever initmodel is called and whenever _calc_dt
178  * is true
179  *
180  * Revision 8.2 89/10/11 08:42:33 mlh
181  * _reset apparently being declared elsewhere
182  *
183  * Revision 8.1 89/10/11 08:34:19 mlh
184  * generate modl_version string in .c file
185  * declare _reset=1
186  *
187  * Revision 8.0 89/09/22 17:26:00 nfh
188  * Freezing
189  *
190  * Revision 7.1 89/09/07 07:44:51 mlh
191  * was failing to initialize time after match
192  * many bugs in handling exact for loop of t to the break point
193  *
194  * Revision 7.0 89/08/30 13:31:25 nfh
195  * Rev 7 is now Experimental; Rev 6 is Testing
196  *
197  * Revision 6.0 89/08/14 16:26:11 nfh
198  * Rev 6.0 is latest of 4.x; now the Experimental version
199  *
200  * Revision 4.0 89/07/24 17:02:39 nfh
201  * Freezing rev 3. Rev 4 is now Experimental
202  *
203  * Revision 3.2 89/07/18 11:54:02 mlh
204  * first_time removed and MODEL_LEVEL used for declaration precedence
205  *
206  * Revision 1.2 89/07/18 11:21:54 mlh
207  * eliminate first_time, etc.
208  *
209  * Revision 1.1 89/07/06 14:47:30 mlh
210  * Initial revision
211  *
212 */
213 
214 /* print the .c file from the lists */
215 
216 #include "modl.h"
217 #include "parse1.hpp"
218 #include "symbol.h"
219 
220 #define P(arg) fputs(arg, fcout)
222 /* firstlist gets statements that must go before anything else */
223 
224 #if NMODL
225 List* nrnstate;
226 extern List *currents, *set_ion_variables(int), *get_ion_variables(int);
227 extern List *begin_dion_stmt(), *end_dion_stmt(char*);
228 #endif
229 
230 extern Symbol* indepsym;
231 extern List* indeplist;
232 extern List* match_bound;
233 extern List* defs_list;
234 extern char* saveindep;
235 extern char* RCS_version;
236 extern char* RCS_date;
237 char* modelline;
238 
239 #if VECTORIZE
240 extern int vectorize;
241 static List* vectorize_replacements; /* pairs of item pointer, strings */
242 extern char* cray_pragma();
243 #endif
244 
245 #if __TURBOC__ || SYSV || VMS
246 #define index strchr
247 #endif
248 
249 static void initstates();
250 static void funcdec();
251 
252 void c_out() {
253 #if NMODL
254  Item* q;
255  extern int point_process;
256 #endif
257 
258 #if VECTORIZE
259  if (vectorize) {
261  c_out_vectorize();
262  return;
263  }
264 #endif
265  Fprintf(fcout, "/* Created by Language version: %s of %s */\n", RCS_version, RCS_date);
266 #if VECTORIZE
267  P("/* NOT VECTORIZED */\n");
268 #endif
269  Fflush(fcout);
270  /* things which must go first and most declarations */
271 #if SIMSYS
272  P("#include <stdio.h>\n#include <math.h>\n#include \"mathlib.h\"\n");
273  P("#include \"common.h\"\n#include \"softbus.h\"\n");
274  P("#include \"sbtypes.h\"\n#include \"Solver.h\"\n");
275 #else
276  P("#include <stdio.h>\n#include <math.h>\n#include \"mech_api.h\"\n");
277  P("#undef PI\n");
278 #endif
281  RCS_version[strlen(RCS_version) - 2] = '\0';
282  RCS_date[strlen(RCS_date) - 11] = '\0';
283  RCS_version = index(RCS_version, ':') + 2;
284  RCS_date = index(RCS_date, ':') + 2;
285  P("static int _reset;\n");
286 #if NMODL
287  P("static ");
288 #endif
289  if (modelline) {
290  Fprintf(fcout, "char *modelname = \"%s\";\n\n", modelline);
291  } else {
292  Fprintf(fcout, "char *modelname = \"\";\n\n");
293  }
294  Fflush(fcout); /* on certain internal errors partial output
295  * is helpful */
296  P("static int error;\n");
297 #if NMODL
298  P("static ");
299 #endif
300  P("int _ninits = 0;\n");
301  P("static int _match_recurse=1;\n");
302 #if NMODL
303  P("static ");
304 #endif
305  P("_modl_cleanup(){ _match_recurse=1;}\n");
306  /*
307  * many machinations are required to make the infinite number of
308  * definitions involving _p in defs.h to be invisible to the user
309  */
310  /*
311  * This one allows scop variables in functions which do not have the
312  * p array as an argument
313  */
314 #if SIMSYS || HMODL || NMODL
315 #else
316  P("static double *_p;\n\n");
317 #endif
318  funcdec();
319  Fflush(fcout);
320 
321  /*
322  * translations of named blocks into functions, procedures, etc. Also
323  * some special declarations used by some blocks
324  */
326  Fflush(fcout);
327 
328  /* Initialization function must always be present */
329 #if NMODL
330  P("\nstatic initmodel() {\n int _i; double _save;");
331 #endif
332 #if SIMSYS || HMODL
333  P("\ninitmodel() {\n int _i; double _save;");
334 #endif
335 #if (!(SIMSYS || HMODL || NMODL))
336  P("\ninitmodel(_pp) double _pp[]; {\n int _i; double _save; _p = _pp;");
337 #endif
338 #if !NMODL
339  P("_initlists();\n");
340 #endif
341  P("_ninits++;\n");
342  P(saveindep); /*see solve.c; blank if not a time dependent process*/
343  P("{\n");
344  initstates();
346  if (match_bound) {
347  P("\n_init_match(_save);");
348  }
349  P("\n}\n}\n");
350  Fflush(fcout);
351 
352 #if NMODL
353  /* generation of initmodel interface */
354 #if VECTORIZE
355  P("\nstatic nrn_init(_pp, _ppd, _v) double *_pp, _v; Datum* _ppd; {\n");
356  P(" _p = _pp; _ppvar = _ppd;\n");
357 #else
358  P("\nstatic nrn_init(_prop, _v) Prop *_prop; double _v; {\n");
359  P(" _p = _prop->param; _ppvar = _prop->dparam;\n");
360 #endif
361  P(" v = _v;\n");
363  P(" initmodel();\n");
365  P("}\n");
366 
367  /* standard modl EQUATION without solve computes current */
368  P("\nstatic double _nrn_current(_v) double _v;{double _current=0.;v=_v;{");
369  if (currents->next != currents) {
371  }
372  ITERATE(q, currents) {
373  Sprintf(buf, " _current += %s;\n", SYM(q)->name);
374  P(buf);
375  }
376  P("\n} return _current;\n}\n");
377 
378  /* the neuron current also has to compute the dcurrent/dv as well
379  as make sure all currents accumulated properly (currents list) */
380 #if VECTORIZE
381  P("\nstatic double nrn_cur(_pp, _ppd, _pdiag, _v) double *_pp, *_pdiag, _v; Datum* _ppd; {\n");
382 #else
383  P("\nstatic double nrn_cur(_prop, _pdiag, _v) Prop *_prop; double *_pdiag, _v;{\n");
384 #endif
385  if (currents->next != currents) {
386  P(" double _g, _rhs;\n");
387 #if VECTORIZE
388  P(" _p = _pp; _ppvar = _ppd;\n");
389 #else
390  P(" _p = _prop->param; _ppvar = _prop->dparam;\n");
391 #endif
393  P(" _g = _nrn_current(_v + .001);\n");
395  P(" _rhs = _nrn_current(_v);\n");
396  printlist(end_dion_stmt(".001"));
397  P(" _g = (_g - _rhs)/.001;\n");
398  /* set the ion variable values */
400  if (point_process) {
401  P(" *_pdiag += _g * 1.e2/(_nd_area);\n return (_rhs - _g*_v) * 1.e2/(_nd_area);\n}\n");
402  } else {
403  P(" *_pdiag += _g;\n return _rhs - _g*_v;\n}\n");
404  }
405  } else {
406  P(" return 0.;\n}\n");
407  }
408 
409  /* nrnstate list contains the EQUATION solve statement so this
410  advances states by dt */
411 #if VECTORIZE
412  P("\nstatic nrn_state(_pp, _ppd, _v) double *_pp, _v; Datum* _ppd; {\n");
413 #else
414  P("\nstatic nrn_state(_prop, _v) Prop *_prop; double _v; {\n");
415 #endif
416  if (nrnstate || currents->next == currents) {
417  P(" double _break, _save;\n");
418 #if VECTORIZE
419  P(" _p = _pp; _ppvar = _ppd;\n");
420 #else
421  P(" _p = _prop->param; _ppvar = _prop->dparam;\n");
422 #endif
423  P(" _break = t + .5*dt; _save = t; delta_t = dt;\n");
424  P(" v=_v;\n{\n");
426  if (nrnstate) {
427  printlist(nrnstate);
428  }
429  if (currents->next == currents) {
431  }
433  P("\n}");
434  }
435  P("\n}\n");
436 #else
437  /* Model function must always be present */
438 #if SIMSYS
439  P("\nmodel() {\n");
440  P("double _break, _save;\n{\n");
441 #else
442  P("\nmodel(_pp, _indepindex) double _pp[]; int _indepindex; {\n");
443  P("double _break, _save;");
444 #if HMODL
445  P("\n{\n");
446 #else
447  P("_p = _pp;\n{\n");
448 #endif
449 #endif
451  P("\n}\n}\n");
452  Fflush(fcout);
453 #endif
454 
455 #if NMODL
456  P("\nstatic terminal(){}\n");
457 #else
458  /* Terminal function must always be present */
459 #if SIMSYS || HMODL
460  P("\nterminal() {");
461  P("\n{\n");
462 #else
463  P("\nterminal(_pp) double _pp[];{");
464  P("_p = _pp;\n{\n");
465 #endif
467  P("\n}\n}\n");
468  Fflush(fcout);
469 #endif
470 
471  /* initlists() is called once to setup slist and dlist pointers */
472 #if NMODL || SIMSYS || HMODL
473  P("\nstatic _initlists() {\n");
474 #else
475  P("\n_initlists() {\n");
476 #endif
477  P(" int _i; static int _first = 1;\n");
478  P(" if (!_first) return;\n");
480  P("_first = 0;\n}\n");
481 }
482 
483 /*
484  * One of the things initmodel() must do is initialize all states to the
485  * value of state0. This generated code goes before any explicit initialize
486  * code written by the user.
487  */
488 static void initstates() {
489  int i;
490  Item* qs;
491  Symbol* s;
492 
493  SYMITER_STAT {
494  Sprintf(buf, "%s0", s->name);
495  if (lookup(buf)) { /* if no constant associated
496  * with a state such as the
497  * ones automattically
498  * generated by SENS then
499  * there is no initialization
500  * line */
501  if (s->subtype & ARRAY) {
502  Fprintf(fcout,
503  " for (_i=0; _i<%d; _i++) %s[_i] = %s0;\n",
504  s->araydim,
505  s->name,
506  s->name);
507  } else {
508  Fprintf(fcout, " %s = %s0;\n", s->name, s->name);
509  }
510  }
511  }
512 }
513 
514 /*
515  * here is the only place as of 18-apr-89 where we don't explicitly know the
516  * type of a list element
517  */
518 
519 void printlist(List* s) {
520  Item* q;
521  int newline = 0, indent = 0, i;
522 
523  /*
524  * most of this is merely to decide where newlines and indentation
525  * goes so that the .c file can be read if something goes wrong
526  */
527  if (!s) {
528  return;
529  }
530  ITERATE(q, s) {
531  if (q->itemtype == SYMBOL) {
532  if (SYM(q)->type == SPECIAL) {
533  switch (SYM(q)->subtype) {
534  case SEMI:
535  newline = 1;
536  break;
537  case BEGINBLK:
538  newline = 1;
539  indent++;
540  break;
541  case ENDBLK:
542  newline = 1;
543  indent--;
544  break;
545  }
546  }
547  Fprintf(fcout, " %s", SYM(q)->name);
548  } else if (q->itemtype == VERBATIM) {
549  Fprintf(fcout, "%s", STR(q));
550  } else {
551  Fprintf(fcout, " %s", STR(q));
552  }
553  if (newline) {
554  newline = 0;
555  Fprintf(fcout, "\n");
556  for (i = 0; i < indent; i++) {
557  Fprintf(fcout, " ");
558  }
559  }
560  }
561 }
562 
563 static void funcdec() {
564  int i;
565  Symbol* s;
566  List* qs;
567 
568  SYMITER(NAME) {
569  /*EMPTY*/ /*maybe*/
570  if (s->subtype & FUNCT) {
571 #define GLOBFUNCT 1
572 #if GLOBFUNCT && NMODL
573 #else
574  Fprintf(fcout, "static double %s();\n", s->name);
575 #endif
576  }
577  if (s->subtype & PROCED) {
578  Fprintf(fcout, "static %s();\n", s->name);
579  }
580  }
581 }
582 
583 #if VECTORIZE
584 void c_out_vectorize() {
585  Item* q;
586  extern int point_process;
587 
588  Fprintf(fcout, "/* Created by Language version: %s of %s */\n", RCS_version, RCS_date);
589  Fflush(fcout);
590  /* things which must go first and most declarations */
591  P("/* VECTORIZED */\n");
592  P("#include <stdio.h>\n#include <math.h>\n#include \"mech_api.h\"\n");
593  P("#undef PI\n");
596  RCS_version[strlen(RCS_version) - 2] = '\0';
597  RCS_date[strlen(RCS_date) - 11] = '\0';
598  RCS_version = index(RCS_version, ':') + 2;
599  RCS_date = index(RCS_date, ':') + 2;
600  P("static int _reset;\n");
601  if (modelline) {
602  Fprintf(fcout, "static char *modelname = \"%s\";\n\n", modelline);
603  } else {
604  Fprintf(fcout, "static char *modelname = \"\";\n\n");
605  }
606  Fflush(fcout); /* on certain internal errors partial output
607  * is helpful */
608  P("static int error;\n");
609  P("static int _ninits = 0;\n");
610  P("static int _match_recurse=1;\n");
611  P("static _modl_cleanup(){ _match_recurse=1;}\n");
612 
613  funcdec();
614  Fflush(fcout);
615 
616  /*
617  * translations of named blocks into functions, procedures, etc. Also
618  * some special declarations used by some blocks
619  */
621  Fflush(fcout);
622 
623  /* Initialization function must always be present */
624 
625  P("\nstatic initmodel(_ix) int _ix; {\n int _i; double _save;");
626 
627 #if 0
628  P("_initlists(_ix);\n");
629  P("_ninits++;\n");
630  P(saveindep); /*see solve.c; blank if not a time dependent process*/
631 #endif
632  P("{\n");
633  initstates();
635  if (match_bound) {
636  assert(!vectorize);
637  P("\n_init_match(_save);");
638  }
639  P("\n}\n}\n");
640  Fflush(fcout);
641 
642  /* generation of initmodel interface */
643  P("\nstatic nrn_init(_count, _nodes, _data, _pdata)\n");
644  P(" int _count; Node** _nodes; double** _data; Datum** _pdata;\n");
645  P("{ int _ix;\n");
646  P(" _p = _data; _ppvar = _pdata;\n");
647  check_tables();
648  P(cray_pragma());
649  P(" for (_ix = 0; _ix < _count; ++_ix) {\n");
650  P(" v = _nodes[_ix]->_v;\n");
652  P(" initmodel(_ix);\n");
654  P(" }\n");
655  P("}\n");
656 
657  /* standard modl EQUATION without solve computes current */
658  P("\nstatic double _nrn_current(_ix, _v) int _ix; double _v;{\n double _current=0.;v=_v;\n {");
659  if (currents->next != currents) {
661  }
662  ITERATE(q, currents) {
663  Sprintf(buf, " _current += %s;\n", SYM(q)->name);
664  P(buf);
665  }
666  P("\n} return _current;\n}\n");
667 
668 
669  /* the neuron current also has to compute the dcurrent/dv as well
670  as make sure all currents accumulated properly (currents list) */
671  P("\nstatic double nrn_cur(_count, _nodes, _data, _pdata)\n");
672  P(" int _count; Node** _nodes; double** _data; Datum** _pdata;\n");
673  P("{\n");
674  if (currents->next != currents) {
675  P("int _ix;\n");
676  P(" _p = _data; _ppvar = _pdata;\n");
677  check_tables();
678 
679  P("\n#if METHOD3\n if (_method3) {\n");
680  /*--- reprduction of normal with minor changes ---*/
681  P(cray_pragma());
682  P(" for (_ix = 0; _ix < _count; ++_ix) {\n");
683  P(" double _g, _rhs, _v;\n");
684  P(" _v = _nodes[_ix]->_v;\n");
686  P(" _g = _nrn_current(_ix, _v + .001);\n");
688  P("\n _rhs = _nrn_current(_ix, _v);\n");
689  printlist(end_dion_stmt(".001"));
690  P(" _g = (_g - _rhs)/.001;\n");
691  /* set the ion variable values */
693  if (point_process) {
694  P(" _nodes[_ix]->_d += _g * 1.e2/(_nd_area);\n");
695  P(" _nodes[_ix]->_rhs += (_g*_v - _rhs) * 1.e2/(_nd_area);\n");
696  } else {
697  P(" _nodes[_ix]->_thisnode._GC += _g;\n");
698  P(" _nodes[_ix]->_thisnode._EC += (_g*_v - _rhs);\n");
699  }
700  P(" }\n");
701  /*-------------*/
702  P("\n }else\n#endif\n {\n");
703 
704  /*--- normal ---*/
705  P(cray_pragma());
706  P(" for (_ix = 0; _ix < _count; ++_ix) {\n");
707  P(" double _g, _rhs, _v;\n");
708  P(" _v = _nodes[_ix]->_v;\n");
710  P(" _g = _nrn_current(_ix, _v + .001);\n");
712  P("\n _rhs = _nrn_current(_ix, _v);\n");
713  printlist(end_dion_stmt(".001"));
714  P(" _g = (_g - _rhs)/.001;\n");
715  /* set the ion variable values */
717  if (point_process) {
718  P(" _nodes[_ix]->_d += _g * 1.e2/(_nd_area);\n");
719  P(" _nodes[_ix]->_rhs += (_g*_v - _rhs) * 1.e2/(_nd_area);\n");
720  } else {
721  P(" _nodes[_ix]->_d += _g;\n");
722  P(" _nodes[_ix]->_rhs += (_g*_v - _rhs);\n");
723  }
724  P(" }\n");
725  /*------------*/
726 
727  P(" }\n");
728  }
729  P(" return 0.;\n}\n");
730 
731  /* nrnstate list contains the EQUATION solve statement so this
732  advances states by dt */
733 
734  P("\nstatic nrn_state(_count, _nodes, _data, _pdata)\n");
735  P(" int _count; Node** _nodes; double** _data; Datum** _pdata;\n");
736  P("{\n");
737  if (nrnstate || currents->next == currents) {
738  P(" int _ix;\n");
739  P(" double _break, _save;\n");
740  P(" _p = _data; _ppvar = _pdata;\n");
741  check_tables();
742  P(" _break = t + .5*dt; _save = t; delta_t = dt;\n");
743 
744  P(cray_pragma());
745  P(" for (_ix = 0; _ix < _count; ++_ix) {\n");
746  P(" v = _nodes[_ix]->_v;\n");
748  P(" }\n");
749 
750  P("\n{\n");
751  if (nrnstate) {
752  printlist(nrnstate);
753  }
754  P("}\n");
755  P(cray_pragma());
756  P(" for (_ix = 0; _ix < _count; ++_ix) {\n");
757  if (currents->next == currents) {
759  }
761  P(" }\n");
762  }
763  P("}\n");
764  Fflush(fcout);
765 
766  P("\nstatic terminal(){}\n");
767 
768  /* vectorized: data must have own copies of slist and dlist
769  for now we don't vectorize if slist or dlist exists. Eventually
770  must separate initialization of static things from vectorized
771  things.
772  */
773  /* initlists() is called once to setup slist and dlist pointers */
774  P("\nstatic _initlists(){\n");
775  P(" int _i; static int _first = 1;\n");
776  P(" if (!_first) return;\n");
778  P("_first = 0;\n}\n");
779 }
780 
781 void vectorize_substitute(Item* q, char* str) {
782  if (!vectorize_replacements) {
783  vectorize_replacements = newlist();
784  }
785  lappenditem(vectorize_replacements, q);
786  lappendstr(vectorize_replacements, str);
787 }
788 
790  Item *q, *q1;
791  if (vectorize_replacements) {
792  ITERATE(q, vectorize_replacements) {
793  q1 = ITM(q);
794  q = q->next;
795  replacstr(q1, STR(q));
796  }
797  }
798 }
799 
800 char* cray_pragma() {
801  static char buf[] =
802  "\
803 \n#if _CRAY\
804 \n#pragma _CRI ivdep\
805 \n#endif\
806 \n";
807  return buf;
808 }
809 
810 #endif /*VECTORIZE*/
short index
Definition: cabvars.h:10
short type
Definition: cabvars.h:9
static void funcdec()
Definition: cout.cpp:563
List * initfunc
Definition: cout.cpp:221
List * procfunc
Definition: cout.cpp:221
List * match_bound
Definition: deriv.cpp:729
#define P(arg)
Definition: cout.cpp:220
List * indeplist
Definition: parsact.cpp:15
List * defs_list
Definition: nocpout.cpp:124
char * RCS_version
Definition: version.cpp:4
List * firstlist
Definition: cout.cpp:221
char * RCS_date
Definition: version.cpp:5
void c_out()
Definition: cout.cpp:252
static void initstates()
Definition: cout.cpp:488
List * initlist
Definition: cout.cpp:221
char * saveindep
Definition: solve.cpp:373
List * termfunc
Definition: cout.cpp:221
char * modelline
Definition: cout.cpp:237
Symbol * indepsym
Definition: declare.cpp:11
List * modelfunc
Definition: cout.cpp:221
void printlist(List *s)
Definition: cout.cpp:519
char buf[512]
Definition: init.cpp:13
#define assert(ex)
Definition: hocassrt.h:32
#define i
Definition: md1redef.h:12
FILE * fcout
Definition: model.cpp:35
#define STR(q)
Definition: model.h:87
#define FUNCT
Definition: model.h:119
#define ITERATE(itm, lst)
Definition: model.h:25
#define ENDBLK
Definition: model.h:124
#define SYMBOL
Definition: model.h:102
#define Fflush
Definition: model.h:236
#define SPECIAL
Definition: model.h:100
#define ITM(q)
Definition: model.h:88
#define SYM(q)
Definition: model.h:86
#define Sprintf
Definition: model.h:233
#define BEGINBLK
Definition: model.h:123
#define SEMI
Definition: model.h:122
#define ARRAY
Definition: model.h:118
#define PROCED
Definition: model.h:120
#define Fprintf
Definition: model.h:234
NMODL parser global flags / functions.
char * name
Definition: init.cpp:16
long subtype
Definition: init.cpp:215
Item * lappendstr(List *list, char *str)
Definition: list.cpp:134
void replacstr(Item *q, char *s)
Definition: list.cpp:225
List * newlist()
Definition: list.cpp:47
Item * lappenditem(List *list, Item *item)
Definition: list.cpp:146
#define SYMITER(arg1)
Definition: symbol.h:13
#define SYMITER_STAT
Definition: symbol.h:22
int vectorize
void c_out_vectorize(const char *)
void vectorize_substitute(Item *q, char *str)
void vectorize_do_substitute()
void check_tables()
Definition: parsact.cpp:547
static int newline
Definition: noccout.cpp:520
static int indent
Definition: noccout.cpp:520
List * get_ion_variables(int)
Definition: nocpout.cpp:2122
List * currents
Definition: nocpout.cpp:140
List * begin_dion_stmt()
Definition: nocpout.cpp:2310
List * set_ion_variables(int)
Definition: nocpout.cpp:2049
List * end_dion_stmt(char *strdel)
Definition: nocpout.cpp:2334
size_t q
static int point_process
Definition: nrnunit.cpp:11
#define lookup
Definition: redef.h:90
Definition: model.h:15
struct Item * next
Definition: model.h:19
Definition: model.h:57
int araydim
Definition: model.h:67
long subtype
Definition: model.h:59
char * name
Definition: model.h:72