1 #include <../../nrnconf.h>
12 #define loc(x, y, z) ((z) + (y) *grid->size_z + (x) *grid->size_z * grid->size_y)
93 unsigned char* subregion,
94 uint64_t* mc3d_start_indices,
110 if (
i == species_ids[0]) {
111 if (mc3d_region_size > 0) {
115 (num_species + num_params));
118 sizeof(uint64_t) * (num_species + num_params));
119 r->
mc3d_mults = (
double**) malloc(
sizeof(
double*) * (num_species + num_params));
121 for (
int row = 0;
row < num_species + num_params;
row++) {
122 r->
mc3d_mults[
row] = (
double*) malloc(
sizeof(
double) * mc3d_region_size);
123 for (
int c = 0;
c < mc3d_region_size;
c++, mult_idx++) {
129 }
else if (subregion ==
NULL) {
147 for (
i = 0;
i < num_species + num_params;
i++) {
151 if (
j == species_ids[
i])
169 uint64_t* mc3d_start_indices,
170 int mc3d_region_size,
212 unsigned char* my_subregion,
215 list_idx, num_species, num_params, species_id, f, my_subregion,
NULL, 0,
NULL);
234 if (react_count == 0)
238 const int tasks_per_thread = (react_count) /
n;
240 const int extra = react_count %
n;
250 if (load >= tasks_per_thread + (extra >
k)) {
279 unsigned int i,
j,
k,
n, start_idx, stop_idx, offset_idx;
280 double temp, ge_value, val_to_set;
284 double* states_cache =
NULL;
285 double* params_cache =
NULL;
286 double* states_cache_dx =
NULL;
287 double* results_array =
NULL;
288 double* results_array_dx =
NULL;
289 double* mc_mults_array =
NULL;
290 double dx = FLT_EPSILON;
292 std::vector<double> x{};
293 std::vector<double> b{};
326 for (
i = start_idx;
i <= stop_idx;
i++) {
343 react->
reaction(states_cache, params_cache, results_array, mc_mults_array);
346 states_cache_dx[
j] += dx;
347 memset(results_array_dx,
354 b[
j] =
dt * results_array[
j];
357 pd = (results_array_dx[
k] - results_array[
k]) / dx;
360 states_cache_dx[
j] -= dx;
387 b[
k] = b[
k] - ge_value * b[
j];
416 free(states_cache_dx);
419 free(results_array_dx);
420 free(mc_mults_array);
453 for (
i = start_idx;
i <= stop_idx;
i++) {
466 react->
reaction(states_cache, params_cache, results_array,
NULL);
469 states_cache_dx[
j] += dx;
470 memset(results_array_dx,
473 react->
reaction(states_cache_dx, params_cache, results_array_dx,
NULL);
474 b[
j] =
dt * results_array[
j];
477 pd = (results_array_dx[
k] - results_array[
k]) / dx;
480 states_cache_dx[
j] -= dx;
507 b[
k] = b[
k] - ge_value * b[
j];
535 free(states_cache_dx);
538 free(results_array_dx);
568 double dt = (*dt_ptr);
631 for (
i = 0;
i < grid_size;
i++) {
647 grid_states = grid->
states;
650 for (
i = 0;
i < grid_size;
i++) {
651 y[
i] = grid_states[
i];
670 const unsigned char calculate_rhs = ydot ==
NULL ? 0 : 1;
675 grid_states = grid->
states;
679 for (
i = 0;
i < grid_size;
i++) {
686 if (!calculate_rhs) {
697 grid_states = grid->
states;
699 for (
i = 0;
i < grid_size;
i++) {
736 double dx = g->
dx, dy = g->
dy, dz = g->
dz;
737 int i,
j,
k, stop_i, stop_j, stop_k;
740 double rate_x = dc_x / (dx * dx);
741 double rate_y = dc_y / (dy * dy);
742 double rate_z = dc_z / (dz * dz);
745 int index, prev_i, prev_j, prev_k, next_i, next_j, next_k;
746 double div_x, div_y, div_z;
749 stop_i = num_states_x - 1;
750 stop_j = num_states_y - 1;
751 stop_k = num_states_z - 1;
755 prev_i = num_states_y * num_states_z,
756 next_i = num_states_y * num_states_z;
760 div_x = (
i == 0 ||
i == stop_i) ? 2. : 1.;
762 for (
j = 0, prev_j =
index + num_states_z, next_j =
index + num_states_z;
765 div_y = (
j == 0 ||
j == stop_j) ? 2. : 1.;
767 for (
k = 0, prev_k =
index + 1, next_k =
index + 1;
k < num_states_z;
768 k++,
index++, prev_i++, next_i++, prev_j++, next_j++) {
769 div_z = (
k == 0 ||
k == stop_k) ? 2. : 1.;
772 ydot[
index] += rate_x *
777 ydot[
index] += rate_y *
782 ydot[
index] += rate_z *
789 prev_j =
index - num_states_z;
790 next_j = (
j == stop_j - 1) ? prev_j :
index + num_states_z;
792 prev_i =
index - num_states_y * num_states_z;
793 next_i = (
i == stop_i - 1) ? prev_i :
index + num_states_y * num_states_z;
796 for (
i = 0,
index = 0, prev_i = 0, next_i = num_states_y * num_states_z;
i < num_states_x;
798 for (
j = 0, prev_j =
index - num_states_z, next_j =
index + num_states_z;
801 for (
k = 0, prev_k =
index - 1, next_k =
index + 1;
k < num_states_z;
802 k++,
index++, prev_i++, next_i++, prev_j++, next_j++, next_k++, prev_k++) {
803 if (
i == 0 ||
i == stop_i ||
j == 0 ||
j == stop_j ||
k == 0 ||
k == stop_k) {
807 ydot[
index] += rate_x *
810 ydot[
index] += rate_y *
813 ydot[
index] += rate_z *
817 prev_j =
index - num_states_z;
818 next_j =
index + num_states_z;
820 prev_i =
index - num_states_y * num_states_z;
821 next_i =
index + num_states_y * num_states_z;
897 const unsigned char calculate_rhs =
RHS ==
NULL ? 0 : 1;
904 grid_states = grid->
states;
908 for (
i = 0;
i < grid_size;
i++) {
915 if (!calculate_rhs) {
961 const double lbc_diag,
962 const double lbc_u_diag,
963 const double ubc_l_diag,
964 const double ubc_diag,
970 c[0] = lbc_u_diag / lbc_diag;
971 b[0] = b[0] / lbc_diag;
973 for (
i = 1;
i < N - 1;
i++) {
974 c[
i] = u_diag / (
diag - l_diag *
c[
i - 1]);
975 b[
i] = (b[
i] - l_diag * b[
i - 1]) / (
diag - l_diag *
c[
i - 1]);
977 b[N - 1] = (b[N - 1] - ubc_l_diag * b[N - 2]) / (ubc_diag - ubc_l_diag *
c[N - 2]);
980 for (
i = N - 2;
i >= 0;
i--) {
981 b[
i] = b[
i] -
c[
i] * b[
i + 1];
1044 double const*
const state,
1046 double*
const scratch) {
1050 double div_y, div_z;
1053 (y == 0 || z == 0 || y == g->
size_y - 1 || z == g->
size_z - 1)) {
1054 for (x = 0; x < g->
size_x; x++)
1060 yp = (y == g->
size_y - 1) ? y - 1 : y + 1;
1061 ym = (y == 0) ? y + 1 : y - 1;
1062 div_y = (y == 0 || y == g->
size_y - 1) ? 2. : 1.;
1069 zp = (z == g->
size_z - 1) ? z - 1 : z + 1;
1070 zm = (z == 0) ? z + 1 : z - 1;
1071 div_z = (z == 0 || z == g->
size_z - 1) ? 2. : 1.;
1083 (state[
IDX(0, yp, z)] - 2. * state[
IDX(0, y, z)] + state[
IDX(0, ym, z)]) /
1086 (state[
IDX(0, y, zp)] - 2. * state[
IDX(0, y, z)] + state[
IDX(0, y, zm)]) /
1093 dt * ((g->
dc_x /
SQ(g->
dx)) * (state[
IDX(x - 1, y, z)] - state[
IDX(x, y, z)]) +
1095 (state[
IDX(x, yp, z)] - 2. * state[
IDX(x, y, z)] + state[
IDX(x, ym, z)]) /
1098 (state[
IDX(x, y, zp)] - 2. * state[
IDX(x, y, z)] + state[
IDX(x, y, zm)]) /
1105 for (x = 1; x < g->
size_x - 1; x++) {
1107 __builtin_prefetch(&(state[
IDX(x +
PREFETCH, y, z)]), 0, 1);
1108 __builtin_prefetch(&(state[
IDX(x +
PREFETCH, yp, z)]), 0, 0);
1109 __builtin_prefetch(&(state[
IDX(x +
PREFETCH, ym, z)]), 0, 0);
1111 RHS[x] = state[
IDX(x, y, z)] +
1114 (state[
IDX(x + 1, y, z)] - 2. * state[
IDX(x, y, z)] +
1115 state[
IDX(x - 1, y, z)]) /
1118 (state[
IDX(x, yp, z)] - 2. * state[
IDX(x, y, z)] + state[
IDX(x, ym, z)]) /
1121 (state[
IDX(x, y, zp)] - 2. * state[
IDX(x, y, z)] + state[
IDX(x, y, zm)]) /
1139 g->
size_x, -r / 2.0, 1.0 + r, -r / 2.0, 1.0, 0, 0, 1.0,
RHS, scratch);
1157 double const*
const state,
1159 double*
const scratch) {
1164 (x == 0 || z == 0 || x == g->
size_x - 1 || z == g->
size_z - 1)) {
1165 for (y = 0; y < g->
size_y; y++)
1193 for (y = 1; y < g->
size_y - 1; y++) {
1233 double const*
const state,
1235 double*
const scratch) {
1240 (x == 0 || y == 0 || x == g->
size_x - 1 || y == g->
size_y - 1)) {
1241 for (z = 0; z < g->
size_z; z++)
1272 for (z = 1; z < g->
size_z - 1; z++) {
1297 int start =
data->start;
1298 int stop =
data->stop;
1302 int sizej =
data->sizej;
1304 double* state_in = ecs_adi_dir->
states_in;
1307 double* scratchpad =
data->scratchpad;
1308 void (*ecs_dg_adi_dir)(
1309 ECS_Grid_node*, double, int, int,
double const*
const,
double*
const,
double*
const) =
1311 for (
k = start;
k < stop;
k++) {
1314 ecs_dg_adi_dir(g,
dt,
i,
j, state_in, &state_out[
k * offset], scratchpad);
struct ECSAdiDirection * ecs_adi_dir_z
void initialize_multicompartment_reaction()
struct ECSAdiDirection * ecs_adi_dir_y
struct ECSAdiGridData * ecs_tasks
void clear_multicompartment_reaction()
struct ECSAdiDirection * ecs_adi_dir_x
void do_multicompartment_reactions(double *)
virtual void apply_node_flux3D(double dt, double *states)=0
virtual void hybrid_connections()=0
virtual void variable_step_diffusion(const double *states, double *ydot)=0
virtual void set_num_threads(const int n)=0
virtual void do_grid_currents(double *, double, int)=0
virtual void variable_step_ode_solve(double *RHS, double dt)=0
virtual void scatter_grid_concentrations()=0
static double jacobian(void *v)
Grid_node * Parallel_grids[100]
void(double *, double *, double *, double *) ECSReactionRate
int const size_t const size_t n
void TaskQueue_add_task(TaskQueue *q, void *(*task)(void *), void *args, void *result)
void TaskQueue_sync(TaskQueue *q)
void(* ecs_dg_adi_dir)(ECS_Grid_node *, const double, const int, const int, double const *const, double *const, double *const)
ECSAdiDirection * ecs_adi_dir
uint64_t * mc3d_indices_offsets
unsigned char * subregion
unsigned int num_params_involved
unsigned int num_species_involved
ECSReactionRate * reaction