1 #include <../../nrnconf.h> 10 #define DcX(x,y,z) (g->dc_x*PERM(x,y,z)) 11 #define DcY(x,y,z) (g->dc_y*PERM(x,y,z)) 12 #define DcZ(x,y,z) (g->dc_z*PERM(x,y,z)) 16 #define Fxx(x1,x2) (ALPHA(x1,y,z)*ALPHA(x2,y,z)*DcX(x1,y,z)*(g->states[IDX(x1,y,z)] - g->states[IDX(x2,y,z)])/((ALPHA(x1,y,z)+ALPHA(x2,y,z)))) 17 #define Fxy(y1,y1d,y2) (ALPHA(x,y1,z)*ALPHA(x,y2,z)*DcY(x,y1d,z)*(g->states[IDX(x,y1,z)] - g->states[IDX(x,y2,z)])/((ALPHA(x,y1,z)+ALPHA(x,y2,z)))) 18 #define Fxz(z1,z1d,z2) (ALPHA(x,y,z1)*ALPHA(x,y,z2)*DcZ(x,y,z1d)*(g->states[IDX(x,y,z1)] - g->states[IDX(x,y,z2)])/((ALPHA(x,y,z1)+ALPHA(x,y,z2)))) 19 #define Fyy(y1,y2) (ALPHA(x,y1,z)*ALPHA(x,y2,z)*DcY(x,y1,z)*(g->states[IDX(x,y1,z)] - g->states[IDX(x,y2,z)])/((ALPHA(x,y1,z)+ALPHA(x,y2,z)))) 20 #define Fzz(z1,z2) (ALPHA(x,y,z1)*ALPHA(x,y,z2)*DcZ(x,y,z1)*(g->states[IDX(x,y,z1)] - g->states[IDX(x,y,z2)])/((ALPHA(x,y,z1)+ALPHA(x,y,z2)))) 23 #define FLUX(pidx,idx) (VOLFRAC(pidx)*VOLFRAC(idx)*(states[pidx] - states[idx]))/(0.5*(VOLFRAC(pidx)+VOLFRAC(idx))) 37 const double* u_diag,
double* b,
double *
c)
41 c[0] = u_diag[0]/diag[0];
46 c[
i] = u_diag[
i]/(diag[
i]-l_diag[i-1]*c[i-1]);
47 b[
i] = (b[
i]-l_diag[i-1]*b[i-1])/(diag[i]-l_diag[i-1]*c[i-1]);
49 b[N-1] = (b[N-1]-l_diag[N-2]*b[N-2])/(diag[N-1]-l_diag[N-2]*c[N-2]);
55 b[
i]=b[
i]-c[
i]*b[i+1];
73 int yp,ypd,ym,ymd,zp,zpd,zm,zmd;
89 div_y = ((y==0||y==g->
size_y-1)?1.0:0.5)*
SQ(g->
dy);
90 div_z = ((z==0||z==g->
size_z-1)?1.0:0.5)*
SQ(g->
dz);
100 yp = (y==g->
size_y-1)?y-1:y+1;
101 ypd = (y==g->
size_y-1)?y:y+1;
114 zp = (z==g->
size_z-1)?z-1:z+1;
115 zpd = (z==g->
size_z-1)?z:z+1;
131 RHS[0] += (
Fxy(yp,ypd,y) -
Fxy(y,ymd,ym))/div_y;
133 RHS[0] += (
Fxz(zp,zpd,z) -
Fxz(z,zmd,zm))/div_z;
134 RHS[0] *= (dt/
ALPHA(0,y,z));
141 diag = (
double*)malloc(g->
size_x*
sizeof(
double));
142 l_diag = (
double*)malloc((g->
size_x-1)*
sizeof(double));
143 u_diag = (
double*)malloc((g->
size_x-1)*
sizeof(double));
145 for(x=1;x<g->
size_x-1;x++)
150 l_diag[x-1] = -dt*prev/
SQ(g->
dx);
151 diag[x] = 1. + dt*(prev +
next)/
SQ(g->
dx);
152 u_diag[x] = -dt*next/
SQ(g->
dx);
160 diag[0] = 1. + dt*next/
SQ(g->
dx);
161 u_diag[0] = -dt*next/
SQ(g->
dx);
169 RHS[x] = state[
IDX(x,y,z)] + (dt/
ALPHA(x,y,z))*
171 + (
Fxy(yp,ypd,y) -
Fxy(y,ymd,ym))/div_y
172 + (
Fxz(zp,zpd,z) -
Fxz(z,zmd,zm))/div_z)
176 RHS[x] = state[
IDX(x,y,z)] + (dt/
ALPHA(x,y,z))*
178 + (
Fxy(yp,ypd,y) -
Fxy(y,ymd,ym))/div_y
179 + (
Fxz(zp,zpd,z) -
Fxz(z,zmd,zm))/div_z)
192 for(x=1;x<g->
size_x-1;x++)
195 __builtin_prefetch(&(state[
IDX(x+
PREFETCH,y,z)]), 0, 1);
196 __builtin_prefetch(&(state[
IDX(x+
PREFETCH,yp,z)]), 0, 0);
197 __builtin_prefetch(&(state[
IDX(x+
PREFETCH,ym,z)]), 0, 0);
198 __builtin_prefetch(&(state[
IDX(x+
PREFETCH,ypd,z)]), 0, 0);
199 __builtin_prefetch(&(state[
IDX(x+
PREFETCH,ymd,z)]), 0, 0);
201 RHS[x] = state[
IDX(x,y,z)] + (dt/
ALPHA(x,y,z))*
203 + (
Fxy(yp,ypd,y) -
Fxy(y,ymd,ym))/div_y
204 + (
Fxz(zp,zpd,z) -
Fxz(z,zmd,zm))/div_z)
236 for(y=0; y<g->
size_y; y++)
249 RHS[0] = state[x + z*g->
size_x];
254 diag = (
double*)malloc(g->
size_y*
sizeof(
double));
255 l_diag = (
double*)malloc((g->
size_y-1)*
sizeof(double));
256 u_diag = (
double*)malloc((g->
size_y-1)*
sizeof(double));
258 for(y=1;y<g->
size_y-1;y++)
263 l_diag[y-1] = -dt*prev/
SQ(g->
dy);
264 diag[y] = 1. + dt*(prev +
next)/
SQ(g->
dy);
265 u_diag[y] = -dt*next/
SQ(g->
dy);
273 diag[0] = 1. + dt*next/
SQ(g->
dy);
274 u_diag[0] = -dt*next/
SQ(g->
dy);
296 for(y=1;y<g->
size_y-1;y++)
335 for(z=0; z<g->
size_z; z++)
347 RHS[0] = state[y + g->
size_y*x];
352 diag = (
double*)malloc(g->
size_z*
sizeof(
double));
353 l_diag = (
double*)malloc((g->
size_z-1)*
sizeof(double));
354 u_diag = (
double*)malloc((g->
size_z-1)*
sizeof(double));
356 for(z=1;z<g->
size_z-1;z++)
361 l_diag[z-1] = -dt*prev/
SQ(g->
dz);
362 diag[z] = 1. + dt*(prev +
next)/
SQ(g->
dz);
363 u_diag[z] = -dt*next/
SQ(g->
dz);
370 diag[0] = 1. + dt*next/
SQ(g->
dz);
371 u_diag[0] = -dt*next/
SQ(g->
dz);
393 for(z=1;z<g->
size_z-1;z++)
432 int yp,ypd,ym,ymd,zp,zpd,zm,zmd,div_y,div_z;
440 for(x=0; x<g->
size_x; x++)
446 div_y = (y==0||y==g->
size_y-1)?2:1;
447 div_z = (z==0||z==g->
size_z-1)?2:1;
457 yp = (y==g->
size_y-1)?y-1:y+1;
458 ypd = (y==g->
size_y-1)?y:y+1;
471 zp = (z==g->
size_z-1)?z-1:z+1;
472 zpd = (z==g->
size_z-1)?z:z+1;
487 RHS[0] += (
DcY(0,ypd,z)*state[
IDX(0,yp,z)] - (
DcY(0,ypd,z)+
DcY(0,ymd,z))*state[
IDX(0,y,z)] +
DcY(0,ymd,z)*state[
IDX(0,ym,z)])/(div_y*
SQ(g->
dy));
489 RHS[0] += (
DcZ(0,y,zpd)*state[
IDX(0,y,zp)] - (
DcZ(0,y,zpd)+
DcZ(0,y,zmd))*state[
IDX(0,y,z)] +
DcZ(0,y,zmd)*state[
IDX(0,y,zm)])/(div_z*
SQ(g->
dz));
496 diag = (
double*)malloc(g->
size_x*
sizeof(
double));
497 l_diag = (
double*)malloc((g->
size_x-1)*
sizeof(double));
498 u_diag = (
double*)malloc((g->
size_x-1)*
sizeof(double));
500 for(x=1;x<g->
size_x-1;x++)
502 l_diag[x-1] = -dt*
DcX(x,y,z)/(2.*
SQ(g->
dx));
503 diag[x] = 1. + dt*(
DcX(x,y,z) +
DcX(x+1,y,z))/(2.*
SQ(g->
dx));
504 u_diag[x] = -dt*
DcX(x+1,y,z)/(2.*
SQ(g->
dx));
510 diag[0] = 1. + 0.5*dt*
DcX(1,y,z)/
SQ(g->
dx);
511 u_diag[0] = -0.5*dt*
DcX(1,y,z)/
SQ(g->
dx);
516 RHS[0] = state[
IDX(0,y,z)]
517 + dt*((
DcX(1,y,z)*state[
IDX(1,y,z)] -
DcX(1,y,z)*state[
IDX(0,y,z)])/(2.*
SQ(g->
dx))
518 + (
DcY(0,ypd,z)*state[
IDX(0,yp,z)] - (
DcY(0,ypd,z)+
DcY(0,ymd,z))*state[
IDX(0,y,z)] +
DcY(0,ymd,z)*state[
IDX(0,ym,z)])/(div_y*
SQ(g->
dy))
519 + (
DcZ(0,y,zpd)*state[
IDX(0,y,zp)] - (
DcZ(0,y,zpd)+
DcZ(0,y,zmd))*state[
IDX(0,y,z)] +
DcZ(0,y,zmd)*state[
IDX(0,y,zm)])/(div_z*
SQ(g->
dz)))
522 RHS[x] = state[
IDX(x,y,z)]
523 + dt*((
DcX(x,y,z)*state[
IDX(x-1,y,z)] -
DcX(x,y,z)*state[
IDX(x,y,z)])/(2.*
SQ(g->
dx))
524 + (
DcY(x,ypd,z)*state[
IDX(x,yp,z)] - (
DcY(x,ypd,z)+
DcY(x,ymd,z))*state[
IDX(x,y,z)] +
DcY(x,ymd,z)*state[
IDX(x,ym,z)])/(div_y*
SQ(g->
dy))
525 + (
DcZ(x,y,zpd)*state[
IDX(x,y,zp)] - (
DcZ(x,y,zpd)+
DcZ(x,y,zmd))*state[
IDX(x,y,z)] +
DcZ(x,y,zmd)*state[
IDX(x,y,zm)])/(div_z*
SQ(g->
dz)))
534 l_diag[g->
size_x-2] = 0.0;
539 for(x=1;x<g->
size_x-1;x++)
542 __builtin_prefetch(&(state[
IDX(x+
PREFETCH,y,z)]), 0, 1);
543 __builtin_prefetch(&(state[
IDX(x+
PREFETCH,yp,z)]), 0, 0);
544 __builtin_prefetch(&(state[
IDX(x+
PREFETCH,ym,z)]), 0, 0);
547 RHS[x] = state[
IDX(x,y,z)]
548 + dt*((
DcX(x+1,y,z)*state[
IDX(x+1,y,z)] - (
DcX(x+1,y,z)+
DcX(x,y,z))*state[
IDX(x,y,z)] +
DcX(x,y,z)*state[
IDX(x-1,y,z)])/(2.*
SQ(g->
dx))
549 + (
DcY(x,ypd,z)*state[
IDX(x,yp,z)] - (
DcY(x,ypd,z)+
DcY(x,ymd,z))*state[
IDX(x,y,z)] +
DcY(x,ymd,z)*state[
IDX(x,ym,z)])/(div_y*
SQ(g->
dy))
550 + (
DcZ(x,y,zpd)*state[
IDX(x,y,zp)] - (
DcZ(x,y,zpd)+
DcZ(x,y,zmd))*state[
IDX(x,y,z)] +
DcZ(x,y,zmd)*state[
IDX(x,y,zm)])/(div_z*
SQ(g->
dz)))
582 for(y=0; y<g->
size_y; y++)
595 RHS[0] = state[x + z*g->
size_x];
600 diag = (
double*)malloc(g->
size_y*
sizeof(
double));
601 l_diag = (
double*)malloc((g->
size_y-1)*
sizeof(double));
602 u_diag = (
double*)malloc((g->
size_y-1)*
sizeof(double));
604 for(y=1;y<g->
size_y-1;y++)
606 l_diag[y-1] = -dt*
DcY(x,y,z)/(2.*
SQ(g->
dy));
607 diag[y] = 1. + dt*(
DcY(x,y,z)+
DcY(x,y+1,z))/(2.*
SQ(g->
dy));
608 u_diag[y] = -dt*
DcY(x,y+1,z)/(2.*
SQ(g->
dy));
614 diag[0] = 1. + 0.5*dt*
DcY(x,1,z)/
SQ(g->
dy);
615 u_diag[0] = -0.5*dt*
DcY(x,1,z)/
SQ(g->
dy);
631 l_diag[g->
size_y-2] = 0.0;
637 for(y=1;y<g->
size_y-1;y++)
643 RHS[y] = state[x + (z + y*g->
size_z)*g->
size_x] - dt*(
DcY(x,y+1,z)*g->
states[
IDX(x,y+1,z)] - (
DcY(x,y+1,z)+
DcY(x,y,z))*g->
states[
IDX(x,y,z)] +
DcY(x,y,z)*g->
states[
IDX(x,y-1,z)])/(2.*
SQ(g->
dy));
675 for(z=0; z<g->
size_z; z++)
688 RHS[0] = state[y + g->
size_y*x];
692 diag = (
double*)malloc(g->
size_z*
sizeof(
double));
693 l_diag = (
double*)malloc((g->
size_z-1)*
sizeof(double));
694 u_diag = (
double*)malloc((g->
size_z-1)*
sizeof(double));
697 for(z=1;z<g->
size_z-1;z++)
699 l_diag[z-1] = -dt*
DcZ(x,y,z)/(2.*
SQ(g->
dz));
700 diag[z] = 1. + dt*(
DcZ(x,y,z)+
DcZ(x,y,z+1))/(2.*
SQ(g->
dz));
701 u_diag[z] = -dt*
DcZ(x,y,z+1)/(2.*
SQ(g->
dz));
707 diag[0] = 1. + 0.5*dt*
DcZ(x,y,1)/
SQ(g->
dz);
708 u_diag[0] = -0.5*dt*
DcZ(x,y,1)/
SQ(g->
dz);
722 l_diag[g->
size_z-2] = 0.0;
729 for(z=1;z<g->
size_z-1;z++)
732 - dt*(
DcZ(x,y,z+1)*g->
states[
IDX(x,y,z+1)] - (
DcZ(x,y,z+1)+
DcZ(x,y,z))*g->
states[
IDX(x,y,z)] +
DcZ(x,y,z)*g->
states[
IDX(x,y,z-1)])/(2.*
SQ(g->
dz));
764 double dx = g->
dx, dy = g->
dy, dz = g->
dz;
765 int i,
j,
k, stop_i, stop_j, stop_k;
766 double rate_x = 1. / (dx * dx);
767 double rate_y = 1. / (dy * dy);
768 double rate_z = 1. / (dz * dz);
771 int index, prev_i, prev_j, prev_k, next_i ,next_j, next_k;
772 int xpd, xmd, ypd, ymd, zpd, zmd;
773 double div_x, div_y, div_z;
776 stop_i = num_states_x - 1;
777 stop_j = num_states_y - 1;
778 stop_k = num_states_z - 1;
780 for (i = 0, index = 0, prev_i = num_states_y*num_states_z, next_i = num_states_y*num_states_z;
781 i < num_states_x; i++) {
783 div_x = (i==0||i==stop_i)?2.:1.;
784 xpd = (i==stop_i)?i:i+1;
787 for(j = 0, prev_j = index + num_states_z, next_j = index + num_states_z; j < num_states_y; j++) {
788 div_y = (j==0||j==stop_j)?2.:1.;
789 ypd = (j==stop_j)?j:j+1;
792 for(k = 0, prev_k = index + 1, next_k = index + 1; k < num_states_z;
793 k++, index++, prev_i++, next_i++, prev_j++, next_j++) {
794 div_z = (k==0||k==stop_k)?2.:1.;
795 zpd = (k==stop_k)?k:k+1;
800 ydot[
index] += rate_x * (
DcX(xmd,j,k)*states[prev_i] -
801 (
DcX(xmd,j,k)+
DcX(xpd,j,k)) * states[index] +
802 DcX(xpd,j,k)*states[next_i])/div_x;
806 ydot[
index] += rate_y * (
DcY(i,ymd,k)*states[prev_j] -
807 (
DcY(i,ymd,k)+
DcY(i,ypd,k)) * states[index] +
808 DcY(i,ypd,k)*states[next_j])/div_y;
813 ydot[
index] += rate_z * (
DcZ(i,j,zmd)*states[prev_k] -
814 (
DcZ(i,j,zmd)+
DcZ(i,j,zpd)) * states[index] +
815 DcZ(i,j,zpd)*states[next_k])/div_z;
818 next_k = (k==stop_k-1)?index:index+2;
822 prev_j = index - num_states_z;
823 next_j = (j==stop_j-1)?prev_j:index + num_states_z;
825 prev_i = index - num_states_y*num_states_z;
826 next_i = (i==stop_i-1)?prev_i:index+num_states_y*num_states_z;
830 for (i = 0, index = 0, prev_i = 0, next_i = num_states_y*num_states_z;
831 i < num_states_x; i++) {
832 for(j = 0, prev_j = index - num_states_z, next_j = index + num_states_z; j < num_states_y; j++) {
834 for(k = 0, prev_k = index - 1, next_k = index + 1; k < num_states_z;
835 k++, index++, prev_i++, next_i++, prev_j++, next_j++, next_k++, prev_k++) {
837 if(i==0||i==stop_i||j==0||j==stop_j||k==0||k==stop_k)
845 ydot[
index] += rate_x * (
DcX(i,j,k)*states[prev_i] -
846 (
DcX(i,j,k)+
DcX(i+1,j,k)) * states[index] +
847 DcX(i+1,j,k)*states[next_i]);
849 ydot[
index] += rate_y * (
DcY(i,j,k)*states[prev_j] -
850 (
DcY(i,j,k)+
DcY(i,j+1,k)) * states[index] +
851 DcY(i,j+1,k)*states[next_j]);
853 ydot[
index] += rate_z * (
DcZ(i,j,k)*states[prev_k] -
854 (
DcZ(i,j,k)+
DcZ(i,j,k+1)) * states[index] +
855 DcZ(i,j,k+1)*states[next_k]);
858 prev_j = index - num_states_z;
859 next_j = index + num_states_z;
861 prev_i = index - num_states_y*num_states_z;
862 next_i = index + num_states_y*num_states_z;
872 double dx = g->
dx, dy = g->
dy, dz = g->
dz;
873 int i,
j,
k, stop_i, stop_j, stop_k;
874 double rate_x = g->
dc_x / (dx * dx);
875 double rate_y = g->
dc_y / (dy * dy);
876 double rate_z = g->
dc_z / (dz * dz);
880 int index, prev_i, prev_j, prev_k, next_i ,next_j, next_k;
883 int xpd, xmd, ypd, ymd, zpd, zmd;
884 double div_x, div_y, div_z;
887 stop_i = num_states_x - 1;
888 stop_j = num_states_y - 1;
889 stop_k = num_states_z - 1;
891 for (i = 0, index = 0, prev_i = num_states_y*num_states_z, next_i = num_states_y*num_states_z;
892 i < num_states_x; i++) {
894 div_x = (i==0||i==stop_i)?2.:1.;
895 xpd = (i==stop_i)?i:i+1;
898 for(j = 0, prev_j = index + num_states_z, next_j = index + num_states_z; j < num_states_y; j++) {
899 div_y = (j==0||j==stop_j)?2.:1.;
900 ypd = (j==stop_j)?j:j+1;
903 for(k = 0, prev_k = index + 1, next_k = index + 1; k < num_states_z;
904 k++, index++, prev_i++, next_i++, prev_j++, next_j++) {
905 div_z = (k==0||k==stop_k)?2.:1.;
906 zpd = (k==stop_k)?k:k+1;
930 next_k = (k==stop_k-1)?index:index+2;
934 prev_j = index - num_states_z;
935 next_j = (j==stop_j-1)?prev_j:index + num_states_z;
937 prev_i = index - num_states_y*num_states_z;
938 next_i = (i==stop_i-1)?prev_i:index+num_states_y*num_states_z;
942 for (i = 0, index = 0, prev_i = 0, next_i = num_states_y*num_states_z;
943 i < num_states_x; i++) {
944 for(j = 0, prev_j = index - num_states_z, next_j = index + num_states_z; j < num_states_y; j++) {
946 for(k = 0, prev_k = index - 1, next_k = index + 1; k < num_states_z;
947 k++, index++, prev_i++, next_i++, prev_j++, next_j++, next_k++, prev_k++) {
949 if(i==0||i==stop_i||j==0||j==stop_j||k==0||k==stop_k)
969 prev_j = index - num_states_z;
970 next_j = index + num_states_z;
972 prev_i = index - num_states_y*num_states_z;
973 next_i = index + num_states_y*num_states_z;
void ecs_set_adi_vol(ECS_Grid_node *g)
static void ecs_dg_adi_tort_x(ECS_Grid_node *g, const double dt, const int y, const int z, double const *const state, double *const RHS, double *const scratch)
static void ecs_dg_adi_vol_x(ECS_Grid_node *g, const double dt, const int y, const int z, double const *const state, double *const RHS, double *const scratch)
static void ecs_dg_adi_tort_z(ECS_Grid_node *g, double const dt, int const x, int const y, double const *const state, double *const RHS, double *const scratch)
static philox4x32_key_t k
void ecs_set_adi_tort(ECS_Grid_node *g)
void _rhs_variable_step_helper_vol(Grid_node *g, double const *const states, double *ydot)
static void ecs_dg_adi_tort_y(ECS_Grid_node *g, double const dt, int const x, int const z, double const *const state, double *const RHS, double *const scratch)
static char scratch[MAXLINE+1]
static void ecs_dg_adi_vol_z(ECS_Grid_node *g, double const dt, int const x, int const y, double const *const state, double *const RHS, double *const scratch)
struct ECSAdiDirection * ecs_adi_dir_z
struct ECSAdiDirection * ecs_adi_dir_y
static int solve_dd_tridiag(int N, const double *l_diag, const double *diag, const double *u_diag, double *b, double *c)
void(* ecs_dg_adi_dir)(ECS_Grid_node *, const double, const int, const int, double const *const, double *const, double *const)
static void ecs_dg_adi_vol_y(ECS_Grid_node *g, double const dt, int const x, int const z, double const *const state, double *const RHS, double *const scratch)
struct ECSAdiDirection * ecs_adi_dir_x
void _rhs_variable_step_helper_tort(Grid_node *g, double const *const states, double *ydot)