Actual source code: matnull.c

  1: /*$Id: matnull.c,v 1.37 2001/03/23 23:21:44 balay Exp $*/
  2: /*
  3:     Routines to project vectors out of null spaces.
  4: */

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

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

 13:    Collective on MPI_Comm

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

 22:    Output Parameter:
 23: .  SP - the null space context

 25:    Level: advanced

 27: .keywords: PC, null space, create

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

 36:   PetscHeaderCreate(sp,_p_MatNullSpace,int,MATNULLSPACE_COOKIE,0,"MatNullSpace",comm,MatNullSpaceDestroy,0);
 37:   PetscLogObjectCreate(sp);
 38:   PetscLogObjectMemory(sp,sizeof(struct _p_MatNullSpace));

 40:   sp->has_cnst = has_cnst;
 41:   sp->n        = n;
 42:   sp->vecs     = vecs;
 43:   sp->vec      = PETSC_NULL;

 45:   *SP          = sp;
 46:   return(0);
 47: }

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

 53:    Collective on MatNullSpace

 55:    Input Parameter:
 56: .  sp - the null space context to be destroyed

 58:    Level: advanced

 60: .keywords: PC, null space, destroy

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

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

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

 73:   PetscLogObjectDestroy(sp);
 74:   PetscHeaderDestroy(sp);
 75:   return(0);
 76: }

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

 81:    Collective on MatNullSpace

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

 87:    Level: advanced

 89: .keywords: PC, null space, remove

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

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

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

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

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

129:    Collective on MatNullSpace

131:    Input Parameters:
132: +  sp - the null space context
133: -  mat - the matrix

135:    Level: advanced

137: .keywords: PC, null space, remove

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

151:   PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view",&flg1);
152:   PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view_draw",&flg2);

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

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

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