1 #include <../../nrnconf.h> 20 extern "C" void set_hybrid_data(int64_t* num_1d_indices_per_grid, int64_t* num_3d_indices_per_grid, int64_t* hybrid_indices1d, int64_t* hybrid_indices3d, int64_t* num_3d_indices_per_1d_seg, int64_t* hybrid_grid_ids,
double* rates,
double* volumes1d,
double* volumes3d,
double* dxs)
24 int grid_id_check = 0;
29 int num_grid_3d_indices;
30 int num_grid_1d_indices;
37 if(
id == hybrid_grid_ids[grid_id_check])
39 num_grid_1d_indices = num_1d_indices_per_grid[grid_id_check];
40 num_grid_3d_indices = num_3d_indices_per_grid[grid_id_check];
49 grid->
hybrid_data->
rates = (
double*)malloc(
sizeof(
double)*num_grid_3d_indices);
56 for(i = 0, k = 0; i < num_grid_1d_indices; i++, index_ctr_1d++)
62 for (j = 0; j < num_3d_indices_per_1d_seg[index_ctr_1d]; j++, index_ctr_3d++, k++)
67 ((
ICS_Grid_node*)grid)->_ics_alphas[hybrid_indices3d[index_ctr_3d]] = volumes3d[index_ctr_3d]/dx;
86 const double* u_diag,
double* b,
double *
c)
90 c[0] = u_diag[0]/diag[0];
95 c[
i] = u_diag[
i]/(diag[
i]-l_diag[i-1]*c[i-1]);
96 b[
i] = (b[
i]-l_diag[i-1]*b[i-1])/(diag[i]-l_diag[i-1]*c[i-1]);
98 b[N-1] = (b[N-1]-l_diag[N-2]*b[N-2])/(diag[N-1]-l_diag[N-2]*c[N-2]);
104 b[
i]=b[
i]-c[
i]*b[i+1];
111 long ordered_index = node_start;
112 long current_index = -1;
113 long next_index = -1;
118 double current_alpha;
120 for(
int i = start;
i < stop - 1;
i += 2)
122 long line_start = ordered_nodes[ordered_index];
123 int line_length = line_defs[
i+1];
126 current_index = line_start;
128 next_index = ordered_nodes[ordered_index];
129 current_state = states[current_index];
130 next_state = states[next_index];
131 current_alpha = alphas[current_index];
132 next_alpha = alphas[next_index];
133 delta[current_index] = dc * next_alpha * current_alpha * (next_state -
current_state) / (next_alpha + current_alpha);
135 for(
int j = 1;
j < line_length - 1;
j++)
138 current_index = next_index;
139 next_index = ordered_nodes[ordered_index];
140 current_state = next_state;
141 next_state = states[next_index];
142 prev_alpha = current_alpha;
143 current_alpha = next_alpha;
144 next_alpha = alphas[next_index];
145 delta[current_index] = dc * ((next_alpha * current_alpha / (next_alpha + current_alpha)) * (next_state -
current_state) -
146 (prev_alpha * current_alpha / (prev_alpha + current_alpha)) * (current_state - prev_state));
150 delta[next_index] = dc * (next_alpha * current_alpha) * (current_state - next_state) / (next_alpha + current_alpha);
155 delta[line_start] = 0.0;
162 long ordered_index = node_start;
163 long current_index = -1;
164 long next_index = -1;
169 double current_alpha;
171 for(
int i = start;
i < stop - 1;
i += 2)
173 long line_start = ordered_nodes[ordered_index];
174 int line_length = line_defs[
i+1];
177 current_index = line_start;
179 next_index = ordered_nodes[ordered_index];
180 current_state = states[current_index];
181 next_state = states[next_index];
182 current_alpha = alphas[current_index];
183 next_alpha = alphas[next_index];
184 delta[current_index] = dc[next_index] * next_alpha * current_alpha * (next_state -
current_state) / (next_alpha + current_alpha);
186 for(
int j = 1;
j < line_length - 1;
j++)
189 current_index = next_index;
190 next_index = ordered_nodes[ordered_index];
191 current_state = next_state;
192 next_state = states[next_index];
193 prev_alpha = current_alpha;
194 current_alpha = next_alpha;
195 next_alpha = alphas[next_index];
196 delta[current_index] = dc[next_index] * (next_alpha * current_alpha * (next_state -
current_state)/(next_alpha + current_alpha)) -
197 dc[current_index] * (prev_alpha * current_alpha * (current_state - prev_state) / (prev_alpha + current_alpha));
201 delta[next_index] = dc[next_index] * (next_alpha * current_alpha) * (current_state - next_state) / (next_alpha + current_alpha);
206 delta[line_start] = 0.0;
219 double* deltas = ics_adi_dir->
deltas;
225 ics_find_deltas(line_start, line_stop, node_start, deltas, line_defs, ordered_nodes, states, ics_adi_dir->
dc, alphas);
227 ics_find_deltas(line_start, line_stop, node_start, deltas, line_defs, ordered_nodes, states, ics_adi_dir->
dcgrid, alphas);
242 for (i = 0; i < NUM_THREADS-1; i++)
253 void ics_dg_adi_x_inhom(
ICS_Grid_node*
g,
int line_start,
int line_stop,
int node_start,
double,
double*
states,
double*
RHS,
double* scratchpad,
double* u_diag,
double*
diag,
double* l_diag){
264 long next_index = -1;
265 long prev_index = -1;
273 long ordered_index = node_start;
274 for(
int i = line_start;
i < line_stop - 1;
i += 2)
276 long N = x_lines[
i+1];
277 long ordered_index_start = ordered_index;
278 for(
int j = 0;
j < N;
j++)
280 current_index = ordered_nodes[ordered_index];
281 RHS[
j] = (dt / alphas[current_index])*
282 (delta_x[current_index] /
SQ(dx)
283 + 2.0 * delta_y[current_index] /
SQ(dy)
284 + 2.0 * delta_z[current_index] /
SQ(dz))
285 + states[current_index] + states_cur[current_index];
289 ordered_index = ordered_index_start;
290 current_index = ordered_nodes[ordered_index];
292 next_index = ordered_nodes[ordered_index];
293 next = alphas[next_index] * dc[next_index] / (alphas[next_index] + alphas[current_index]);
294 diag[0] = 1.0 + dt * next /
SQ(dx);
295 u_diag[0] = -dt * next /
SQ(dx);
297 for(
int c = 1;
c < N - 1;
c++){
298 prev_index = current_index;
299 current_index = next_index;
300 next_index = ordered_nodes[ordered_index];
301 prev = alphas[prev_index] * dc[current_index] / (alphas[prev_index] + alphas[current_index]);
302 next = alphas[next_index] * dc[next_index] / (alphas[next_index] + alphas[current_index]);
303 l_diag[
c-1] = -dt*prev/
SQ(dx);
304 diag[
c] = 1. + dt*(prev +
next)/
SQ(dx);
305 u_diag[
c] = -dt*next/
SQ(dx);
308 prev = alphas[current_index] * dc[next_index] / (alphas[current_index] + alphas[next_index]);
309 diag[N-1] = 1.0 + dt * prev /
SQ(dx);
310 l_diag[N-2] = -dt * prev /
SQ(dx);
315 ordered_index = ordered_index_start;
316 for(
int k = 0;
k < N;
k++)
318 current_index = ordered_nodes[ordered_index];
319 states[current_index] = RHS[
k];
325 void ics_dg_adi_y_inhom(
ICS_Grid_node*
g,
int line_start,
int line_stop,
int node_start,
double,
double*
states,
double*
RHS,
double* scratchpad,
double* u_diag,
double*
diag,
double* l_diag){
332 long next_index = -1;
333 long prev_index = -1;
339 long ordered_index = node_start;
341 for(
int i = line_start;
i < line_stop - 1;
i += 2)
344 long ordered_index_start = ordered_index;
346 for(
int j = 0;
j < N;
j++)
348 current_index = ordered_y_nodes[ordered_index];
349 RHS[
j] = states[current_index] - dt * delta[current_index] / (alphas[current_index] *
SQ(dy));
353 ordered_index = ordered_index_start;
354 current_index = ordered_y_nodes[ordered_index];
356 next_index = ordered_y_nodes[ordered_index];
357 next = alphas[next_index] * dc[next_index] / (alphas[next_index] + alphas[current_index]);
358 diag[0] = 1.0 + dt * next /
SQ(dy);
359 u_diag[0] = -dt * next /
SQ(dy);
361 for(
int c = 1;
c < N - 1;
c++){
362 prev_index = current_index;
363 current_index = next_index;
364 next_index = ordered_y_nodes[ordered_index];
365 prev = alphas[prev_index] * dc[prev_index] / (alphas[prev_index] + alphas[current_index]);
366 next = alphas[next_index] * dc[next_index] / (alphas[next_index] + alphas[current_index]);
367 l_diag[
c-1] = -dt*prev/
SQ(dy);
368 diag[
c] = 1. + dt*(prev +
next)/
SQ(dy);
369 u_diag[
c] = -dt*next/
SQ(dy);
372 prev = alphas[current_index] * dc[current_index] / (alphas[current_index] + alphas[next_index]);
373 diag[N-1] = 1.0 + dt * prev /
SQ(dy);
374 l_diag[N-2] = -dt * prev /
SQ(dy);
378 ordered_index = ordered_index_start;
379 for(
int k = 0;
k < N;
k++)
381 current_index = ordered_y_nodes[ordered_index];
382 states[current_index] = RHS[
k];
388 void ics_dg_adi_z_inhom(
ICS_Grid_node*
g,
int line_start,
int line_stop,
int node_start,
double,
double*
states,
double*
RHS,
double* scratchpad,
double* u_diag,
double*
diag,
double* l_diag){
396 long next_index = -1;
397 long prev_index = -1;
402 long ordered_index = node_start;
403 for(
int i = line_start;
i< line_stop - 1;
i+=2)
406 long ordered_index_start = ordered_index;
408 for(
int j = 0;
j < N;
j++)
410 current_index = ordered_z_nodes[ordered_index];
411 RHS[
j] = states[current_index] - dt * delta[current_index] / (
SQ(dz) * alphas[current_index]);
415 ordered_index = ordered_index_start;
416 current_index = ordered_z_nodes[ordered_index];
418 next_index = ordered_z_nodes[ordered_index];
419 next = alphas[next_index] * dc[next_index] / (alphas[next_index] + alphas[current_index]);
420 diag[0] = 1.0 + dt * next /
SQ(dz);
421 u_diag[0] = -dt * next /
SQ(dz);
423 for(
int c = 1;
c < N - 1;
c++){
424 prev_index = current_index;
425 current_index = next_index;
426 next_index = ordered_z_nodes[ordered_index];
427 prev = alphas[prev_index] * dc[prev_index] / (alphas[prev_index] + alphas[current_index]);
428 next = alphas[next_index] * dc[next_index] / (alphas[next_index] + alphas[current_index]);
429 l_diag[
c-1] = -dt*prev/
SQ(dz);
430 diag[
c] = 1. + dt*(prev +
next)/
SQ(dz);
431 u_diag[
c] = -dt*next/
SQ(dz);
434 prev = alphas[current_index] * dc[current_index] / (alphas[current_index] + alphas[next_index]);
435 diag[N-1] = 1.0 + dt * prev /
SQ(dz);
436 l_diag[N-2] = -dt * prev /
SQ(dz);
439 ordered_index = ordered_index_start;
440 for(
int k = 0;
k < N;
k++)
442 current_index = ordered_z_nodes[ordered_index];
443 states[current_index] = RHS[
k];
450 void ics_dg_adi_x(
ICS_Grid_node*
g,
int line_start,
int line_stop,
int node_start,
double,
double*
states,
double*
RHS,
double* scratchpad,
double* u_diag,
double*
diag,
double* l_diag){
461 long next_index = -1;
462 long prev_index = -1;
470 long ordered_index = node_start;
471 for(
int i = line_start;
i < line_stop - 1;
i += 2)
473 long N = x_lines[
i+1];
474 long ordered_index_start = ordered_index;
475 for(
int j = 0;
j < N;
j++)
477 current_index = ordered_nodes[ordered_index];
478 RHS[
j] = (dt / alphas[current_index])*(delta_x[current_index] / (
SQ(dx)) + 2 * delta_y[current_index] /
SQ(dy) + 2 * delta_z[current_index] /
SQ(dz)) + states[current_index] + states_cur[current_index];
482 ordered_index = ordered_index_start;
483 current_index = ordered_nodes[ordered_index];
485 next_index = ordered_nodes[ordered_index];
486 next = alphas[next_index] * dc / (alphas[next_index] + alphas[current_index]);
487 diag[0] = 1.0 + dt * next /
SQ(dx);
488 u_diag[0] = -dt * next /
SQ(dx);
490 for(
int c = 1;
c < N - 1;
c++){
491 prev_index = current_index;
492 current_index = next_index;
493 next_index = ordered_nodes[ordered_index];
494 prev = alphas[prev_index] * dc / (alphas[prev_index] + alphas[current_index]);
495 next = alphas[next_index] * dc / (alphas[next_index] + alphas[current_index]);
496 l_diag[
c-1] = -dt*prev/
SQ(dx);
497 diag[
c] = 1. + dt*(prev +
next)/
SQ(dx);
498 u_diag[
c] = -dt*next/
SQ(dx);
501 prev = alphas[current_index] * dc / (alphas[current_index] + alphas[next_index]);
502 diag[N-1] = 1.0 + dt * prev /
SQ(dx);
503 l_diag[N-2] = -dt * prev /
SQ(dx);
508 ordered_index = ordered_index_start;
509 for(
int k = 0;
k < N;
k++)
511 current_index = ordered_nodes[ordered_index];
512 states[current_index] = RHS[
k];
518 void ics_dg_adi_y(
ICS_Grid_node*
g,
int line_start,
int line_stop,
int node_start,
double,
double*
states,
double*
RHS,
double* scratchpad,
double* u_diag,
double*
diag,
double* l_diag){
525 long next_index = -1;
526 long prev_index = -1;
532 long ordered_index = node_start;
534 for(
int i = line_start;
i < line_stop - 1;
i += 2)
537 long ordered_index_start = ordered_index;
539 for(
int j = 0;
j < N;
j++)
541 current_index = ordered_y_nodes[ordered_index];
542 RHS[
j] = states[current_index] - dt * delta[current_index] / (alphas[current_index] *
SQ(dy));
546 ordered_index = ordered_index_start;
547 current_index = ordered_y_nodes[ordered_index];
549 next_index = ordered_y_nodes[ordered_index];
550 next = alphas[next_index] * dc / (alphas[next_index] + alphas[current_index]);
551 diag[0] = 1.0 + dt * next /
SQ(dy);
552 u_diag[0] = -dt * next /
SQ(dy);
554 for(
int c = 1;
c < N - 1;
c++){
555 prev_index = current_index;
556 current_index = next_index;
557 next_index = ordered_y_nodes[ordered_index];
558 prev = alphas[prev_index] * dc / (alphas[prev_index] + alphas[current_index]);
559 next = alphas[next_index] * dc / (alphas[next_index] + alphas[current_index]);
560 l_diag[
c-1] = -dt*prev/
SQ(dy);
561 diag[
c] = 1. + dt*(prev +
next)/
SQ(dy);
562 u_diag[
c] = -dt*next/
SQ(dy);
565 prev = alphas[current_index] * dc / (alphas[current_index] + alphas[next_index]);
566 diag[N-1] = 1.0 + dt * prev /
SQ(dy);
567 l_diag[N-2] = -dt * prev /
SQ(dy);
571 ordered_index = ordered_index_start;
572 for(
int k = 0;
k < N;
k++)
574 current_index = ordered_y_nodes[ordered_index];
575 states[current_index] = RHS[
k];
581 void ics_dg_adi_z(
ICS_Grid_node*
g,
int line_start,
int line_stop,
int node_start,
double,
double*
states,
double*
RHS,
double* scratchpad,
double* u_diag,
double*
diag,
double* l_diag){
589 long next_index = -1;
590 long prev_index = -1;
595 long ordered_index = node_start;
596 for(
int i = line_start;
i< line_stop - 1;
i+=2)
599 long ordered_index_start = ordered_index;
601 for(
int j = 0;
j < N;
j++)
603 current_index = ordered_z_nodes[ordered_index];
604 RHS[
j] = states[current_index] - dt * delta[current_index] / (
SQ(dz) * alphas[current_index]);
608 ordered_index = ordered_index_start;
609 current_index = ordered_z_nodes[ordered_index];
611 next_index = ordered_z_nodes[ordered_index];
612 next = alphas[next_index] * dc / (alphas[next_index] + alphas[current_index]);
613 diag[0] = 1.0 + dt * next /
SQ(dz);
614 u_diag[0] = -dt * next /
SQ(dz);
616 for(
int c = 1;
c < N - 1;
c++){
617 prev_index = current_index;
618 current_index = next_index;
619 next_index = ordered_z_nodes[ordered_index];
620 prev = alphas[prev_index] * dc / (alphas[prev_index] + alphas[current_index]);
621 next = alphas[next_index] * dc / (alphas[next_index] + alphas[current_index]);
622 l_diag[
c-1] = -dt*prev/
SQ(dz);
623 diag[
c] = 1. + dt*(prev +
next)/
SQ(dz);
624 u_diag[
c] = -dt*next/
SQ(dz);
627 prev = alphas[current_index] * dc / (alphas[current_index] + alphas[next_index]);
628 diag[N-1] = 1.0 + dt * prev /
SQ(dz);
629 l_diag[N-2] = -dt * prev /
SQ(dz);
632 ordered_index = ordered_index_start;
633 for(
int k = 0;
k < N;
k++)
635 current_index = ordered_z_nodes[ordered_index];
636 states[current_index] = RHS[
k];
646 void (*ics_dg_adi_dir)(
ICS_Grid_node*
g,
int,
int,
int, double,
double*,
double*,
double*,
double*,
double*,
double*) = ics_adi_dir -> ics_dg_adi_dir;
651 double r = dt/(ics_adi_dir->
d * ics_adi_dir->
d);
652 ics_dg_adi_dir(g, line_start, line_stop, node_start, r, g->
states, data->
RHS, data->
scratchpad, data->
u_diag, data->
diag, data->
l_diag);
665 for (i = 0; i < NUM_THREADS-1; i++)
677 static inline double flux(
const double alphai,
const double alphaj,
678 const double statei,
const double statej)
680 return 2.0 * alphai * alphaj * (statei - statej) /
685 double* ydot,
long* line_defs,
687 double const *
const states,
688 double r,
double* alphas)
690 long ordered_index = node_start;
691 long current_index = -1;
692 long next_index = -1;
697 double current_alpha;
699 for(
int i = start;
i < stop - 1;
i += 2)
701 long line_start = ordered_nodes[ordered_index];
702 int line_length = line_defs[
i+1];
705 current_index = line_start;
707 next_index = ordered_nodes[ordered_index];
708 current_state = states[current_index];
709 next_state = states[next_index];
710 current_alpha = alphas[current_index];
711 next_alpha = alphas[next_index];
712 ydot[current_index] += (r / current_alpha) *
713 flux(next_alpha, current_alpha,
714 next_state, current_state);
716 for(
int j = 1;
j < line_length - 1;
j++)
719 current_index = next_index;
720 next_index = ordered_nodes[ordered_index];
721 current_state = next_state;
722 next_state = states[next_index];
723 prev_alpha = current_alpha;
724 current_alpha = next_alpha;
725 next_alpha = alphas[next_index];
726 ydot[current_index] += (r / current_alpha) * (
flux(prev_alpha, current_alpha, prev_state, current_state) +
727 flux(next_alpha, current_alpha, next_state, current_state));
730 ydot[next_index] += r *
flux(current_alpha, next_alpha, current_state, next_state)/next_alpha;
741 double* ydot,
long* line_defs,
743 double const *
const states,
744 double r,
double* dcs,
double* alphas)
746 long ordered_index = node_start;
747 long current_index = -1;
748 long next_index = -1;
753 double current_alpha;
755 double current_dc, next_dc;
756 for(
int i = start;
i < stop - 1;
i += 2)
758 long line_start = ordered_nodes[ordered_index];
759 int line_length = line_defs[
i+1];
762 current_index = line_start;
764 next_index = ordered_nodes[ordered_index];
765 current_state = states[current_index];
766 next_state = states[next_index];
767 current_alpha = alphas[current_index];
768 next_alpha = alphas[next_index];
769 current_dc = dcs[current_index];
770 next_dc = dcs[next_index];
771 ydot[current_index] += (r/current_alpha) * next_dc
772 *
flux(next_alpha, current_alpha,
773 next_state, current_state);
775 for(
int j = 1;
j < line_length - 1;
j++)
778 current_index = next_index;
779 next_index = ordered_nodes[ordered_index];
780 current_state = next_state;
781 next_state = states[next_index];
782 prev_alpha = current_alpha;
783 current_alpha = next_alpha;
784 next_alpha = alphas[next_index];
785 current_dc = next_dc;
786 next_dc = dcs[next_index];
787 ydot[current_index] += (r / current_alpha) * ( current_dc *
flux(prev_alpha, current_alpha, prev_state, current_state) +
788 next_dc *
flux(next_alpha, current_alpha, next_state, current_state));
791 ydot[next_index] += r * next_dc *
flux(current_alpha, next_alpha, current_state, next_state)/next_alpha;
802 double rate_x, rate_y, rate_z;
833 x_line_defs, x_ordered_nodes, states, rate_x,
837 y_line_defs, y_ordered_nodes, states, rate_y,
841 z_line_defs, z_ordered_nodes, states, rate_z,
846 rate_x = 1.0 / (dx *
dx);
847 rate_y = 1.0 / (
dy *
dy);
848 rate_z = 1.0 / (
dz *
dz);
851 x_line_defs, x_ordered_nodes, states, rate_x,
855 y_line_defs, y_ordered_nodes, states, rate_y,
859 z_line_defs, z_ordered_nodes, states, rate_z,
865 static void variable_step_x(
ICS_Grid_node*
g,
int line_start,
int line_stop,
int node_start,
double*
states,
double* CVodeRHS,
double*
RHS,
double* scratchpad,
double* alphas,
double *dcs,
double dt)
876 long next_index = -1;
877 long prev_index = -1;
885 long ordered_index = node_start;
886 for(
int i = line_start;
i < line_stop - 1;
i += 2)
888 long N = x_lines[
i+1];
889 long ordered_index_start = ordered_index;
890 for(
int j = 0;
j < N;
j++)
892 current_index = ordered_nodes[ordered_index];
893 RHS[
j] = CVodeRHS[current_index]
894 - dt * (delta_x[current_index]/
SQ(dx)
895 + delta_y[current_index]/
SQ(dy)
896 + delta_z[current_index]/
SQ(dz)
897 )/alphas[current_index];
901 ordered_index = ordered_index_start;
902 current_index = ordered_nodes[ordered_index];
904 next_index = ordered_nodes[ordered_index];
905 next = alphas[next_index] * dcs[next_index] / (alphas[next_index] + alphas[current_index]);
906 diag[0] = 1.0 + dt * next /
SQ(dx);
907 u_diag[0] = -dt * next /
SQ(dx);
909 for(
int c = 1;
c < N - 1;
c++){
910 prev_index = current_index;
911 current_index = next_index;
912 next_index = ordered_nodes[ordered_index];
913 prev = alphas[prev_index] * dcs[current_index] / (alphas[prev_index] + alphas[current_index]);
914 next = alphas[next_index] * dcs[next_index] / (alphas[next_index] + alphas[current_index]);
915 l_diag[
c-1] = -dt*prev /
SQ(dx);
916 diag[
c] = 1. + dt*(prev +
next) /
SQ(dx);
917 u_diag[
c] = -dt*next /
SQ(dx);
920 prev = alphas[current_index] * dcs[current_index] / (alphas[current_index] + alphas[next_index]);
921 diag[N-1] = 1.0 + dt * prev /
SQ(dx);
922 l_diag[N-2] = -dt * prev /
SQ(dx);
926 ordered_index = ordered_index_start;
927 for(
int k = 0;
k < N;
k++)
929 current_index = ordered_nodes[ordered_index];
930 states[current_index] = RHS[
k];
944 long next_index = -1;
945 long prev_index = -1;
952 long ordered_index = node_start;
954 for(
int i = line_start;
i < line_stop - 1;
i += 2)
957 long ordered_index_start = ordered_index;
959 for(
int j = 0;
j < N;
j++)
961 current_index = ordered_y_nodes[ordered_index];
962 RHS[
j] = states[current_index] - dt * delta[current_index]
963 / (alphas[current_index] *
SQ(dy));
967 ordered_index = ordered_index_start;
968 current_index = ordered_y_nodes[ordered_index];
970 next_index = ordered_y_nodes[ordered_index];
971 next = alphas[next_index] * dcs[next_index] / (alphas[next_index] + alphas[current_index]);
972 diag[0] = 1.0 + dt * next /
SQ(dy);
973 u_diag[0] = -dt * next /
SQ(dy);
975 for(
int c = 1;
c < N - 1;
c++){
976 prev_index = current_index;
977 current_index = next_index;
978 next_index = ordered_y_nodes[ordered_index];
979 prev = alphas[prev_index] * dcs[current_index] / (alphas[prev_index] + alphas[current_index]);
980 next = alphas[next_index] * dcs[next_index] / (alphas[next_index] + alphas[current_index]);
981 l_diag[
c-1] = -dt*prev/
SQ(dy);
982 diag[
c] = 1. + dt*(prev +
next)/
SQ(dy);
983 u_diag[
c] = -dt*next/
SQ(dy);
986 prev = alphas[current_index] * dcs[current_index] / (alphas[current_index] + alphas[next_index]);
987 diag[N-1] = 1.0 + dt * prev /
SQ(dy);
988 l_diag[N-2] = -dt * prev /
SQ(dy);
992 ordered_index = ordered_index_start;
993 for(
int k = 0;
k < N;
k++)
995 current_index = ordered_y_nodes[ordered_index];
996 states[current_index] = RHS[
k];
1011 long next_index = -1;
1012 long prev_index = -1;
1018 long ordered_index = node_start;
1019 for(
int i = line_start;
i< line_stop - 1;
i+=2)
1021 long N = lines[
i+1];
1022 long ordered_index_start = ordered_index;
1024 for(
int j = 0;
j < N;
j++)
1026 current_index = ordered_z_nodes[ordered_index];
1027 RHS[
j] = states[current_index] - dt * delta[current_index]
1028 / (alphas[current_index] *
SQ(dz));
1032 ordered_index = ordered_index_start;
1033 current_index = ordered_z_nodes[ordered_index];
1035 next_index = ordered_z_nodes[ordered_index];
1036 next = alphas[next_index] * dcs[next_index] / (alphas[next_index] + alphas[current_index]);
1037 diag[0] = 1.0 + dt * next /
SQ(dz);
1038 u_diag[0] = -dt * next /
SQ(dz);
1040 for(
int c = 1;
c < N - 1;
c++){
1041 prev_index = current_index;
1042 current_index = next_index;
1043 next_index = ordered_z_nodes[ordered_index];
1044 prev = alphas[prev_index] * dcs[current_index] / (alphas[prev_index] + alphas[current_index]);
1045 next = alphas[next_index] * dcs[next_index] / (alphas[next_index] + alphas[current_index]);
1046 l_diag[
c-1] = -dt*prev /
SQ(dz);
1047 diag[
c] = 1. + dt*(prev +
next) /
SQ(dz);
1048 u_diag[
c] = -dt*next /
SQ(dz);
1051 prev = alphas[current_index] * dcs[current_index] / (alphas[current_index] + alphas[next_index]);
1052 diag[N-1] = 1.0 + dt * prev /
SQ(dz);
1053 l_diag[N-2] = -dt * prev /
SQ(dz);
1056 ordered_index = ordered_index_start;
1057 for(
int k = 0;
k < N;
k++)
1059 current_index = ordered_z_nodes[ordered_index];
1060 states[current_index] = RHS[
k];
1077 long next_index = -1;
1078 long prev_index = -1;
1086 double r = dt * dc /
SQ(dx);
1089 long ordered_index = node_start;
1090 for(
int i = line_start;
i < line_stop - 1;
i += 2)
1092 long N = x_lines[
i+1];
1093 long ordered_index_start = ordered_index;
1094 for(
int j = 0;
j < N;
j++)
1096 current_index = ordered_nodes[ordered_index];
1097 RHS[
j] = CVodeRHS[current_index]
1098 - dt * (delta_x[current_index]/
SQ(dx)
1099 + delta_y[current_index]/
SQ(dy)
1100 + delta_z[current_index]/
SQ(dz)
1101 )/alphas[current_index];
1105 ordered_index = ordered_index_start;
1106 current_index = ordered_nodes[ordered_index];
1108 next_index = ordered_nodes[ordered_index];
1109 next = alphas[next_index] * r / (alphas[next_index] + alphas[current_index]);
1110 diag[0] = 1.0 +
next;
1113 for(
int c = 1;
c < N - 1;
c++){
1114 prev_index = current_index;
1115 current_index = next_index;
1116 next_index = ordered_nodes[ordered_index];
1117 prev = alphas[prev_index] * r / (alphas[prev_index] + alphas[current_index]);
1118 next = alphas[next_index] * r / (alphas[next_index] + alphas[current_index]);
1119 l_diag[
c-1] = -
prev;
1120 diag[
c] = 1. + prev +
next;
1124 prev = alphas[current_index] * r / (alphas[current_index] + alphas[next_index]);
1125 diag[N-1] = 1.0 +
prev;
1126 l_diag[N-2] = -
prev;
1130 ordered_index = ordered_index_start;
1131 for(
int k = 0;
k < N;
k++)
1133 current_index = ordered_nodes[ordered_index];
1134 states[current_index] = RHS[
k];
1148 long next_index = -1;
1149 long prev_index = -1;
1155 double r = dt * dc /
SQ(dy);
1159 long ordered_index = node_start;
1161 for(
int i = line_start;
i < line_stop - 1;
i += 2)
1163 long N = lines[
i+1];
1164 long ordered_index_start = ordered_index;
1166 for(
int j = 0;
j < N;
j++)
1168 current_index = ordered_y_nodes[ordered_index];
1169 RHS[
j] = states[current_index]
1170 -dt * delta[current_index]/(alphas[current_index]*
SQ(dy));
1174 ordered_index = ordered_index_start;
1175 current_index = ordered_y_nodes[ordered_index];
1177 next_index = ordered_y_nodes[ordered_index];
1178 next = alphas[next_index] * r / (alphas[next_index] + alphas[current_index]);
1179 diag[0] = 1.0 +
next;
1182 for(
int c = 1;
c < N - 1;
c++){
1183 prev_index = current_index;
1184 current_index = next_index;
1185 next_index = ordered_y_nodes[ordered_index];
1186 prev = alphas[prev_index] * r / (alphas[prev_index] + alphas[current_index]);
1187 next = alphas[next_index] * r / (alphas[next_index] + alphas[current_index]);
1188 l_diag[
c-1] = -
prev;
1189 diag[
c] = 1. + prev +
next;
1193 prev = alphas[current_index] * r / (alphas[current_index] + alphas[next_index]);
1194 diag[N-1] = 1.0 +
prev;
1195 l_diag[N-2] = -
prev;
1199 ordered_index = ordered_index_start;
1200 for(
int k = 0;
k < N;
k++)
1202 current_index = ordered_y_nodes[ordered_index];
1203 states[current_index] = RHS[
k];
1218 long next_index = -1;
1219 long prev_index = -1;
1224 double r = dt * dc /
SQ(dz);
1228 long ordered_index = node_start;
1229 for(
int i = line_start;
i< line_stop - 1;
i+=2)
1231 long N = lines[
i+1];
1232 long ordered_index_start = ordered_index;
1234 for(
int j = 0;
j < N;
j++)
1236 current_index = ordered_z_nodes[ordered_index];
1237 RHS[
j] = states[current_index]
1238 -dt * delta[current_index]/(alphas[current_index]*
SQ(dz));
1242 ordered_index = ordered_index_start;
1243 current_index = ordered_z_nodes[ordered_index];
1245 next_index = ordered_z_nodes[ordered_index];
1246 next = alphas[next_index] * r / (alphas[next_index] + alphas[current_index]);
1247 diag[0] = 1.0 +
next;
1250 for(
int c = 1;
c < N - 1;
c++){
1251 prev_index = current_index;
1252 current_index = next_index;
1253 next_index = ordered_z_nodes[ordered_index];
1254 prev = alphas[prev_index] * r / (alphas[prev_index] + alphas[current_index]);
1255 next = alphas[next_index] * r / (alphas[next_index] + alphas[current_index]);
1256 l_diag[
c-1] = -
prev;
1257 diag[
c] = 1. + prev +
next;
1261 prev = alphas[current_index] * r / (alphas[current_index] + alphas[next_index]);
1262 diag[N-1] = 1.0 +
prev;
1263 l_diag[N-2] = -
prev;
1266 ordered_index = ordered_index_start;
1267 for(
int k = 0;
k < N;
k++)
1269 current_index = ordered_z_nodes[ordered_index];
1270 states[current_index] = RHS[
k];
1304 double* CVode_states_copy = (
double*)calloc(num_states,
sizeof(
double));
1305 memcpy(CVode_states_copy, CVodeRHS,
sizeof(
double)*num_states);
1313 x_line_defs, x_ordered_nodes, CVode_states_copy,
1316 y_line_defs, y_ordered_nodes, CVode_states_copy,
1319 z_line_defs, z_ordered_nodes, CVode_states_copy,
1323 CVode_states_copy, CVodeRHS, Grid_RHS, Grid_ScratchPad,
1326 CVode_states_copy, Grid_RHS, Grid_ScratchPad, alphas,
1329 CVode_states_copy, Grid_RHS, Grid_ScratchPad, alphas,
1336 x_line_defs, x_ordered_nodes, CVode_states_copy,
1339 y_line_defs, y_ordered_nodes, CVode_states_copy,
1342 z_line_defs, z_ordered_nodes, CVode_states_copy,
1346 CVode_states_copy, CVodeRHS, Grid_RHS,
1350 CVode_states_copy, Grid_RHS, Grid_ScratchPad, alphas,
1353 CVode_states_copy, Grid_RHS, Grid_ScratchPad, alphas,
1357 memcpy(CVodeRHS, CVode_states_copy,
sizeof(
double)*num_states);
1358 free(CVode_states_copy);
1372 double vol_1d, vol_3d, rate, conc_1d;
1373 int my_3d_index, my_1d_index;
1376 int total_num_3d_indices_per_1d_seg = 0;
1377 for(
int i = 0;
i < num_1d_indices;
i++) {
1378 total_num_3d_indices_per_1d_seg += num_3d_indices_per_1d_seg[
i];
1382 double* old_g_states = (
double*) malloc(
sizeof(
double) * total_num_3d_indices_per_1d_seg);
1385 for(
int i = 0;
i < num_1d_indices;
i++) {
1386 for (
int j = 0;
j < num_3d_indices_per_1d_seg[
i];
j++, vol_3d_index++) {
1387 old_g_states[vol_3d_index] = g->
states[indices3d[vol_3d_index]];
1392 for(
int i = 0;
i<num_1d_indices;
i++)
1394 vol_1d = volumes1d[
i];
1395 my_1d_index = indices1d[
i];
1396 conc_1d =
states[my_1d_index];
1400 for(
int j=0;
j<num_3d_indices_per_1d_seg[
i];
j++, vol_3d_index++)
1402 vol_3d = volumes3d[vol_3d_index];
1404 my_3d_index = indices3d[vol_3d_index];
1405 rate = (rates[vol_3d_index]) * (old_g_states[vol_3d_index] - conc_1d);
1407 g->
states[my_3d_index] -= dt * rate;
1408 states[my_1d_index] += dt * rate * vol_3d / vol_1d;
1426 double vol_1d, vol_3d, rate, conc_1d;
1427 int my_3d_index, my_1d_index;
1428 int vol_3d_index = 0;
1430 for(
int i = 0;
i<num_1d_indices;
i++)
1432 vol_1d = volumes1d[
i];
1433 my_1d_index = indices1d[
i];
1434 conc_1d = cvode_states_1d[my_1d_index];
1435 for(
int j=0;
j<num_3d_indices_per_1d_seg[
i];
j++, vol_3d_index++)
1437 vol_3d = volumes3d[vol_3d_index];
1439 my_3d_index = indices3d[vol_3d_index];
1440 rate = (rates[vol_3d_index]) * (cvode_states_3d[my_3d_index] - conc_1d);
1442 ydot_3d[my_3d_index] -= rate;
1443 ydot_1d[my_1d_index] += rate * vol_3d / vol_1d;
void run_threaded_ics_dg_adi(struct ICSAdiDirection *)
void ics_dg_adi_y_inhom(ICS_Grid_node *g, int line_start, int line_stop, int node_start, double, double *states, double *RHS, double *scratchpad, double *u_diag, double *diag, double *l_diag)
void ics_dg_adi_z(ICS_Grid_node *g, int line_start, int line_stop, int node_start, double, double *states, double *RHS, double *scratchpad, double *u_diag, double *diag, double *l_diag)
void _ics_hybrid_helper(ICS_Grid_node *g)
static void * do_ics_deltas(void *dataptr)
void ics_dg_adi_z_inhom(ICS_Grid_node *g, int line_start, int line_stop, int node_start, double, double *states, double *RHS, double *scratchpad, double *u_diag, double *diag, double *l_diag)
long * ordered_start_stop_indices
ICSAdiDirection * ics_adi_dir
void ics_dg_adi_x(ICS_Grid_node *g, int line_start, int line_stop, int node_start, double, double *states, double *RHS, double *scratchpad, double *u_diag, double *diag, double *l_diag)
void TaskQueue_sync(TaskQueue *q)
static void variable_step_z(ICS_Grid_node *g, int line_start, int line_stop, int node_start, double *states, double *RHS, double *scratchpad, double *alphas, double *dcs, double dt)
struct ICSAdiDirection * ics_adi_dir_y
static philox4x32_key_t k
long * line_start_stop_indices
void set_hybrid_data(int64_t *num_1d_indices_per_grid, int64_t *num_3d_indices_per_grid, int64_t *hybrid_indices1d, int64_t *hybrid_indices3d, int64_t *num_3d_indices_per_1d_seg, int64_t *hybrid_grid_ids, double *rates, double *volumes1d, double *volumes3d, double *dxs)
Grid_node * Parallel_grids[100]
void ics_dg_adi_y(ICS_Grid_node *g, int line_start, int line_stop, int node_start, double, double *states, double *RHS, double *scratchpad, double *u_diag, double *diag, double *l_diag)
void run_threaded_deltas(ICS_Grid_node *g, ICSAdiDirection *ics_adi_dir)
static void variable_step_y(ICS_Grid_node *g, int line_start, int line_stop, int node_start, double *states, double *RHS, double *scratchpad, double *alphas, double *dcs, double dt)
static double current_state(void *v)
static double flux(const double alphai, const double alphaj, const double statei, const double statej)
void * do_ics_dg_adi(void *dataptr)
void ics_dg_adi_x_inhom(ICS_Grid_node *g, int line_start, int line_stop, int node_start, double, double *states, double *RHS, double *scratchpad, double *u_diag, double *diag, double *l_diag)
void ics_ode_solve_helper(ICS_Grid_node *g, double dt, double *CVodeRHS)
void _ics_rhs_variable_step_helper(ICS_Grid_node *g, double const *const states, double *ydot)
struct ICSAdiDirection * ics_adi_dir_x
static int solve_dd_tridiag(int N, const double *l_diag, const double *diag, const double *u_diag, double *b, double *c)
Hybrid_data * hybrid_data
static void variable_step_delta(long start, long stop, long node_start, double *ydot, long *line_defs, long *ordered_nodes, double const *const states, double r, double *alphas)
struct ICSAdiDirection * ics_adi_dir_z
void ics_find_deltas(long start, long stop, long node_start, double *delta, long *line_defs, long *ordered_nodes, double *states, double dc, double *alphas)
static void variable_step_x(ICS_Grid_node *g, int line_start, int line_stop, int node_start, double *states, double *CVodeRHS, double *RHS, double *scratchpad, double *alphas, double *dcs, double dt)
void TaskQueue_add_task(TaskQueue *q, void *(*task)(void *), void *args, void *result)
long * num_3d_indices_per_1d_seg
void _ics_variable_hybrid_helper(ICS_Grid_node *g, const double *cvode_states_3d, double *const ydot_3d, const double *cvode_states_1d, double *const ydot_1d)
struct ICSAdiGridData * ics_tasks