⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 symamgsol.c

📁 a software code for computing selected eigenvalues of large sparse symmetric matrices
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdlib.h>#include <stdio.h>#include <blas.h>#include <lapack.h>#include <ilupack.h>#include <ilupackmacros.h>#define MAX_LINE        255#define STDERR          stderr#define STDOUT          stdout//#define PRINT_INFO#define IABS(A)         (((A)>=0)?(A):-(A))#define MAX(A,B)        (((A)>(B))?(A):(B))#define MIN(A,B)        (((A)<(B))?(A):(B))#if defined _DOUBLE_REAL_ || defined _SINGLE_REAL_#define CONJG(A)      (A)#define MYCSRMATVEC          CSRMATVEC #define MYCSRMATTVEC         CSRMATTVEC #ifdef _DOUBLE_REAL_#define MYSYMAMGSOL          DSYMAMGsol#define MYSYMPILUCSOL        DSYMpilucsol#define MYSYMPILUCLSOL       DSYMpiluclsol#define MYSYMPILUCUSOL       DSYMpilucusol#define MYPRIVATESPTRS       dprivatesptrs#define MYSPTRS              dsptrs#else			   #define MYSYMAMGSOL          SSYMAMGsol#define MYSYMPILUCSOL        SSYMpilucsol#define MYSYMPILUCLSOL       SSYMpiluclsol#define MYSYMPILUCUSOL       SSYMpilucusol#define MYPRIVATESPTRS       sprivatesptrs#define MYSPTRS              ssptrs#endif#else#ifdef _COMPLEX_SYMMETRIC_#define CONJG(A)     (A)#define MYCSRMATVEC          CSRMATVEC #define MYCSRMATTVEC         CSRMATTVEC #ifdef _SINGLE_COMPLEX_#define MYSYMAMGSOL          CSYMAMGsol#define MYSYMPILUCSOL        CSYMpilucsol#define MYSYMPILUCLSOL       CSYMpiluclsol#define MYSYMPILUCUSOL       CSYMpilucusol#define MYSPTRS              csptrs#else#define MYSYMAMGSOL          ZSYMAMGsol#define MYSYMPILUCSOL        ZSYMpilucsol#define MYSYMPILUCLSOL       ZSYMpiluclsol#define MYSYMPILUCUSOL       ZSYMpilucusol#define MYSPTRS              zsptrs#endif#else#define MYCSRMATVEC          CSRMATVEC #define MYCSRMATTVEC         CSRMATHVEC #ifdef _SINGLE_COMPLEX_#define CONJG(A)     (conjg(A))#define MYSYMAMGSOL          CHERAMGsol#define MYSYMPILUCSOL        CHERpilucsol#define MYSYMPILUCLSOL       CHERpiluclsol#define MYSYMPILUCUSOL       CHERpilucusol#define MYPRIVATESPTRS       cprivatehptrs#define MYSPTRS              chptrs#else#define CONJG(A)     (dconjg(A))#define MYSYMAMGSOL          ZHERAMGsol#define MYSYMPILUCSOL        ZHERpilucsol#define MYSYMPILUCLSOL       ZHERpiluclsol#define MYSYMPILUCUSOL       ZHERpilucusol#define MYPRIVATESPTRS       zprivatehptrs#define MYSPTRS              zhptrs#endif#endif#endif#define MAX_LINE        255#define STDERR          stderr#define STDOUT          stdout#define MAX(A,B)        (((A)>(B))?(A):(B))#define MIN(A,B)        (((A)<(B))?(A):(B))/*   Given a multilevel ILU decomposition performed by SYMAMGsetup,    SYMAMGsol performs a simple forward backward substitution*/ void MYSYMAMGSOL(AMGLEVELMAT PRE, integer nlev, 		 ILUPACKPARAM *IPparam,		 FLOAT *rhs, FLOAT *sol, FLOAT *buff){/*   PRE       linked list of multilevel ILU preconditioners   nlev      number of levels (blocks)   rhs       given right hand side   sol       solution obtained by SYMAMGsol   buff      work array of length 2n, where n is the size of the original              matrix     Code written by Matthias Bollhoefer, February 2005*/   AMGLEVELMAT *next, *prev;   integer i, j, k,n=PRE.n, nB, *p, *invq, sumn=0, lev,buffldl,buffldl2,ierr, flag,           globalflag=0;      FLOAT *scal, *a;   REALS val, vali;#ifdef PRINT_INFO   static integer check=1;   if (check) {     check=0;#ifdef _SINGLE_REAL_      printf("SSYM solve\n");#else#ifdef _DOUBLE_REAL_     printf("DSYM solve\n");#else#ifdef _SINGLE_COMPLEX_#ifdef _COMPLEX_SYMMETRIC_     printf("CSYM solve\n");#else     printf("CHER solve\n");#endif#else#ifdef _COMPLEX_SYMMETRIC_     printf("ZSYM solve\n");#else     printf("ZHER solve\n");#endif#endif#endif#endif   }#endif   buff+=n;   for (i=0; i<n; i++)       buff[i]=rhs[i];   buff-=n;   /* block forward substitution */   next=&PRE;   prev=NULL;   lev=1;      while (lev<nlev) {	 nB=next->nB;	 p=next->p;#ifdef PRINT_INFO	 printf("%3d\n",lev);fflush(stdout);#endif	 if (lev>1) {	    scal=next->colscal-sumn;	    buff+=n;	    for (i=sumn; i<n; i++) {#if defined _DOUBLE_REAL_ || defined _SINGLE_REAL_	        buff[i]*=scal[i];#else		val=buff[i].r;	        buff[i].r= val*scal[i].r+buff[i].i*scal[i].i;	        buff[i].i=-val*scal[i].i+buff[i].i*scal[i].r;#endif	    }	    buff-=n;	 } /* end if */	 /* reorder the whole system */	 p-=sumn;	 for (i=sumn; i<n; i++)	     buff[i]=buff[n+sumn+p[i]-1];	 p+=sumn;	 	 /* first block */	 if (next->LU.ja[0]<0) {	    flag=-1;	    globalflag=-1;	 }	 else	   flag=0;	 next->LU.ja[0]=IABS(next->LU.ja[0]);	 if (flag) {	    // printf("1.\n");fflush(stdout);	    // solve system with [(L+D)D^{-1}]	    MYSYMPILUCLSOL(&nB, buff+sumn,buff+n+sumn, next->LU.a,next->LU.ja);	    // printf("2.\n");fflush(stdout);	 }	 else	    MYSYMPILUCSOL(&nB, buff+sumn,buff+n+sumn, next->LU.a,next->LU.ja);	 if (flag) {	    sol +=sumn;	    buff+=n+sumn;	    // multiply by D^{-1}	    i=0;	    a=next->LU.a;	    // printf("3.\n");fflush(stdout);	    while (i<nB) {	          if (next->LU.ja[nB+1+i]==0) {#if defined _DOUBLE_REAL_ || defined _SINGLE_REAL_		     sol[i]=buff[i]*a[i];#else		     sol[i].r=buff[i].r*a[i].r-buff[i].i*a[i].i;		     sol[i].i=buff[i].r*a[i].i+buff[i].i*a[i].r;#endif		     i++;		  }		  else {#if defined _DOUBLE_REAL_ || defined _SINGLE_REAL_		     sol[i]  =a[i]            *buff[i]+a[nB+1+i]*buff[i+1];		     sol[i+1]=a[nB+1+i]       *buff[i]+a[i+1]   *buff[i+1];#else		     sol[i].r  =a[i].r     *buff[i].r  -a[i].i     *buff[i].i		               +a[nB+1+i].r*buff[i+1].r-a[nB+1+i].i*buff[i+1].i;		     sol[i].i  =a[i].r     *buff[i].i  +a[i].i     *buff[i].r		               +a[nB+1+i].r*buff[i+1].i+a[nB+1+i].i*buff[i+1].r;#ifdef _COMPLEX_SYMMETRIC_		     		     sol[i+1].r=a[nB+1+i].r*buff[i].r  -a[nB+1+i].i*buff[i].i		               +a[i+1].r   *buff[i+1].r-a[i+1].i   *buff[i+1].i;		     sol[i+1].i=a[nB+1+i].r*buff[i].i  +a[nB+1+i].i*buff[i].r		               +a[i+1].r   *buff[i+1].i+a[i+1].i   *buff[i+1].r;#else		     sol[i+1].r=a[nB+1+i].r*buff[i].r  +a[nB+1+i].i*buff[i].i		               +a[i+1].r   *buff[i+1].r-a[i+1].i   *buff[i+1].i;		     sol[i+1].i=a[nB+1+i].r*buff[i].i  -a[nB+1+i].i*buff[i].r		               +a[i+1].r   *buff[i+1].i+a[i+1].i   *buff[i+1].r;#endif#endif		     i+=2;		  }	    } // end while	    // multiply by |D|^{-1}	    i=0;	    a=next->absdiag;	    // printf("4.\n");fflush(stdout);	    while (i<nB) {	          if (next->LU.ja[nB+1+i]==0) {#if defined _DOUBLE_REAL_ || defined _SINGLE_REAL_		     buff[i]*=a[i];#else		     val      =buff[i].r*a[i].r-buff[i].i*a[i].i;		     buff[i].i=buff[i].r*a[i].i+buff[i].i*a[i].r;		     buff[i].r=val;#endif		     i++;		  }		  else {#if defined _DOUBLE_REAL_ || defined _SINGLE_REAL_		     val      =a[i]            *buff[i]+a[nB+1+i]*buff[i+1];		     buff[i+1]=a[nB+1+i]       *buff[i]+a[i+1]   *buff[i+1];		     buff[i]  =val;#else		     val        =a[i].r     *buff[i].r  -a[i].i     *buff[i].i		                +a[nB+1+i].r*buff[i+1].r-a[nB+1+i].i*buff[i+1].i;		     buff[i].i  =a[i].r     *buff[i].i  +a[i].i     *buff[i].r		                +a[nB+1+i].r*buff[i+1].i+a[nB+1+i].i*buff[i+1].r;#ifdef _COMPLEX_SYMMETRIC_		     		     vali       =a[nB+1+i].r*buff[i].r  -a[nB+1+i].i*buff[i].i		                +a[i+1].r   *buff[i+1].r-a[i+1].i   *buff[i+1].i;		     buff[i+1].i=a[nB+1+i].r*buff[i].i  +a[nB+1+i].i*buff[i].r		                +a[i+1].r   *buff[i+1].i+a[i+1].i   *buff[i+1].r;#else		     vali       =a[nB+1+i].r*buff[i].r  +a[nB+1+i].i*buff[i].i		                +a[i+1].r   *buff[i+1].r-a[i+1].i   *buff[i+1].i;		     buff[i+1].i=a[nB+1+i].r*buff[i].i  -a[nB+1+i].i*buff[i].r		                +a[i+1].r   *buff[i+1].i+a[i+1].i   *buff[i+1].r;#endif		     buff[i+1].r=vali;		     buff[i].r  =val;#endif		     i+=2;		  }	    } // end while	    // printf("5.\n");fflush(stdout);	    // solve system with [D^{-1}(D+U)]	    MYSYMPILUCUSOL(&nB, sol,sol, next->LU.a,next->LU.ja);	    // printf("6.\n");fflush(stdout);	    MYCSRMATTVEC(next->F,sol,sol+nB);	    // printf("7.\n");fflush(stdout);	    next->LU.ja[0]=-IABS(next->LU.ja[0]);	    sol -=sumn;	    buff-=n+sumn;	 }	 else	    /* second block, multiply by F^H */	    MYCSRMATTVEC(next->F,buff+n+sumn,sol+sumn+nB);	 sumn+=nB;	 /* coarse grid projection */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -