1 #include <../../nrnconf.h> 10 #define loc(x,y,z)((z) + (y) * grid->size_z + (x) * grid->size_z * grid->size_y) 36 if(threaded_reactions_tasks !=
NULL)
40 SAFE_FREE(threaded_reactions_tasks[k].onset);
41 SAFE_FREE(threaded_reactions_tasks[k].offset);
70 for (r = ecs_reactions; r !=
NULL; r = tmp)
100 unsigned char* subregion,
102 int mc3d_region_size,
double* mc3d_mults)
118 if(i==species_ids[0])
120 if (mc3d_region_size > 0)
126 r->
mc3d_mults = (
double**)malloc(
sizeof(
double*)*(num_species + num_params));
128 for(
int row = 0;
row < num_species + num_params;
row++)
130 r->
mc3d_mults[
row] = (
double*)malloc(
sizeof(
double)*mc3d_region_size);
131 for(
int c = 0;
c < mc3d_region_size;
c++, mult_idx++)
139 else if(subregion ==
NULL)
160 for(i = 0; i < num_species + num_params; i++)
166 if(j==species_ids[i])
181 int num_params,
int* species_id,
183 int mc3d_region_size,
double* mc3d_mults,
187 mc3d_start_indices, mc3d_region_size, mc3d_mults);
216 int num_params,
int* species_id,
217 unsigned char* my_subregion,
238 for(react = ecs_reactions; react !=
NULL; react = react ->
next)
245 const int tasks_per_thread = (react_count) / n;
247 const int extra = react_count %
n;
253 for(k = 0, load = 0, react = ecs_reactions; react !=
NULL; react = react ->
next)
259 if(load >= tasks_per_thread + (extra>k))
273 if(k == n - 1 && react ->
next ==
NULL)
292 unsigned int i,
j,
k,
n, start_idx, stop_idx, offset_idx;
293 double temp, ge_value, val_to_set;
297 double* states_cache =
NULL;
298 double* params_cache =
NULL;
299 double* states_cache_dx =
NULL;
300 double* results_array =
NULL;
301 double* results_array_dx =
NULL;
302 double* mc_mults_array =
NULL;
303 double dx = FLT_EPSILON;
310 for(react = ecs_reactions; react !=
NULL; react = react ->
next)
351 for(i = start_idx; i <= stop_idx; i++)
371 react->
reaction(states_cache, params_cache, results_array, mc_mults_array);
375 states_cache_dx[
j] += dx;
377 react->
reaction(states_cache_dx, params_cache, results_array_dx, mc_mults_array);
382 pd = (results_array_dx[
k] - results_array[
k])/dx;
383 m_set_val(jacobian, k, j, (j==k) - dt*pd);
385 states_cache_dx[
j] -= dx;
504 for(i = start_idx; i <= stop_idx; i++)
520 react->
reaction(states_cache, params_cache, results_array,
NULL);
524 states_cache_dx[
j] += dx;
526 react->
reaction(states_cache_dx, params_cache, results_array_dx,
NULL);
531 pd = (results_array_dx[
k] - results_array[
k])/dx;
532 m_set_val(jacobian, k, j, (j==k) - dt*pd);
534 states_cache_dx[
j] -= dx;
640 double dt = (*dt_ptr);
647 if(threaded_reactions_tasks !=
NULL)
704 for (i = 0; i < grid_size; i++) {
720 grid_states = grid->
states;
723 for (i = 0; i < grid_size; i++) {
724 y[
i] = grid_states[
i];
742 const unsigned char calculate_rhs = ydot ==
NULL ? 0 : 1;
743 states = orig_states;
747 grid_states = grid->
states;
751 for (i = 0; i < grid_size; i++) {
752 grid_states[
i] = states[
i];
758 if (!calculate_rhs) {
762 states = orig_states;
765 if(threaded_reactions_tasks !=
NULL){
770 grid_states = grid->
states;
772 for(i = 0; i < grid_size; i++)
774 ydot[
i] += (grid_states[
i] - states[
i])/dt;
775 grid_states[
i] = states[
i];
782 states = orig_states;
810 double dx = g->
dx, dy = g->
dy, dz = g->
dz;
811 int i,
j,
k, stop_i, stop_j, stop_k;
814 double rate_x = dc_x / (dx * dx);
815 double rate_y = dc_y / (dy * dy);
816 double rate_z = dc_z / (dz * dz);
819 int index, prev_i, prev_j, prev_k, next_i ,next_j, next_k;
820 double div_x, div_y, div_z;
823 stop_i = num_states_x - 1;
824 stop_j = num_states_y - 1;
825 stop_k = num_states_z - 1;
827 for (i = 0, index = 0, prev_i = num_states_y*num_states_z, next_i = num_states_y*num_states_z;
828 i < num_states_x; i++) {
830 div_x = (i==0||i==stop_i)?2.:1.;
832 for(j = 0, prev_j = index + num_states_z, next_j = index + num_states_z; j < num_states_y; j++) {
833 div_y = (j==0||j==stop_j)?2.:1.;
835 for(k = 0, prev_k = index + 1, next_k = index + 1; k < num_states_z;
836 k++, index++, prev_i++, next_i++, prev_j++, next_j++) {
837 div_z = (k==0||k==stop_k)?2.:1.;
841 ydot[
index] += rate_x * (states[prev_i] -
842 2.0 * states[
index] + states[next_i])/div_x;
846 ydot[
index] += rate_y * (states[prev_j] -
847 2.0 * states[
index] + states[next_j])/div_y;
851 ydot[
index] += rate_z * (states[prev_k] -
852 2.0 * states[
index] + states[next_k])/div_z;
854 next_k = (k==stop_k-1)?index:index+2;
859 prev_j = index - num_states_z;
860 next_j = (j==stop_j-1)?prev_j:index + num_states_z;
862 prev_i = index - num_states_y*num_states_z;
863 next_i = (i==stop_i-1)?prev_i:index+num_states_y*num_states_z;
867 for (i = 0, index = 0, prev_i = 0, next_i = num_states_y*num_states_z;
868 i < num_states_x; i++) {
869 for(j = 0, prev_j = index - num_states_z, next_j = index + num_states_z; j < num_states_y; j++) {
871 for(k = 0, prev_k = index - 1, next_k = index + 1; k < num_states_z;
872 k++, index++, prev_i++, next_i++, prev_j++, next_j++, next_k++, prev_k++) {
874 if(i==0||i==stop_i||j==0||j==stop_j||k==0||k==stop_k)
881 ydot[
index] += rate_x * (states[prev_i] -
882 2.0 * states[
index] + states[next_i]);
884 ydot[
index] += rate_y * (states[prev_j] -
885 2.0 * states[
index] + states[next_j]);
887 ydot[
index] += rate_z * (states[prev_k] -
888 2.0 * states[
index] + states[next_k]);
891 prev_j = index - num_states_z;
892 next_j = index + num_states_z;
894 prev_i = index - num_states_y*num_states_z;
895 next_i = index + num_states_y*num_states_z;
965 const unsigned char calculate_rhs = RHS ==
NULL ? 0 : 1;
967 states = orig_states;
972 grid_states = grid->
states;
976 for (i = 0; i < grid_size; i++) {
977 grid_states[
i] = states[
i];
983 if (!calculate_rhs) {
987 states = orig_states;
991 if(threaded_reactions_tasks !=
NULL){
1034 const double u_diag,
const double lbc_diag,
const double lbc_u_diag,
1035 const double ubc_l_diag,
const double ubc_diag,
double*
const b,
double*
const c)
1040 c[0] = lbc_u_diag/lbc_diag;
1041 b[0] = b[0]/lbc_diag;
1045 c[
i] = u_diag/(diag-l_diag*c[i-1]);
1046 b[
i] = (b[
i]-l_diag*b[i-1])/(diag-l_diag*c[i-1]);
1048 b[N-1] = (b[N-1]-ubc_l_diag*b[N-2])/(ubc_diag-ubc_l_diag*c[N-2]);
1053 b[
i]=b[
i]-c[
i]*b[i+1];
1116 double div_y, div_z;
1120 for(x=0; x<g->
size_x; x++)
1127 yp = (y==g->
size_y-1)?y-1:y+1;
1128 ym = (y==0)?y+1:y-1;
1129 div_y = (y==0||y==g->
size_y-1)?2.:1.;
1139 zp = (z==g->
size_z-1)?z-1:z+1;
1140 zm = (z==0)?z+1:z-1;
1141 div_z = (z==0||z==g->
size_z-1)?2.:1.;
1155 - 2.*state[
IDX(0,y,z)]
1156 + state[
IDX(0,ym,z)])/div_y
1158 - 2.*state[
IDX(0,y,z)]
1159 + state[
IDX(0,y,zm)])/div_z);
1162 RHS[0] += dt*(g->
dc_x/
SQ(g->
dx))*(state[
IDX(1,y,z)] - state[
IDX(0,y,z)]);
1168 - 2.*state[
IDX(x,y,z)]
1169 + state[
IDX(x,ym,z)])/div_y
1171 - 2.*state[
IDX(x,y,z)]
1172 + state[
IDX(x,y,zm)])/div_z);
1180 for(x=1; x<g->
size_x-1; x++)
1183 __builtin_prefetch(&(state[
IDX(x+
PREFETCH,y,z)]), 0, 1);
1184 __builtin_prefetch(&(state[
IDX(x+
PREFETCH,yp,z)]), 0, 0);
1185 __builtin_prefetch(&(state[
IDX(x+
PREFETCH,ym,z)]), 0, 0);
1187 RHS[x] = state[
IDX(x,y,z)]
1188 + dt*((g->
dc_x/
SQ(g->
dx))*(state[
IDX(x+1,y,z)] - 2.*state[
IDX(x,y,z)] + state[
IDX(x-1,y,z)])/2.
1189 + (g->
dc_y/
SQ(g->
dy))*(state[
IDX(x,yp,z)] - 2.*state[
IDX(x,y,z)] + state[
IDX(x,ym,z)])/div_y
1219 for(y=0; y<g->
size_y; y++)
1226 RHS[0] = state[x + z*g->
size_x];
1234 RHS[0] = state[x + z*g->
size_x]
1245 for(y=1; y<g->
size_y-1; y++)
1277 for(z=0; z<g->
size_z; z++)
1285 RHS[0] = state[y + g->
size_y*x];
1306 for(z=1; z<g->
size_z-1; z++)
1325 int sizej = data -> sizej;
1327 double* state_in = ecs_adi_dir-> states_in;
1328 double* state_out = ecs_adi_dir-> states_out;
1329 int offset = ecs_adi_dir -> line_size;
1330 double* scratchpad = data -> scratchpad;
1331 void (*ecs_dg_adi_dir)(
ECS_Grid_node*, double,
int,
int,
double const *
const,
double*
const,
double*
const) = ecs_adi_dir -> ecs_dg_adi_dir;
1332 for (k = start; k <
stop; k++)
1336 ecs_dg_adi_dir(g, dt, i, j, state_in, &state_out[k*offset], scratchpad);
1361 for (k = 0; k < NUM_THREADS-1; k++)
uint64_t * mc3d_indices_offsets
virtual void variable_step_ode_solve(double *RHS, double dt)=0
virtual void scatter_grid_concentrations()=0
void TaskQueue_sync(TaskQueue *q)
virtual void variable_step_diffusion(const double *states, double *ydot)=0
#define m_set_val(A, i, j, val)
unsigned int num_params_involved
static philox4x32_key_t k
void(* ECSReactionRate)(double *, double *, double *, double *)
ECSAdiDirection * ecs_adi_dir
Grid_node * Parallel_grids[100]
int const size_t const size_t n
virtual void do_grid_currents(double *, double, int)=0
void clear_multicompartment_reaction()
#define v_set_val(x, i, val)
unsigned int num_species_involved
static double v_get(void *v)
static char scratch[MAXLINE+1]
virtual void set_num_threads(const int n)=0
struct ECSAdiDirection * ecs_adi_dir_z
struct ECSAdiGridData * ecs_tasks
virtual void hybrid_connections()=0
virtual void apply_node_flux3D(double dt, double *states)=0
struct ECSAdiDirection * ecs_adi_dir_y
unsigned char * subregion
void initialize_multicompartment_reaction()
#define m_get_val(A, i, j)
void(* ecs_dg_adi_dir)(ECS_Grid_node *, const double, const int, const int, double const *const, double *const, double *const)
void TaskQueue_add_task(TaskQueue *q, void *(*task)(void *), void *args, void *result)
struct ECSAdiDirection * ecs_adi_dir_x
static double jacobian(void *v)
void do_multicompartment_reactions(double *)