xref: /petsc/src/mat/interface/matnull.c (revision 8bb6bcc5f2ec8c4de9acc1bc2451c00a7df385a7)
1*8bb6bcc5SSatish Balay /*$Id: matnull.c,v 1.33 2000/08/01 20:01:52 bsmith Exp balay $*/
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 
95615d1e5SSatish Balay #undef __FUNC__
105cfeda75SBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatNullSpaceCreate"
11112a2221SBarry Smith /*@C
125cfeda75SBarry Smith    MatNullSpaceCreate - Creates a data structure used to project vectors
13b4fd4287SBarry Smith    out of null spaces.
14f7765cecSBarry Smith 
154e472627SLois Curfman McInnes    Collective on MPI_Comm
164e472627SLois Curfman McInnes 
17f7765cecSBarry Smith    Input Parameters:
1883c3bef8SLois Curfman McInnes +  comm - the MPI communicator associated with the object
1983c3bef8SLois Curfman McInnes .  has_cnst - PETSC_TRUE if the null space contains the constant vector; otherwise PETSC_FALSE
20b4fd4287SBarry Smith .  n - number of vectors (excluding constant vector) in null space
2183c3bef8SLois Curfman McInnes -  vecs - the vectors that span the null space (excluding the constant vector);
224e472627SLois Curfman McInnes           these vectors must be orthonormal
23f7765cecSBarry Smith 
24f7765cecSBarry Smith    Output Parameter:
25b4fd4287SBarry Smith .  SP - the null space context
26f7765cecSBarry Smith 
2783c3bef8SLois Curfman McInnes    Level: advanced
2883c3bef8SLois Curfman McInnes 
2983c3bef8SLois Curfman McInnes .keywords: PC, null space, create
3041a59933SSatish Balay 
315cfeda75SBarry Smith .seealso: MatNullSpaceDestroy(), MatNullSpaceRemove()
32f7765cecSBarry Smith @*/
335cfeda75SBarry Smith int MatNullSpaceCreate(MPI_Comm comm,int has_cnst,int n,Vec *vecs,MatNullSpace *SP)
34f7765cecSBarry Smith {
355cfeda75SBarry Smith   MatNullSpace sp;
36f7765cecSBarry Smith 
373a40ed3dSBarry Smith   PetscFunctionBegin;
385cfeda75SBarry Smith   PetscHeaderCreate(sp,_p_MatNullSpace,int,MATNULLSPACE_COOKIE,0,"MatNullSpace",comm,MatNullSpaceDestroy,0);
39b4fd4287SBarry Smith   PLogObjectCreate(sp);
405cfeda75SBarry Smith   PLogObjectMemory(sp,sizeof(struct _p_MatNullSpace));
41f7765cecSBarry Smith 
42b4fd4287SBarry Smith   sp->has_cnst = has_cnst;
43b4fd4287SBarry Smith   sp->n        = n;
44b4fd4287SBarry Smith   sp->vecs     = vecs;
455cfeda75SBarry Smith   sp->vec      = PETSC_NULL;
46b4fd4287SBarry Smith 
47b4fd4287SBarry Smith   *SP          = sp;
483a40ed3dSBarry Smith   PetscFunctionReturn(0);
49f7765cecSBarry Smith }
50f7765cecSBarry Smith 
515615d1e5SSatish Balay #undef __FUNC__
525cfeda75SBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatNullSpaceDestroy"
53f7765cecSBarry Smith /*@
545cfeda75SBarry Smith    MatNullSpaceDestroy - Destroys a data structure used to project vectors
55b4fd4287SBarry Smith    out of null spaces.
56b4fd4287SBarry Smith 
575cfeda75SBarry Smith    Collective on MatNullSpace
584e472627SLois Curfman McInnes 
59b4fd4287SBarry Smith    Input Parameter:
60b9756687SLois Curfman McInnes .  sp - the null space context to be destroyed
61b9756687SLois Curfman McInnes 
62b9756687SLois Curfman McInnes    Level: advanced
63b4fd4287SBarry Smith 
6483c3bef8SLois Curfman McInnes .keywords: PC, null space, destroy
6541a59933SSatish Balay 
665cfeda75SBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceRemove()
67b4fd4287SBarry Smith @*/
685cfeda75SBarry Smith int MatNullSpaceDestroy(MatNullSpace sp)
69b4fd4287SBarry Smith {
705cfeda75SBarry Smith   int ierr;
7185614651SBarry Smith 
725cfeda75SBarry Smith   PetscFunctionBegin;
7385614651SBarry Smith   if (--sp->refct > 0) PetscFunctionReturn(0);
7485614651SBarry Smith 
755cfeda75SBarry Smith   if (sp->vec) {ierr = VecDestroy(sp->vec);CHKERRQ(ierr);}
765cfeda75SBarry Smith 
77b4fd4287SBarry Smith   PLogObjectDestroy(sp);
78b4fd4287SBarry Smith   PetscHeaderDestroy(sp);
793a40ed3dSBarry Smith   PetscFunctionReturn(0);
80b4fd4287SBarry Smith }
81b4fd4287SBarry Smith 
825615d1e5SSatish Balay #undef __FUNC__
835cfeda75SBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatNullSpaceRemove"
84b4fd4287SBarry Smith /*@
855cfeda75SBarry Smith    MatNullSpaceRemove - Removes all the components of a null space from a vector.
86f7765cecSBarry Smith 
875cfeda75SBarry Smith    Collective on MatNullSpace
88f7765cecSBarry Smith 
894e472627SLois Curfman McInnes    Input Parameters:
904e472627SLois Curfman McInnes +  sp - the null space context
9183c3bef8SLois Curfman McInnes -  vec - the vector from which the null space is to be removed
924e472627SLois Curfman McInnes 
93b9756687SLois Curfman McInnes    Level: advanced
94b9756687SLois Curfman McInnes 
9583c3bef8SLois Curfman McInnes .keywords: PC, null space, remove
9641a59933SSatish Balay 
975cfeda75SBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy()
98f7765cecSBarry Smith @*/
995cfeda75SBarry Smith int MatNullSpaceRemove(MatNullSpace sp,Vec vec,Vec *out)
100f7765cecSBarry Smith {
101b4fd4287SBarry Smith   Scalar sum;
102b4fd4287SBarry Smith   int    j,n = sp->n,N,ierr;
1035cfeda75SBarry Smith   Vec    l = vec;
104f7765cecSBarry Smith 
1053a40ed3dSBarry Smith   PetscFunctionBegin;
1065cfeda75SBarry Smith   if (out) {
1075cfeda75SBarry Smith     if (!sp->vec) {
1085cfeda75SBarry Smith       ierr = VecDuplicate(vec,&sp->vec);CHKERRQ(ierr);
1095cfeda75SBarry Smith     }
1105cfeda75SBarry Smith     *out = sp->vec;
1115cfeda75SBarry Smith     ierr = VecCopy(vec,*out);CHKERRQ(ierr);
1125cfeda75SBarry Smith     l    = *out;
1135cfeda75SBarry Smith   }
1145cfeda75SBarry Smith 
115b4fd4287SBarry Smith   if (sp->has_cnst) {
1165cfeda75SBarry Smith     ierr = VecSum(l,&sum);CHKERRQ(ierr);
1175cfeda75SBarry Smith     ierr = VecGetSize(l,&N);CHKERRQ(ierr);
11818a7d68fSSatish Balay     sum  = sum/(-1.0*N);
1195cfeda75SBarry Smith     ierr = VecShift(&sum,l);CHKERRQ(ierr);
120f7765cecSBarry Smith   }
121b4fd4287SBarry Smith 
122b4fd4287SBarry Smith   for (j=0; j<n; j++) {
1235cfeda75SBarry Smith     ierr = VecDot(l,sp->vecs[j],&sum);CHKERRQ(ierr);
124b4fd4287SBarry Smith     sum  = -sum;
1255cfeda75SBarry Smith     ierr = VecAXPY(&sum,sp->vecs[j],l);CHKERRQ(ierr);
126f7765cecSBarry Smith   }
127b4fd4287SBarry Smith 
1283a40ed3dSBarry Smith   PetscFunctionReturn(0);
129f7765cecSBarry Smith }
130a2e34c3dSBarry Smith 
131a2e34c3dSBarry Smith #undef __FUNC__
132a2e34c3dSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatNullSpaceTest"
133a2e34c3dSBarry Smith /*@
134a2e34c3dSBarry Smith    MatNullSpaceTest  - Tests if the claimed null space is really a
135a2e34c3dSBarry Smith      null space of a matrix
136a2e34c3dSBarry Smith 
137a2e34c3dSBarry Smith    Collective on MatNullSpace
138a2e34c3dSBarry Smith 
139a2e34c3dSBarry Smith    Input Parameters:
140a2e34c3dSBarry Smith +  sp - the null space context
141a2e34c3dSBarry Smith -  mat - the matrix
142a2e34c3dSBarry Smith 
143a2e34c3dSBarry Smith    Level: advanced
144a2e34c3dSBarry Smith 
145a2e34c3dSBarry Smith .keywords: PC, null space, remove
146a2e34c3dSBarry Smith 
147a2e34c3dSBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy()
148a2e34c3dSBarry Smith @*/
149a2e34c3dSBarry Smith int MatNullSpaceTest(MatNullSpace sp,Mat mat)
150a2e34c3dSBarry Smith {
151a2e34c3dSBarry Smith   Scalar     sum;
152*8bb6bcc5SSatish Balay   PetscReal  nrm;
153a2e34c3dSBarry Smith   int        j,n = sp->n,N,ierr,m;
154a2e34c3dSBarry Smith   Vec        l,r;
155a2e34c3dSBarry Smith   MPI_Comm   comm = sp->comm;
156a2e34c3dSBarry Smith   PetscTruth flg1,flg2;
157a2e34c3dSBarry Smith 
158a2e34c3dSBarry Smith   PetscFunctionBegin;
159a2e34c3dSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-mat_null_space_test_view",&flg1);CHKERRQ(ierr);
160a2e34c3dSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-mat_null_space_test_view_draw",&flg2);CHKERRQ(ierr);
161a2e34c3dSBarry Smith 
162a2e34c3dSBarry Smith   if (!sp->vec) {
163a2e34c3dSBarry Smith     if (n) {
164a2e34c3dSBarry Smith       ierr = VecDuplicate(sp->vecs[0],&sp->vec);CHKERRQ(ierr);
165a2e34c3dSBarry Smith     } else {
166a2e34c3dSBarry Smith       ierr = MatGetLocalSize(mat,&m,PETSC_NULL);CHKERRQ(ierr);
167a2e34c3dSBarry Smith       ierr = VecCreateMPI(sp->comm,m,PETSC_DETERMINE,&sp->vec);CHKERRQ(ierr);
168a2e34c3dSBarry Smith     }
169a2e34c3dSBarry Smith   }
170a2e34c3dSBarry Smith   l    = sp->vec;
171a2e34c3dSBarry Smith 
172a2e34c3dSBarry Smith   if (sp->has_cnst) {
173a2e34c3dSBarry Smith     ierr = VecDuplicate(l,&r);CHKERRQ(ierr);
174a2e34c3dSBarry Smith     ierr = VecGetSize(l,&N);CHKERRQ(ierr);
175a2e34c3dSBarry Smith     sum  = 1.0/N;
176a2e34c3dSBarry Smith     ierr = VecSet(&sum,l);CHKERRQ(ierr);
177a2e34c3dSBarry Smith     ierr = MatMult(mat,l,r);CHKERRQ(ierr);
178*8bb6bcc5SSatish Balay     ierr = VecNorm(r,NORM_2,&nrm);CHKERRQ(ierr);
179*8bb6bcc5SSatish Balay     if (nrm < 1.e-7) {ierr = PetscPrintf(comm,"Constants are likely null vector");CHKERRQ(ierr);}
180a2e34c3dSBarry Smith     else {ierr = PetscPrintf(comm,"Constants are unlikely null vector ");CHKERRQ(ierr);}
181*8bb6bcc5SSatish Balay     ierr = PetscPrintf(comm,"|| A * 1 || = %g\n",nrm);CHKERRQ(ierr);
182*8bb6bcc5SSatish Balay     if (nrm > 1.e-7 && flg1) {ierr = VecView(r,VIEWER_STDOUT_(comm));CHKERRQ(ierr);}
183*8bb6bcc5SSatish Balay     if (nrm > 1.e-7 && flg2) {ierr = VecView(r,VIEWER_DRAW_(comm));CHKERRQ(ierr);}
184a2e34c3dSBarry Smith     ierr = VecDestroy(r);CHKERRQ(ierr);
185a2e34c3dSBarry Smith   }
186a2e34c3dSBarry Smith 
187a2e34c3dSBarry Smith   for (j=0; j<n; j++) {
188a2e34c3dSBarry Smith     ierr = (*mat->ops->mult)(mat,sp->vecs[j],l);CHKERRQ(ierr);
189*8bb6bcc5SSatish Balay     ierr = VecNorm(l,NORM_2,&nrm);CHKERRQ(ierr);
190*8bb6bcc5SSatish Balay     if (nrm < 1.e-7) {ierr = PetscPrintf(comm,"Null vector %d is likely null vector",j);CHKERRQ(ierr);}
191a2e34c3dSBarry Smith     else {ierr = PetscPrintf(comm,"Null vector %d unlikely null vector ",j);CHKERRQ(ierr);}
192*8bb6bcc5SSatish Balay     ierr = PetscPrintf(comm,"|| A * v[%d] || = %g\n",j,nrm);CHKERRQ(ierr);
193*8bb6bcc5SSatish Balay     if (nrm > 1.e-7 && flg1) {ierr = VecView(l,VIEWER_STDOUT_(comm));CHKERRQ(ierr);}
194*8bb6bcc5SSatish Balay     if (nrm > 1.e-7 && flg2) {ierr = VecView(l,VIEWER_DRAW_(comm));CHKERRQ(ierr);}
195a2e34c3dSBarry Smith   }
196a2e34c3dSBarry Smith 
197a2e34c3dSBarry Smith   PetscFunctionReturn(0);
198a2e34c3dSBarry Smith }
199a2e34c3dSBarry Smith 
200