1be1d678aSKris Buschelman #define PETSCMAT_DLL 2be1d678aSKris Buschelman 3f7765cecSBarry Smith /* 4b4fd4287SBarry Smith Routines to project vectors out of null spaces. 5f7765cecSBarry Smith */ 6f7765cecSBarry Smith 7b9147fbbSdalcinl #include "include/private/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__ 1372875594SBarry Smith #define __FUNCT__ "MatNullSpaceSetFunction" 1472875594SBarry Smith /*@C 1572875594SBarry Smith MatNullSpaceSetFunction - set a function that removes a null space from a vector 1672875594SBarry Smith out of null spaces. 1772875594SBarry Smith 1872875594SBarry Smith Collective on MatNullSpace 1972875594SBarry Smith 2072875594SBarry Smith Input Parameters: 2172875594SBarry Smith + sp - the null space object 229dbe9a8aSBarry Smith . rem - the function that removes the null space 239dbe9a8aSBarry Smith - ctx - context for the remove function 2472875594SBarry Smith 25658c74aaSSatish Balay Level: advanced 2672875594SBarry Smith 27658c74aaSSatish Balay .keywords: PC, null space, create 28b47fd4b1SSatish Balay 2972875594SBarry Smith .seealso: MatNullSpaceDestroy(), MatNullSpaceRemove(), KSPSetNullSpace(), MatNullSpace, MatNullSpaceCreate() 3072875594SBarry Smith @*/ 319dbe9a8aSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceSetFunction(MatNullSpace sp, PetscErrorCode (*rem)(Vec,void*),void *ctx) 3272875594SBarry Smith { 3372875594SBarry Smith PetscFunctionBegin; 34*3cfa8680SLisandro Dalcin PetscValidHeaderSpecific(sp,MAT_NULLSPACE_COOKIE,1); 359dbe9a8aSBarry Smith sp->remove = rem; 369dbe9a8aSBarry Smith sp->rmctx = ctx; 3772875594SBarry Smith PetscFunctionReturn(0); 3872875594SBarry Smith } 3972875594SBarry Smith 4072875594SBarry Smith #undef __FUNCT__ 414a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceCreate" 42f39d8e23SSatish Balay /*@ 435cfeda75SBarry Smith MatNullSpaceCreate - Creates a data structure used to project vectors 44b4fd4287SBarry Smith out of null spaces. 45f7765cecSBarry Smith 464e472627SLois Curfman McInnes Collective on MPI_Comm 474e472627SLois Curfman McInnes 48f7765cecSBarry Smith Input Parameters: 4983c3bef8SLois Curfman McInnes + comm - the MPI communicator associated with the object 5083c3bef8SLois Curfman McInnes . has_cnst - PETSC_TRUE if the null space contains the constant vector; otherwise PETSC_FALSE 51b4fd4287SBarry Smith . n - number of vectors (excluding constant vector) in null space 5283c3bef8SLois Curfman McInnes - vecs - the vectors that span the null space (excluding the constant vector); 53f7a9e4ceSBarry Smith these vectors must be orthonormal. These vectors are NOT copied, so do not change them 54f7a9e4ceSBarry Smith after this call. You should free the array that you pass in. 55f7765cecSBarry Smith 56f7765cecSBarry Smith Output Parameter: 57b4fd4287SBarry Smith . SP - the null space context 58f7765cecSBarry Smith 5983c3bef8SLois Curfman McInnes Level: advanced 6083c3bef8SLois Curfman McInnes 616e1639daSBarry Smith Users manual sections: 626e1639daSBarry Smith . sec_singular 636e1639daSBarry Smith 6483c3bef8SLois Curfman McInnes .keywords: PC, null space, create 6541a59933SSatish Balay 6672875594SBarry Smith .seealso: MatNullSpaceDestroy(), MatNullSpaceRemove(), KSPSetNullSpace(), MatNullSpace, MatNullSpaceSetFunction() 67f7765cecSBarry Smith @*/ 68be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceCreate(MPI_Comm comm,PetscTruth has_cnst,PetscInt n,const Vec vecs[],MatNullSpace *SP) 69f7765cecSBarry Smith { 705cfeda75SBarry Smith MatNullSpace sp; 71dfbe8321SBarry Smith PetscErrorCode ierr; 72c1ac3661SBarry Smith PetscInt i; 73f7765cecSBarry Smith 743a40ed3dSBarry Smith PetscFunctionBegin; 75574b3360SMatthew Knepley if (n) PetscValidPointer(vecs,4); 76574b3360SMatthew Knepley for (i=0; i<n; i++) PetscValidHeaderSpecific(vecs[i],VEC_COOKIE,4); 77574b3360SMatthew Knepley PetscValidPointer(SP,5); 78574b3360SMatthew Knepley 79574b3360SMatthew Knepley *SP = PETSC_NULL; 80574b3360SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 81574b3360SMatthew Knepley ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr); 82574b3360SMatthew Knepley #endif 83574b3360SMatthew Knepley 8452e6d16bSBarry Smith ierr = PetscHeaderCreate(sp,_p_MatNullSpace,int,MAT_NULLSPACE_COOKIE,0,"MatNullSpace",comm,MatNullSpaceDestroy,0);CHKERRQ(ierr); 8552e6d16bSBarry Smith ierr = PetscLogObjectMemory(sp,sizeof(struct _p_MatNullSpace));CHKERRQ(ierr); 86f7765cecSBarry Smith 87b4fd4287SBarry Smith sp->has_cnst = has_cnst; 88b4fd4287SBarry Smith sp->n = n; 895cfeda75SBarry Smith sp->vec = PETSC_NULL; 90f7a9e4ceSBarry Smith if (n) { 91f7a9e4ceSBarry Smith ierr = PetscMalloc(n*sizeof(Vec),&sp->vecs);CHKERRQ(ierr); 92f7a9e4ceSBarry Smith for (i=0; i<n; i++) sp->vecs[i] = vecs[i]; 93f7a9e4ceSBarry Smith } else { 94f7a9e4ceSBarry Smith sp->vecs = 0; 95f7a9e4ceSBarry Smith } 96b4fd4287SBarry Smith 97f7a9e4ceSBarry Smith for (i=0; i<n; i++) { 98f7a9e4ceSBarry Smith ierr = PetscObjectReference((PetscObject)sp->vecs[i]);CHKERRQ(ierr); 99f7a9e4ceSBarry Smith } 100b4fd4287SBarry Smith *SP = sp; 1013a40ed3dSBarry Smith PetscFunctionReturn(0); 102f7765cecSBarry Smith } 103f7765cecSBarry Smith 1044a2ae208SSatish Balay #undef __FUNCT__ 1054a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceDestroy" 106f7765cecSBarry Smith /*@ 1075cfeda75SBarry Smith MatNullSpaceDestroy - Destroys a data structure used to project vectors 108b4fd4287SBarry Smith out of null spaces. 109b4fd4287SBarry Smith 1105cfeda75SBarry Smith Collective on MatNullSpace 1114e472627SLois Curfman McInnes 112b4fd4287SBarry Smith Input Parameter: 113b9756687SLois Curfman McInnes . sp - the null space context to be destroyed 114b9756687SLois Curfman McInnes 115b9756687SLois Curfman McInnes Level: advanced 116b4fd4287SBarry Smith 11783c3bef8SLois Curfman McInnes .keywords: PC, null space, destroy 11841a59933SSatish Balay 11972875594SBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceRemove(), MatNullSpaceSetFunction() 120b4fd4287SBarry Smith @*/ 121be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceDestroy(MatNullSpace sp) 122b4fd4287SBarry Smith { 123dfbe8321SBarry Smith PetscErrorCode ierr; 12485614651SBarry Smith 1255cfeda75SBarry Smith PetscFunctionBegin; 126*3cfa8680SLisandro Dalcin PetscValidHeaderSpecific(sp,MAT_NULLSPACE_COOKIE,1); 12785614651SBarry Smith if (--sp->refct > 0) PetscFunctionReturn(0); 12885614651SBarry Smith 1295cfeda75SBarry Smith if (sp->vec) {ierr = VecDestroy(sp->vec);CHKERRQ(ierr);} 130f7a9e4ceSBarry Smith if (sp->vecs) { 131f7a9e4ceSBarry Smith ierr = VecDestroyVecs(sp->vecs,sp->n);CHKERRQ(ierr); 132f7a9e4ceSBarry Smith } 133d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(sp);CHKERRQ(ierr); 1343a40ed3dSBarry Smith PetscFunctionReturn(0); 135b4fd4287SBarry Smith } 136b4fd4287SBarry Smith 1374a2ae208SSatish Balay #undef __FUNCT__ 1384a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceRemove" 139b4fd4287SBarry Smith /*@ 1405cfeda75SBarry Smith MatNullSpaceRemove - Removes all the components of a null space from a vector. 141f7765cecSBarry Smith 1425cfeda75SBarry Smith Collective on MatNullSpace 143f7765cecSBarry Smith 1444e472627SLois Curfman McInnes Input Parameters: 1454e472627SLois Curfman McInnes + sp - the null space context 1464e7234bfSBarry Smith . vec - the vector from which the null space is to be removed 1475fcf39f4SBarry Smith - out - if this is requested (not PETSC_NULL) then this is a vector with the null space removed otherwise 1484e7234bfSBarry Smith the removal is done in-place (in vec) 1494e7234bfSBarry Smith 150db090513SMatthew Knepley Note: The user is not responsible for the vector returned and should not destroy it. 1514e472627SLois Curfman McInnes 152b9756687SLois Curfman McInnes Level: advanced 153b9756687SLois Curfman McInnes 15483c3bef8SLois Curfman McInnes .keywords: PC, null space, remove 15541a59933SSatish Balay 15672875594SBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy(), MatNullSpaceSetFunction() 157f7765cecSBarry Smith @*/ 158be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceRemove(MatNullSpace sp,Vec vec,Vec *out) 159f7765cecSBarry Smith { 16087828ca2SBarry Smith PetscScalar sum; 1616849ba73SBarry Smith PetscErrorCode ierr; 162c1ac3661SBarry Smith PetscInt j,n = sp->n,N; 1635cfeda75SBarry Smith Vec l = vec; 164f7765cecSBarry Smith 1653a40ed3dSBarry Smith PetscFunctionBegin; 1663cd8ff7eSMatthew Knepley PetscValidHeaderSpecific(sp,MAT_NULLSPACE_COOKIE,1); 1673cd8ff7eSMatthew Knepley PetscValidHeaderSpecific(vec,VEC_COOKIE,2); 1683cd8ff7eSMatthew Knepley 1695cfeda75SBarry Smith if (out) { 1703cd8ff7eSMatthew Knepley PetscValidPointer(out,3); 1715cfeda75SBarry Smith if (!sp->vec) { 1725cfeda75SBarry Smith ierr = VecDuplicate(vec,&sp->vec);CHKERRQ(ierr); 1735cfeda75SBarry Smith } 1745cfeda75SBarry Smith *out = sp->vec; 1755cfeda75SBarry Smith ierr = VecCopy(vec,*out);CHKERRQ(ierr); 1765cfeda75SBarry Smith l = *out; 1775cfeda75SBarry Smith } 1785cfeda75SBarry Smith 179b4fd4287SBarry Smith if (sp->has_cnst) { 1805cfeda75SBarry Smith ierr = VecSum(l,&sum);CHKERRQ(ierr); 1815cfeda75SBarry Smith ierr = VecGetSize(l,&N);CHKERRQ(ierr); 18218a7d68fSSatish Balay sum = sum/(-1.0*N); 1832dcb1b2aSMatthew Knepley ierr = VecShift(l,sum);CHKERRQ(ierr); 184f7765cecSBarry Smith } 185b4fd4287SBarry Smith 186b4fd4287SBarry Smith for (j=0; j<n; j++) { 1875cfeda75SBarry Smith ierr = VecDot(l,sp->vecs[j],&sum);CHKERRQ(ierr); 1885eb3c597SBarry Smith ierr = VecAXPY(l,-sum,sp->vecs[j]);CHKERRQ(ierr); 189f7765cecSBarry Smith } 190b4fd4287SBarry Smith 19172875594SBarry Smith if (sp->remove){ 192ce0145b1SBarry Smith ierr = (*sp->remove)(l,sp->rmctx); 19372875594SBarry Smith } 1943a40ed3dSBarry Smith PetscFunctionReturn(0); 195f7765cecSBarry Smith } 196a2e34c3dSBarry Smith 1974a2ae208SSatish Balay #undef __FUNCT__ 1984a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceTest" 199a2e34c3dSBarry Smith /*@ 200a2e34c3dSBarry Smith MatNullSpaceTest - Tests if the claimed null space is really a 201a2e34c3dSBarry Smith null space of a matrix 202a2e34c3dSBarry Smith 203a2e34c3dSBarry Smith Collective on MatNullSpace 204a2e34c3dSBarry Smith 205a2e34c3dSBarry Smith Input Parameters: 206a2e34c3dSBarry Smith + sp - the null space context 207a2e34c3dSBarry Smith - mat - the matrix 208a2e34c3dSBarry Smith 209a2e34c3dSBarry Smith Level: advanced 210a2e34c3dSBarry Smith 211a2e34c3dSBarry Smith .keywords: PC, null space, remove 212a2e34c3dSBarry Smith 21372875594SBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy(), MatNullSpaceSetFunction() 214a2e34c3dSBarry Smith @*/ 215be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceTest(MatNullSpace sp,Mat mat) 216a2e34c3dSBarry Smith { 21787828ca2SBarry Smith PetscScalar sum; 2188bb6bcc5SSatish Balay PetscReal nrm; 219*3cfa8680SLisandro Dalcin PetscInt j,n,N,m; 2206849ba73SBarry Smith PetscErrorCode ierr; 221a2e34c3dSBarry Smith Vec l,r; 222a2e34c3dSBarry Smith PetscTruth flg1,flg2; 2233050cee2SBarry Smith PetscViewer viewer; 224a2e34c3dSBarry Smith 225a2e34c3dSBarry Smith PetscFunctionBegin; 226*3cfa8680SLisandro Dalcin PetscValidHeaderSpecific(sp,MAT_NULLSPACE_COOKIE,1); 227*3cfa8680SLisandro Dalcin PetscValidHeaderSpecific(mat,MAT_COOKIE,2); 228*3cfa8680SLisandro Dalcin n = sp->n; 229b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view",&flg1);CHKERRQ(ierr); 230b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view_draw",&flg2);CHKERRQ(ierr); 231a2e34c3dSBarry Smith 232a2e34c3dSBarry Smith if (!sp->vec) { 233a2e34c3dSBarry Smith if (n) { 234a2e34c3dSBarry Smith ierr = VecDuplicate(sp->vecs[0],&sp->vec);CHKERRQ(ierr); 235a2e34c3dSBarry Smith } else { 236a2e34c3dSBarry Smith ierr = MatGetLocalSize(mat,&m,PETSC_NULL);CHKERRQ(ierr); 237a2e34c3dSBarry Smith ierr = VecCreateMPI(sp->comm,m,PETSC_DETERMINE,&sp->vec);CHKERRQ(ierr); 238a2e34c3dSBarry Smith } 239a2e34c3dSBarry Smith } 240a2e34c3dSBarry Smith l = sp->vec; 241a2e34c3dSBarry Smith 242*3cfa8680SLisandro Dalcin ierr = PetscViewerASCIIGetStdout(sp->comm,&viewer);CHKERRQ(ierr); 243a2e34c3dSBarry Smith if (sp->has_cnst) { 244a2e34c3dSBarry Smith ierr = VecDuplicate(l,&r);CHKERRQ(ierr); 245a2e34c3dSBarry Smith ierr = VecGetSize(l,&N);CHKERRQ(ierr); 246a2e34c3dSBarry Smith sum = 1.0/N; 2472dcb1b2aSMatthew Knepley ierr = VecSet(l,sum);CHKERRQ(ierr); 248a2e34c3dSBarry Smith ierr = MatMult(mat,l,r);CHKERRQ(ierr); 2498bb6bcc5SSatish Balay ierr = VecNorm(r,NORM_2,&nrm);CHKERRQ(ierr); 250*3cfa8680SLisandro Dalcin if (nrm < 1.e-7) {ierr = PetscPrintf(sp->comm,"Constants are likely null vector");CHKERRQ(ierr);} 251*3cfa8680SLisandro Dalcin else {ierr = PetscPrintf(sp->comm,"Constants are unlikely null vector ");CHKERRQ(ierr);} 252*3cfa8680SLisandro Dalcin ierr = PetscPrintf(sp->comm,"|| A * 1 || = %G\n",nrm);CHKERRQ(ierr); 2533050cee2SBarry Smith if (nrm > 1.e-7 && flg1) {ierr = VecView(r,viewer);CHKERRQ(ierr);} 2543050cee2SBarry Smith if (nrm > 1.e-7 && flg2) {ierr = VecView(r,viewer);CHKERRQ(ierr);} 255a2e34c3dSBarry Smith ierr = VecDestroy(r);CHKERRQ(ierr); 256a2e34c3dSBarry Smith } 257a2e34c3dSBarry Smith 258a2e34c3dSBarry Smith for (j=0; j<n; j++) { 259a2e34c3dSBarry Smith ierr = (*mat->ops->mult)(mat,sp->vecs[j],l);CHKERRQ(ierr); 2608bb6bcc5SSatish Balay ierr = VecNorm(l,NORM_2,&nrm);CHKERRQ(ierr); 261*3cfa8680SLisandro Dalcin if (nrm < 1.e-7) {ierr = PetscPrintf(sp->comm,"Null vector %D is likely null vector",j);CHKERRQ(ierr);} 262*3cfa8680SLisandro Dalcin else {ierr = PetscPrintf(sp->comm,"Null vector %D unlikely null vector ",j);CHKERRQ(ierr);} 263*3cfa8680SLisandro Dalcin ierr = PetscPrintf(sp->comm,"|| A * v[%D] || = %G\n",j,nrm);CHKERRQ(ierr); 2643050cee2SBarry Smith if (nrm > 1.e-7 && flg1) {ierr = VecView(l,viewer);CHKERRQ(ierr);} 2653050cee2SBarry Smith if (nrm > 1.e-7 && flg2) {ierr = VecView(l,viewer);CHKERRQ(ierr);} 266a2e34c3dSBarry Smith } 267a2e34c3dSBarry Smith 26872875594SBarry Smith if (sp->remove){ 26972875594SBarry Smith SETERRQ(PETSC_ERR_SUP,"Cannot test a null space provided as a function with MatNullSpaceSetFunction()"); 27072875594SBarry Smith } 27172875594SBarry Smith 272a2e34c3dSBarry Smith PetscFunctionReturn(0); 273a2e34c3dSBarry Smith } 274a2e34c3dSBarry Smith 275