static PetscErrorCode PCSetUp_LU(PC pc) { PetscErrorCode ierr; PC_LU *dir = (PC_LU*)pc->data; PetscFunctionBegin; if (dir->reusefill && pc->setupcalled) ((PC_Factor*)dir)->info.fill = dir->actualfill; if (dir->inplace) { if (dir->row && dir->col && dir->row != dir->col) {ierr = ISDestroy(dir->row);CHKERRQ(ierr);} if (dir->col) {ierr = ISDestroy(dir->col);CHKERRQ(ierr);} ierr = MatGetOrdering(pc->pmat,((PC_Factor*)dir)->ordering,&dir->row,&dir->col);CHKERRQ(ierr); if (dir->row) { ierr = PetscLogObjectParent(pc,dir->row);CHKERRQ(ierr); ierr = PetscLogObjectParent(pc,dir->col);CHKERRQ(ierr); } ierr = MatLUFactor(pc->pmat,dir->row,dir->col,&((PC_Factor*)dir)->info);CHKERRQ(ierr); ((PC_Factor*)dir)->fact = pc->pmat; } else { MatInfo info; if (!pc->setupcalled) { ierr = MatGetOrdering(pc->pmat,((PC_Factor*)dir)->ordering,&dir->row,&dir->col);CHKERRQ(ierr); if (dir->nonzerosalongdiagonal) { ierr = MatReorderForNonzeroDiagonal(pc->pmat,dir->nonzerosalongdiagonaltol,dir->row,dir->col);CHKERRQ(ierr); } if (dir->row) { ierr = PetscLogObjectParent(pc,dir->row);CHKERRQ(ierr); ierr = PetscLogObjectParent(pc,dir->col);CHKERRQ(ierr); } ierr = MatGetFactor(pc->pmat,((PC_Factor*)dir)->solvertype,MAT_FACTOR_LU,&((PC_Factor*)dir)->fact);CHKERRQ(ierr); ierr = MatLUFactorSymbolic(((PC_Factor*)dir)->fact,pc->pmat,dir->row,dir->col,&((PC_Factor*)dir)->info);CHKERRQ(ierr); ierr = MatGetInfo(((PC_Factor*)dir)->fact,MAT_LOCAL,&info);CHKERRQ(ierr); dir->actualfill = info.fill_ratio_needed; ierr = PetscLogObjectParent(pc,((PC_Factor*)dir)->fact);CHKERRQ(ierr); } else if (pc->flag != SAME_NONZERO_PATTERN) { if (!dir->reuseordering) { if (dir->row && dir->col && dir->row != dir->col) {ierr = ISDestroy(dir->row);CHKERRQ(ierr);} if (dir->col) {ierr = ISDestroy(dir->col);CHKERRQ(ierr);} ierr = MatGetOrdering(pc->pmat,((PC_Factor*)dir)->ordering,&dir->row,&dir->col);CHKERRQ(ierr); if (dir->nonzerosalongdiagonal) { ierr = MatReorderForNonzeroDiagonal(pc->pmat,dir->nonzerosalongdiagonaltol,dir->row,dir->col);CHKERRQ(ierr); } if (dir->row) { ierr = PetscLogObjectParent(pc,dir->row);CHKERRQ(ierr); ierr = PetscLogObjectParent(pc,dir->col);CHKERRQ(ierr); } } ierr = MatDestroy(((PC_Factor*)dir)->fact);CHKERRQ(ierr); ierr = MatGetFactor(pc->pmat,((PC_Factor*)dir)->solvertype,MAT_FACTOR_LU,&((PC_Factor*)dir)->fact);CHKERRQ(ierr); ierr = MatLUFactorSymbolic(((PC_Factor*)dir)->fact,pc->pmat,dir->row,dir->col,&((PC_Factor*)dir)->info);CHKERRQ(ierr); ierr = MatGetInfo(((PC_Factor*)dir)->fact,MAT_LOCAL,&info);CHKERRQ(ierr); dir->actualfill = info.fill_ratio_needed; ierr = PetscLogObjectParent(pc,((PC_Factor*)dir)->fact);CHKERRQ(ierr); } ierr = MatLUFactorNumeric(((PC_Factor*)dir)->fact,pc->pmat,&((PC_Factor*)dir)->info);CHKERRQ(ierr); } PetscFunctionReturn(0); }
int main(int argc,char **args) { Mat C; PetscInt i,j,m = 3,n = 3,Ii,J; PetscErrorCode ierr; PetscBool flg; PetscScalar v; IS perm,iperm; Vec x,u,b,y; PetscReal norm,tol=PETSC_SMALL; MatFactorInfo info; PetscMPIInt size; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_WORLD,1,"This is a uniprocessor example only!"); ierr = MatCreate(PETSC_COMM_WORLD,&C);CHKERRQ(ierr); ierr = MatSetSizes(C,PETSC_DECIDE,PETSC_DECIDE,m*n,m*n);CHKERRQ(ierr); ierr = MatSetFromOptions(C);CHKERRQ(ierr); ierr = MatSetUp(C);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,NULL,"-symmetric",&flg);CHKERRQ(ierr); if (flg) { /* Treat matrix as symmetric only if we set this flag */ ierr = MatSetOption(C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); ierr = MatSetOption(C,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr); } /* Create the matrix for the five point stencil, YET AGAIN */ for (i=0; i<m; i++) { for (j=0; j<n; j++) { v = -1.0; Ii = j + n*i; if (i>0) {J = Ii - n; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (i<m-1) {J = Ii + n; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (j>0) {J = Ii - 1; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (j<n-1) {J = Ii + 1; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} v = 4.0; ierr = MatSetValues(C,1,&Ii,1,&Ii,&v,INSERT_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatGetOrdering(C,MATORDERINGRCM,&perm,&iperm);CHKERRQ(ierr); ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = ISView(perm,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,m*n,&u);CHKERRQ(ierr); ierr = VecSet(u,1.0);CHKERRQ(ierr); ierr = VecDuplicate(u,&x);CHKERRQ(ierr); ierr = VecDuplicate(u,&b);CHKERRQ(ierr); ierr = VecDuplicate(u,&y);CHKERRQ(ierr); ierr = MatMult(C,u,b);CHKERRQ(ierr); ierr = VecCopy(b,y);CHKERRQ(ierr); ierr = VecScale(y,2.0);CHKERRQ(ierr); ierr = MatNorm(C,NORM_FROBENIUS,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"Frobenius norm of matrix %g\n",(double)norm);CHKERRQ(ierr); ierr = MatNorm(C,NORM_1,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"One norm of matrix %g\n",(double)norm);CHKERRQ(ierr); ierr = MatNorm(C,NORM_INFINITY,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"Infinity norm of matrix %g\n",(double)norm);CHKERRQ(ierr); ierr = MatFactorInfoInitialize(&info);CHKERRQ(ierr); info.fill = 2.0; info.dtcol = 0.0; info.zeropivot = 1.e-14; info.pivotinblocks = 1.0; ierr = MatLUFactor(C,perm,iperm,&info);CHKERRQ(ierr); /* Test MatSolve */ ierr = MatSolve(C,b,x);CHKERRQ(ierr); ierr = VecView(b,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = VecView(x,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = VecAXPY(x,-1.0,u);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"MatSolve: Norm of error %g\n",(double)norm);CHKERRQ(ierr); } /* Test MatSolveAdd */ ierr = MatSolveAdd(C,b,y,x);CHKERRQ(ierr); ierr = VecAXPY(x,-1.0,y);CHKERRQ(ierr); ierr = VecAXPY(x,-1.0,u);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"MatSolveAdd(): Norm of error %g\n",(double)norm);CHKERRQ(ierr); } ierr = ISDestroy(&perm);CHKERRQ(ierr); ierr = ISDestroy(&iperm);CHKERRQ(ierr); ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&y);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
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); }
PetscErrorCode PCBDDCNullSpaceAssembleCorrection(PC pc, PetscBool isdir, IS local_dofs) { PC_BDDC *pcbddc = (PC_BDDC*)pc->data; PC_IS *pcis = (PC_IS*)pc->data; Mat_IS* matis = (Mat_IS*)pc->pmat->data; KSP local_ksp; PC newpc; NullSpaceCorrection_ctx shell_ctx; Mat local_mat,local_pmat,small_mat,inv_small_mat; Vec work1,work2; const Vec *nullvecs; VecScatter scatter_ctx; IS is_aux; MatFactorInfo matinfo; PetscScalar *basis_mat,*Kbasis_mat,*array,*array_mat; PetscScalar one = 1.0,zero = 0.0, m_one = -1.0; PetscInt basis_dofs,basis_size,nnsp_size,i,k; PetscBool nnsp_has_cnst; PetscErrorCode ierr; PetscFunctionBegin; /* Infer the local solver */ ierr = ISGetSize(local_dofs,&basis_dofs);CHKERRQ(ierr); if (isdir) { /* Dirichlet solver */ local_ksp = pcbddc->ksp_D; } else { /* Neumann solver */ local_ksp = pcbddc->ksp_R; } ierr = KSPGetOperators(local_ksp,&local_mat,&local_pmat);CHKERRQ(ierr); /* Get null space vecs */ ierr = MatNullSpaceGetVecs(pcbddc->NullSpace,&nnsp_has_cnst,&nnsp_size,&nullvecs);CHKERRQ(ierr); basis_size = nnsp_size; if (nnsp_has_cnst) { basis_size++; } if (basis_dofs) { /* Create shell ctx */ ierr = PetscNew(&shell_ctx);CHKERRQ(ierr); /* Create work vectors in shell context */ ierr = VecCreate(PETSC_COMM_SELF,&shell_ctx->work_small_1);CHKERRQ(ierr); ierr = VecSetSizes(shell_ctx->work_small_1,basis_size,basis_size);CHKERRQ(ierr); ierr = VecSetType(shell_ctx->work_small_1,VECSEQ);CHKERRQ(ierr); ierr = VecDuplicate(shell_ctx->work_small_1,&shell_ctx->work_small_2);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_SELF,&shell_ctx->work_full_1);CHKERRQ(ierr); ierr = VecSetSizes(shell_ctx->work_full_1,basis_dofs,basis_dofs);CHKERRQ(ierr); ierr = VecSetType(shell_ctx->work_full_1,VECSEQ);CHKERRQ(ierr); ierr = VecDuplicate(shell_ctx->work_full_1,&shell_ctx->work_full_2);CHKERRQ(ierr); /* Allocate workspace */ ierr = MatCreateSeqDense(PETSC_COMM_SELF,basis_dofs,basis_size,NULL,&shell_ctx->basis_mat );CHKERRQ(ierr); ierr = MatCreateSeqDense(PETSC_COMM_SELF,basis_dofs,basis_size,NULL,&shell_ctx->Kbasis_mat);CHKERRQ(ierr); ierr = MatDenseGetArray(shell_ctx->basis_mat,&basis_mat);CHKERRQ(ierr); ierr = MatDenseGetArray(shell_ctx->Kbasis_mat,&Kbasis_mat);CHKERRQ(ierr); /* Restrict local null space on selected dofs (Dirichlet or Neumann) and compute matrices N and K*N */ ierr = VecDuplicate(shell_ctx->work_full_1,&work1);CHKERRQ(ierr); ierr = VecDuplicate(shell_ctx->work_full_1,&work2);CHKERRQ(ierr); ierr = VecScatterCreate(pcis->vec1_N,local_dofs,work1,(IS)0,&scatter_ctx);CHKERRQ(ierr); } for (k=0;k<nnsp_size;k++) { ierr = VecScatterBegin(matis->rctx,nullvecs[k],pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(matis->rctx,nullvecs[k],pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); if (basis_dofs) { ierr = VecPlaceArray(work1,(const PetscScalar*)&basis_mat[k*basis_dofs]);CHKERRQ(ierr); ierr = VecScatterBegin(scatter_ctx,pcis->vec1_N,work1,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(scatter_ctx,pcis->vec1_N,work1,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecPlaceArray(work2,(const PetscScalar*)&Kbasis_mat[k*basis_dofs]);CHKERRQ(ierr); ierr = MatMult(local_mat,work1,work2);CHKERRQ(ierr); ierr = VecResetArray(work1);CHKERRQ(ierr); ierr = VecResetArray(work2);CHKERRQ(ierr); } } if (basis_dofs) { if (nnsp_has_cnst) { ierr = VecPlaceArray(work1,(const PetscScalar*)&basis_mat[k*basis_dofs]);CHKERRQ(ierr); ierr = VecSet(work1,one);CHKERRQ(ierr); ierr = VecPlaceArray(work2,(const PetscScalar*)&Kbasis_mat[k*basis_dofs]);CHKERRQ(ierr); ierr = MatMult(local_mat,work1,work2);CHKERRQ(ierr); ierr = VecResetArray(work1);CHKERRQ(ierr); ierr = VecResetArray(work2);CHKERRQ(ierr); } ierr = VecDestroy(&work1);CHKERRQ(ierr); ierr = VecDestroy(&work2);CHKERRQ(ierr); ierr = VecScatterDestroy(&scatter_ctx);CHKERRQ(ierr); ierr = MatDenseRestoreArray(shell_ctx->basis_mat,&basis_mat);CHKERRQ(ierr); ierr = MatDenseRestoreArray(shell_ctx->Kbasis_mat,&Kbasis_mat);CHKERRQ(ierr); /* Assemble another Mat object in shell context */ ierr = MatTransposeMatMult(shell_ctx->basis_mat,shell_ctx->Kbasis_mat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&small_mat);CHKERRQ(ierr); ierr = MatFactorInfoInitialize(&matinfo);CHKERRQ(ierr); ierr = ISCreateStride(PETSC_COMM_SELF,basis_size,0,1,&is_aux);CHKERRQ(ierr); ierr = MatLUFactor(small_mat,is_aux,is_aux,&matinfo);CHKERRQ(ierr); ierr = ISDestroy(&is_aux);CHKERRQ(ierr); ierr = PetscMalloc1(basis_size*basis_size,&array_mat);CHKERRQ(ierr); for (k=0;k<basis_size;k++) { ierr = VecSet(shell_ctx->work_small_1,zero);CHKERRQ(ierr); ierr = VecSetValue(shell_ctx->work_small_1,k,one,INSERT_VALUES);CHKERRQ(ierr); ierr = VecAssemblyBegin(shell_ctx->work_small_1);CHKERRQ(ierr); ierr = VecAssemblyEnd(shell_ctx->work_small_1);CHKERRQ(ierr); ierr = MatSolve(small_mat,shell_ctx->work_small_1,shell_ctx->work_small_2);CHKERRQ(ierr); ierr = VecGetArrayRead(shell_ctx->work_small_2,(const PetscScalar**)&array);CHKERRQ(ierr); for (i=0;i<basis_size;i++) { array_mat[i*basis_size+k]=array[i]; } ierr = VecRestoreArrayRead(shell_ctx->work_small_2,(const PetscScalar**)&array);CHKERRQ(ierr); } ierr = MatCreateSeqDense(PETSC_COMM_SELF,basis_size,basis_size,array_mat,&inv_small_mat);CHKERRQ(ierr); ierr = MatMatMult(shell_ctx->basis_mat,inv_small_mat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&shell_ctx->Lbasis_mat);CHKERRQ(ierr); ierr = PetscFree(array_mat);CHKERRQ(ierr); ierr = MatDestroy(&inv_small_mat);CHKERRQ(ierr); ierr = MatDestroy(&small_mat);CHKERRQ(ierr); ierr = MatScale(shell_ctx->Kbasis_mat,m_one);CHKERRQ(ierr); /* Rebuild local PC */ ierr = KSPGetPC(local_ksp,&shell_ctx->local_pc);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)shell_ctx->local_pc);CHKERRQ(ierr); ierr = PCCreate(PETSC_COMM_SELF,&newpc);CHKERRQ(ierr); ierr = PCSetOperators(newpc,local_mat,local_mat);CHKERRQ(ierr); ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); ierr = PCShellSetContext(newpc,shell_ctx);CHKERRQ(ierr); ierr = PCShellSetApply(newpc,PCBDDCApplyNullSpaceCorrectionPC);CHKERRQ(ierr); ierr = PCShellSetDestroy(newpc,PCBDDCDestroyNullSpaceCorrectionPC);CHKERRQ(ierr); ierr = PCSetUp(newpc);CHKERRQ(ierr); ierr = KSPSetPC(local_ksp,newpc);CHKERRQ(ierr); ierr = PCDestroy(&newpc);CHKERRQ(ierr); ierr = KSPSetUp(local_ksp);CHKERRQ(ierr); } /* test */ if (pcbddc->dbg_flag && basis_dofs) { KSP check_ksp; PC check_pc; Mat test_mat; Vec work3; PetscReal test_err,lambda_min,lambda_max; PetscBool setsym,issym=PETSC_FALSE; PetscInt tabs; ierr = PetscViewerASCIIGetTab(pcbddc->dbg_viewer,&tabs);CHKERRQ(ierr); ierr = KSPGetPC(local_ksp,&check_pc);CHKERRQ(ierr); ierr = VecDuplicate(shell_ctx->work_full_1,&work1);CHKERRQ(ierr); ierr = VecDuplicate(shell_ctx->work_full_1,&work2);CHKERRQ(ierr); ierr = VecDuplicate(shell_ctx->work_full_1,&work3);CHKERRQ(ierr); ierr = VecSetRandom(shell_ctx->work_small_1,NULL);CHKERRQ(ierr); ierr = MatMult(shell_ctx->basis_mat,shell_ctx->work_small_1,work1);CHKERRQ(ierr); ierr = VecCopy(work1,work2);CHKERRQ(ierr); ierr = MatMult(local_mat,work1,work3);CHKERRQ(ierr); ierr = PCApply(check_pc,work3,work1);CHKERRQ(ierr); ierr = VecAXPY(work1,m_one,work2);CHKERRQ(ierr); ierr = VecNorm(work1,NORM_INFINITY,&test_err);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d error for nullspace correction for ",PetscGlobalRank);CHKERRQ(ierr); ierr = PetscViewerASCIIUseTabs(pcbddc->dbg_viewer,PETSC_FALSE);CHKERRQ(ierr); if (isdir) { ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Dirichlet ");CHKERRQ(ierr); } else { ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Neumann ");CHKERRQ(ierr); } ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"solver is :%1.14e\n",test_err);CHKERRQ(ierr); ierr = PetscViewerASCIISetTab(pcbddc->dbg_viewer,tabs);CHKERRQ(ierr); ierr = PetscViewerASCIIUseTabs(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); ierr = MatTransposeMatMult(shell_ctx->Lbasis_mat,shell_ctx->Kbasis_mat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&test_mat);CHKERRQ(ierr); ierr = MatShift(test_mat,one);CHKERRQ(ierr); ierr = MatNorm(test_mat,NORM_INFINITY,&test_err);CHKERRQ(ierr); ierr = MatDestroy(&test_mat);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d error for nullspace matrices is :%1.14e\n",PetscGlobalRank,test_err);CHKERRQ(ierr); /* Create ksp object suitable for extreme eigenvalues' estimation */ ierr = KSPCreate(PETSC_COMM_SELF,&check_ksp);CHKERRQ(ierr); ierr = KSPSetErrorIfNotConverged(check_ksp,pc->erroriffailure);CHKERRQ(ierr); ierr = KSPSetOperators(check_ksp,local_mat,local_mat);CHKERRQ(ierr); ierr = KSPSetTolerances(check_ksp,1.e-8,1.e-8,PETSC_DEFAULT,basis_dofs);CHKERRQ(ierr); ierr = KSPSetComputeSingularValues(check_ksp,PETSC_TRUE);CHKERRQ(ierr); ierr = MatIsSymmetricKnown(pc->pmat,&setsym,&issym);CHKERRQ(ierr); if (issym) { ierr = KSPSetType(check_ksp,KSPCG);CHKERRQ(ierr); } ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); ierr = VecSetRandom(work1,NULL);CHKERRQ(ierr); ierr = MatMult(local_mat,work1,work2);CHKERRQ(ierr); ierr = KSPSolve(check_ksp,work2,work2);CHKERRQ(ierr); ierr = VecAXPY(work2,m_one,work1);CHKERRQ(ierr); ierr = VecNorm(work2,NORM_INFINITY,&test_err);CHKERRQ(ierr); ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max,&lambda_min);CHKERRQ(ierr); ierr = KSPGetIterationNumber(check_ksp,&k);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d error for adapted KSP %1.14e (it %d, eigs %1.6e %1.6e)\n",PetscGlobalRank,test_err,k,lambda_min,lambda_max);CHKERRQ(ierr); ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); ierr = VecDestroy(&work1);CHKERRQ(ierr); ierr = VecDestroy(&work2);CHKERRQ(ierr); ierr = VecDestroy(&work3);CHKERRQ(ierr); } /* all processes shoud call this, even the void ones */ if (pcbddc->dbg_flag) { ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); } PetscFunctionReturn(0); }
int main(int argc,char **argv) { Mat mat,B; PetscErrorCode ierr; PetscInt i,j; PetscScalar v; IS isrow,iscol; PetscViewer viewer; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); /* ------- Assemble matrix, --------- */ ierr = MatCreate(PETSC_COMM_WORLD,&mat);CHKERRQ(ierr); ierr = MatSetSizes(mat,PETSC_DECIDE,PETSC_DECIDE,4,4);CHKERRQ(ierr); ierr = MatSetFromOptions(mat);CHKERRQ(ierr); ierr = MatSetUp(mat);CHKERRQ(ierr); /* set anti-diagonal of matrix */ v = 1.0; i = 0; j = 3; ierr = MatSetValues(mat,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); v = 2.0; i = 1; j = 2; ierr = MatSetValues(mat,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); v = 3.0; i = 2; j = 1; ierr = MatSetValues(mat,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); v = 4.0; i = 3; j = 0; ierr = MatSetValues(mat,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = PetscViewerASCIIGetStdout(PETSC_COMM_WORLD,&viewer);CHKERRQ(ierr); ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_DENSE);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Original matrix\n");CHKERRQ(ierr); ierr = MatView(mat,viewer);CHKERRQ(ierr); ierr = MatGetOrdering(mat,MATORDERINGNATURAL,&isrow,&iscol);CHKERRQ(ierr); ierr = MatPermute(mat,isrow,iscol,&B);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Original matrix permuted by identity\n");CHKERRQ(ierr); ierr = MatView(B,viewer);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = MatReorderForNonzeroDiagonal(mat,1.e-8,isrow,iscol);CHKERRQ(ierr); ierr = MatPermute(mat,isrow,iscol,&B);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Original matrix permuted by identity + NonzeroDiagonal()\n");CHKERRQ(ierr); ierr = MatView(B,viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Row permutation\n");CHKERRQ(ierr); ierr = ISView(isrow,viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Column permutation\n");CHKERRQ(ierr); ierr = ISView(iscol,viewer);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = ISDestroy(&isrow);CHKERRQ(ierr); ierr = ISDestroy(&iscol);CHKERRQ(ierr); ierr = MatGetOrdering(mat,MATORDERINGND,&isrow,&iscol);CHKERRQ(ierr); ierr = MatPermute(mat,isrow,iscol,&B);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Original matrix permuted by ND\n");CHKERRQ(ierr); ierr = MatView(B,viewer);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"ND row permutation\n");CHKERRQ(ierr); ierr = ISView(isrow,viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"ND column permutation\n");CHKERRQ(ierr); ierr = ISView(iscol,viewer);CHKERRQ(ierr); ierr = MatReorderForNonzeroDiagonal(mat,1.e-8,isrow,iscol);CHKERRQ(ierr); ierr = MatPermute(mat,isrow,iscol,&B);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Original matrix permuted by ND + NonzeroDiagonal()\n");CHKERRQ(ierr); ierr = MatView(B,viewer);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"ND + NonzeroDiagonal() row permutation\n");CHKERRQ(ierr); ierr = ISView(isrow,viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"ND + NonzeroDiagonal() column permutation\n");CHKERRQ(ierr); ierr = ISView(iscol,viewer);CHKERRQ(ierr); ierr = ISDestroy(&isrow);CHKERRQ(ierr); ierr = ISDestroy(&iscol);CHKERRQ(ierr); ierr = MatGetOrdering(mat,MATORDERINGRCM,&isrow,&iscol);CHKERRQ(ierr); ierr = MatPermute(mat,isrow,iscol,&B);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Original matrix permuted by RCM\n");CHKERRQ(ierr); ierr = MatView(B,viewer);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"RCM row permutation\n");CHKERRQ(ierr); ierr = ISView(isrow,viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"RCM column permutation\n");CHKERRQ(ierr); ierr = ISView(iscol,viewer);CHKERRQ(ierr); ierr = MatReorderForNonzeroDiagonal(mat,1.e-8,isrow,iscol);CHKERRQ(ierr); ierr = MatPermute(mat,isrow,iscol,&B);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Original matrix permuted by RCM + NonzeroDiagonal()\n");CHKERRQ(ierr); ierr = MatView(B,viewer);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"RCM + NonzeroDiagonal() row permutation\n");CHKERRQ(ierr); ierr = ISView(isrow,viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"RCM + NonzeroDiagonal() column permutation\n");CHKERRQ(ierr); ierr = ISView(iscol,viewer);CHKERRQ(ierr); ierr = MatLUFactor(mat,isrow,iscol,PETSC_NULL);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"Factored matrix permuted by RCM + NonzeroDiagonal()\n");CHKERRQ(ierr); ierr = MatView(mat,viewer);CHKERRQ(ierr); /* Free data structures */ ierr = ISDestroy(&isrow);CHKERRQ(ierr); ierr = ISDestroy(&iscol);CHKERRQ(ierr); ierr = MatDestroy(&mat);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **args) { Mat A,B; Vec xx,s1,s2,yy; PetscErrorCode ierr; PetscInt m=45,rows[2],cols[2],bs=1,i,row,col,*idx,M; PetscScalar rval,vals1[4],vals2[4]; PetscRandom rdm; IS is1,is2; PetscReal s1norm,s2norm,rnorm,tol = 1.e-4; PetscTruth flg; MatFactorInfo info; PetscInitialize(&argc,&args,(char *)0,help); /* Test MatSetValues() and MatGetValues() */ ierr = PetscOptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-mat_size",&m,PETSC_NULL);CHKERRQ(ierr); M = m*bs; ierr = MatCreateSeqBAIJ(PETSC_COMM_SELF,bs,M,M,1,PETSC_NULL,&A);CHKERRQ(ierr); ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,M,M,15,PETSC_NULL,&B);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_SELF,&rdm);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,M,&xx);CHKERRQ(ierr); ierr = VecDuplicate(xx,&s1);CHKERRQ(ierr); ierr = VecDuplicate(xx,&s2);CHKERRQ(ierr); ierr = VecDuplicate(xx,&yy);CHKERRQ(ierr); /* For each row add atleast 15 elements */ for (row=0; row<M; row++) { for (i=0; i<25*bs; i++) { ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); col = (PetscInt)(PetscRealPart(rval)*M); ierr = MatSetValues(A,1,&row,1,&col,&rval,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(B,1,&row,1,&col,&rval,INSERT_VALUES);CHKERRQ(ierr); } } /* Now set blocks of values */ for (i=0; i<20*bs; i++) { ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); cols[0] = (PetscInt)(PetscRealPart(rval)*M); vals1[0] = rval; ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); cols[1] = (PetscInt)(PetscRealPart(rval)*M); vals1[1] = rval; ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); rows[0] = (PetscInt)(PetscRealPart(rval)*M); vals1[2] = rval; ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); rows[1] = (PetscInt)(PetscRealPart(rval)*M); vals1[3] = rval; ierr = MatSetValues(A,2,rows,2,cols,vals1,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(B,2,rows,2,cols,vals1,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Test MatNorm() */ ierr = MatNorm(A,NORM_FROBENIUS,&s1norm);CHKERRQ(ierr); ierr = MatNorm(B,NORM_FROBENIUS,&s2norm);CHKERRQ(ierr); rnorm = PetscAbsScalar(s2norm-s1norm)/s2norm; if ( rnorm>tol ) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatNorm_FROBENIUS()- NormA=%16.14e NormB=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } ierr = MatNorm(A,NORM_INFINITY,&s1norm);CHKERRQ(ierr); ierr = MatNorm(B,NORM_INFINITY,&s2norm);CHKERRQ(ierr); rnorm = PetscAbsScalar(s2norm-s1norm)/s2norm; if ( rnorm>tol ) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatNorm_INFINITY()- NormA=%16.14e NormB=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } ierr = MatNorm(A,NORM_1,&s1norm);CHKERRQ(ierr); ierr = MatNorm(B,NORM_1,&s2norm);CHKERRQ(ierr); rnorm = PetscAbsScalar(s2norm-s1norm)/s2norm; if ( rnorm>tol ) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatNorm_NORM_1()- NormA=%16.14e NormB=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } /* MatShift() */ rval = 10*s1norm; ierr = MatShift(A,rval);CHKERRQ(ierr); ierr = MatShift(B,rval);CHKERRQ(ierr); /* Test MatTranspose() */ ierr = MatTranspose(A,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr); ierr = MatTranspose(B,MAT_REUSE_MATRIX,&B);CHKERRQ(ierr); /* Now do MatGetValues() */ for (i=0; i<30; i++) { ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); cols[0] = (PetscInt)(PetscRealPart(rval)*M); ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); cols[1] = (PetscInt)(PetscRealPart(rval)*M); ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); rows[0] = (PetscInt)(PetscRealPart(rval)*M); ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); rows[1] = (PetscInt)(PetscRealPart(rval)*M); ierr = MatGetValues(A,2,rows,2,cols,vals1);CHKERRQ(ierr); ierr = MatGetValues(B,2,rows,2,cols,vals2);CHKERRQ(ierr); ierr = PetscMemcmp(vals1,vals2,4*sizeof(PetscScalar),&flg);CHKERRQ(ierr); if (!flg) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatGetValues bs = %D\n",bs);CHKERRQ(ierr); } } /* Test MatMult(), MatMultAdd() */ for (i=0; i<40; i++) { ierr = VecSetRandom(xx,rdm);CHKERRQ(ierr); ierr = VecSet(s2,0.0);CHKERRQ(ierr); ierr = MatMult(A,xx,s1);CHKERRQ(ierr); ierr = MatMultAdd(A,xx,s2,s2);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"MatMult not equal to MatMultAdd Norm1=%e Norm2=%e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } } /* Test MatMult() */ ierr = MatMultEqual(A,B,10,&flg);CHKERRQ(ierr); if (!flg){ ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatMult()\n");CHKERRQ(ierr); } /* Test MatMultAdd() */ ierr = MatMultAddEqual(A,B,10,&flg);CHKERRQ(ierr); if (!flg){ ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatMultAdd()\n");CHKERRQ(ierr); } /* Test MatMultTranspose() */ ierr = MatMultTransposeEqual(A,B,10,&flg);CHKERRQ(ierr); if (!flg){ ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatMultTranspose()\n");CHKERRQ(ierr); } /* Test MatMultTransposeAdd() */ ierr = MatMultTransposeAddEqual(A,B,10,&flg);CHKERRQ(ierr); if (!flg){ ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatMultTransposeAdd()\n");CHKERRQ(ierr); } /* Do LUFactor() on both the matrices */ ierr = PetscMalloc(M*sizeof(PetscInt),&idx);CHKERRQ(ierr); for (i=0; i<M; i++) idx[i] = i; ierr = ISCreateGeneral(PETSC_COMM_SELF,M,idx,&is1);CHKERRQ(ierr); ierr = ISCreateGeneral(PETSC_COMM_SELF,M,idx,&is2);CHKERRQ(ierr); ierr = PetscFree(idx);CHKERRQ(ierr); ierr = ISSetPermutation(is1);CHKERRQ(ierr); ierr = ISSetPermutation(is2);CHKERRQ(ierr); ierr = MatFactorInfoInitialize(&info);CHKERRQ(ierr); info.fill = 2.0; info.dtcol = 0.0; info.zeropivot = 1.e-14; info.pivotinblocks = 1.0; ierr = MatLUFactor(B,is1,is2,&info);CHKERRQ(ierr); ierr = MatLUFactor(A,is1,is2,&info);CHKERRQ(ierr); /* Test MatSolveAdd() */ for (i=0; i<10; i++) { ierr = VecSetRandom(xx,rdm);CHKERRQ(ierr); ierr = VecSetRandom(yy,rdm);CHKERRQ(ierr); ierr = MatSolveAdd(B,xx,yy,s2);CHKERRQ(ierr); ierr = MatSolveAdd(A,xx,yy,s1);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error:MatSolveAdd - Norm1=%16.14e Norm2=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } } /* Test MatSolveAdd() when x = A'b +x */ for (i=0; i<10; i++) { ierr = VecSetRandom(xx,rdm);CHKERRQ(ierr); ierr = VecSetRandom(s1,rdm);CHKERRQ(ierr); ierr = VecCopy(s2,s1);CHKERRQ(ierr); ierr = MatSolveAdd(B,xx,s2,s2);CHKERRQ(ierr); ierr = MatSolveAdd(A,xx,s1,s1);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error:MatSolveAdd(same) - Norm1=%16.14e Norm2=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } } /* Test MatSolve() */ for (i=0; i<10; i++) { ierr = VecSetRandom(xx,rdm);CHKERRQ(ierr); ierr = MatSolve(B,xx,s2);CHKERRQ(ierr); ierr = MatSolve(A,xx,s1);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error:MatSolve - Norm1=%16.14e Norm2=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } } /* Test MatSolveTranspose() */ if (bs < 8) { for (i=0; i<10; i++) { ierr = VecSetRandom(xx,rdm);CHKERRQ(ierr); ierr = MatSolveTranspose(B,xx,s2);CHKERRQ(ierr); ierr = MatSolveTranspose(A,xx,s1);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error:MatSolveTranspose - Norm1=%16.14e Norm2=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } } } ierr = MatDestroy(A);CHKERRQ(ierr); ierr = MatDestroy(B);CHKERRQ(ierr); ierr = VecDestroy(xx);CHKERRQ(ierr); ierr = VecDestroy(s1);CHKERRQ(ierr); ierr = VecDestroy(s2);CHKERRQ(ierr); ierr = VecDestroy(yy);CHKERRQ(ierr); ierr = ISDestroy(is1);CHKERRQ(ierr); ierr = ISDestroy(is2);CHKERRQ(ierr); ierr = PetscRandomDestroy(rdm);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
PetscErrorCode DMCoarsen_Plex(DM dm, MPI_Comm comm, DM *dmCoarsened) { DM_Plex *mesh = (DM_Plex*) dm->data; #ifdef PETSC_HAVE_PRAGMATIC DM udm, coordDM; DMLabel bd; Mat A; Vec coordinates, mb, mx; PetscSection coordSection; const PetscScalar *coords; double *coarseCoords; IS bdIS; PetscReal *x, *y, *z, *eqns, *metric; PetscReal coarseRatio = PetscSqr(0.5); const PetscInt *faces; PetscInt *cells, *bdFaces, *bdFaceIds; PetscInt dim, numCorners, cStart, cEnd, numCells, numCoarseCells, c, vStart, vEnd, numVertices, numCoarseVertices, v, numBdFaces, f, maxConeSize, size, bdSize, coff; #endif PetscErrorCode ierr; PetscFunctionBegin; #ifdef PETSC_HAVE_PRAGMATIC if (!mesh->coarseMesh) { ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); ierr = DMGetCoordinateDM(dm, &coordDM);CHKERRQ(ierr); ierr = DMGetDefaultSection(coordDM, &coordSection);CHKERRQ(ierr); ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); ierr = DMPlexUninterpolate(dm, &udm);CHKERRQ(ierr); ierr = DMPlexGetMaxSizes(udm, &maxConeSize, NULL);CHKERRQ(ierr); numCells = cEnd - cStart; numVertices = vEnd - vStart; ierr = PetscCalloc5(numVertices, &x, numVertices, &y, numVertices, &z, numVertices*PetscSqr(dim), &metric, numCells*maxConeSize, &cells);CHKERRQ(ierr); ierr = VecGetArrayRead(coordinates, &coords);CHKERRQ(ierr); for (v = vStart; v < vEnd; ++v) { PetscInt off; ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); x[v-vStart] = coords[off+0]; y[v-vStart] = coords[off+1]; if (dim > 2) z[v-vStart] = coords[off+2]; } ierr = VecRestoreArrayRead(coordinates, &coords);CHKERRQ(ierr); for (c = 0, coff = 0; c < numCells; ++c) { const PetscInt *cone; PetscInt coneSize, cl; ierr = DMPlexGetConeSize(udm, c, &coneSize);CHKERRQ(ierr); ierr = DMPlexGetCone(udm, c, &cone);CHKERRQ(ierr); for (cl = 0; cl < coneSize; ++cl) cells[coff++] = cone[cl] - vStart; } switch (dim) { case 2: pragmatic_2d_init(&numVertices, &numCells, cells, x, y); break; case 3: pragmatic_3d_init(&numVertices, &numCells, cells, x, y, z); break; default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "No Pragmatic coarsening defined for dimension %d", dim); } /* Create boundary mesh */ ierr = DMLabelCreate("boundary", &bd);CHKERRQ(ierr); ierr = DMPlexMarkBoundaryFaces(dm, bd);CHKERRQ(ierr); ierr = DMLabelGetStratumIS(bd, 1, &bdIS);CHKERRQ(ierr); ierr = DMLabelGetStratumSize(bd, 1, &numBdFaces);CHKERRQ(ierr); ierr = ISGetIndices(bdIS, &faces);CHKERRQ(ierr); for (f = 0, bdSize = 0; f < numBdFaces; ++f) { PetscInt *closure = NULL; PetscInt closureSize, cl; ierr = DMPlexGetTransitiveClosure(dm, faces[f], PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); for (cl = 0; cl < closureSize*2; cl += 2) { if ((closure[cl] >= vStart) && (closure[cl] < vEnd)) ++bdSize; } ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); } ierr = PetscMalloc2(bdSize, &bdFaces, numBdFaces, &bdFaceIds);CHKERRQ(ierr); for (f = 0, bdSize = 0; f < numBdFaces; ++f) { PetscInt *closure = NULL; PetscInt closureSize, cl; ierr = DMPlexGetTransitiveClosure(dm, faces[f], PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); for (cl = 0; cl < closureSize*2; cl += 2) { if ((closure[cl] >= vStart) && (closure[cl] < vEnd)) bdFaces[bdSize++] = closure[cl] - vStart; } /* TODO Fix */ bdFaceIds[f] = 1; ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); } ierr = ISDestroy(&bdIS);CHKERRQ(ierr); ierr = DMLabelDestroy(&bd);CHKERRQ(ierr); pragmatic_set_boundary(&numBdFaces, bdFaces, bdFaceIds); /* Create metric */ size = (dim*(dim+1))/2; ierr = PetscMalloc1(PetscSqr(size), &eqns);CHKERRQ(ierr); ierr = MatCreateSeqDense(PETSC_COMM_SELF, size, size, eqns, &A);CHKERRQ(ierr); ierr = MatCreateVecs(A, &mx, &mb);CHKERRQ(ierr); ierr = VecSet(mb, 1.0);CHKERRQ(ierr); for (c = 0; c < numCells; ++c) { const PetscScalar *sol; PetscScalar *cellCoords = NULL; PetscReal e[3], vol; const PetscInt *cone; PetscInt coneSize, cl, i, j, d, r; ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, c, NULL, &cellCoords);CHKERRQ(ierr); /* Only works for simplices */ for (i = 0, r = 0; i < dim+1; ++i) { for (j = 0; j < i; ++j, ++r) { for (d = 0; d < dim; ++d) e[d] = cellCoords[i*dim+d] - cellCoords[j*dim+d]; /* FORTRAN ORDERING */ if (dim == 2) { eqns[0*size+r] = PetscSqr(e[0]); eqns[1*size+r] = 2.0*e[0]*e[1]; eqns[2*size+r] = PetscSqr(e[1]); } else { eqns[0*size+r] = PetscSqr(e[0]); eqns[1*size+r] = 2.0*e[0]*e[1]; eqns[2*size+r] = 2.0*e[0]*e[2]; eqns[3*size+r] = PetscSqr(e[1]); eqns[4*size+r] = 2.0*e[1]*e[2]; eqns[5*size+r] = PetscSqr(e[2]); } } } ierr = MatSetUnfactored(A);CHKERRQ(ierr); ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, c, NULL, &cellCoords);CHKERRQ(ierr); ierr = MatLUFactor(A, NULL, NULL, NULL);CHKERRQ(ierr); ierr = MatSolve(A, mb, mx);CHKERRQ(ierr); ierr = VecGetArrayRead(mx, &sol);CHKERRQ(ierr); ierr = DMPlexComputeCellGeometryFVM(dm, c, &vol, NULL, NULL);CHKERRQ(ierr); ierr = DMPlexGetCone(udm, c, &cone);CHKERRQ(ierr); ierr = DMPlexGetConeSize(udm, c, &coneSize);CHKERRQ(ierr); for (cl = 0; cl < coneSize; ++cl) { const PetscInt v = cone[cl] - vStart; if (dim == 2) { metric[v*4+0] += vol*coarseRatio*sol[0]; metric[v*4+1] += vol*coarseRatio*sol[1]; metric[v*4+2] += vol*coarseRatio*sol[1]; metric[v*4+3] += vol*coarseRatio*sol[2]; } else { metric[v*9+0] += vol*coarseRatio*sol[0]; metric[v*9+1] += vol*coarseRatio*sol[1]; metric[v*9+3] += vol*coarseRatio*sol[1]; metric[v*9+2] += vol*coarseRatio*sol[2]; metric[v*9+6] += vol*coarseRatio*sol[2]; metric[v*9+4] += vol*coarseRatio*sol[3]; metric[v*9+5] += vol*coarseRatio*sol[4]; metric[v*9+7] += vol*coarseRatio*sol[4]; metric[v*9+8] += vol*coarseRatio*sol[5]; } } ierr = VecRestoreArrayRead(mx, &sol);CHKERRQ(ierr); } for (v = 0; v < numVertices; ++v) { const PetscInt *support; PetscInt supportSize, s; PetscReal vol, totVol = 0.0; ierr = DMPlexGetSupport(udm, v+vStart, &support);CHKERRQ(ierr); ierr = DMPlexGetSupportSize(udm, v+vStart, &supportSize);CHKERRQ(ierr); for (s = 0; s < supportSize; ++s) {ierr = DMPlexComputeCellGeometryFVM(dm, support[s], &vol, NULL, NULL);CHKERRQ(ierr); totVol += vol;} for (s = 0; s < PetscSqr(dim); ++s) metric[v*PetscSqr(dim)+s] /= totVol; } ierr = VecDestroy(&mx);CHKERRQ(ierr); ierr = VecDestroy(&mb);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = DMDestroy(&udm);CHKERRQ(ierr); ierr = PetscFree(eqns);CHKERRQ(ierr); pragmatic_set_metric(metric); pragmatic_adapt(); /* Read out mesh */ pragmatic_get_info(&numCoarseVertices, &numCoarseCells); ierr = PetscMalloc1(numCoarseVertices*dim, &coarseCoords);CHKERRQ(ierr); switch (dim) { case 2: pragmatic_get_coords_2d(x, y); numCorners = 3; for (v = 0; v < numCoarseVertices; ++v) {coarseCoords[v*2+0] = x[v]; coarseCoords[v*2+1] = y[v];} break; case 3: pragmatic_get_coords_3d(x, y, z); numCorners = 4; for (v = 0; v < numCoarseVertices; ++v) {coarseCoords[v*3+0] = x[v]; coarseCoords[v*3+1] = y[v]; coarseCoords[v*3+2] = z[v];} break; default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "No Pragmatic coarsening defined for dimension %d", dim); } pragmatic_get_elements(cells); /* TODO Read out markers for boundary */ ierr = DMPlexCreateFromCellList(PetscObjectComm((PetscObject) dm), dim, numCoarseCells, numCoarseVertices, numCorners, PETSC_TRUE, cells, dim, coarseCoords, &mesh->coarseMesh);CHKERRQ(ierr); pragmatic_finalize(); ierr = PetscFree5(x, y, z, metric, cells);CHKERRQ(ierr); ierr = PetscFree2(bdFaces, bdFaceIds);CHKERRQ(ierr); ierr = PetscFree(coarseCoords);CHKERRQ(ierr); } #endif ierr = PetscObjectReference((PetscObject) mesh->coarseMesh);CHKERRQ(ierr); *dmCoarsened = mesh->coarseMesh; PetscFunctionReturn(0); }
int main(int argc,char **argv) { Mat A,F,B,X,C,Aher,G; Vec b,x,c,d,e; PetscErrorCode ierr; PetscInt m = 5,n,p,i,j,nrows,ncols; PetscScalar *v,*barray,rval; PetscReal norm,tol=1.e-12; PetscMPIInt size,rank; PetscRandom rand; const PetscInt *rows,*cols; IS isrows,iscols; PetscBool mats_view=PETSC_FALSE; MatFactorInfo finfo; PetscInitialize(&argc,&argv,(char*) 0,help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rand);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rand);CHKERRQ(ierr); /* Get local dimensions of matrices */ ierr = PetscOptionsGetInt(NULL,"-m",&m,NULL);CHKERRQ(ierr); n = m; ierr = PetscOptionsGetInt(NULL,"-n",&n,NULL);CHKERRQ(ierr); p = m/2; ierr = PetscOptionsGetInt(NULL,"-p",&p,NULL);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,"-mats_view",&mats_view);CHKERRQ(ierr); /* Create matrix A */ ierr = PetscPrintf(PETSC_COMM_WORLD," Create Elemental matrix A\n");CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = MatSetType(A,MATELEMENTAL);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); /* Set local matrix entries */ ierr = MatGetOwnershipIS(A,&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); for (i=0; i<nrows; i++) { for (j=0; j<ncols; j++) { ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); v[i*ncols+j] = rval; } } ierr = MatSetValues(A,nrows,rows,ncols,cols,v,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = ISRestoreIndices(isrows,&rows);CHKERRQ(ierr); ierr = ISRestoreIndices(iscols,&cols);CHKERRQ(ierr); ierr = ISDestroy(&isrows);CHKERRQ(ierr); ierr = ISDestroy(&iscols);CHKERRQ(ierr); ierr = PetscFree(v);CHKERRQ(ierr); if (mats_view) { ierr = PetscPrintf(PETSC_COMM_WORLD, "A: nrows %d, m %d; ncols %d, n %d\n",nrows,m,ncols,n);CHKERRQ(ierr); ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } /* Create rhs matrix B */ ierr = PetscPrintf(PETSC_COMM_WORLD," Create rhs matrix B\n");CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&B);CHKERRQ(ierr); ierr = MatSetSizes(B,m,p,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); ierr = PetscMalloc1(nrows*ncols,&v);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 = MatSetValues(B,nrows,rows,ncols,cols,v,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = ISRestoreIndices(isrows,&rows);CHKERRQ(ierr); ierr = ISRestoreIndices(iscols,&cols);CHKERRQ(ierr); ierr = ISDestroy(&isrows);CHKERRQ(ierr); ierr = ISDestroy(&iscols);CHKERRQ(ierr); ierr = PetscFree(v);CHKERRQ(ierr); if (mats_view) { ierr = PetscPrintf(PETSC_COMM_WORLD, "B: nrows %d, m %d; ncols %d, p %d\n",nrows,m,ncols,p);CHKERRQ(ierr); ierr = MatView(B,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } /* Create rhs vector b and solution x (same size as b) */ ierr = VecCreate(PETSC_COMM_WORLD,&b);CHKERRQ(ierr); ierr = VecSetSizes(b,m,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(b);CHKERRQ(ierr); ierr = VecGetArray(b,&barray);CHKERRQ(ierr); for (j=0; j<m; j++) { ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); barray[j] = rval; } ierr = VecRestoreArray(b,&barray);CHKERRQ(ierr); ierr = VecAssemblyBegin(b);CHKERRQ(ierr); ierr = VecAssemblyEnd(b);CHKERRQ(ierr); if (mats_view) { ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD, "[%d] b: m %d\n",rank,m);CHKERRQ(ierr); ierr = PetscSynchronizedFlush(PETSC_COMM_WORLD,PETSC_STDOUT);CHKERRQ(ierr); ierr = VecView(b,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = VecDuplicate(b,&x);CHKERRQ(ierr); /* Create matrix X - same size as B */ ierr = PetscPrintf(PETSC_COMM_WORLD," Create solution matrix X\n");CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&X);CHKERRQ(ierr); ierr = MatSetSizes(X,m,p,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = MatSetType(X,MATELEMENTAL);CHKERRQ(ierr); ierr = MatSetFromOptions(X);CHKERRQ(ierr); ierr = MatSetUp(X);CHKERRQ(ierr); ierr = MatAssemblyBegin(X,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(X,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Cholesky factorization */ /*------------------------*/ ierr = PetscPrintf(PETSC_COMM_WORLD," Create Elemental matrix Aher\n");CHKERRQ(ierr); ierr = MatHermitianTranspose(A,MAT_INITIAL_MATRIX,&Aher);CHKERRQ(ierr); ierr = MatAXPY(Aher,1.0,A,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* Aher = A + A^T */ if (!rank) { /* add 100.0 to diagonals of Aher to make it spd */ PetscInt M,N; ierr = MatGetSize(Aher,&M,&N);CHKERRQ(ierr); for (i=0; i<M; i++) { rval = 100.0; ierr = MatSetValues(Aher,1,&i,1,&i,&rval,ADD_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(Aher,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(Aher,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); if (mats_view) { ierr = PetscPrintf(PETSC_COMM_WORLD, "Aher:\n");CHKERRQ(ierr); ierr = MatView(Aher,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } /* Cholesky factorization */ /*------------------------*/ ierr = PetscPrintf(PETSC_COMM_WORLD," Test Cholesky Solver \n");CHKERRQ(ierr); /* In-place Cholesky */ /* Create matrix factor G, then copy Aher to G */ ierr = MatCreate(PETSC_COMM_WORLD,&G);CHKERRQ(ierr); ierr = MatSetSizes(G,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = MatSetType(G,MATELEMENTAL);CHKERRQ(ierr); ierr = MatSetFromOptions(G);CHKERRQ(ierr); ierr = MatSetUp(G);CHKERRQ(ierr); ierr = MatAssemblyBegin(G,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(G,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatCopy(Aher,G,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* Only G = U^T * U is implemented for now */ ierr = MatCholeskyFactor(G,0,0);CHKERRQ(ierr); if (mats_view) { ierr = PetscPrintf(PETSC_COMM_WORLD, "Cholesky Factor G:\n");CHKERRQ(ierr); ierr = MatView(G,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } /* Solve U^T * U x = b and U^T * U X = B */ ierr = MatSolve(G,b,x);CHKERRQ(ierr); ierr = MatMatSolve(G,B,X);CHKERRQ(ierr); ierr = MatDestroy(&G);CHKERRQ(ierr); /* Out-place Cholesky */ ierr = MatGetFactor(Aher,MATSOLVERELEMENTAL,MAT_FACTOR_CHOLESKY,&G);CHKERRQ(ierr); ierr = MatCholeskyFactorSymbolic(G,Aher,0,&finfo);CHKERRQ(ierr); ierr = MatCholeskyFactorNumeric(G,Aher,&finfo);CHKERRQ(ierr); if (mats_view) { ierr = MatView(G,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = MatSolve(G,b,x);CHKERRQ(ierr); ierr = MatMatSolve(G,B,X);CHKERRQ(ierr); ierr = MatDestroy(&G);CHKERRQ(ierr); /* Check norm(Aher*x - b) */ ierr = VecCreate(PETSC_COMM_WORLD,&c);CHKERRQ(ierr); ierr = VecSetSizes(c,m,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(c);CHKERRQ(ierr); ierr = MatMult(Aher,x,c);CHKERRQ(ierr); ierr = VecAXPY(c,-1.0,b);CHKERRQ(ierr); ierr = VecNorm(c,NORM_1,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Warning: |Aher*x - b| for Cholesky %g\n",(double)norm);CHKERRQ(ierr); } /* Check norm(Aher*X - B) */ ierr = MatMatMult(Aher,X,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr); ierr = MatAXPY(C,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatNorm(C,NORM_1,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Warning: |Aher*X - B| for Cholesky %g\n",(double)norm);CHKERRQ(ierr); } /* LU factorization */ /*------------------*/ ierr = PetscPrintf(PETSC_COMM_WORLD," Test LU Solver \n");CHKERRQ(ierr); /* In-place LU */ /* Create matrix factor F, then copy A to F */ ierr = MatCreate(PETSC_COMM_WORLD,&F);CHKERRQ(ierr); ierr = MatSetSizes(F,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = MatSetType(F,MATELEMENTAL);CHKERRQ(ierr); ierr = MatSetFromOptions(F);CHKERRQ(ierr); ierr = MatSetUp(F);CHKERRQ(ierr); ierr = MatAssemblyBegin(F,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(F,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatCopy(A,F,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* Create vector d to test MatSolveAdd() */ ierr = VecDuplicate(x,&d);CHKERRQ(ierr); ierr = VecCopy(x,d);CHKERRQ(ierr); /* PF=LU or F=LU factorization - perms is ignored by Elemental; set finfo.dtcol !0 or 0 to enable/disable partial pivoting */ finfo.dtcol = 0.1; ierr = MatLUFactor(F,0,0,&finfo);CHKERRQ(ierr); /* Solve LUX = PB or LUX = B */ ierr = MatSolveAdd(F,b,d,x);CHKERRQ(ierr); ierr = MatMatSolve(F,B,X);CHKERRQ(ierr); ierr = MatDestroy(&F);CHKERRQ(ierr); /* Check norm(A*X - B) */ ierr = VecCreate(PETSC_COMM_WORLD,&e);CHKERRQ(ierr); ierr = VecSetSizes(e,m,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(e);CHKERRQ(ierr); ierr = MatMult(A,x,c);CHKERRQ(ierr); ierr = MatMult(A,d,e);CHKERRQ(ierr); ierr = VecAXPY(c,-1.0,e);CHKERRQ(ierr); ierr = VecAXPY(c,-1.0,b);CHKERRQ(ierr); ierr = VecNorm(c,NORM_1,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Warning: |A*x - b| for LU %g\n",(double)norm);CHKERRQ(ierr); } ierr = MatMatMult(A,X,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr); ierr = MatAXPY(C,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatNorm(C,NORM_1,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Warning: |A*X - B| for LU %g\n",(double)norm);CHKERRQ(ierr); } /* Out-place LU */ ierr = MatGetFactor(A,MATSOLVERELEMENTAL,MAT_FACTOR_LU,&F);CHKERRQ(ierr); ierr = MatLUFactorSymbolic(F,A,0,0,&finfo);CHKERRQ(ierr); ierr = MatLUFactorNumeric(F,A,&finfo);CHKERRQ(ierr); if (mats_view) { ierr = MatView(F,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = MatSolve(F,b,x);CHKERRQ(ierr); ierr = MatMatSolve(F,B,X);CHKERRQ(ierr); ierr = MatDestroy(&F);CHKERRQ(ierr); /* Free space */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&Aher);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = MatDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = VecDestroy(&c);CHKERRQ(ierr); ierr = VecDestroy(&d);CHKERRQ(ierr); ierr = VecDestroy(&e);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rand);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
For MATSEQDENSE matrix, the factorization is just a thin wrapper to LAPACK \n\n"; #include <petscmat.h> #undef __FUNCT__ #define __FUNCT__ "main" int main(int argc,char **argv) { Mat mat,F,RHS,SOLU; MatInfo info; PetscErrorCode ierr; PetscInt m = 10,n = 10,i,j,rstart,rend,nrhs=2; PetscScalar value = 1.0; Vec x,y,b,ytmp; PetscReal norm,tol=1.e-15; PetscMPIInt size; PetscScalar *rhs_array,*solu_array; PetscRandom rand; PetscScalar *array,rval; PetscInitialize(&argc,&argv,(char*) 0,help); 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 single vectors */ ierr = VecCreate(PETSC_COMM_WORLD,&y);CHKERRQ(ierr); ierr = VecSetSizes(y,PETSC_DECIDE,m);CHKERRQ(ierr); ierr = VecSetFromOptions(y);CHKERRQ(ierr); ierr = VecDuplicate(y,&x);CHKERRQ(ierr); ierr = VecDuplicate(y,&ytmp);CHKERRQ(ierr); ierr = VecSet(x,value);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD,&b);CHKERRQ(ierr); ierr = VecSetSizes(b,PETSC_DECIDE,n);CHKERRQ(ierr); ierr = VecSetFromOptions(b);CHKERRQ(ierr); /* create multiple vectors RHS and SOLU */ ierr = MatCreate(PETSC_COMM_WORLD,&RHS);CHKERRQ(ierr); ierr = MatSetSizes(RHS,PETSC_DECIDE,PETSC_DECIDE,n,nrhs);CHKERRQ(ierr); ierr = MatSetType(RHS,MATDENSE);CHKERRQ(ierr); ierr = MatSetFromOptions(RHS);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(RHS,NULL);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rand);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rand);CHKERRQ(ierr); ierr = MatDenseGetArray(RHS,&array);CHKERRQ(ierr); for (j=0; j<nrhs; j++) { for (i=0; i<n; i++) { ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); array[n*j+i] = rval; } } ierr = MatDenseRestoreArray(RHS,&array);CHKERRQ(ierr); ierr = MatDuplicate(RHS,MAT_DO_NOT_COPY_VALUES,&SOLU);CHKERRQ(ierr); /* create matrix */ ierr = MatCreateSeqDense(PETSC_COMM_WORLD,m,n,NULL,&mat);CHKERRQ(ierr); ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); for (i=rstart; i<rend; i++) { value = (PetscReal)i+1; ierr = MatSetValues(mat,1,&i,1,&i,&value,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatGetInfo(mat,MAT_LOCAL,&info);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"matrix nonzeros = %D, allocated nonzeros = %D\n", (PetscInt)info.nz_used,(PetscInt)info.nz_allocated);CHKERRQ(ierr); /* Cholesky factorization - perm and factinfo are ignored by LAPACK */ /* in-place Cholesky */ ierr = MatMult(mat,x,b);CHKERRQ(ierr); ierr = MatDuplicate(mat,MAT_COPY_VALUES,&F);CHKERRQ(ierr); ierr = MatCholeskyFactor(F,0,0);CHKERRQ(ierr); ierr = MatSolve(F,b,y);CHKERRQ(ierr); ierr = MatDestroy(&F);CHKERRQ(ierr); value = -1.0; ierr = VecAXPY(y,value,x);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Warning: Norm of error for Cholesky %G\n",norm);CHKERRQ(ierr); } /* out-place Cholesky */ ierr = MatGetFactor(mat,MATSOLVERPETSC,MAT_FACTOR_CHOLESKY,&F);CHKERRQ(ierr); ierr = MatCholeskyFactorSymbolic(F,mat,0,0);CHKERRQ(ierr); ierr = MatCholeskyFactorNumeric(F,mat,0);CHKERRQ(ierr); ierr = MatSolve(F,b,y);CHKERRQ(ierr); value = -1.0; ierr = VecAXPY(y,value,x);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Warning: Norm of error for Cholesky %G\n",norm);CHKERRQ(ierr); } ierr = MatDestroy(&F);CHKERRQ(ierr); /* LU factorization - perms and factinfo are ignored by LAPACK */ i = m-1; value = 1.0; ierr = MatSetValues(mat,1,&i,1,&i,&value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatMult(mat,x,b);CHKERRQ(ierr); ierr = MatDuplicate(mat,MAT_COPY_VALUES,&F);CHKERRQ(ierr); /* in-place LU */ ierr = MatLUFactor(F,0,0,0);CHKERRQ(ierr); ierr = MatSolve(F,b,y);CHKERRQ(ierr); value = -1.0; ierr = VecAXPY(y,value,x);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Warning: Norm of error for LU %G\n",norm);CHKERRQ(ierr); } ierr = MatMatSolve(F,RHS,SOLU);CHKERRQ(ierr); ierr = MatDenseGetArray(SOLU,&solu_array);CHKERRQ(ierr); ierr = MatDenseGetArray(RHS,&rhs_array);CHKERRQ(ierr); for (j=0; j<nrhs; j++) { ierr = VecPlaceArray(y,solu_array+j*m);CHKERRQ(ierr); ierr = VecPlaceArray(b,rhs_array+j*m);CHKERRQ(ierr); ierr = MatMult(mat,y,ytmp);CHKERRQ(ierr); ierr = VecAXPY(ytmp,-1.0,b);CHKERRQ(ierr); /* ytmp = mat*SOLU[:,j] - RHS[:,j] */ ierr = VecNorm(ytmp,NORM_2,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Error: Norm of residual for LU %G\n",norm);CHKERRQ(ierr); } ierr = VecResetArray(b);CHKERRQ(ierr); ierr = VecResetArray(y);CHKERRQ(ierr); } ierr = MatDenseRestoreArray(RHS,&rhs_array);CHKERRQ(ierr); ierr = MatDenseRestoreArray(SOLU,&solu_array);CHKERRQ(ierr); ierr = MatDestroy(&F);CHKERRQ(ierr); /* out-place LU */ ierr = MatGetFactor(mat,MATSOLVERPETSC,MAT_FACTOR_LU,&F);CHKERRQ(ierr); ierr = MatLUFactorSymbolic(F,mat,0,0,0);CHKERRQ(ierr); ierr = MatLUFactorNumeric(F,mat,0);CHKERRQ(ierr); ierr = MatSolve(F,b,y);CHKERRQ(ierr); value = -1.0; ierr = VecAXPY(y,value,x);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Warning: Norm of error for LU %G\n",norm);CHKERRQ(ierr); } /* free space */ ierr = MatDestroy(&F);CHKERRQ(ierr); ierr = MatDestroy(&mat);CHKERRQ(ierr); ierr = MatDestroy(&RHS);CHKERRQ(ierr); ierr = MatDestroy(&SOLU);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rand);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = VecDestroy(&y);CHKERRQ(ierr); ierr = VecDestroy(&ytmp);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **args) { const int iM11=0, iM12=1, iL11=2, iL22=3, iL21=4, ix=5; Mat M11,M12,L11,L22,L21; /* matrix */ Vec x,y; /* input and output vectors */ Vec omg1,omg2,omg3,omg4; /* temporary vectors for the operation y=Ax */ KSP ksp; /* linear solver context */ PetscViewer fd[5]; /* viewer */ char file[6][PETSC_MAX_PATH_LEN]; /* input file name */ PetscErrorCode ierr; PetscInt M, N; /* number of rows and columns of the GLOBAL matrices (they should be the same) */ PetscInt m, n; /* number of rows and columns of the LOCAL matrices */ PetscInt istart, iend; /* ownership row range of the process using GLOBAL indexes */ PetscScalar one=1.0; PetscMPIInt rank, size; PetscBool flg[6]; PetscInitialize(&argc,&args,(char *)0,help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD, "Number of processes size=%d\n", size); // ************ READ MATRICES AND VECTOR x FROM INPUT ***** // M11 and M12 ierr = PetscOptionsGetString(PETSC_NULL,"-m11",file[iM11],PETSC_MAX_PATH_LEN,&flg[iM11]);CHKERRQ(ierr); ierr = PetscOptionsGetString(PETSC_NULL,"-m12",file[iM12],PETSC_MAX_PATH_LEN,&flg[iM12]);CHKERRQ(ierr); // L11 L22 and L21 ierr = PetscOptionsGetString(PETSC_NULL,"-l11",file[iL11],PETSC_MAX_PATH_LEN,&flg[iL11]);CHKERRQ(ierr); ierr = PetscOptionsGetString(PETSC_NULL,"-l22",file[iL22],PETSC_MAX_PATH_LEN,&flg[iL22]);CHKERRQ(ierr); ierr = PetscOptionsGetString(PETSC_NULL,"-l21",file[iL21],PETSC_MAX_PATH_LEN,&flg[iL21]);CHKERRQ(ierr); // All of the matrix have to be defined by the user. // If the user don't specify none of them, it will generate laplacian matrices. if (flg[iM11] && flg[iM12] && flg[iL11] && flg[iL22] && flg[iL21]){ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[iM11],FILE_MODE_READ,\ &fd[iM11]);CHKERRQ(ierr); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[iM12],FILE_MODE_READ,\ &fd[iM12]);CHKERRQ(ierr); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[iL11],FILE_MODE_READ,\ &fd[iL11]);CHKERRQ(ierr); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[iL22],FILE_MODE_READ,\ &fd[iL22]);CHKERRQ(ierr); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[iL21],FILE_MODE_READ,\ &fd[iL21]);CHKERRQ(ierr); // Load the matrix and vector; then destroy the viewer. // M11 and M12 ierr = MatCreate(PETSC_COMM_WORLD,&M11);CHKERRQ(ierr); ierr = MatSetType(M11,MATAIJ);CHKERRQ(ierr); ierr = MatSetFromOptions(M11);CHKERRQ(ierr); ierr = MatLoad(M11,fd[iM11]);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&M12);CHKERRQ(ierr); ierr = MatSetType(M12,MATAIJ);CHKERRQ(ierr); ierr = MatSetFromOptions(M12);CHKERRQ(ierr); ierr = MatLoad(M12,fd[iM12]);CHKERRQ(ierr); // L11 L22 and L21 ierr = MatCreate(PETSC_COMM_WORLD,&L11);CHKERRQ(ierr); ierr = MatSetType(L11,MATAIJ);CHKERRQ(ierr); ierr = MatSetFromOptions(L11);CHKERRQ(ierr); ierr = MatLoad(L11,fd[iL11]);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&L22);CHKERRQ(ierr); ierr = MatSetType(L22,MATAIJ);CHKERRQ(ierr); ierr = MatSetFromOptions(L22);CHKERRQ(ierr); ierr = MatLoad(L22,fd[iL22]);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&L21);CHKERRQ(ierr); ierr = MatSetType(L21,MATAIJ);CHKERRQ(ierr); ierr = MatSetFromOptions(L21);CHKERRQ(ierr); ierr = MatLoad(L21,fd[iL21]);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd[iM11]);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd[iM12]);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd[iL11]);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd[iL22]);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd[iL21]);CHKERRQ(ierr); } else if(!flg[iM11] && !flg[iM12] && !flg[iL11] && !flg[iL22] && !flg[iL21]){ // ******************* CREATING FAKE MATRICES ***************** PetscInt i,col[3]; M = N = 100; PetscScalar value[3]; ierr = MatCreate(PETSC_COMM_WORLD,&M11);CHKERRQ(ierr); ierr = MatSetSizes(M11,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); ierr = MatSetFromOptions(M11);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&M12);CHKERRQ(ierr); ierr = MatSetSizes(M12,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); ierr = MatSetFromOptions(M12);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&L11);CHKERRQ(ierr); ierr = MatSetSizes(L11,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); ierr = MatSetFromOptions(L11);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&L22);CHKERRQ(ierr); ierr = MatSetSizes(L22,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); ierr = MatSetFromOptions(L22);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&L21);CHKERRQ(ierr); ierr = MatSetSizes(L21,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); ierr = MatSetFromOptions(L21);CHKERRQ(ierr); // Set values for them value[0] = -1.0; value[1] = 2.0; value[2] = -1.0; for (i=1; i<M-1; i++) { col[0] = i-1; col[1] = i; col[2] = i+1; ierr = MatSetValues(M11,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(M12,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(L11,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(L22,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(L21,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } i = N - 1; col[0] = N - 2; col[1] = N - 1; ierr = MatSetValues(M11,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(M12,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(L11,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(L22,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(L21,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); i = 0; col[0] = 0; col[1] = 1; value[0] = 2.0; value[1] = -1.0; ierr = MatSetValues(M11,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(M12,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(L11,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(L22,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(L21,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(M11,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(M11,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyBegin(M12,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(M12,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyBegin(L11,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(L11,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyBegin(L22,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(L22,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyBegin(L21,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(L21,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); // ******************** END CREATING FAKE MATRICES ************* } else{ SETERRQ(PETSC_COMM_WORLD,1,"You must either indicate the ascii file for each matrix M11 M12 L11 L22 L21 using the option -m11 -m12 .... or without any of these options."); PetscFinalize(); return 1; } // Get some information about the partitioning of the matrix ierr = MatGetSize(M11,&M,&N);CHKERRQ(ierr); printf("Global dimension of the matrix M11 M=%d N=%d\n",M,N); ierr = MatGetLocalSize(M11,&m,&n); printf("Local dimension of the matrix M11 m=%d n=%d\n",m,n); ierr = MatGetOwnershipRange(M11,&istart,&iend); printf("Ownership range of the rows for process %d istart=%d iend=%d\n",rank,istart,iend); // Read vector x from input. If it's not specified by the user, the vector x will be a unitary vector. ierr = PetscOptionsGetString(PETSC_NULL,"-x",file[ix],PETSC_MAX_PATH_LEN,&flg[ix]);CHKERRQ(ierr); if(!flg[ix]){ ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr); ierr = VecSetSizes(x,PETSC_DECIDE,M);CHKERRQ(ierr); ierr = VecSetFromOptions(x);CHKERRQ(ierr); ierr = VecSet(x,one);CHKERRQ(ierr); /*ierr = VecAssemblyBegin(x);CHKERRQ(ierr);*/ /*ierr = VecAssemblyEnd(x);CHKERRQ(ierr);*/ } else{ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[ix],FILE_MODE_READ,&fd[ix]);CHKERRQ(ierr); ierr = VecLoad(x,fd[ix]);CHKERRQ(ierr); } ierr = PetscObjectSetName((PetscObject) x, "The input vector");CHKERRQ(ierr); // ************ END READ MATRICES AND VECTOR x FROM INPUT ***** // Create the temporary vectors and y ierr = VecDuplicate(x,&y);CHKERRQ(ierr); ierr = VecDuplicate(x,&omg1);CHKERRQ(ierr); ierr = VecDuplicate(x,&omg2);CHKERRQ(ierr); ierr = VecDuplicate(x,&omg3);CHKERRQ(ierr); ierr = VecDuplicate(x,&omg4);CHKERRQ(ierr); // ****************** COMPUTE y=Ax ******************* // Set the Krylov object ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); // Set operators. Here the matrix that defines the linear system // also serves as the preconditioning matrix. ierr = KSPSetOperators(ksp,L22,L22,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); // Set runtime options, e.g., // -ksp_type <type> -pc_type <type> -ksp_monitor -ksp_rtol <rtol> // These options will override those specified above as long as // KSPSetFromOptions() is called _after_ any other customization // routines. ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); // Multiplication y = A*x // omg1 = M11*x // omg2 = L21*x // L22*omg3 = omg2 // omg4 = omg1 + M12*omg3 // L11*y = omg4 ierr = MatMult(M11, x, omg1);CHKERRQ(ierr); ierr = MatMult(L21, x, omg2);CHKERRQ(ierr); ierr = KSPSolve(ksp,omg2,omg3);CHKERRQ(ierr); ierr = MatMult(M12, omg3, omg4);CHKERRQ(ierr); ierr = VecAXPY(omg4, one, omg1);CHKERRQ(ierr); ierr = KSPSetOperators(ksp,L11,L11,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = KSPSolve(ksp,omg4,y);CHKERRQ(ierr); // ****************** END COMPUTE y=Ax ************************** /*ierr = VecView(y, PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr);*/ PetscBool test = PETSC_FALSE; ierr = PetscOptionsGetBool(PETSC_NULL,"-test",&test,PETSC_NULL);CHKERRQ(ierr); if(test){ // ******************** TESTING ********************************* // the testing doesn't work if the number of process are more than one // because the type of the matrices must be different from matmpiaij. Let's try matseqaij Mat L11_inv, L22_inv, I; Mat A; Mat M11_d; Vec y2; PetscInt i; PetscScalar val; // Create identity matrix ierr = MatCreate(PETSC_COMM_WORLD,&I);CHKERRQ(ierr); ierr = MatSetType(I, MATDENSE); ierr = MatSetSizes(I,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); ierr = MatSetFromOptions(I);CHKERRQ(ierr); val = 1.0; for (i=0; i<M; i++) { ierr = MatSetValues(I,1,&i,1,&i,&val,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(I,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(I,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); // Create L11_inv ierr = MatCreate(PETSC_COMM_WORLD,&L11_inv);CHKERRQ(ierr); ierr = MatSetType(L11_inv, MATDENSE); ierr = MatSetSizes(L11_inv,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); ierr = MatSetFromOptions(L11_inv);CHKERRQ(ierr); ierr = MatAssemblyBegin(L11_inv,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(L11_inv,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); // Create L22_inv ierr = MatCreate(PETSC_COMM_WORLD,&L22_inv);CHKERRQ(ierr); ierr = MatSetType(L22_inv, MATDENSE); ierr = MatSetSizes(L22_inv,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); ierr = MatSetFromOptions(L22_inv);CHKERRQ(ierr); ierr = MatAssemblyBegin(L22_inv,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(L22_inv,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); // Create A ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); // Define M11_d ierr = MatCreate(PETSC_COMM_WORLD,&M11_d);CHKERRQ(ierr); ierr = MatSetType(M11_d, MATDENSE); ierr = MatSetSizes(M11_d,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); ierr = MatSetFromOptions(M11_d);CHKERRQ(ierr); ierr = MatAssemblyBegin(M11_d,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(M11_d,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); // Calculate A = L11^{-1}*(M11 + M12*L22^{-1}*L21) IS perm, iperm; MatFactorInfo info; ierr = MatGetOrdering(L11,MATORDERINGNATURAL,&perm,&iperm);CHKERRQ(ierr); ierr = MatFactorInfoInitialize(&info); CHKERRQ(ierr); ierr = MatLUFactor(L11, perm, iperm, &info); CHKERRQ(ierr); ierr = MatMatSolve(L11, I, L11_inv);CHKERRQ(ierr); // TODO try to convert L11_inv to be sparse such as matseqaij // ierr = MatView(L11_inv, PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = MatGetOrdering(L22,MATORDERINGNATURAL,&perm,&iperm);CHKERRQ(ierr); ierr = MatFactorInfoInitialize(&info); CHKERRQ(ierr); ierr = MatLUFactor(L22, perm, iperm, &info); CHKERRQ(ierr); ierr = MatMatSolve(L22, I, L22_inv);CHKERRQ(ierr); ierr = MatMatMult(M12, L22_inv, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &A);CHKERRQ(ierr); ierr = MatMatMult(A, L21, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &A);CHKERRQ(ierr); ierr = MatConvert(M11, MATDENSE, MAT_INITIAL_MATRIX, &M11_d); ierr = MatAXPY(A,1.0,M11_d,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatMatMult(L11_inv, A, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &A);CHKERRQ(ierr); ierr = VecDuplicate(x,&y2);CHKERRQ(ierr); ierr = MatMult(A, x, y2);CHKERRQ(ierr); /*ierr = VecView(y2, PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr);*/ // Check the error PetscReal norm; ierr = VecAXPY(y2,-1.0,y);CHKERRQ(ierr); ierr = VecNorm(y2,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm of error %A\n", norm);CHKERRQ(ierr); // ******************** END TESTING ***************************** } PetscFinalize(); return 0; }