173f4d377SMatthew Knepley /*$Id: matnull.c,v 1.40 2001/09/07 20:09:09 bsmith Exp $*/ 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 98ba1e511SMatthew Knepley int MAT_NULLSPACE_COOKIE; 108ba1e511SMatthew Knepley 114a2ae208SSatish Balay #undef __FUNCT__ 124a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceCreate" 13112a2221SBarry Smith /*@C 145cfeda75SBarry Smith MatNullSpaceCreate - Creates a data structure used to project vectors 15b4fd4287SBarry Smith out of null spaces. 16f7765cecSBarry Smith 174e472627SLois Curfman McInnes Collective on MPI_Comm 184e472627SLois Curfman McInnes 19f7765cecSBarry Smith Input Parameters: 2083c3bef8SLois Curfman McInnes + comm - the MPI communicator associated with the object 2183c3bef8SLois Curfman McInnes . has_cnst - PETSC_TRUE if the null space contains the constant vector; otherwise PETSC_FALSE 22b4fd4287SBarry Smith . n - number of vectors (excluding constant vector) in null space 2383c3bef8SLois Curfman McInnes - vecs - the vectors that span the null space (excluding the constant vector); 244e472627SLois Curfman McInnes these vectors must be orthonormal 25f7765cecSBarry Smith 26f7765cecSBarry Smith Output Parameter: 27b4fd4287SBarry Smith . SP - the null space context 28f7765cecSBarry Smith 2983c3bef8SLois Curfman McInnes Level: advanced 3083c3bef8SLois Curfman McInnes 31*6e1639daSBarry Smith Users manual sections: 32*6e1639daSBarry Smith . sec_singular 33*6e1639daSBarry Smith 3483c3bef8SLois Curfman McInnes .keywords: PC, null space, create 3541a59933SSatish Balay 36*6e1639daSBarry Smith .seealso: MatNullSpaceDestroy(), MatNullSpaceRemove(), PCNullSpaceAttach(), MatNullSpace 37f7765cecSBarry Smith @*/ 385cfeda75SBarry Smith int MatNullSpaceCreate(MPI_Comm comm,int has_cnst,int n,Vec *vecs,MatNullSpace *SP) 39f7765cecSBarry Smith { 405cfeda75SBarry Smith MatNullSpace sp; 41f7765cecSBarry Smith 423a40ed3dSBarry Smith PetscFunctionBegin; 438ba1e511SMatthew Knepley PetscHeaderCreate(sp,_p_MatNullSpace,int,MAT_NULLSPACE_COOKIE,0,"MatNullSpace",comm,MatNullSpaceDestroy,0); 44b0a32e0cSBarry Smith PetscLogObjectCreate(sp); 45b0a32e0cSBarry Smith PetscLogObjectMemory(sp,sizeof(struct _p_MatNullSpace)); 46f7765cecSBarry Smith 47b4fd4287SBarry Smith sp->has_cnst = has_cnst; 48b4fd4287SBarry Smith sp->n = n; 49b4fd4287SBarry Smith sp->vecs = vecs; 505cfeda75SBarry Smith sp->vec = PETSC_NULL; 51b4fd4287SBarry Smith 52b4fd4287SBarry Smith *SP = sp; 533a40ed3dSBarry Smith PetscFunctionReturn(0); 54f7765cecSBarry Smith } 55f7765cecSBarry Smith 564a2ae208SSatish Balay #undef __FUNCT__ 574a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceDestroy" 58f7765cecSBarry Smith /*@ 595cfeda75SBarry Smith MatNullSpaceDestroy - Destroys a data structure used to project vectors 60b4fd4287SBarry Smith out of null spaces. 61b4fd4287SBarry Smith 625cfeda75SBarry Smith Collective on MatNullSpace 634e472627SLois Curfman McInnes 64b4fd4287SBarry Smith Input Parameter: 65b9756687SLois Curfman McInnes . sp - the null space context to be destroyed 66b9756687SLois Curfman McInnes 67b9756687SLois Curfman McInnes Level: advanced 68b4fd4287SBarry Smith 6983c3bef8SLois Curfman McInnes .keywords: PC, null space, destroy 7041a59933SSatish Balay 715cfeda75SBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceRemove() 72b4fd4287SBarry Smith @*/ 735cfeda75SBarry Smith int MatNullSpaceDestroy(MatNullSpace sp) 74b4fd4287SBarry Smith { 755cfeda75SBarry Smith int ierr; 7685614651SBarry Smith 775cfeda75SBarry Smith PetscFunctionBegin; 7885614651SBarry Smith if (--sp->refct > 0) PetscFunctionReturn(0); 7985614651SBarry Smith 805cfeda75SBarry Smith if (sp->vec) {ierr = VecDestroy(sp->vec);CHKERRQ(ierr);} 815cfeda75SBarry Smith 82b0a32e0cSBarry Smith PetscLogObjectDestroy(sp); 83b4fd4287SBarry Smith PetscHeaderDestroy(sp); 843a40ed3dSBarry Smith PetscFunctionReturn(0); 85b4fd4287SBarry Smith } 86b4fd4287SBarry Smith 874a2ae208SSatish Balay #undef __FUNCT__ 884a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceRemove" 89b4fd4287SBarry Smith /*@ 905cfeda75SBarry Smith MatNullSpaceRemove - Removes all the components of a null space from a vector. 91f7765cecSBarry Smith 925cfeda75SBarry Smith Collective on MatNullSpace 93f7765cecSBarry Smith 944e472627SLois Curfman McInnes Input Parameters: 954e472627SLois Curfman McInnes + sp - the null space context 9683c3bef8SLois Curfman McInnes - vec - the vector from which the null space is to be removed 974e472627SLois Curfman McInnes 98b9756687SLois Curfman McInnes Level: advanced 99b9756687SLois Curfman McInnes 10083c3bef8SLois Curfman McInnes .keywords: PC, null space, remove 10141a59933SSatish Balay 1025cfeda75SBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy() 103f7765cecSBarry Smith @*/ 1045cfeda75SBarry Smith int MatNullSpaceRemove(MatNullSpace sp,Vec vec,Vec *out) 105f7765cecSBarry Smith { 10687828ca2SBarry Smith PetscScalar sum; 107b4fd4287SBarry Smith int j,n = sp->n,N,ierr; 1085cfeda75SBarry Smith Vec l = vec; 109f7765cecSBarry Smith 1103a40ed3dSBarry Smith PetscFunctionBegin; 1115cfeda75SBarry Smith if (out) { 1125cfeda75SBarry Smith if (!sp->vec) { 1135cfeda75SBarry Smith ierr = VecDuplicate(vec,&sp->vec);CHKERRQ(ierr); 1145cfeda75SBarry Smith } 1155cfeda75SBarry Smith *out = sp->vec; 1165cfeda75SBarry Smith ierr = VecCopy(vec,*out);CHKERRQ(ierr); 1175cfeda75SBarry Smith l = *out; 1185cfeda75SBarry Smith } 1195cfeda75SBarry Smith 120b4fd4287SBarry Smith if (sp->has_cnst) { 1215cfeda75SBarry Smith ierr = VecSum(l,&sum);CHKERRQ(ierr); 1225cfeda75SBarry Smith ierr = VecGetSize(l,&N);CHKERRQ(ierr); 12318a7d68fSSatish Balay sum = sum/(-1.0*N); 1245cfeda75SBarry Smith ierr = VecShift(&sum,l);CHKERRQ(ierr); 125f7765cecSBarry Smith } 126b4fd4287SBarry Smith 127b4fd4287SBarry Smith for (j=0; j<n; j++) { 1285cfeda75SBarry Smith ierr = VecDot(l,sp->vecs[j],&sum);CHKERRQ(ierr); 129b4fd4287SBarry Smith sum = -sum; 1305cfeda75SBarry Smith ierr = VecAXPY(&sum,sp->vecs[j],l);CHKERRQ(ierr); 131f7765cecSBarry Smith } 132b4fd4287SBarry Smith 1333a40ed3dSBarry Smith PetscFunctionReturn(0); 134f7765cecSBarry Smith } 135a2e34c3dSBarry Smith 1364a2ae208SSatish Balay #undef __FUNCT__ 1374a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceTest" 138a2e34c3dSBarry Smith /*@ 139a2e34c3dSBarry Smith MatNullSpaceTest - Tests if the claimed null space is really a 140a2e34c3dSBarry Smith null space of a matrix 141a2e34c3dSBarry Smith 142a2e34c3dSBarry Smith Collective on MatNullSpace 143a2e34c3dSBarry Smith 144a2e34c3dSBarry Smith Input Parameters: 145a2e34c3dSBarry Smith + sp - the null space context 146a2e34c3dSBarry Smith - mat - the matrix 147a2e34c3dSBarry Smith 148a2e34c3dSBarry Smith Level: advanced 149a2e34c3dSBarry Smith 150a2e34c3dSBarry Smith .keywords: PC, null space, remove 151a2e34c3dSBarry Smith 152a2e34c3dSBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy() 153a2e34c3dSBarry Smith @*/ 154a2e34c3dSBarry Smith int MatNullSpaceTest(MatNullSpace sp,Mat mat) 155a2e34c3dSBarry Smith { 15687828ca2SBarry Smith PetscScalar sum; 1578bb6bcc5SSatish Balay PetscReal nrm; 158a2e34c3dSBarry Smith int j,n = sp->n,N,ierr,m; 159a2e34c3dSBarry Smith Vec l,r; 160a2e34c3dSBarry Smith MPI_Comm comm = sp->comm; 161a2e34c3dSBarry Smith PetscTruth flg1,flg2; 162a2e34c3dSBarry Smith 163a2e34c3dSBarry Smith PetscFunctionBegin; 164b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view",&flg1);CHKERRQ(ierr); 165b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view_draw",&flg2);CHKERRQ(ierr); 166a2e34c3dSBarry Smith 167a2e34c3dSBarry Smith if (!sp->vec) { 168a2e34c3dSBarry Smith if (n) { 169a2e34c3dSBarry Smith ierr = VecDuplicate(sp->vecs[0],&sp->vec);CHKERRQ(ierr); 170a2e34c3dSBarry Smith } else { 171a2e34c3dSBarry Smith ierr = MatGetLocalSize(mat,&m,PETSC_NULL);CHKERRQ(ierr); 172a2e34c3dSBarry Smith ierr = VecCreateMPI(sp->comm,m,PETSC_DETERMINE,&sp->vec);CHKERRQ(ierr); 173a2e34c3dSBarry Smith } 174a2e34c3dSBarry Smith } 175a2e34c3dSBarry Smith l = sp->vec; 176a2e34c3dSBarry Smith 177a2e34c3dSBarry Smith if (sp->has_cnst) { 178a2e34c3dSBarry Smith ierr = VecDuplicate(l,&r);CHKERRQ(ierr); 179a2e34c3dSBarry Smith ierr = VecGetSize(l,&N);CHKERRQ(ierr); 180a2e34c3dSBarry Smith sum = 1.0/N; 181a2e34c3dSBarry Smith ierr = VecSet(&sum,l);CHKERRQ(ierr); 182a2e34c3dSBarry Smith ierr = MatMult(mat,l,r);CHKERRQ(ierr); 1838bb6bcc5SSatish Balay ierr = VecNorm(r,NORM_2,&nrm);CHKERRQ(ierr); 1848bb6bcc5SSatish Balay if (nrm < 1.e-7) {ierr = PetscPrintf(comm,"Constants are likely null vector");CHKERRQ(ierr);} 185a2e34c3dSBarry Smith else {ierr = PetscPrintf(comm,"Constants are unlikely null vector ");CHKERRQ(ierr);} 1868bb6bcc5SSatish Balay ierr = PetscPrintf(comm,"|| A * 1 || = %g\n",nrm);CHKERRQ(ierr); 187b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg1) {ierr = VecView(r,PETSC_VIEWER_STDOUT_(comm));CHKERRQ(ierr);} 188b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg2) {ierr = VecView(r,PETSC_VIEWER_DRAW_(comm));CHKERRQ(ierr);} 189a2e34c3dSBarry Smith ierr = VecDestroy(r);CHKERRQ(ierr); 190a2e34c3dSBarry Smith } 191a2e34c3dSBarry Smith 192a2e34c3dSBarry Smith for (j=0; j<n; j++) { 193a2e34c3dSBarry Smith ierr = (*mat->ops->mult)(mat,sp->vecs[j],l);CHKERRQ(ierr); 1948bb6bcc5SSatish Balay ierr = VecNorm(l,NORM_2,&nrm);CHKERRQ(ierr); 1958bb6bcc5SSatish Balay if (nrm < 1.e-7) {ierr = PetscPrintf(comm,"Null vector %d is likely null vector",j);CHKERRQ(ierr);} 196a2e34c3dSBarry Smith else {ierr = PetscPrintf(comm,"Null vector %d unlikely null vector ",j);CHKERRQ(ierr);} 1978bb6bcc5SSatish Balay ierr = PetscPrintf(comm,"|| A * v[%d] || = %g\n",j,nrm);CHKERRQ(ierr); 198b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg1) {ierr = VecView(l,PETSC_VIEWER_STDOUT_(comm));CHKERRQ(ierr);} 199b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg2) {ierr = VecView(l,PETSC_VIEWER_DRAW_(comm));CHKERRQ(ierr);} 200a2e34c3dSBarry Smith } 201a2e34c3dSBarry Smith 202a2e34c3dSBarry Smith PetscFunctionReturn(0); 203a2e34c3dSBarry Smith } 204a2e34c3dSBarry Smith 205