1f7765cecSBarry Smith /* 2b4fd4287SBarry Smith Routines to project vectors out of null spaces. 3f7765cecSBarry Smith */ 4f7765cecSBarry Smith 55cfeda75SBarry Smith #include "src/mat/matimpl.h" /*I "petscmat.h" I*/ 6e090d566SSatish Balay #include "petscsys.h" 7f7765cecSBarry Smith 86849ba73SBarry Smith PetscCookie MAT_NULLSPACE_COOKIE = 0; 98ba1e511SMatthew Knepley 104a2ae208SSatish Balay #undef __FUNCT__ 114a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceCreate" 12112a2221SBarry Smith /*@C 135cfeda75SBarry Smith MatNullSpaceCreate - Creates a data structure used to project vectors 14b4fd4287SBarry Smith out of null spaces. 15f7765cecSBarry Smith 164e472627SLois Curfman McInnes Collective on MPI_Comm 174e472627SLois Curfman McInnes 18f7765cecSBarry Smith Input Parameters: 1983c3bef8SLois Curfman McInnes + comm - the MPI communicator associated with the object 2083c3bef8SLois Curfman McInnes . has_cnst - PETSC_TRUE if the null space contains the constant vector; otherwise PETSC_FALSE 21b4fd4287SBarry Smith . n - number of vectors (excluding constant vector) in null space 2283c3bef8SLois Curfman McInnes - vecs - the vectors that span the null space (excluding the constant vector); 23f7a9e4ceSBarry Smith these vectors must be orthonormal. These vectors are NOT copied, so do not change them 24f7a9e4ceSBarry Smith after this call. You should free the array that you pass in. 25f7765cecSBarry Smith 26f7765cecSBarry Smith Output Parameter: 27b4fd4287SBarry Smith . SP - the null space context 28f7765cecSBarry Smith 2983c3bef8SLois Curfman McInnes Level: advanced 3083c3bef8SLois Curfman McInnes 316e1639daSBarry Smith Users manual sections: 326e1639daSBarry Smith . sec_singular 336e1639daSBarry Smith 3483c3bef8SLois Curfman McInnes .keywords: PC, null space, create 3541a59933SSatish Balay 36d8fd42c4SBarry Smith .seealso: MatNullSpaceDestroy(), MatNullSpaceRemove(), KSPSetNullSpace(), MatNullSpace 37f7765cecSBarry Smith @*/ 38c1ac3661SBarry Smith PetscErrorCode MatNullSpaceCreate(MPI_Comm comm,PetscTruth has_cnst,PetscInt n,const Vec vecs[],MatNullSpace *SP) 39f7765cecSBarry Smith { 405cfeda75SBarry Smith MatNullSpace sp; 41dfbe8321SBarry Smith PetscErrorCode ierr; 42c1ac3661SBarry Smith PetscInt i; 43f7765cecSBarry Smith 443a40ed3dSBarry Smith PetscFunctionBegin; 45*52e6d16bSBarry Smith ierr = PetscHeaderCreate(sp,_p_MatNullSpace,int,MAT_NULLSPACE_COOKIE,0,"MatNullSpace",comm,MatNullSpaceDestroy,0);CHKERRQ(ierr); 46*52e6d16bSBarry Smith ierr = PetscLogObjectMemory(sp,sizeof(struct _p_MatNullSpace));CHKERRQ(ierr); 47f7765cecSBarry Smith 48b4fd4287SBarry Smith sp->has_cnst = has_cnst; 49b4fd4287SBarry Smith sp->n = n; 505cfeda75SBarry Smith sp->vec = PETSC_NULL; 51f7a9e4ceSBarry Smith if (n) { 52f7a9e4ceSBarry Smith ierr = PetscMalloc(n*sizeof(Vec),&sp->vecs);CHKERRQ(ierr); 53f7a9e4ceSBarry Smith for (i=0; i<n; i++) sp->vecs[i] = vecs[i]; 54f7a9e4ceSBarry Smith } else { 55f7a9e4ceSBarry Smith sp->vecs = 0; 56f7a9e4ceSBarry Smith } 57b4fd4287SBarry Smith 58f7a9e4ceSBarry Smith for (i=0; i<n; i++) { 59f7a9e4ceSBarry Smith ierr = PetscObjectReference((PetscObject)sp->vecs[i]);CHKERRQ(ierr); 60f7a9e4ceSBarry Smith } 61b4fd4287SBarry Smith *SP = sp; 623a40ed3dSBarry Smith PetscFunctionReturn(0); 63f7765cecSBarry Smith } 64f7765cecSBarry Smith 654a2ae208SSatish Balay #undef __FUNCT__ 664a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceDestroy" 67f7765cecSBarry Smith /*@ 685cfeda75SBarry Smith MatNullSpaceDestroy - Destroys a data structure used to project vectors 69b4fd4287SBarry Smith out of null spaces. 70b4fd4287SBarry Smith 715cfeda75SBarry Smith Collective on MatNullSpace 724e472627SLois Curfman McInnes 73b4fd4287SBarry Smith Input Parameter: 74b9756687SLois Curfman McInnes . sp - the null space context to be destroyed 75b9756687SLois Curfman McInnes 76b9756687SLois Curfman McInnes Level: advanced 77b4fd4287SBarry Smith 7883c3bef8SLois Curfman McInnes .keywords: PC, null space, destroy 7941a59933SSatish Balay 805cfeda75SBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceRemove() 81b4fd4287SBarry Smith @*/ 82dfbe8321SBarry Smith PetscErrorCode MatNullSpaceDestroy(MatNullSpace sp) 83b4fd4287SBarry Smith { 84dfbe8321SBarry Smith PetscErrorCode ierr; 8585614651SBarry Smith 865cfeda75SBarry Smith PetscFunctionBegin; 8785614651SBarry Smith if (--sp->refct > 0) PetscFunctionReturn(0); 8885614651SBarry Smith 895cfeda75SBarry Smith if (sp->vec) {ierr = VecDestroy(sp->vec);CHKERRQ(ierr);} 90f7a9e4ceSBarry Smith if (sp->vecs) { 91f7a9e4ceSBarry Smith ierr = VecDestroyVecs(sp->vecs,sp->n);CHKERRQ(ierr); 92f7a9e4ceSBarry Smith } 93d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(sp);CHKERRQ(ierr); 943a40ed3dSBarry Smith PetscFunctionReturn(0); 95b4fd4287SBarry Smith } 96b4fd4287SBarry Smith 974a2ae208SSatish Balay #undef __FUNCT__ 984a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceRemove" 99b4fd4287SBarry Smith /*@ 1005cfeda75SBarry Smith MatNullSpaceRemove - Removes all the components of a null space from a vector. 101f7765cecSBarry Smith 1025cfeda75SBarry Smith Collective on MatNullSpace 103f7765cecSBarry Smith 1044e472627SLois Curfman McInnes Input Parameters: 1054e472627SLois Curfman McInnes + sp - the null space context 1064e7234bfSBarry Smith . vec - the vector from which the null space is to be removed 1075fcf39f4SBarry Smith - out - if this is requested (not PETSC_NULL) then this is a vector with the null space removed otherwise 1084e7234bfSBarry Smith the removal is done in-place (in vec) 1094e7234bfSBarry Smith 1104e7234bfSBarry Smith 1114e472627SLois Curfman McInnes 112b9756687SLois Curfman McInnes Level: advanced 113b9756687SLois Curfman McInnes 11483c3bef8SLois Curfman McInnes .keywords: PC, null space, remove 11541a59933SSatish Balay 1165cfeda75SBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy() 117f7765cecSBarry Smith @*/ 118dfbe8321SBarry Smith PetscErrorCode MatNullSpaceRemove(MatNullSpace sp,Vec vec,Vec *out) 119f7765cecSBarry Smith { 12087828ca2SBarry Smith PetscScalar sum; 1216849ba73SBarry Smith PetscErrorCode ierr; 122c1ac3661SBarry Smith PetscInt j,n = sp->n,N; 1235cfeda75SBarry Smith Vec l = vec; 124f7765cecSBarry Smith 1253a40ed3dSBarry Smith PetscFunctionBegin; 1265cfeda75SBarry Smith if (out) { 1275cfeda75SBarry Smith if (!sp->vec) { 1285cfeda75SBarry Smith ierr = VecDuplicate(vec,&sp->vec);CHKERRQ(ierr); 1295cfeda75SBarry Smith } 1305cfeda75SBarry Smith *out = sp->vec; 1315cfeda75SBarry Smith ierr = VecCopy(vec,*out);CHKERRQ(ierr); 1325cfeda75SBarry Smith l = *out; 1335cfeda75SBarry Smith } 1345cfeda75SBarry Smith 135b4fd4287SBarry Smith if (sp->has_cnst) { 1365cfeda75SBarry Smith ierr = VecSum(l,&sum);CHKERRQ(ierr); 1375cfeda75SBarry Smith ierr = VecGetSize(l,&N);CHKERRQ(ierr); 13818a7d68fSSatish Balay sum = sum/(-1.0*N); 1395cfeda75SBarry Smith ierr = VecShift(&sum,l);CHKERRQ(ierr); 140f7765cecSBarry Smith } 141b4fd4287SBarry Smith 142b4fd4287SBarry Smith for (j=0; j<n; j++) { 1435cfeda75SBarry Smith ierr = VecDot(l,sp->vecs[j],&sum);CHKERRQ(ierr); 144b4fd4287SBarry Smith sum = -sum; 1455cfeda75SBarry Smith ierr = VecAXPY(&sum,sp->vecs[j],l);CHKERRQ(ierr); 146f7765cecSBarry Smith } 147b4fd4287SBarry Smith 1483a40ed3dSBarry Smith PetscFunctionReturn(0); 149f7765cecSBarry Smith } 150a2e34c3dSBarry Smith 1514a2ae208SSatish Balay #undef __FUNCT__ 1524a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceTest" 153a2e34c3dSBarry Smith /*@ 154a2e34c3dSBarry Smith MatNullSpaceTest - Tests if the claimed null space is really a 155a2e34c3dSBarry Smith null space of a matrix 156a2e34c3dSBarry Smith 157a2e34c3dSBarry Smith Collective on MatNullSpace 158a2e34c3dSBarry Smith 159a2e34c3dSBarry Smith Input Parameters: 160a2e34c3dSBarry Smith + sp - the null space context 161a2e34c3dSBarry Smith - mat - the matrix 162a2e34c3dSBarry Smith 163a2e34c3dSBarry Smith Level: advanced 164a2e34c3dSBarry Smith 165a2e34c3dSBarry Smith .keywords: PC, null space, remove 166a2e34c3dSBarry Smith 167a2e34c3dSBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy() 168a2e34c3dSBarry Smith @*/ 169dfbe8321SBarry Smith PetscErrorCode MatNullSpaceTest(MatNullSpace sp,Mat mat) 170a2e34c3dSBarry Smith { 17187828ca2SBarry Smith PetscScalar sum; 1728bb6bcc5SSatish Balay PetscReal nrm; 173c1ac3661SBarry Smith PetscInt j,n = sp->n,N,m; 1746849ba73SBarry Smith PetscErrorCode ierr; 175a2e34c3dSBarry Smith Vec l,r; 176a2e34c3dSBarry Smith MPI_Comm comm = sp->comm; 177a2e34c3dSBarry Smith PetscTruth flg1,flg2; 178a2e34c3dSBarry Smith 179a2e34c3dSBarry Smith PetscFunctionBegin; 180b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view",&flg1);CHKERRQ(ierr); 181b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view_draw",&flg2);CHKERRQ(ierr); 182a2e34c3dSBarry Smith 183a2e34c3dSBarry Smith if (!sp->vec) { 184a2e34c3dSBarry Smith if (n) { 185a2e34c3dSBarry Smith ierr = VecDuplicate(sp->vecs[0],&sp->vec);CHKERRQ(ierr); 186a2e34c3dSBarry Smith } else { 187a2e34c3dSBarry Smith ierr = MatGetLocalSize(mat,&m,PETSC_NULL);CHKERRQ(ierr); 188a2e34c3dSBarry Smith ierr = VecCreateMPI(sp->comm,m,PETSC_DETERMINE,&sp->vec);CHKERRQ(ierr); 189a2e34c3dSBarry Smith } 190a2e34c3dSBarry Smith } 191a2e34c3dSBarry Smith l = sp->vec; 192a2e34c3dSBarry Smith 193a2e34c3dSBarry Smith if (sp->has_cnst) { 194a2e34c3dSBarry Smith ierr = VecDuplicate(l,&r);CHKERRQ(ierr); 195a2e34c3dSBarry Smith ierr = VecGetSize(l,&N);CHKERRQ(ierr); 196a2e34c3dSBarry Smith sum = 1.0/N; 197a2e34c3dSBarry Smith ierr = VecSet(&sum,l);CHKERRQ(ierr); 198a2e34c3dSBarry Smith ierr = MatMult(mat,l,r);CHKERRQ(ierr); 1998bb6bcc5SSatish Balay ierr = VecNorm(r,NORM_2,&nrm);CHKERRQ(ierr); 2008bb6bcc5SSatish Balay if (nrm < 1.e-7) {ierr = PetscPrintf(comm,"Constants are likely null vector");CHKERRQ(ierr);} 201a2e34c3dSBarry Smith else {ierr = PetscPrintf(comm,"Constants are unlikely null vector ");CHKERRQ(ierr);} 2028bb6bcc5SSatish Balay ierr = PetscPrintf(comm,"|| A * 1 || = %g\n",nrm);CHKERRQ(ierr); 203b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg1) {ierr = VecView(r,PETSC_VIEWER_STDOUT_(comm));CHKERRQ(ierr);} 204b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg2) {ierr = VecView(r,PETSC_VIEWER_DRAW_(comm));CHKERRQ(ierr);} 205a2e34c3dSBarry Smith ierr = VecDestroy(r);CHKERRQ(ierr); 206a2e34c3dSBarry Smith } 207a2e34c3dSBarry Smith 208a2e34c3dSBarry Smith for (j=0; j<n; j++) { 209a2e34c3dSBarry Smith ierr = (*mat->ops->mult)(mat,sp->vecs[j],l);CHKERRQ(ierr); 2108bb6bcc5SSatish Balay ierr = VecNorm(l,NORM_2,&nrm);CHKERRQ(ierr); 21177431f27SBarry Smith if (nrm < 1.e-7) {ierr = PetscPrintf(comm,"Null vector %D is likely null vector",j);CHKERRQ(ierr);} 21277431f27SBarry Smith else {ierr = PetscPrintf(comm,"Null vector %D unlikely null vector ",j);CHKERRQ(ierr);} 21377431f27SBarry Smith ierr = PetscPrintf(comm,"|| A * v[%D] || = %g\n",j,nrm);CHKERRQ(ierr); 214b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg1) {ierr = VecView(l,PETSC_VIEWER_STDOUT_(comm));CHKERRQ(ierr);} 215b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg2) {ierr = VecView(l,PETSC_VIEWER_DRAW_(comm));CHKERRQ(ierr);} 216a2e34c3dSBarry Smith } 217a2e34c3dSBarry Smith 218a2e34c3dSBarry Smith PetscFunctionReturn(0); 219a2e34c3dSBarry Smith } 220a2e34c3dSBarry Smith 221