1*a2e34c3dSBarry Smith /*$Id: matnull.c,v 1.32 2000/07/31 03:50:59 bsmith Exp bsmith $*/ 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 } 130*a2e34c3dSBarry Smith 131*a2e34c3dSBarry Smith #undef __FUNC__ 132*a2e34c3dSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatNullSpaceTest" 133*a2e34c3dSBarry Smith /*@ 134*a2e34c3dSBarry Smith MatNullSpaceTest - Tests if the claimed null space is really a 135*a2e34c3dSBarry Smith null space of a matrix 136*a2e34c3dSBarry Smith 137*a2e34c3dSBarry Smith Collective on MatNullSpace 138*a2e34c3dSBarry Smith 139*a2e34c3dSBarry Smith Input Parameters: 140*a2e34c3dSBarry Smith + sp - the null space context 141*a2e34c3dSBarry Smith - mat - the matrix 142*a2e34c3dSBarry Smith 143*a2e34c3dSBarry Smith Level: advanced 144*a2e34c3dSBarry Smith 145*a2e34c3dSBarry Smith .keywords: PC, null space, remove 146*a2e34c3dSBarry Smith 147*a2e34c3dSBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy() 148*a2e34c3dSBarry Smith @*/ 149*a2e34c3dSBarry Smith int MatNullSpaceTest(MatNullSpace sp,Mat mat) 150*a2e34c3dSBarry Smith { 151*a2e34c3dSBarry Smith Scalar sum; 152*a2e34c3dSBarry Smith int j,n = sp->n,N,ierr,m; 153*a2e34c3dSBarry Smith Vec l,r; 154*a2e34c3dSBarry Smith MPI_Comm comm = sp->comm; 155*a2e34c3dSBarry Smith PetscTruth flg1,flg2; 156*a2e34c3dSBarry Smith 157*a2e34c3dSBarry Smith PetscFunctionBegin; 158*a2e34c3dSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_null_space_test_view",&flg1);CHKERRQ(ierr); 159*a2e34c3dSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_null_space_test_view_draw",&flg2);CHKERRQ(ierr); 160*a2e34c3dSBarry Smith 161*a2e34c3dSBarry Smith if (!sp->vec) { 162*a2e34c3dSBarry Smith if (n) { 163*a2e34c3dSBarry Smith ierr = VecDuplicate(sp->vecs[0],&sp->vec);CHKERRQ(ierr); 164*a2e34c3dSBarry Smith } else { 165*a2e34c3dSBarry Smith ierr = MatGetLocalSize(mat,&m,PETSC_NULL);CHKERRQ(ierr); 166*a2e34c3dSBarry Smith ierr = VecCreateMPI(sp->comm,m,PETSC_DETERMINE,&sp->vec);CHKERRQ(ierr); 167*a2e34c3dSBarry Smith } 168*a2e34c3dSBarry Smith } 169*a2e34c3dSBarry Smith l = sp->vec; 170*a2e34c3dSBarry Smith 171*a2e34c3dSBarry Smith if (sp->has_cnst) { 172*a2e34c3dSBarry Smith ierr = VecDuplicate(l,&r);CHKERRQ(ierr); 173*a2e34c3dSBarry Smith ierr = VecGetSize(l,&N);CHKERRQ(ierr); 174*a2e34c3dSBarry Smith sum = 1.0/N; 175*a2e34c3dSBarry Smith ierr = VecSet(&sum,l);CHKERRQ(ierr); 176*a2e34c3dSBarry Smith ierr = MatMult(mat,l,r);CHKERRQ(ierr); 177*a2e34c3dSBarry Smith ierr = VecNorm(r,NORM_2,&sum);CHKERRQ(ierr); 178*a2e34c3dSBarry Smith if (sum < 1.e-7) {ierr = PetscPrintf(comm,"Constants are likely null vector");CHKERRQ(ierr);} 179*a2e34c3dSBarry Smith else {ierr = PetscPrintf(comm,"Constants are unlikely null vector ");CHKERRQ(ierr);} 180*a2e34c3dSBarry Smith ierr = PetscPrintf(comm,"|| A * 1 || = %g\n",sum);CHKERRQ(ierr); 181*a2e34c3dSBarry Smith if (sum > 1.e-7 && flg1) {ierr = VecView(r,VIEWER_STDOUT_(comm));CHKERRQ(ierr);} 182*a2e34c3dSBarry Smith if (sum > 1.e-7 && flg2) {ierr = VecView(r,VIEWER_DRAW_(comm));CHKERRQ(ierr);} 183*a2e34c3dSBarry Smith ierr = VecDestroy(r);CHKERRQ(ierr); 184*a2e34c3dSBarry Smith } 185*a2e34c3dSBarry Smith 186*a2e34c3dSBarry Smith for (j=0; j<n; j++) { 187*a2e34c3dSBarry Smith ierr = (*mat->ops->mult)(mat,sp->vecs[j],l);CHKERRQ(ierr); 188*a2e34c3dSBarry Smith ierr = VecNorm(l,NORM_2,&sum);CHKERRQ(ierr); 189*a2e34c3dSBarry Smith if (sum < 1.e-7) {ierr = PetscPrintf(comm,"Null vector %d is likely null vector",j);CHKERRQ(ierr);} 190*a2e34c3dSBarry Smith else {ierr = PetscPrintf(comm,"Null vector %d unlikely null vector ",j);CHKERRQ(ierr);} 191*a2e34c3dSBarry Smith ierr = PetscPrintf(comm,"|| A * v[%d] || = %g\n",j,sum);CHKERRQ(ierr); 192*a2e34c3dSBarry Smith if (sum > 1.e-7 && flg1) {ierr = VecView(l,VIEWER_STDOUT_(comm));CHKERRQ(ierr);} 193*a2e34c3dSBarry Smith if (sum > 1.e-7 && flg2) {ierr = VecView(l,VIEWER_DRAW_(comm));CHKERRQ(ierr);} 194*a2e34c3dSBarry Smith } 195*a2e34c3dSBarry Smith 196*a2e34c3dSBarry Smith PetscFunctionReturn(0); 197*a2e34c3dSBarry Smith } 198*a2e34c3dSBarry Smith 199