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: }