Пример #1
0
PetscErrorCode DMCoarsen_AKKT_GAMG11(DM dm, Mat P0f0c, Mat *P1f1c_out) {
  PetscErrorCode ierr;
  DM_AKKT* kkt = (DM_AKKT*)(dm->data);
  Mat Aff   = kkt->Aff;   /* fine-level KKT matrix */ 
  Mat A1f0f;              /* fine-level dual (constraint) Jacobian */
  Mat A1f0c;              /* = A1f0f*P0f0c coarsen only primal indices */
  Mat B1f1f;              /* = A1f0c'*A1f0c */
  PC  gamg11;/* Use PCGAMG internally to get access to some of its methods to operate on B1f1f = A1f0c*A1f0c', where A1f0c = A1f0f*P0f0c. */
  PC_GAMG* pc_gamg11;
  Mat G1f1f; /* = Graph(B1f1f) */
  Mat P1f1c; /* = Prolongator(G1f1f); */
  PetscCoarsenData *coarsening;
  PetscFunctionBegin;

  /* 
   What is faster: 
     - A0c1f = P0f0c'*A0f1f followed by B1f1f = A0c1f'*A0c1f, or
     - A1f0c = A1f0f*P0f0c  followed by B1f1f = A1f0c*A1f0c'?
   My bet is on the latter: 
     - fewer transpositions inside MatMatMult and row indices are always local.
   */

  ierr = MatGetSubMatrix(Aff, kkt->isf[1], kkt->isf[0], MAT_INITIAL_MATRIX, &A1f0f);      CHKERRQ(ierr);
  if(kkt->transposeP) {
    ierr = MatMatTransposeMult(A1f0f,P0f0c,MAT_INITIAL_MATRIX, PETSC_DEFAULT, &A1f0c);    CHKERRQ(ierr); 
  }
  ierr = MatMatMult(A1f0f,P0f0c,MAT_INITIAL_MATRIX, PETSC_DEFAULT, &A1f0c);               CHKERRQ(ierr); 
  ierr = MatMatTransposeMult(A1f0c, A1f0c, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &B1f1f);    CHKERRQ(ierr); 
  
  /* We create PCGAMG here since it is only needed for coarsening and we don't want to have to carry the attendant data structures, if we don't need them. */
  ierr = PCCreate(((PetscObject)dm)->comm, &gamg11); CHKERRQ(ierr);
  /* This must be an aggregating GAMG. */
  ierr = PCSetType(gamg11, PCGAMG);                  CHKERRQ(ierr);
  ierr = PCGAMGSetSquareGraph(gamg11, PETSC_FALSE);  CHKERRQ(ierr);
  /* 
   Observe that we want to "square" A1f0c before passing it (B1f1f) to GAMG.
   This is not because we are not sure how GAMG will deal with a (potentially) non-square matrix,
   but rather because if we asked GAMG to square it, it would also smooth the resulting prolongator.
   At least PC_GAMG_AGG would, and we need an unsmoothed prolongator. 
   */
  ierr = PCSetOperators(gamg11, B1f1f, B1f1f, DIFFERENT_NONZERO_PATTERN);            CHKERRQ(ierr);
  /* FIX: Currently there is no way to tell GAMG to coarsen onto a give comm, but it shouldn't be hard to hack that stuff in. */
  pc_gamg11 = (PC_GAMG*)(gamg11->data);
  ierr = pc_gamg11->graph(gamg11, B1f1f, &G1f1f);                                   CHKERRQ(ierr);
  ierr = pc_gamg11->coarsen(gamg11, &G1f1f, &coarsening);                           CHKERRQ(ierr);
  ierr = pc_gamg11->prolongator(gamg11, B1f1f, G1f1f, coarsening, &P1f1c);          CHKERRQ(ierr);

  ierr = MatDestroy(&A1f0f); CHKERRQ(ierr);
  ierr = MatDestroy(&A1f0c); CHKERRQ(ierr);
  ierr = MatDestroy(&B1f1f); CHKERRQ(ierr);
  ierr = MatDestroy(&G1f1f); CHKERRQ(ierr);
  ierr = PCDestroy(&gamg11); CHKERRQ(ierr);
  
  *P1f1c_out = P1f1c;

  PetscFunctionReturn(0);
}
Пример #2
0
 std::shared_ptr<GenericMatrix> MatMatTransposeMult(GenericMatrix& A, GenericMatrix& B)
 {
   const dolfin::PETScMatrix* Ap = &as_type<const dolfin::PETScMatrix>(A);
   const dolfin::PETScMatrix* Bp = &as_type<const dolfin::PETScMatrix>(B);
   Mat CC;
   PetscErrorCode ierr = MatMatTransposeMult(Ap->mat(), Bp->mat(), MAT_INITIAL_MATRIX, PETSC_DEFAULT, &CC);
   dolfin::PETScMatrix CCC = PETScMatrix(CC);
   return CCC.copy();  
 }
Пример #3
0
static PetscErrorCode PCBDDCScalingSetUp_Deluxe_Private(PC pc)
{
  PC_BDDC                *pcbddc=(PC_BDDC*)pc->data;
  PCBDDCDeluxeScaling    deluxe_ctx=pcbddc->deluxe_ctx;
  PCBDDCSubSchurs        sub_schurs = pcbddc->sub_schurs;
  PetscScalar            *matdata,*matdata2;
  PetscInt               i,max_subset_size,cum,cum2;
  const PetscInt         *idxs;
  PetscBool              newsetup = PETSC_FALSE;
  PetscErrorCode         ierr;

  PetscFunctionBegin;
  if (!sub_schurs) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Missing PCBDDCSubSchurs");
  if (!sub_schurs->n_subs) PetscFunctionReturn(0);

  /* Allocate arrays for subproblems */
  if (!deluxe_ctx->seq_n) {
    deluxe_ctx->seq_n = sub_schurs->n_subs;
    ierr = PetscCalloc5(deluxe_ctx->seq_n,&deluxe_ctx->seq_scctx,deluxe_ctx->seq_n,&deluxe_ctx->seq_work1,deluxe_ctx->seq_n,&deluxe_ctx->seq_work2,deluxe_ctx->seq_n,&deluxe_ctx->seq_mat,deluxe_ctx->seq_n,&deluxe_ctx->seq_mat_inv_sum);CHKERRQ(ierr);
    newsetup = PETSC_TRUE;
  } else if (deluxe_ctx->seq_n != sub_schurs->n_subs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Number of deluxe subproblems %D is different from the sub_schurs %D",deluxe_ctx->seq_n,sub_schurs->n_subs);

  /* the change of basis is just a reference to sub_schurs->change (if any) */
  deluxe_ctx->change         = sub_schurs->change;
  deluxe_ctx->change_with_qr = sub_schurs->change_with_qr;

  /* Create objects for deluxe */
  max_subset_size = 0;
  for (i=0;i<sub_schurs->n_subs;i++) {
    PetscInt subset_size;
    ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr);
    max_subset_size = PetscMax(subset_size,max_subset_size);
  }
  if (newsetup) {
    ierr = PetscMalloc1(2*max_subset_size,&deluxe_ctx->workspace);CHKERRQ(ierr);
  }
  cum = cum2 = 0;
  ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs);CHKERRQ(ierr);
  ierr = MatSeqAIJGetArray(sub_schurs->S_Ej_all,&matdata);CHKERRQ(ierr);
  ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_all,&matdata2);CHKERRQ(ierr);
  for (i=0;i<deluxe_ctx->seq_n;i++) {
    PetscInt     subset_size;

    ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr);
    if (newsetup) {
      IS  sub;
      /* work vectors */
      ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,subset_size,deluxe_ctx->workspace,&deluxe_ctx->seq_work1[i]);CHKERRQ(ierr);
      ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,subset_size,deluxe_ctx->workspace+subset_size,&deluxe_ctx->seq_work2[i]);CHKERRQ(ierr);

      /* scatters */
      ierr = ISCreateGeneral(PETSC_COMM_SELF,subset_size,idxs+cum,PETSC_COPY_VALUES,&sub);CHKERRQ(ierr);
      ierr = VecScatterCreate(pcbddc->work_scaling,sub,deluxe_ctx->seq_work1[i],NULL,&deluxe_ctx->seq_scctx[i]);CHKERRQ(ierr);
      ierr = ISDestroy(&sub);CHKERRQ(ierr);
    }

    /* S_E_j */
    ierr = MatDestroy(&deluxe_ctx->seq_mat[i]);CHKERRQ(ierr);
    ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,matdata+cum2,&deluxe_ctx->seq_mat[i]);CHKERRQ(ierr);

    /* \sum_k S^k_E_j */
    ierr = MatDestroy(&deluxe_ctx->seq_mat_inv_sum[i]);CHKERRQ(ierr);
    ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,matdata2+cum2,&deluxe_ctx->seq_mat_inv_sum[i]);CHKERRQ(ierr);
    ierr = MatSetOption(deluxe_ctx->seq_mat_inv_sum[i],MAT_SPD,sub_schurs->is_posdef);CHKERRQ(ierr);
    ierr = MatSetOption(deluxe_ctx->seq_mat_inv_sum[i],MAT_HERMITIAN,sub_schurs->is_hermitian);CHKERRQ(ierr);
    if (sub_schurs->is_hermitian) {
      ierr = MatCholeskyFactor(deluxe_ctx->seq_mat_inv_sum[i],NULL,NULL);CHKERRQ(ierr);
    } else {
      ierr = MatLUFactor(deluxe_ctx->seq_mat_inv_sum[i],NULL,NULL,NULL);CHKERRQ(ierr);
    }
    if (pcbddc->deluxe_singlemat) {
      Mat X,Y;
      if (!sub_schurs->is_hermitian) {
        ierr = MatTranspose(deluxe_ctx->seq_mat[i],MAT_INITIAL_MATRIX,&X);CHKERRQ(ierr);
      } else {
        ierr = PetscObjectReference((PetscObject)deluxe_ctx->seq_mat[i]);CHKERRQ(ierr);
        X    = deluxe_ctx->seq_mat[i];
      }
      ierr = MatDuplicate(X,MAT_DO_NOT_COPY_VALUES,&Y);CHKERRQ(ierr);
      if (!sub_schurs->is_hermitian) {
        ierr = PCBDDCMatTransposeMatSolve_SeqDense(deluxe_ctx->seq_mat_inv_sum[i],X,Y);CHKERRQ(ierr);
      } else {
        ierr = MatMatSolve(deluxe_ctx->seq_mat_inv_sum[i],X,Y);CHKERRQ(ierr);
      }

      ierr = MatDestroy(&deluxe_ctx->seq_mat_inv_sum[i]);CHKERRQ(ierr);
      ierr = MatDestroy(&deluxe_ctx->seq_mat[i]);CHKERRQ(ierr);
      ierr = MatDestroy(&X);CHKERRQ(ierr);
      if (deluxe_ctx->change) {
        Mat C,CY;

        if (!deluxe_ctx->change_with_qr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only QR based change of basis");
        ierr = KSPGetOperators(deluxe_ctx->change[i],&C,NULL);CHKERRQ(ierr);
        ierr = MatMatMult(C,Y,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&CY);CHKERRQ(ierr);
        ierr = MatMatTransposeMult(CY,C,MAT_REUSE_MATRIX,PETSC_DEFAULT,&Y);CHKERRQ(ierr);
        ierr = MatDestroy(&CY);CHKERRQ(ierr);
      }
      ierr = MatTranspose(Y,MAT_INPLACE_MATRIX,&Y);CHKERRQ(ierr);
      deluxe_ctx->seq_mat[i] = Y;
    }
    cum += subset_size;
    cum2 += subset_size*subset_size;
  }
  ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs);CHKERRQ(ierr);
  ierr = MatSeqAIJRestoreArray(sub_schurs->S_Ej_all,&matdata);CHKERRQ(ierr);
  ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_all,&matdata2);CHKERRQ(ierr);
  if (pcbddc->deluxe_singlemat) {
    deluxe_ctx->change         = NULL;
    deluxe_ctx->change_with_qr = PETSC_FALSE;
  }

  if (deluxe_ctx->change && !deluxe_ctx->change_with_qr) {
    for (i=0;i<deluxe_ctx->seq_n;i++) {
      if (newsetup) {
        PC pc;

        ierr = KSPGetPC(deluxe_ctx->change[i],&pc);CHKERRQ(ierr);
        ierr = PCSetType(pc,PCLU);CHKERRQ(ierr);
        ierr = KSPSetFromOptions(deluxe_ctx->change[i]);CHKERRQ(ierr);
      }
      ierr = KSPSetUp(deluxe_ctx->change[i]);CHKERRQ(ierr);
    }
  }
  PetscFunctionReturn(0);
}
Пример #4
0
int main(int argc,char **argv) {
    Mat            A,B,C,D;
    PetscScalar    a[]= {1.,1.,0.,0.,1.,1.,0.,0.,1.};
    PetscInt       ij[]= {0,1,2};
    PetscScalar    none=-1.;
    PetscErrorCode ierr;
    PetscReal      fill=4;
    PetscReal      norm;

    PetscInitialize(&argc,&argv,(char *)0,help);
    ierr = MatCreate(PETSC_COMM_SELF,&A);
    CHKERRQ(ierr);
    ierr = MatSetSizes(A,3,3,3,3);
    CHKERRQ(ierr);
    ierr = MatSetType(A,MATSEQAIJ);
    CHKERRQ(ierr);
    ierr = MatSetUp(A);
    CHKERRQ(ierr);
    ierr = MatSetOption(A,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);
    CHKERRQ(ierr);
    ierr = MatSetValues(A,3,ij,3,ij,a,ADD_VALUES);
    CHKERRQ(ierr);
    ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
    CHKERRQ(ierr);
    ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
    CHKERRQ(ierr);
    ierr = MatSetOptionsPrefix(A,"A_");
    CHKERRQ(ierr);
    ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);
    CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_SELF,"\n");
    CHKERRQ(ierr);

    /* Test MatMatMult() */
    ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&B);
    CHKERRQ(ierr);      /* B = A^T */
    ierr = MatMatMult(B,A,MAT_INITIAL_MATRIX,fill,&C);
    CHKERRQ(ierr); /* C = B*A */
    ierr = MatSetOptionsPrefix(C,"C=B*A=A^T*A_");
    CHKERRQ(ierr);
    ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD);
    CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_SELF,"\n");
    CHKERRQ(ierr);

    ierr = MatMatMultSymbolic(C,A,fill,&D);
    CHKERRQ(ierr);
    ierr = MatMatMultNumeric(C,A,D);
    CHKERRQ(ierr);  /* D = C*A = (A^T*A)*A */
    ierr = MatSetOptionsPrefix(D,"D=C*A=(A^T*A)*A_");
    CHKERRQ(ierr);
    ierr = MatView(D,PETSC_VIEWER_STDOUT_WORLD);
    CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_SELF,"\n");
    CHKERRQ(ierr);

    /* Repeat the numeric product to test reuse of the previous symbolic product */
    ierr = MatMatMultNumeric(C,A,D);
    CHKERRQ(ierr);
    ierr = MatView(D,PETSC_VIEWER_STDOUT_WORLD);
    CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_SELF,"\n");
    CHKERRQ(ierr);

    ierr = MatDestroy(&B);
    CHKERRQ(ierr);
    ierr = MatDestroy(&C);
    CHKERRQ(ierr);

    /* Test PtAP routine. */
    ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);
    CHKERRQ(ierr);      /* B = A */
    ierr = MatPtAP(A,B,MAT_INITIAL_MATRIX,fill,&C);
    CHKERRQ(ierr); /* C = B^T*A*B */
    ierr = MatAXPY(D,none,C,DIFFERENT_NONZERO_PATTERN);
    CHKERRQ(ierr);
    ierr = MatNorm(D,NORM_FROBENIUS,&norm);
    if (norm > 1.e-15) {
        ierr = PetscPrintf(PETSC_COMM_SELF,"Error in MatPtAP: %g\n",norm);
    }
    ierr = MatDestroy(&C);
    CHKERRQ(ierr);
    ierr = MatDestroy(&D);
    CHKERRQ(ierr);

    /* Repeat PtAP to test symbolic/numeric separation for reuse of the symbolic product */
    ierr = MatPtAP(A,B,MAT_INITIAL_MATRIX,fill,&C);
    CHKERRQ(ierr);
    ierr = MatSetOptionsPrefix(C,"C=BtAB_");
    CHKERRQ(ierr);
    ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD);
    CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_SELF,"\n");
    CHKERRQ(ierr);

    ierr = MatPtAPSymbolic(A,B,fill,&D);
    CHKERRQ(ierr);
    ierr = MatPtAPNumeric(A,B,D);
    CHKERRQ(ierr);
    ierr = MatSetOptionsPrefix(D,"D=BtAB_");
    CHKERRQ(ierr);
    ierr = MatView(D,PETSC_VIEWER_STDOUT_WORLD);
    CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_SELF,"\n");
    CHKERRQ(ierr);

    /* Repeat numeric product to test reuse of the previous symbolic product */
    ierr = MatPtAPNumeric(A,B,D);
    CHKERRQ(ierr);
    ierr = MatAXPY(D,none,C,DIFFERENT_NONZERO_PATTERN);
    CHKERRQ(ierr);
    ierr = MatNorm(D,NORM_FROBENIUS,&norm);
    if (norm > 1.e-15) {
        ierr = PetscPrintf(PETSC_COMM_SELF,"Error in symbolic/numeric MatPtAP: %g\n",norm);
    }
    ierr = MatDestroy(&B);
    ierr = MatDestroy(&C);
    ierr = MatDestroy(&D);

    /* A test contributed by Tobias Neckel <*****@*****.**> */
    ierr = testPTAPRectangular();
    CHKERRQ(ierr);

    /* test MatMatTransposeMult(): A*B^T */
    ierr = MatMatTransposeMult(A,A,MAT_INITIAL_MATRIX,fill,&D);
    CHKERRQ(ierr); /* D = A*A^T */
    ierr = MatSetOptionsPrefix(D,"D=A*A^T_");
    CHKERRQ(ierr);
    ierr = MatView(D,PETSC_VIEWER_STDOUT_WORLD);
    CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_SELF,"\n");
    CHKERRQ(ierr);

    ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&B);
    CHKERRQ(ierr); /* B = A^T */
    ierr = MatMatMult(A,B,MAT_INITIAL_MATRIX,fill,&C);
    CHKERRQ(ierr); /* C=A*B */
    ierr = MatSetOptionsPrefix(C,"D=A*B=A*A^T_");
    CHKERRQ(ierr);
    ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD);
    CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_SELF,"\n");
    CHKERRQ(ierr);

    ierr = MatDestroy(&A);
    ierr = MatDestroy(&B);
    ierr = MatDestroy(&C);
    ierr = MatDestroy(&D);
    PetscFinalize();
    return(0);
}
Пример #5
0
int main(int argc,char **args)
{
  Mat            A,B,Y;                 /*input : the three imput matrix */
  Mat            P;                     /* P=QR factorization*/
  PetscViewer    fd1,fd2;
  char           file[4][PETSC_MAX_PATH_LEN];
  //Mat            C;                     /*C=B*Y*/
  PetscInt       m,n;                   /*size of matrix C;*/
  Mat            E,X;                 /*lhs and rhs of the linear equations;*/
  Vec            b,x;                   /*column vector of rhs;*/
  KSP            ksp;                   /* linear solver context */
  PetscErrorCode ierr;
  PetscInt       i,its;                 /*iteration numbers of KSP*/
  PetscBool      flg;

  m=10;
  n=4;

  PetscInitialize(&argc,&args,(char*)0,help);
  ierr = PetscOptionsGetString(NULL,"-fa",file[0],PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
  if(!flg){SETERRQ(PETSC_COMM_WORLD,1,"Please provide matrix A!\n");}
  ierr = PetscOptionsGetString(NULL,"-fb",file[1],PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
  if(!flg){SETERRQ(PETSC_COMM_WORLD,1,"Please provide matrix B!\n");}
  ierr = PetscOptionsGetString(NULL,"-fy",file[2],PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
  if(!flg){SETERRQ(PETSC_COMM_WORLD,1,"Please provide matrix Y!\n");}
  ierr = PetscOptionsGetString(NULL,"-fp",file[3],PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
  if(!flg){SETERRQ(PETSC_COMM_WORLD,1,"Please provide matrix P!\n");}


  /*Load the matrices*/
  ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[0],FILE_MODE_READ,&fd1);
  ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr);
  ierr = MatSetFromOptions(A);CHKERRQ(ierr);
  ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[1],FILE_MODE_READ,&fd2);
  ierr = MatCreate(PETSC_COMM_WORLD,&B);CHKERRQ(ierr);
  ierr = MatSetFromOptions(B);CHKERRQ(ierr);

  ierr = MatLoad(A,fd1);CHKERRQ(ierr);
  ierr = MatLoad(B,fd2);CHKERRQ(ierr);
  readmm(file[2], &Y);
  readmm(file[3], &P);
  ierr = PetscPrintf(PETSC_COMM_SELF,"Read file completes.\n");CHKERRQ(ierr);
#if(cxDEBUG==1)
  ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 
  ierr = MatView(B,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 
#endif

  Mat Q1;
  ierr = MatCreate(PETSC_COMM_WORLD, &Q1); CHKERRQ(ierr);
  ierr = MatSetFromOptions(Q1); CHKERRQ(ierr);
  ierr = MatMatMult(B,Y,MAT_INITIAL_MATRIX,PETSC_DEFAULT, &Q1);CHKERRQ(ierr); 
#if(cxDEBUG==1)
  ierr = PetscPrintf(PETSC_COMM_SELF,"Cao this is BY.\n");CHKERRQ(ierr);
  ierr = MatView(Q1,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
#endif

  getQ1(&Q1);
 
#if(cxDEBUG==1)
  ierr = PetscPrintf(PETSC_COMM_SELF,"\nTHIS IS Q1.\n");CHKERRQ(ierr);
  ierr = MatView(Q1,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
#endif
  
  Mat SBP;
  ierr = MatMatTransposeMult(Q1,Q1,MAT_INITIAL_MATRIX,  PETSC_DEFAULT ,&SBP);
  ierr = MatAssemblyBegin(SBP,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(SBP,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatShift(SBP,-1);
  ierr = MatScale(SBP,-1);
  
#if(cxDEBUG==1)  
  ierr = PetscPrintf(PETSC_COMM_SELF,"\nTHIS IS SBP = Q1*Q1'.\n");CHKERRQ(ierr);
  ierr = MatView(SBP,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_SELF,"\nBelows is act_P.\n");CHKERRQ(ierr);
  ierr = MatView(P  ,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
#endif

  ierr = MatMatMult(A,Y,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&E);CHKERRQ(ierr);
  ierr = MatMatMult(SBP,E,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&E);CHKERRQ(ierr);
  
#if(cxDEBUG==1)
  ierr = PetscPrintf(PETSC_COMM_SELF,"\nBelows is PAY.\n");CHKERRQ(ierr);
  ierr = MatView(E,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
#endif
  ierr = MatAssemblyBegin(E,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(E,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);


  //ierr = MatGetSize(E,&m,&n);CHKERRQ(ierr);
  ierr = MatCreate(PETSC_COMM_WORLD,&X);CHKERRQ(ierr);
  ierr = MatSetSizes(X,PETSC_DECIDE,PETSC_DECIDE,m,n);CHKERRQ(ierr);
  ierr = MatSetFromOptions(X);CHKERRQ(ierr);
  ierr = MatSetUp(X); CHKERRQ(ierr);
  ierr = MatZeroEntries(X);CHKERRQ(ierr);

  ierr = MatAssemblyBegin(X,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(X,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);

 // PetscInt ix[m];
 // for(i=0;i<m;i++){
 //   ix[i] = i;
 // }
  
  VecCreate(PETSC_COMM_WORLD,&b);
  VecSetSizes(b,PETSC_DECIDE,m);
  VecSetFromOptions(b);
  
  VecCreate(PETSC_COMM_WORLD,&x);
  VecSetSizes(x,PETSC_DECIDE,m);
  VecSetFromOptions(x);

//#if(cxDEBUG==1)
  ierr = PetscPrintf(PETSC_COMM_SELF,"\nBEFORE CG Check A\n");CHKERRQ(ierr);
  ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_SELF,"\nBEFORE CG Check SBP\n");CHKERRQ(ierr);
  ierr = MatView(SBP,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_SELF,"\nBEFORE CG Check E\n");CHKERRQ(ierr);
  ierr = MatView(E,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
//#endif
  
  for(i=0;i<n;i++){
    MatGetColumnVector(E,b,i);
    PetscPrintf(PETSC_COMM_WORLD,"the rhs\n");
    VecView(b,PETSC_VIEWER_STDOUT_WORLD);
    KSPCreate(PETSC_COMM_WORLD,&ksp);
    KSPSetOperators(ksp,A,SBP);
    KSPSetNormType(ksp,KSP_NORM_UNPRECONDITIONED);
    KSPSetCheckNormIteration(ksp,-1);
    KSPSetTolerances(ksp,1.0e-06,PETSC_DEFAULT,PETSC_DEFAULT,400);
    KSPSetInitialGuessNonzero(ksp,PETSC_FALSE);
    KSPSetFromOptions(ksp);
    KSPSolve(ksp,b,x);
    KSPGetIterationNumber(ksp,&its);
    PetscPrintf(PETSC_COMM_WORLD,"%d-th equation,iteration=%D\n",i,its);
    VecView(x,PETSC_VIEWER_STDOUT_WORLD);
  }
  return 0;
  
}
Пример #6
0
int main(int argc,char **argv)
{
  Mat                  A,R,C,C_dense,C_sparse,Rt_dense,P,PtAP;
  PetscInt             row,col,m,n;
  PetscErrorCode       ierr;
  MatScalar            one         =1.0,val;
  MatColoring          mc;
  MatTransposeColoring matcoloring = 0;
  ISColoring           iscoloring;
  PetscBool            equal;
  PetscMPIInt          size;

  ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr;
  ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
  if (size != 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"This is a uniprocessor example only!");

  /* Create seqaij A */
  ierr = MatCreate(PETSC_COMM_SELF,&A);CHKERRQ(ierr);
  ierr = MatSetSizes(A,4,4,4,4);CHKERRQ(ierr);
  ierr = MatSetType(A,MATSEQAIJ);CHKERRQ(ierr);
  ierr = MatSetFromOptions(A);CHKERRQ(ierr);
  ierr = MatSetUp(A);CHKERRQ(ierr);
  row  = 0; col=0; val=1.0; ierr = MatSetValues(A,1,&row,1,&col,&val,ADD_VALUES);CHKERRQ(ierr);
  row  = 1; col=3; val=2.0; ierr = MatSetValues(A,1,&row,1,&col,&val,ADD_VALUES);CHKERRQ(ierr);
  row  = 2; col=2; val=3.0; ierr = MatSetValues(A,1,&row,1,&col,&val,ADD_VALUES);CHKERRQ(ierr);
  row  = 3; col=0; val=4.0; ierr = MatSetValues(A,1,&row,1,&col,&val,ADD_VALUES);CHKERRQ(ierr);
  ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatSetOptionsPrefix(A,"A_");CHKERRQ(ierr);
  ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_SELF,"\n");CHKERRQ(ierr);

  /* Create seqaij R */
  ierr = MatCreate(PETSC_COMM_SELF,&R);CHKERRQ(ierr);
  ierr = MatSetSizes(R,2,4,2,4);CHKERRQ(ierr);
  ierr = MatSetType(R,MATSEQAIJ);CHKERRQ(ierr);
  ierr = MatSetFromOptions(R);CHKERRQ(ierr);
  ierr = MatSetUp(R);CHKERRQ(ierr);
  row  = 0; col=0; ierr = MatSetValues(R,1,&row,1,&col,&one,ADD_VALUES);CHKERRQ(ierr);
  row  = 0; col=1; ierr = MatSetValues(R,1,&row,1,&col,&one,ADD_VALUES);CHKERRQ(ierr);

  row  = 1; col=1; ierr = MatSetValues(R,1,&row,1,&col,&one,ADD_VALUES);CHKERRQ(ierr);
  row  = 1; col=2; ierr = MatSetValues(R,1,&row,1,&col,&one,ADD_VALUES);CHKERRQ(ierr);
  row  = 1; col=3; ierr = MatSetValues(R,1,&row,1,&col,&one,ADD_VALUES);CHKERRQ(ierr);
  ierr = MatAssemblyBegin(R,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(R,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatSetOptionsPrefix(R,"R_");CHKERRQ(ierr);
  ierr = MatView(R,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_SELF,"\n");CHKERRQ(ierr);

  /* C = A*R^T */
  ierr = MatMatTransposeMult(A,R,MAT_INITIAL_MATRIX,2.0,&C);CHKERRQ(ierr);
  ierr = MatSetOptionsPrefix(C,"ARt_");CHKERRQ(ierr);
  ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_SELF,"\n");CHKERRQ(ierr);

  /* Create MatTransposeColoring from symbolic C=A*R^T */
  ierr = MatColoringCreate(C,&mc);CHKERRQ(ierr);
  ierr = MatColoringSetDistance(mc,2);CHKERRQ(ierr);
  /* ierr = MatColoringSetType(mc,MATCOLORINGSL);CHKERRQ(ierr); */
  ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr);
  ierr = MatColoringApply(mc,&iscoloring);CHKERRQ(ierr);
  ierr = MatColoringDestroy(&mc);CHKERRQ(ierr);
  ierr = MatTransposeColoringCreate(C,iscoloring,&matcoloring);CHKERRQ(ierr);
  ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);

  /* Create Rt_dense */
  ierr = MatCreate(PETSC_COMM_WORLD,&Rt_dense);CHKERRQ(ierr);
  ierr = MatSetSizes(Rt_dense,4,matcoloring->ncolors,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr);
  ierr = MatSetType(Rt_dense,MATDENSE);CHKERRQ(ierr);
  ierr = MatSeqDenseSetPreallocation(Rt_dense,NULL);CHKERRQ(ierr);
  ierr = MatAssemblyBegin(Rt_dense,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(Rt_dense,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatGetLocalSize(Rt_dense,&m,&n);CHKERRQ(ierr);
  printf("Rt_dense: %d,%d\n",(int)m,(int)n);

  /* Get Rt_dense by Apply MatTransposeColoring to R */
  ierr = MatTransColoringApplySpToDen(matcoloring,R,Rt_dense);CHKERRQ(ierr);

  /* C_dense = A*Rt_dense */
  ierr = MatMatMult(A,Rt_dense,MAT_INITIAL_MATRIX,2.0,&C_dense);CHKERRQ(ierr);
  ierr = MatSetOptionsPrefix(C_dense,"ARt_dense_");CHKERRQ(ierr);
  /*ierr = MatView(C_dense,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); */
  /*ierr = PetscPrintf(PETSC_COMM_SELF,"\n");CHKERRQ(ierr); */

  /* Recover C from C_dense */
  ierr = MatDuplicate(C,MAT_DO_NOT_COPY_VALUES,&C_sparse);CHKERRQ(ierr);
  ierr = MatTransColoringApplyDenToSp(matcoloring,C_dense,C_sparse);CHKERRQ(ierr);
  ierr = MatSetOptionsPrefix(C_sparse,"ARt_color_");CHKERRQ(ierr);
  ierr = MatView(C_sparse,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_SELF,"\n");CHKERRQ(ierr);

  ierr = MatDestroy(&C_dense);CHKERRQ(ierr);
  ierr = MatDestroy(&C_sparse);CHKERRQ(ierr);
  ierr = MatDestroy(&Rt_dense);CHKERRQ(ierr);
  ierr = MatTransposeColoringDestroy(&matcoloring);CHKERRQ(ierr);
  ierr = MatDestroy(&C);CHKERRQ(ierr);

  /* Test PtAP = P^T*A*P, P = R^T */
  ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&P);CHKERRQ(ierr);
  ierr = MatPtAP(A,P,MAT_INITIAL_MATRIX,2.0,&PtAP);CHKERRQ(ierr);
  ierr = MatSetOptionsPrefix(PtAP,"PtAP_");CHKERRQ(ierr);
  ierr = MatView(PtAP,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
  ierr = MatDestroy(&P);CHKERRQ(ierr);

  /* Test C = RARt */
  ierr = MatRARt(A,R,MAT_INITIAL_MATRIX,2.0,&C);CHKERRQ(ierr);
  ierr = MatRARt(A,R,MAT_REUSE_MATRIX,2.0,&C);CHKERRQ(ierr);
  ierr = MatEqual(C,PtAP,&equal);CHKERRQ(ierr);
  if (!equal) {
    ierr = PetscPrintf(PETSC_COMM_SELF,"Error: PtAP != RARt");CHKERRQ(ierr);
  }

  /* Free spaces */
  ierr = MatDestroy(&C);CHKERRQ(ierr);
  ierr = MatDestroy(&A);CHKERRQ(ierr);
  ierr = MatDestroy(&R);CHKERRQ(ierr);
  ierr = MatDestroy(&PtAP);CHKERRQ(ierr);
  ierr = PetscFinalize();
  return ierr;
}
Пример #7
0
Файл: ex39.c Проект: petsc/petsc
int main(int argc,char **args)
{
    Mat            Cdense,B,C,Ct;
    Vec            d;
    PetscInt       i,j,m = 5,n,nrows,ncols;
    const PetscInt *rows,*cols;
    IS             isrows,iscols;
    PetscErrorCode ierr;
    PetscScalar    *v;
    PetscMPIInt    rank,size;
    PetscReal      Cnorm;
    PetscBool      flg,mats_view=PETSC_FALSE;

    ierr = PetscInitialize(&argc,&args,(char*)0,help);
    if (ierr) return ierr;
    ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
    CHKERRQ(ierr);
    ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);
    CHKERRQ(ierr);
    ierr = PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL);
    CHKERRQ(ierr);
    n    = m;
    ierr = PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);
    CHKERRQ(ierr);
    ierr = PetscOptionsHasName(NULL,NULL,"-mats_view",&mats_view);
    CHKERRQ(ierr);

    ierr = MatCreate(PETSC_COMM_WORLD,&C);
    CHKERRQ(ierr);
    ierr = MatSetSizes(C,m,n,PETSC_DECIDE,PETSC_DECIDE);
    CHKERRQ(ierr);
    ierr = MatSetType(C,MATELEMENTAL);
    CHKERRQ(ierr);
    ierr = MatSetFromOptions(C);
    CHKERRQ(ierr);
    ierr = MatSetUp(C);
    CHKERRQ(ierr);
    ierr = MatGetOwnershipIS(C,&isrows,&iscols);
    CHKERRQ(ierr);
    ierr = ISGetLocalSize(isrows,&nrows);
    CHKERRQ(ierr);
    ierr = ISGetIndices(isrows,&rows);
    CHKERRQ(ierr);
    ierr = ISGetLocalSize(iscols,&ncols);
    CHKERRQ(ierr);
    ierr = ISGetIndices(iscols,&cols);
    CHKERRQ(ierr);
    ierr = PetscMalloc1(nrows*ncols,&v);
    CHKERRQ(ierr);
#if defined(PETSC_USE_COMPLEX)
    PetscRandom rand;
    PetscScalar rval;
    ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rand);
    CHKERRQ(ierr);
    ierr = PetscRandomSetFromOptions(rand);
    CHKERRQ(ierr);
    for (i=0; i<nrows; i++) {
        for (j=0; j<ncols; j++) {
            ierr         = PetscRandomGetValue(rand,&rval);
            CHKERRQ(ierr);
            v[i*ncols+j] = rval;
        }
    }
    ierr = PetscRandomDestroy(&rand);
    CHKERRQ(ierr);
#else
    for (i=0; i<nrows; i++) {
        for (j=0; j<ncols; j++) {
            v[i*ncols+j] = (PetscReal)(10000*rank+100*rows[i]+cols[j]);
        }
    }
#endif
    ierr = MatSetValues(C,nrows,rows,ncols,cols,v,INSERT_VALUES);
    CHKERRQ(ierr);
    ierr = ISRestoreIndices(isrows,&rows);
    CHKERRQ(ierr);
    ierr = ISRestoreIndices(iscols,&cols);
    CHKERRQ(ierr);
    ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);
    CHKERRQ(ierr);
    ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);
    CHKERRQ(ierr);
    ierr = ISDestroy(&isrows);
    CHKERRQ(ierr);
    ierr = ISDestroy(&iscols);
    CHKERRQ(ierr);

    /* Test MatView(), MatDuplicate() and out-of-place MatConvert() */
    ierr = MatDuplicate(C,MAT_COPY_VALUES,&B);
    CHKERRQ(ierr);
    if (mats_view) {
        ierr = PetscPrintf(PETSC_COMM_WORLD,"Duplicated C:\n");
        CHKERRQ(ierr);
        ierr = MatView(B,PETSC_VIEWER_STDOUT_WORLD);
        CHKERRQ(ierr);
    }
    ierr = MatDestroy(&B);
    CHKERRQ(ierr);
    ierr = MatConvert(C,MATMPIDENSE,MAT_INITIAL_MATRIX,&Cdense);
    CHKERRQ(ierr);
    ierr = MatMultEqual(C,Cdense,5,&flg);
    CHKERRQ(ierr);
    if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMETYPE,"Cdense != C. MatConvert() fails");

    /* Test MatNorm() */
    ierr = MatNorm(C,NORM_1,&Cnorm);
    CHKERRQ(ierr);

    /* Test MatTranspose(), MatZeroEntries() and MatGetDiagonal() */
    ierr = MatTranspose(C,MAT_INITIAL_MATRIX,&Ct);
    CHKERRQ(ierr);
    ierr = MatConjugate(Ct);
    CHKERRQ(ierr);
    if (mats_view) {
        ierr = PetscPrintf(PETSC_COMM_WORLD,"C's Transpose Conjugate:\n");
        CHKERRQ(ierr);
        ierr = MatView(Ct,PETSC_VIEWER_STDOUT_WORLD);
        CHKERRQ(ierr);
    }
    ierr = MatZeroEntries(Ct);
    CHKERRQ(ierr);
    ierr = VecCreate(PETSC_COMM_WORLD,&d);
    CHKERRQ(ierr);
    ierr = VecSetSizes(d,m>n ? n : m,PETSC_DECIDE);
    CHKERRQ(ierr);
    ierr = VecSetFromOptions(d);
    CHKERRQ(ierr);
    ierr = MatGetDiagonal(C,d);
    CHKERRQ(ierr);
    if (mats_view) {
        ierr = PetscPrintf(PETSC_COMM_WORLD,"Diagonal of C:\n");
        CHKERRQ(ierr);
        ierr = VecView(d,PETSC_VIEWER_STDOUT_WORLD);
        CHKERRQ(ierr);
    }
    if (m>n) {
        ierr = MatDiagonalScale(C,NULL,d);
        CHKERRQ(ierr);
    } else {
        ierr = MatDiagonalScale(C,d,NULL);
        CHKERRQ(ierr);
    }
    if (mats_view) {
        ierr = PetscPrintf(PETSC_COMM_WORLD,"Diagonal Scaled C:\n");
        CHKERRQ(ierr);
        ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD);
        CHKERRQ(ierr);
    }

    /* Test MatAXPY(), MatAYPX() and in-place MatConvert() */
    ierr = MatCreate(PETSC_COMM_WORLD,&B);
    CHKERRQ(ierr);
    ierr = MatSetSizes(B,m,n,PETSC_DECIDE,PETSC_DECIDE);
    CHKERRQ(ierr);
    ierr = MatSetType(B,MATELEMENTAL);
    CHKERRQ(ierr);
    ierr = MatSetFromOptions(B);
    CHKERRQ(ierr);
    ierr = MatSetUp(B);
    CHKERRQ(ierr);
    ierr = MatGetOwnershipIS(B,&isrows,&iscols);
    CHKERRQ(ierr);
    ierr = ISGetLocalSize(isrows,&nrows);
    CHKERRQ(ierr);
    ierr = ISGetIndices(isrows,&rows);
    CHKERRQ(ierr);
    ierr = ISGetLocalSize(iscols,&ncols);
    CHKERRQ(ierr);
    ierr = ISGetIndices(iscols,&cols);
    CHKERRQ(ierr);
    for (i=0; i<nrows; i++) {
        for (j=0; j<ncols; j++) {
            v[i*ncols+j] = (PetscReal)(1000*rows[i]+cols[j]);
        }
    }
    ierr = MatSetValues(B,nrows,rows,ncols,cols,v,INSERT_VALUES);
    CHKERRQ(ierr);
    ierr = PetscFree(v);
    CHKERRQ(ierr);
    ierr = ISRestoreIndices(isrows,&rows);
    CHKERRQ(ierr);
    ierr = ISRestoreIndices(iscols,&cols);
    CHKERRQ(ierr);
    ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
    CHKERRQ(ierr);
    ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
    CHKERRQ(ierr);
    ierr = MatAXPY(B,2.5,C,SAME_NONZERO_PATTERN);
    CHKERRQ(ierr);
    ierr = MatAYPX(B,3.75,C,SAME_NONZERO_PATTERN);
    CHKERRQ(ierr);
    ierr = MatConvert(B,MATDENSE,MAT_INPLACE_MATRIX,&B);
    CHKERRQ(ierr);
    if (mats_view) {
        ierr = PetscPrintf(PETSC_COMM_WORLD,"B after MatAXPY and MatAYPX:\n");
        CHKERRQ(ierr);
        ierr = MatView(B,PETSC_VIEWER_STDOUT_WORLD);
        CHKERRQ(ierr);
    }
    ierr = ISDestroy(&isrows);
    CHKERRQ(ierr);
    ierr = ISDestroy(&iscols);
    CHKERRQ(ierr);
    ierr = MatDestroy(&B);
    CHKERRQ(ierr);

    /* Test MatMatTransposeMult(): B = C*C^T */
    ierr = MatMatTransposeMult(C,C,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B);
    CHKERRQ(ierr);
    if (mats_view) {
        ierr = PetscPrintf(PETSC_COMM_WORLD,"C MatMatTransposeMult C:\n");
        CHKERRQ(ierr);
        ierr = MatView(B,PETSC_VIEWER_STDOUT_WORLD);
        CHKERRQ(ierr);
    }

    ierr = MatDestroy(&Cdense);
    CHKERRQ(ierr);
    ierr = PetscFree(v);
    CHKERRQ(ierr);
    ierr = MatDestroy(&B);
    CHKERRQ(ierr);
    ierr = MatDestroy(&C);
    CHKERRQ(ierr);
    ierr = MatDestroy(&Ct);
    CHKERRQ(ierr);
    ierr = VecDestroy(&d);
    CHKERRQ(ierr);
    ierr = PetscFinalize();
    return ierr;
}