45 return permeability[idx];
70 states_x = (
double*) malloc(
sizeof(
double) * my_num_states_x * my_num_states_y *
72 states_y = (
double*) malloc(
sizeof(
double) * my_num_states_x * my_num_states_y *
74 states_cur = (
double*) malloc(
sizeof(
double) * my_num_states_x * my_num_states_y *
99 if (PyFloat_Check(my_permeability)) {
102 permeability[0] = PyFloat_AsDouble((PyObject*) my_permeability);
115 if (PyFloat_Check(my_alpha)) {
116 alpha = (
double*) malloc(
sizeof(
double));
117 alpha[0] = PyFloat_AsDouble((PyObject*) my_alpha);
161 sizeof(
double) *
MAX(my_num_states_x,
MAX(my_num_states_y, my_num_states_z)));
229 return new_Grid->
insert(grid_list_index);
247 double* ics_alphas) {
309 long x_max = x_line_defs[1];
310 long y_max = y_line_defs[1];
311 long z_max = z_line_defs[1];
312 long xy_max = (x_max > y_max) ? x_max : y_max;
359 if (dcgrid ==
NULL) {
400 double* ics_alphas) {
417 return new_Grid->
insert(grid_list_index);
434 double* ics_alphas) {
450 return new_Grid->
insert(grid_list_index);
454 extern "C" int set_diffusion(
int grid_list_index,
int grid_id,
double*
dc,
int length) {
457 while (
id < grid_id) {
463 node->set_diffusion(
dc, length);
470 while (
id < grid_id) {
484 if (PyFloat_Check(my_permeability)) {
486 double new_permeability = PyFloat_AsDouble((PyObject*) my_permeability);
494 permeability[0] = PyFloat_AsDouble((PyObject*) my_permeability);
521 while (
id < grid_id) {
532 if (PyFloat_Check(my_alpha)) {
534 alpha[0] = PyFloat_AsDouble((PyObject*) my_alpha);
536 alpha = (
double*) malloc(
sizeof(
double));
537 alpha[0] = PyFloat_AsDouble((PyObject*) my_alpha);
592 int64_t* nodes_per_seg,
593 int64_t* nodes_per_seg_start_indices,
594 PyObject* neuron_pointers) {
597 ssize_t
n = (ssize_t) PyList_Size(neuron_pointers);
601 for (
i = 0;
i < index_in_list;
i++) {
605 g->ics_surface_nodes_per_seg = nodes_per_seg;
607 g->ics_surface_nodes_per_seg_start_indices = nodes_per_seg_start_indices;
609 g->ics_concentration_seg_ptrs = (
double**) malloc(
n *
sizeof(
double*));
610 for (
i = 0;
i <
n;
i++) {
611 g->ics_concentration_seg_ptrs[
i] =
612 ((
PyHocObject*) PyList_GET_ITEM(neuron_pointers,
i))->u.px_;
620 PyObject* neuron_pointers,
621 double* scale_factors) {
624 ssize_t
n = (ssize_t) PyList_Size(neuron_pointers);
627 for (
i = 0;
i < index_in_list;
i++) {
630 g->ics_scale_factors = scale_factors;
632 g->ics_current_seg_ptrs = (
double**) malloc(
n *
sizeof(
double*));
634 for (
i = 0;
i <
n;
i++) {
635 g->ics_current_seg_ptrs[
i] = ((
PyHocObject*) PyList_GET_ITEM(neuron_pointers,
i))->u.px_;
643 PyObject* grid_indices,
644 PyObject* neuron_pointers) {
656 ssize_t
n = (ssize_t) PyList_Size(grid_indices);
660 for (
i = 0;
i < index_in_list;
i++) {
665 free(
g->concentration_list);
669 g->num_concentrations =
n;
673 for (
i = 0;
i <
n;
i++) {
675 g->concentration_list[
i].source =
PyInt_AS_LONG(PyList_GET_ITEM(grid_indices,
i));
676 g->concentration_list[
i].destination =
677 ((
PyHocObject*) PyList_GET_ITEM(neuron_pointers,
i))->u.px_;
684 PyObject* grid_indices,
685 PyObject* neuron_pointers,
686 PyObject* scale_factors) {
699 ssize_t
n = (ssize_t) PyList_Size(grid_indices);
704 for (
i = 0;
i < index_in_list;
i++) {
709 free(
g->current_list);
717 for (
i = 0;
i <
n;
i++) {
718 g->current_list[
i].destination =
PyInt_AS_LONG(PyList_GET_ITEM(grid_indices,
i));
719 g->current_list[
i].scale_factor = PyFloat_AS_DOUBLE(PyList_GET_ITEM(scale_factors,
i));
720 g->current_list[
i].source = ((
PyHocObject*) PyList_GET_ITEM(neuron_pointers,
i))->u.px_;
736 nrnmpi_int_allgather_inplace(
g->proc_num_currents, 1);
738 g->proc_offsets[0] = 0;
740 g->proc_offsets[
i] =
g->proc_offsets[
i - 1] +
g->proc_num_currents[
i - 1];
741 g->num_all_currents =
g->proc_offsets[
i - 1] +
g->proc_num_currents[
i - 1];
744 free(
g->current_dest);
745 free(
g->all_currents);
746 g->current_dest = (
long*) malloc(
g->num_all_currents *
sizeof(
long));
747 g->all_currents = (
double*) malloc(
g->num_all_currents *
sizeof(
double));
750 for (
i = 0;
i <
n;
i++) {
751 dests[
i] =
g->current_list[
i].destination;
753 nrnmpi_long_allgatherv_inplace(
g->current_dest,
g->proc_num_currents,
g->proc_offsets);
755 free(
g->all_currents);
756 g->all_currents = (
double*) malloc(
sizeof(
double) *
g->num_currents);
757 g->num_all_currents =
g->num_currents;
760 free(
g->all_currents);
761 g->all_currents = (
double*) malloc(
sizeof(
double) *
g->num_currents);
762 g->num_all_currents =
g->num_currents;
770 *head = (*head)->
next;
801 while (*head !=
NULL) {
803 *head = (*head)->
next;
841 for (
i = 0;
i <
n;
i++) {
851 double* val = d->
val;
856 val[
i] =
c[
i].scale_factor * (*
c[
i].source) / grid->
alpha[
c[
i].destination];
860 val[
i] =
c[
i].scale_factor * (*
c[
i].source) /
864 val[
i] =
c[
i].scale_factor * (*
c[
i].source) / grid->
alpha[0];
895 tasks[
i].
onset =
i * tasks_per_thread;
896 tasks[
i].
offset =
MIN((
i + 1) * tasks_per_thread, m);
914 for (
i = 0;
i <
n;
i++)
917 for (
i = 0;
i <
n;
i++) {
923 for (
i = 0;
i <
n;
i++)
934 int* current_indices,
937 double volume_fraction;
945 for (
i = 0;
i < current_count;
i++) {
1054 for (
i = 0;
i <
n;
i++) {
1077 for (
i = 0,
j = 0;
i < nstates;
i++,
j +=
step) {
1112 int total_react = 0;
1122 nrnmpi_int_allgather_inplace(proc_num_init, 1);
1124 if (!proc_num_init[
i])
1184 nrnmpi_dbl_allgatherv_inplace(all_scales,
1188 nrnmpi_int_allgatherv_inplace(all_indices,
1291 int new_min_index = 0;
1292 int min_element = thread_sizes[0];
1293 for (
int i = 0;
i < nthreads;
i++) {
1294 if (min_element > thread_sizes[
i]) {
1295 min_element = thread_sizes[
i];
1299 return new_min_index;
1305 int* nodes_per_thread = (
int*) calloc(nthreads,
sizeof(
int));
1307 int* lines_per_thread = (
int*) calloc(nthreads,
sizeof(
int));
1309 int* thread_idx_counter = (
int*) calloc(nthreads,
sizeof(
int));
1313 int** thread_line_defs = (
int**) malloc(nthreads *
sizeof(
int*));
1321 line_thread_id[
i / 2] = min_index;
1322 lines_per_thread[min_index] += 1;
1326 for (
i = 0;
i < nthreads;
i++) {
1327 thread_line_defs[
i] = (
int*) malloc(lines_per_thread[
i] * 2 *
sizeof(
int));
1335 thread_idx = line_thread_id[
i / 2];
1336 line_idx = thread_idx_counter[thread_idx];
1339 thread_idx_counter[thread_idx] += 2;
1343 int ordered_line_def_counter = 0;
1344 for (
i = 0;
i < nthreads;
i++) {
1345 for (
j = 0;
j < lines_per_thread[
i] * 2;
j++) {
1347 ordered_line_def_counter++;
1357 long line_start_node;
1358 for (
i = 2;
i < nthreads * 2;
i += 2) {
1366 lines_per_thread[
i / 2] * 2;
1370 int ordered_node_idx_counter = 0;
1372 for (
i = 0;
i < nthreads;
i++) {
1373 for (
j = 0;
j < lines_per_thread[
i] * 2;
j += 2) {
1374 current_node = thread_line_defs[
i][
j];
1377 ordered_node_idx_counter++;
1378 for (
k = 1;
k < thread_line_defs[
i][
j + 1];
k++) {
1382 ordered_node_idx_counter++;
1388 for (
i = 0;
i < nthreads;
i++) {
1389 free(thread_line_defs[
i]);
1391 free(thread_line_defs);
1392 free(nodes_per_thread);
1393 free(lines_per_thread);
1394 free(thread_idx_counter);
1400 int* nodes_per_thread = (
int*) calloc(nthreads,
sizeof(
int));
1402 int* lines_per_thread = (
int*) calloc(nthreads,
sizeof(
int));
1404 int* thread_idx_counter = (
int*) calloc(nthreads,
sizeof(
int));
1408 int** thread_line_defs = (
int**) malloc(nthreads *
sizeof(
int*));
1416 line_thread_id[
i / 2] = min_index;
1417 lines_per_thread[min_index] += 1;
1421 for (
i = 0;
i < nthreads;
i++) {
1422 thread_line_defs[
i] = (
int*) malloc(lines_per_thread[
i] * 2 *
sizeof(
int));
1430 thread_idx = line_thread_id[
i / 2];
1431 line_idx = thread_idx_counter[thread_idx];
1434 thread_idx_counter[thread_idx] += 2;
1438 int ordered_line_def_counter = 0;
1439 for (
i = 0;
i < nthreads;
i++) {
1440 for (
j = 0;
j < lines_per_thread[
i] * 2;
j++) {
1442 ordered_line_def_counter++;
1454 long line_start_node;
1455 for (
i = 2;
i < nthreads * 2;
i += 2) {
1463 (lines_per_thread[
i / 2] * 2);
1467 int ordered_node_idx_counter = 0;
1469 for (
i = 0;
i < nthreads;
i++) {
1470 for (
j = 0;
j < lines_per_thread[
i] * 2;
j += 2) {
1471 current_node = thread_line_defs[
i][
j];
1474 ordered_node_idx_counter++;
1475 for (
k = 1;
k < thread_line_defs[
i][
j + 1];
k++) {
1476 current_node =
_neighbors[(current_node * 3) + 1];
1479 ordered_node_idx_counter++;
1485 for (
i = 0;
i < nthreads;
i++) {
1486 free(thread_line_defs[
i]);
1488 free(thread_line_defs);
1489 free(nodes_per_thread);
1490 free(lines_per_thread);
1491 free(thread_idx_counter);
1497 int* nodes_per_thread = (
int*) calloc(nthreads,
sizeof(
int));
1499 int* lines_per_thread = (
int*) calloc(nthreads,
sizeof(
int));
1501 int* thread_idx_counter = (
int*) calloc(nthreads,
sizeof(
int));
1505 int** thread_line_defs = (
int**) malloc(nthreads *
sizeof(
int*));
1513 line_thread_id[
i / 2] = min_index;
1514 lines_per_thread[min_index] += 1;
1519 for (
i = 0;
i < nthreads;
i++) {
1520 thread_line_defs[
i] = (
int*) malloc(lines_per_thread[
i] * 2 *
sizeof(
int));
1528 thread_idx = line_thread_id[
i / 2];
1529 line_idx = thread_idx_counter[thread_idx];
1532 thread_idx_counter[thread_idx] += 2;
1536 int ordered_line_def_counter = 0;
1537 for (
i = 0;
i < nthreads;
i++) {
1538 for (
j = 0;
j < lines_per_thread[
i] * 2;
j++) {
1540 ordered_line_def_counter++;
1552 long line_start_node;
1553 for (
i = 2;
i < nthreads * 2;
i += 2) {
1561 lines_per_thread[
i / 2] * 2;
1565 int ordered_node_idx_counter = 0;
1567 for (
i = 0;
i < nthreads;
i++) {
1568 for (
j = 0;
j < lines_per_thread[
i] * 2;
j += 2) {
1569 current_node = thread_line_defs[
i][
j];
1572 ordered_node_idx_counter++;
1573 for (
k = 1;
k < thread_line_defs[
i][
j + 1];
k++) {
1574 current_node =
_neighbors[(current_node * 3) + 2];
1577 ordered_node_idx_counter++;
1583 for (
i = 0;
i < nthreads;
i++) {
1584 free(thread_line_defs[
i]);
1586 free(thread_line_defs);
1587 free(nodes_per_thread);
1588 free(lines_per_thread);
1589 free(thread_idx_counter);
1603 for (
i = 0;
i <
n;
i++) {
1649 int seg_start_index, seg_stop_index;
1653 for (
i = 0;
i <
n;
i++) {
1657 for (
j = seg_start_index;
j < seg_stop_index;
j++) {
1720 double*
const ydot_3d,
1721 const double* cvode_states_1d,
1722 double*
const ydot_1d) {
1728 double total_seg_concentration;
1729 double average_seg_concentration;
1730 int seg_start_index, seg_stop_index;
1734 for (
i = 0;
i <
n;
i++) {
1735 total_seg_concentration = 0.0;
1738 for (
j = seg_start_index;
j < seg_stop_index;
j++) {
1741 average_seg_concentration = total_seg_concentration / (seg_stop_index - seg_start_index);
double * induced_currents
unsigned char multicompartment_inititalized
double * induced_currents_scale
void apply_node_flux3D(double dt, double *states)
void set_tortuosity(PyHocObject *)
int induced_current_count
int * all_reaction_indices
int * proc_induced_current_count
void do_grid_currents(double *, double, int)
void variable_step_diffusion(const double *states, double *ydot)
struct ECSAdiDirection * ecs_adi_dir_z
double * set_rxd_currents(int, int *, PyHocObject **)
void initialize_multicompartment_reaction()
void set_volume_fraction(PyHocObject *)
struct ECSAdiDirection * ecs_adi_dir_y
int add_multicompartment_reaction(int, int *, int)
struct ECSAdiGridData * ecs_tasks
void clear_multicompartment_reaction()
void variable_step_ode_solve(double *RHS, double dt)
int total_reaction_states
void variable_step_hybrid_connections(const double *cvode_states_3d, double *const ydot_3d, const double *cvode_states_1d, double *const ydot_1d)
int * proc_num_reaction_states
int * proc_induced_current_offset
struct ECSAdiDirection * ecs_adi_dir_x
void set_num_threads(const int n)
void hybrid_connections()
void scatter_grid_concentrations()
double * all_reaction_states
double * local_induced_currents
void set_diffusion(double *, int)
void do_multicompartment_reactions(double *)
int * induced_currents_index
double(* get_alpha)(double *, int)
int64_t * ics_surface_nodes_per_seg
Concentration_Pair * concentration_list
double(* get_permeability)(double *, int)
Hybrid_data * hybrid_data
int64_t * ics_surface_nodes_per_seg_start_indices
PyObject ** node_flux_src
unsigned char VARIABLE_ECS_VOLUME
int insert(int grid_list_index)
double ** ics_current_seg_ptrs
double * ics_scale_factors
Current_Triple * current_list
double ** ics_concentration_seg_ptrs
ssize_t num_concentrations
struct ICSAdiDirection * ics_adi_dir_x
void run_threaded_ics_dg_adi(struct ICSAdiDirection *)
void scatter_grid_concentrations()
void hybrid_connections()
void apply_node_flux3D(double dt, double *states)
struct ICSAdiDirection * ics_adi_dir_y
void divide_y_work(const int nthreads)
struct ICSAdiGridData * ics_tasks
struct ICSAdiDirection * ics_adi_dir_z
void variable_step_ode_solve(double *RHS, double dt)
void variable_step_diffusion(const double *states, double *ydot)
void divide_x_work(const int nthreads)
void set_diffusion(double *, int)
void do_grid_currents(double *, double, int)
void set_num_threads(const int n)
void divide_z_work(const int nthreads)
void variable_step_hybrid_connections(const double *cvode_states_3d, double *const ydot_3d, const double *cvode_states_1d, double *const ydot_1d)
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)
static double get_permeability_array(double *permeability, int idx)
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)
double * _rxd_induced_currents_scale
static int find_min_element_index(const int thread_sizes[], const int nthreads)
int set_tortuosity(int grid_list_index, int grid_id, PyHocObject *my_permeability)
void ics_set_grid_concentrations(int grid_list_index, int index_in_list, int64_t *nodes_per_seg, int64_t *nodes_per_seg_start_indices, PyObject *neuron_pointers)
static double get_alpha_array(double *alpha, int idx)
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 bc, double bc_value, double atolscale)
int * _rxd_induced_currents_ecs_idx
void make_time_ptr(PyHocObject *my_dt_ptr, PyHocObject *my_t_ptr)
void empty_list(int list_index)
int * _rxd_induced_currents_grid
static void * gather_currents(void *dataptr)
void set_grid_currents(int grid_list_index, int index_in_list, PyObject *grid_indices, PyObject *neuron_pointers, PyObject *scale_factors)
int set_diffusion(int grid_list_index, int grid_id, double *dc, int length)
static double get_alpha_scalar(double *alpha, int)
double * _rxd_induced_currents_ecs
void set_grid_concentrations(int grid_list_index, int index_in_list, PyObject *grid_indices, PyObject *neuron_pointers)
static double get_permeability_scalar(double *, int)
Grid_node * Parallel_grids[100]
void delete_by_id(int id)
int set_volume_fraction(int grid_list_index, int grid_id, PyHocObject *my_alpha)
void ics_set_grid_currents(int grid_list_index, int index_in_list, PyObject *neuron_pointers, double *scale_factors)
int remove(Grid_node **head, Grid_node *find)
void apply_node_flux(int, long *, double *, PyObject **, double, double *)
static Node * node(Object *)
int const size_t const size_t n
static philox4x32_key_t k
void TaskQueue_add_task(TaskQueue *q, void *(*task)(void *), void *args, void *result)
void TaskQueue_sync(TaskQueue *q)
void _ics_variable_hybrid_helper(ICS_Grid_node *, const double *, double *const, const double *, double *const)
void _ics_rhs_variable_step_helper(ICS_Grid_node *, double const *const, double *)
void ecs_run_threaded_dg_adi(const int, const int, ECS_Grid_node *, ECSAdiDirection *, const int)
void ecs_set_adi_tort(ECS_Grid_node *)
void ics_dg_adi_z(ICS_Grid_node *g, int, int, int, double, double *, double *, double *, double *, double *, double *)
void ecs_set_adi_vol(ECS_Grid_node *)
void run_threaded_deltas(ICS_Grid_node *g, ICSAdiDirection *ics_adi_dir)
void ics_ode_solve_helper(ICS_Grid_node *, double, double *)
void _rhs_variable_step_helper(Grid_node *, double const *const, double *)
void ics_dg_adi_x_inhom(ICS_Grid_node *g, int, int, int, double, double *, double *, double *, double *, double *, double *)
int find(const int, const int, const int, const int, const int)
void ics_dg_adi_z_inhom(ICS_Grid_node *g, int, int, int, double, double *, double *, double *, double *, double *, double *)
void ecs_set_adi_homogeneous(ECS_Grid_node *)
void _rhs_variable_step_helper_tort(Grid_node *, double const *const, double *)
void ics_dg_adi_y(ICS_Grid_node *g, int, int, int, double, double *, double *, double *, double *, double *, double *)
void _ics_hybrid_helper(ICS_Grid_node *)
void _rhs_variable_step_helper_vol(Grid_node *, double const *const, double *)
void ics_dg_adi_x(ICS_Grid_node *g, int, int, int, double, double *, double *, double *, double *, double *, double *)
void ics_dg_adi_y_inhom(ICS_Grid_node *g, int, int, int, double, double *, double *, double *, double *, double *, double *)
long * ordered_start_stop_indices
void(* ics_dg_adi_dir)(ICS_Grid_node *g, int, int, int, double, double *, double *, double *, double *, double *, double *)
long * line_start_stop_indices