NEURON
glinerec.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 // we want to plot correctly during the local step method when
3 // cvode.solve(tstop) is invoked. However, not all GraphLine are time graphs,
4 // so we assume that the time graphs will be added during stdinit
5 // during iteration over the graph lists of the stdrun implementation which
6 // calls Graph.simgraph(). Constantly updating during stdinit
7 // overcomes the problem of new addexpr, addval, and changed locations of
8 // point processes.
9 // Note: cvode.simgraph_remove() deletes all the GLineRecord instances.
10 
11 #include "hocparse.h"
12 #include "code.h"
13 #undef begin
14 #undef add
15 
16 #include <OS/list.h>
17 #include "nrnoc2iv.h"
18 #include "vrecitem.h"
19 #include "netcvode.h"
20 #include "cvodeobj.h"
21 
22 #if HAVE_IV // to end of file
23 #include "graph.h"
24 #include "glinerec.h"
25 #include "ocjump.h"
26 
28 
29 class GLineRecordList;
30 
31 declarePtrList(GLineRecordList, GLineRecord)
32 implementPtrList(GLineRecordList, GLineRecord)
33 static GLineRecordList* grl;
34 
35 // Since GraphLine is not an observable, its destructor calls this.
36 // So ivoc will work, a stub is placed in ivoc/datapath.cpp
37 void graphLineRecDeleted(GraphLine* gl) {
38  if (!grl) { return; }
39  int i, cnt = grl->count();
40  for (i = 0; i < cnt; ++i) {
41  GLineRecord* r = grl->item(i);
42  if (r->uses(gl)) {
43  delete r;
44  return;
45  }
46  }
47 }
48 
50  if (!grl) { return; }
51  while (grl->count()) {
52  delete grl->item(grl->count()-1);
53  }
54 }
55 
56 void Graph::simgraph() {
57  int i, cnt;
58  if (!grl) { grl = new GLineRecordList(); }
59  cnt = line_list_.count();
60  for (i = 0; i < cnt; ++i) {
61  GraphLine* gl = line_list_.item(i);
62  PlayRecord* pr = net_cvode_instance->playrec_uses(gl);
63  if (pr) {
64  delete pr;
65  }
66  GLineRecord* r = new GLineRecord(gl);
67  grl->append(r);
68  }
69 }
70 
71 void GLineRecord::fill_pd1() {
72  Inst* pcsav = hoc_pc;
73  for (hoc_pc = gl_->expr_->u.u_proc->defn.in; hoc_pc->in != STOP;) { // run machine analogous to hoc_execute(inst);
74  double* pd = NULL;
75  Inst* pc1 = hoc_pc++; // must be incremented before the function return.
76  if (pc1->pf == rangepoint) {
77  hoc_pushx(0.5); // arc position
79  pd = hoc_pxpop();
80  hoc_pushx(*pd);
81  }else if (pc1->pf == rangevareval) {
83  pd = hoc_pxpop();
84  hoc_pushx(*pd);
85  }else if (pc1->pf == varpush) {
86  Symbol* sym = hoc_pc->sym;
87  if (strcmp(sym->name, "t") == 0) {
88  saw_t_ = true;
89  }
90  hoc_varpush();
91  }else{
92  (*((pc1)->pf))();
93  }
94  if (pd) {
95  pd_and_vec_.push_back(std::pair<double*, IvocVect*>(pd, NULL));
96  }
97  }
98  hoc_pc = pcsav;
99 
100 #if 0
101  Symbol* esym = gl_->expr_;
102  int sz = esym->u.u_proc->size;
103  Inst* inst = esym->u.u_proc->defn.in;
104  printf("\n%s\n", gl_->name());
105  for (int i = 0; i < sz; ++i) {
106  hoc_debugzz(inst + i);
107  }
108 #endif
109 }
110 
111 void GLineRecord::fill_pd() {
112  // Call only if cache_efficient will not change pointers before useing
113  // the results of his computation.
114 
115  // Get rid of old pd_and_vec_ info.
116  for (GLineRecordEData::iterator it = pd_and_vec_.begin(); it != pd_and_vec_.end(); ++it) {
117  if ((*it).second) {
118  delete (*it).second;
119  }
120  }
121  pd_and_vec_.resize(0);
122  saw_t_ = false;
123  pd_ = gl_->pval_;
124  if (pd_) {
125  return;
126  }
127 
128  // Execute the expr Inst by Inst but when rangepoint or
129  // rangevareval are seen, execute a series of stack machine instructions
130  // that give us the pointer to the range variable (see the implementation
131  // in nrn/src/nrnoc/cabcode.cpp) but leaving the stack as though the
132  // original instruction was executed.
133  assert(gl_->expr_);
134  ObjectContext objc(gl_->obj_);
135  fill_pd1();
136  objc.restore();
137 #if 0
138  printf("\n%s\n", gl_->name());
139  for (GLineRecordEData::iterator it = pd_and_vec_.begin(); it != pd_and_vec_.end(); ++it) {
140  printf(" pd=%p\n", (*it).first);
141  }
142 #endif
143 }
144 
146  //shouldnt be necessary but just in case
147 // printf("GLineRecord %p name=%s\n", this, gl->name());
148  gl_ = gl;
149  gl_->simgraph_activate(true);
150  v_ = NULL;
151  saw_t_ = false;
152 }
153 
155  //printf("GVectorRecord %p\n", this);
156  gv_ = gv;
157 }
158 
160  //printf("GraphVector::record_install()\n");
161  GVectorRecord* gvr = new GVectorRecord(this);
162 }
163 
165  //printf("GraphVector::record_uninstall()\n");
166 }
167 
169 // printf("~GLineRecord %p\n", this);
170  int i;
171  if (v_) {
172  delete v_;
173  v_ = NULL;
174  }
175 
176  for (GLineRecordEData::iterator it = pd_and_vec_.begin(); it != pd_and_vec_.end(); ++it) {
177  if ((*it).second) {
178  delete (*it).second;
179  }
180  }
181 
182  for (i = grl->count()-1; i >= 0; --i) {
183  if (grl->item(i) == this) {
184  gl_->simgraph_activate(false);
185  grl->remove(i);
186  return;
187  }
188  }
189 }
190 
192  printf("~GVectorRecord %p\n", this);
193 #if 0 // for now not allowing vector buffering
194  for (GLineRecordEData::iterator it = pd_and_vec_.begin(); it != pd_and_vec_.end(); ++it) {
195  if ((*it).second) {
196  delete (*it).second;
197  }
198  }
199 #endif
200 }
201 
203  gl_->simgraph_init();
204 }
205 
207 }
208 
209 void GLineRecord::continuous(double t) {
210  gl_->simgraph_continuous(t);
211 }
212 
213 void GVectorRecord::continuous(double t) {
214 }
215 
216 int GVectorRecord::count() {
217  return gv_->py_data()->count();
218 }
219 double* GVectorRecord::pdata(int i) {
220  return gv_->py_data()->p(i);
221 }
222 
223 void GLineRecord::plot(int vecsz, double tstop) {
224  double dt = tstop/double(vecsz-1);
225  DataVec* x = (DataVec*)gl_->x_data();
226  DataVec* y = (DataVec*)gl_->y_data();
227  if (v_) {
228  v_->resize(vecsz);
229  double* v = vector_vec(v_);
230  for (int i=0; i < vecsz; ++i) {
231  x->add(dt*i);
232  y->add(v[i]);
233  }
234  }else if (gl_->expr_) {
235  // transfer elements to range variables and plot expression result
236  ObjectContext obc(NULL);
237  for (int i=0; i < vecsz; ++i) {
238  x->add(dt*i);
239  for (GLineRecordEData::iterator it = pd_and_vec_.begin(); it != pd_and_vec_.end(); ++it) {
240  double* pd = (*it).first;
241  *pd = (*it).second->elem(i);
242  }
243  gl_->plot();
244  }
245  obc.restore();
246  }else{
247  assert(0);
248  }
249 }
250 #else // do not HAVE_IV
252 #endif // HAVE_IV
HocStruct Symbol * sym
Definition: hocdec.h:61
#define assert(ex)
Definition: hocassrt.h:26
Coord x(int index) const
Definition: graph.h:228
#define declarePtrList(PtrList, T)
virtual void record_init()
void rangevareval(void)
Definition: cabcode.cpp:1455
virtual void continuous(double t)
virtual void continuous(double t)
double * hoc_pxpop(void)
Definition: code.cpp:827
Definition: graph.h:163
char * name
Definition: model.h:72
unsigned long size
Definition: hocdec.h:77
#define v
Definition: md1redef.h:4
void rangepoint(void)
Definition: cabcode.cpp:1464
static void pr(N_Vector x)
Definition: hocdec.h:51
virtual ~GLineRecord()
virtual void record_init()
virtual ~GVectorRecord()
virtual bool uses(void *v)
Definition: glinerec.h:20
GLineRecord(GraphLine *)
double dt
Definition: init.cpp:123
#define implementPtrList(PtrList, T)
void add(float)
#define STOP
Definition: hocdec.h:66
#define printf
Definition: mwprefix.h:26
Coord y(int index) const
Definition: graph.h:229
#define cnt
Definition: spt2queue.cpp:19
Proc * u_proc
Definition: hocdec.h:144
Inst defn
Definition: hocdec.h:76
Definition: model.h:57
void fill_pd1()
void fill_pd()
void record_uninstall()
void plot(int, double)
Pfrv pf
Definition: hocdec.h:52
void hoc_pushx(double)
void rangevarevalpointer(void)
Definition: cabcode.cpp:1410
Inst * hoc_pc
#define varpush
Definition: redef.h:131
#define i
Definition: md1redef.h:12
GVectorRecord(GraphVector *)
void simgraph_activate(bool)
double * vector_vec(Vect *v)
Definition: ivocvect.cpp:271
double * pdata(int)
PlayRecord * playrec_uses(void *)
Definition: netcvode.cpp:6009
void simgraph_remove()
Definition: glinerec.cpp:251
union Symbol::@18 u
double t
Definition: init.cpp:123
void record_install()
void simgraph()
return NULL
Definition: cabcode.cpp:461
NetCvode * net_cvode_instance
Definition: cvodestb.cpp:27
HocUnion Inst * in
Definition: hocdec.h:60