173f4d377SMatthew Knepley /*$Id: matnull.c,v 1.40 2001/09/07 20:09:09 bsmith Exp $*/ 2f7765cecSBarry Smith /* 3b4fd4287SBarry Smith Routines to project vectors out of null spaces. 4f7765cecSBarry Smith */ 5f7765cecSBarry Smith 65cfeda75SBarry Smith #include "src/mat/matimpl.h" /*I "petscmat.h" I*/ 7e090d566SSatish Balay #include "petscsys.h" 8f7765cecSBarry Smith 98ba1e511SMatthew Knepley int MAT_NULLSPACE_COOKIE; 108ba1e511SMatthew Knepley 114a2ae208SSatish Balay #undef __FUNCT__ 124a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceCreate" 13112a2221SBarry Smith /*@C 145cfeda75SBarry Smith MatNullSpaceCreate - Creates a data structure used to project vectors 15b4fd4287SBarry Smith out of null spaces. 16f7765cecSBarry Smith 174e472627SLois Curfman McInnes Collective on MPI_Comm 184e472627SLois Curfman McInnes 19f7765cecSBarry Smith Input Parameters: 2083c3bef8SLois Curfman McInnes + comm - the MPI communicator associated with the object 2183c3bef8SLois Curfman McInnes . has_cnst - PETSC_TRUE if the null space contains the constant vector; otherwise PETSC_FALSE 22b4fd4287SBarry Smith . n - number of vectors (excluding constant vector) in null space 2383c3bef8SLois Curfman McInnes - vecs - the vectors that span the null space (excluding the constant vector); 24*f7a9e4ceSBarry Smith these vectors must be orthonormal. These vectors are NOT copied, so do not change them 25*f7a9e4ceSBarry Smith after this call. You should free the array that you pass in. 26f7765cecSBarry Smith 27f7765cecSBarry Smith Output Parameter: 28b4fd4287SBarry Smith . SP - the null space context 29f7765cecSBarry Smith 3083c3bef8SLois Curfman McInnes Level: advanced 3183c3bef8SLois Curfman McInnes 326e1639daSBarry Smith Users manual sections: 336e1639daSBarry Smith . sec_singular 346e1639daSBarry Smith 3583c3bef8SLois Curfman McInnes .keywords: PC, null space, create 3641a59933SSatish Balay 376e1639daSBarry Smith .seealso: MatNullSpaceDestroy(), MatNullSpaceRemove(), PCNullSpaceAttach(), MatNullSpace 38f7765cecSBarry Smith @*/ 395cfeda75SBarry Smith int MatNullSpaceCreate(MPI_Comm comm,int has_cnst,int n,Vec *vecs,MatNullSpace *SP) 40f7765cecSBarry Smith { 415cfeda75SBarry Smith MatNullSpace sp; 42*f7a9e4ceSBarry Smith int ierr,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; 52*f7a9e4ceSBarry Smith if (n) { 53*f7a9e4ceSBarry Smith ierr = PetscMalloc(n*sizeof(Vec),&sp->vecs);CHKERRQ(ierr); 54*f7a9e4ceSBarry Smith for (i=0; i<n; i++) sp->vecs[i] = vecs[i]; 55*f7a9e4ceSBarry Smith } else { 56*f7a9e4ceSBarry Smith sp->vecs = 0; 57*f7a9e4ceSBarry Smith } 58b4fd4287SBarry Smith 59*f7a9e4ceSBarry Smith for (i=0; i<n; i++) { 60*f7a9e4ceSBarry Smith ierr = PetscObjectReference((PetscObject)sp->vecs[i]);CHKERRQ(ierr); 61*f7a9e4ceSBarry 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 @*/ 835cfeda75SBarry Smith int MatNullSpaceDestroy(MatNullSpace sp) 84b4fd4287SBarry Smith { 855cfeda75SBarry Smith int 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);} 91*f7a9e4ceSBarry Smith if (sp->vecs) { 92*f7a9e4ceSBarry Smith ierr = VecDestroyVecs(sp->vecs,sp->n);CHKERRQ(ierr); 93*f7a9e4ceSBarry 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 10883c3bef8SLois Curfman McInnes - vec - the vector from which the null space is to be removed 1094e472627SLois Curfman McInnes 110b9756687SLois Curfman McInnes Level: advanced 111b9756687SLois Curfman McInnes 11283c3bef8SLois Curfman McInnes .keywords: PC, null space, remove 11341a59933SSatish Balay 1145cfeda75SBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy() 115f7765cecSBarry Smith @*/ 1165cfeda75SBarry Smith int MatNullSpaceRemove(MatNullSpace sp,Vec vec,Vec *out) 117f7765cecSBarry Smith { 11887828ca2SBarry Smith PetscScalar sum; 119b4fd4287SBarry Smith int j,n = sp->n,N,ierr; 1205cfeda75SBarry Smith Vec l = vec; 121f7765cecSBarry Smith 1223a40ed3dSBarry Smith PetscFunctionBegin; 1235cfeda75SBarry Smith if (out) { 1245cfeda75SBarry Smith if (!sp->vec) { 1255cfeda75SBarry Smith ierr = VecDuplicate(vec,&sp->vec);CHKERRQ(ierr); 1265cfeda75SBarry Smith } 1275cfeda75SBarry Smith *out = sp->vec; 1285cfeda75SBarry Smith ierr = VecCopy(vec,*out);CHKERRQ(ierr); 1295cfeda75SBarry Smith l = *out; 1305cfeda75SBarry Smith } 1315cfeda75SBarry Smith 132b4fd4287SBarry Smith if (sp->has_cnst) { 1335cfeda75SBarry Smith ierr = VecSum(l,&sum);CHKERRQ(ierr); 1345cfeda75SBarry Smith ierr = VecGetSize(l,&N);CHKERRQ(ierr); 13518a7d68fSSatish Balay sum = sum/(-1.0*N); 1365cfeda75SBarry Smith ierr = VecShift(&sum,l);CHKERRQ(ierr); 137f7765cecSBarry Smith } 138b4fd4287SBarry Smith 139b4fd4287SBarry Smith for (j=0; j<n; j++) { 1405cfeda75SBarry Smith ierr = VecDot(l,sp->vecs[j],&sum);CHKERRQ(ierr); 141b4fd4287SBarry Smith sum = -sum; 1425cfeda75SBarry Smith ierr = VecAXPY(&sum,sp->vecs[j],l);CHKERRQ(ierr); 143f7765cecSBarry Smith } 144b4fd4287SBarry Smith 1453a40ed3dSBarry Smith PetscFunctionReturn(0); 146f7765cecSBarry Smith } 147a2e34c3dSBarry Smith 1484a2ae208SSatish Balay #undef __FUNCT__ 1494a2ae208SSatish Balay #define __FUNCT__ "MatNullSpaceTest" 150a2e34c3dSBarry Smith /*@ 151a2e34c3dSBarry Smith MatNullSpaceTest - Tests if the claimed null space is really a 152a2e34c3dSBarry Smith null space of a matrix 153a2e34c3dSBarry Smith 154a2e34c3dSBarry Smith Collective on MatNullSpace 155a2e34c3dSBarry Smith 156a2e34c3dSBarry Smith Input Parameters: 157a2e34c3dSBarry Smith + sp - the null space context 158a2e34c3dSBarry Smith - mat - the matrix 159a2e34c3dSBarry Smith 160a2e34c3dSBarry Smith Level: advanced 161a2e34c3dSBarry Smith 162a2e34c3dSBarry Smith .keywords: PC, null space, remove 163a2e34c3dSBarry Smith 164a2e34c3dSBarry Smith .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy() 165a2e34c3dSBarry Smith @*/ 166a2e34c3dSBarry Smith int MatNullSpaceTest(MatNullSpace sp,Mat mat) 167a2e34c3dSBarry Smith { 16887828ca2SBarry Smith PetscScalar sum; 1698bb6bcc5SSatish Balay PetscReal nrm; 170a2e34c3dSBarry Smith int j,n = sp->n,N,ierr,m; 171a2e34c3dSBarry Smith Vec l,r; 172a2e34c3dSBarry Smith MPI_Comm comm = sp->comm; 173a2e34c3dSBarry Smith PetscTruth flg1,flg2; 174a2e34c3dSBarry Smith 175a2e34c3dSBarry Smith PetscFunctionBegin; 176b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view",&flg1);CHKERRQ(ierr); 177b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_null_space_test_view_draw",&flg2);CHKERRQ(ierr); 178a2e34c3dSBarry Smith 179a2e34c3dSBarry Smith if (!sp->vec) { 180a2e34c3dSBarry Smith if (n) { 181a2e34c3dSBarry Smith ierr = VecDuplicate(sp->vecs[0],&sp->vec);CHKERRQ(ierr); 182a2e34c3dSBarry Smith } else { 183a2e34c3dSBarry Smith ierr = MatGetLocalSize(mat,&m,PETSC_NULL);CHKERRQ(ierr); 184a2e34c3dSBarry Smith ierr = VecCreateMPI(sp->comm,m,PETSC_DETERMINE,&sp->vec);CHKERRQ(ierr); 185a2e34c3dSBarry Smith } 186a2e34c3dSBarry Smith } 187a2e34c3dSBarry Smith l = sp->vec; 188a2e34c3dSBarry Smith 189a2e34c3dSBarry Smith if (sp->has_cnst) { 190a2e34c3dSBarry Smith ierr = VecDuplicate(l,&r);CHKERRQ(ierr); 191a2e34c3dSBarry Smith ierr = VecGetSize(l,&N);CHKERRQ(ierr); 192a2e34c3dSBarry Smith sum = 1.0/N; 193a2e34c3dSBarry Smith ierr = VecSet(&sum,l);CHKERRQ(ierr); 194a2e34c3dSBarry Smith ierr = MatMult(mat,l,r);CHKERRQ(ierr); 1958bb6bcc5SSatish Balay ierr = VecNorm(r,NORM_2,&nrm);CHKERRQ(ierr); 1968bb6bcc5SSatish Balay if (nrm < 1.e-7) {ierr = PetscPrintf(comm,"Constants are likely null vector");CHKERRQ(ierr);} 197a2e34c3dSBarry Smith else {ierr = PetscPrintf(comm,"Constants are unlikely null vector ");CHKERRQ(ierr);} 1988bb6bcc5SSatish Balay ierr = PetscPrintf(comm,"|| A * 1 || = %g\n",nrm);CHKERRQ(ierr); 199b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg1) {ierr = VecView(r,PETSC_VIEWER_STDOUT_(comm));CHKERRQ(ierr);} 200b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg2) {ierr = VecView(r,PETSC_VIEWER_DRAW_(comm));CHKERRQ(ierr);} 201a2e34c3dSBarry Smith ierr = VecDestroy(r);CHKERRQ(ierr); 202a2e34c3dSBarry Smith } 203a2e34c3dSBarry Smith 204a2e34c3dSBarry Smith for (j=0; j<n; j++) { 205a2e34c3dSBarry Smith ierr = (*mat->ops->mult)(mat,sp->vecs[j],l);CHKERRQ(ierr); 2068bb6bcc5SSatish Balay ierr = VecNorm(l,NORM_2,&nrm);CHKERRQ(ierr); 2078bb6bcc5SSatish Balay if (nrm < 1.e-7) {ierr = PetscPrintf(comm,"Null vector %d is likely null vector",j);CHKERRQ(ierr);} 208a2e34c3dSBarry Smith else {ierr = PetscPrintf(comm,"Null vector %d unlikely null vector ",j);CHKERRQ(ierr);} 2098bb6bcc5SSatish Balay ierr = PetscPrintf(comm,"|| A * v[%d] || = %g\n",j,nrm);CHKERRQ(ierr); 210b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg1) {ierr = VecView(l,PETSC_VIEWER_STDOUT_(comm));CHKERRQ(ierr);} 211b0a32e0cSBarry Smith if (nrm > 1.e-7 && flg2) {ierr = VecView(l,PETSC_VIEWER_DRAW_(comm));CHKERRQ(ierr);} 212a2e34c3dSBarry Smith } 213a2e34c3dSBarry Smith 214a2e34c3dSBarry Smith PetscFunctionReturn(0); 215a2e34c3dSBarry Smith } 216a2e34c3dSBarry Smith 217