Actual source code: isutil.c

petsc-3.7.3 2016-08-01
Report Typos and Errors
  1: #include <petsctao.h> /*I "petsctao.h" I*/
  2: #include <petsc/private/taoimpl.h>
  3: #include <petsc/private/matimpl.h>
  4: #include <../src/tao/matrix/submatfree.h>

  8: /*@C
  9:   TaoVecGetSubVec - Gets a subvector using the IS

 11:   Input Parameters:
 12: + vfull - the full matrix
 13: . is - the index set for the subvector
 14: . reduced_type - the method TAO is using for subsetting (TAO_SUBSET_SUBVEC, TAO_SUBSET_MASK,  TAO_SUBSET_MATRIXFREE)
 15: - maskvalue - the value to set the unused vector elements to (for TAO_SUBSET_MASK or TAO_SUBSET_MATRIXFREE)

 17:   Output Parameters:
 18: . vreduced - the subvector

 20:   Notes:
 21:   maskvalue should usually be 0.0, unless a pointwise divide will be used.

 23: @*/
 24: PetscErrorCode TaoVecGetSubVec(Vec vfull, IS is, TaoSubsetType reduced_type, PetscReal maskvalue, Vec *vreduced)
 25: {
 27:   PetscInt       nfull,nreduced,nreduced_local,rlow,rhigh,flow,fhigh;
 28:   PetscInt       i,nlocal;
 29:   PetscReal      *fv,*rv;
 30:   const PetscInt *s;
 31:   IS             ident;
 32:   VecType        vtype;
 33:   VecScatter     scatter;
 34:   MPI_Comm       comm;


 40:   VecGetSize(vfull, &nfull);
 41:   ISGetSize(is, &nreduced);

 43:   if (nreduced == nfull) {
 44:     VecDestroy(vreduced);
 45:     VecDuplicate(vfull,vreduced);
 46:     VecCopy(vfull,*vreduced);
 47:   } else {
 48:     switch (reduced_type) {
 49:     case TAO_SUBSET_SUBVEC:
 50:       VecGetType(vfull,&vtype);
 51:       VecGetOwnershipRange(vfull,&flow,&fhigh);
 52:       ISGetLocalSize(is,&nreduced_local);
 53:       PetscObjectGetComm((PetscObject)vfull,&comm);
 54:       if (*vreduced) {
 55:         VecDestroy(vreduced);
 56:       }
 57:       VecCreate(comm,vreduced);
 58:       VecSetType(*vreduced,vtype);

 60:       VecSetSizes(*vreduced,nreduced_local,nreduced);
 61:       VecGetOwnershipRange(*vreduced,&rlow,&rhigh);
 62:       ISCreateStride(comm,nreduced_local,rlow,1,&ident);
 63:       VecScatterCreate(vfull,is,*vreduced,ident,&scatter);
 64:       VecScatterBegin(scatter,vfull,*vreduced,INSERT_VALUES,SCATTER_FORWARD);
 65:       VecScatterEnd(scatter,vfull,*vreduced,INSERT_VALUES,SCATTER_FORWARD);
 66:       VecScatterDestroy(&scatter);
 67:       ISDestroy(&ident);
 68:       break;

 70:     case TAO_SUBSET_MASK:
 71:     case TAO_SUBSET_MATRIXFREE:
 72:       /* vr[i] = vf[i]   if i in is
 73:        vr[i] = 0       otherwise */
 74:       if (!*vreduced) {
 75:         VecDuplicate(vfull,vreduced);
 76:       }

 78:       VecSet(*vreduced,maskvalue);
 79:       ISGetLocalSize(is,&nlocal);
 80:       VecGetOwnershipRange(vfull,&flow,&fhigh);
 81:       VecGetArray(vfull,&fv);
 82:       VecGetArray(*vreduced,&rv);
 83:       ISGetIndices(is,&s);
 84:       if (nlocal > (fhigh-flow)) SETERRQ2(PETSC_COMM_WORLD,1,"IS local size %d > Vec local size %d",nlocal,fhigh-flow);
 85:       for (i=0;i<nlocal;i++) {
 86:         rv[s[i]-flow] = fv[s[i]-flow];
 87:       }
 88:       ISRestoreIndices(is,&s);
 89:       VecRestoreArray(vfull,&fv);
 90:       VecRestoreArray(*vreduced,&rv);
 91:       break;
 92:     }
 93:   }
 94:   return(0);
 95: }

 99: /*@C
100:   TaoMatGetSubMat - Gets a submatrix using the IS

102:   Input Parameters:
103: + M - the full matrix (n x n)
104: . is - the index set for the submatrix (both row and column index sets need to be the same)
105: . v1 - work vector of dimension n, needed for TAO_SUBSET_MASK option
106: - subset_type - the method TAO is using for subsetting (TAO_SUBSET_SUBVEC, TAO_SUBSET_MASK,
107:   TAO_SUBSET_MATRIXFREE)

109:   Output Parameters:
110: . Msub - the submatrix
111: @*/
112: PetscErrorCode TaoMatGetSubMat(Mat M, IS is, Vec v1, TaoSubsetType subset_type, Mat *Msub)
113: {
115:   IS             iscomp;
116:   PetscBool      flg = PETSC_FALSE;

121:   MatDestroy(Msub);
122:   switch (subset_type) {
123:   case TAO_SUBSET_SUBVEC:
124:     MatGetSubMatrix(M, is, is, MAT_INITIAL_MATRIX, Msub);
125:     break;

127:   case TAO_SUBSET_MASK:
128:     /* Get Reduced Hessian
129:      Msub[i,j] = M[i,j] if i,j in Free_Local or i==j
130:      Msub[i,j] = 0      if i!=j and i or j not in Free_Local
131:      */
132:     PetscOptionsBegin(PetscObjectComm((PetscObject)M),NULL,NULL,NULL);
133:     PetscOptionsBool("-different_submatrix","use separate hessian matrix when computing submatrices","TaoSubsetType",flg,&flg,NULL);
134:     PetscOptionsEnd();
135:     if (flg) {
136:       MatDuplicate(M, MAT_COPY_VALUES, Msub);
137:     } else {
138:       /* Act on hessian directly (default) */
139:       PetscObjectReference((PetscObject)M);
140:       *Msub = M;
141:     }
142:     /* Save the diagonal to temporary vector */
143:     MatGetDiagonal(*Msub,v1);

145:     /* Zero out rows and columns */
146:     ISComplementVec(is,v1,&iscomp);

148:     /* Use v1 instead of 0 here because of PETSc bug */
149:     MatZeroRowsColumnsIS(*Msub,iscomp,1.0,v1,v1);

151:     ISDestroy(&iscomp);
152:     break;
153:   case TAO_SUBSET_MATRIXFREE:
154:     ISComplementVec(is,v1,&iscomp);
155:     MatCreateSubMatrixFree(M,iscomp,iscomp,Msub);
156:     ISDestroy(&iscomp);
157:     break;
158:   }
159:   return(0);
160: }