NEURON
grids.h
Go to the documentation of this file.
1 /******************************************************************
2 Author: Austin Lachance
3 Date: 10/28/16
4 Description: Header File for grids.cpp. Allows access to Grid_node
5 and Flux_pair structs and their respective functions
6 ******************************************************************/
7 #include <stdio.h>
8 #include <assert.h>
9 #include <nrnmpi.h>
10 
11 #include <nrnwrap_Python.h>
12 
13 #define SAFE_FREE(ptr){if((ptr)!=NULL) free(ptr);}
14 #define IDX(x,y,z) ((z) + (y) * g->size_z + (x) * g->size_z * g->size_y)
15 #define INDEX(x,y,z) ((z) + (y) * grid->size_z + (x) * grid->size_z * grid->size_y)
16 #define ALPHA(x,y,z) (g->get_alpha(g->alpha,IDX(x,y,z)))
17 #define VOLFRAC(idx) (g->get_alpha(g->alpha,idx))
18 #define TORT(idx) (g->get_permeability(g->permeability,idx))
19 #define PERM(x,y,z) (g->get_permeability(g->permeability,IDX(x,y,z)))
20 #define SQ(x) ((x)*(x))
21 #define CU(x) ((x)*(x)*(x))
22 #define TRUE 1
23 #define FALSE 0
24 #define TORTUOSITY 2
25 #define VOLUME_FRACTION 3
26 #define ICS_ALPHA 4
27 
28 #define NEUMANN 0
29 #define DIRICHLET 1
30 
31 #define MAX(a,b) ((a)>(b)?(a):(b))
32 #define MIN(a,b) ((a)<(b)?(a):(b))
33 
34 typedef struct {
35  PyObject_HEAD
36  void* ho_;
37  union {
38  double x_;
39  char* s_;
40  void* ho_;
41  double* px_;
42  }u;
43  void* sym_; // for functions and arrays
44  void* iteritem_; // enough info to carry out Iterator protocol
45  int nindex_; // number indices seen so far (or narg)
46  int* indices_; // one fewer than nindex_
47  int type_; // 0 HocTopLevelInterpreter, 1 HocObject
48  // 2 function (or TEMPLATE)
49  // 3 array
50  // 4 reference to number
51  // 5 reference to string
52  // 6 reference to hoc object
53  // 7 forall section iterator
54  // 8 pointer to a hoc scalar
55  // 9 incomplete pointer to a hoc array (similar to 3)
56 } PyHocObject;
57 
58 typedef struct Hybrid_data {
60  long* indices1d;
62  long* indices3d;
63  double* rates;
64  double* volumes1d;
65  double* volumes3d;
66 } Hybrid_data;
67 
68 typedef struct Flux_pair {
69  double *flux; // Value of flux
70  int grid_index; // Location in grid
71 } Flux;
72 
73 typedef struct {
74  double* destination; /* memory loc to transfer concentration to */
75  long source; /* index in grid for source */
77 
78 typedef struct {
79  long destination; /* index in grid */
80  double* source; /* memory loc of e.g. ica */
81  double scale_factor;
83 
84 typedef void (*ReactionRate)(double**, double**, double**, double*, double*, double*, double*, double**, double);
85 typedef void (*ECSReactionRate)(double*, double*, double*, double*);
86 typedef struct Reaction {
87  struct Reaction* next;
89  unsigned int num_species_involved;
90  unsigned int num_params_involved;
91  double** species_states;
92  unsigned char* subregion;
93  unsigned int region_size;
95  double** mc3d_mults;
96 } Reaction;
97 
98 typedef struct {
99  double* copyFrom;
100  long copyTo;
101 } AdiLineData;
102 
103 typedef struct {
104  /*TODO: Support for mixed boundaries and by edge (maybe even by voxel)*/
105  unsigned char type;
106  double value;
108 
109 class Grid_node {
110  public:
112 
113  double *states; // Array of doubles representing Grid space
114  double *states_x;
115  double *states_y;
116  double *states_z; //TODO: This is only used by ICS, is it necessary?
117  double *states_cur;
118  int size_x; // Size of X dimension
119  int size_y; // Size of Y dimension
120  int size_z; // Size of Z dimension
121  double dc_x; // X diffusion constant
122  double dc_y; // Y diffusion constant
123  double dc_z; // Z diffusion constant
124  double dx; // ∆X
125  double dy; // ∆Y
126  double dz; // ∆Z
128  bool hybrid;
133  ssize_t num_concentrations, num_currents;
134 
135  /*used for MPI implementation*/
142  double* all_currents;
143 
144  /*Extension to handle a variable diffusion characteristics of a grid*/
145  unsigned char VARIABLE_ECS_VOLUME; /*FLAG which variable volume fraction
146  methods should be used*/
147  /*diffusion characteristics are arrays of a single value or
148  * the number of voxels (size_x*size_y*size_z)*/
149  double *permeability; /* 1/tortuosities^2 squared
150  D_eff = D_free*permeability */
151  double *alpha; /* volume fractions */
152  /*Function that will be assigned when the grid is created to either return
153  * the single value or the value at a given index*/
154  double (*get_alpha)(double*,int);
155  double (*get_permeability)(double*,int);
156  double atolscale;
157 
164 
165  int insert(int grid_list_index);
168  double * node_flux_scale;
169  PyObject ** node_flux_src;
170 
171 
172  virtual ~Grid_node(){};
173  virtual void set_diffusion(double*, int) = 0;
174  virtual void set_num_threads(const int n) = 0;
175  virtual void do_grid_currents(double*, double, int) = 0;
176  virtual void apply_node_flux3D(double dt, double* states) = 0;
177  virtual void volume_setup() = 0;
178  virtual int dg_adi() = 0;
179  virtual void variable_step_diffusion(const double* states, double* ydot) = 0;
180  virtual void variable_step_ode_solve(double* RHS, double dt) = 0;
181  virtual void scatter_grid_concentrations() = 0;
182  virtual void hybrid_connections() = 0;
183  virtual void variable_step_hybrid_connections(const double* cvode_states_3d, double* const ydot_3d, const double* cvode_states_1d, double *const ydot_1d) = 0;
184 };
185 
186 class ECS_Grid_node : public Grid_node{
187  public:
188  //Data for DG-ADI
189  ECS_Grid_node();
190  ECS_Grid_node(PyHocObject*, int, int, int, double, double, double,
191  double, double, double, PyHocObject*, PyHocObject*, int,
192  double, double);
193  ~ECS_Grid_node();
198 
199  //Data for multicompartment reactions
217 
218  void set_num_threads(const int n);
219  void do_grid_currents(double *, double, int);
220  void apply_node_flux3D(double dt, double* states);
221  void volume_setup();
222  int dg_adi();
223  void variable_step_diffusion(const double* states, double* ydot);
224  void variable_step_ode_solve(double* RHS, double dt);
225  void variable_step_hybrid_connections(const double* cvode_states_3d, double* const ydot_3d, const double* cvode_states_1d, double *const ydot_1d);
226  void scatter_grid_concentrations();
227  void hybrid_connections();
228  void set_diffusion(double*, int);
231  void do_multicompartment_reactions(double*);
232  void initialize_multicompartment_reaction();
233  void clear_multicompartment_reaction();
234  int add_multicompartment_reaction(int, int*, int);
235  double* set_rxd_currents(int, int*, PyHocObject**);
236 };
237 
238 typedef struct ECSAdiDirection{
239  void (*ecs_dg_adi_dir)(ECS_Grid_node*, const double, const int, const int, double const * const, double* const, double* const);
240  double* states_in;
241  double* states_out;
244 
245 typedef struct ECSAdiGridData{
246  int start, stop;
247  double* state;
249  int sizej;
251  double* scratchpad;
253 
254 class ICS_Grid_node : public Grid_node{
255  public:
256  ICS_Grid_node();
257  ~ICS_Grid_node();
258  //fractional volumes
259  double* _ics_alphas;
260  //stores the positive x,y, and z neighbors for each node. [node0_x, node0_y, node0_z, node1_x ...]
261  long* _neighbors;
262 
263  /*Line definitions from Python. In pattern of [line_start_node, line_length, ...]
264  Array is sorted from longest to shortest line */
268 
269  //Lengths of _sorted_lines arrays. Used to find thread start and stop indices
273 
274  //maximum line length for scratchpad memory allocation
276 
277  //total number of nodes for this grid
279 
280  //indices for thread start and stop positions
282 
283  //Data for DG-ADI
288 
289  ICS_Grid_node(PyHocObject*, long, long*, long*, long, long*, long,
290  long*, long, double*, double*, double, bool, double,
291  double*);
292  void divide_x_work(const int nthreads);
293  void divide_y_work(const int nthreads);
294  void divide_z_work(const int nthreads);
295  void set_num_threads(const int n);
296  void do_grid_currents(double*, double, int);
297  void apply_node_flux3D(double dt, double* states);
298  void volume_setup();
299  int dg_adi();
300  void variable_step_diffusion(const double* states, double* ydot);
301  void variable_step_ode_solve(double* RHS, double dt);
302  void hybrid_connections();
303  void variable_step_hybrid_connections(const double* cvode_states_3d, double* const ydot_3d, const double* cvode_states_1d, double *const ydot_1d);
304  void scatter_grid_concentrations();
306  void set_diffusion(double*, int);
307  void do_multicompartment_reactions(double*);
308  void initialize_multicompartment_reaction();
309  void clear_multicompartment_reaction();
310  int add_multicompartment_reaction(int, int*, int);
311  double* set_rxd_currents(int, int*, PyHocObject**);
312 };
313 
314 typedef struct ICSAdiDirection{
315  void (*ics_dg_adi_dir)(ICS_Grid_node* g, int, int, int, double, double*, double*, double*, double*, double*, double*);
316  double* states_in;
317  double* states_out;
318  double* deltas;
323  double dc;
324  double* dcgrid;
325  double d;
327 
328 
329 typedef struct ICSAdiGridData{
330  //Start and stop node indices for lines
331  int line_start, line_stop;
332  //Where to start in the ordered_nodes array
334  double* state;
337  double* scratchpad;
338  double* RHS;
339  double* l_diag;
340  double* diag;
341  double* u_diag;
342  //double* deltas;
344 
345 /***** GLOBALS *******************************************************************/
346 extern double *dt_ptr; // Universal ∆t
347 extern double *t_ptr; // Universal t
348 
349 // static int N = 100; // Number of grid_lists (size of Parallel_grids)
350 extern Grid_node *Parallel_grids[100];// Array of Grid_node * lists
351 /*********************************************************************************/
352 
353 
354 // Set the global ∆t
355 void make_dt_ptr(PyHocObject* my_dt_ptr);
356 
357 
358 // Create a single Grid_node
359 /* Parameters: Python object that includes array of double pointers,
360  size of x, y, and z dimensions
361  x, y, and z diffusion constants
362  delta x, delta y, and delta z*/
363 
364 // Free a single Grid_node "grid"
365 //void free_Grid(Grid_node *grid);
366 
367 // Insert a Grid_node "new_Grid" into the list located at grid_list_index in Parallel_grids
368 extern "C" int ECS_insert(int grid_list_index, PyHocObject* my_states, int my_num_states_x,
369  int my_num_states_y, int my_num_states_z, double my_dc_x, double my_dc_y,
370  double my_dc_z, double my_dx, double my_dy, double my_dz,
371  PyHocObject* my_alpha, PyHocObject* my_permeability, int, double, double);
372 
373 Grid_node *ICS_make_Grid(PyHocObject* my_states, long num_nodes, long* neighbors,
374  long* x_line_defs, long x_lines_length, long* y_line_defs, long y_lines_length, long* z_line_defs,
375  long z_lines_length, double* dcs, double dx, bool is_diffusable, double atolscale, double* ics_alphas);
376 
377 // Insert an ICS_Grid_node "new_Grid" into the list located at grid_list_index in Parallel_grids
378 extern "C" int ICS_insert(int grid_list_index, PyHocObject* my_states, long num_nodes, long* neighbors,
379  long* x_line_defs, long x_lines_length, long* y_line_defs, long y_lines_length, long* z_line_defs,
380  long z_lines_length, double* dcs, double dx, bool is_diffusable, double atolscale, double* ics_alphas);
381 
382 extern "C" int ICS_insert_inhom(int grid_list_index, PyHocObject* my_states, long num_nodes, long* neighbors,
383  long* x_line_defs, long x_lines_length, long* y_line_defs, long y_lines_length, long* z_line_defs,
384  long z_lines_length, double* dcs, double dx, bool is_diffusable, double atolscale, double* ics_alphas);
385 
386 
387 
388 // Set the diffusion coefficients for a given grid_id
389 extern "C" int set_diffusion(int, int, double*, int);
390 
391 // Delete a specific Grid_node "find" from the list "head"
392 int remove(Grid_node **head, Grid_node *find);
393 
394 // Destroy the list located at list_index and free all memory
395 void empty_list(int list_index);
396 
397 void apply_node_flux(int, long*, double*, PyObject**, double, double*);
int grid_index
Definition: grids.h:70
uint64_t * mc3d_indices_offsets
Definition: grids.h:94
double value
Definition: grids.h:106
double dc_z
Definition: grids.h:123
int * react_offsets
Definition: grids.h:201
void empty_list(int list_index)
Definition: grids.cpp:742
double d
Definition: grids.h:325
long * _sorted_y_lines
Definition: grids.h:266
int ordered_start
Definition: grids.h:333
bool hybrid
Definition: grids.h:128
unsigned char multicompartment_inititalized
Definition: grids.h:208
long * indices1d
Definition: grids.h:60
double * state
Definition: grids.h:334
virtual ~Grid_node()
Definition: grids.h:172
int * proc_offsets
Definition: grids.h:137
double * states_z
Definition: grids.h:116
int * proc_induced_current_offset
Definition: grids.h:212
struct Reaction Reaction
double * states_in
Definition: grids.h:316
double * local_induced_currents
Definition: grids.h:215
long * _neighbors
Definition: grids.h:261
long _line_length_max
Definition: grids.h:275
double * states_out
Definition: grids.h:317
double * ics_scale_factors
Definition: grids.h:162
int line_size
Definition: grids.h:242
int ECS_insert(int grid_list_index, PyHocObject *my_states, int my_num_states_x, int my_num_states_y, int my_num_states_z, double my_dc_x, double my_dc_y, double my_dc_z, double my_dx, double my_dy, double my_dz, PyHocObject *my_alpha, PyHocObject *my_permeability, int, double, double)
Definition: grids.cpp:195
long * ordered_start_stop_indices
Definition: grids.h:321
#define g
Definition: passive0.cpp:23
double * states_y
Definition: grids.h:115
ICSAdiDirection * ics_adi_dir
Definition: grids.h:336
struct Flux_pair Flux
void make_dt_ptr(PyHocObject *my_dt_ptr)
void
double * states_x
Definition: grids.h:114
double * states_cur
Definition: grids.h:117
int ics_num_segs
Definition: grids.h:163
void run_threaded_ics_dg_adi(ICS_Grid_node *g, ICSAdiDirection *ics_adi_dir)
long * current_dest
Definition: grids.h:141
int size_x
Definition: grids.h:118
long * _sorted_x_lines
Definition: grids.h:265
double * permeability
Definition: grids.h:149
int64_t * ics_surface_nodes_per_seg
Definition: grids.h:158
struct Reaction * next
Definition: grids.h:87
struct ICSAdiDirection * ics_adi_dir_y
Definition: grids.h:286
long * ordered_line_defs
Definition: grids.h:319
void set_num_threads(const int n)
Definition: rxd.cpp:1287
int * induced_currents_index
Definition: grids.h:209
void * ho_
Definition: grids.h:40
int size_y
Definition: grids.h:119
ECS_Grid_node * g
Definition: grids.h:248
int * proc_num_reactions
Definition: grids.h:205
unsigned int num_params_involved
Definition: grids.h:90
int * proc_flux_offsets
Definition: grids.h:139
void apply_node_flux(int, long *, double *, PyObject **, double, double *)
Definition: rxd.cpp:321
int total_reaction_states
Definition: grids.h:207
int nindex_
Definition: grids.h:45
ulong uint64_t
Concentration_Pair * concentration_list
Definition: grids.h:131
void(* ECSReactionRate)(double *, double *, double *, double *)
Definition: grids.h:85
ECSAdiDirection * ecs_adi_dir
Definition: grids.h:250
void * sym_
Definition: grids.h:43
unsigned int region_size
Definition: grids.h:93
long * line_start_stop_indices
Definition: grids.h:322
long * _nodes_per_thread
Definition: grids.h:281
void start()
Definition: hel2mos.cpp:205
double ** ics_current_seg_ptrs
Definition: grids.h:161
double * diag
Definition: grids.h:340
double dt
Definition: init.cpp:123
double * state
Definition: grids.h:247
double * all_reaction_states
Definition: grids.h:213
unsigned char VARIABLE_ECS_VOLUME
Definition: grids.h:145
int ICS_insert_inhom(int grid_list_index, PyHocObject *my_states, long num_nodes, long *neighbors, long *x_line_defs, long x_lines_length, long *y_line_defs, long y_lines_length, long *z_line_defs, long z_lines_length, double *dcs, double dx, bool is_diffusable, double atolscale, double *ics_alphas)
Definition: grids.cpp:365
struct ICSAdiGridData ICSAdiGridData
void * iteritem_
Definition: grids.h:44
int * reaction_indices
Definition: grids.h:203
Current_Triple * current_list
Definition: grids.h:132
double * _ics_alphas
Definition: grids.h:259
struct ECSAdiDirection ECSAdiDirection
double dc_x
Definition: grids.h:121
int const size_t const size_t n
Definition: nrngsl.h:12
Grid_node * Parallel_grids[100]
Definition: grids.cpp:16
int num_all_currents
Definition: grids.h:136
double * induced_currents_scale
Definition: grids.h:216
int * indices_
Definition: grids.h:46
int
Definition: nrnmusic.cpp:71
static double insert(void *v)
Definition: tqueue.cpp:22
double * volumes3d
Definition: grids.h:65
double * source
Definition: grids.h:80
char * s_
Definition: grids.h:39
double * RHS
Definition: grids.h:338
double * states
Definition: grids.h:113
double * deltas
Definition: grids.h:318
double dz
Definition: grids.h:126
long destination
Definition: grids.h:79
long * _sorted_z_lines
Definition: grids.h:267
double * volumes1d
Definition: grids.h:64
double dc
Definition: grids.h:323
double * node_flux_scale
Definition: grids.h:168
double * alpha
Definition: grids.h:151
long _y_lines_length
Definition: grids.h:271
unsigned int num_species_involved
Definition: grids.h:89
double * l_diag
Definition: grids.h:339
struct Hybrid_data Hybrid_data
int set_volume_fraction(int grid_list_index, int grid_id, PyHocObject *my_alpha)
Definition: grids.cpp:457
double * dcgrid
Definition: grids.h:324
long * indices3d
Definition: grids.h:62
unsigned char type
Definition: grids.h:105
int64_t * ics_surface_nodes_per_seg_start_indices
Definition: grids.h:159
double * states_out
Definition: grids.h:241
double * destination
Definition: grids.h:74
ECSReactionRate reaction
Definition: grids.h:88
int line_stop
Definition: grids.h:331
int induced_current_count
Definition: grids.h:210
double * scratchpad
Definition: grids.h:337
double * states_in
Definition: grids.h:240
double * rates
Definition: grids.h:63
double dc_y
Definition: grids.h:122
int induced_idx
Definition: grids.h:200
int set_tortuosity(int grid_list_index, int grid_id, PyHocObject *my_permeability)
Definition: grids.cpp:391
double * px_
Definition: grids.h:41
int size_z
Definition: grids.h:120
struct ECSAdiGridData ECSAdiGridData
long _num_nodes
Definition: grids.h:278
struct ECSAdiDirection * ecs_adi_dir_z
Definition: grids.h:197
int node_flux_count
Definition: grids.h:166
int * proc_num_fluxes
Definition: grids.h:140
struct ICSAdiDirection ICSAdiDirection
struct ECSAdiGridData * ecs_tasks
Definition: grids.h:194
int react_offset_count
Definition: grids.h:202
double ** species_states
Definition: grids.h:91
int set_diffusion(int, int, double *, int)
Definition: grids.cpp:375
bool diffusable
Definition: grids.h:127
double * copyFrom
Definition: grids.h:99
PyObject_HEAD void * ho_
Definition: grids.h:36
long * ordered_nodes
Definition: grids.h:320
BoundaryConditions * bc
Definition: grids.h:129
double * scratchpad
Definition: grids.h:251
double * all_currents
Definition: grids.h:142
Grid_node * next
Definition: grids.h:111
long _z_lines_length
Definition: grids.h:272
struct ICSAdiDirection * ics_adi_dir_x
Definition: grids.h:285
ssize_t num_currents
Definition: grids.h:133
PyObject ** node_flux_src
Definition: grids.h:169
double ** ics_concentration_seg_ptrs
Definition: grids.h:160
Hybrid_data * hybrid_data
Definition: grids.h:130
long copyTo
Definition: grids.h:100
#define RHS(i)
Definition: multisplit.cpp:64
long num_1d_indices
Definition: grids.h:59
struct ICSAdiDirection * ics_adi_dir_z
Definition: grids.h:287
double dy
Definition: grids.h:125
int * proc_num_currents
Definition: grids.h:138
struct ECSAdiDirection * ecs_adi_dir_y
Definition: grids.h:196
unsigned char * subregion
Definition: grids.h:92
double x_
Definition: grids.h:38
void apply_node_flux3D(Grid_node *, double, double *)
int find(const int, const int, const int, const int, const int)
int * all_reaction_indices
Definition: grids.h:204
int * proc_num_reaction_states
Definition: grids.h:206
long * node_flux_idx
Definition: grids.h:167
int type_
Definition: grids.h:47
double * flux
Definition: grids.h:69
int * proc_induced_current_count
Definition: grids.h:211
long _x_lines_length
Definition: grids.h:270
void(* ReactionRate)(double **, double **, double **, double *, double *, double *, double *, double **, double)
Definition: grids.h:84
ICS_Grid_node * g
Definition: grids.h:335
double * induced_currents
Definition: grids.h:214
long * num_3d_indices_per_1d_seg
Definition: grids.h:61
struct ECSAdiDirection * ecs_adi_dir_x
Definition: grids.h:195
int ICS_insert(int grid_list_index, PyHocObject *my_states, long num_nodes, long *neighbors, long *x_line_defs, long x_lines_length, long *y_line_defs, long y_lines_length, long *z_line_defs, long z_lines_length, double *dcs, double dx, bool is_diffusable, double atolscale, double *ics_alphas)
Definition: grids.cpp:354
double scale_factor
Definition: grids.h:81
double * t_ptr
Definition: grids.cpp:15
double dx
Definition: grids.h:124
struct ICSAdiGridData * ics_tasks
Definition: grids.h:284
double * states
Definition: rxd.cpp:62
double * u_diag
Definition: grids.h:341
Grid_node * ICS_make_Grid(PyHocObject *my_states, long num_nodes, long *neighbors, long *x_line_defs, long x_lines_length, long *y_line_defs, long y_lines_length, long *z_line_defs, long z_lines_length, double *dcs, double dx, bool is_diffusable, double atolscale, double *ics_alphas)
double * dt_ptr
Definition: grids.cpp:14
double atolscale
Definition: grids.h:156
double ** mc3d_mults
Definition: grids.h:95