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) {
39  return;
40  }
41  int i, cnt = grl->count();
42  for (i = 0; i < cnt; ++i) {
43  GLineRecord* r = grl->item(i);
44  if (r->uses(gl)) {
45  delete r;
46  return;
47  }
48  }
49 }
50 
52  if (!grl) {
53  return;
54  }
55  while (grl->count()) {
56  delete grl->item(grl->count() - 1);
57  }
58 }
59 
60 void Graph::simgraph() {
61  int i, cnt;
62  if (!grl) {
63  grl = new GLineRecordList();
64  }
65  cnt = line_list_.count();
66  for (i = 0; i < cnt; ++i) {
67  GraphLine* gl = line_list_.item(i);
69  if (pr) {
70  delete pr;
71  }
72  GLineRecord* r = new GLineRecord(gl);
73  grl->append(r);
74  }
75 }
76 
77 void GLineRecord::fill_pd1() {
78  Inst* pcsav = hoc_pc;
79  for (hoc_pc = gl_->expr_->u.u_proc->defn.in;
80  hoc_pc->in != STOP;) { // run machine analogous to hoc_execute(inst);
81  double* pd = NULL;
82  Inst* pc1 = hoc_pc++; // must be incremented before the function return.
83  if (pc1->pf == rangepoint) {
84  hoc_pushx(0.5); // arc position
86  pd = hoc_pxpop();
87  hoc_pushx(*pd);
88  } else if (pc1->pf == rangevareval) {
90  pd = hoc_pxpop();
91  hoc_pushx(*pd);
92  } else if (pc1->pf == varpush) {
93  Symbol* sym = hoc_pc->sym;
94  if (strcmp(sym->name, "t") == 0) {
95  saw_t_ = true;
96  }
97  hoc_varpush();
98  } else {
99  (*((pc1)->pf))();
100  }
101  if (pd) {
102  pd_and_vec_.push_back(std::pair<double*, IvocVect*>(pd, NULL));
103  }
104  }
105  hoc_pc = pcsav;
106 
107 #if 0
108  Symbol* esym = gl_->expr_;
109  int sz = esym->u.u_proc->size;
110  Inst* inst = esym->u.u_proc->defn.in;
111  printf("\n%s\n", gl_->name());
112  for (int i = 0; i < sz; ++i) {
113  hoc_debugzz(inst + i);
114  }
115 #endif
116 }
117 
118 void GLineRecord::fill_pd() {
119  // Call only if cache_efficient will not change pointers before useing
120  // the results of his computation.
121 
122  // Get rid of old pd_and_vec_ info.
123  for (GLineRecordEData::iterator it = pd_and_vec_.begin(); it != pd_and_vec_.end(); ++it) {
124  if ((*it).second) {
125  delete (*it).second;
126  }
127  }
128  pd_and_vec_.resize(0);
129  saw_t_ = false;
130  pd_ = gl_->pval_;
131  if (pd_) {
132  return;
133  }
134 
135  // Execute the expr Inst by Inst but when rangepoint or
136  // rangevareval are seen, execute a series of stack machine instructions
137  // that give us the pointer to the range variable (see the implementation
138  // in nrn/src/nrnoc/cabcode.cpp) but leaving the stack as though the
139  // original instruction was executed.
140  assert(gl_->expr_);
141  ObjectContext objc(gl_->obj_);
142  fill_pd1();
143  objc.restore();
144 #if 0
145  printf("\n%s\n", gl_->name());
146  for (GLineRecordEData::iterator it = pd_and_vec_.begin(); it != pd_and_vec_.end(); ++it) {
147  printf(" pd=%p\n", (*it).first);
148  }
149 #endif
150 }
151 
153  : PlayRecord(NULL) {
154  // shouldnt be necessary but just in case
155  // printf("GLineRecord %p name=%s\n", this, gl->name());
156  gl_ = gl;
157  gl_->simgraph_activate(true);
158  v_ = NULL;
159  saw_t_ = false;
160 }
161 
163  : PlayRecord(NULL) {
164  // printf("GVectorRecord %p\n", this);
165  gv_ = gv;
166 }
167 
169  // printf("GraphVector::record_install()\n");
170  GVectorRecord* gvr = new GVectorRecord(this);
171 }
172 
174  // printf("GraphVector::record_uninstall()\n");
175 }
176 
178  // printf("~GLineRecord %p\n", this);
179  int i;
180  if (v_) {
181  delete v_;
182  v_ = NULL;
183  }
184 
185  for (GLineRecordEData::iterator it = pd_and_vec_.begin(); it != pd_and_vec_.end(); ++it) {
186  if ((*it).second) {
187  delete (*it).second;
188  }
189  }
190 
191  for (i = grl->count() - 1; i >= 0; --i) {
192  if (grl->item(i) == this) {
193  gl_->simgraph_activate(false);
194  grl->remove(i);
195  return;
196  }
197  }
198 }
199 
201  printf("~GVectorRecord %p\n", this);
202 #if 0 // for now not allowing vector buffering
203  for (GLineRecordEData::iterator it = pd_and_vec_.begin(); it != pd_and_vec_.end(); ++it) {
204  if ((*it).second) {
205  delete (*it).second;
206  }
207  }
208 #endif
209 }
210 
212  gl_->simgraph_init();
213 }
214 
216 
217 void GLineRecord::continuous(double t) {
219 }
220 
221 void GVectorRecord::continuous(double t) {}
222 
223 int GVectorRecord::count() {
224  return gv_->py_data()->count();
225 }
226 double* GVectorRecord::pdata(int i) {
227  return gv_->py_data()->p(i);
228 }
229 
230 void GLineRecord::plot(int vecsz, double tstop) {
231  double dt = tstop / double(vecsz - 1);
232  DataVec* x = (DataVec*) gl_->x_data();
233  DataVec* y = (DataVec*) gl_->y_data();
234  if (v_) {
235  v_->resize(vecsz);
236  double* v = vector_vec(v_);
237  for (int i = 0; i < vecsz; ++i) {
238  x->add(dt * i);
239  y->add(v[i]);
240  }
241  } else if (gl_->expr_) {
242  // transfer elements to range variables and plot expression result
243  ObjectContext obc(NULL);
244  for (int i = 0; i < vecsz; ++i) {
245  x->add(dt * i);
246  for (GLineRecordEData::iterator it = pd_and_vec_.begin(); it != pd_and_vec_.end();
247  ++it) {
248  double* pd = (*it).first;
249  *pd = (*it).second->elem(i);
250  }
251  gl_->plot();
252  }
253  obc.restore();
254  } else {
255  assert(0);
256  }
257 }
258 #else // do not HAVE_IV
260 #endif // HAVE_IV
void rangevareval(void)
Definition: cabcode.cpp:1456
void rangevarevalpointer(void)
Definition: cabcode.cpp:1410
void rangepoint(void)
Definition: cabcode.cpp:1465
int count()
Definition: graph.h:245
double * p(int i)
Definition: graph.h:248
Definition: graph.h:200
void add(float)
virtual bool uses(void *v)
Definition: glinerec.h:22
void plot(int, double)
virtual void continuous(double t)
void fill_pd()
GLineRecord(GraphLine *)
virtual void record_init()
bool saw_t_
Definition: glinerec.h:36
GraphLine * gl_
Definition: glinerec.h:30
void fill_pd1()
IvocVect * v_
Definition: glinerec.h:31
GLineRecordEData pd_and_vec_
Definition: glinerec.h:35
virtual ~GLineRecord()
const DataVec * y_data() const
Definition: graph.h:298
const DataVec * x_data() const
Definition: graph.h:295
virtual void record_init()
GVectorRecord(GraphVector *)
virtual void continuous(double t)
GraphVector * gv_
Definition: glinerec.h:57
virtual ~GVectorRecord()
double * pdata(int)
void simgraph()
LineList line_list_
Definition: graph.h:170
void simgraph_init()
void plot()
const char * name() const
Object * obj_
Definition: graph.h:372
double * pval_
Definition: graph.h:371
void simgraph_continuous(double)
void simgraph_activate(bool)
Symbol * expr_
Definition: graph.h:370
DataPointers * py_data()
Definition: graph.h:395
void record_uninstall()
void record_install()
void resize(size_t n)
Definition: ivocvect.h:47
void simgraph_remove()
Definition: glinerec.cpp:259
PlayRecord * playrec_uses(void *)
Definition: netcvode.cpp:6287
double * pd_
Definition: vrecitem.h:91
double dt
Definition: netcvode.cpp:76
double t
Definition: cvodeobj.cpp:59
NetCvode * net_cvode_instance
Definition: cvodestb.cpp:27
double * hoc_pxpop(void)
Definition: code.cpp:838
#define assert(ex)
Definition: hocassrt.h:32
#define STOP
Definition: hocdec.h:66
void hoc_pushx(double)
double * vector_vec(Vect *v)
Definition: ivocvect.cpp:328
#define implementPtrList(PtrList, T)
#define declarePtrList(PtrList, T)
#define v
Definition: md1redef.h:4
#define i
Definition: md1redef.h:12
#define printf
Definition: mwprefix.h:26
Inst * hoc_pc
static void pr(N_Vector x)
#define varpush
Definition: redef.h:131
#define cnt
Definition: spt2queue.cpp:19
#define NULL
Definition: sptree.h:16
Inst defn
Definition: hocdec.h:76
unsigned long size
Definition: hocdec.h:77
Definition: model.h:57
Proc * u_proc
Definition: hocdec.h:145
union Symbol::@18 u
char * name
Definition: model.h:72
Definition: hocdec.h:51
Pfrv pf
Definition: hocdec.h:52
HocUnion Inst * in
Definition: hocdec.h:60
HocStruct Symbol * sym
Definition: hocdec.h:61