PrecondJac.c

 /* Jacobi (diagonal) preconditioner */

 /* Copyright John B. Pormann, 21 July 2000, all rights reserved */



 #include "CardioWave.h"

 static char* RCSID = "$Id: PrecondJac.c,v 1.4 2005/05/18 21:29:22 john Exp $";

 static vector InvDiag?  = _INIT_VECTOR;
 static real*  Stn_InvDiag = NULL;

 int InitPreconditioner( char** res ) {
 	if( (DebugLevel>0) and (SelfPE==0) ) {
 		printf("Preconditioner: Jacobi\n");
 		if( DebugLevel > 1 ) {
 			printf("PrecondJac?: RCSID: %s\n",RCSID);
 		}
 	}

 	return( 0 );
 }

 void ExitPreconditioner( void ) {
 	vecfree( &InvDiag? );

 	return;
 }

 void ComputeFactors( bigmatrix A ) {
 	int i,b,ofs;
 	int nblks = A.NumBlocks?;
 	real* av;
 	real* xv;
 	sparse* S;

 	/* A.Int may be NULL, so we'll look at A.Ext for matrix type */
 	if( A.MatrixInfo?[0].type == _STENCIL ) {
 		Stn_InvDiag = (real*)malloc( nblks*sizeof(real) );

 		for(b=0;b<nblks;b++) {
 		  /* find dimensionality of system */
 		  S = &A.MatrixInfo?[b+b*nblks];
 		  switch( S->jcoef[0] ) {
 			case 0: Stn_InvDiag[b] = 1.0/S->coef[0];
 				break;
 			case 1: Stn_InvDiag[b] = 1.0/S->coef[1];
 				break;
 			case 2: Stn_InvDiag[b] = 1.0/S->coef[4];
 				break;
 			case 3: Stn_InvDiag[b] = 1.0/S->coef[13];
 				break;
 		  }
 		}
 	} else {
 		vecalloc( &InvDiag?, Solver );

 		/* go thru each block in turn */
 		/* : but put all 1/Aii terms into 1 big vector */
 		/*   for better performance during Prec.Solve  */
 		xv = InvDiag?.data;
 		for(b=0;b<nblks;b++) {
 			av  = A.MatrixInfo?[b+b*nblks].coef;
 			ofs = A.BlockSplit?[b];
 			for(i=0;i<A.MatrixInfo?[b+b*nblks].rows;i++) {
 				xv[i+ofs] = 1.0/av[i];
 			}
 		}
 	}

 	return;
 }

 int PreconditionSystem( bigmatrix A, vector x, vector b ) {
 	int i,j,k,nd,ne;
 	int ofsI,ofsR;
 	int nblks = A.NumBlocks?;
 	real val;
 	vector xtmp,btmp;

 	/* x = b/diag(A) */
 	if( A.MatrixInfo?[0].type == _STENCIL ) {

 		for(i=0;i<nblks;i++) {
 			xtmp.size  = A.BlockSplit?[i+1] - A.BlockSplit?[i];
 			xtmp.dtype = A.MatrixInfo?[i+i*nblks].dtype;
 			xtmp.data  = x.data + A.BlockSplit?[i];
 			btmp.size  = A.BlockSplit?[i+1] - A.BlockSplit?[i];
 			btmp.dtype = A.MatrixInfo?[i+i*nblks].dtype;
 			btmp.data  = b.data + A.BlockSplit?[i];
 			vvaddb( Stn_InvDiag[i], btmp, 0.0, xtmp );

 			/* take care of the DBCs? */
 			nd = A.MatrixInfo?[i+i*nblks].jcoef[0];
 			switch( nd ) {
 				case 3: ofsI = 5;		/* where do DBCs? start?      */
 					ofsR = 27;			/* (I=jcoef, R=coef offsets) */
 					break;
 				case 2: ofsI = 4;
 					ofsR = 9;
 					break;
 				case 1: ofsI = 3;
 					ofsR = 3;
 					break;
 				case 0: ofsI = 2;
 					ofsR = 1;
 					break;
 			}
 			ne = A.MatrixInfo?[i+i*nblks].jcoef[ofsI];
 			for(j=0;j<ne;j++) {
 				k = A.MatrixInfo?[i+i*nblks].jcoef[ofsI+1+j];
 				/* xtmp.data[k] = A.MatrixInfo?[i+i*nblks].coef[ofsR+j]; */
 				xtmp.data[k] = btmp.data[k];
 			}
 		}

 	} else {
 		vvmpyb( 1.0, b, InvDiag?, 0.0, x );
 	}

 	return( 0 );
 }
Edit - History - Print - Recent Changes - Search
Page last modified on November 23, 2009, at 10:14 AM