PetscErrorCode SolveInit(FEMInf fem, int L, PetscScalar *e0, Vec *x) { PetscErrorCode ierr; Mat H, S; ierr = CalcMat(fem, L, &H, &S); CHKERRQ(ierr); EPS eps; ierr = PrintTimeStamp(fem->comm, "EPS", NULL); CHKERRQ(ierr); ierr = EPSCreate(fem->comm, &eps); CHKERRQ(ierr); ierr = EPSSetTarget(eps, -0.6); CHKERRQ(ierr); ierr = EPSSetWhichEigenpairs(eps, EPS_TARGET_MAGNITUDE); CHKERRQ(ierr); ierr = EPSSetOperators(eps, H, S); CHKERRQ(ierr); if(S == NULL) { ierr = EPSSetProblemType(eps, EPS_NHEP); CHKERRQ(ierr); } else { ierr = EPSSetProblemType(eps, EPS_GNHEP); CHKERRQ(ierr); } Vec x0[1]; MatCreateVecs(H, &x0[0], NULL); int num; FEMInfGetSize(fem, &num); for(int i = 0; i < num; i++) { VecSetValue(x0[0], i, 0.5, INSERT_VALUES); } VecAssemblyBegin(x0[0]); VecAssemblyEnd(x0[0]); EPSSetInitialSpace(eps, 1, x0); ierr = EPSSetFromOptions(eps); CHKERRQ(ierr); ierr = EPSSolve(eps); CHKERRQ(ierr); PetscInt nconv; EPSGetConverged(eps, &nconv); if(nconv == 0) SETERRQ(fem->comm, 1, "Failed to digonalize in init state\n"); Vec x_ans; MatCreateVecs(H, &x_ans, NULL); EPSGetEigenpair(eps, 0, e0, NULL, x_ans, NULL); EPSDestroy(&eps); PetscScalar v[1]; PetscInt idx[1] = {1}; VecGetValues(x_ans, 1, idx, v); PetscScalar scale_factor = v[0] / cabs(v[0]); VecScale( x_ans, 1.0/scale_factor); PetscScalar norm0; Vec Sx; MatCreateVecs(S, &Sx, NULL); MatMult(S, x_ans, Sx); VecDot(x_ans, Sx, &norm0); VecScale(x_ans, 1.0/sqrt(norm0)); *x = x_ans; return 0; }
static void ApplyPCPrecPETSCGen(void *x, PRIMME_INT *ldx, void *y, PRIMME_INT *ldy, int *blockSize, int trans, PC *pc, MPI_Comm comm) { int i; Vec xvec, yvec; Mat matrix; PetscErrorCode ierr; PetscInt mLocal, nLocal; ierr = PCGetOperators(pc[0],&matrix,NULL); CHKERRABORT(comm, ierr); assert(sizeof(PetscScalar) == sizeof(SCALAR)); ierr = MatGetLocalSize(matrix, &mLocal, &nLocal); CHKERRABORT(comm, ierr); assert(mLocal == nLocal && nLocal <= *ldx && mLocal <= *ldy); #if PETSC_VERSION_LT(3,6,0) ierr = MatGetVecs(matrix, &xvec, &yvec); CHKERRABORT(comm, ierr); #else ierr = MatCreateVecs(matrix, &xvec, &yvec); CHKERRABORT(comm, ierr); #endif for (i=0; i<*blockSize; i++) { ierr = VecPlaceArray(xvec, ((SCALAR*)x) + (*ldx)*i); CHKERRABORT(comm, ierr); ierr = VecPlaceArray(yvec, ((SCALAR*)y) + (*ldy)*i); CHKERRABORT(comm, ierr); if (trans == 0) { ierr = PCApply(*pc, xvec, yvec); CHKERRABORT(comm, ierr); } else if (pc[1]) { ierr = PCApply(pc[1], xvec, yvec); CHKERRABORT(comm, ierr); } else { ierr = PCApplyTranspose(pc[0], xvec, yvec); } ierr = VecResetArray(xvec); CHKERRABORT(comm, ierr); ierr = VecResetArray(yvec); CHKERRABORT(comm, ierr); } ierr = VecDestroy(&xvec); CHKERRABORT(comm, ierr); ierr = VecDestroy(&yvec); CHKERRABORT(comm, ierr); }
PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) { PetscErrorCode ierr; PetscInt n,bs; Mat_IS *is = (Mat_IS*)A->data; IS from,to; Vec global; PetscFunctionBegin; PetscCheckSameComm(A,1,rmapping,2); if (rmapping != cmapping) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MATIS requires the row and column mappings to be identical"); if (is->mapping) { /* Currenly destroys the objects that will be created by this routine. Is there anything else that should be checked? */ ierr = ISLocalToGlobalMappingDestroy(&is->mapping);CHKERRQ(ierr); ierr = VecDestroy(&is->x);CHKERRQ(ierr); ierr = VecDestroy(&is->y);CHKERRQ(ierr); ierr = VecScatterDestroy(&is->ctx);CHKERRQ(ierr); ierr = MatDestroy(&is->A);CHKERRQ(ierr); } ierr = PetscObjectReference((PetscObject)rmapping);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingDestroy(&is->mapping);CHKERRQ(ierr); is->mapping = rmapping; /* ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); */ /* Create the local matrix A */ ierr = ISLocalToGlobalMappingGetSize(rmapping,&n);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&bs);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); if (bs > 1) { ierr = MatSetType(is->A,MATSEQBAIJ);CHKERRQ(ierr); } else { ierr = MatSetType(is->A,MATSEQAIJ);CHKERRQ(ierr); } ierr = MatSetSizes(is->A,n,n,n,n);CHKERRQ(ierr); ierr = MatSetBlockSize(is->A,bs);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); /* Create the local work vectors */ ierr = VecCreate(PETSC_COMM_SELF,&is->x);CHKERRQ(ierr); ierr = VecSetBlockSize(is->x,bs);CHKERRQ(ierr); ierr = VecSetSizes(is->x,n,n);CHKERRQ(ierr); ierr = VecSetOptionsPrefix(is->x,((PetscObject)A)->prefix);CHKERRQ(ierr); ierr = VecAppendOptionsPrefix(is->x,"is_");CHKERRQ(ierr); ierr = VecSetFromOptions(is->x);CHKERRQ(ierr); ierr = VecDuplicate(is->x,&is->y);CHKERRQ(ierr); /* setup the global to local scatter */ ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&to);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); ierr = MatCreateVecs(A,&global,NULL);CHKERRQ(ierr); ierr = VecScatterCreate(global,from,is->x,to,&is->ctx);CHKERRQ(ierr); ierr = VecDestroy(&global);CHKERRQ(ierr); ierr = ISDestroy(&to);CHKERRQ(ierr); ierr = ISDestroy(&from);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode KSPSetUp_TSIRM(KSP ksp) { PetscErrorCode ierr; KSP_TSIRM *tsirm = (KSP_TSIRM*)ksp->data; PetscFunctionBegin; /* Initialization */ tsirm->tol_ls = 1e-40; tsirm->size_ls = 12; tsirm->maxiter_ls = 15; tsirm->cgls = 0; /* Matrix of the system */ ierr = KSPGetOperators(ksp,&tsirm->A,NULL); CHKERRQ(ierr); /* Matrix of the system */ ierr = MatGetSize(tsirm->A,&tsirm->size,NULL); CHKERRQ(ierr); /* Size of the system */ ierr = MatGetOwnershipRange(tsirm->A,&tsirm->Istart,&tsirm->Iend); CHKERRQ(ierr); /* Matrix S of residuals */ ierr = MatCreate(PETSC_COMM_WORLD,&tsirm->S); CHKERRQ(ierr); ierr = MatSetSizes(tsirm->S,tsirm->Iend-tsirm->Istart,PETSC_DECIDE,tsirm->size,tsirm->size_ls); CHKERRQ(ierr); ierr = MatSetType(tsirm->S,MATDENSE); CHKERRQ(ierr); ierr = MatSetUp(tsirm->S); CHKERRQ(ierr); /* Residual and vector Alpha computed in the minimization step */ ierr = MatCreateVecs(tsirm->S,&tsirm->Alpha,&tsirm->r); CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc, char **argv) { MPI_Comm comm; Mat A; /* A graph */ Vec c; /* A vector giving the component of each vertex */ Vec cold; /* The vector c from the last iteration */ PetscScalar *carray; PetscInt testnum = 0; PetscInt V, vStart, vEnd, v, n; PetscMPIInt size; PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, NULL,help);if (ierr) return ierr; comm = PETSC_COMM_WORLD; ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); /* Use matrix to encode a graph */ ierr = PetscOptionsGetInt(NULL,NULL, "-testnum", &testnum, NULL);CHKERRQ(ierr); ierr = CreateGraph(comm, testnum, &A);CHKERRQ(ierr); ierr = MatGetSize(A, &V, NULL);CHKERRQ(ierr); /* Replace matrix-vector multiplication with one that calculates the minimum rather than the sum */ if (size == 1) { ierr = MatShellSetOperation(A, MATOP_MULT, (void (*)) MatMultMax_SeqAIJ);CHKERRQ(ierr); } else { Mat_MPIAIJ *a = (Mat_MPIAIJ *) A->data; ierr = MatShellSetOperation(a->A, MATOP_MULT, (void (*)) MatMultMax_SeqAIJ);CHKERRQ(ierr); ierr = MatShellSetOperation(a->B, MATOP_MULT, (void (*)) MatMultMax_SeqAIJ);CHKERRQ(ierr); ierr = MatShellSetOperation(a->B, MATOP_MULT_ADD, (void (*)) MatMultAddMax_SeqAIJ);CHKERRQ(ierr); } /* Initialize each vertex as a separate component */ ierr = MatCreateVecs(A, &c, NULL);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A, &vStart, &vEnd);CHKERRQ(ierr); ierr = VecGetArray(c, &carray);CHKERRQ(ierr); for (v = vStart; v < vEnd; ++v) { carray[v-vStart] = v; } ierr = VecRestoreArray(c, &carray);CHKERRQ(ierr); /* Preprocess in parallel to find local components */ /* Multiply until c does not change */ ierr = VecDuplicate(c, &cold);CHKERRQ(ierr); for (v = 0; v < V; ++v) { Vec cnew = cold; PetscBool stop; ierr = MatMult(A, c, cnew);CHKERRQ(ierr); ierr = VecEqual(c, cnew, &stop);CHKERRQ(ierr); if (stop) break; cold = c; c = cnew; } /* Report */ ierr = VecUniqueEntries(c, &n, NULL);CHKERRQ(ierr); ierr = PetscPrintf(comm, "Components: %d Iterations: %d\n", n, v);CHKERRQ(ierr); ierr = VecView(c, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* Cleanup */ ierr = VecDestroy(&c);CHKERRQ(ierr); ierr = VecDestroy(&cold);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **args) { Mat A; Vec x; PetscErrorCode ierr; PetscViewer fd; /* viewer */ char file[PETSC_MAX_PATH_LEN]; /* input file name */ PetscReal norm; PetscBool flg; PetscInitialize(&argc,&args,(char*)0,help); /* Determine file from which we read the matrix A */ ierr = PetscOptionsGetString(NULL,"-f",file,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate binary file with the -f option"); /* Load matrix A */ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&fd);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatLoad(A,fd);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); ierr = MatCreateVecs(A,&x,NULL);CHKERRQ(ierr); ierr = MatGetDiagonal(A,x);CHKERRQ(ierr); ierr = VecScale(x,-1.0);CHKERRQ(ierr); ierr = MatDiagonalSet(A,x,ADD_VALUES);CHKERRQ(ierr); ierr = MatGetDiagonal(A,x);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm %g\n",(double)norm);CHKERRQ(ierr); /* Free data structures */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
/*@ PCMGGetRScale - Gets the pointwise scaling for the restriction operator from level l to l-1. Collective on PC Input Parameters: + pc - the multigrid context . rscale - the scaling - l - the level (0 is coarsest) to supply [Do not supply 0] Level: advanced Notes: When evaluating a function on a coarse level one does not want to do F(R * x) one does F(rscale * R * x) where rscale is 1 over the row sums of R. .keywords: MG, set, multigrid, restriction, level .seealso: PCMGSetInterpolation(), PCMGGetRestriction() @*/ PetscErrorCode PCMGGetRScale(PC pc,PetscInt l,Vec *rscale) { PetscErrorCode ierr; PC_MG *mg = (PC_MG*)pc->data; PC_MG_Levels **mglevels = mg->levels; PetscFunctionBegin; PetscValidHeaderSpecific(pc,PC_CLASSID,1); if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); if (l <= 0 || mg->nlevels <= l) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Level %D must be in range {1,...,%D}",l,mg->nlevels-1); if (!mglevels[l]->rscale) { Mat R; Vec X,Y,coarse,fine; PetscInt M,N; ierr = PCMGGetRestriction(pc,l,&R);CHKERRQ(ierr); ierr = MatCreateVecs(R,&X,&Y);CHKERRQ(ierr); ierr = MatGetSize(R,&M,&N);CHKERRQ(ierr); if (M < N) { fine = X; coarse = Y; } else if (N < M) { fine = Y; coarse = X; } else SETERRQ(PetscObjectComm((PetscObject)R),PETSC_ERR_SUP,"Restriction matrix is square, cannot determine which Vec is coarser"); ierr = VecSet(fine,1.);CHKERRQ(ierr); ierr = MatRestrict(R,fine,coarse);CHKERRQ(ierr); ierr = VecDestroy(&fine);CHKERRQ(ierr); ierr = VecReciprocal(coarse);CHKERRQ(ierr); mglevels[l]->rscale = coarse; } *rscale = mglevels[l]->rscale; PetscFunctionReturn(0); }
PETSC_EXTERN PetscErrorCode MatMFFDSetBase_MFFD(Mat J,Vec U,Vec F) { PetscErrorCode ierr; MatMFFD ctx = (MatMFFD)J->data; PetscFunctionBegin; ierr = MatMFFDResetHHistory(J);CHKERRQ(ierr); if (!ctx->current_u) { ierr = VecDuplicate(U,&ctx->current_u);CHKERRQ(ierr); ierr = VecLockReadPush(ctx->current_u);CHKERRQ(ierr); } ierr = VecLockReadPop(ctx->current_u);CHKERRQ(ierr); ierr = VecCopy(U,ctx->current_u);CHKERRQ(ierr); ierr = VecLockReadPush(ctx->current_u);CHKERRQ(ierr); if (F) { if (ctx->current_f_allocated) {ierr = VecDestroy(&ctx->current_f);CHKERRQ(ierr);} ctx->current_f = F; ctx->current_f_allocated = PETSC_FALSE; } else if (!ctx->current_f_allocated) { ierr = MatCreateVecs(J,NULL,&ctx->current_f);CHKERRQ(ierr); ctx->current_f_allocated = PETSC_TRUE; } if (!ctx->w) { ierr = VecDuplicate(ctx->current_u,&ctx->w);CHKERRQ(ierr); } J->assembled = PETSC_TRUE; PetscFunctionReturn(0); }
PetscErrorCode MatMultTranspose_Composite_Multiplicative(Mat A,Vec x,Vec y) { Mat_Composite *shell = (Mat_Composite*)A->data; Mat_CompositeLink tail = shell->tail; PetscErrorCode ierr; Vec in,out; PetscFunctionBegin; if (!tail) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); in = x; if (shell->left) { if (!shell->leftwork) { ierr = VecDuplicate(shell->left,&shell->leftwork);CHKERRQ(ierr); } ierr = VecPointwiseMult(shell->leftwork,shell->left,in);CHKERRQ(ierr); in = shell->leftwork; } while (tail->prev) { if (!tail->prev->work) { /* should reuse previous work if the same size */ ierr = MatCreateVecs(tail->mat,NULL,&tail->prev->work);CHKERRQ(ierr); } out = tail->prev->work; ierr = MatMultTranspose(tail->mat,in,out);CHKERRQ(ierr); in = out; tail = tail->prev; } ierr = MatMultTranspose(tail->mat,in,y);CHKERRQ(ierr); if (shell->right) { ierr = VecPointwiseMult(y,shell->right,y);CHKERRQ(ierr); } ierr = VecScale(y,shell->scale);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **args) { const PetscInt inds[] = {0,1}; PetscScalar avals[] = {2,3,5,7}; Mat S; User user; PetscErrorCode ierr; Vec base; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; ierr = PetscNew(&user);CHKERRQ(ierr); ierr = MatCreateSeqAIJ(PETSC_COMM_WORLD,2,2,2,NULL,&user->B);CHKERRQ(ierr); ierr = MatSetUp(user->B);CHKERRQ(ierr); ierr = MatSetValues(user->B,2,inds,2,inds,avals,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(user->B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(user->B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatCreateVecs(user->B,&base,NULL);CHKERRQ(ierr); ierr = MatCreateShell(PETSC_COMM_WORLD,2,2,2,2,user,&S);CHKERRQ(ierr); ierr = MatSetUp(S);CHKERRQ(ierr); ierr = MatShellSetOperation(S,MATOP_MULT,(void (*)(void))MatMult_User);CHKERRQ(ierr); ierr = MatShellSetOperation(S,MATOP_MULT_TRANSPOSE,(void (*)(void))MatMultTranspose_User);CHKERRQ(ierr); ierr = MatShellTestMult(S,MyFunction,base,user,NULL);CHKERRQ(ierr); ierr = MatShellTestMultTranspose(S,MyFunction,base,user,NULL);CHKERRQ(ierr); ierr = VecDestroy(&base);CHKERRQ(ierr); ierr = MatDestroy(&user->B);CHKERRQ(ierr); ierr = MatDestroy(&S);CHKERRQ(ierr); ierr = PetscFree(user);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
static void PETScMatvecGenNoBlock(void *x, PRIMME_INT ldx, void *y, PRIMME_INT ldy, int blockSize, int trans, Mat matrix, MPI_Comm comm) { int i; Vec xvec, yvec; PetscInt m, n, mLocal, nLocal; PetscErrorCode ierr; assert(sizeof(PetscScalar) == sizeof(SCALAR)); ierr = MatGetSize(matrix, &m, &n); CHKERRABORT(comm, ierr); ierr = MatGetLocalSize(matrix, &mLocal, &nLocal); CHKERRABORT(comm, ierr); #if PETSC_VERSION_LT(3,6,0) ierr = MatGetVecs(matrix, &xvec, &yvec); CHKERRABORT(comm, ierr); #else ierr = MatCreateVecs(matrix, &xvec, &yvec); CHKERRABORT(comm, ierr); #endif if (trans == 1) { Vec aux = xvec; xvec = yvec; yvec = aux; } for (i=0; i<blockSize; i++) { ierr = VecPlaceArray(xvec, ((SCALAR*)x) + ldx*i); CHKERRABORT(comm, ierr); ierr = VecPlaceArray(yvec, ((SCALAR*)y) + ldy*i); CHKERRABORT(comm, ierr); if (trans == 0) { ierr = MatMult(matrix, xvec, yvec); CHKERRABORT(comm, ierr); } else { ierr = MatMultHermitianTranspose(matrix, xvec, yvec); CHKERRABORT(comm, ierr); } ierr = VecResetArray(xvec); CHKERRABORT(comm, ierr); ierr = VecResetArray(yvec); CHKERRABORT(comm, ierr); } ierr = VecDestroy(&xvec); CHKERRABORT(comm, ierr); ierr = VecDestroy(&yvec); CHKERRABORT(comm, 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; PetscErrorCode ierr; PetscFunctionBegin; if (!sub_schurs->n_subs) { PetscFunctionReturn(0); } /* Create work vectors for sequential part of deluxe */ ierr = MatCreateVecs(sub_schurs->S_Ej_all,&deluxe_ctx->seq_work1,&deluxe_ctx->seq_work2);CHKERRQ(ierr); /* Compute deluxe sequential scatter */ if (sub_schurs->reuse_mumps && !sub_schurs->is_dir) { PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; ierr = PetscObjectReference((PetscObject)reuse_mumps->correction_scatter_B);CHKERRQ(ierr); deluxe_ctx->seq_scctx = reuse_mumps->correction_scatter_B; } else { ierr = VecScatterCreate(pcbddc->work_scaling,sub_schurs->is_Ej_all,deluxe_ctx->seq_work1,NULL,&deluxe_ctx->seq_scctx);CHKERRQ(ierr); } /* Create Mat object for deluxe scaling */ ierr = PetscObjectReference((PetscObject)sub_schurs->S_Ej_all);CHKERRQ(ierr); deluxe_ctx->seq_mat = sub_schurs->S_Ej_all; if (sub_schurs->sum_S_Ej_all) { /* if this matrix is present, then we need to create the KSP object to invert it */ PC pc_temp; MatSolverPackage solver=NULL; char ksp_prefix[256]; size_t len; ierr = KSPCreate(PETSC_COMM_SELF,&deluxe_ctx->seq_ksp);CHKERRQ(ierr); ierr = KSPSetOperators(deluxe_ctx->seq_ksp,sub_schurs->sum_S_Ej_all,sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); ierr = KSPSetType(deluxe_ctx->seq_ksp,KSPPREONLY);CHKERRQ(ierr); ierr = KSPGetPC(deluxe_ctx->seq_ksp,&pc_temp);CHKERRQ(ierr); ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); ierr = PCFactorGetMatSolverPackage(pc_temp,(const MatSolverPackage*)&solver);CHKERRQ(ierr); if (solver) { PC new_pc; PCType type; ierr = PCGetType(pc_temp,&type);CHKERRQ(ierr); ierr = KSPGetPC(deluxe_ctx->seq_ksp,&new_pc);CHKERRQ(ierr); ierr = PCSetType(new_pc,type);CHKERRQ(ierr); ierr = PCFactorSetMatSolverPackage(new_pc,solver);CHKERRQ(ierr); } ierr = PetscStrlen(((PetscObject)(pcbddc->ksp_D))->prefix,&len);CHKERRQ(ierr); len -= 10; /* remove "dirichlet_" */ ierr = PetscStrncpy(ksp_prefix,((PetscObject)(pcbddc->ksp_D))->prefix,len+1);CHKERRQ(ierr); ierr = PetscStrcat(ksp_prefix,"deluxe_");CHKERRQ(ierr); ierr = KSPSetOptionsPrefix(deluxe_ctx->seq_ksp,ksp_prefix);CHKERRQ(ierr); ierr = KSPSetFromOptions(deluxe_ctx->seq_ksp);CHKERRQ(ierr); ierr = KSPSetUp(deluxe_ctx->seq_ksp);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode MatMult_SchurComplement(Mat N,Vec x,Vec y) { Mat_SchurComplement *Na = (Mat_SchurComplement*)N->data; PetscErrorCode ierr; PetscFunctionBegin; if (!Na->work1) {ierr = MatCreateVecs(Na->A,&Na->work1,NULL);CHKERRQ(ierr);} if (!Na->work2) {ierr = MatCreateVecs(Na->A,&Na->work2,NULL);CHKERRQ(ierr);} ierr = MatMult(Na->B,x,Na->work1);CHKERRQ(ierr); ierr = KSPSolve(Na->ksp,Na->work1,Na->work2);CHKERRQ(ierr); ierr = MatMult(Na->C,Na->work2,y);CHKERRQ(ierr); ierr = VecScale(y,-1.0);CHKERRQ(ierr); if (Na->D) { ierr = MatMultAdd(Na->D,x,y,y);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode MatCreateVecs_SchurComplement(Mat N,Vec *right,Vec *left) { Mat_SchurComplement *Na = (Mat_SchurComplement*)N->data; PetscErrorCode ierr; PetscFunctionBegin; if (Na->D) { ierr = MatCreateVecs(Na->D,right,left);CHKERRQ(ierr); PetscFunctionReturn(0); } if (right) { ierr = MatCreateVecs(Na->B,right,NULL);CHKERRQ(ierr); } if (left) { ierr = MatCreateVecs(Na->C,NULL,left);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode MatCreateVecs_Transpose(Mat A,Vec *r, Vec *l) { Mat_Transpose *Aa = (Mat_Transpose*)A->data; PetscErrorCode ierr; PetscFunctionBegin; ierr = MatCreateVecs(Aa->A,l,r);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode MatCreateVecs_HT(Mat N,Vec *r, Vec *l) { Mat_HT *Na = (Mat_HT*)N->data; PetscErrorCode ierr; PetscFunctionBegin; ierr = MatCreateVecs(Na->A,l,r);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode SolveFinal(FEMInf fem, int L1, PetscScalar energy, Vec x0, Vec *x1, PetscScalar *alpha) { PetscErrorCode ierr; Mat S, L, D; CalcMat(fem, L1, &L, &S); MatAXPY(L, -energy, S, DIFFERENT_NONZERO_PATTERN); MatDestroy(&S); PetscScalar mat_ele_cos; // <Y_10 | P_q(cos theta) | Y_00> mat_ele_cos = Y1ElePq(1, 1, 0, 0, 0); if(getenv("SHOW_DEBUG")) printf("mat_ele_cos = %f\n", PetscRealPart(mat_ele_cos)); PF dp_length; PotCreate(PETSC_COMM_SELF, &dp_length); ierr = PotSetPower(dp_length, mat_ele_cos, 1); CHKERRQ(ierr); ierr =FEMInfCreateMat(fem, 1, &D); ierr = FEMInfPotR1Mat(fem, dp_length, D); CHKERRQ(ierr); Vec driv; MatCreateVecs(L, &driv, NULL); ierr = MatMult(D, x0, driv); CHKERRQ(ierr); ierr = MatDestroy(&D); CHKERRQ(ierr); KSP ksp; ierr = KSPCreate(fem->comm, &ksp); CHKERRQ(ierr); ierr = KSPSetOperators(ksp, L, L); CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp); CHKERRQ(ierr); ierr = MatCreateVecs(L, x1, NULL); ierr = KSPSolve(ksp, driv, *x1); CHKERRQ(ierr); ierr = VecDot(*x1, driv, alpha); CHKERRQ(ierr); // KSPView(ksp, PETSC_VIEWER_STDOUT_SELF); KSPDestroy(&ksp); MatDestroy(&L); VecDestroy(&driv); return 0; }
/*@ MatComputeExplicitOperatorTranspose - Computes the explicit matrix representation of a give matrix that can apply MatMultTranspose() Collective on Mat Input Parameter: . inmat - the matrix Output Parameter: . mat - the explict operator transposed Notes: This computation is done by applying the transpose of the operator to columns of the identity matrix. Currently, this routine uses a dense matrix format when 1 processor is used and a sparse format otherwise. This routine is costly in general, and is recommended for use only with relatively small systems. Level: advanced .keywords: Mat, compute, explicit, operator @*/ PetscErrorCode MatComputeExplicitOperatorTranspose(Mat inmat,Mat *mat) { Vec in,out; PetscErrorCode ierr; PetscInt i,m,n,M,N,*rows,start,end; MPI_Comm comm; PetscScalar *array,zero = 0.0,one = 1.0; PetscMPIInt size; PetscFunctionBegin; PetscValidHeaderSpecific(inmat,MAT_CLASSID,1); PetscValidPointer(mat,2); ierr = PetscObjectGetComm((PetscObject)inmat,&comm);CHKERRQ(ierr); ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); ierr = MatGetLocalSize(inmat,&m,&n);CHKERRQ(ierr); ierr = MatGetSize(inmat,&M,&N);CHKERRQ(ierr); ierr = MatCreateVecs(inmat,&in,&out);CHKERRQ(ierr); ierr = VecSetOption(in,VEC_IGNORE_OFF_PROC_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); ierr = VecGetOwnershipRange(out,&start,&end);CHKERRQ(ierr); ierr = PetscMalloc1(m,&rows);CHKERRQ(ierr); for (i=0; i<m; i++) rows[i] = start + i; ierr = MatCreate(comm,mat);CHKERRQ(ierr); ierr = MatSetSizes(*mat,m,n,M,N);CHKERRQ(ierr); if (size == 1) { ierr = MatSetType(*mat,MATSEQDENSE);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(*mat,NULL);CHKERRQ(ierr); } else { ierr = MatSetType(*mat,MATMPIAIJ);CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(*mat,n,NULL,N-n,NULL);CHKERRQ(ierr); } for (i=0; i<N; i++) { ierr = VecSet(in,zero);CHKERRQ(ierr); ierr = VecSetValues(in,1,&i,&one,INSERT_VALUES);CHKERRQ(ierr); ierr = VecAssemblyBegin(in);CHKERRQ(ierr); ierr = VecAssemblyEnd(in);CHKERRQ(ierr); ierr = MatMultTranspose(inmat,in,out);CHKERRQ(ierr); ierr = VecGetArray(out,&array);CHKERRQ(ierr); ierr = MatSetValues(*mat,m,rows,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); ierr = VecRestoreArray(out,&array);CHKERRQ(ierr); } ierr = PetscFree(rows);CHKERRQ(ierr); ierr = VecDestroy(&out);CHKERRQ(ierr); ierr = VecDestroy(&in);CHKERRQ(ierr); ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode PCSetUp_Jacobi_NonSymmetric(PC pc) { PetscErrorCode ierr; PC_Jacobi *jac = (PC_Jacobi*)pc->data; PetscFunctionBegin; ierr = MatCreateVecs(pc->pmat,&jac->diag,0);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)jac->diag);CHKERRQ(ierr); ierr = PCSetUp_Jacobi(pc);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ SNESFASCreateCoarseVec - create Vec corresponding to a state vector on one level coarser than current level Collective Input Arguments: . snes - SNESFAS Output Arguments: . Xcoarse - vector on level one coarser than snes Level: developer .seealso: SNESFASSetRestriction(), SNESFASRestrict() @*/ PetscErrorCode SNESFASCreateCoarseVec(SNES snes,Vec *Xcoarse) { PetscErrorCode ierr; SNES_FAS *fas = (SNES_FAS*)snes->data; PetscFunctionBegin; if (fas->rscale) { ierr = VecDuplicate(fas->rscale,Xcoarse);CHKERRQ(ierr); } else if (fas->inject) { ierr = MatCreateVecs(fas->inject,Xcoarse,NULL);CHKERRQ(ierr); } else SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONGSTATE,"Must set restriction or injection");CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ MatCreateSchurComplementPmat - create a preconditioning matrix for the Schur complement by assembling Sp = A11 - A10 inv(diag(A00)) A01 Collective on Mat Input Parameters: + A00,A01,A10,A11 - the four parts of the original matrix A = [A00 A01; A10 A11] (A01,A10, and A11 are optional, implying zero matrices) . ainvtype - type of approximation for inv(A00) used when forming Sp = A11 - A10 inv(A00) A01 - preuse - MAT_INITIAL_MATRIX for a new Sp, or MAT_REUSE_MATRIX to reuse an existing Sp, or MAT_IGNORE_MATRIX to put nothing in Sp Output Parameter: - Spmat - approximate Schur complement suitable for preconditioning S = A11 - A10 inv(diag(A00)) A01 Note: Since the real Schur complement is usually dense, providing a good approximation to newpmat usually requires application-specific information. The default for assembled matrices is to use the inverse of the diagonal of the (0,0) block A00 in place of A00^{-1}. This rarely produce a scalable algorithm. Optionally, A00 can be lumped before forming inv(diag(A00)). Level: advanced Concepts: matrices^submatrices .seealso: MatCreateSchurComplement(), MatGetSchurComplement(), MatSchurComplementGetPmat(), MatSchurComplementAinvType @*/ PetscErrorCode MatCreateSchurComplementPmat(Mat A00,Mat A01,Mat A10,Mat A11,MatSchurComplementAinvType ainvtype,MatReuse preuse,Mat *Spmat) { PetscErrorCode ierr; PetscInt N00; PetscFunctionBegin; /* Use an appropriate approximate inverse of A00 to form A11 - A10 inv(diag(A00)) A01; a NULL A01, A10 or A11 indicates a zero matrix. */ /* TODO: Perhaps should create an appropriately-sized zero matrix of the same type as A00? */ if ((!A01 || !A10) & !A11) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot assemble Spmat: A01, A10 and A11 are all NULL."); if (preuse == MAT_IGNORE_MATRIX) PetscFunctionReturn(0); /* A zero size A00 or empty A01 or A10 imply S = A11. */ ierr = MatGetSize(A00,&N00,NULL);CHKERRQ(ierr); if (!A01 || !A10 || !N00) { if (preuse == MAT_INITIAL_MATRIX) { ierr = MatDuplicate(A11,MAT_COPY_VALUES,Spmat);CHKERRQ(ierr); } else { /* MAT_REUSE_MATRIX */ /* TODO: when can we pass SAME_NONZERO_PATTERN? */ ierr = MatCopy(A11,*Spmat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); } } else { Mat AdB; Vec diag; ierr = MatCreateVecs(A00,&diag,NULL);CHKERRQ(ierr); if (ainvtype == MAT_SCHUR_COMPLEMENT_AINV_LUMP) { ierr = MatGetRowSum(A00,diag);CHKERRQ(ierr); } else if (ainvtype == MAT_SCHUR_COMPLEMENT_AINV_DIAG) { ierr = MatGetDiagonal(A00,diag);CHKERRQ(ierr); } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown MatSchurComplementAinvType: %D", ainvtype); ierr = VecReciprocal(diag);CHKERRQ(ierr); ierr = MatDuplicate(A01,MAT_COPY_VALUES,&AdB);CHKERRQ(ierr); ierr = MatDiagonalScale(AdB,diag,NULL);CHKERRQ(ierr); ierr = VecDestroy(&diag);CHKERRQ(ierr); /* Cannot really reuse Spmat in MatMatMult() because of MatAYPX() --> MatAXPY() --> MatHeaderReplace() --> MatDestroy_XXX_MatMatMult() */ ierr = MatDestroy(Spmat);CHKERRQ(ierr); ierr = MatMatMult(A10,AdB,MAT_INITIAL_MATRIX,PETSC_DEFAULT,Spmat);CHKERRQ(ierr); if (!A11) { ierr = MatScale(*Spmat,-1.0);CHKERRQ(ierr); } else { /* TODO: when can we pass SAME_NONZERO_PATTERN? */ ierr = MatAYPX(*Spmat,-1,A11,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); } ierr = MatDestroy(&AdB);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode PCLSCAllocate_Private(PC pc) { PC_LSC *lsc = (PC_LSC*)pc->data; Mat A; PetscErrorCode ierr; PetscFunctionBegin; if (lsc->allocated) PetscFunctionReturn(0); ierr = KSPCreate(PetscObjectComm((PetscObject)pc),&lsc->kspL);CHKERRQ(ierr); ierr = KSPSetErrorIfNotConverged(lsc->kspL,pc->erroriffailure);CHKERRQ(ierr); ierr = PetscObjectIncrementTabLevel((PetscObject)lsc->kspL,(PetscObject)pc,1);CHKERRQ(ierr); ierr = KSPSetType(lsc->kspL,KSPPREONLY);CHKERRQ(ierr); ierr = KSPSetOptionsPrefix(lsc->kspL,((PetscObject)pc)->prefix);CHKERRQ(ierr); ierr = KSPAppendOptionsPrefix(lsc->kspL,"lsc_");CHKERRQ(ierr); ierr = MatSchurComplementGetSubMatrices(pc->mat,&A,NULL,NULL,NULL,NULL);CHKERRQ(ierr); ierr = MatCreateVecs(A,&lsc->x0,&lsc->y0);CHKERRQ(ierr); ierr = MatCreateVecs(pc->pmat,&lsc->x1,NULL);CHKERRQ(ierr); if (lsc->scalediag) { ierr = VecDuplicate(lsc->x0,&lsc->scale);CHKERRQ(ierr); } lsc->allocated = PETSC_TRUE; PetscFunctionReturn(0); }
int main(int argc,char **args) { KSP ksp; /* linear solver context */ Mat A; /* linear system matrix */ Vec x,b; /* approx solution, RHS */ PetscInt Ii,Istart,Iend; PetscErrorCode ierr; PetscScalar v[3] = {-1./2., 1., -1./2.}; PetscInt j[3]; PetscInt k=15; PetscInt M,m=420; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; ierr = PetscOptionsGetInt(NULL,NULL,"-k",&k,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL);CHKERRQ(ierr); ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = KSPGetOperators(ksp,&A,NULL);CHKERRQ(ierr); ierr = MatSetSizes(A,m,m,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A,&Istart,&Iend);CHKERRQ(ierr); ierr = MatGetSize(A,&M,NULL);CHKERRQ(ierr); for (Ii=Istart; Ii<Iend; Ii++) { j[0] = Ii - k; j[1] = Ii; j[2] = (Ii + k) < M ? (Ii + k) : -1; ierr = MatSetValues(A,1,&Ii,3,j,v,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr); ierr = VecSetFromOptions(b);CHKERRQ(ierr); ierr = VecSet(b,1.0);CHKERRQ(ierr); ierr = VecSetFromOptions(x);CHKERRQ(ierr); ierr = VecSet(x,2.0);CHKERRQ(ierr); ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc, char **argv) { PetscErrorCode ierr; Mat A; KSP ksp; PC pc; IS zero, one; MatNullSpace nullsp; Vec x, b; MPI_Comm comm; PetscInitialize(&argc, &argv, NULL, NULL); comm = PETSC_COMM_WORLD; ierr = MatCreate(comm, &A);CHKERRQ(ierr); ierr = MatSetSizes(A, 4, 4, PETSC_DECIDE, PETSC_DECIDE);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatCreateVecs(A, &x, &b);CHKERRQ(ierr); ierr = VecSet(x, 2.0);CHKERRQ(ierr); ierr = VecSet(b, 12.0);CHKERRQ(ierr); ierr = MatDiagonalSet(A, x, INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = ISCreateStride(comm, 2, 0, 1, &zero);CHKERRQ(ierr); ierr = ISCreateStride(comm, 2, 2, 1, &one);CHKERRQ(ierr); ierr = MatNullSpaceCreate(comm, PETSC_TRUE, 0, NULL, &nullsp);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject)zero, "nullspace",(PetscObject)nullsp);CHKERRQ(ierr); ierr = KSPCreate(comm, &ksp);CHKERRQ(ierr); ierr = KSPSetOperators(ksp, A, A);CHKERRQ(ierr); ierr = KSPSetUp(ksp);CHKERRQ(ierr); ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = PCFieldSplitSetIS(pc, "0", zero); ierr = PCFieldSplitSetIS(pc, "1", one); ierr = KSPSolve(ksp, b, x);CHKERRQ(ierr); ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = MatNullSpaceDestroy(&nullsp);CHKERRQ(ierr); ierr = ISDestroy(&zero);CHKERRQ(ierr); ierr = ISDestroy(&one);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); PetscFinalize(); return 0; }
int main(int argc,char **args) { KSP ksp; Mat A; Vec x,b; PetscViewer fd; char file[PETSC_MAX_PATH_LEN]; PetscErrorCode ierr; PetscBool flg,preload = PETSC_TRUE; PetscInitialize(&argc,&args,(char*)0,help); ierr = PetscLogDefaultBegin();CHKERRQ(ierr); ierr = PetscOptionsGetString(NULL,NULL,"-f",file,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); PetscPreLoadBegin(preload,"Load system"); /* Load the matrix and vector; then destroy the viewer. */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&fd);CHKERRQ(ierr); ierr = MatLoad(A,fd);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr); ierr = VecSetFromOptions(b);CHKERRQ(ierr); ierr = VecSet(b,1.0);CHKERRQ(ierr); ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = KSPSetOperators(ksp,A,A);CHKERRQ(ierr); ierr = KSPSetUp(ksp);CHKERRQ(ierr); ierr = KSPSetUpOnBlocks(ksp);CHKERRQ(ierr); PetscPreLoadStage("KSPSolve"); ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = KSPDestroy(&ksp);CHKERRQ(ierr); PetscPreLoadEnd(); ierr = PetscLogView_VecScatter(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
static PetscErrorCode PCSetUp_CP(PC pc) { PC_CP *cp = (PC_CP*)pc->data; PetscInt i,j,*colcnt; PetscErrorCode ierr; PetscBool flg; Mat_SeqAIJ *aij = (Mat_SeqAIJ*)pc->pmat->data; PetscFunctionBegin; ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATSEQAIJ,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Currently only handles SeqAIJ matrices"); ierr = MatGetLocalSize(pc->pmat,&cp->m,&cp->n);CHKERRQ(ierr); if (cp->m != cp->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Currently only for square matrices"); if (!cp->work) {ierr = MatCreateVecs(pc->pmat,&cp->work,NULL);CHKERRQ(ierr);} if (!cp->d) {ierr = PetscMalloc1(cp->n,&cp->d);CHKERRQ(ierr);} if (cp->a && pc->flag != SAME_NONZERO_PATTERN) { ierr = PetscFree3(cp->a,cp->i,cp->j);CHKERRQ(ierr); cp->a = 0; } /* convert to column format */ if (!cp->a) { ierr = PetscMalloc3(aij->nz,&cp->a,cp->n+1,&cp->i,aij->nz,&cp->j);CHKERRQ(ierr); } ierr = PetscCalloc1(cp->n,&colcnt);CHKERRQ(ierr); for (i=0; i<aij->nz; i++) colcnt[aij->j[i]]++; cp->i[0] = 0; for (i=0; i<cp->n; i++) cp->i[i+1] = cp->i[i] + colcnt[i]; ierr = PetscMemzero(colcnt,cp->n*sizeof(PetscInt));CHKERRQ(ierr); for (i=0; i<cp->m; i++) { /* over rows */ for (j=aij->i[i]; j<aij->i[i+1]; j++) { /* over columns in row */ cp->j[cp->i[aij->j[j]]+colcnt[aij->j[j]]] = i; cp->a[cp->i[aij->j[j]]+colcnt[aij->j[j]]++] = aij->a[j]; } } ierr = PetscFree(colcnt);CHKERRQ(ierr); /* compute sum of squares of each column d[] */ for (i=0; i<cp->n; i++) { /* over columns */ cp->d[i] = 0.; for (j=cp->i[i]; j<cp->i[i+1]; j++) cp->d[i] += cp->a[j]*cp->a[j]; /* over rows in column */ cp->d[i] = 1.0/cp->d[i]; } PetscFunctionReturn(0); }
static PetscErrorCode PCSetUp_Composite(PC pc) { PetscErrorCode ierr; PC_Composite *jac = (PC_Composite*)pc->data; PC_CompositeLink next = jac->head; PetscFunctionBegin; if (!jac->work1) { ierr = MatCreateVecs(pc->pmat,&jac->work1,0);CHKERRQ(ierr); } while (next) { ierr = PCSetOperators(next->pc,pc->mat,pc->pmat);CHKERRQ(ierr); next = next->next; } PetscFunctionReturn(0); }
// Test Mat BNHat up to N=10 when Op is a diagonal Mat TEST(operatorsCreateBnHeadTest, testBNHatDiagonalOp) { Mat Op; // operator (e.g., Laplacian) PetscReal dt = 2.3, // time-step size c = 0.5, // time-scheme coefficient of the implicit diffusive term val = 2.0 / dt; // value set on the diagonal of the operator PetscInt nx = 10, // number of points in the x-direction ny = 12; // number of points in the y-direction PetscReal ans = nx * ny * dt; // expected sum of all elements of B1Hat // Create and assemble operator MatCreate(PETSC_COMM_WORLD, &Op); MatSetSizes(Op, PETSC_DECIDE, PETSC_DECIDE, nx * ny, nx * ny); MatSetType(Op, MATAIJ); MatSetUp(Op); for (PetscInt i = 0; i < nx * ny; i++) MatSetValues(Op, 1, &i, 1, &i, &val, INSERT_VALUES); MatAssemblyBegin(Op, MAT_FINAL_ASSEMBLY); MatAssemblyEnd(Op, MAT_FINAL_ASSEMBLY); for (PetscInt N = 1; N <= 10; N++) { Mat BNHat; // Nth-order approximation of the inverse of (I/dt - c*Op) // Call function to test petibm::operators::createBnHead(Op, dt, c, N, BNHat); // Check size of Mat BNHat { PetscInt nrows, ncols; MatGetSize(BNHat, &nrows, &ncols); ASSERT_EQ(nx * ny, nrows); ASSERT_EQ(nx * ny, ncols); } // Check sum of elements of BNHat is the expected value if (N > 1) ans += dt * nx * ny * std::pow(c * dt * val, N - 1); { PetscReal sum; Vec v; MatCreateVecs(Op, &v, nullptr); MatGetRowSum(BNHat, v); VecSum(v, &sum); ASSERT_TRUE(std::abs(sum - ans) <= 1.0E-11); VecDestroy(&v); } MatDestroy(&BNHat); } MatDestroy(&Op); }
static PetscErrorCode KSPSetUp_GCR(KSP ksp) { KSP_GCR *ctx = (KSP_GCR*)ksp->data; PetscErrorCode ierr; Mat A; PetscBool diagonalscale; PetscFunctionBegin; ierr = PCGetDiagonalScale(ksp->pc,&diagonalscale);CHKERRQ(ierr); if (diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"Krylov method %s does not support diagonal scaling",((PetscObject)ksp)->type_name); ierr = KSPGetOperators(ksp, &A, NULL);CHKERRQ(ierr); ierr = MatCreateVecs(A, &ctx->R, NULL);CHKERRQ(ierr); ierr = VecDuplicateVecs(ctx->R, ctx->restart, &ctx->VV);CHKERRQ(ierr); ierr = VecDuplicateVecs(ctx->R, ctx->restart, &ctx->SS);CHKERRQ(ierr); ierr = PetscMalloc1(ctx->restart, &ctx->val);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* PCGAMGGetDataWithGhosts - hacks into Mat MPIAIJ so this must have size > 1 Input Parameter: . Gmat - MPIAIJ matrix for scattters . data_sz - number of data terms per node (# cols in output) . data_in[nloc*data_sz] - column oriented data Output Parameter: . a_stride - numbrt of rows of output . a_data_out[stride*data_sz] - output data with ghosts */ PetscErrorCode PCGAMGGetDataWithGhosts(Mat Gmat,PetscInt data_sz,PetscReal data_in[],PetscInt *a_stride,PetscReal **a_data_out) { PetscErrorCode ierr; Vec tmp_crds; Mat_MPIAIJ *mpimat = (Mat_MPIAIJ*)Gmat->data; PetscInt nnodes,num_ghosts,dir,kk,jj,my0,Iend,nloc; PetscScalar *data_arr; PetscReal *datas; PetscBool isMPIAIJ; PetscFunctionBegin; ierr = PetscObjectBaseTypeCompare((PetscObject)Gmat, MATMPIAIJ, &isMPIAIJ);CHKERRQ(ierr); ierr = MatGetOwnershipRange(Gmat, &my0, &Iend);CHKERRQ(ierr); nloc = Iend - my0; ierr = VecGetLocalSize(mpimat->lvec, &num_ghosts);CHKERRQ(ierr); nnodes = num_ghosts + nloc; *a_stride = nnodes; ierr = MatCreateVecs(Gmat, &tmp_crds, 0);CHKERRQ(ierr); ierr = PetscMalloc1(data_sz*nnodes, &datas);CHKERRQ(ierr); for (dir=0; dir<data_sz; dir++) { /* set local, and global */ for (kk=0; kk<nloc; kk++) { PetscInt gid = my0 + kk; PetscScalar crd = (PetscScalar)data_in[dir*nloc + kk]; /* col oriented */ datas[dir*nnodes + kk] = PetscRealPart(crd); ierr = VecSetValues(tmp_crds, 1, &gid, &crd, INSERT_VALUES);CHKERRQ(ierr); } ierr = VecAssemblyBegin(tmp_crds);CHKERRQ(ierr); ierr = VecAssemblyEnd(tmp_crds);CHKERRQ(ierr); /* get ghost datas */ ierr = VecScatterBegin(mpimat->Mvctx,tmp_crds,mpimat->lvec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(mpimat->Mvctx,tmp_crds,mpimat->lvec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecGetArray(mpimat->lvec, &data_arr);CHKERRQ(ierr); for (kk=nloc,jj=0;jj<num_ghosts;kk++,jj++) datas[dir*nnodes + kk] = PetscRealPart(data_arr[jj]); ierr = VecRestoreArray(mpimat->lvec, &data_arr);CHKERRQ(ierr); } ierr = VecDestroy(&tmp_crds);CHKERRQ(ierr); *a_data_out = datas; PetscFunctionReturn(0); }