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 8*6849ba73SBarry 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 @*/ 38dfbe8321SBarry Smith PetscErrorCode MatNullSpaceCreate(MPI_Comm comm,int has_cnst,int n,const Vec vecs[],MatNullSpace *SP) 39f7765cecSBarry Smith { 405cfeda75SBarry Smith MatNullSpace sp; 41dfbe8321SBarry Smith PetscErrorCode ierr; 42dfbe8321SBarry Smith int 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 @*/ 83dfbe8321SBarry Smith PetscErrorCode MatNullSpaceDestroy(MatNullSpace sp) 84b4fd4287SBarry Smith { 85dfbe8321SBarry Smith PetscErrorCode 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 1084e7234bfSBarry Smith . vec - the vector from which the null space is to be removed 1095fcf39f4SBarry Smith - out - if this is requested (not PETSC_NULL) then this is a vector with the null space removed otherwise 1104e7234bfSBarry Smith the removal is done in-place (in vec) 1114e7234bfSBarry Smith 1124e7234bfSBarry 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 @*/ 120dfbe8321SBarry Smith PetscErrorCode MatNullSpaceRemove(MatNullSpace sp,Vec vec,Vec *out) 121f7765cecSBarry Smith { 12287828ca2SBarry Smith PetscScalar sum; 123*6849ba73SBarry Smith PetscErrorCode ierr; 124*6849ba73SBarry Smith int j,n = sp->n,N; 1255cfeda75SBarry Smith Vec l = vec; 126f7765cecSBarry Smith 1273a40ed3dSBarry Smith PetscFunctionBegin; 1285cfeda75SBarry Smith if (out) { 1295cfeda75SBarry Smith if (!sp->vec) { 1305cfeda75SBarry Smith ierr = VecDuplicate(vec,&sp->vec);CHKERRQ(ierr); 1315cfeda75SBarry Smith } 1325cfeda75SBarry Smith *out = sp->vec; 1335cfeda75SBarry Smith ierr = VecCopy(vec,*out);CHKERRQ(ierr); 1345cfeda75SBarry Smith l = *out; 1355cfeda75SBarry Smith } 1365cfeda75SBarry Smith 137b4fd4287SBarry Smith if (sp->has_cnst) { 1385cfeda75SBarry Smith ierr = VecSum(l,&sum);CHKERRQ(ierr); 1395cfeda75SBarry Smith ierr = VecGetSize(l,&N);CHKERRQ(ierr); 14018a7d68fSSatish Balay sum = sum/(-1.0*N); 1415cfeda75SBarry Smith ierr = VecShift(&sum,l);CHKERRQ(ierr); 142f7765cecSBarry Smith } 143b4fd4287SBarry Smith 144b4fd4287SBarry Smith for (j=0; j<n; j++) { 1455cfeda75SBarry Smith ierr = VecDot(l,sp->vecs[j],&sum);CHKERRQ(ierr); 146b4fd4287SBarry Smith sum = -sum; 1475cfeda75SBarry Smith ierr = VecAXPY(&sum,sp->vecs[j],l);CHKERRQ(ierr); 148f7765cecSBarry Smith } 149b4fd4287SBarry Smith 1503a40ed3dSBarry Smith PetscFunctionReturn(0); 151f7765cecSBarry Smith } 152a2e34c3dSBarry Smith 1534a2ae208SSatish Balay #undef __FUNCT__ 1544a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceTest" 155a2e34c3dSBarry Smith /*@ 156a2e34c3dSBarry Smith MatNullSpaceTest - Tests if the claimed null space is really a 157a2e34c3dSBarry Smith null space of a matrix 158a2e34c3dSBarry Smith 159a2e34c3dSBarry Smith Collective on MatNullSpace 160a2e34c3dSBarry Smith 161a2e34c3dSBarry Smith Input Parameters: 162a2e34c3dSBarry Smith + sp - the null space context 163a2e34c3dSBarry Smith - mat - the matrix 164a2e34c3dSBarry Smith 165a2e34c3dSBarry Smith Level: advanced 166a2e34c3dSBarry Smith 167a2e34c3dSBarry Smith .keywords: PC, null space, remove 168a2e34c3dSBarry Smith 169a2e34c3dSBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy() 170a2e34c3dSBarry Smith @*/ 171dfbe8321SBarry Smith PetscErrorCode MatNullSpaceTest(MatNullSpace sp,Mat mat) 172a2e34c3dSBarry Smith { 17387828ca2SBarry Smith PetscScalar sum; 1748bb6bcc5SSatish Balay PetscReal nrm; 175*6849ba73SBarry Smith int j,n = sp->n,N,m; 176*6849ba73SBarry Smith PetscErrorCode ierr; 177a2e34c3dSBarry Smith Vec l,r; 178a2e34c3dSBarry Smith MPI_Comm comm = sp->comm; 179a2e34c3dSBarry Smith PetscTruth flg1,flg2; 180a2e34c3dSBarry Smith 181a2e34c3dSBarry Smith PetscFunctionBegin; 182b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view",&flg1);CHKERRQ(ierr); 183b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view_draw",&flg2);CHKERRQ(ierr); 184a2e34c3dSBarry Smith 185a2e34c3dSBarry Smith if (!sp->vec) { 186a2e34c3dSBarry Smith if (n) { 187a2e34c3dSBarry Smith ierr = VecDuplicate(sp->vecs[0],&sp->vec);CHKERRQ(ierr); 188a2e34c3dSBarry Smith } else { 189a2e34c3dSBarry Smith ierr = MatGetLocalSize(mat,&m,PETSC_NULL);CHKERRQ(ierr); 190a2e34c3dSBarry Smith ierr = VecCreateMPI(sp->comm,m,PETSC_DETERMINE,&sp->vec);CHKERRQ(ierr); 191a2e34c3dSBarry Smith } 192a2e34c3dSBarry Smith } 193a2e34c3dSBarry Smith l = sp->vec; 194a2e34c3dSBarry Smith 195a2e34c3dSBarry Smith if (sp->has_cnst) { 196a2e34c3dSBarry Smith ierr = VecDuplicate(l,&r);CHKERRQ(ierr); 197a2e34c3dSBarry Smith ierr = VecGetSize(l,&N);CHKERRQ(ierr); 198a2e34c3dSBarry Smith sum = 1.0/N; 199a2e34c3dSBarry Smith ierr = VecSet(&sum,l);CHKERRQ(ierr); 200a2e34c3dSBarry Smith ierr = MatMult(mat,l,r);CHKERRQ(ierr); 2018bb6bcc5SSatish Balay ierr = VecNorm(r,NORM_2,&nrm);CHKERRQ(ierr); 2028bb6bcc5SSatish Balay if (nrm < 1.e-7) {ierr = PetscPrintf(comm,"Constants are likely null vector");CHKERRQ(ierr);} 203a2e34c3dSBarry Smith else {ierr = PetscPrintf(comm,"Constants are unlikely null vector ");CHKERRQ(ierr);} 2048bb6bcc5SSatish Balay ierr = PetscPrintf(comm,"|| A * 1 || = %g\n",nrm);CHKERRQ(ierr); 205b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg1) {ierr = VecView(r,PETSC_VIEWER_STDOUT_(comm));CHKERRQ(ierr);} 206b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg2) {ierr = VecView(r,PETSC_VIEWER_DRAW_(comm));CHKERRQ(ierr);} 207a2e34c3dSBarry Smith ierr = VecDestroy(r);CHKERRQ(ierr); 208a2e34c3dSBarry Smith } 209a2e34c3dSBarry Smith 210a2e34c3dSBarry Smith for (j=0; j<n; j++) { 211a2e34c3dSBarry Smith ierr = (*mat->ops->mult)(mat,sp->vecs[j],l);CHKERRQ(ierr); 2128bb6bcc5SSatish Balay ierr = VecNorm(l,NORM_2,&nrm);CHKERRQ(ierr); 2138bb6bcc5SSatish Balay if (nrm < 1.e-7) {ierr = PetscPrintf(comm,"Null vector %d is likely null vector",j);CHKERRQ(ierr);} 214a2e34c3dSBarry Smith else {ierr = PetscPrintf(comm,"Null vector %d unlikely null vector ",j);CHKERRQ(ierr);} 2158bb6bcc5SSatish Balay ierr = PetscPrintf(comm,"|| A * v[%d] || = %g\n",j,nrm);CHKERRQ(ierr); 216b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg1) {ierr = VecView(l,PETSC_VIEWER_STDOUT_(comm));CHKERRQ(ierr);} 217b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg2) {ierr = VecView(l,PETSC_VIEWER_DRAW_(comm));CHKERRQ(ierr);} 218a2e34c3dSBarry Smith } 219a2e34c3dSBarry Smith 220a2e34c3dSBarry Smith PetscFunctionReturn(0); 221a2e34c3dSBarry Smith } 222a2e34c3dSBarry Smith 223