Exemplo n.º 1
0
/* 2d linear elasticity */
int elasti1_2d(LSst *lsst) {
  pCsr     A;
  int      ier;
  char     stim[32];

  /* -- Part I: matrix assembly */
  if ( lsst->info.verb != '0' )  fprintf(stdout,"    Matrix and right-hand side assembly\n");

  /* counting P2 nodes (for dylib) */
	if ( lsst->info.typ == P2 && !lsst->info.np2 ) {
		lsst->info.np2 = hashar_2d(lsst);
		if ( lsst->info.np2 == 0 ) {
			fprintf(stdout," # Error on P2 nodes.\n");
			return(0);
		}
	}

  /* allocating memory (for dylib) */
  if ( !lsst->sol.u ) {
    lsst->sol.u  = (double*)calloc(lsst->info.dim*(lsst->info.npi+lsst->info.np2),sizeof(double));
    assert(lsst->sol.u);
  }

  /* build matrix */
  A = lsst->info.typ == P1 ? matA_P1_2d(lsst) : matA_P2_2d(lsst);
  lsst->sol.F = lsst->info.typ == P1 ? rhsF_P1_2d(lsst) : rhsF_P2_2d(lsst);

  /* free mesh structure + boundary conditions */
  if ( !lsst->info.xport && lsst->info.mfree ) {
		free(lsst->mesh.tria);
    if ( !lsst->info.zip )  free(lsst->mesh.point);
	}

  /* -- Part II: solver */
  if ( lsst->info.verb != '0' ) {
    fprintf(stdout,"    Solving linear system:");  fflush(stdout);
    ier = csrPrecondGrad(A,lsst->sol.u,lsst->sol.F,&lsst->sol.res,&lsst->sol.nit,1);
    if ( ier <= 0 )
      fprintf(stdout,"\n # convergence problem: %d\n",ier);
    else
      fprintf(stdout," %E in %d iterations\n",lsst->sol.res,lsst->sol.nit);
	}
  else {
    ier = csrPrecondGrad(A,lsst->sol.u,lsst->sol.F,&lsst->sol.res,&lsst->sol.nit,1);
  }

  /* free memory */
  csrFree(A);
  free(lsst->sol.F);

  return(ier > 0);
}
Exemplo n.º 2
0
/* solve Ax = b using preconditionned conjugate gradient method. Return code:
 >0 upon completion, <0 no convergence
 0 memory problem
 -1 ill conditioned matrix
 -2 max it reached  */
int csrPrecondGrad(pCsr A,double *x,double *b,double *er,int *ni,char tgv) {
    pCsr      L;
    double   *ap,*p,*q,*y;
    double    dp,nn,rmp,rm,rm2,alpha,beta,err;
    int       n,it,ier,nit;
    
    /* allocation */
    if ( !x || !b )  return(0);
    assert(A->nr == A->nc);
    n = A->nr;
    y = (double*)malloc(A->nr*sizeof(double));
    assert(y);
    
    /* compute R0 = y = b - A.x0 */
    nn = csrXY(x,x,A->nr);
    if ( nn < CS_EPSD2 ) {
        memcpy(y,b,A->nr*sizeof(double));
    }
    else {
        csrAxpy(A,x,b,y,-1.,1.);
    }
    rmp = csrXY(y,y,A->nr);
    if ( fabs(rmp) < CS_EPSD2 ) {
        free(y);
        return(1);
    }
    else if ( tgv ) {
        rmp /= CS_TGV2;
    }
    
    /* P_1 = P^-1.R_0 */
    p  = (double*)malloc(A->nr*sizeof(double));
    q  = (double*)malloc(A->nr*sizeof(double));
    ap = (double*)malloc(A->nr*sizeof(double));
    assert(p);
    assert(q);
    assert(ap);
    
    /* incomplete SSOR factorization */
    L = csrTr(A);
    csrSSOR(A,L,p,y);
    
    err = *er;
    err = err * err * rmp;
    nit = *ni;
    ier = 1;
    it  = 0;
    rm  = rmp;
    while ( (err < rm) && ++it <= nit ) {
        /* alpha_m = <P^-1.R_m-1,R_m-1> / <AP_m,P_m> */
        rm = csrXY(p,y,n);
        if ( fabs(rm) <= CS_EPSD2 )  break;
        dp = csrAxdotx(A,p,ap);
        if ( fabs(dp) <= CS_EPSD2 )  break;
        
        /* X_m = X_m-1 + alpha_m.P_m , R_m = R_m-1 - alpha_m AP_m */
        alpha = (rm / dp);
        csrlXmY(p,x,x,alpha,1.0,n);
        csrlXmY(ap,y,y,-alpha,1.0,n);
        
        /* beta_m = <P^-1.R_m,R_m> / <P^-1.R_m-1,R_m-1> */
        csrSSOR(A,L,q,y);
        rm2 = csrXY(q,y,n);
        if ( fabs(rm2) <= CS_EPSD2 )  break;
        
        /* P_m+1 = P^-1.R_m + beta_m P_m */
        beta = rm2 / rm;
        csrlXmY(p,q,p,beta,1.0,n);
        //printf("  GC1: it  %d err %E   rm %E\n",it,err,rm2);
        rm = rm2;
    }
    if ( it > nit )   ier = -2;
    *er = sqrt(rm / rmp);
    *ni = it;
    free(p);
    free(q);
    free(y);
    free(ap);
    csrFree(L);
    return(ier);
}