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; 47574b3360SMatthew Knepley if (n) PetscValidPointer(vecs,4); 48574b3360SMatthew Knepley for (i=0; i<n; i++) PetscValidHeaderSpecific(vecs[i],VEC_COOKIE,4); 49574b3360SMatthew Knepley PetscValidPointer(SP,5); 50574b3360SMatthew Knepley 51574b3360SMatthew Knepley *SP = PETSC_NULL; 52574b3360SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 53574b3360SMatthew Knepley ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr); 54574b3360SMatthew Knepley #endif 55574b3360SMatthew 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 121*3cd8ff7eSMatthew Knepley Note: The vector returned is managed by the MatNullSpace, so the user should not destroy it. 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; 137*3cd8ff7eSMatthew Knepley PetscValidHeaderSpecific(sp,MAT_NULLSPACE_COOKIE,1); 138*3cd8ff7eSMatthew Knepley PetscValidHeaderSpecific(vec,VEC_COOKIE,2); 139*3cd8ff7eSMatthew Knepley 1405cfeda75SBarry Smith if (out) { 141*3cd8ff7eSMatthew Knepley PetscValidPointer(out,3); 1425cfeda75SBarry Smith if (!sp->vec) { 1435cfeda75SBarry Smith ierr = VecDuplicate(vec,&sp->vec);CHKERRQ(ierr); 1445cfeda75SBarry Smith } 1455cfeda75SBarry Smith *out = sp->vec; 1465cfeda75SBarry Smith ierr = VecCopy(vec,*out);CHKERRQ(ierr); 1475cfeda75SBarry Smith l = *out; 1485cfeda75SBarry Smith } 1495cfeda75SBarry Smith 150b4fd4287SBarry Smith if (sp->has_cnst) { 1515cfeda75SBarry Smith ierr = VecSum(l,&sum);CHKERRQ(ierr); 1525cfeda75SBarry Smith ierr = VecGetSize(l,&N);CHKERRQ(ierr); 15318a7d68fSSatish Balay sum = sum/(-1.0*N); 1542dcb1b2aSMatthew Knepley ierr = VecShift(l,sum);CHKERRQ(ierr); 155f7765cecSBarry Smith } 156b4fd4287SBarry Smith 157b4fd4287SBarry Smith for (j=0; j<n; j++) { 1585cfeda75SBarry Smith ierr = VecDot(l,sp->vecs[j],&sum);CHKERRQ(ierr); 159b4fd4287SBarry Smith sum = -sum; 1602dcb1b2aSMatthew Knepley ierr = VecAXPY(l,sum,sp->vecs[j]);CHKERRQ(ierr); 161f7765cecSBarry Smith } 162b4fd4287SBarry Smith 1633a40ed3dSBarry Smith PetscFunctionReturn(0); 164f7765cecSBarry Smith } 165a2e34c3dSBarry Smith 1664a2ae208SSatish Balay #undef __FUNCT__ 1674a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceTest" 168a2e34c3dSBarry Smith /*@ 169a2e34c3dSBarry Smith MatNullSpaceTest - Tests if the claimed null space is really a 170a2e34c3dSBarry Smith null space of a matrix 171a2e34c3dSBarry Smith 172a2e34c3dSBarry Smith Collective on MatNullSpace 173a2e34c3dSBarry Smith 174a2e34c3dSBarry Smith Input Parameters: 175a2e34c3dSBarry Smith + sp - the null space context 176a2e34c3dSBarry Smith - mat - the matrix 177a2e34c3dSBarry Smith 178a2e34c3dSBarry Smith Level: advanced 179a2e34c3dSBarry Smith 180a2e34c3dSBarry Smith .keywords: PC, null space, remove 181a2e34c3dSBarry Smith 182a2e34c3dSBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy() 183a2e34c3dSBarry Smith @*/ 184be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceTest(MatNullSpace sp,Mat mat) 185a2e34c3dSBarry Smith { 18687828ca2SBarry Smith PetscScalar sum; 1878bb6bcc5SSatish Balay PetscReal nrm; 188c1ac3661SBarry Smith PetscInt j,n = sp->n,N,m; 1896849ba73SBarry Smith PetscErrorCode ierr; 190a2e34c3dSBarry Smith Vec l,r; 191a2e34c3dSBarry Smith MPI_Comm comm = sp->comm; 192a2e34c3dSBarry Smith PetscTruth flg1,flg2; 193a2e34c3dSBarry Smith 194a2e34c3dSBarry Smith PetscFunctionBegin; 195b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view",&flg1);CHKERRQ(ierr); 196b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view_draw",&flg2);CHKERRQ(ierr); 197a2e34c3dSBarry Smith 198a2e34c3dSBarry Smith if (!sp->vec) { 199a2e34c3dSBarry Smith if (n) { 200a2e34c3dSBarry Smith ierr = VecDuplicate(sp->vecs[0],&sp->vec);CHKERRQ(ierr); 201a2e34c3dSBarry Smith } else { 202a2e34c3dSBarry Smith ierr = MatGetLocalSize(mat,&m,PETSC_NULL);CHKERRQ(ierr); 203a2e34c3dSBarry Smith ierr = VecCreateMPI(sp->comm,m,PETSC_DETERMINE,&sp->vec);CHKERRQ(ierr); 204a2e34c3dSBarry Smith } 205a2e34c3dSBarry Smith } 206a2e34c3dSBarry Smith l = sp->vec; 207a2e34c3dSBarry Smith 208a2e34c3dSBarry Smith if (sp->has_cnst) { 209a2e34c3dSBarry Smith ierr = VecDuplicate(l,&r);CHKERRQ(ierr); 210a2e34c3dSBarry Smith ierr = VecGetSize(l,&N);CHKERRQ(ierr); 211a2e34c3dSBarry Smith sum = 1.0/N; 2122dcb1b2aSMatthew Knepley ierr = VecSet(l,sum);CHKERRQ(ierr); 213a2e34c3dSBarry Smith ierr = MatMult(mat,l,r);CHKERRQ(ierr); 2148bb6bcc5SSatish Balay ierr = VecNorm(r,NORM_2,&nrm);CHKERRQ(ierr); 2158bb6bcc5SSatish Balay if (nrm < 1.e-7) {ierr = PetscPrintf(comm,"Constants are likely null vector");CHKERRQ(ierr);} 216a2e34c3dSBarry Smith else {ierr = PetscPrintf(comm,"Constants are unlikely null vector ");CHKERRQ(ierr);} 2178bb6bcc5SSatish Balay ierr = PetscPrintf(comm,"|| A * 1 || = %g\n",nrm);CHKERRQ(ierr); 218b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg1) {ierr = VecView(r,PETSC_VIEWER_STDOUT_(comm));CHKERRQ(ierr);} 219b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg2) {ierr = VecView(r,PETSC_VIEWER_DRAW_(comm));CHKERRQ(ierr);} 220a2e34c3dSBarry Smith ierr = VecDestroy(r);CHKERRQ(ierr); 221a2e34c3dSBarry Smith } 222a2e34c3dSBarry Smith 223a2e34c3dSBarry Smith for (j=0; j<n; j++) { 224a2e34c3dSBarry Smith ierr = (*mat->ops->mult)(mat,sp->vecs[j],l);CHKERRQ(ierr); 2258bb6bcc5SSatish Balay ierr = VecNorm(l,NORM_2,&nrm);CHKERRQ(ierr); 22677431f27SBarry Smith if (nrm < 1.e-7) {ierr = PetscPrintf(comm,"Null vector %D is likely null vector",j);CHKERRQ(ierr);} 22777431f27SBarry Smith else {ierr = PetscPrintf(comm,"Null vector %D unlikely null vector ",j);CHKERRQ(ierr);} 22877431f27SBarry Smith ierr = PetscPrintf(comm,"|| A * v[%D] || = %g\n",j,nrm);CHKERRQ(ierr); 229b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg1) {ierr = VecView(l,PETSC_VIEWER_STDOUT_(comm));CHKERRQ(ierr);} 230b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg2) {ierr = VecView(l,PETSC_VIEWER_DRAW_(comm));CHKERRQ(ierr);} 231a2e34c3dSBarry Smith } 232a2e34c3dSBarry Smith 233a2e34c3dSBarry Smith PetscFunctionReturn(0); 234a2e34c3dSBarry Smith } 235a2e34c3dSBarry Smith 236