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: Users manual sections:
30: . Section 4.15 Solving Singular Systems
32: .keywords: PC, null space, create
34: .seealso: MatNullSpaceDestroy(), MatNullSpaceRemove(), PCNullSpaceAttach(), MatNullSpace
35: @*/
36: int MatNullSpaceCreate(MPI_Comm comm,int has_cnst,int n,Vec *vecs,MatNullSpace *SP)
37: {
38: MatNullSpace sp;
41: PetscHeaderCreate(sp,_p_MatNullSpace,int,MAT_NULLSPACE_COOKIE,0,"MatNullSpace",comm,MatNullSpaceDestroy,0);
42: PetscLogObjectCreate(sp);
43: PetscLogObjectMemory(sp,sizeof(struct _p_MatNullSpace));
45: sp->has_cnst = has_cnst;
46: sp->n = n;
47: sp->vecs = vecs;
48: sp->vec = PETSC_NULL;
50: *SP = sp;
51: return(0);
52: }
54: /*@
55: MatNullSpaceDestroy - Destroys a data structure used to project vectors
56: out of null spaces.
58: Collective on MatNullSpace
60: Input Parameter:
61: . sp - the null space context to be destroyed
63: Level: advanced
65: .keywords: PC, null space, destroy
67: .seealso: MatNullSpaceCreate(), MatNullSpaceRemove()
68: @*/
69: int MatNullSpaceDestroy(MatNullSpace sp)
70: {
74: if (--sp->refct > 0) return(0);
76: if (sp->vec) {VecDestroy(sp->vec);}
78: PetscLogObjectDestroy(sp);
79: PetscHeaderDestroy(sp);
80: return(0);
81: }
83: /*@
84: MatNullSpaceRemove - Removes all the components of a null space from a vector.
86: Collective on MatNullSpace
88: Input Parameters:
89: + sp - the null space context
90: - vec - the vector from which the null space is to be removed
92: Level: advanced
94: .keywords: PC, null space, remove
96: .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy()
97: @*/
98: int MatNullSpaceRemove(MatNullSpace sp,Vec vec,Vec *out)
99: {
100: PetscScalar sum;
101: int j,n = sp->n,N,ierr;
102: Vec l = vec;
105: if (out) {
106: if (!sp->vec) {
107: VecDuplicate(vec,&sp->vec);
108: }
109: *out = sp->vec;
110: VecCopy(vec,*out);
111: l = *out;
112: }
114: if (sp->has_cnst) {
115: VecSum(l,&sum);
116: VecGetSize(l,&N);
117: sum = sum/(-1.0*N);
118: VecShift(&sum,l);
119: }
121: for (j=0; j<n; j++) {
122: VecDot(l,sp->vecs[j],&sum);
123: sum = -sum;
124: VecAXPY(&sum,sp->vecs[j],l);
125: }
126:
127: return(0);
128: }
130: /*@
131: MatNullSpaceTest - Tests if the claimed null space is really a
132: null space of a matrix
134: Collective on MatNullSpace
136: Input Parameters:
137: + sp - the null space context
138: - mat - the matrix
140: Level: advanced
142: .keywords: PC, null space, remove
144: .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy()
145: @*/
146: int MatNullSpaceTest(MatNullSpace sp,Mat mat)
147: {
148: PetscScalar sum;
149: PetscReal nrm;
150: int j,n = sp->n,N,ierr,m;
151: Vec l,r;
152: MPI_Comm comm = sp->comm;
153: PetscTruth flg1,flg2;
156: PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view",&flg1);
157: PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view_draw",&flg2);
159: if (!sp->vec) {
160: if (n) {
161: VecDuplicate(sp->vecs[0],&sp->vec);
162: } else {
163: MatGetLocalSize(mat,&m,PETSC_NULL);
164: VecCreateMPI(sp->comm,m,PETSC_DETERMINE,&sp->vec);
165: }
166: }
167: l = sp->vec;
169: if (sp->has_cnst) {
170: VecDuplicate(l,&r);
171: VecGetSize(l,&N);
172: sum = 1.0/N;
173: VecSet(&sum,l);
174: MatMult(mat,l,r);
175: VecNorm(r,NORM_2,&nrm);
176: if (nrm < 1.e-7) {PetscPrintf(comm,"Constants are likely null vector");}
177: else {PetscPrintf(comm,"Constants are unlikely null vector ");}
178: PetscPrintf(comm,"|| A * 1 || = %gn",nrm);
179: if (nrm > 1.e-7 && flg1) {VecView(r,PETSC_VIEWER_STDOUT_(comm));}
180: if (nrm > 1.e-7 && flg2) {VecView(r,PETSC_VIEWER_DRAW_(comm));}
181: VecDestroy(r);
182: }
184: for (j=0; j<n; j++) {
185: (*mat->ops->mult)(mat,sp->vecs[j],l);
186: VecNorm(l,NORM_2,&nrm);
187: if (nrm < 1.e-7) {PetscPrintf(comm,"Null vector %d is likely null vector",j);}
188: else {PetscPrintf(comm,"Null vector %d unlikely null vector ",j);}
189: PetscPrintf(comm,"|| A * v[%d] || = %gn",j,nrm);
190: if (nrm > 1.e-7 && flg1) {VecView(l,PETSC_VIEWER_STDOUT_(comm));}
191: if (nrm > 1.e-7 && flg2) {VecView(l,PETSC_VIEWER_DRAW_(comm));}
192: }
193:
194: return(0);
195: }