xref: /petsc/src/mat/interface/matnull.c (revision f7a9e4ce2f28be551302492b6607a8f8bd4cabee)
173f4d377SMatthew Knepley /*$Id: matnull.c,v 1.40 2001/09/07 20:09:09 bsmith Exp $*/
2f7765cecSBarry Smith /*
3b4fd4287SBarry Smith     Routines to project vectors out of null spaces.
4f7765cecSBarry Smith */
5f7765cecSBarry Smith 
65cfeda75SBarry Smith #include "src/mat/matimpl.h"      /*I "petscmat.h" I*/
7e090d566SSatish Balay #include "petscsys.h"
8f7765cecSBarry Smith 
98ba1e511SMatthew Knepley int MAT_NULLSPACE_COOKIE;
108ba1e511SMatthew Knepley 
114a2ae208SSatish Balay #undef __FUNCT__
124a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceCreate"
13112a2221SBarry Smith /*@C
145cfeda75SBarry Smith    MatNullSpaceCreate - Creates a data structure used to project vectors
15b4fd4287SBarry Smith    out of null spaces.
16f7765cecSBarry Smith 
174e472627SLois Curfman McInnes    Collective on MPI_Comm
184e472627SLois Curfman McInnes 
19f7765cecSBarry Smith    Input Parameters:
2083c3bef8SLois Curfman McInnes +  comm - the MPI communicator associated with the object
2183c3bef8SLois Curfman McInnes .  has_cnst - PETSC_TRUE if the null space contains the constant vector; otherwise PETSC_FALSE
22b4fd4287SBarry Smith .  n - number of vectors (excluding constant vector) in null space
2383c3bef8SLois Curfman McInnes -  vecs - the vectors that span the null space (excluding the constant vector);
24*f7a9e4ceSBarry Smith           these vectors must be orthonormal. These vectors are NOT copied, so do not change them
25*f7a9e4ceSBarry Smith           after this call. You should free the array that you pass in.
26f7765cecSBarry Smith 
27f7765cecSBarry Smith    Output Parameter:
28b4fd4287SBarry Smith .  SP - the null space context
29f7765cecSBarry Smith 
3083c3bef8SLois Curfman McInnes    Level: advanced
3183c3bef8SLois Curfman McInnes 
326e1639daSBarry Smith   Users manual sections:
336e1639daSBarry Smith .   sec_singular
346e1639daSBarry Smith 
3583c3bef8SLois Curfman McInnes .keywords: PC, null space, create
3641a59933SSatish Balay 
376e1639daSBarry Smith .seealso: MatNullSpaceDestroy(), MatNullSpaceRemove(), PCNullSpaceAttach(), MatNullSpace
38f7765cecSBarry Smith @*/
395cfeda75SBarry Smith int MatNullSpaceCreate(MPI_Comm comm,int has_cnst,int n,Vec *vecs,MatNullSpace *SP)
40f7765cecSBarry Smith {
415cfeda75SBarry Smith   MatNullSpace sp;
42*f7a9e4ceSBarry Smith   int          ierr,i;
43f7765cecSBarry Smith 
443a40ed3dSBarry Smith   PetscFunctionBegin;
458ba1e511SMatthew Knepley   PetscHeaderCreate(sp,_p_MatNullSpace,int,MAT_NULLSPACE_COOKIE,0,"MatNullSpace",comm,MatNullSpaceDestroy,0);
46b0a32e0cSBarry Smith   PetscLogObjectCreate(sp);
47b0a32e0cSBarry Smith   PetscLogObjectMemory(sp,sizeof(struct _p_MatNullSpace));
48f7765cecSBarry Smith 
49b4fd4287SBarry Smith   sp->has_cnst = has_cnst;
50b4fd4287SBarry Smith   sp->n        = n;
515cfeda75SBarry Smith   sp->vec      = PETSC_NULL;
52*f7a9e4ceSBarry Smith   if (n) {
53*f7a9e4ceSBarry Smith     ierr = PetscMalloc(n*sizeof(Vec),&sp->vecs);CHKERRQ(ierr);
54*f7a9e4ceSBarry Smith     for (i=0; i<n; i++) sp->vecs[i] = vecs[i];
55*f7a9e4ceSBarry Smith   } else {
56*f7a9e4ceSBarry Smith     sp->vecs = 0;
57*f7a9e4ceSBarry Smith   }
58b4fd4287SBarry Smith 
59*f7a9e4ceSBarry Smith   for (i=0; i<n; i++) {
60*f7a9e4ceSBarry Smith     ierr = PetscObjectReference((PetscObject)sp->vecs[i]);CHKERRQ(ierr);
61*f7a9e4ceSBarry Smith   }
62b4fd4287SBarry Smith   *SP          = sp;
633a40ed3dSBarry Smith   PetscFunctionReturn(0);
64f7765cecSBarry Smith }
65f7765cecSBarry Smith 
664a2ae208SSatish Balay #undef __FUNCT__
674a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceDestroy"
68f7765cecSBarry Smith /*@
695cfeda75SBarry Smith    MatNullSpaceDestroy - Destroys a data structure used to project vectors
70b4fd4287SBarry Smith    out of null spaces.
71b4fd4287SBarry Smith 
725cfeda75SBarry Smith    Collective on MatNullSpace
734e472627SLois Curfman McInnes 
74b4fd4287SBarry Smith    Input Parameter:
75b9756687SLois Curfman McInnes .  sp - the null space context to be destroyed
76b9756687SLois Curfman McInnes 
77b9756687SLois Curfman McInnes    Level: advanced
78b4fd4287SBarry Smith 
7983c3bef8SLois Curfman McInnes .keywords: PC, null space, destroy
8041a59933SSatish Balay 
815cfeda75SBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceRemove()
82b4fd4287SBarry Smith @*/
835cfeda75SBarry Smith int MatNullSpaceDestroy(MatNullSpace sp)
84b4fd4287SBarry Smith {
855cfeda75SBarry Smith   int ierr;
8685614651SBarry Smith 
875cfeda75SBarry Smith   PetscFunctionBegin;
8885614651SBarry Smith   if (--sp->refct > 0) PetscFunctionReturn(0);
8985614651SBarry Smith 
905cfeda75SBarry Smith   if (sp->vec) {ierr = VecDestroy(sp->vec);CHKERRQ(ierr);}
91*f7a9e4ceSBarry Smith   if (sp->vecs) {
92*f7a9e4ceSBarry Smith     ierr = VecDestroyVecs(sp->vecs,sp->n);CHKERRQ(ierr);
93*f7a9e4ceSBarry Smith   }
94b0a32e0cSBarry Smith   PetscLogObjectDestroy(sp);
95b4fd4287SBarry Smith   PetscHeaderDestroy(sp);
963a40ed3dSBarry Smith   PetscFunctionReturn(0);
97b4fd4287SBarry Smith }
98b4fd4287SBarry Smith 
994a2ae208SSatish Balay #undef __FUNCT__
1004a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceRemove"
101b4fd4287SBarry Smith /*@
1025cfeda75SBarry Smith    MatNullSpaceRemove - Removes all the components of a null space from a vector.
103f7765cecSBarry Smith 
1045cfeda75SBarry Smith    Collective on MatNullSpace
105f7765cecSBarry Smith 
1064e472627SLois Curfman McInnes    Input Parameters:
1074e472627SLois Curfman McInnes +  sp - the null space context
10883c3bef8SLois Curfman McInnes -  vec - the vector from which the null space is to be removed
1094e472627SLois Curfman McInnes 
110b9756687SLois Curfman McInnes    Level: advanced
111b9756687SLois Curfman McInnes 
11283c3bef8SLois Curfman McInnes .keywords: PC, null space, remove
11341a59933SSatish Balay 
1145cfeda75SBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy()
115f7765cecSBarry Smith @*/
1165cfeda75SBarry Smith int MatNullSpaceRemove(MatNullSpace sp,Vec vec,Vec *out)
117f7765cecSBarry Smith {
11887828ca2SBarry Smith   PetscScalar sum;
119b4fd4287SBarry Smith   int         j,n = sp->n,N,ierr;
1205cfeda75SBarry Smith   Vec         l = vec;
121f7765cecSBarry Smith 
1223a40ed3dSBarry Smith   PetscFunctionBegin;
1235cfeda75SBarry Smith   if (out) {
1245cfeda75SBarry Smith     if (!sp->vec) {
1255cfeda75SBarry Smith       ierr = VecDuplicate(vec,&sp->vec);CHKERRQ(ierr);
1265cfeda75SBarry Smith     }
1275cfeda75SBarry Smith     *out = sp->vec;
1285cfeda75SBarry Smith     ierr = VecCopy(vec,*out);CHKERRQ(ierr);
1295cfeda75SBarry Smith     l    = *out;
1305cfeda75SBarry Smith   }
1315cfeda75SBarry Smith 
132b4fd4287SBarry Smith   if (sp->has_cnst) {
1335cfeda75SBarry Smith     ierr = VecSum(l,&sum);CHKERRQ(ierr);
1345cfeda75SBarry Smith     ierr = VecGetSize(l,&N);CHKERRQ(ierr);
13518a7d68fSSatish Balay     sum  = sum/(-1.0*N);
1365cfeda75SBarry Smith     ierr = VecShift(&sum,l);CHKERRQ(ierr);
137f7765cecSBarry Smith   }
138b4fd4287SBarry Smith 
139b4fd4287SBarry Smith   for (j=0; j<n; j++) {
1405cfeda75SBarry Smith     ierr = VecDot(l,sp->vecs[j],&sum);CHKERRQ(ierr);
141b4fd4287SBarry Smith     sum  = -sum;
1425cfeda75SBarry Smith     ierr = VecAXPY(&sum,sp->vecs[j],l);CHKERRQ(ierr);
143f7765cecSBarry Smith   }
144b4fd4287SBarry Smith 
1453a40ed3dSBarry Smith   PetscFunctionReturn(0);
146f7765cecSBarry Smith }
147a2e34c3dSBarry Smith 
1484a2ae208SSatish Balay #undef __FUNCT__
1494a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceTest"
150a2e34c3dSBarry Smith /*@
151a2e34c3dSBarry Smith    MatNullSpaceTest  - Tests if the claimed null space is really a
152a2e34c3dSBarry Smith      null space of a matrix
153a2e34c3dSBarry Smith 
154a2e34c3dSBarry Smith    Collective on MatNullSpace
155a2e34c3dSBarry Smith 
156a2e34c3dSBarry Smith    Input Parameters:
157a2e34c3dSBarry Smith +  sp - the null space context
158a2e34c3dSBarry Smith -  mat - the matrix
159a2e34c3dSBarry Smith 
160a2e34c3dSBarry Smith    Level: advanced
161a2e34c3dSBarry Smith 
162a2e34c3dSBarry Smith .keywords: PC, null space, remove
163a2e34c3dSBarry Smith 
164a2e34c3dSBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy()
165a2e34c3dSBarry Smith @*/
166a2e34c3dSBarry Smith int MatNullSpaceTest(MatNullSpace sp,Mat mat)
167a2e34c3dSBarry Smith {
16887828ca2SBarry Smith   PetscScalar  sum;
1698bb6bcc5SSatish Balay   PetscReal    nrm;
170a2e34c3dSBarry Smith   int          j,n = sp->n,N,ierr,m;
171a2e34c3dSBarry Smith   Vec          l,r;
172a2e34c3dSBarry Smith   MPI_Comm     comm = sp->comm;
173a2e34c3dSBarry Smith   PetscTruth   flg1,flg2;
174a2e34c3dSBarry Smith 
175a2e34c3dSBarry Smith   PetscFunctionBegin;
176b0a32e0cSBarry Smith   ierr = PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view",&flg1);CHKERRQ(ierr);
177b0a32e0cSBarry Smith   ierr = PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view_draw",&flg2);CHKERRQ(ierr);
178a2e34c3dSBarry Smith 
179a2e34c3dSBarry Smith   if (!sp->vec) {
180a2e34c3dSBarry Smith     if (n) {
181a2e34c3dSBarry Smith       ierr = VecDuplicate(sp->vecs[0],&sp->vec);CHKERRQ(ierr);
182a2e34c3dSBarry Smith     } else {
183a2e34c3dSBarry Smith       ierr = MatGetLocalSize(mat,&m,PETSC_NULL);CHKERRQ(ierr);
184a2e34c3dSBarry Smith       ierr = VecCreateMPI(sp->comm,m,PETSC_DETERMINE,&sp->vec);CHKERRQ(ierr);
185a2e34c3dSBarry Smith     }
186a2e34c3dSBarry Smith   }
187a2e34c3dSBarry Smith   l    = sp->vec;
188a2e34c3dSBarry Smith 
189a2e34c3dSBarry Smith   if (sp->has_cnst) {
190a2e34c3dSBarry Smith     ierr = VecDuplicate(l,&r);CHKERRQ(ierr);
191a2e34c3dSBarry Smith     ierr = VecGetSize(l,&N);CHKERRQ(ierr);
192a2e34c3dSBarry Smith     sum  = 1.0/N;
193a2e34c3dSBarry Smith     ierr = VecSet(&sum,l);CHKERRQ(ierr);
194a2e34c3dSBarry Smith     ierr = MatMult(mat,l,r);CHKERRQ(ierr);
1958bb6bcc5SSatish Balay     ierr = VecNorm(r,NORM_2,&nrm);CHKERRQ(ierr);
1968bb6bcc5SSatish Balay     if (nrm < 1.e-7) {ierr = PetscPrintf(comm,"Constants are likely null vector");CHKERRQ(ierr);}
197a2e34c3dSBarry Smith     else {ierr = PetscPrintf(comm,"Constants are unlikely null vector ");CHKERRQ(ierr);}
1988bb6bcc5SSatish Balay     ierr = PetscPrintf(comm,"|| A * 1 || = %g\n",nrm);CHKERRQ(ierr);
199b0a32e0cSBarry Smith     if (nrm > 1.e-7 && flg1) {ierr = VecView(r,PETSC_VIEWER_STDOUT_(comm));CHKERRQ(ierr);}
200b0a32e0cSBarry Smith     if (nrm > 1.e-7 && flg2) {ierr = VecView(r,PETSC_VIEWER_DRAW_(comm));CHKERRQ(ierr);}
201a2e34c3dSBarry Smith     ierr = VecDestroy(r);CHKERRQ(ierr);
202a2e34c3dSBarry Smith   }
203a2e34c3dSBarry Smith 
204a2e34c3dSBarry Smith   for (j=0; j<n; j++) {
205a2e34c3dSBarry Smith     ierr = (*mat->ops->mult)(mat,sp->vecs[j],l);CHKERRQ(ierr);
2068bb6bcc5SSatish Balay     ierr = VecNorm(l,NORM_2,&nrm);CHKERRQ(ierr);
2078bb6bcc5SSatish Balay     if (nrm < 1.e-7) {ierr = PetscPrintf(comm,"Null vector %d is likely null vector",j);CHKERRQ(ierr);}
208a2e34c3dSBarry Smith     else {ierr = PetscPrintf(comm,"Null vector %d unlikely null vector ",j);CHKERRQ(ierr);}
2098bb6bcc5SSatish Balay     ierr = PetscPrintf(comm,"|| A * v[%d] || = %g\n",j,nrm);CHKERRQ(ierr);
210b0a32e0cSBarry Smith     if (nrm > 1.e-7 && flg1) {ierr = VecView(l,PETSC_VIEWER_STDOUT_(comm));CHKERRQ(ierr);}
211b0a32e0cSBarry Smith     if (nrm > 1.e-7 && flg2) {ierr = VecView(l,PETSC_VIEWER_DRAW_(comm));CHKERRQ(ierr);}
212a2e34c3dSBarry Smith   }
213a2e34c3dSBarry Smith 
214a2e34c3dSBarry Smith   PetscFunctionReturn(0);
215a2e34c3dSBarry Smith }
216a2e34c3dSBarry Smith 
217