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_Waitall(4,req,MPI_STATUS_IGNORE);
198 for (d=0; d<ns; d++) {
199 double err[bs];
for (j=0; j<bs; j++) err[j] = rhs[d*bs+j];
203 for (j=0; j<bs; j++) norm += (err[j]*err[j]);
205 for (d=0; d<ns; d++) {
206 double err[bs];
for (j=0; j<bs; j++) err[j] = rhs[(d+ns*(n-1))*bs+j];
210 for (j=0; j<bs; j++) norm += (err[j]*err[j]);
213 for (d=0; d<ns; d++) {
214 double err[bs];
for (j=0; j<bs; j++) err[j] = rhs[d*bs+j];
218 for (j=0; j<bs; j++) norm += (err[j]*err[j]);
225 MPI_Allreduce(&norm,&global_norm,1,MPI_DOUBLE,MPI_SUM,*comm);
227 global_norm = sqrt(global_norm/NT);
228 if (!iter) norm0 = global_norm;
237 if (context->
verbose && (!rank))
239 printf(
"\t\titer: %d, norm: %1.16E\n",iter,global_norm);
243 for (d=0; d<ns; d++) {
244 double xt[bs],binv[bs2];
247 for (j=0; j<bs; j++) xt[j] = rhs[(i*ns+d)*bs+j];
254 for (j=0; j<bs; j++) xt[j] = rhs[(i*ns+d)*bs+j];
260 for (i=1; i<n-1; i++) {
261 for (d=0; d<ns; d++) {
262 double xt[bs],binv[bs2];
263 for (j=0; j<bs; j++) xt[j] = rhs[(i*ns+d)*bs+j];
271 for (d=0; d<ns; d++) {
272 double xt[bs],binv[bs2];
273 for (j=0; j<bs; j++) xt[j] = rhs[d*bs+j];
Header file for TridiagLU.
Contains macros and function definitions for common matrix operations.
#define _MatVecMultiplySubtract_(y, A, x, N)
#define _MatVecMultiply_(A, x, y, N)
#define _MatrixInvert_(A, B, N)
int blocktridiagIterJacobi(double *a, double *b, double *c, double *x, int n, int ns, int bs, void *r, void *m)