/*@ BVMultVec - Computes y = beta*y + alpha*X*q. Logically Collective on BV and Vec Input Parameters: + X - a basis vectors object . alpha,beta - scalars . y - a vector - q - an array of scalars Output Parameter: . y - the modified vector Notes: This operation is the analogue of BVMult() but with a BV and a Vec, instead of two BV. Note that arguments are listed in different order with respect to BVMult(). If X has leading columns specified, then these columns do not participate in the computation. The length of array q must be equal to the number of active columns of X minus the number of leading columns, i.e. the first entry of q multiplies the first non-leading column. Level: intermediate .seealso: BVMult(), BVMultColumn(), BVMultInPlace(), BVSetActiveColumns() @*/ PetscErrorCode BVMultVec(BV X,PetscScalar alpha,PetscScalar beta,Vec y,PetscScalar *q) { PetscErrorCode ierr; PetscInt n,N; PetscFunctionBegin; PetscValidHeaderSpecific(X,BV_CLASSID,1); PetscValidLogicalCollectiveScalar(X,alpha,2); PetscValidLogicalCollectiveScalar(X,beta,3); PetscValidHeaderSpecific(y,VEC_CLASSID,4); PetscValidPointer(q,5); PetscValidType(X,1); BVCheckSizes(X,1); PetscValidType(y,4); PetscCheckSameComm(X,1,y,4); ierr = VecGetSize(y,&N);CHKERRQ(ierr); ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr); if (N!=X->N || n!=X->n) SETERRQ4(PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_INCOMP,"Vec sizes (global %D, local %D) do not match BV sizes (global %D, local %D)",N,n,X->N,X->n); if (!X->n) PetscFunctionReturn(0); ierr = PetscLogEventBegin(BV_Mult,X,y,0,0);CHKERRQ(ierr); ierr = (*X->ops->multvec)(X,alpha,beta,y,q);CHKERRQ(ierr); ierr = PetscLogEventEnd(BV_Mult,X,y,0,0);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ BVOrthogonalizeVec - Orthogonalize a given vector with respect to all active columns. Collective on BV Input Parameters: + bv - the basis vectors context - v - the vector Output Parameters: + H - (optional) coefficients computed during orthogonalization . norm - (optional) norm of the vector after being orthogonalized - lindep - (optional) flag indicating that refinement did not improve the quality of orthogonalization Notes: This function is equivalent to BVOrthogonalizeColumn() but orthogonalizes a vector as an argument rather than taking one of the BV columns. The vector is orthogonalized against all active columns. Level: advanced .seealso: BVOrthogonalizeColumn(), BVSetOrthogonalization(), BVSetActiveColumns() @*/ PetscErrorCode BVOrthogonalizeVec(BV bv,Vec v,PetscScalar *H,PetscReal *norm,PetscBool *lindep) { PetscErrorCode ierr; PetscInt i,ksave,lsave; PetscFunctionBegin; PetscValidHeaderSpecific(bv,BV_CLASSID,1); PetscValidHeaderSpecific(v,VEC_CLASSID,2); PetscValidType(bv,1); BVCheckSizes(bv,1); PetscValidType(v,2); PetscCheckSameComm(bv,1,v,2); ierr = PetscLogEventBegin(BV_Orthogonalize,bv,0,0,0);CHKERRQ(ierr); ksave = bv->k; lsave = bv->l; bv->l = -bv->nc; /* must also orthogonalize against constraints and leading columns */ ierr = BV_AllocateCoeffs(bv);CHKERRQ(ierr); ierr = BV_AllocateSignature(bv);CHKERRQ(ierr); switch (bv->orthog_type) { case BV_ORTHOG_CGS: ierr = BVOrthogonalizeCGS(bv,0,v,H,norm,lindep);CHKERRQ(ierr); break; case BV_ORTHOG_MGS: ierr = BVOrthogonalizeMGS(bv,0,v,NULL,H,norm,lindep);CHKERRQ(ierr); break; } bv->k = ksave; bv->l = lsave; if (H) for (i=bv->l;i<bv->k;i++) H[i-bv->l] = bv->h[bv->nc+i]; ierr = PetscLogEventEnd(BV_Orthogonalize,bv,0,0,0);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ BVMultInPlaceTranspose - Update a set of vectors as V(:,s:e-1) = V*Q'(:,s:e-1). Logically Collective on BV Input Parameters: + Q - a sequential dense matrix . s - first column of V to be overwritten - e - first column of V not to be overwritten Input/Output Parameter: + V - basis vectors Notes: This is a variant of BVMultInPlace() where the conjugate transpose of Q is used. Level: intermediate .seealso: BVMultInPlace() @*/ PetscErrorCode BVMultInPlaceTranspose(BV V,Mat Q,PetscInt s,PetscInt e) { PetscErrorCode ierr; PetscBool match; PetscInt m,n; PetscFunctionBegin; PetscValidHeaderSpecific(V,BV_CLASSID,1); PetscValidHeaderSpecific(Q,MAT_CLASSID,2); PetscValidLogicalCollectiveInt(V,s,3); PetscValidLogicalCollectiveInt(V,e,4); PetscValidType(V,1); BVCheckSizes(V,1); PetscValidType(Q,2); ierr = PetscObjectTypeCompare((PetscObject)Q,MATSEQDENSE,&match);CHKERRQ(ierr); if (!match) SETERRQ(PetscObjectComm((PetscObject)V),PETSC_ERR_SUP,"Mat argument must be of type seqdense"); if (s<V->l || s>V->m) SETERRQ3(PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_OUTOFRANGE,"Argument s has wrong value %D, should be between %D and %D",s,V->l,V->m); if (e<V->l || e>V->m) SETERRQ3(PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_OUTOFRANGE,"Argument e has wrong value %D, should be between %D and %D",e,V->l,V->m); ierr = MatGetSize(Q,&m,&n);CHKERRQ(ierr); if (n<V->k) SETERRQ2(PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_SIZ,"Mat argument has %D columns, should have at least %D",n,V->k); if (e>m) SETERRQ2(PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_SIZ,"Mat argument only has %D rows, the requested value of e is larger: %D",m,e); if (s>=e || !V->n) PetscFunctionReturn(0); ierr = PetscLogEventBegin(BV_Mult,V,Q,0,0);CHKERRQ(ierr); ierr = (*V->ops->multinplacetrans)(V,Q,s,e);CHKERRQ(ierr); ierr = PetscLogEventEnd(BV_Mult,V,Q,0,0);CHKERRQ(ierr); ierr = PetscObjectStateIncrease((PetscObject)V);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ BVMult - Computes Y = beta*Y + alpha*X*Q. Logically Collective on BV Input Parameters: + Y,X - basis vectors . alpha,beta - scalars - Q - a sequential dense matrix Output Parameter: . Y - the modified basis vectors Notes: X and Y must be different objects. The case X=Y can be addressed with BVMultInPlace(). The matrix Q must be a sequential dense Mat, with all entries equal on all processes (otherwise each process will compute a different update). The dimensions of Q must be at least m,n where m is the number of active columns of X and n is the number of active columns of Y. The leading columns of Y are not modified. Also, if X has leading columns specified, then these columns do not participate in the computation. Hence, only rows (resp. columns) of Q starting from lx (resp. ly) are used, where lx (resp. ly) is the number of leading columns of X (resp. Y). Level: intermediate .seealso: BVMultVec(), BVMultColumn(), BVMultInPlace(), BVSetActiveColumns() @*/ PetscErrorCode BVMult(BV Y,PetscScalar alpha,PetscScalar beta,BV X,Mat Q) { PetscErrorCode ierr; PetscBool match; PetscInt m,n; PetscFunctionBegin; PetscValidHeaderSpecific(Y,BV_CLASSID,1); PetscValidLogicalCollectiveScalar(Y,alpha,2); PetscValidLogicalCollectiveScalar(Y,beta,3); PetscValidHeaderSpecific(X,BV_CLASSID,4); PetscValidHeaderSpecific(Q,MAT_CLASSID,5); PetscValidType(Y,1); BVCheckSizes(Y,1); PetscValidType(X,4); BVCheckSizes(X,4); PetscValidType(Q,5); PetscCheckSameTypeAndComm(Y,1,X,4); if (X==Y) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_ARG_WRONG,"X and Y arguments must be different"); ierr = PetscObjectTypeCompare((PetscObject)Q,MATSEQDENSE,&match);CHKERRQ(ierr); if (!match) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_SUP,"Mat argument must be of type seqdense"); ierr = MatGetSize(Q,&m,&n);CHKERRQ(ierr); if (m<X->k) SETERRQ2(PetscObjectComm((PetscObject)Y),PETSC_ERR_ARG_SIZ,"Mat argument has %D rows, should have at least %D",m,X->k); if (n<Y->k) SETERRQ2(PetscObjectComm((PetscObject)Y),PETSC_ERR_ARG_SIZ,"Mat argument has %D columns, should have at least %D",n,Y->k); if (X->n!=Y->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Mismatching local dimension X %D, Y %D",X->n,Y->n); if (!X->n) PetscFunctionReturn(0); ierr = PetscLogEventBegin(BV_Mult,X,Y,0,0);CHKERRQ(ierr); ierr = (*Y->ops->mult)(Y,alpha,beta,X,Q);CHKERRQ(ierr); ierr = PetscLogEventEnd(BV_Mult,X,Y,0,0);CHKERRQ(ierr); ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ BVOrthogonalize - Orthogonalize all columns (except leading ones), that is, compute the QR decomposition. Collective on BV Input Parameter: . V - basis vectors Output Parameters: + V - the modified basis vectors - R - a sequential dense matrix (or NULL) Notes: On input, matrix R must be a sequential dense Mat, with at least as many rows and columns as the number of active columns of V. The output satisfies V0 = V*R (where V0 represent the input V) and V'*V = I. If V has leading columns, then they are not modified (are assumed to be already orthonormal) and the corresponding part of R is not referenced. Can pass NULL if R is not required. Level: intermediate .seealso: BVOrthogonalizeColumn(), BVOrthogonalizeVec(), BVSetActiveColumns() @*/ PetscErrorCode BVOrthogonalize(BV V,Mat R) { PetscErrorCode ierr; PetscBool match; PetscInt m,n; PetscFunctionBegin; PetscValidHeaderSpecific(V,BV_CLASSID,1); PetscValidType(V,1); BVCheckSizes(V,1); if (R) { PetscValidHeaderSpecific(R,MAT_CLASSID,2); PetscValidType(R,2); ierr = PetscObjectTypeCompare((PetscObject)R,MATSEQDENSE,&match);CHKERRQ(ierr); if (!match) SETERRQ(PetscObjectComm((PetscObject)V),PETSC_ERR_SUP,"Mat argument must be of type seqdense"); ierr = MatGetSize(R,&m,&n);CHKERRQ(ierr); if (m!=n) SETERRQ2(PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_SIZ,"Mat argument is not square, it has %D rows and %D columns",m,n); if (n<V->k) SETERRQ2(PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_SIZ,"Mat size %D is smaller than the number of BV active columns %D",n,V->k); } if (V->matrix) SETERRQ(PetscObjectComm((PetscObject)V),PETSC_ERR_SUP,"Not implemented for non-standard inner product, use BVOrthogonalizeColumn() instead"); if (V->nc) SETERRQ(PetscObjectComm((PetscObject)V),PETSC_ERR_SUP,"Not implemented for BV with constraints, use BVOrthogonalizeColumn() instead"); ierr = PetscLogEventBegin(BV_Orthogonalize,V,R,0,0);CHKERRQ(ierr); if (V->ops->orthogonalize) { ierr = (*V->ops->orthogonalize)(V,R);CHKERRQ(ierr); } else { /* no specific QR function available, so proceed column by column with Gram-Schmidt */ ierr = BVOrthogonalize_GS(V,R);CHKERRQ(ierr); } ierr = PetscLogEventEnd(BV_Orthogonalize,V,R,0,0);CHKERRQ(ierr); ierr = PetscObjectStateIncrease((PetscObject)V);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ BVInsertConstraints - Insert a set of vectors as constraints. Collective on BV Input Parameters: + V - basis vectors - C - set of vectors to be inserted as constraints Input/Output Parameter: . nc - number of input vectors, on output the number of linearly independent vectors Notes: The constraints are relevant only during orthogonalization. Constraint vectors span a subspace that is deflated in every orthogonalization operation, so they are intended for removing those directions from the orthogonal basis computed in regular BV columns. Constraints are not stored in regular BV colums, but in a special part of the storage. They can be accessed with negative indices in BVGetColumn(). This operation is DESTRUCTIVE, meaning that all data contained in the columns of V is lost. This is typically invoked just after creating the BV. Once a set of constraints has been set, it is not allowed to call this function again. The vectors are copied one by one and then orthogonalized against the previous ones. If any of them is linearly dependent then it is discarded and the value of nc is decreased. The behaviour is similar to BVInsertVecs(). Level: advanced .seealso: BVInsertVecs(), BVOrthogonalizeColumn(), BVGetColumn(), BVGetNumConstraints() @*/ PetscErrorCode BVInsertConstraints(BV V,PetscInt *nc,Vec *C) { PetscErrorCode ierr; PetscInt msave; PetscFunctionBegin; PetscValidHeaderSpecific(V,BV_CLASSID,1); PetscValidPointer(nc,2); PetscValidLogicalCollectiveInt(V,*nc,2); if (!*nc) PetscFunctionReturn(0); if (*nc<0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of constraints (given %D) cannot be negative",*nc); PetscValidPointer(C,3); PetscValidHeaderSpecific(*C,VEC_CLASSID,3); PetscValidType(V,1); BVCheckSizes(V,1); PetscCheckSameComm(V,1,*C,3); if (V->nc) SETERRQ(PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_WRONGSTATE,"Constraints already present in this BV object"); if (V->ci[0]!=-1 || V->ci[1]!=-1) SETERRQ(PetscObjectComm((PetscObject)V),PETSC_ERR_SUP,"Cannot call BVInsertConstraints after BVGetColumn"); msave = V->m; ierr = BVResize(V,*nc+V->m,PETSC_FALSE);CHKERRQ(ierr); ierr = BVInsertVecs(V,0,nc,C,PETSC_TRUE);CHKERRQ(ierr); V->nc = *nc; V->m = msave; V->ci[0] = -V->nc-1; V->ci[1] = -V->nc-1; ierr = PetscObjectStateIncrease((PetscObject)V);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ VecScatterCreateToAll - Creates a vector and a scatter context that copies all vector values to each processor Collective Input Parameter: . vin - input MPIVEC Output Parameter: + ctx - scatter context - vout - output SEQVEC that is large enough to scatter into Level: intermediate Note: vout may be PETSC_NULL [PETSC_NULL_OBJECT from fortran] if you do not need to have it created Usage: $ VecScatterCreateToAll(vin,&ctx,&vout); $ $ // scatter as many times as you need $ VecScatterBegin(ctx,vin,vout,INSERT_VALUES,SCATTER_FORWARD); $ VecScatterEnd(ctx,vin,vout,INSERT_VALUES,SCATTER_FORWARD); $ $ // destroy scatter context and local vector when no longer needed $ VecScatterDestroy(ctx); $ VecDestroy(vout); Do NOT create a vector and then pass it in as the final argument vout! vout is created by this routine automatically (unless you pass PETSC_NULL in for that argument if you do not need it). .seealso VecScatterCreate(), VecScatterCreateToZero(), VecScatterBegin(), VecScatterEnd() @*/ PetscErrorCode PETSCVEC_DLLEXPORT VecScatterCreateToAll(Vec vin,VecScatter *ctx,Vec *vout) { PetscErrorCode ierr; PetscInt N; IS is; Vec tmp; Vec *tmpv; PetscTruth tmpvout = PETSC_FALSE; PetscFunctionBegin; PetscValidHeaderSpecific(vin,VEC_COOKIE,1); PetscValidType(vin,1); PetscValidPointer(ctx,2); if (vout) { PetscValidPointer(vout,3); tmpv = vout; } else { tmpvout = PETSC_TRUE; tmpv = &tmp; } /* Create seq vec on each proc, with the same size of the original mpi vec */ ierr = VecGetSize(vin,&N);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,N,tmpv);CHKERRQ(ierr); /* Create the VecScatter ctx with the communication info */ ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&is);CHKERRQ(ierr); ierr = VecScatterCreate(vin,is,*tmpv,is,ctx);CHKERRQ(ierr); ierr = ISDestroy(is);CHKERRQ(ierr); if (tmpvout) {ierr = VecDestroy(*tmpv);CHKERRQ(ierr);} PetscFunctionReturn(0); }
/*@ BVInsertVec - Insert a vector into the specified column. Collective on BV Input Parameters: + V - basis vectors . j - the column of V to be overwritten - w - the vector to be copied Level: intermediate .seealso: BVInsertVecs() @*/ PetscErrorCode BVInsertVec(BV V,PetscInt j,Vec w) { PetscErrorCode ierr; PetscInt n,N; Vec v; PetscFunctionBegin; PetscValidHeaderSpecific(V,BV_CLASSID,1); PetscValidLogicalCollectiveInt(V,j,2); PetscValidHeaderSpecific(w,VEC_CLASSID,3); PetscValidType(V,1); BVCheckSizes(V,1); PetscCheckSameComm(V,1,w,3); ierr = VecGetSize(w,&N);CHKERRQ(ierr); ierr = VecGetLocalSize(w,&n);CHKERRQ(ierr); if (N!=V->N || n!=V->n) SETERRQ4(PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_INCOMP,"Vec sizes (global %D, local %D) do not match BV sizes (global %D, local %D)",N,n,V->N,V->n); if (j<-V->nc || j>=V->m) SETERRQ3(PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_OUTOFRANGE,"Argument j has wrong value %D, should be between %D and %D",j,-V->nc,V->m-1); ierr = BVGetColumn(V,j,&v);CHKERRQ(ierr); ierr = VecCopy(w,v);CHKERRQ(ierr); ierr = BVRestoreColumn(V,j,&v);CHKERRQ(ierr); ierr = PetscObjectStateIncrease((PetscObject)V);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ STApplyTranspose - Applies the transpose of the operator to a vector, for instance B^T(A - sB)^-T in the case of the shift-and-invert tranformation and generalized eigenproblem. Collective on ST and Vec Input Parameters: + st - the spectral transformation context - x - input vector Output Parameter: . y - output vector Level: developer .seealso: STApply() @*/ PetscErrorCode STApplyTranspose(ST st,Vec x,Vec y) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(st,ST_CLASSID,1); PetscValidHeaderSpecific(x,VEC_CLASSID,2); PetscValidHeaderSpecific(y,VEC_CLASSID,3); PetscValidType(st,1); STCheckMatrices(st,1); if (x == y) SETERRQ(PetscObjectComm((PetscObject)st),PETSC_ERR_ARG_IDN,"x and y must be different vectors"); if (!st->setupcalled) { ierr = STSetUp(st);CHKERRQ(ierr); } if (!st->ops->applytrans) SETERRQ(PetscObjectComm((PetscObject)st),PETSC_ERR_SUP,"ST does not have applytrans"); ierr = PetscLogEventBegin(ST_ApplyTranspose,st,x,y,0);CHKERRQ(ierr); st->applys++; if (st->D) { /* with balancing */ ierr = VecPointwiseMult(st->wb,x,st->D);CHKERRQ(ierr); ierr = (*st->ops->applytrans)(st,st->wb,y);CHKERRQ(ierr); ierr = VecPointwiseDivide(y,y,st->D);CHKERRQ(ierr); } else { ierr = (*st->ops->applytrans)(st,x,y);CHKERRQ(ierr); } ierr = PetscLogEventEnd(ST_ApplyTranspose,st,x,y,0);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ BVMultColumn - Computes y = beta*y + alpha*X*q, where y is the j-th column of X. Logically Collective on BV Input Parameters: + X - a basis vectors object . alpha,beta - scalars . j - the column index - q - an array of scalars Notes: This operation is equivalent to BVMultVec() but it uses column j of X rather than taking a Vec as an argument. The number of active columns of X is set to j before the computation, and restored afterwards. If X has leading columns specified, then these columns do not participate in the computation. Therefore, the length of array q must be equal to j minus the number of leading columns. Level: advanced .seealso: BVMult(), BVMultVec(), BVMultInPlace(), BVSetActiveColumns() @*/ PetscErrorCode BVMultColumn(BV X,PetscScalar alpha,PetscScalar beta,PetscInt j,PetscScalar *q) { PetscErrorCode ierr; PetscInt ksave; Vec y; PetscFunctionBegin; PetscValidHeaderSpecific(X,BV_CLASSID,1); PetscValidLogicalCollectiveScalar(X,alpha,2); PetscValidLogicalCollectiveScalar(X,beta,3); PetscValidLogicalCollectiveInt(X,j,4); PetscValidPointer(q,5); PetscValidType(X,1); BVCheckSizes(X,1); if (j<0) SETERRQ(PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_OUTOFRANGE,"Index j must be non-negative"); if (j>=X->m) SETERRQ2(PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_OUTOFRANGE,"Index j=%D but BV only has %D columns",j,X->m); ierr = PetscLogEventBegin(BV_Mult,X,0,0,0);CHKERRQ(ierr); ksave = X->k; X->k = j; ierr = BVGetColumn(X,j,&y);CHKERRQ(ierr); ierr = (*X->ops->multvec)(X,alpha,beta,y,q);CHKERRQ(ierr); ierr = BVRestoreColumn(X,j,&y);CHKERRQ(ierr); X->k = ksave; ierr = PetscLogEventEnd(BV_Mult,X,0,0,0);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ MatGetSchurComplement - Obtain the Schur complement from eliminating part of the matrix in another part. Collective on Mat Input Parameters: + A - matrix in which the complement is to be taken . isrow0 - rows to eliminate . iscol0 - columns to eliminate, (isrow0,iscol0) should be square and nonsingular . isrow1 - rows in which the Schur complement is formed . iscol1 - columns in which the Schur complement is formed . mreuse - MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX, use MAT_IGNORE_MATRIX to put nothing in S . plump - the type of approximation used for the inverse of the (0,0) block used in forming Sp: MAT_SCHUR_COMPLEMENT_AINV_DIAG or MAT_SCHUR_COMPLEMENT_AINV_LUMP - preuse - MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX, use MAT_IGNORE_MATRIX to put nothing in Sp Output Parameters: + S - exact Schur complement, often of type MATSCHURCOMPLEMENT which is difficult to use for preconditioning - Sp - approximate Schur complement suitable for preconditioning 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)). Sometimes users would like to provide problem-specific data in the Schur complement, usually only for special row and column index sets. In that case, the user should call PetscObjectComposeFunction() to set "MatNestGetSubMat_C" to their function. If their function needs to fall back to the default implementation, it should call MatGetSchurComplement_Basic(). Level: advanced Concepts: matrices^submatrices .seealso: MatGetSubMatrix(), PCFIELDSPLIT, MatCreateSchurComplement(), MatSchurComplementAinvType @*/ PetscErrorCode MatGetSchurComplement(Mat A,IS isrow0,IS iscol0,IS isrow1,IS iscol1,MatReuse mreuse,Mat *S,MatSchurComplementAinvType ainvtype,MatReuse preuse,Mat *Sp) { PetscErrorCode ierr,(*f)(Mat,IS,IS,IS,IS,MatReuse,Mat*,MatReuse,Mat*) = NULL; PetscFunctionBegin; PetscValidHeaderSpecific(A,MAT_CLASSID,1); PetscValidHeaderSpecific(isrow0,IS_CLASSID,2); PetscValidHeaderSpecific(iscol0,IS_CLASSID,3); PetscValidHeaderSpecific(isrow1,IS_CLASSID,4); PetscValidHeaderSpecific(iscol1,IS_CLASSID,5); if (mreuse == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*S,MAT_CLASSID,7); if (preuse == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*Sp,MAT_CLASSID,9); PetscValidType(A,1); if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); f = NULL; if (mreuse == MAT_REUSE_MATRIX) { /* This is the only situation, in which we can demand that the user pass a non-NULL pointer to non-garbage in S. */ ierr = PetscObjectQueryFunction((PetscObject)*S,"MatGetSchurComplement_C",&f);CHKERRQ(ierr); } if (f) { ierr = (*f)(A,isrow0,iscol0,isrow1,iscol1,mreuse,S,preuse,Sp);CHKERRQ(ierr); } else { ierr = MatGetSchurComplement_Basic(A,isrow0,iscol0,isrow1,iscol1,mreuse,S,ainvtype,preuse,Sp);CHKERRQ(ierr); } PetscFunctionReturn(0); }
/*@ BVOrthogonalizeSomeColumn - Orthogonalize one of the column vectors with respect to some of the previous ones. Collective on BV Input Parameters: + bv - the basis vectors context . j - index of column to be orthogonalized - which - logical array indicating selected columns Output Parameters: + H - (optional) coefficients computed during orthogonalization . norm - (optional) norm of the vector after being orthogonalized - lindep - (optional) flag indicating that refinement did not improve the quality of orthogonalization Notes: This function is similar to BVOrthogonalizeColumn(), but V[j] is orthogonalized only against columns V[i] having which[i]=PETSC_TRUE. The length of array which must be j at least. The use of this operation is restricted to MGS orthogonalization type. Level: advanced .seealso: BVOrthogonalizeColumn(), BVSetOrthogonalization() @*/ PetscErrorCode BVOrthogonalizeSomeColumn(BV bv,PetscInt j,PetscBool *which,PetscScalar *H,PetscReal *norm,PetscBool *lindep) { PetscErrorCode ierr; PetscInt i,ksave,lsave; PetscFunctionBegin; PetscValidHeaderSpecific(bv,BV_CLASSID,1); PetscValidLogicalCollectiveInt(bv,j,2); PetscValidPointer(which,3); PetscValidType(bv,1); BVCheckSizes(bv,1); if (j<0) SETERRQ(PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_OUTOFRANGE,"Index j must be non-negative"); if (j>=bv->m) SETERRQ2(PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_OUTOFRANGE,"Index j=%D but BV only has %D columns",j,bv->m); if (bv->orthog_type!=BV_ORTHOG_MGS) SETERRQ(PetscObjectComm((PetscObject)bv),PETSC_ERR_SUP,"Operation only available for MGS orthogonalization"); ierr = PetscLogEventBegin(BV_Orthogonalize,bv,0,0,0);CHKERRQ(ierr); ksave = bv->k; lsave = bv->l; bv->l = -bv->nc; /* must also orthogonalize against constraints and leading columns */ ierr = BV_AllocateCoeffs(bv);CHKERRQ(ierr); ierr = BV_AllocateSignature(bv);CHKERRQ(ierr); ierr = BVOrthogonalizeMGS(bv,j,NULL,which,H,norm,lindep);CHKERRQ(ierr); bv->k = ksave; bv->l = lsave; if (H) for (i=bv->l;i<j;i++) H[i-bv->l] = bv->h[bv->nc+i]; ierr = PetscLogEventEnd(BV_Orthogonalize,bv,0,0,0);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@C PetscRandomView - Views a random number generator object. Collective on PetscRandom Input Parameters: + rnd - The random number generator context - viewer - an optional visualization context Notes: The available visualization contexts include + PETSC_VIEWER_STDOUT_SELF - standard output (default) - PETSC_VIEWER_STDOUT_WORLD - synchronized standard output where only the first processor opens the file. All other processors send their data to the first processor to print. You can change the format the vector is printed using the option PetscViewerSetFormat(). Level: beginner .seealso: PetscRealView(), PetscScalarView(), PetscIntView() @*/ PetscErrorCode PetscRandomView(PetscRandom rnd,PetscViewer viewer) { PetscErrorCode ierr; PetscBool iascii; #if defined(PETSC_HAVE_SAWS) PetscBool issaws; #endif PetscFunctionBegin; PetscValidHeaderSpecific(rnd,PETSC_RANDOM_CLASSID,1); PetscValidType(rnd,1); if (!viewer) { ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)rnd),&viewer); CHKERRQ(ierr); } PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); PetscCheckSameComm(rnd,1,viewer,2); ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii); CHKERRQ(ierr); #if defined(PETSC_HAVE_SAWS) ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws); CHKERRQ(ierr); #endif if (iascii) { PetscMPIInt rank; ierr = PetscObjectPrintClassNamePrefixType((PetscObject)rnd,viewer); CHKERRQ(ierr); ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)rnd),&rank); CHKERRQ(ierr); ierr = PetscViewerASCIIPushSynchronized(viewer); CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Random type %s, seed %D\n",rank,((PetscObject)rnd)->type_name,rnd->seed); CHKERRQ(ierr); ierr = PetscViewerFlush(viewer); CHKERRQ(ierr); ierr = PetscViewerASCIIPopSynchronized(viewer); CHKERRQ(ierr); #if defined(PETSC_HAVE_SAWS) } else if (issaws) { PetscMPIInt rank; const char *name; ierr = PetscObjectGetName((PetscObject)rnd,&name); CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); CHKERRQ(ierr); if (!((PetscObject)rnd)->amsmem && !rank) { char dir[1024]; ierr = PetscObjectViewSAWs((PetscObject)rnd,viewer); CHKERRQ(ierr); ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/Low",name); CHKERRQ(ierr); PetscStackCallSAWs(SAWs_Register,(dir,&rnd->low,1,SAWs_READ,SAWs_DOUBLE)); } #endif } PetscFunctionReturn(0); }
/*@C BVView - Prints the BV data structure. Collective on BV Input Parameters: + bv - the BV context - viewer - optional visualization context Note: The available visualization contexts include + PETSC_VIEWER_STDOUT_SELF - standard output (default) - PETSC_VIEWER_STDOUT_WORLD - synchronized standard output where only the first processor opens the file. All other processors send their data to the first processor to print. The user can open an alternative visualization contexts with PetscViewerASCIIOpen() (output to a specified file). Level: beginner .seealso: PetscViewerASCIIOpen() @*/ PetscErrorCode BVView(BV bv,PetscViewer viewer) { PetscErrorCode ierr; PetscBool isascii; PetscViewerFormat format; const char *orthname[2] = {"classical","modified"}; const char *refname[3] = {"if needed","never","always"}; PetscFunctionBegin; PetscValidHeaderSpecific(bv,BV_CLASSID,1); PetscValidType(bv,1); if (!viewer) { ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)bv),&viewer);CHKERRQ(ierr); } PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); if (isascii) { ierr = PetscObjectPrintClassNamePrefixType((PetscObject)bv,viewer);CHKERRQ(ierr); ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { ierr = PetscViewerASCIIPrintf(viewer,"%D columns of global length %D\n",bv->m,bv->N);CHKERRQ(ierr); if (bv->nc>0) { ierr = PetscViewerASCIIPrintf(viewer,"number of constraints: %D\n",bv->nc);CHKERRQ(ierr); } ierr = PetscViewerASCIIPrintf(viewer,"orthogonalization method: %s Gram-Schmidt\n",orthname[bv->orthog_type]);CHKERRQ(ierr); switch (bv->orthog_ref) { case BV_ORTHOG_REFINE_IFNEEDED: ierr = PetscViewerASCIIPrintf(viewer,"orthogonalization refinement: %s (eta: %g)\n",refname[bv->orthog_ref],(double)bv->orthog_eta);CHKERRQ(ierr); break; case BV_ORTHOG_REFINE_NEVER: case BV_ORTHOG_REFINE_ALWAYS: ierr = PetscViewerASCIIPrintf(viewer,"orthogonalization refinement: %s\n",refname[bv->orthog_ref]);CHKERRQ(ierr); break; } if (bv->matrix) { if (bv->indef) { ierr = PetscViewerASCIIPrintf(viewer,"indefinite inner product\n");CHKERRQ(ierr); } else { ierr = PetscViewerASCIIPrintf(viewer,"non-standard inner product\n");CHKERRQ(ierr); } ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr); ierr = MatView(bv->matrix,viewer);CHKERRQ(ierr); ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); } } else { if (bv->ops->view) { ierr = (*bv->ops->view)(bv,viewer);CHKERRQ(ierr); } else { ierr = BVView_Default(bv,viewer);CHKERRQ(ierr); } } ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); } else { ierr = (*bv->ops->view)(bv,viewer);CHKERRQ(ierr); } PetscFunctionReturn(0); }
/*@ DMRedundantGetSize - Gets the size of a densely coupled redundant object Not Collective Input Parameter: + dm - redundant DM Output Parameters: + rank - rank of process to own redundant degrees of freedom (or NULL) - N - total number of redundant degrees of freedom (or NULL) Level: advanced .seealso DMDestroy(), DMCreateGlobalVector(), DMRedundantCreate(), DMRedundantSetSize() @*/ PetscErrorCode DMRedundantGetSize(DM dm,PetscInt *rank,PetscInt *N) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); PetscValidType(dm,1); ierr = PetscUseMethod(dm,"DMRedundantGetSize_C",(DM,PetscInt*,PetscInt*),(dm,rank,N));CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ MatISSetPreallocation - Preallocates memory for a MATIS parallel matrix. Collective on MPI_Comm Input Parameters: + B - the matrix . d_nz - number of nonzeros per row in DIAGONAL portion of local submatrix (same value is used for all local rows) . d_nnz - array containing the number of nonzeros in the various rows of the DIAGONAL portion of the local submatrix (possibly different for each row) or NULL, if d_nz is used to specify the nonzero structure. The size of this array is equal to the number of local rows, i.e 'm'. For matrices that will be factored, you must leave room for (and set) the diagonal entry even if it is zero. . o_nz - number of nonzeros per row in the OFF-DIAGONAL portion of local submatrix (same value is used for all local rows). - o_nnz - array containing the number of nonzeros in the various rows of the OFF-DIAGONAL portion of the local submatrix (possibly different for each row) or NULL, if o_nz is used to specify the nonzero structure. The size of this array is equal to the number of local rows, i.e 'm'. If the *_nnz parameter is given then the *_nz parameter is ignored Level: intermediate Notes: This function has the same interface as the MPIAIJ preallocation routine in order to simplify the transition from the asssembled format to the unassembled one. It overestimates the preallocation of MATIS local matrices; for exact preallocation, the user should set the preallocation directly on local matrix objects. .keywords: matrix .seealso: MatCreate(), MatCreateIS(), MatMPIAIJSetPreallocation(), MatISGetLocalMat() @*/ PetscErrorCode MatISSetPreallocation(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(B,MAT_CLASSID,1); PetscValidType(B,1); ierr = PetscTryMethod(B,"MatISSetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(B,d_nz,d_nnz,o_nz,o_nnz));CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ MatTransposeGetMat - Gets the Mat object stored inside a MATTRANSPOSEMAT Logically collective on Mat Input Parameter: . A - the MATTRANSPOSE matrix Output Parameter: . M - the matrix object stored inside A Level: intermediate .seealso: MatCreateTranspose() @*/ PetscErrorCode MatTransposeGetMat(Mat A,Mat *M) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(A,MAT_CLASSID,1); PetscValidType(A,1); PetscValidPointer(M,2); ierr = PetscUseMethod(A,"MatTransposeGetMat_C",(Mat,Mat*),(A,M));CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ DMRedundantSetSize - Sets the size of a densely coupled redundant object Collective on DM Input Parameter: + dm - redundant DM . rank - rank of process to own redundant degrees of freedom - N - total number of redundant degrees of freedom Level: advanced .seealso DMDestroy(), DMCreateGlobalVector(), DMRedundantCreate(), DMRedundantGetSize() @*/ PetscErrorCode DMRedundantSetSize(DM dm,PetscInt rank,PetscInt N) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); PetscValidType(dm,1); PetscValidLogicalCollectiveInt(dm,rank,2); PetscValidLogicalCollectiveInt(dm,N,3); ierr = PetscTryMethod(dm,"DMRedundantSetSize_C",(DM,PetscInt,PetscInt),(dm,rank,N));CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ STPostSolve - Optional post-solve phase, intended for any actions that must be performed on the ST object after the eigensolver has finished. Collective on ST Input Parameters: . st - the spectral transformation context Level: developer .seealso: EPSSolve() @*/ PetscErrorCode STPostSolve(ST st) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(st,ST_CLASSID,1); PetscValidType(st,1); if (st->ops->postsolve) { ierr = (*st->ops->postsolve)(st);CHKERRQ(ierr); } PetscFunctionReturn(0); }
/*@ PetscRandomSeed - Seed the generator. Not collective Input Parameters: . r - The random number generator context Level: intermediate Usage: PetscRandomSetSeed(r,a positive integer); PetscRandomSeed(r); PetscRandomGetValue() will now start with the new seed. PetscRandomSeed(r) without a call to PetscRandomSetSeed() re-initializes the seed. The random numbers generated will be the same as before. Concepts: random numbers^seed .seealso: PetscRandomCreate(), PetscRandomGetSeed(), PetscRandomSetSeed() @*/ PetscErrorCode PetscRandomSeed(PetscRandom r) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1); PetscValidType(r,1); ierr = (*r->ops->seed)(r);CHKERRQ(ierr); ierr = PetscObjectStateIncrease((PetscObject)r);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ STBackTransform - Back-transformation phase, intended for spectral transformations which require to transform the computed eigenvalues back to the original eigenvalue problem. Not Collective Input Parameters: st - the spectral transformation context eigr - real part of a computed eigenvalue eigi - imaginary part of a computed eigenvalue Level: developer @*/ PetscErrorCode STBackTransform(ST st,PetscInt n,PetscScalar* eigr,PetscScalar* eigi) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(st,ST_CLASSID,1); PetscValidType(st,1); if (st->ops->backtransform) { ierr = (*st->ops->backtransform)(st,n,eigr,eigi);CHKERRQ(ierr); } PetscFunctionReturn(0); }
/*@ STGetBilinearForm - Returns the matrix used in the bilinear form with a generalized problem with semi-definite B. Not collective, though a parallel Mat may be returned Input Parameters: . st - the spectral transformation context Output Parameter: . B - output matrix Notes: The output matrix B must be destroyed after use. It will be NULL in case of standard eigenproblems. Level: developer @*/ PetscErrorCode STGetBilinearForm(ST st,Mat *B) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(st,ST_CLASSID,1); PetscValidType(st,1); PetscValidPointer(B,2); STCheckMatrices(st,1); ierr = (*st->ops->getbilinearform)(st,B);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ RGIsTrivial - Whether it is the trivial region (whole complex plane). Not Collective Input Parameter: . rg - the region context Output Parameter: . trivial - true if the region is equal to the whole complex plane, e.g., an interval region with all four endpoints unbounded or an ellipse with infinite radius. Level: basic @*/ PetscErrorCode RGIsTrivial(RG rg,PetscBool *trivial) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(rg,RG_CLASSID,1); PetscValidType(rg,1); PetscValidPointer(trivial,2); if (*rg->ops->istrivial) { ierr = (*rg->ops->istrivial)(rg,trivial);CHKERRQ(ierr); } else *trivial = PETSC_FALSE; PetscFunctionReturn(0); }
/*@ BVMatMult - Computes the matrix-vector product for each column, Y=A*X. Neighbor-wise Collective on Mat and BV Input Parameters: + V - basis vectors context - A - the matrix Output Parameter: . Y - the result Note: Both V and Y must be distributed in the same manner. Only active columns (excluding the leading ones) are processed. In the result Y, columns are overwritten starting from the leading ones. Level: beginner .seealso: BVCopy(), BVSetActiveColumns(), BVMatMultColumn() @*/ PetscErrorCode BVMatMult(BV V,Mat A,BV Y) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(V,BV_CLASSID,1); PetscValidType(V,1); BVCheckSizes(V,1); PetscValidHeaderSpecific(A,MAT_CLASSID,2); PetscValidHeaderSpecific(Y,BV_CLASSID,3); PetscValidType(Y,3); BVCheckSizes(Y,3); PetscCheckSameComm(V,1,A,2); PetscCheckSameTypeAndComm(V,1,Y,3); if (V->n!=Y->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Mismatching local dimension V %D, Y %D",V->n,Y->n); if (V->k-V->l>Y->m-Y->l) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Y has %D non-leading columns, not enough to store %D columns",Y->m-Y->l,V->k-V->l); ierr = PetscLogEventBegin(BV_MatMult,V,A,Y,0);CHKERRQ(ierr); ierr = (*V->ops->matmult)(V,A,Y);CHKERRQ(ierr); ierr = PetscLogEventEnd(BV_MatMult,V,A,Y,0);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ RGComputeContour - Computes the coordinates of several points lying in the contour of the region. Not Collective Input Parameters: + rg - the region context - n - number of points to compute Output Parameter: + cr - location to store real parts - ci - location to store imaginary parts Level: intermediate @*/ PetscErrorCode RGComputeContour(RG rg,PetscInt n,PetscScalar *cr,PetscScalar *ci) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(rg,RG_CLASSID,1); PetscValidType(rg,1); PetscValidPointer(cr,3); #if defined(PETSC_USE_COMPLEX) PetscValidPointer(ci,4); #endif ierr = (*rg->ops->computecontour)(rg,n,cr,ci);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* Developer Notes: This should be implemented with a MatCreate_SchurComplement() as that is the standard design for new Mat classes. */ PetscErrorCode MatGetSchurComplement_Basic(Mat mat,IS isrow0,IS iscol0,IS isrow1,IS iscol1,MatReuse mreuse,Mat *newmat,MatSchurComplementAinvType ainvtype, MatReuse preuse,Mat *newpmat) { PetscErrorCode ierr; Mat A=0,Ap=0,B=0,C=0,D=0; PetscFunctionBegin; PetscValidHeaderSpecific(mat,MAT_CLASSID,1); PetscValidType(mat,1); PetscValidHeaderSpecific(isrow0,IS_CLASSID,2); PetscValidHeaderSpecific(iscol0,IS_CLASSID,3); PetscValidHeaderSpecific(isrow1,IS_CLASSID,4); PetscValidHeaderSpecific(iscol1,IS_CLASSID,5); if (mreuse == MAT_IGNORE_MATRIX && preuse == MAT_IGNORE_MATRIX) PetscFunctionReturn(0); if (mreuse == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,7); if (preuse == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newpmat,MAT_CLASSID,9); if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); if (mreuse != MAT_IGNORE_MATRIX) { /* Use MatSchurComplement */ if (mreuse == MAT_REUSE_MATRIX) { ierr = MatSchurComplementGetSubMatrices(*newmat,&A,&Ap,&B,&C,&D);CHKERRQ(ierr); if (!A || !Ap || !B || !C) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Attempting to reuse matrix but Schur complement matrices unset"); if (A != Ap) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Preconditioning matrix does not match operator"); ierr = MatDestroy(&Ap);CHKERRQ(ierr); /* get rid of extra reference */ } } ierr = MatGetSubMatrix(mat,isrow0,iscol0,mreuse,&A);CHKERRQ(ierr); ierr = MatGetSubMatrix(mat,isrow0,iscol1,mreuse,&B);CHKERRQ(ierr); ierr = MatGetSubMatrix(mat,isrow1,iscol0,mreuse,&C);CHKERRQ(ierr); ierr = MatGetSubMatrix(mat,isrow1,iscol1,mreuse,&D);CHKERRQ(ierr); switch (mreuse) { case MAT_INITIAL_MATRIX: ierr = MatCreateSchurComplement(A,A,B,C,D,newmat);CHKERRQ(ierr); break; case MAT_REUSE_MATRIX: ierr = MatSchurComplementUpdateSubMatrices(*newmat,A,A,B,C,D);CHKERRQ(ierr); break; default: if (mreuse != MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Unrecognized value of mreuse"); } if (preuse != MAT_IGNORE_MATRIX) { ierr = MatCreateSchurComplementPmat(A,B,C,D,ainvtype,preuse,newpmat);CHKERRQ(ierr); } ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = MatDestroy(&D);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@C BVAXPY - Computes Y = Y + alpha*X. Logically Collective on BV Input Parameters: + Y,X - basis vectors - alpha - scalar Output Parameter: . Y - the modified basis vectors Notes: X and Y must be different objects, with compatible dimensions. The effect is the same as doing a VecAXPY for each of the active columns (excluding the leading ones). Level: intermediate .seealso: BVMult(), BVSetActiveColumns() @*/ PetscErrorCode BVAXPY(BV Y,PetscScalar alpha,BV X) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(Y,BV_CLASSID,1); PetscValidLogicalCollectiveScalar(Y,alpha,2); PetscValidHeaderSpecific(X,BV_CLASSID,3); PetscValidType(Y,1); BVCheckSizes(Y,1); PetscValidType(X,3); BVCheckSizes(X,3); PetscCheckSameTypeAndComm(Y,1,X,3); if (X==Y) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_ARG_WRONG,"X and Y arguments must be different"); if (X->n!=Y->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Mismatching local dimension X %D, Y %D",X->n,Y->n); if (X->k-X->l!=Y->k-Y->l) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Y has %D non-leading columns, while X has %D",Y->m-Y->l,X->k-X->l); if (!X->n) PetscFunctionReturn(0); ierr = PetscLogEventBegin(BV_AXPY,X,Y,0,0);CHKERRQ(ierr); ierr = (*Y->ops->axpy)(Y,alpha,X);CHKERRQ(ierr); ierr = PetscLogEventEnd(BV_AXPY,X,Y,0,0);CHKERRQ(ierr); ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@C PetscViewerView - Visualizes a viewer object. Collective on PetscViewer Input Parameters: + v - the viewer - viewer - visualization context Notes: The available visualization contexts include + PETSC_VIEWER_STDOUT_SELF - standard output (default) . PETSC_VIEWER_STDOUT_WORLD - synchronized standard output where only the first processor opens the file. All other processors send their data to the first processor to print. - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure Level: beginner .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), PetscViewerSocketOpen(), PetscViewerBinaryOpen(), PetscViewerLoad() @*/ PetscErrorCode PetscViewerView(PetscViewer v,PetscViewer viewer) { PetscErrorCode ierr; PetscBool iascii; PetscViewerFormat format; #if defined(PETSC_HAVE_SAWS) PetscBool issaws; #endif PetscFunctionBegin; PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,1); PetscValidType(v,1); if (!viewer) { ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)v),&viewer);CHKERRQ(ierr); } PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); PetscCheckSameComm(v,1,viewer,2); ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); #if defined(PETSC_HAVE_SAWS) ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); #endif if (iascii) { ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); ierr = PetscObjectPrintClassNamePrefixType((PetscObject)v,viewer);CHKERRQ(ierr); if (format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { if (v->format) { ierr = PetscViewerASCIIPrintf(viewer," Viewer format = %s\n",PetscViewerFormats[v->format]);CHKERRQ(ierr); } ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); if (v->ops->view) { ierr = (*v->ops->view)(v,viewer);CHKERRQ(ierr); } ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); } #if defined(PETSC_HAVE_SAWS) } else if (issaws) { if (!((PetscObject)v)->amsmem) { ierr = PetscObjectViewSAWs((PetscObject)v,viewer);CHKERRQ(ierr); if (v->ops->view) { ierr = (*v->ops->view)(v,viewer);CHKERRQ(ierr); } } #endif } PetscFunctionReturn(0); }
/*@ BVInsertVecs - Insert a set of vectors into the specified columns. Collective on BV Input Parameters: + V - basis vectors . s - first column of V to be overwritten . W - set of vectors to be copied - orth - flag indicating if the vectors must be orthogonalized Input/Output Parameter: . m - number of input vectors, on output the number of linearly independent vectors Notes: Copies the contents of vectors W to V(:,s:s+n). If the orthogonalization flag is set, then the vectors are copied one by one and then orthogonalized against the previous ones. If any of them is linearly dependent then it is discarded and the value of m is decreased. Level: intermediate .seealso: BVInsertVec(), BVOrthogonalizeColumn() @*/ PetscErrorCode BVInsertVecs(BV V,PetscInt s,PetscInt *m,Vec *W,PetscBool orth) { PetscErrorCode ierr; PetscInt n,N,i,ndep; PetscBool lindep; PetscReal norm; Vec v; PetscFunctionBegin; PetscValidHeaderSpecific(V,BV_CLASSID,1); PetscValidLogicalCollectiveInt(V,s,2); PetscValidPointer(m,3); PetscValidLogicalCollectiveInt(V,*m,3); if (!*m) PetscFunctionReturn(0); if (*m<0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",*m); PetscValidPointer(W,4); PetscValidHeaderSpecific(*W,VEC_CLASSID,4); PetscValidLogicalCollectiveBool(V,orth,5); PetscValidType(V,1); BVCheckSizes(V,1); PetscCheckSameComm(V,1,*W,4); ierr = VecGetSize(*W,&N);CHKERRQ(ierr); ierr = VecGetLocalSize(*W,&n);CHKERRQ(ierr); if (N!=V->N || n!=V->n) SETERRQ4(PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_INCOMP,"Vec sizes (global %D, local %D) do not match BV sizes (global %D, local %D)",N,n,V->N,V->n); if (s<0 || s>=V->m) SETERRQ2(PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_OUTOFRANGE,"Argument s has wrong value %D, should be between 0 and %D",s,V->m-1); if (s+(*m)>V->m) SETERRQ1(PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_OUTOFRANGE,"Too many vectors provided, there is only room for %D",V->m); ndep = 0; for (i=0;i<*m;i++) { ierr = BVGetColumn(V,s+i-ndep,&v);CHKERRQ(ierr); ierr = VecCopy(W[i],v);CHKERRQ(ierr); ierr = BVRestoreColumn(V,s+i-ndep,&v);CHKERRQ(ierr); if (orth) { ierr = BVOrthogonalizeColumn(V,s+i-ndep,NULL,&norm,&lindep);CHKERRQ(ierr); if (norm==0.0 || lindep) { ierr = PetscInfo1(V,"Removing linearly dependent vector %D\n",i);CHKERRQ(ierr); ndep++; } else { ierr = BVScaleColumn(V,s+i-ndep,1.0/norm);CHKERRQ(ierr); } } } *m -= ndep; ierr = PetscObjectStateIncrease((PetscObject)V);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ BVScale - Multiply the BV entries by a scalar value. Logically Collective on BV Input Parameters: + bv - basis vectors - alpha - scaling factor Note: All active columns (except the leading ones) are scaled. Level: intermediate .seealso: BVScaleColumn(), BVSetActiveColumns() @*/ PetscErrorCode BVScale(BV bv,PetscScalar alpha) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(bv,BV_CLASSID,1); PetscValidLogicalCollectiveScalar(bv,alpha,2); PetscValidType(bv,1); BVCheckSizes(bv,1); if (!bv->n || alpha == (PetscScalar)1.0) PetscFunctionReturn(0); ierr = PetscLogEventBegin(BV_Scale,bv,0,0,0);CHKERRQ(ierr); ierr = (*bv->ops->scale)(bv,-1,alpha);CHKERRQ(ierr); ierr = PetscLogEventEnd(BV_Scale,bv,0,0,0);CHKERRQ(ierr); ierr = PetscObjectStateIncrease((PetscObject)bv);CHKERRQ(ierr); PetscFunctionReturn(0); }