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" 14f39d8e23SSatish 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; 47*574b3360SMatthew Knepley if (n) PetscValidPointer(vecs,4); 48*574b3360SMatthew Knepley for (i=0; i<n; i++) PetscValidHeaderSpecific(vecs[i],VEC_COOKIE,4); 49*574b3360SMatthew Knepley PetscValidPointer(SP,5); 50*574b3360SMatthew Knepley 51*574b3360SMatthew Knepley *SP = PETSC_NULL; 52*574b3360SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 53*574b3360SMatthew Knepley ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr); 54*574b3360SMatthew Knepley #endif 55*574b3360SMatthew Knepley 5652e6d16bSBarry Smith ierr = PetscHeaderCreate(sp,_p_MatNullSpace,int,MAT_NULLSPACE_COOKIE,0,"MatNullSpace",comm,MatNullSpaceDestroy,0);CHKERRQ(ierr); 5752e6d16bSBarry Smith ierr = PetscLogObjectMemory(sp,sizeof(struct _p_MatNullSpace));CHKERRQ(ierr); 58f7765cecSBarry Smith 59b4fd4287SBarry Smith sp->has_cnst = has_cnst; 60b4fd4287SBarry Smith sp->n = n; 615cfeda75SBarry Smith sp->vec = PETSC_NULL; 62f7a9e4ceSBarry Smith if (n) { 63f7a9e4ceSBarry Smith ierr = PetscMalloc(n*sizeof(Vec),&sp->vecs);CHKERRQ(ierr); 64f7a9e4ceSBarry Smith for (i=0; i<n; i++) sp->vecs[i] = vecs[i]; 65f7a9e4ceSBarry Smith } else { 66f7a9e4ceSBarry Smith sp->vecs = 0; 67f7a9e4ceSBarry Smith } 68b4fd4287SBarry Smith 69f7a9e4ceSBarry Smith for (i=0; i<n; i++) { 70f7a9e4ceSBarry Smith ierr = PetscObjectReference((PetscObject)sp->vecs[i]);CHKERRQ(ierr); 71f7a9e4ceSBarry Smith } 72b4fd4287SBarry Smith *SP = sp; 733a40ed3dSBarry Smith PetscFunctionReturn(0); 74f7765cecSBarry Smith } 75f7765cecSBarry Smith 764a2ae208SSatish Balay #undef __FUNCT__ 774a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceDestroy" 78f7765cecSBarry Smith /*@ 795cfeda75SBarry Smith MatNullSpaceDestroy - Destroys a data structure used to project vectors 80b4fd4287SBarry Smith out of null spaces. 81b4fd4287SBarry Smith 825cfeda75SBarry Smith Collective on MatNullSpace 834e472627SLois Curfman McInnes 84b4fd4287SBarry Smith Input Parameter: 85b9756687SLois Curfman McInnes . sp - the null space context to be destroyed 86b9756687SLois Curfman McInnes 87b9756687SLois Curfman McInnes Level: advanced 88b4fd4287SBarry Smith 8983c3bef8SLois Curfman McInnes .keywords: PC, null space, destroy 9041a59933SSatish Balay 915cfeda75SBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceRemove() 92b4fd4287SBarry Smith @*/ 93be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceDestroy(MatNullSpace sp) 94b4fd4287SBarry Smith { 95dfbe8321SBarry Smith PetscErrorCode ierr; 9685614651SBarry Smith 975cfeda75SBarry Smith PetscFunctionBegin; 9885614651SBarry Smith if (--sp->refct > 0) PetscFunctionReturn(0); 9985614651SBarry Smith 1005cfeda75SBarry Smith if (sp->vec) {ierr = VecDestroy(sp->vec);CHKERRQ(ierr);} 101f7a9e4ceSBarry Smith if (sp->vecs) { 102f7a9e4ceSBarry Smith ierr = VecDestroyVecs(sp->vecs,sp->n);CHKERRQ(ierr); 103f7a9e4ceSBarry Smith } 104d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(sp);CHKERRQ(ierr); 1053a40ed3dSBarry Smith PetscFunctionReturn(0); 106b4fd4287SBarry Smith } 107b4fd4287SBarry Smith 1084a2ae208SSatish Balay #undef __FUNCT__ 1094a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceRemove" 110b4fd4287SBarry Smith /*@ 1115cfeda75SBarry Smith MatNullSpaceRemove - Removes all the components of a null space from a vector. 112f7765cecSBarry Smith 1135cfeda75SBarry Smith Collective on MatNullSpace 114f7765cecSBarry Smith 1154e472627SLois Curfman McInnes Input Parameters: 1164e472627SLois Curfman McInnes + sp - the null space context 1174e7234bfSBarry Smith . vec - the vector from which the null space is to be removed 1185fcf39f4SBarry Smith - out - if this is requested (not PETSC_NULL) then this is a vector with the null space removed otherwise 1194e7234bfSBarry Smith the removal is done in-place (in vec) 1204e7234bfSBarry Smith 1214e7234bfSBarry Smith 1224e472627SLois Curfman McInnes 123b9756687SLois Curfman McInnes Level: advanced 124b9756687SLois Curfman McInnes 12583c3bef8SLois Curfman McInnes .keywords: PC, null space, remove 12641a59933SSatish Balay 1275cfeda75SBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy() 128f7765cecSBarry Smith @*/ 129be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceRemove(MatNullSpace sp,Vec vec,Vec *out) 130f7765cecSBarry Smith { 13187828ca2SBarry Smith PetscScalar sum; 1326849ba73SBarry Smith PetscErrorCode ierr; 133c1ac3661SBarry Smith PetscInt j,n = sp->n,N; 1345cfeda75SBarry Smith Vec l = vec; 135f7765cecSBarry Smith 1363a40ed3dSBarry Smith PetscFunctionBegin; 1375cfeda75SBarry Smith if (out) { 1385cfeda75SBarry Smith if (!sp->vec) { 1395cfeda75SBarry Smith ierr = VecDuplicate(vec,&sp->vec);CHKERRQ(ierr); 1405cfeda75SBarry Smith } 1415cfeda75SBarry Smith *out = sp->vec; 1425cfeda75SBarry Smith ierr = VecCopy(vec,*out);CHKERRQ(ierr); 1435cfeda75SBarry Smith l = *out; 1445cfeda75SBarry Smith } 1455cfeda75SBarry Smith 146b4fd4287SBarry Smith if (sp->has_cnst) { 1475cfeda75SBarry Smith ierr = VecSum(l,&sum);CHKERRQ(ierr); 1485cfeda75SBarry Smith ierr = VecGetSize(l,&N);CHKERRQ(ierr); 14918a7d68fSSatish Balay sum = sum/(-1.0*N); 1502dcb1b2aSMatthew Knepley ierr = VecShift(l,sum);CHKERRQ(ierr); 151f7765cecSBarry Smith } 152b4fd4287SBarry Smith 153b4fd4287SBarry Smith for (j=0; j<n; j++) { 1545cfeda75SBarry Smith ierr = VecDot(l,sp->vecs[j],&sum);CHKERRQ(ierr); 155b4fd4287SBarry Smith sum = -sum; 1562dcb1b2aSMatthew Knepley ierr = VecAXPY(l,sum,sp->vecs[j]);CHKERRQ(ierr); 157f7765cecSBarry Smith } 158b4fd4287SBarry Smith 1593a40ed3dSBarry Smith PetscFunctionReturn(0); 160f7765cecSBarry Smith } 161a2e34c3dSBarry Smith 1624a2ae208SSatish Balay #undef __FUNCT__ 1634a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceTest" 164a2e34c3dSBarry Smith /*@ 165a2e34c3dSBarry Smith MatNullSpaceTest - Tests if the claimed null space is really a 166a2e34c3dSBarry Smith null space of a matrix 167a2e34c3dSBarry Smith 168a2e34c3dSBarry Smith Collective on MatNullSpace 169a2e34c3dSBarry Smith 170a2e34c3dSBarry Smith Input Parameters: 171a2e34c3dSBarry Smith + sp - the null space context 172a2e34c3dSBarry Smith - mat - the matrix 173a2e34c3dSBarry Smith 174a2e34c3dSBarry Smith Level: advanced 175a2e34c3dSBarry Smith 176a2e34c3dSBarry Smith .keywords: PC, null space, remove 177a2e34c3dSBarry Smith 178a2e34c3dSBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy() 179a2e34c3dSBarry Smith @*/ 180be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceTest(MatNullSpace sp,Mat mat) 181a2e34c3dSBarry Smith { 18287828ca2SBarry Smith PetscScalar sum; 1838bb6bcc5SSatish Balay PetscReal nrm; 184c1ac3661SBarry Smith PetscInt j,n = sp->n,N,m; 1856849ba73SBarry Smith PetscErrorCode ierr; 186a2e34c3dSBarry Smith Vec l,r; 187a2e34c3dSBarry Smith MPI_Comm comm = sp->comm; 188a2e34c3dSBarry Smith PetscTruth flg1,flg2; 189a2e34c3dSBarry Smith 190a2e34c3dSBarry Smith PetscFunctionBegin; 191b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view",&flg1);CHKERRQ(ierr); 192b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view_draw",&flg2);CHKERRQ(ierr); 193a2e34c3dSBarry Smith 194a2e34c3dSBarry Smith if (!sp->vec) { 195a2e34c3dSBarry Smith if (n) { 196a2e34c3dSBarry Smith ierr = VecDuplicate(sp->vecs[0],&sp->vec);CHKERRQ(ierr); 197a2e34c3dSBarry Smith } else { 198a2e34c3dSBarry Smith ierr = MatGetLocalSize(mat,&m,PETSC_NULL);CHKERRQ(ierr); 199a2e34c3dSBarry Smith ierr = VecCreateMPI(sp->comm,m,PETSC_DETERMINE,&sp->vec);CHKERRQ(ierr); 200a2e34c3dSBarry Smith } 201a2e34c3dSBarry Smith } 202a2e34c3dSBarry Smith l = sp->vec; 203a2e34c3dSBarry Smith 204a2e34c3dSBarry Smith if (sp->has_cnst) { 205a2e34c3dSBarry Smith ierr = VecDuplicate(l,&r);CHKERRQ(ierr); 206a2e34c3dSBarry Smith ierr = VecGetSize(l,&N);CHKERRQ(ierr); 207a2e34c3dSBarry Smith sum = 1.0/N; 2082dcb1b2aSMatthew Knepley ierr = VecSet(l,sum);CHKERRQ(ierr); 209a2e34c3dSBarry Smith ierr = MatMult(mat,l,r);CHKERRQ(ierr); 2108bb6bcc5SSatish Balay ierr = VecNorm(r,NORM_2,&nrm);CHKERRQ(ierr); 2118bb6bcc5SSatish Balay if (nrm < 1.e-7) {ierr = PetscPrintf(comm,"Constants are likely null vector");CHKERRQ(ierr);} 212a2e34c3dSBarry Smith else {ierr = PetscPrintf(comm,"Constants are unlikely null vector ");CHKERRQ(ierr);} 2138bb6bcc5SSatish Balay ierr = PetscPrintf(comm,"|| A * 1 || = %g\n",nrm);CHKERRQ(ierr); 214b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg1) {ierr = VecView(r,PETSC_VIEWER_STDOUT_(comm));CHKERRQ(ierr);} 215b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg2) {ierr = VecView(r,PETSC_VIEWER_DRAW_(comm));CHKERRQ(ierr);} 216a2e34c3dSBarry Smith ierr = VecDestroy(r);CHKERRQ(ierr); 217a2e34c3dSBarry Smith } 218a2e34c3dSBarry Smith 219a2e34c3dSBarry Smith for (j=0; j<n; j++) { 220a2e34c3dSBarry Smith ierr = (*mat->ops->mult)(mat,sp->vecs[j],l);CHKERRQ(ierr); 2218bb6bcc5SSatish Balay ierr = VecNorm(l,NORM_2,&nrm);CHKERRQ(ierr); 22277431f27SBarry Smith if (nrm < 1.e-7) {ierr = PetscPrintf(comm,"Null vector %D is likely null vector",j);CHKERRQ(ierr);} 22377431f27SBarry Smith else {ierr = PetscPrintf(comm,"Null vector %D unlikely null vector ",j);CHKERRQ(ierr);} 22477431f27SBarry Smith ierr = PetscPrintf(comm,"|| A * v[%D] || = %g\n",j,nrm);CHKERRQ(ierr); 225b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg1) {ierr = VecView(l,PETSC_VIEWER_STDOUT_(comm));CHKERRQ(ierr);} 226b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg2) {ierr = VecView(l,PETSC_VIEWER_DRAW_(comm));CHKERRQ(ierr);} 227a2e34c3dSBarry Smith } 228a2e34c3dSBarry Smith 229a2e34c3dSBarry Smith PetscFunctionReturn(0); 230a2e34c3dSBarry Smith } 231a2e34c3dSBarry Smith 232