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: .keywords: PC, null space, create
31: .seealso: MatNullSpaceDestroy(), MatNullSpaceRemove(), PCNullSpaceAttach()
32: @*/
33: int MatNullSpaceCreate(MPI_Comm comm,int has_cnst,int n,Vec *vecs,MatNullSpace *SP)
34: {
35: MatNullSpace sp;
38: PetscHeaderCreate(sp,_p_MatNullSpace,int,MAT_NULLSPACE_COOKIE,0,"MatNullSpace",comm,MatNullSpaceDestroy,0);
39: PetscLogObjectCreate(sp);
40: PetscLogObjectMemory(sp,sizeof(struct _p_MatNullSpace));
42: sp->has_cnst = has_cnst;
43: sp->n = n;
44: sp->vecs = vecs;
45: sp->vec = PETSC_NULL;
47: *SP = sp;
48: return(0);
49: }
51: /*@
52: MatNullSpaceDestroy - Destroys a data structure used to project vectors
53: out of null spaces.
55: Collective on MatNullSpace
57: Input Parameter:
58: . sp - the null space context to be destroyed
60: Level: advanced
62: .keywords: PC, null space, destroy
64: .seealso: MatNullSpaceCreate(), MatNullSpaceRemove()
65: @*/
66: int MatNullSpaceDestroy(MatNullSpace sp)
67: {
71: if (--sp->refct > 0) return(0);
73: if (sp->vec) {VecDestroy(sp->vec);}
75: PetscLogObjectDestroy(sp);
76: PetscHeaderDestroy(sp);
77: return(0);
78: }
80: /*@
81: MatNullSpaceRemove - Removes all the components of a null space from a vector.
83: Collective on MatNullSpace
85: Input Parameters:
86: + sp - the null space context
87: - vec - the vector from which the null space is to be removed
89: Level: advanced
91: .keywords: PC, null space, remove
93: .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy()
94: @*/
95: int MatNullSpaceRemove(MatNullSpace sp,Vec vec,Vec *out)
96: {
97: PetscScalar sum;
98: int j,n = sp->n,N,ierr;
99: Vec l = vec;
102: if (out) {
103: if (!sp->vec) {
104: VecDuplicate(vec,&sp->vec);
105: }
106: *out = sp->vec;
107: VecCopy(vec,*out);
108: l = *out;
109: }
111: if (sp->has_cnst) {
112: VecSum(l,&sum);
113: VecGetSize(l,&N);
114: sum = sum/(-1.0*N);
115: VecShift(&sum,l);
116: }
118: for (j=0; j<n; j++) {
119: VecDot(l,sp->vecs[j],&sum);
120: sum = -sum;
121: VecAXPY(&sum,sp->vecs[j],l);
122: }
123:
124: return(0);
125: }
127: /*@
128: MatNullSpaceTest - Tests if the claimed null space is really a
129: null space of a matrix
131: Collective on MatNullSpace
133: Input Parameters:
134: + sp - the null space context
135: - mat - the matrix
137: Level: advanced
139: .keywords: PC, null space, remove
141: .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy()
142: @*/
143: int MatNullSpaceTest(MatNullSpace sp,Mat mat)
144: {
145: PetscScalar sum;
146: PetscReal nrm;
147: int j,n = sp->n,N,ierr,m;
148: Vec l,r;
149: MPI_Comm comm = sp->comm;
150: PetscTruth flg1,flg2;
153: PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view",&flg1);
154: PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view_draw",&flg2);
156: if (!sp->vec) {
157: if (n) {
158: VecDuplicate(sp->vecs[0],&sp->vec);
159: } else {
160: MatGetLocalSize(mat,&m,PETSC_NULL);
161: VecCreateMPI(sp->comm,m,PETSC_DETERMINE,&sp->vec);
162: }
163: }
164: l = sp->vec;
166: if (sp->has_cnst) {
167: VecDuplicate(l,&r);
168: VecGetSize(l,&N);
169: sum = 1.0/N;
170: VecSet(&sum,l);
171: MatMult(mat,l,r);
172: VecNorm(r,NORM_2,&nrm);
173: if (nrm < 1.e-7) {PetscPrintf(comm,"Constants are likely null vector");}
174: else {PetscPrintf(comm,"Constants are unlikely null vector ");}
175: PetscPrintf(comm,"|| A * 1 || = %gn",nrm);
176: if (nrm > 1.e-7 && flg1) {VecView(r,PETSC_VIEWER_STDOUT_(comm));}
177: if (nrm > 1.e-7 && flg2) {VecView(r,PETSC_VIEWER_DRAW_(comm));}
178: VecDestroy(r);
179: }
181: for (j=0; j<n; j++) {
182: (*mat->ops->mult)(mat,sp->vecs[j],l);
183: VecNorm(l,NORM_2,&nrm);
184: if (nrm < 1.e-7) {PetscPrintf(comm,"Null vector %d is likely null vector",j);}
185: else {PetscPrintf(comm,"Null vector %d unlikely null vector ",j);}
186: PetscPrintf(comm,"|| A * v[%d] || = %gn",j,nrm);
187: if (nrm > 1.e-7 && flg1) {VecView(l,PETSC_VIEWER_STDOUT_(comm));}
188: if (nrm > 1.e-7 && flg2) {VecView(l,PETSC_VIEWER_DRAW_(comm));}
189: }
190:
191: return(0);
192: }