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 {
254 #if NMODL
255  Item *q;
256  extern int point_process;
257 #endif
258 
259 #if VECTORIZE
260  if (vectorize) {
262  c_out_vectorize();
263  return;
264  }
265 #endif
266  Fprintf(fcout, "/* Created by Language version: %s of %s */\n",
268 #if VECTORIZE
269  P("/* NOT VECTORIZED */\n");
270 #endif
271  Fflush(fcout);
272  /* things which must go first and most declarations */
273 #if SIMSYS
274  P("#include <stdio.h>\n#include <math.h>\n#include \"mathlib.h\"\n");
275  P("#include \"common.h\"\n#include \"softbus.h\"\n");
276  P("#include \"sbtypes.h\"\n#include \"Solver.h\"\n");
277 #else
278  P("#include <stdio.h>\n#include <math.h>\n#include \"scoplib.h\"\n");
279  P("#undef PI\n");
280 #endif
281  printlist(defs_list);
282  printlist(firstlist);
283  RCS_version[strlen(RCS_version) - 2] = '\0';
284  RCS_date[strlen(RCS_date) - 11] = '\0';
285  RCS_version = index(RCS_version, ':') + 2;
286  RCS_date = index(RCS_date, ':') + 2;
287  P("static int _reset;\n");
288 #if NMODL
289  P("static ");
290 #endif
291  if (modelline) {
292  Fprintf(fcout, "char *modelname = \"%s\";\n\n", modelline);
293  } else {
294  Fprintf(fcout, "char *modelname = \"\";\n\n");
295  }
296  Fflush(fcout); /* on certain internal errors partial output
297  * is helpful */
298  P("static int error;\n");
299 #if NMODL
300  P("static ");
301 #endif
302  P("int _ninits = 0;\n");
303  P("static int _match_recurse=1;\n");
304 #if NMODL
305  P("static ");
306 #endif
307  P("_modl_cleanup(){ _match_recurse=1;}\n");
308  /*
309  * many machinations are required to make the infinite number of
310  * definitions involving _p in defs.h to be invisible to the user
311  */
312  /*
313  * This one allows scop variables in functions which do not have the
314  * p array as an argument
315  */
316 #if SIMSYS || HMODL || NMODL
317 #else
318  P("static double *_p;\n\n");
319 #endif
320  funcdec();
321  Fflush(fcout);
322 
323  /*
324  * translations of named blocks into functions, procedures, etc. Also
325  * some special declarations used by some blocks
326  */
327  printlist(procfunc);
328  Fflush(fcout);
329 
330  /* Initialization function must always be present */
331 #if NMODL
332  P("\nstatic initmodel() {\n int _i; double _save;");
333 #endif
334 #if SIMSYS || HMODL
335  P("\ninitmodel() {\n int _i; double _save;");
336 #endif
337 #if (!(SIMSYS || HMODL || NMODL))
338  P("\ninitmodel(_pp) double _pp[]; {\n int _i; double _save; _p = _pp;");
339 #endif
340 #if !NMODL
341  P("_initlists();\n");
342 #endif
343  P("_ninits++;\n");
344  P(saveindep); /*see solve.c; blank if not a time dependent process*/
345  P("{\n");
346  initstates();
347  printlist(initfunc);
348  if (match_bound) {
349  P("\n_init_match(_save);");
350  }
351  P("\n}\n}\n");
352  Fflush(fcout);
353 
354 #if NMODL
355  /* generation of initmodel interface */
356 #if VECTORIZE
357  P("\nstatic nrn_init(_pp, _ppd, _v) double *_pp, _v; Datum* _ppd; {\n");
358  P(" _p = _pp; _ppvar = _ppd;\n");
359 #else
360  P("\nstatic nrn_init(_prop, _v) Prop *_prop; double _v; {\n");
361  P(" _p = _prop->param; _ppvar = _prop->dparam;\n");
362 #endif
363  P(" v = _v;\n");
365  P(" initmodel();\n");
367  P("}\n");
368 
369  /* standard modl EQUATION without solve computes current */
370  P("\nstatic double _nrn_current(_v) double _v;{double _current=0.;v=_v;{");
371  if (currents->next != currents) {
372  printlist(modelfunc);
373  }
374  ITERATE(q, currents) {
375  Sprintf(buf, " _current += %s;\n", SYM(q)->name);
376  P(buf);
377  }
378  P("\n} return _current;\n}\n");
379 
380  /* the neuron current also has to compute the dcurrent/dv as well
381  as make sure all currents accumulated properly (currents list) */
382 #if VECTORIZE
383  P("\nstatic double nrn_cur(_pp, _ppd, _pdiag, _v) double *_pp, *_pdiag, _v; Datum* _ppd; {\n");
384 #else
385  P("\nstatic double nrn_cur(_prop, _pdiag, _v) Prop *_prop; double *_pdiag, _v;{\n");
386 #endif
387  if (currents->next != currents) {
388  P(" double _g, _rhs;\n");
389 #if VECTORIZE
390  P(" _p = _pp; _ppvar = _ppd;\n");
391 #else
392  P(" _p = _prop->param; _ppvar = _prop->dparam;\n");
393 #endif
395  P(" _g = _nrn_current(_v + .001);\n");
397  P(" _rhs = _nrn_current(_v);\n");
398  printlist(end_dion_stmt(".001"));
399  P(" _g = (_g - _rhs)/.001;\n");
400  /* set the ion variable values */
402  if (point_process) {
403  P(" *_pdiag += _g * 1.e2/(_nd_area);\n return (_rhs - _g*_v) * 1.e2/(_nd_area);\n}\n");
404  }else{
405  P(" *_pdiag += _g;\n return _rhs - _g*_v;\n}\n");
406  }
407  }else{
408  P(" return 0.;\n}\n");
409  }
410 
411  /* nrnstate list contains the EQUATION solve statement so this
412  advances states by dt */
413 #if VECTORIZE
414  P("\nstatic nrn_state(_pp, _ppd, _v) double *_pp, _v; Datum* _ppd; {\n");
415 #else
416  P("\nstatic nrn_state(_prop, _v) Prop *_prop; double _v; {\n");
417 #endif
418  if (nrnstate || currents->next == currents) {
419  P(" double _break, _save;\n");
420 #if VECTORIZE
421  P(" _p = _pp; _ppvar = _ppd;\n");
422 #else
423  P(" _p = _prop->param; _ppvar = _prop->dparam;\n");
424 #endif
425  P(" _break = t + .5*dt; _save = t; delta_t = dt;\n");
426  P(" v=_v;\n{\n");
428  if (nrnstate) {
429  printlist(nrnstate);
430  }
431  if (currents->next == currents) {
432  printlist(modelfunc);
433  }
435  P("\n}");
436  }
437  P("\n}\n");
438 #else
439  /* Model function must always be present */
440 #if SIMSYS
441  P("\nmodel() {\n");
442  P("double _break, _save;\n{\n");
443 #else
444  P("\nmodel(_pp, _indepindex) double _pp[]; int _indepindex; {\n");
445  P("double _break, _save;");
446 #if HMODL
447  P("\n{\n");
448 #else
449  P("_p = _pp;\n{\n");
450 #endif
451 #endif
452  printlist(modelfunc);
453  P("\n}\n}\n");
454  Fflush(fcout);
455 #endif
456 
457 #if NMODL
458  P("\nstatic terminal(){}\n");
459 #else
460  /* Terminal function must always be present */
461 #if SIMSYS || HMODL
462  P("\nterminal() {");
463  P("\n{\n");
464 #else
465  P("\nterminal(_pp) double _pp[];{");
466  P("_p = _pp;\n{\n");
467 #endif
468  printlist(termfunc);
469  P("\n}\n}\n");
470  Fflush(fcout);
471 #endif
472 
473  /* initlists() is called once to setup slist and dlist pointers */
474 #if NMODL || SIMSYS || HMODL
475  P("\nstatic _initlists() {\n");
476 #else
477  P("\n_initlists() {\n");
478 #endif
479  P(" int _i; static int _first = 1;\n");
480  P(" if (!_first) return;\n");
481  printlist(initlist);
482  P("_first = 0;\n}\n");
483 }
484 
485 /*
486  * One of the things initmodel() must do is initialize all states to the
487  * value of state0. This generated code goes before any explicit initialize
488  * code written by the user.
489  */
490 static void initstates()
491 {
492  int i;
493  Item *qs;
494  Symbol *s;
495 
496  SYMITER_STAT {
497  Sprintf(buf, "%s0", s->name);
498  if (lookup(buf)) { /* if no constant associated
499  * with a state such as the
500  * ones automattically
501  * generated by SENS then
502  * there is no initialization
503  * line */
504  if (s->subtype & ARRAY) {
505  Fprintf(fcout,
506  " for (_i=0; _i<%d; _i++) %s[_i] = %s0;\n",
507  s->araydim, s->name, s->name);
508  } else {
509  Fprintf(fcout, " %s = %s0;\n",
510  s->name, s->name);
511  }
512  }
513  }
514 }
515 
516 /*
517  * here is the only place as of 18-apr-89 where we don't explicitly know the
518  * type of a list element
519  */
520 
522 {
523  Item *q;
524  int newline = 0, indent = 0, i;
525 
526  /*
527  * most of this is merely to decide where newlines and indentation
528  * goes so that the .c file can be read if something goes wrong
529  */
530  if (!s) {
531  return;
532  }
533  ITERATE(q, s) {
534  if (q->itemtype == SYMBOL) {
535  if (SYM(q)->type == SPECIAL) {
536  switch (SYM(q)->subtype) {
537 
538  case SEMI:
539  newline = 1;
540  break;
541  case BEGINBLK:
542  newline = 1;
543  indent++;
544  break;
545  case ENDBLK:
546  newline = 1;
547  indent--;
548  break;
549  }
550  }
551  Fprintf(fcout, " %s", SYM(q)->name);
552  } else if (q->itemtype == VERBATIM) {
553  Fprintf(fcout, "%s", STR(q));
554  }else {
555  Fprintf(fcout, " %s", STR(q));
556  }
557  if (newline) {
558  newline = 0;
559  Fprintf(fcout, "\n");
560  for (i = 0; i < indent; i++) {
561  Fprintf(fcout, " ");
562  }
563  }
564  }
565 }
566 
567 static void funcdec()
568 {
569  int i;
570  Symbol *s;
571  List *qs;
572 
573  SYMITER(NAME) {
574  /*EMPTY*/ /*maybe*/
575  if (s->subtype & FUNCT) {
576 #define GLOBFUNCT 1
577 #if GLOBFUNCT && NMODL
578 #else
579  Fprintf(fcout, "static double %s();\n", s->name);
580 #endif
581  }
582  if (s->subtype & PROCED) {
583  Fprintf(fcout, "static %s();\n", s->name);
584  }
585  }
586 }
587 
588 #if VECTORIZE
589 void c_out_vectorize()
590 {
591  Item *q;
592  extern int point_process;
593 
594  Fprintf(fcout, "/* Created by Language version: %s of %s */\n",
596  Fflush(fcout);
597  /* things which must go first and most declarations */
598  P("/* VECTORIZED */\n");
599  P("#include <stdio.h>\n#include <math.h>\n#include \"scoplib.h\"\n");
600  P("#undef PI\n");
601  printlist(defs_list);
602  printlist(firstlist);
603  RCS_version[strlen(RCS_version) - 2] = '\0';
604  RCS_date[strlen(RCS_date) - 11] = '\0';
605  RCS_version = index(RCS_version, ':') + 2;
606  RCS_date = index(RCS_date, ':') + 2;
607  P("static int _reset;\n");
608  if (modelline) {
609  Fprintf(fcout, "static char *modelname = \"%s\";\n\n", modelline);
610  } else {
611  Fprintf(fcout, "static char *modelname = \"\";\n\n");
612  }
613  Fflush(fcout); /* on certain internal errors partial output
614  * is helpful */
615  P("static int error;\n");
616  P("static int _ninits = 0;\n");
617  P("static int _match_recurse=1;\n");
618  P("static _modl_cleanup(){ _match_recurse=1;}\n");
619 
620  funcdec();
621  Fflush(fcout);
622 
623  /*
624  * translations of named blocks into functions, procedures, etc. Also
625  * some special declarations used by some blocks
626  */
627  printlist(procfunc);
628  Fflush(fcout);
629 
630  /* Initialization function must always be present */
631 
632  P("\nstatic initmodel(_ix) int _ix; {\n int _i; double _save;");
633 
634 #if 0
635  P("_initlists(_ix);\n");
636  P("_ninits++;\n");
637  P(saveindep); /*see solve.c; blank if not a time dependent process*/
638 #endif
639  P("{\n");
640  initstates();
641  printlist(initfunc);
642  if (match_bound) {
643  assert(!vectorize);
644  P("\n_init_match(_save);");
645  }
646  P("\n}\n}\n");
647  Fflush(fcout);
648 
649  /* generation of initmodel interface */
650  P("\nstatic nrn_init(_count, _nodes, _data, _pdata)\n");
651  P(" int _count; Node** _nodes; double** _data; Datum** _pdata;\n");
652  P("{ int _ix;\n");
653  P(" _p = _data; _ppvar = _pdata;\n");
654  check_tables();
655  P(cray_pragma());
656  P(" for (_ix = 0; _ix < _count; ++_ix) {\n");
657  P(" v = _nodes[_ix]->_v;\n");
659  P(" initmodel(_ix);\n");
661  P(" }\n");
662  P("}\n");
663 
664  /* standard modl EQUATION without solve computes current */
665  P("\nstatic double _nrn_current(_ix, _v) int _ix; double _v;{\n double _current=0.;v=_v;\n {");
666  if (currents->next != currents) {
667  printlist(modelfunc);
668  }
669  ITERATE(q, currents) {
670  Sprintf(buf, " _current += %s;\n", SYM(q)->name);
671  P(buf);
672  }
673  P("\n} return _current;\n}\n");
674 
675 
676  /* the neuron current also has to compute the dcurrent/dv as well
677  as make sure all currents accumulated properly (currents list) */
678  P("\nstatic double nrn_cur(_count, _nodes, _data, _pdata)\n");
679  P(" int _count; Node** _nodes; double** _data; Datum** _pdata;\n");
680  P("{\n");
681  if (currents->next != currents) {
682  P("int _ix;\n");
683  P(" _p = _data; _ppvar = _pdata;\n");
684  check_tables();
685 
686  P("\n#if METHOD3\n if (_method3) {\n");
687  /*--- reprduction of normal with minor changes ---*/
688  P(cray_pragma());
689  P(" for (_ix = 0; _ix < _count; ++_ix) {\n");
690  P(" double _g, _rhs, _v;\n");
691  P(" _v = _nodes[_ix]->_v;\n");
693  P(" _g = _nrn_current(_ix, _v + .001);\n");
695  P("\n _rhs = _nrn_current(_ix, _v);\n");
696  printlist(end_dion_stmt(".001"));
697  P(" _g = (_g - _rhs)/.001;\n");
698  /* set the ion variable values */
700  if (point_process) {
701  P(" _nodes[_ix]->_d += _g * 1.e2/(_nd_area);\n");
702  P(" _nodes[_ix]->_rhs += (_g*_v - _rhs) * 1.e2/(_nd_area);\n");
703  }else{
704  P(" _nodes[_ix]->_thisnode._GC += _g;\n");
705  P(" _nodes[_ix]->_thisnode._EC += (_g*_v - _rhs);\n");
706  }
707  P(" }\n");
708  /*-------------*/
709  P("\n }else\n#endif\n {\n");
710 
711  /*--- normal ---*/
712  P(cray_pragma());
713  P(" for (_ix = 0; _ix < _count; ++_ix) {\n");
714  P(" double _g, _rhs, _v;\n");
715  P(" _v = _nodes[_ix]->_v;\n");
717  P(" _g = _nrn_current(_ix, _v + .001);\n");
719  P("\n _rhs = _nrn_current(_ix, _v);\n");
720  printlist(end_dion_stmt(".001"));
721  P(" _g = (_g - _rhs)/.001;\n");
722  /* set the ion variable values */
724  if (point_process) {
725  P(" _nodes[_ix]->_d += _g * 1.e2/(_nd_area);\n");
726  P(" _nodes[_ix]->_rhs += (_g*_v - _rhs) * 1.e2/(_nd_area);\n");
727  }else{
728  P(" _nodes[_ix]->_d += _g;\n");
729  P(" _nodes[_ix]->_rhs += (_g*_v - _rhs);\n");
730  }
731  P(" }\n");
732  /*------------*/
733 
734  P(" }\n");
735 
736  }
737  P(" return 0.;\n}\n");
738 
739  /* nrnstate list contains the EQUATION solve statement so this
740  advances states by dt */
741 
742  P("\nstatic nrn_state(_count, _nodes, _data, _pdata)\n");
743  P(" int _count; Node** _nodes; double** _data; Datum** _pdata;\n");
744  P("{\n");
745  if (nrnstate || currents->next == currents) {
746  P(" int _ix;\n");
747  P(" double _break, _save;\n");
748  P(" _p = _data; _ppvar = _pdata;\n");
749  check_tables();
750  P(" _break = t + .5*dt; _save = t; delta_t = dt;\n");
751 
752  P(cray_pragma());
753  P(" for (_ix = 0; _ix < _count; ++_ix) {\n");
754  P(" v = _nodes[_ix]->_v;\n");
756  P(" }\n");
757 
758  P("\n{\n");
759  if (nrnstate) {
760  printlist(nrnstate);
761  }
762  P("}\n");
763  P(cray_pragma());
764  P(" for (_ix = 0; _ix < _count; ++_ix) {\n");
765  if (currents->next == currents) {
766  printlist(modelfunc);
767  }
769  P(" }\n");
770  }
771  P("}\n");
772  Fflush(fcout);
773 
774  P("\nstatic terminal(){}\n");
775 
776  /* vectorized: data must have own copies of slist and dlist
777  for now we don't vectorize if slist or dlist exists. Eventually
778  must separate initialization of static things from vectorized
779  things.
780  */
781  /* initlists() is called once to setup slist and dlist pointers */
782  P("\nstatic _initlists(){\n");
783  P(" int _i; static int _first = 1;\n");
784  P(" if (!_first) return;\n");
785  printlist(initlist);
786  P("_first = 0;\n}\n");
787 }
788 
789 void vectorize_substitute(Item* q, char* str)
790 {
791  if (!vectorize_replacements) {
792  vectorize_replacements = newlist();
793  }
794  lappenditem(vectorize_replacements, q);
795  lappendstr(vectorize_replacements, str);
796 }
797 
799  Item *q, *q1;
800  if (vectorize_replacements) {
801  ITERATE(q, vectorize_replacements) {
802  q1 = ITM(q);
803  q = q->next;
804  replacstr(q1, STR(q));
805  }
806  }
807 }
808 
809 char* cray_pragma() {
810  static char buf[] = "\
811 \n#if _CRAY\
812 \n#pragma _CRI ivdep\
813 \n#endif\
814 \n";
815  return buf;
816 }
817 
818 #endif /*VECTORIZE*/
List * currents
Definition: nocpout.cpp:140
short itemtype
Definition: model.h:16
#define assert(ex)
Definition: hocassrt.h:26
List * get_ion_variables(int)
Definition: nocpout.cpp:1949
short type
Definition: cabvars.h:10
void c_out_vectorize(const char *)
void vectorize_do_substitute()
List * indeplist
Definition: parsact.cpp:15
static int point_process
Definition: nrnunit.cpp:11
#define PROCED
Definition: model.h:120
List * initfunc
Definition: cout.cpp:221
static void initstates()
Definition: cout.cpp:490
#define ITERATE(itm, lst)
Definition: model.h:25
#define SYM(q)
Definition: model.h:86
#define SYMITER_STAT
Definition: symbol.h:14
#define SPECIAL
Definition: model.h:100
List * initlist
Definition: cout.cpp:221
char * name
Definition: model.h:72
#define Fprintf
Definition: model.h:249
#define SYMBOL
Definition: model.h:102
#define P(arg)
Definition: cout.cpp:220
struct Item * next
Definition: model.h:19
List * set_ion_variables(int)
Definition: nocpout.cpp:1883
Definition: model.h:15
static int indent
Definition: noccout.cpp:514
void c_out()
Definition: cout.cpp:252
_CONST char * s
Definition: system.cpp:74
#define ARRAY
Definition: model.h:118
List * defs_list
Definition: nocpout.cpp:124
Item * lappendstr(List *list, char *str)
Definition: list.cpp:149
List * procfunc
Definition: cout.cpp:221
char * modelline
Definition: cout.cpp:237
void vectorize_substitute(Item *q, char *str)
static int newline
Definition: noccout.cpp:514
Definition: model.h:57
#define Fflush
Definition: model.h:251
char * name
Definition: init.cpp:16
char * RCS_date
Definition: version.cpp:5
char * saveindep
Definition: solve.cpp:369
List * newlist()
Definition: list.cpp:50
#define ENDBLK
Definition: model.h:124
#define FUNCT
Definition: model.h:119
List * begin_dion_stmt()
Definition: nocpout.cpp:2123
char * RCS_version
Definition: version.cpp:4
NMODL parser global flags / functions.
#define lookup
Definition: redef.h:90
long subtype
Definition: model.h:59
Item * lappenditem(List *list, Item *item)
Definition: list.cpp:167
void check_tables()
Definition: parsact.cpp:538
List * match_bound
Definition: deriv.cpp:637
#define STR(q)
Definition: model.h:87
int vectorize
static void funcdec()
Definition: cout.cpp:567
int araydim
Definition: model.h:67
long subtype
Definition: init.cpp:122
#define i
Definition: md1redef.h:12
void printlist(List *s)
Definition: cout.cpp:521
Symbol * indepsym
Definition: declare.cpp:11
List * firstlist
Definition: cout.cpp:221
char buf[512]
Definition: init.cpp:13
List * modelfunc
Definition: cout.cpp:221
void replacstr(Item *q, char *s)
Definition: list.cpp:250
#define Sprintf
Definition: model.h:248
#define SEMI
Definition: model.h:122
size_t q
List * termfunc
Definition: cout.cpp:221
List * end_dion_stmt(char *strdel)
Definition: nocpout.cpp:2149
FILE * fcout
Definition: model.cpp:33
#define BEGINBLK
Definition: model.h:123
short index
Definition: cabvars.h:11
#define ITM(q)
Definition: model.h:88
#define SYMITER(arg1)
Definition: symbol.h:9