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