1be1d678aSKris Buschelman #define PETSCMAT_DLL 2be1d678aSKris Buschelman 3f7765cecSBarry Smith /* 4b4fd4287SBarry Smith Routines to project vectors out of null spaces. 5f7765cecSBarry Smith */ 6f7765cecSBarry Smith 75cfeda75SBarry Smith #include "src/mat/matimpl.h" /*I "petscmat.h" I*/ 8e090d566SSatish Balay #include "petscsys.h" 9f7765cecSBarry Smith 10be1d678aSKris Buschelman PetscCookie PETSCMAT_DLLEXPORT MAT_NULLSPACE_COOKIE = 0; 118ba1e511SMatthew Knepley 124a2ae208SSatish Balay #undef __FUNCT__ 134a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceCreate" 14*f39d8e23SSatish Balay /*@ 155cfeda75SBarry Smith MatNullSpaceCreate - Creates a data structure used to project vectors 16b4fd4287SBarry Smith out of null spaces. 17f7765cecSBarry Smith 184e472627SLois Curfman McInnes Collective on MPI_Comm 194e472627SLois Curfman McInnes 20f7765cecSBarry Smith Input Parameters: 2183c3bef8SLois Curfman McInnes + comm - the MPI communicator associated with the object 2283c3bef8SLois Curfman McInnes . has_cnst - PETSC_TRUE if the null space contains the constant vector; otherwise PETSC_FALSE 23b4fd4287SBarry Smith . n - number of vectors (excluding constant vector) in null space 2483c3bef8SLois Curfman McInnes - vecs - the vectors that span the null space (excluding the constant vector); 25f7a9e4ceSBarry Smith these vectors must be orthonormal. These vectors are NOT copied, so do not change them 26f7a9e4ceSBarry Smith after this call. You should free the array that you pass in. 27f7765cecSBarry Smith 28f7765cecSBarry Smith Output Parameter: 29b4fd4287SBarry Smith . SP - the null space context 30f7765cecSBarry Smith 3183c3bef8SLois Curfman McInnes Level: advanced 3283c3bef8SLois Curfman McInnes 336e1639daSBarry Smith Users manual sections: 346e1639daSBarry Smith . sec_singular 356e1639daSBarry Smith 3683c3bef8SLois Curfman McInnes .keywords: PC, null space, create 3741a59933SSatish Balay 38d8fd42c4SBarry Smith .seealso: MatNullSpaceDestroy(), MatNullSpaceRemove(), KSPSetNullSpace(), MatNullSpace 39f7765cecSBarry Smith @*/ 40be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceCreate(MPI_Comm comm,PetscTruth has_cnst,PetscInt n,const Vec vecs[],MatNullSpace *SP) 41f7765cecSBarry Smith { 425cfeda75SBarry Smith MatNullSpace sp; 43dfbe8321SBarry Smith PetscErrorCode ierr; 44c1ac3661SBarry Smith PetscInt i; 45f7765cecSBarry Smith 463a40ed3dSBarry Smith PetscFunctionBegin; 4752e6d16bSBarry Smith ierr = PetscHeaderCreate(sp,_p_MatNullSpace,int,MAT_NULLSPACE_COOKIE,0,"MatNullSpace",comm,MatNullSpaceDestroy,0);CHKERRQ(ierr); 4852e6d16bSBarry Smith ierr = PetscLogObjectMemory(sp,sizeof(struct _p_MatNullSpace));CHKERRQ(ierr); 49f7765cecSBarry Smith 50b4fd4287SBarry Smith sp->has_cnst = has_cnst; 51b4fd4287SBarry Smith sp->n = n; 525cfeda75SBarry Smith sp->vec = PETSC_NULL; 53f7a9e4ceSBarry Smith if (n) { 54f7a9e4ceSBarry Smith ierr = PetscMalloc(n*sizeof(Vec),&sp->vecs);CHKERRQ(ierr); 55f7a9e4ceSBarry Smith for (i=0; i<n; i++) sp->vecs[i] = vecs[i]; 56f7a9e4ceSBarry Smith } else { 57f7a9e4ceSBarry Smith sp->vecs = 0; 58f7a9e4ceSBarry Smith } 59b4fd4287SBarry Smith 60f7a9e4ceSBarry Smith for (i=0; i<n; i++) { 61f7a9e4ceSBarry Smith ierr = PetscObjectReference((PetscObject)sp->vecs[i]);CHKERRQ(ierr); 62f7a9e4ceSBarry Smith } 63b4fd4287SBarry Smith *SP = sp; 643a40ed3dSBarry Smith PetscFunctionReturn(0); 65f7765cecSBarry Smith } 66f7765cecSBarry Smith 674a2ae208SSatish Balay #undef __FUNCT__ 684a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceDestroy" 69f7765cecSBarry Smith /*@ 705cfeda75SBarry Smith MatNullSpaceDestroy - Destroys a data structure used to project vectors 71b4fd4287SBarry Smith out of null spaces. 72b4fd4287SBarry Smith 735cfeda75SBarry Smith Collective on MatNullSpace 744e472627SLois Curfman McInnes 75b4fd4287SBarry Smith Input Parameter: 76b9756687SLois Curfman McInnes . sp - the null space context to be destroyed 77b9756687SLois Curfman McInnes 78b9756687SLois Curfman McInnes Level: advanced 79b4fd4287SBarry Smith 8083c3bef8SLois Curfman McInnes .keywords: PC, null space, destroy 8141a59933SSatish Balay 825cfeda75SBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceRemove() 83b4fd4287SBarry Smith @*/ 84be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceDestroy(MatNullSpace sp) 85b4fd4287SBarry Smith { 86dfbe8321SBarry Smith PetscErrorCode ierr; 8785614651SBarry Smith 885cfeda75SBarry Smith PetscFunctionBegin; 8985614651SBarry Smith if (--sp->refct > 0) PetscFunctionReturn(0); 9085614651SBarry Smith 915cfeda75SBarry Smith if (sp->vec) {ierr = VecDestroy(sp->vec);CHKERRQ(ierr);} 92f7a9e4ceSBarry Smith if (sp->vecs) { 93f7a9e4ceSBarry Smith ierr = VecDestroyVecs(sp->vecs,sp->n);CHKERRQ(ierr); 94f7a9e4ceSBarry Smith } 95d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(sp);CHKERRQ(ierr); 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 @*/ 120be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceRemove(MatNullSpace sp,Vec vec,Vec *out) 121f7765cecSBarry Smith { 12287828ca2SBarry Smith PetscScalar sum; 1236849ba73SBarry Smith PetscErrorCode ierr; 124c1ac3661SBarry Smith PetscInt 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); 1412dcb1b2aSMatthew Knepley ierr = VecShift(l,sum);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; 1472dcb1b2aSMatthew Knepley ierr = VecAXPY(l,sum,sp->vecs[j]);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 @*/ 171be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceTest(MatNullSpace sp,Mat mat) 172a2e34c3dSBarry Smith { 17387828ca2SBarry Smith PetscScalar sum; 1748bb6bcc5SSatish Balay PetscReal nrm; 175c1ac3661SBarry Smith PetscInt j,n = sp->n,N,m; 1766849ba73SBarry 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; 1992dcb1b2aSMatthew Knepley ierr = VecSet(l,sum);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); 21377431f27SBarry Smith if (nrm < 1.e-7) {ierr = PetscPrintf(comm,"Null vector %D is likely null vector",j);CHKERRQ(ierr);} 21477431f27SBarry Smith else {ierr = PetscPrintf(comm,"Null vector %D unlikely null vector ",j);CHKERRQ(ierr);} 21577431f27SBarry Smith 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