Beispiel #1
0
static PetscErrorCode PCSetUp_SPAI(PC pc)
{
  PC_SPAI        *ispai = (PC_SPAI*)pc->data;
  PetscErrorCode ierr;
  Mat            AT;

  PetscFunctionBegin;

  init_SPAI();

  if (ispai->sp) {
    ierr = ConvertMatToMatrix(ispai->comm_spai,pc->pmat,pc->pmat,&ispai->B);CHKERRQ(ierr);
  } else {
    /* Use the transpose to get the column nonzero structure. */
    ierr = MatTranspose(pc->pmat,MAT_INITIAL_MATRIX,&AT);CHKERRQ(ierr);
    ierr = ConvertMatToMatrix(ispai->comm_spai,pc->pmat,AT,&ispai->B);CHKERRQ(ierr);
    ierr = MatDestroy(&AT);CHKERRQ(ierr);
  }

  /* Destroy the transpose */
  /* Don't know how to do it. PETSc developers? */
    
  /* construct SPAI preconditioner */
  /* FILE *messages */     /* file for warning messages */
  /* double epsilon */     /* tolerance */
  /* int nbsteps */        /* max number of "improvement" steps per line */
  /* int max */            /* max dimensions of is_I, q, etc. */
  /* int maxnew */         /* max number of new entries per step */
  /* int block_size */     /* block_size == 1 specifies scalar elments
                              block_size == n specifies nxn constant-block elements
                              block_size == 0 specifies variable-block elements */
  /* int cache_size */     /* one of (1,2,3,4,5,6) indicting size of cache */
                           /* cache_size == 0 indicates no caching */
  /* int    verbose    */  /* verbose == 0 specifies that SPAI is silent
                              verbose == 1 prints timing and matrix statistics */

  ierr = bspai(ispai->B,&ispai->M,
		   stdout,
		   ispai->epsilon,
		   ispai->nbsteps,
		   ispai->max,
		   ispai->maxnew,
		   ispai->block_size,
		   ispai->cache_size,
	       ispai->verbose);CHKERRQ(ierr);

  ierr = ConvertMatrixToMat(((PetscObject)pc)->comm,ispai->M,&ispai->PM);CHKERRQ(ierr);

  /* free the SPAI matrices */
  sp_free_matrix(ispai->B);
  sp_free_matrix(ispai->M);

  PetscFunctionReturn(0);
}
Beispiel #2
0
int bspai
(matrix *A, matrix **bspai_matrix,
 FILE *messages_arg,   /* file for warning messages */
 double epsilon_arg,   /* tolerance */
 int nbsteps_arg,      /* max number of accepted elements per line
                          (sc = 0); is set to ld+lu+1 for spar = 2 */
 int max_arg,          /* max dimensions of I, q, etc. */
 int maxnew_arg,       /* max number of new entries per step */
 int bs,               /* block size */
 int cache_size_arg,   /* one of (1,2,3,4,5,6) indicting size of cache */
                       /* cache_size == 0 indicates no caching */
 int verbose_arg,
 int spar_arg,
 int lower_diag_arg,
 int upper_diag_arg,
 double tau_arg)
{
  matrix *B;
  matrix *M_B;
  matrix *M;
  extern int A_max_block_size;
  int total_bad_cols;
  int j,nnz,ierr;
  if (verbose_arg) matrix_statistics(A,"A");
  if (spar_arg && A->max_block_size > 1)	/* MH: ??? */
    {
	printf("Sorry, sc > 0 only supported for block size 1\n");
	exit(1);
    }
  /* Scalar case */
  if (bs == 1) {
    if (verbose_arg && (A->myid == 0))
      printf("\nConstructing scalar SPAI matrix M from A\n");

    if ((ierr = spai(A, &M,
	     messages_arg,
	     epsilon_arg,
	     nbsteps_arg,
	     max_arg,
	     maxnew_arg,
	     cache_size_arg,
	     verbose_arg,
             spar_arg,
             lower_diag_arg,
             upper_diag_arg,
		     tau_arg)) != 0)  return ierr;
#ifdef MPI
    MPI_Barrier(A->comm);
#endif

  }

  /* Block case */
  else {

    /* Convert A to either a constant or variable block matrix B. */
    /* The 3rd argument can be used to set an upper limit
       on the block size. For now it's unused (i.e., zero). */
    if (verbose_arg && (A->myid == 0))
      printf("\nConstructing block matrix B from A\n");
    B = block_matrix(A,bs,0,verbose_arg);

    if (verbose_arg) matrix_statistics(B,"B");

    if (verbose_arg && (A->myid == 0))
      printf("Constructing block SPAI matrix M_B from B\n");
    if ((ierr = spai(B, &M_B,
	       messages_arg,
	       epsilon_arg,
	       nbsteps_arg,
	       max_arg,
	       maxnew_arg,
	       cache_size_arg,
	       verbose_arg,
               spar_arg,
               lower_diag_arg,
               upper_diag_arg,
		     tau_arg)) != 0)  return ierr;

#ifdef MPI
    MPI_Barrier(A->comm);
#endif

    /* VE */
    if (num_bad_cols) printf("SPAI: # bad columns = %d\n",num_bad_cols);

    if (verbose_arg) matrix_statistics(M_B,"M_B");

    /*  Convert M_B to scalar matrix.  */
    if (verbose_arg && (A->myid == 0))
      printf("\nConstructing scalar SPAI matrix M from M_B\n");
    M = scalar_matrix(M_B,verbose_arg);

    sp_free_matrix(B);
    sp_free_matrix(M_B);

  }

  if (verbose_arg) matrix_statistics(M,"M");

  *bspai_matrix = M;
  return 0;

}