#define NRANSI #include "nrutil.h" #define NPRE 1 #define NPOST 1 #define NGMAX 15 void mglin(double **u, int n, int ncycle) { void addint(double **uf, double **uc, double **res, int nf); void copy(double **aout, double **ain, int n); void fill0(double **u, int n); void interp(double **uf, double **uc, int nf); void relax(double **u, double **rhs, int n); void resid(double **res, double **u, double **rhs, int n); void rstrct(double **uc, double **uf, int nc); void slvsml(double **u, double **rhs); unsigned int j,jcycle,jj,jpost,jpre,nf,ng=0,ngrid,nn; double **ires[NGMAX+1],**irho[NGMAX+1],**irhs[NGMAX+1],**iu[NGMAX+1]; nn=n; while (nn >>= 1) ng++; if (n != 1+(1L << ng)) nrerror("n-1 must be a power of 2 in mglin."); if (ng > NGMAX) nrerror("increase NGMAX in mglin."); nn=n/2+1; ngrid=ng-1; irho[ngrid]=dmatrix(1,nn,1,nn); rstrct(irho[ngrid],u,nn); while (nn > 3) { nn=nn/2+1; irho[--ngrid]=dmatrix(1,nn,1,nn); rstrct(irho[ngrid],irho[ngrid+1],nn); } nn=3; iu[1]=dmatrix(1,nn,1,nn); irhs[1]=dmatrix(1,nn,1,nn); slvsml(iu[1],irho[1]); free_dmatrix(irho[1],1,nn,1,nn); ngrid=ng; for (j=2;j<=ngrid;j++) { nn=2*nn-1; iu[j]=dmatrix(1,nn,1,nn); irhs[j]=dmatrix(1,nn,1,nn); ires[j]=dmatrix(1,nn,1,nn); interp(iu[j],iu[j-1],nn); copy(irhs[j],(j != ngrid ? irho[j] : u),nn); for (jcycle=1;jcycle<=ncycle;jcycle++) { nf=nn; for (jj=j;jj>=2;jj--) { for (jpre=1;jpre<=NPRE;jpre++) relax(iu[jj],irhs[jj],nf); resid(ires[jj],iu[jj],irhs[jj],nf); nf=nf/2+1; rstrct(irhs[jj-1],ires[jj],nf); fill0(iu[jj-1],nf); } slvsml(iu[1],irhs[1]); nf=3; for (jj=2;jj<=j;jj++) { nf=2*nf-1; addint(iu[jj],iu[jj-1],ires[jj],nf); for (jpost=1;jpost<=NPOST;jpost++) relax(iu[jj],irhs[jj],nf); } } } copy(u,iu[ngrid],n); for (nn=n,j=ng;j>=2;j--,nn=nn/2+1) { free_dmatrix(ires[j],1,nn,1,nn); free_dmatrix(irhs[j],1,nn,1,nn); free_dmatrix(iu[j],1,nn,1,nn); if (j != ng) free_dmatrix(irho[j],1,nn,1,nn); } free_dmatrix(irhs[1],1,3,1,3); free_dmatrix(iu[1],1,3,1,3); } #undef NPRE #undef NPOST #undef NGMAX #undef NRANSI