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); 24f7a9e4ceSBarry Smith these vectors must be orthonormal. These vectors are NOT copied, so do not change them 25f7a9e4ceSBarry Smith after this call. You should free the array that you pass in. 26f7765cecSBarry Smith 27f7765cecSBarry Smith Output Parameter: 28b4fd4287SBarry Smith . SP - the null space context 29f7765cecSBarry Smith 3083c3bef8SLois Curfman McInnes Level: advanced 3183c3bef8SLois Curfman McInnes 326e1639daSBarry Smith Users manual sections: 336e1639daSBarry Smith . sec_singular 346e1639daSBarry Smith 3583c3bef8SLois Curfman McInnes .keywords: PC, null space, create 3641a59933SSatish Balay 376e1639daSBarry Smith .seealso: MatNullSpaceDestroy(), MatNullSpaceRemove(), PCNullSpaceAttach(), MatNullSpace 38f7765cecSBarry Smith @*/ 39*4e7234bfSBarry Smith int MatNullSpaceCreate(MPI_Comm comm,int has_cnst,int n,const Vec vecs[],MatNullSpace *SP) 40f7765cecSBarry Smith { 415cfeda75SBarry Smith MatNullSpace sp; 42f7a9e4ceSBarry Smith int ierr,i; 43f7765cecSBarry Smith 443a40ed3dSBarry Smith PetscFunctionBegin; 458ba1e511SMatthew Knepley PetscHeaderCreate(sp,_p_MatNullSpace,int,MAT_NULLSPACE_COOKIE,0,"MatNullSpace",comm,MatNullSpaceDestroy,0); 46b0a32e0cSBarry Smith PetscLogObjectCreate(sp); 47b0a32e0cSBarry Smith PetscLogObjectMemory(sp,sizeof(struct _p_MatNullSpace)); 48f7765cecSBarry Smith 49b4fd4287SBarry Smith sp->has_cnst = has_cnst; 50b4fd4287SBarry Smith sp->n = n; 515cfeda75SBarry Smith sp->vec = PETSC_NULL; 52f7a9e4ceSBarry Smith if (n) { 53f7a9e4ceSBarry Smith ierr = PetscMalloc(n*sizeof(Vec),&sp->vecs);CHKERRQ(ierr); 54f7a9e4ceSBarry Smith for (i=0; i<n; i++) sp->vecs[i] = vecs[i]; 55f7a9e4ceSBarry Smith } else { 56f7a9e4ceSBarry Smith sp->vecs = 0; 57f7a9e4ceSBarry Smith } 58b4fd4287SBarry Smith 59f7a9e4ceSBarry Smith for (i=0; i<n; i++) { 60f7a9e4ceSBarry Smith ierr = PetscObjectReference((PetscObject)sp->vecs[i]);CHKERRQ(ierr); 61f7a9e4ceSBarry Smith } 62b4fd4287SBarry Smith *SP = sp; 633a40ed3dSBarry Smith PetscFunctionReturn(0); 64f7765cecSBarry Smith } 65f7765cecSBarry Smith 664a2ae208SSatish Balay #undef __FUNCT__ 674a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceDestroy" 68f7765cecSBarry Smith /*@ 695cfeda75SBarry Smith MatNullSpaceDestroy - Destroys a data structure used to project vectors 70b4fd4287SBarry Smith out of null spaces. 71b4fd4287SBarry Smith 725cfeda75SBarry Smith Collective on MatNullSpace 734e472627SLois Curfman McInnes 74b4fd4287SBarry Smith Input Parameter: 75b9756687SLois Curfman McInnes . sp - the null space context to be destroyed 76b9756687SLois Curfman McInnes 77b9756687SLois Curfman McInnes Level: advanced 78b4fd4287SBarry Smith 7983c3bef8SLois Curfman McInnes .keywords: PC, null space, destroy 8041a59933SSatish Balay 815cfeda75SBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceRemove() 82b4fd4287SBarry Smith @*/ 835cfeda75SBarry Smith int MatNullSpaceDestroy(MatNullSpace sp) 84b4fd4287SBarry Smith { 855cfeda75SBarry Smith int ierr; 8685614651SBarry Smith 875cfeda75SBarry Smith PetscFunctionBegin; 8885614651SBarry Smith if (--sp->refct > 0) PetscFunctionReturn(0); 8985614651SBarry Smith 905cfeda75SBarry Smith if (sp->vec) {ierr = VecDestroy(sp->vec);CHKERRQ(ierr);} 91f7a9e4ceSBarry Smith if (sp->vecs) { 92f7a9e4ceSBarry Smith ierr = VecDestroyVecs(sp->vecs,sp->n);CHKERRQ(ierr); 93f7a9e4ceSBarry Smith } 94b0a32e0cSBarry Smith PetscLogObjectDestroy(sp); 95b4fd4287SBarry Smith PetscHeaderDestroy(sp); 963a40ed3dSBarry Smith PetscFunctionReturn(0); 97b4fd4287SBarry Smith } 98b4fd4287SBarry Smith 994a2ae208SSatish Balay #undef __FUNCT__ 1004a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceRemove" 101b4fd4287SBarry Smith /*@ 1025cfeda75SBarry Smith MatNullSpaceRemove - Removes all the components of a null space from a vector. 103f7765cecSBarry Smith 1045cfeda75SBarry Smith Collective on MatNullSpace 105f7765cecSBarry Smith 1064e472627SLois Curfman McInnes Input Parameters: 1074e472627SLois Curfman McInnes + sp - the null space context 108*4e7234bfSBarry Smith . vec - the vector from which the null space is to be removed 109*4e7234bfSBarry Smith - out - if this is supplied (not PETSC_NULL) then this is vec with the null space removed otherwise 110*4e7234bfSBarry Smith the removal is done in-place (in vec) 111*4e7234bfSBarry Smith 112*4e7234bfSBarry Smith 1134e472627SLois Curfman McInnes 114b9756687SLois Curfman McInnes Level: advanced 115b9756687SLois Curfman McInnes 11683c3bef8SLois Curfman McInnes .keywords: PC, null space, remove 11741a59933SSatish Balay 1185cfeda75SBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy() 119f7765cecSBarry Smith @*/ 1205cfeda75SBarry Smith int MatNullSpaceRemove(MatNullSpace sp,Vec vec,Vec *out) 121f7765cecSBarry Smith { 12287828ca2SBarry Smith PetscScalar sum; 123b4fd4287SBarry Smith int j,n = sp->n,N,ierr; 1245cfeda75SBarry Smith Vec l = vec; 125f7765cecSBarry Smith 1263a40ed3dSBarry Smith PetscFunctionBegin; 1275cfeda75SBarry Smith if (out) { 1285cfeda75SBarry Smith if (!sp->vec) { 1295cfeda75SBarry Smith ierr = VecDuplicate(vec,&sp->vec);CHKERRQ(ierr); 1305cfeda75SBarry Smith } 1315cfeda75SBarry Smith *out = sp->vec; 1325cfeda75SBarry Smith ierr = VecCopy(vec,*out);CHKERRQ(ierr); 1335cfeda75SBarry Smith l = *out; 1345cfeda75SBarry Smith } 1355cfeda75SBarry Smith 136b4fd4287SBarry Smith if (sp->has_cnst) { 1375cfeda75SBarry Smith ierr = VecSum(l,&sum);CHKERRQ(ierr); 1385cfeda75SBarry Smith ierr = VecGetSize(l,&N);CHKERRQ(ierr); 13918a7d68fSSatish Balay sum = sum/(-1.0*N); 1405cfeda75SBarry Smith ierr = VecShift(&sum,l);CHKERRQ(ierr); 141f7765cecSBarry Smith } 142b4fd4287SBarry Smith 143b4fd4287SBarry Smith for (j=0; j<n; j++) { 1445cfeda75SBarry Smith ierr = VecDot(l,sp->vecs[j],&sum);CHKERRQ(ierr); 145b4fd4287SBarry Smith sum = -sum; 1465cfeda75SBarry Smith ierr = VecAXPY(&sum,sp->vecs[j],l);CHKERRQ(ierr); 147f7765cecSBarry Smith } 148b4fd4287SBarry Smith 1493a40ed3dSBarry Smith PetscFunctionReturn(0); 150f7765cecSBarry Smith } 151a2e34c3dSBarry Smith 1524a2ae208SSatish Balay #undef __FUNCT__ 1534a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceTest" 154a2e34c3dSBarry Smith /*@ 155a2e34c3dSBarry Smith MatNullSpaceTest - Tests if the claimed null space is really a 156a2e34c3dSBarry Smith null space of a matrix 157a2e34c3dSBarry Smith 158a2e34c3dSBarry Smith Collective on MatNullSpace 159a2e34c3dSBarry Smith 160a2e34c3dSBarry Smith Input Parameters: 161a2e34c3dSBarry Smith + sp - the null space context 162a2e34c3dSBarry Smith - mat - the matrix 163a2e34c3dSBarry Smith 164a2e34c3dSBarry Smith Level: advanced 165a2e34c3dSBarry Smith 166a2e34c3dSBarry Smith .keywords: PC, null space, remove 167a2e34c3dSBarry Smith 168a2e34c3dSBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy() 169a2e34c3dSBarry Smith @*/ 170a2e34c3dSBarry Smith int MatNullSpaceTest(MatNullSpace sp,Mat mat) 171a2e34c3dSBarry Smith { 17287828ca2SBarry Smith PetscScalar sum; 1738bb6bcc5SSatish Balay PetscReal nrm; 174a2e34c3dSBarry Smith int j,n = sp->n,N,ierr,m; 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); 2118bb6bcc5SSatish Balay if (nrm < 1.e-7) {ierr = PetscPrintf(comm,"Null vector %d is likely null vector",j);CHKERRQ(ierr);} 212a2e34c3dSBarry Smith else {ierr = PetscPrintf(comm,"Null vector %d unlikely null vector ",j);CHKERRQ(ierr);} 2138bb6bcc5SSatish Balay 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