102 int iter,d,i,j,NT,bs2=bs*bs,nsbs=ns*bs;
103 double norm=0,norm0=0,global_norm=0;
106 MPI_Comm *comm = (MPI_Comm*) m;
110 MPI_Comm_size(*comm,&nproc);
111 MPI_Comm_rank(*comm,&rank);
119 fprintf(stderr,
"Error in tridiagIterJacobi(): NULL pointer passed for parameters!\n");
123 double *rhs = (
double*) calloc (ns*n*bs,
sizeof(
double));
124 for (i=0; i<ns*n*bs; i++) rhs[i] = x[i];
126 for (i=0; i<n; i++) {
127 for (d=0; d<ns; d++) {
134 double *recvbufL, *recvbufR, *sendbufL, *sendbufR;
135 recvbufL = (
double*) calloc (nsbs,
sizeof(
double));
136 recvbufR = (
double*) calloc (nsbs,
sizeof(
double));
137 sendbufL = (
double*) calloc (nsbs,
sizeof(
double));
138 sendbufR = (
double*) calloc (nsbs,
sizeof(
double));
145 if (context->
evaluate_norm) MPI_Allreduce(&n,&NT,1,MPI_INT,MPI_SUM,*comm);
150 if (context->
verbose) printf(
"\n");
152 if (context->
verbose && (!rank)) printf(
"\n");
159 if ( (iter >= context->
maxiter)
160 || (iter && context->
evaluate_norm && (global_norm < context->atol))
161 || (iter && context->
evaluate_norm && (global_norm/norm0 < context->rtol)) ) {
166 for (d=0; d<nsbs; d++) recvbufL[d] = recvbufR[d] = 0;
168 MPI_Request req[4] = {MPI_REQUEST_NULL,MPI_REQUEST_NULL,MPI_REQUEST_NULL,MPI_REQUEST_NULL};
169 if (rank) MPI_Irecv(recvbufL,nsbs,MPI_DOUBLE,rank-1,2,*comm,&req[0]);
170 if (rank != nproc-1) MPI_Irecv(recvbufR,nsbs,MPI_DOUBLE,rank+1,3,*comm,&req[1]);
171 for (d=0; d<nsbs; d++) {
173 sendbufR[d] = x[(n-1)*nsbs+d];
175 if (rank) MPI_Isend(sendbufL,nsbs,MPI_DOUBLE,rank-1,3,*comm,&req[2]);
176 if (rank != nproc-1) MPI_Isend(sendbufR,nsbs,MPI_DOUBLE,rank+1,2,*comm,&req[3]);
182 for (i=1; i<n-1; i++) {
183 for (d=0; d<ns; d++) {
184 double err[bs];
for (j=0; j<bs; j++) err[j] = rhs[(i*ns+d)*bs+j];
188 for (j=0; j<bs; j++) norm += (err[j]*err[j]);
194 MPI_Status status_arr[4];
195 MPI_Waitall(4,req,status_arr);
199 for (d=0; d<ns; d++) {
200 double err[bs];
for (j=0; j<bs; j++) err[j] = rhs[d*bs+j];
204 for (j=0; j<bs; j++) norm += (err[j]*err[j]);
206 for (d=0; d<ns; d++) {
207 double err[bs];
for (j=0; j<bs; j++) err[j] = rhs[(d+ns*(n-1))*bs+j];
211 for (j=0; j<bs; j++) norm += (err[j]*err[j]);
214 for (d=0; d<ns; d++) {
215 double err[bs];
for (j=0; j<bs; j++) err[j] = rhs[d*bs+j];
219 for (j=0; j<bs; j++) norm += (err[j]*err[j]);
226 MPI_Allreduce(&norm,&global_norm,1,MPI_DOUBLE,MPI_SUM,*comm);
228 global_norm = sqrt(global_norm/NT);
229 if (!iter) norm0 = global_norm;
238 if (context->
verbose && (!rank))
240 printf(
"\t\titer: %d, norm: %1.16E\n",iter,global_norm);
244 for (d=0; d<ns; d++) {
245 double xt[bs],binv[bs2];
248 for (j=0; j<bs; j++) xt[j] = rhs[(i*ns+d)*bs+j];
255 for (j=0; j<bs; j++) xt[j] = rhs[(i*ns+d)*bs+j];
261 for (i=1; i<n-1; i++) {
262 for (d=0; d<ns; d++) {
263 double xt[bs],binv[bs2];
264 for (j=0; j<bs; j++) xt[j] = rhs[(i*ns+d)*bs+j];
272 for (d=0; d<ns; d++) {
273 double xt[bs],binv[bs2];
274 for (j=0; j<bs; j++) xt[j] = rhs[d*bs+j];
Header file for TridiagLU.
#define _MatVecMultiplySubtract_(y, A, x, N)
Contains macros and function definitions for common matrix operations.
#define _MatrixInvert_(A, B, N)
int blocktridiagIterJacobi(double *, double *, double *, double *, int, int, int, void *, void *)
#define _MatVecMultiply_(A, x, y, N)