Actual source code: matnull.c

  1: /*$Id: matnull.c,v 1.40 2001/09/07 20:09:09 bsmith Exp $*/
  2: /*
  3:     Routines to project vectors out of null spaces.
  4: */

 6:  #include src/mat/matimpl.h
 7:  #include petscsys.h

  9: int MAT_NULLSPACE_COOKIE;

 11: /*@C
 12:    MatNullSpaceCreate - Creates a data structure used to project vectors 
 13:    out of null spaces.

 15:    Collective on MPI_Comm

 17:    Input Parameters:
 18: +  comm - the MPI communicator associated with the object
 19: .  has_cnst - PETSC_TRUE if the null space contains the constant vector; otherwise PETSC_FALSE
 20: .  n - number of vectors (excluding constant vector) in null space
 21: -  vecs - the vectors that span the null space (excluding the constant vector);
 22:           these vectors must be orthonormal

 24:    Output Parameter:
 25: .  SP - the null space context

 27:    Level: advanced

 29: .keywords: PC, null space, create

 31: .seealso: MatNullSpaceDestroy(), MatNullSpaceRemove(), PCNullSpaceAttach()
 32: @*/
 33: int MatNullSpaceCreate(MPI_Comm comm,int has_cnst,int n,Vec *vecs,MatNullSpace *SP)
 34: {
 35:   MatNullSpace sp;

 38:   PetscHeaderCreate(sp,_p_MatNullSpace,int,MAT_NULLSPACE_COOKIE,0,"MatNullSpace",comm,MatNullSpaceDestroy,0);
 39:   PetscLogObjectCreate(sp);
 40:   PetscLogObjectMemory(sp,sizeof(struct _p_MatNullSpace));

 42:   sp->has_cnst = has_cnst;
 43:   sp->n        = n;
 44:   sp->vecs     = vecs;
 45:   sp->vec      = PETSC_NULL;

 47:   *SP          = sp;
 48:   return(0);
 49: }

 51: /*@
 52:    MatNullSpaceDestroy - Destroys a data structure used to project vectors 
 53:    out of null spaces.

 55:    Collective on MatNullSpace

 57:    Input Parameter:
 58: .  sp - the null space context to be destroyed

 60:    Level: advanced

 62: .keywords: PC, null space, destroy

 64: .seealso: MatNullSpaceCreate(), MatNullSpaceRemove()
 65: @*/
 66: int MatNullSpaceDestroy(MatNullSpace sp)
 67: {

 71:   if (--sp->refct > 0) return(0);

 73:   if (sp->vec) {VecDestroy(sp->vec);}

 75:   PetscLogObjectDestroy(sp);
 76:   PetscHeaderDestroy(sp);
 77:   return(0);
 78: }

 80: /*@
 81:    MatNullSpaceRemove - Removes all the components of a null space from a vector.

 83:    Collective on MatNullSpace

 85:    Input Parameters:
 86: +  sp - the null space context
 87: -  vec - the vector from which the null space is to be removed 

 89:    Level: advanced

 91: .keywords: PC, null space, remove

 93: .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy()
 94: @*/
 95: int MatNullSpaceRemove(MatNullSpace sp,Vec vec,Vec *out)
 96: {
 97:   PetscScalar sum;
 98:   int         j,n = sp->n,N,ierr;
 99:   Vec         l = vec;

102:   if (out) {
103:     if (!sp->vec) {
104:       VecDuplicate(vec,&sp->vec);
105:     }
106:     *out = sp->vec;
107:     VecCopy(vec,*out);
108:     l    = *out;
109:   }

111:   if (sp->has_cnst) {
112:     VecSum(l,&sum);
113:     VecGetSize(l,&N);
114:     sum  = sum/(-1.0*N);
115:     VecShift(&sum,l);
116:   }

118:   for (j=0; j<n; j++) {
119:     VecDot(l,sp->vecs[j],&sum);
120:     sum  = -sum;
121:     VecAXPY(&sum,sp->vecs[j],l);
122:   }
123: 
124:   return(0);
125: }

127: /*@
128:    MatNullSpaceTest  - Tests if the claimed null space is really a
129:      null space of a matrix

131:    Collective on MatNullSpace

133:    Input Parameters:
134: +  sp - the null space context
135: -  mat - the matrix

137:    Level: advanced

139: .keywords: PC, null space, remove

141: .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy()
142: @*/
143: int MatNullSpaceTest(MatNullSpace sp,Mat mat)
144: {
145:   PetscScalar  sum;
146:   PetscReal    nrm;
147:   int          j,n = sp->n,N,ierr,m;
148:   Vec          l,r;
149:   MPI_Comm     comm = sp->comm;
150:   PetscTruth   flg1,flg2;

153:   PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view",&flg1);
154:   PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view_draw",&flg2);

156:   if (!sp->vec) {
157:     if (n) {
158:       VecDuplicate(sp->vecs[0],&sp->vec);
159:     } else {
160:       MatGetLocalSize(mat,&m,PETSC_NULL);
161:       VecCreateMPI(sp->comm,m,PETSC_DETERMINE,&sp->vec);
162:     }
163:   }
164:   l    = sp->vec;

166:   if (sp->has_cnst) {
167:     VecDuplicate(l,&r);
168:     VecGetSize(l,&N);
169:     sum  = 1.0/N;
170:     VecSet(&sum,l);
171:     MatMult(mat,l,r);
172:     VecNorm(r,NORM_2,&nrm);
173:     if (nrm < 1.e-7) {PetscPrintf(comm,"Constants are likely null vector");}
174:     else {PetscPrintf(comm,"Constants are unlikely null vector ");}
175:     PetscPrintf(comm,"|| A * 1 || = %gn",nrm);
176:     if (nrm > 1.e-7 && flg1) {VecView(r,PETSC_VIEWER_STDOUT_(comm));}
177:     if (nrm > 1.e-7 && flg2) {VecView(r,PETSC_VIEWER_DRAW_(comm));}
178:     VecDestroy(r);
179:   }

181:   for (j=0; j<n; j++) {
182:     (*mat->ops->mult)(mat,sp->vecs[j],l);
183:     VecNorm(l,NORM_2,&nrm);
184:     if (nrm < 1.e-7) {PetscPrintf(comm,"Null vector %d is likely null vector",j);}
185:     else {PetscPrintf(comm,"Null vector %d unlikely null vector ",j);}
186:     PetscPrintf(comm,"|| A * v[%d] || = %gn",j,nrm);
187:     if (nrm > 1.e-7 && flg1) {VecView(l,PETSC_VIEWER_STDOUT_(comm));}
188:     if (nrm > 1.e-7 && flg2) {VecView(l,PETSC_VIEWER_DRAW_(comm));}
189:   }
190: 
191:   return(0);
192: }