1 #include <../../nrnconf.h>
21 int64_t* num_3d_indices_per_grid,
22 int64_t* hybrid_indices1d,
23 int64_t* hybrid_indices3d,
24 int64_t* num_3d_indices_per_1d_seg,
25 int64_t* hybrid_grid_ids,
32 int grid_id_check = 0;
37 int num_grid_3d_indices;
38 int num_grid_1d_indices;
45 if (
id == hybrid_grid_ids[grid_id_check]) {
46 num_grid_1d_indices = num_1d_indices_per_grid[grid_id_check];
47 num_grid_3d_indices = num_3d_indices_per_grid[grid_id_check];
57 grid->
hybrid_data->
rates = (
double*) malloc(
sizeof(
double) * num_grid_3d_indices);
64 for (
i = 0,
k = 0;
i < num_grid_1d_indices;
i++, index_ctr_1d++) {
67 num_3d_indices_per_1d_seg[index_ctr_1d];
70 for (
j = 0;
j < num_3d_indices_per_1d_seg[index_ctr_1d];
j++, index_ctr_3d++,
k++) {
74 ((
ICS_Grid_node*) grid)->_ics_alphas[hybrid_indices3d[index_ctr_3d]] =
75 volumes3d[index_ctr_3d] / dx;
101 c[0] = u_diag[0] /
diag[0];
102 b[0] = b[0] /
diag[0];
104 for (
i = 1;
i < N - 1;
i++) {
105 c[
i] = u_diag[
i] / (
diag[
i] - l_diag[
i - 1] *
c[
i - 1]);
106 b[
i] = (b[
i] - l_diag[
i - 1] * b[
i - 1]) / (
diag[
i] - l_diag[
i - 1] *
c[
i - 1]);
108 b[N - 1] = (b[N - 1] - l_diag[N - 2] * b[N - 2]) / (
diag[N - 1] - l_diag[N - 2] *
c[N - 2]);
112 for (
i = N - 2;
i >= 0;
i--) {
113 b[
i] = b[
i] -
c[
i] * b[
i + 1];
128 long ordered_index = node_start;
129 long current_index = -1;
130 long next_index = -1;
135 double current_alpha;
138 long line_start = ordered_nodes[ordered_index];
139 int line_length = line_defs[
i + 1];
140 if (line_length > 1) {
141 current_index = line_start;
143 next_index = ordered_nodes[ordered_index];
145 next_state =
states[next_index];
146 current_alpha = alphas[current_index];
147 next_alpha = alphas[next_index];
148 delta[current_index] =
dc * next_alpha * current_alpha * (next_state -
current_state) /
149 (next_alpha + current_alpha);
151 for (
int j = 1;
j < line_length - 1;
j++) {
153 current_index = next_index;
154 next_index = ordered_nodes[ordered_index];
156 next_state =
states[next_index];
157 prev_alpha = current_alpha;
158 current_alpha = next_alpha;
159 next_alpha = alphas[next_index];
160 delta[current_index] =
161 dc * ((next_alpha * current_alpha / (next_alpha + current_alpha)) *
163 (prev_alpha * current_alpha / (prev_alpha + current_alpha)) *
168 delta[next_index] =
dc * (next_alpha * current_alpha) * (
current_state - next_state) /
169 (next_alpha + current_alpha);
172 delta[line_start] = 0.0;
187 long ordered_index = node_start;
188 long current_index = -1;
189 long next_index = -1;
194 double current_alpha;
197 long line_start = ordered_nodes[ordered_index];
198 int line_length = line_defs[
i + 1];
199 if (line_length > 1) {
200 current_index = line_start;
202 next_index = ordered_nodes[ordered_index];
204 next_state =
states[next_index];
205 current_alpha = alphas[current_index];
206 next_alpha = alphas[next_index];
207 delta[current_index] =
dc[next_index] * next_alpha * current_alpha *
210 for (
int j = 1;
j < line_length - 1;
j++) {
212 current_index = next_index;
213 next_index = ordered_nodes[ordered_index];
215 next_state =
states[next_index];
216 prev_alpha = current_alpha;
217 current_alpha = next_alpha;
218 next_alpha = alphas[next_index];
219 delta[current_index] =
220 dc[next_index] * (next_alpha * current_alpha * (next_state -
current_state) /
221 (next_alpha + current_alpha)) -
222 dc[current_index] * (prev_alpha * current_alpha * (
current_state - prev_state) /
223 (prev_alpha + current_alpha));
227 delta[next_index] =
dc[next_index] * (next_alpha * current_alpha) *
231 delta[line_start] = 0.0;
240 int line_start =
data->line_start;
241 int line_stop =
data->line_stop;
242 int node_start =
data->ordered_start;
244 double* deltas = ics_adi_dir->
deltas;
247 double* alphas =
g->_ics_alphas;
279 g->ics_tasks[
i].ordered_start =
283 g->ics_tasks[
i].ics_adi_dir = ics_adi_dir;
307 double* delta_x =
g->ics_adi_dir_x->deltas;
308 double* delta_y =
g->ics_adi_dir_y->deltas;
309 double* delta_z =
g->ics_adi_dir_z->deltas;
310 double* states_cur =
g->states_cur;
311 double* alphas =
g->_ics_alphas;
312 double*
dc =
g->ics_adi_dir_x->dcgrid;
313 double dx =
g->ics_adi_dir_x->d;
314 double dy =
g->ics_adi_dir_y->d;
315 double dz =
g->ics_adi_dir_z->d;
317 long next_index = -1;
318 long prev_index = -1;
322 long* x_lines =
g->ics_adi_dir_x->ordered_line_defs;
323 long* ordered_nodes =
g->ics_adi_dir_x->ordered_nodes;
326 long ordered_index = node_start;
327 for (
int i = line_start;
i < line_stop - 1;
i += 2) {
328 long N = x_lines[
i + 1];
329 long ordered_index_start = ordered_index;
330 for (
int j = 0;
j < N;
j++) {
331 current_index = ordered_nodes[ordered_index];
332 RHS[
j] = (
dt / alphas[current_index]) *
333 (delta_x[current_index] /
SQ(dx) + 2.0 * delta_y[current_index] /
SQ(dy) +
334 2.0 * delta_z[current_index] /
SQ(dz)) +
335 states[current_index] + states_cur[current_index];
339 ordered_index = ordered_index_start;
340 current_index = ordered_nodes[ordered_index];
342 next_index = ordered_nodes[ordered_index];
343 next = alphas[next_index] *
dc[next_index] / (alphas[next_index] + alphas[current_index]);
347 for (
int c = 1;
c < N - 1;
c++) {
348 prev_index = current_index;
349 current_index = next_index;
350 next_index = ordered_nodes[ordered_index];
351 prev = alphas[prev_index] *
dc[current_index] /
352 (alphas[prev_index] + alphas[current_index]);
353 next = alphas[next_index] *
dc[next_index] /
354 (alphas[next_index] + alphas[current_index]);
360 prev = alphas[current_index] *
dc[next_index] /
361 (alphas[current_index] + alphas[next_index]);
363 l_diag[N - 2] = -
dt *
prev /
SQ(dx);
368 ordered_index = ordered_index_start;
369 for (
int k = 0;
k < N;
k++) {
370 current_index = ordered_nodes[ordered_index];
388 double* delta =
g->ics_adi_dir_y->deltas;
389 long* lines =
g->ics_adi_dir_y->ordered_line_defs;
390 double* alphas =
g->_ics_alphas;
391 double*
dc =
g->ics_adi_dir_y->dcgrid;
392 double dy =
g->ics_adi_dir_y->d;
394 long next_index = -1;
395 long prev_index = -1;
400 long* ordered_y_nodes =
g->ics_adi_dir_y->ordered_nodes;
401 long ordered_index = node_start;
403 for (
int i = line_start;
i < line_stop - 1;
i += 2) {
404 long N = lines[
i + 1];
405 long ordered_index_start = ordered_index;
407 for (
int j = 0;
j < N;
j++) {
408 current_index = ordered_y_nodes[ordered_index];
410 dt * delta[current_index] / (alphas[current_index] *
SQ(dy));
414 ordered_index = ordered_index_start;
415 current_index = ordered_y_nodes[ordered_index];
417 next_index = ordered_y_nodes[ordered_index];
418 next = alphas[next_index] *
dc[next_index] / (alphas[next_index] + alphas[current_index]);
422 for (
int c = 1;
c < N - 1;
c++) {
423 prev_index = current_index;
424 current_index = next_index;
425 next_index = ordered_y_nodes[ordered_index];
426 prev = alphas[prev_index] *
dc[prev_index] /
427 (alphas[prev_index] + alphas[current_index]);
428 next = alphas[next_index] *
dc[next_index] /
429 (alphas[next_index] + alphas[current_index]);
435 prev = alphas[current_index] *
dc[current_index] /
436 (alphas[current_index] + alphas[next_index]);
438 l_diag[N - 2] = -
dt *
prev /
SQ(dy);
442 ordered_index = ordered_index_start;
443 for (
int k = 0;
k < N;
k++) {
444 current_index = ordered_y_nodes[ordered_index];
461 double* delta =
g->ics_adi_dir_z->deltas;
462 long* lines =
g->ics_adi_dir_z->ordered_line_defs;
463 long* ordered_z_nodes =
g->ics_adi_dir_z->ordered_nodes;
464 double* alphas =
g->_ics_alphas;
465 double*
dc =
g->ics_adi_dir_z->dcgrid;
466 double dz =
g->ics_adi_dir_z->d;
468 long next_index = -1;
469 long prev_index = -1;
474 long ordered_index = node_start;
475 for (
int i = line_start;
i < line_stop - 1;
i += 2) {
476 long N = lines[
i + 1];
477 long ordered_index_start = ordered_index;
479 for (
int j = 0;
j < N;
j++) {
480 current_index = ordered_z_nodes[ordered_index];
482 dt * delta[current_index] / (
SQ(dz) * alphas[current_index]);
486 ordered_index = ordered_index_start;
487 current_index = ordered_z_nodes[ordered_index];
489 next_index = ordered_z_nodes[ordered_index];
490 next = alphas[next_index] *
dc[next_index] / (alphas[next_index] + alphas[current_index]);
494 for (
int c = 1;
c < N - 1;
c++) {
495 prev_index = current_index;
496 current_index = next_index;
497 next_index = ordered_z_nodes[ordered_index];
498 prev = alphas[prev_index] *
dc[prev_index] /
499 (alphas[prev_index] + alphas[current_index]);
500 next = alphas[next_index] *
dc[next_index] /
501 (alphas[next_index] + alphas[current_index]);
507 prev = alphas[current_index] *
dc[current_index] /
508 (alphas[current_index] + alphas[next_index]);
510 l_diag[N - 2] = -
dt *
prev /
SQ(dz);
513 ordered_index = ordered_index_start;
514 for (
int k = 0;
k < N;
k++) {
515 current_index = ordered_z_nodes[ordered_index];
534 double* delta_x =
g->ics_adi_dir_x->deltas;
535 double* delta_y =
g->ics_adi_dir_y->deltas;
536 double* delta_z =
g->ics_adi_dir_z->deltas;
537 double* states_cur =
g->states_cur;
538 double* alphas =
g->_ics_alphas;
539 double dc =
g->ics_adi_dir_x->dc;
540 double dx =
g->ics_adi_dir_x->d;
541 double dy =
g->ics_adi_dir_y->d;
542 double dz =
g->ics_adi_dir_z->d;
544 long next_index = -1;
545 long prev_index = -1;
549 long* x_lines =
g->ics_adi_dir_x->ordered_line_defs;
550 long* ordered_nodes =
g->ics_adi_dir_x->ordered_nodes;
553 long ordered_index = node_start;
554 for (
int i = line_start;
i < line_stop - 1;
i += 2) {
555 long N = x_lines[
i + 1];
556 long ordered_index_start = ordered_index;
557 for (
int j = 0;
j < N;
j++) {
558 current_index = ordered_nodes[ordered_index];
559 RHS[
j] = (
dt / alphas[current_index]) *
560 (delta_x[current_index] / (
SQ(dx)) + 2 * delta_y[current_index] /
SQ(dy) +
561 2 * delta_z[current_index] /
SQ(dz)) +
562 states[current_index] + states_cur[current_index];
566 ordered_index = ordered_index_start;
567 current_index = ordered_nodes[ordered_index];
569 next_index = ordered_nodes[ordered_index];
570 next = alphas[next_index] *
dc / (alphas[next_index] + alphas[current_index]);
574 for (
int c = 1;
c < N - 1;
c++) {
575 prev_index = current_index;
576 current_index = next_index;
577 next_index = ordered_nodes[ordered_index];
578 prev = alphas[prev_index] *
dc / (alphas[prev_index] + alphas[current_index]);
579 next = alphas[next_index] *
dc / (alphas[next_index] + alphas[current_index]);
585 prev = alphas[current_index] *
dc / (alphas[current_index] + alphas[next_index]);
587 l_diag[N - 2] = -
dt *
prev /
SQ(dx);
592 ordered_index = ordered_index_start;
593 for (
int k = 0;
k < N;
k++) {
594 current_index = ordered_nodes[ordered_index];
612 double* delta =
g->ics_adi_dir_y->deltas;
613 long* lines =
g->ics_adi_dir_y->ordered_line_defs;
614 double* alphas =
g->_ics_alphas;
615 double dc =
g->ics_adi_dir_y->dc;
616 double dy =
g->ics_adi_dir_y->d;
618 long next_index = -1;
619 long prev_index = -1;
624 long* ordered_y_nodes =
g->ics_adi_dir_y->ordered_nodes;
625 long ordered_index = node_start;
627 for (
int i = line_start;
i < line_stop - 1;
i += 2) {
628 long N = lines[
i + 1];
629 long ordered_index_start = ordered_index;
631 for (
int j = 0;
j < N;
j++) {
632 current_index = ordered_y_nodes[ordered_index];
634 dt * delta[current_index] / (alphas[current_index] *
SQ(dy));
638 ordered_index = ordered_index_start;
639 current_index = ordered_y_nodes[ordered_index];
641 next_index = ordered_y_nodes[ordered_index];
642 next = alphas[next_index] *
dc / (alphas[next_index] + alphas[current_index]);
646 for (
int c = 1;
c < N - 1;
c++) {
647 prev_index = current_index;
648 current_index = next_index;
649 next_index = ordered_y_nodes[ordered_index];
650 prev = alphas[prev_index] *
dc / (alphas[prev_index] + alphas[current_index]);
651 next = alphas[next_index] *
dc / (alphas[next_index] + alphas[current_index]);
657 prev = alphas[current_index] *
dc / (alphas[current_index] + alphas[next_index]);
659 l_diag[N - 2] = -
dt *
prev /
SQ(dy);
663 ordered_index = ordered_index_start;
664 for (
int k = 0;
k < N;
k++) {
665 current_index = ordered_y_nodes[ordered_index];
682 double* delta =
g->ics_adi_dir_z->deltas;
683 long* lines =
g->ics_adi_dir_z->ordered_line_defs;
684 long* ordered_z_nodes =
g->ics_adi_dir_z->ordered_nodes;
685 double* alphas =
g->_ics_alphas;
686 double dc =
g->ics_adi_dir_z->dc;
687 double dz =
g->ics_adi_dir_z->d;
689 long next_index = -1;
690 long prev_index = -1;
695 long ordered_index = node_start;
696 for (
int i = line_start;
i < line_stop - 1;
i += 2) {
697 long N = lines[
i + 1];
698 long ordered_index_start = ordered_index;
700 for (
int j = 0;
j < N;
j++) {
701 current_index = ordered_z_nodes[ordered_index];
703 dt * delta[current_index] / (
SQ(dz) * alphas[current_index]);
707 ordered_index = ordered_index_start;
708 current_index = ordered_z_nodes[ordered_index];
710 next_index = ordered_z_nodes[ordered_index];
711 next = alphas[next_index] *
dc / (alphas[next_index] + alphas[current_index]);
715 for (
int c = 1;
c < N - 1;
c++) {
716 prev_index = current_index;
717 current_index = next_index;
718 next_index = ordered_z_nodes[ordered_index];
719 prev = alphas[prev_index] *
dc / (alphas[prev_index] + alphas[current_index]);
720 next = alphas[next_index] *
dc / (alphas[next_index] + alphas[current_index]);
726 prev = alphas[current_index] *
dc / (alphas[current_index] + alphas[next_index]);
728 l_diag[N - 2] = -
dt *
prev /
SQ(dz);
731 ordered_index = ordered_index_start;
732 for (
int k = 0;
k < N;
k++) {
733 current_index = ordered_z_nodes[ordered_index];
755 int line_start =
data->line_start;
756 int line_stop =
data->line_stop;
757 int node_start =
data->ordered_start;
759 double r =
dt / (ics_adi_dir->
d * ics_adi_dir->
d);
797 static inline double flux(
const double alphai,
800 const double statej) {
801 return 2.0 * alphai * alphaj * (statei - statej) / ((alphai + alphaj));
810 double const*
const states,
813 long ordered_index = node_start;
814 long current_index = -1;
815 long next_index = -1;
820 double current_alpha;
823 long line_start = ordered_nodes[ordered_index];
824 int line_length = line_defs[
i + 1];
825 if (line_length > 1) {
826 current_index = line_start;
828 next_index = ordered_nodes[ordered_index];
830 next_state =
states[next_index];
831 current_alpha = alphas[current_index];
832 next_alpha = alphas[next_index];
833 ydot[current_index] += (r / current_alpha) *
836 for (
int j = 1;
j < line_length - 1;
j++) {
838 current_index = next_index;
839 next_index = ordered_nodes[ordered_index];
841 next_state =
states[next_index];
842 prev_alpha = current_alpha;
843 current_alpha = next_alpha;
844 next_alpha = alphas[next_index];
845 ydot[current_index] += (r / current_alpha) *
850 ydot[next_index] += r *
flux(current_alpha, next_alpha,
current_state, next_state) /
865 double const*
const states,
869 long ordered_index = node_start;
870 long current_index = -1;
871 long next_index = -1;
876 double current_alpha;
878 double current_dc, next_dc;
880 long line_start = ordered_nodes[ordered_index];
881 int line_length = line_defs[
i + 1];
882 if (line_length > 1) {
883 current_index = line_start;
885 next_index = ordered_nodes[ordered_index];
887 next_state =
states[next_index];
888 current_alpha = alphas[current_index];
889 next_alpha = alphas[next_index];
890 current_dc = dcs[current_index];
891 next_dc = dcs[next_index];
892 ydot[current_index] += (r / current_alpha) * next_dc *
895 for (
int j = 1;
j < line_length - 1;
j++) {
897 current_index = next_index;
898 next_index = ordered_nodes[ordered_index];
900 next_state =
states[next_index];
901 prev_alpha = current_alpha;
902 current_alpha = next_alpha;
903 next_alpha = alphas[next_index];
904 current_dc = next_dc;
905 next_dc = dcs[next_index];
906 ydot[current_index] +=
907 (r / current_alpha) *
912 ydot[next_index] += r * next_dc *
922 double rate_x, rate_y, rate_z;
924 double dx =
g->ics_adi_dir_x->d, dy =
g->ics_adi_dir_y->d, dz =
g->ics_adi_dir_z->d;
926 long x_line_start =
g->ics_adi_dir_x->line_start_stop_indices[0];
927 long x_line_stop =
g->ics_adi_dir_x->line_start_stop_indices[
NUM_THREADS * 2 - 1];
928 long x_node_start =
g->ics_adi_dir_x->ordered_start_stop_indices[0];
929 long* x_line_defs =
g->ics_adi_dir_x->ordered_line_defs;
930 long* x_ordered_nodes =
g->ics_adi_dir_x->ordered_nodes;
932 long y_line_start =
g->ics_adi_dir_y->line_start_stop_indices[0];
933 long y_line_stop =
g->ics_adi_dir_y->line_start_stop_indices[
NUM_THREADS * 2 - 1];
934 long y_node_start =
g->ics_adi_dir_y->ordered_start_stop_indices[0];
935 long* y_line_defs =
g->ics_adi_dir_y->ordered_line_defs;
936 long* y_ordered_nodes =
g->ics_adi_dir_y->ordered_nodes;
938 long z_line_start =
g->ics_adi_dir_z->line_start_stop_indices[0];
939 long z_line_stop =
g->ics_adi_dir_z->line_start_stop_indices[
NUM_THREADS * 2 - 1];
940 long z_node_start =
g->ics_adi_dir_z->ordered_start_stop_indices[0];
941 long* z_line_defs =
g->ics_adi_dir_z->ordered_line_defs;
942 long* z_ordered_nodes =
g->ics_adi_dir_z->ordered_nodes;
944 double* alphas =
g->_ics_alphas;
946 if (
g->ics_adi_dir_x->dcgrid ==
NULL) {
947 rate_x =
g->ics_adi_dir_x->dc / (dx * dx);
948 rate_y =
g->ics_adi_dir_y->dc / (dy * dy);
949 rate_z =
g->ics_adi_dir_z->dc / (dz * dz);
981 rate_x = 1.0 / (dx * dx);
982 rate_y = 1.0 / (dy * dy);
983 rate_z = 1.0 / (dz * dz);
993 g->ics_adi_dir_x->dcgrid,
1004 g->ics_adi_dir_y->dcgrid,
1015 g->ics_adi_dir_z->dcgrid,
1032 long* x_lines =
g->ics_adi_dir_x->ordered_line_defs;
1033 long* ordered_nodes =
g->ics_adi_dir_x->ordered_nodes;
1034 double* l_diag =
g->ics_tasks->l_diag;
1035 double*
diag =
g->ics_tasks->diag;
1036 double* u_diag =
g->ics_tasks->u_diag;
1037 double* delta_x =
g->ics_adi_dir_x->deltas;
1038 double* delta_y =
g->ics_adi_dir_y->deltas;
1039 double* delta_z =
g->ics_adi_dir_z->deltas;
1041 long next_index = -1;
1042 long prev_index = -1;
1045 double dx =
g->ics_adi_dir_x->d;
1046 double dy =
g->ics_adi_dir_y->d;
1047 double dz =
g->ics_adi_dir_z->d;
1050 long ordered_index = node_start;
1051 for (
int i = line_start;
i < line_stop - 1;
i += 2) {
1052 long N = x_lines[
i + 1];
1053 long ordered_index_start = ordered_index;
1054 for (
int j = 0;
j < N;
j++) {
1055 current_index = ordered_nodes[ordered_index];
1056 RHS[
j] = CVodeRHS[current_index] -
1058 (delta_x[current_index] /
SQ(dx) + delta_y[current_index] /
SQ(dy) +
1059 delta_z[current_index] /
SQ(dz)) /
1060 alphas[current_index];
1064 ordered_index = ordered_index_start;
1065 current_index = ordered_nodes[ordered_index];
1067 next_index = ordered_nodes[ordered_index];
1068 next = alphas[next_index] * dcs[next_index] / (alphas[next_index] + alphas[current_index]);
1072 for (
int c = 1;
c < N - 1;
c++) {
1073 prev_index = current_index;
1074 current_index = next_index;
1075 next_index = ordered_nodes[ordered_index];
1076 prev = alphas[prev_index] * dcs[current_index] /
1077 (alphas[prev_index] + alphas[current_index]);
1078 next = alphas[next_index] * dcs[next_index] /
1079 (alphas[next_index] + alphas[current_index]);
1085 prev = alphas[current_index] * dcs[current_index] /
1086 (alphas[current_index] + alphas[next_index]);
1088 l_diag[N - 2] = -
dt *
prev /
SQ(dx);
1092 ordered_index = ordered_index_start;
1093 for (
int k = 0;
k < N;
k++) {
1094 current_index = ordered_nodes[ordered_index];
1110 double* delta =
g->ics_adi_dir_y->deltas;
1111 long* lines =
g->ics_adi_dir_y->ordered_line_defs;
1113 double* l_diag =
g->ics_tasks->l_diag;
1114 double*
diag =
g->ics_tasks->diag;
1115 double* u_diag =
g->ics_tasks->u_diag;
1117 long next_index = -1;
1118 long prev_index = -1;
1121 double dy =
g->ics_adi_dir_y->d;
1124 long* ordered_y_nodes =
g->ics_adi_dir_y->ordered_nodes;
1125 long ordered_index = node_start;
1127 for (
int i = line_start;
i < line_stop - 1;
i += 2) {
1128 long N = lines[
i + 1];
1129 long ordered_index_start = ordered_index;
1131 for (
int j = 0;
j < N;
j++) {
1132 current_index = ordered_y_nodes[ordered_index];
1134 dt * delta[current_index] / (alphas[current_index] *
SQ(dy));
1138 ordered_index = ordered_index_start;
1139 current_index = ordered_y_nodes[ordered_index];
1141 next_index = ordered_y_nodes[ordered_index];
1142 next = alphas[next_index] * dcs[next_index] / (alphas[next_index] + alphas[current_index]);
1146 for (
int c = 1;
c < N - 1;
c++) {
1147 prev_index = current_index;
1148 current_index = next_index;
1149 next_index = ordered_y_nodes[ordered_index];
1150 prev = alphas[prev_index] * dcs[current_index] /
1151 (alphas[prev_index] + alphas[current_index]);
1152 next = alphas[next_index] * dcs[next_index] /
1153 (alphas[next_index] + alphas[current_index]);
1159 prev = alphas[current_index] * dcs[current_index] /
1160 (alphas[current_index] + alphas[next_index]);
1162 l_diag[N - 2] = -
dt *
prev /
SQ(dy);
1166 ordered_index = ordered_index_start;
1167 for (
int k = 0;
k < N;
k++) {
1168 current_index = ordered_y_nodes[ordered_index];
1184 double* delta =
g->ics_adi_dir_z->deltas;
1185 long* lines =
g->ics_adi_dir_z->ordered_line_defs;
1186 long* ordered_z_nodes =
g->ics_adi_dir_z->ordered_nodes;
1188 double* l_diag =
g->ics_tasks->l_diag;
1189 double*
diag =
g->ics_tasks->diag;
1190 double* u_diag =
g->ics_tasks->u_diag;
1192 long next_index = -1;
1193 long prev_index = -1;
1196 double dz =
g->ics_adi_dir_z->d;
1199 long ordered_index = node_start;
1200 for (
int i = line_start;
i < line_stop - 1;
i += 2) {
1201 long N = lines[
i + 1];
1202 long ordered_index_start = ordered_index;
1204 for (
int j = 0;
j < N;
j++) {
1205 current_index = ordered_z_nodes[ordered_index];
1207 dt * delta[current_index] / (alphas[current_index] *
SQ(dz));
1211 ordered_index = ordered_index_start;
1212 current_index = ordered_z_nodes[ordered_index];
1214 next_index = ordered_z_nodes[ordered_index];
1215 next = alphas[next_index] * dcs[next_index] / (alphas[next_index] + alphas[current_index]);
1219 for (
int c = 1;
c < N - 1;
c++) {
1220 prev_index = current_index;
1221 current_index = next_index;
1222 next_index = ordered_z_nodes[ordered_index];
1223 prev = alphas[prev_index] * dcs[current_index] /
1224 (alphas[prev_index] + alphas[current_index]);
1225 next = alphas[next_index] * dcs[next_index] /
1226 (alphas[next_index] + alphas[current_index]);
1232 prev = alphas[current_index] * dcs[current_index] /
1233 (alphas[current_index] + alphas[next_index]);
1235 l_diag[N - 2] = -
dt *
prev /
SQ(dz);
1238 ordered_index = ordered_index_start;
1239 for (
int k = 0;
k < N;
k++) {
1240 current_index = ordered_z_nodes[ordered_index];
1258 long* x_lines =
g->ics_adi_dir_x->ordered_line_defs;
1259 long* ordered_nodes =
g->ics_adi_dir_x->ordered_nodes;
1260 double* l_diag =
g->ics_tasks->l_diag;
1261 double*
diag =
g->ics_tasks->diag;
1262 double* u_diag =
g->ics_tasks->u_diag;
1263 double* delta_x =
g->ics_adi_dir_x->deltas;
1264 double* delta_y =
g->ics_adi_dir_y->deltas;
1265 double* delta_z =
g->ics_adi_dir_z->deltas;
1266 long next_index = -1;
1267 long prev_index = -1;
1270 double dx =
g->ics_adi_dir_x->d;
1271 double dy =
g->ics_adi_dir_y->d;
1272 double dz =
g->ics_adi_dir_z->d;
1273 double dc =
g->ics_adi_dir_x->dc;
1275 double r =
dt *
dc /
SQ(dx);
1278 long ordered_index = node_start;
1279 for (
int i = line_start;
i < line_stop - 1;
i += 2) {
1280 long N = x_lines[
i + 1];
1281 long ordered_index_start = ordered_index;
1282 for (
int j = 0;
j < N;
j++) {
1283 current_index = ordered_nodes[ordered_index];
1284 RHS[
j] = CVodeRHS[current_index] -
1286 (delta_x[current_index] /
SQ(dx) + delta_y[current_index] /
SQ(dy) +
1287 delta_z[current_index] /
SQ(dz)) /
1288 alphas[current_index];
1292 ordered_index = ordered_index_start;
1293 current_index = ordered_nodes[ordered_index];
1295 next_index = ordered_nodes[ordered_index];
1296 next = alphas[next_index] * r / (alphas[next_index] + alphas[current_index]);
1300 for (
int c = 1;
c < N - 1;
c++) {
1301 prev_index = current_index;
1302 current_index = next_index;
1303 next_index = ordered_nodes[ordered_index];
1304 prev = alphas[prev_index] * r / (alphas[prev_index] + alphas[current_index]);
1305 next = alphas[next_index] * r / (alphas[next_index] + alphas[current_index]);
1306 l_diag[
c - 1] = -
prev;
1311 prev = alphas[current_index] * r / (alphas[current_index] + alphas[next_index]);
1313 l_diag[N - 2] = -
prev;
1317 ordered_index = ordered_index_start;
1318 for (
int k = 0;
k < N;
k++) {
1319 current_index = ordered_nodes[ordered_index];
1334 double* delta =
g->ics_adi_dir_y->deltas;
1335 long* lines =
g->ics_adi_dir_y->ordered_line_defs;
1337 double* l_diag =
g->ics_tasks->l_diag;
1338 double*
diag =
g->ics_tasks->diag;
1339 double* u_diag =
g->ics_tasks->u_diag;
1341 long next_index = -1;
1342 long prev_index = -1;
1345 double dy =
g->ics_adi_dir_y->d;
1346 double dc =
g->ics_adi_dir_y->dc;
1348 double r =
dt *
dc /
SQ(dy);
1351 long* ordered_y_nodes =
g->ics_adi_dir_y->ordered_nodes;
1352 long ordered_index = node_start;
1354 for (
int i = line_start;
i < line_stop - 1;
i += 2) {
1355 long N = lines[
i + 1];
1356 long ordered_index_start = ordered_index;
1358 for (
int j = 0;
j < N;
j++) {
1359 current_index = ordered_y_nodes[ordered_index];
1361 dt * delta[current_index] / (alphas[current_index] *
SQ(dy));
1365 ordered_index = ordered_index_start;
1366 current_index = ordered_y_nodes[ordered_index];
1368 next_index = ordered_y_nodes[ordered_index];
1369 next = alphas[next_index] * r / (alphas[next_index] + alphas[current_index]);
1373 for (
int c = 1;
c < N - 1;
c++) {
1374 prev_index = current_index;
1375 current_index = next_index;
1376 next_index = ordered_y_nodes[ordered_index];
1377 prev = alphas[prev_index] * r / (alphas[prev_index] + alphas[current_index]);
1378 next = alphas[next_index] * r / (alphas[next_index] + alphas[current_index]);
1379 l_diag[
c - 1] = -
prev;
1384 prev = alphas[current_index] * r / (alphas[current_index] + alphas[next_index]);
1386 l_diag[N - 2] = -
prev;
1390 ordered_index = ordered_index_start;
1391 for (
int k = 0;
k < N;
k++) {
1392 current_index = ordered_y_nodes[ordered_index];
1407 double* delta =
g->ics_adi_dir_z->deltas;
1408 long* lines =
g->ics_adi_dir_z->ordered_line_defs;
1409 long* ordered_z_nodes =
g->ics_adi_dir_z->ordered_nodes;
1411 double* l_diag =
g->ics_tasks->l_diag;
1412 double*
diag =
g->ics_tasks->diag;
1413 double* u_diag =
g->ics_tasks->u_diag;
1415 long next_index = -1;
1416 long prev_index = -1;
1419 double dz =
g->ics_adi_dir_z->d;
1420 double dc =
g->ics_adi_dir_z->dc;
1421 double r =
dt *
dc /
SQ(dz);
1425 long ordered_index = node_start;
1426 for (
int i = line_start;
i < line_stop - 1;
i += 2) {
1427 long N = lines[
i + 1];
1428 long ordered_index_start = ordered_index;
1430 for (
int j = 0;
j < N;
j++) {
1431 current_index = ordered_z_nodes[ordered_index];
1433 dt * delta[current_index] / (alphas[current_index] *
SQ(dz));
1437 ordered_index = ordered_index_start;
1438 current_index = ordered_z_nodes[ordered_index];
1440 next_index = ordered_z_nodes[ordered_index];
1441 next = alphas[next_index] * r / (alphas[next_index] + alphas[current_index]);
1445 for (
int c = 1;
c < N - 1;
c++) {
1446 prev_index = current_index;
1447 current_index = next_index;
1448 next_index = ordered_z_nodes[ordered_index];
1449 prev = alphas[prev_index] * r / (alphas[prev_index] + alphas[current_index]);
1450 next = alphas[next_index] * r / (alphas[next_index] + alphas[current_index]);
1451 l_diag[
c - 1] = -
prev;
1456 prev = alphas[current_index] * r / (alphas[current_index] + alphas[next_index]);
1458 l_diag[N - 2] = -
prev;
1461 ordered_index = ordered_index_start;
1462 for (
int k = 0;
k < N;
k++) {
1463 current_index = ordered_z_nodes[ordered_index];
1473 long x_line_start =
g->ics_adi_dir_x->line_start_stop_indices[0];
1474 long x_line_stop =
g->ics_adi_dir_x->line_start_stop_indices[
NUM_THREADS * 2 - 1];
1475 long x_node_start =
g->ics_adi_dir_x->ordered_start_stop_indices[0];
1476 long* x_line_defs =
g->ics_adi_dir_x->ordered_line_defs;
1477 long* x_ordered_nodes =
g->ics_adi_dir_x->ordered_nodes;
1478 double* delta_x =
g->ics_adi_dir_x->deltas;
1480 long y_line_start =
g->ics_adi_dir_y->line_start_stop_indices[0];
1481 long y_line_stop =
g->ics_adi_dir_y->line_start_stop_indices[
NUM_THREADS * 2 - 1];
1482 long y_node_start =
g->ics_adi_dir_y->ordered_start_stop_indices[0];
1483 long* y_line_defs =
g->ics_adi_dir_y->ordered_line_defs;
1484 long* y_ordered_nodes =
g->ics_adi_dir_y->ordered_nodes;
1485 double* delta_y =
g->ics_adi_dir_y->deltas;
1487 long z_line_start =
g->ics_adi_dir_z->line_start_stop_indices[0];
1488 long z_line_stop =
g->ics_adi_dir_z->line_start_stop_indices[
NUM_THREADS * 2 - 1];
1489 long z_node_start =
g->ics_adi_dir_z->ordered_start_stop_indices[0];
1490 long* z_line_defs =
g->ics_adi_dir_z->ordered_line_defs;
1491 long* z_ordered_nodes =
g->ics_adi_dir_z->ordered_nodes;
1492 double* delta_z =
g->ics_adi_dir_z->deltas;
1494 double* Grid_RHS =
g->ics_tasks->RHS;
1495 double* Grid_ScratchPad =
g->ics_tasks->scratchpad;
1497 double* CVode_states_copy = (
double*) calloc(
num_states,
sizeof(
double));
1498 memcpy(CVode_states_copy, CVodeRHS,
sizeof(
double) *
num_states);
1500 double* alphas =
g->_ics_alphas;
1502 if (
g->ics_adi_dir_x->dcgrid ==
NULL) {
1511 g->ics_adi_dir_x->dc,
1520 g->ics_adi_dir_y->dc,
1529 g->ics_adi_dir_z->dc,
1569 g->ics_adi_dir_x->dcgrid,
1578 g->ics_adi_dir_y->dcgrid,
1587 g->ics_adi_dir_z->dcgrid,
1599 g->ics_adi_dir_x->dcgrid,
1609 g->ics_adi_dir_y->dcgrid,
1619 g->ics_adi_dir_z->dcgrid,
1623 memcpy(CVodeRHS, CVode_states_copy,
sizeof(
double) *
num_states);
1624 free(CVode_states_copy);
1629 long num_1d_indices =
g->hybrid_data->num_1d_indices;
1630 long* indices1d =
g->hybrid_data->indices1d;
1631 long* num_3d_indices_per_1d_seg =
g->hybrid_data->num_3d_indices_per_1d_seg;
1632 long* indices3d =
g->hybrid_data->indices3d;
1633 double* rates =
g->hybrid_data->rates;
1634 double* volumes1d =
g->hybrid_data->volumes1d;
1635 double* volumes3d =
g->hybrid_data->volumes3d;
1637 double vol_1d, vol_3d, rate, conc_1d;
1638 int my_3d_index, my_1d_index;
1641 int total_num_3d_indices_per_1d_seg = 0;
1642 for (
int i = 0;
i < num_1d_indices;
i++) {
1643 total_num_3d_indices_per_1d_seg += num_3d_indices_per_1d_seg[
i];
1647 double* old_g_states = (
double*) malloc(
sizeof(
double) * total_num_3d_indices_per_1d_seg);
1650 for (
int i = 0;
i < num_1d_indices;
i++) {
1651 for (
int j = 0;
j < num_3d_indices_per_1d_seg[
i];
j++, vol_3d_index++) {
1652 old_g_states[vol_3d_index] =
g->states[indices3d[vol_3d_index]];
1657 for (
int i = 0;
i < num_1d_indices;
i++) {
1658 vol_1d = volumes1d[
i];
1659 my_1d_index = indices1d[
i];
1660 conc_1d =
states[my_1d_index];
1665 for (
int j = 0;
j < num_3d_indices_per_1d_seg[
i];
j++, vol_3d_index++) {
1666 vol_3d = volumes3d[vol_3d_index];
1668 my_3d_index = indices3d[vol_3d_index];
1669 rate = (rates[vol_3d_index]) * (old_g_states[vol_3d_index] - conc_1d);
1671 g->states[my_3d_index] -=
dt * rate;
1672 states[my_1d_index] +=
dt * rate * vol_3d / vol_1d;
1682 const double* cvode_states_3d,
1683 double*
const ydot_3d,
1684 const double* cvode_states_1d,
1685 double*
const ydot_1d) {
1686 long num_1d_indices =
g->hybrid_data->num_1d_indices;
1687 long* indices1d =
g->hybrid_data->indices1d;
1688 long* num_3d_indices_per_1d_seg =
g->hybrid_data->num_3d_indices_per_1d_seg;
1689 long* indices3d =
g->hybrid_data->indices3d;
1690 double* rates =
g->hybrid_data->rates;
1691 double* volumes1d =
g->hybrid_data->volumes1d;
1692 double* volumes3d =
g->hybrid_data->volumes3d;
1694 double vol_1d, vol_3d, rate, conc_1d;
1695 int my_3d_index, my_1d_index;
1696 int vol_3d_index = 0;
1698 for (
int i = 0;
i < num_1d_indices;
i++) {
1699 vol_1d = volumes1d[
i];
1700 my_1d_index = indices1d[
i];
1701 conc_1d = cvode_states_1d[my_1d_index];
1702 for (
int j = 0;
j < num_3d_indices_per_1d_seg[
i];
j++, vol_3d_index++) {
1703 vol_3d = volumes3d[vol_3d_index];
1705 my_3d_index = indices3d[vol_3d_index];
1706 rate = (rates[vol_3d_index]) * (cvode_states_3d[my_3d_index] - conc_1d);
1708 ydot_3d[my_3d_index] -= rate;
1709 ydot_1d[my_1d_index] += rate * vol_3d / vol_1d;
Hybrid_data * hybrid_data
void run_threaded_ics_dg_adi(struct ICSAdiDirection *)
struct ICSAdiGridData * ics_tasks
Grid_node * Parallel_grids[100]
static philox4x32_key_t k
void TaskQueue_add_task(TaskQueue *q, void *(*task)(void *), void *args, void *result)
void TaskQueue_sync(TaskQueue *q)
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)
static void * do_ics_deltas(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_rhs_variable_step_helper(ICS_Grid_node *g, double const *const states, double *ydot)
void run_threaded_deltas(ICS_Grid_node *g, ICSAdiDirection *ics_adi_dir)
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)
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)
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 int solve_dd_tridiag(int N, const double *l_diag, const double *diag, const double *u_diag, double *b, double *c)
static double flux(const double alphai, const double alphaj, const double statei, const double statej)
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)
void ics_ode_solve_helper(ICS_Grid_node *g, double dt, double *CVodeRHS)
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)
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)
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 _ics_hybrid_helper(ICS_Grid_node *g)
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 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)
void * do_ics_dg_adi(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)
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)
static double current_state(void *v)
long * num_3d_indices_per_1d_seg
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
ICSAdiDirection * ics_adi_dir