NEURON
section.h
Go to the documentation of this file.
1 /* /local/src/master/nrn/src/nrnoc/section.h,v 1.4 1996/05/21 17:09:24 hines Exp */
2 #ifndef section_h
3 #define section_h
4 
5 /* In order to support oc objects containing sections, instead of vector
6  of ordered sections, we now have a list (in the nmodl sense)
7  of unordered sections. The lesser efficiency is ok because the
8  number crunching is vectorized. ie only the user interface deals
9  with sections and that needs to be convenient
10 */
11 /* Data structure for solving branching 1-D tree diffusion type equations.
12  Vector of ordered sections each of which points to a vector of nodes.
13  Each section must have at least one node. There may be 0 sections.
14  The order of last node to first node is used in triangularization.
15  First node to last is used in back substitution.
16  The first node of a section is connected to some node of a section
17  with lesser index.
18 */
19 /* An equation is associated with each node. d and rhs are the diagonal and
20  right hand side respectively. a is the effect of this node on the parent
21  node's equation. b is the effect of the parent node on this node's
22  equation.
23  d is assumed to be non-zero.
24  d and rhs is calculated from the property list.
25 */
26 
27 
28 #include "nrnredef.h"
29 #include "options.h"
30 #include "hoclist.h"
31 
32 /*#define DEBUGSOLVE 1*/
33 #define xpop hoc_xpop
34 #define pc hoc_pc
35 #define spop hoc_spop
36 #define execerror hoc_execerror
37 #include "hocdec.h"
38 
39 typedef struct Section {
40  int refcount; /* may be in more than one list */
41  short nnode; /* Number of nodes for ith section */
42  struct Section* parentsec; /* parent section of node 0 */
43  struct Section* child; /* root of the list of children
44  connected to this parent kept in
45  order of increasing x */
46  struct Section* sibling; /* used as list of sections that have same parent */
47 
48 
49  /* the parentnode is only valid when tree_changed = 0 */
50  struct Node* parentnode; /* parent node */
51  struct Node** pnode; /* Pointer to pointer vector of node structures */
52  int order; /* index of this in secorder vector */
53  short recalc_area_; /* NODEAREA, NODERINV, diam, L need recalculation */
54  short volatile_mark; /* for searching */
55  void* volatile_ptr; /* e.g. ShapeSection* */
56 #if DIAMLIST
57  short npt3d; /* number of 3-d points */
58  short pt3d_bsize; /* amount of allocated space for 3-d points */
59  struct Pt3d* pt3d; /* list of 3d points with diameter */
60  struct Pt3d* logical_connection; /* nil for legacy, otherwise specifies logical connection
61  position (for translation) */
62 #endif
63  struct Prop* prop; /* eg. length, etc. */
65 
66 #if DIAMLIST
67 typedef struct Pt3d {
68  float x, y, z, d; /* 3d point, microns */
69  double arc;
70 } Pt3d;
71 #endif
72 
73 #if METHOD3
74 typedef float NodeCoef;
75 typedef double NodeVal;
76 
77 typedef struct Info3Coef {
78  NodeVal current; /* for use in next time step */
79  NodeVal djdv0;
80  NodeCoef coef0; /* 5dx/12 */
81  NodeCoef coefn; /* 1dx/12 */
82  NodeCoef coefjdot; /* dx^2*ra/12 */
83  NodeCoef coefdg; /* dx/12 */
84  NodeCoef coefj; /* 1/(ra*dx) */
85  struct Node* nd2; /* the node dx away in the opposite direction*/
86  /* note above implies that nodes next to branches cannot have point processes
87  and still be third order correct. Also nodes next to branches cannot themselves
88  be branch points */
89 } Info3Coef;
90 
91 typedef struct Info3Val { /* storage to help build matrix efficiently */
92  NodeVal GC; /* doesn't include point processes */
93  NodeVal EC;
94  NodeCoef Cdt;
95 } Info3Val;
96 
97 /*METHOD3*/
98 #endif
99 
100 /* if any double is added after area then think about changing
101 the notify_free_val parameter in node_free in solve.cpp
102 */
103 
104 #define NODED(n) (*((n)->_d))
105 #define NODERHS(n) (*((n)->_rhs))
106 
107 #undef NODEV /* sparc-sun-solaris2.9 */
108 
109 #if CACHEVEC == 0
110 #define NODEA(n) ((n)->_a)
111 #define NODEB(n) ((n)->_b)
112 #define NODEV(n) ((n)->_v)
113 #define NODEAREA(n) ((n)->_area)
114 #else /* CACHEVEC */
115 #define NODEV(n) (*((n)->_v))
116 #define NODEAREA(n) ((n)->_area)
117 #define NODERINV(n) ((n)->_rinv)
118 #define VEC_A(i) (_nt->_actual_a[(i)])
119 #define VEC_B(i) (_nt->_actual_b[(i)])
120 #define VEC_D(i) (_nt->_actual_d[(i)])
121 #define VEC_RHS(i) (_nt->_actual_rhs[(i)])
122 #define VEC_V(i) (_nt->_actual_v[(i)])
123 #define VEC_AREA(i) (_nt->_actual_area[(i)])
124 #define NODEA(n) (VEC_A((n)->v_node_index))
125 #define NODEB(n) (VEC_B((n)->v_node_index))
126 #endif /* CACHEVEC */
127 
128 extern int use_sparse13;
129 extern int use_cachevec;
130 extern int secondorder;
131 extern int cvode_active_;
132 
133 typedef struct Node {
134 #if CACHEVEC == 0
135  double _v; /* membrane potential */
136  double _area; /* area in um^2 but see treesetup.cpp */
137  double _a; /* effect of node in parent equation */
138  double _b; /* effect of parent in node equation */
139 #else /* CACHEVEC */
140  double* _v; /* membrane potential */
141  double _area; /* area in um^2 but see treesetup.cpp */
142  double _rinv; /* conductance uS from node to parent */
143  double _v_temp; /* vile necessity til actual_v allocated */
144 #endif /* CACHEVEC */
145  double* _d; /* diagonal element in node equation */
146  double* _rhs; /* right hand side in node equation */
147  double* _a_matelm;
148  double* _b_matelm;
149  int eqn_index_; /* sparse13 matrix row/col index */
150  /* if no extnodes then = v_node_index +1*/
151  /* each extnode adds nlayer more equations after this */
152  struct Prop* prop; /* Points to beginning of property list */
153  Section* child; /* section connected to this node */
154  /* 0 means no other section connected */
155  Section* sec; /* section this node is in */
156  /* #if PARANEURON */
157  struct Node* _classical_parent; /* needed for multisplit */
158  struct NrnThread* _nt;
159 /* #endif */
160 #if EXTRACELLULAR
161  struct Extnode* extnode;
162 #endif
163 
164 #if EXTRAEQN
165  struct Eqnblock* eqnblock; /* hook to other equations which
166  need to be solved at the same time as the membrane
167  potential. eg. fast changeing ionic concentrations */
168 #endif /*MOREEQN*/
169 
170 #if DEBUGSOLVE
171  double savd;
172  double savrhs;
173 #endif /*DEBUGSOLVE*/
174 #if VECTORIZE
175  int v_node_index; /* only used to calculate parent_node_indices*/
176 #endif
177  int sec_node_index_; /* to calculate segment index from *Node */
178 #if METHOD3
179  Info3Coef toparent;
180  Info3Coef fromparent;
181  Info3Val thisnode;
182 #endif
184 
185 #if EXTRACELLULAR
186 /* pruned to only work with sparse13 */
187 extern int nrn_nlayer_extracellular;
188 #define nlayer (nrn_nlayer_extracellular) /* first (0) layer is extracellular next to membrane */
189 typedef struct Extnode {
190  double* param; /* points to extracellular parameter vector */
191  /* v is membrane potential. so v internal = Node.v + Node.vext[0] */
192  /* However, the Node equation is for v internal. */
193  /* This is reconciled during update. */
194 
195  /* Following all have allocated size of nlayer */
196  double* v; /* v external. */
197  double* _a;
198  double* _b;
199  double** _d;
200  double** _rhs; /* d, rhs, a, and b are analogous to those in node */
201  double** _a_matelm;
202  double** _b_matelm;
203  double** _x12; /* effect of v[layer] on eqn layer-1 (or internal)*/
204  double** _x21; /* effect of v[layer-1 or internal] on eqn layer*/
206 #endif
207 
208 #if !INCLUDEHOCH
209 #include "hocdec.h" /* Prop needs Datum and Datum needs Symbol */
210 #endif
211 
212 #define PROP_PY_INDEX 10
213 
214 typedef struct Prop {
215  struct Prop* next; /* linked list of properties */
216  short type; /* type of membrane, e.g. passive, HH, etc. */
217  short unused1; /* gcc and borland need pairs of shorts to align the same.*/
218  int param_size; /* for notifying hoc_free_val_array */
219  double* param; /* vector of doubles for this property */
220  Datum* dparam; /* usually vector of pointers to doubles
221  of other properties but maybe other things as well
222  for example one cable section property is a
223  symbol */
224  long _alloc_seq; /* for cache efficiency */
225  Object* ob; /* nil if normal property, otherwise the object containing the data*/
227 
228 #if defined(__cplusplus)
229 extern "C" {
230 #endif
231 
232 extern double* nrn_prop_data_alloc(int type, int count, Prop* p);
233 extern Datum* nrn_prop_datum_alloc(int type, int count, Prop* p);
234 extern void nrn_prop_data_free(int type, double* pd);
235 extern void nrn_prop_datum_free(int type, Datum* ppd);
236 extern Section* chk_access();
237 extern double nrn_ghk(double, double, double, double);
238 
239 
240 #if defined(__cplusplus)
241 }
242 #endif
243 
244 /* a point process is computed just like regular mechanisms. Ie it appears
245 in the property list whose type specifies which allocation, current, and
246 state functions to call. This means some nodes have more properties than
247 other nodes even in the same section. The Point_process structure allows
248 the interface to hoc variable names.
249 Each variable symbol u.rng->type refers to the point process mechanism.
250 The variable is treated as a vector
251 variable whose first index specifies "which one" of that mechanisms insertion
252 points we are talking about. Finally the variable u.rng->index tells us
253 where in the p-array to look. The number of point_process vectors is the
254 number of different point process types. This is different from the
255 mechanism type which enumerates all mechanisms including the point_processes.
256 It is the responsibility of create_point_process to set up the vectors and
257 fill in the symbol information. However only after the process is given
258 a location can the variables be set or accessed. This is because the
259 allocation function may have to connect to some ionic parameters and the
260 process exists primarily as a property of a node.
261 */
262 typedef struct Point_process {
263  Section* sec; /* section and node location for the point mechanism*/
265  Prop* prop; /* pointer to the actual property linked to the
266  node property list */
267  Object* ob; /* object that owns this process */
268  void* presyn_; /* non-threshold presynapse for NetCon */
269  void* nvi_; /* NrnVarIntegrator (for local step method) */
270  void* _vnt; /* NrnThread* (for NET_RECEIVE and multicore) */
272 
273 #if EXTRAEQN
274 /*Blocks of equations can hang off each node of the current conservation
275 equations. These are equations which must be solved simultaneously
276 because they depend on the voltage and affect the voltage. An example
277 are fast changing ionic concentrations (or merely if we want to be
278 able to calculate steady states using a stable method).
279 */
280 typedef struct Eqnblock {
281  struct Eqnblock* eqnblock_next; /* may be several such blocks */
282  Pfri eqnblock_triang; /* triangularization function */
283  Pfri eqnblock_bksub; /* back substitution function */
284  double* eqnblock_data;
285 #if 0
286  the solving functions know how to find the following info from
287  the eqnblock_data.
288  double *eqnblock_row; /* current conservation depends on states */
289  double *eqnblock_col; /* state equations depend on voltage */
290  double *eqnblock_matrix; /* state equations depend on states */
291  double *eqnblock_rhs:
292  the functions merely take a pointer to the node and this Eqnblock
293  in order to update the values of the diagonal, v, and the rhs
294  The interface with EXTRACELLULAR makes things a bit more subtle.
295  It seems clear that we will have to change the meaning of v to
296  be membrane potential so that the internal potential is v + vext.
297  This will avoid requiring two rows and two columns since
298  the state equations will depend only on v and not vext.
299  In fact, if vext did not have longitudinal relationships with
300  other vext the extracellular mechanism could be implemented in
301  this style.
302 #endif
303 } Eqnblock;
304 #endif /*EXTRAEQN*/
305 
306 extern int nrn_global_ncell; /* note that for multiple threads all the rootnodes are no longer
307  contiguous */
308 extern hoc_List* section_list; /* Where the Sections live */
309 
310 extern Section* sec_alloc(); /* Allocates a single section */
311 extern void node_alloc(Section*, short); /* Allocates node vectors in a section*/
312 extern double section_length(Section*), nrn_diameter(Node*);
313 extern Node* nrn_parent_node(Node*);
314 extern Section* nrn_section_alloc();
315 extern void nrn_section_free(Section*);
316 extern int nrn_is_valid_section_ptr(void*);
317 
318 #if METHOD3
319 extern int _method3;
320 #endif
321 
322 #include <multicore.h>
323 
324 extern int stoprun;
325 #define tstopbit (1 << 15)
326 #define tstopset stoprun |= tstopbit
327 #define tstopunset stoprun &= (~tstopbit)
328 /* cvode.event(tevent) sets this. Reset at beginning */
329 /* of any hoc call for integration and before returning to hoc */
330 
331 
332 #include "nrn_ansi.h"
333 
334 #endif
short type
Definition: cabvars.h:9
static Pfrv mechanism[]
Definition: cabvars.h:26
static double order(void *v)
Definition: cvodeobj.cpp:239
static void update(NrnThread *)
Definition: fadvance.cpp:597
int(* Pfri)(void)
Definition: hocdec.h:39
static VoidFunc functions[]
Definition: hocmodl.h:4
#define rhs
Definition: lineq.h:6
#define GC
Definition: md1redef.h:7
#define v
Definition: md1redef.h:4
#define thisnode
Definition: md1redef.h:6
#define EC
Definition: md1redef.h:8
static Node * node(Object *)
Definition: netcvode.cpp:340
static List * info
if(status)
size_t p
static List * potential
Definition: nrnunit.cpp:12
static List * current
Definition: nrnunit.cpp:12
#define EXTRACELLULAR
Definition: options.h:19
static double take(void *v)
Definition: ocbbs.cpp:454
int find(const int, const int, const int, const int, const int)
void node_alloc(Section *, short)
Definition: solve.cpp:826
double nrn_ghk(double, double, double, double)
Definition: eion.cpp:347
Section * chk_access()
Definition: cabcode.cpp:444
int stoprun
Definition: fadvance.cpp:166
int nrn_nlayer_extracellular
Definition: extcelln.cpp:18
hoc_List * section_list
Definition: init.cpp:102
int nrn_is_valid_section_ptr(void *)
Definition: cxprop.cpp:335
struct Prop Prop
struct Node Node
Datum * nrn_prop_datum_alloc(int type, int count, Prop *p)
Definition: cxprop.cpp:289
double nrn_diameter(Node *)
Definition: cabcode.cpp:432
struct Point_process Point_process
int nrn_global_ncell
Definition: init.cpp:103
void nrn_prop_datum_free(int type, Datum *ppd)
Definition: cxprop.cpp:313
Node * nrn_parent_node(Node *)
Definition: treeset.cpp:838
int cvode_active_
Definition: fadvance.cpp:163
struct Section Section
int use_sparse13
Definition: treeset.cpp:71
void nrn_prop_data_free(int type, double *pd)
Definition: cxprop.cpp:306
void nrn_section_free(Section *)
Definition: cxprop.cpp:331
int use_cachevec
Definition: treeset.cpp:63
int secondorder
Definition: init.cpp:96
double section_length(Section *)
Definition: cabcode.cpp:387
Section * sec_alloc()
Definition: solve.cpp:476
Section * nrn_section_alloc()
Definition: cxprop.cpp:324
struct Pt3d Pt3d
struct Extnode Extnode
double * nrn_prop_data_alloc(int type, int count, Prop *p)
Definition: cxprop.cpp:277
double ** _a_matelm
Definition: section.h:201
double ** _b_matelm
Definition: section.h:202
double * _b
Definition: section.h:198
double ** _x21
Definition: section.h:204
double ** _x12
Definition: section.h:203
double * _a
Definition: section.h:197
double * param
Definition: section.h:190
double * v
Definition: section.h:196
double ** _d
Definition: section.h:199
double ** _rhs
Definition: section.h:200
Definition: section.h:133
struct NrnThread * _nt
Definition: section.h:158
double * _v
Definition: section.h:140
struct Extnode * extnode
Definition: section.h:161
struct Node * _classical_parent
Definition: section.h:157
double _v_temp
Definition: section.h:143
double * _rhs
Definition: section.h:146
double _area
Definition: section.h:141
int eqn_index_
Definition: section.h:149
double * _a_matelm
Definition: section.h:147
Section * sec
Definition: section.h:155
int v_node_index
Definition: section.h:175
struct Prop * prop
Definition: section.h:152
Section * child
Definition: section.h:153
double * _b_matelm
Definition: section.h:148
double * _d
Definition: section.h:145
double _rinv
Definition: section.h:142
int sec_node_index_
Definition: section.h:177
Represent main neuron object computed by single thread.
Definition: multicore.h:58
Definition: hocdec.h:227
Object * ob
Definition: section.h:267
Section * sec
Definition: section.h:263
void * nvi_
Definition: section.h:269
void * presyn_
Definition: section.h:268
void * _vnt
Definition: section.h:270
Node * node
Definition: section.h:264
Prop * prop
Definition: section.h:265
Definition: section.h:214
Datum * dparam
Definition: section.h:220
short unused1
Definition: section.h:217
double * param
Definition: section.h:219
Object * ob
Definition: section.h:225
int param_size
Definition: section.h:218
long _alloc_seq
Definition: section.h:224
short type
Definition: section.h:216
struct Prop * next
Definition: section.h:215
Definition: section.h:67
float z
Definition: section.h:68
double arc
Definition: section.h:69
float x
Definition: section.h:68
float y
Definition: section.h:68
float d
Definition: section.h:68
int order
Definition: section.h:52
short volatile_mark
Definition: section.h:54
short recalc_area_
Definition: section.h:53
struct Node ** pnode
Definition: section.h:51
struct Node * parentnode
Definition: section.h:50
struct Prop * prop
Definition: section.h:63
void * volatile_ptr
Definition: section.h:55
struct Pt3d * logical_connection
Definition: section.h:60
short pt3d_bsize
Definition: section.h:58
struct Section * child
Definition: section.h:43
short npt3d
Definition: section.h:57
struct Section * parentsec
Definition: section.h:42
struct Section * sibling
Definition: section.h:46
short nnode
Definition: section.h:41
struct Pt3d * pt3d
Definition: section.h:59
int refcount
Definition: section.h:40
Definition: hocdec.h:177