1be1d678aSKris Buschelman 2b4319ba4SBarry Smith /* 3b4319ba4SBarry Smith Creates a matrix class for using the Neumann-Neumann type preconditioners. 4b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 5b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 6b4319ba4SBarry Smith product is handled "implicitly". 7b4319ba4SBarry Smith 8b4319ba4SBarry Smith We provide: 9b4319ba4SBarry Smith MatMult() 10b4319ba4SBarry Smith 11b4319ba4SBarry Smith Currently this allows for only one subdomain per processor. 12b4319ba4SBarry Smith 13b4319ba4SBarry Smith */ 14b4319ba4SBarry Smith 15c6db04a5SJed Brown #include <../src/mat/impls/is/matis.h> /*I "petscmat.h" I*/ 16b4319ba4SBarry Smith 17b4319ba4SBarry Smith #undef __FUNCT__ 1869796d55SStefano Zampini #define __FUNCT__ "MatIsHermitian_IS" 1969796d55SStefano Zampini PetscErrorCode MatIsHermitian_IS(Mat A,PetscReal tol,PetscBool *flg) 2069796d55SStefano Zampini { 2169796d55SStefano Zampini PetscErrorCode ierr; 2269796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 2369796d55SStefano Zampini PetscBool local_sym; 2469796d55SStefano Zampini 2569796d55SStefano Zampini PetscFunctionBegin; 2669796d55SStefano Zampini ierr = MatIsHermitian(matis->A,tol,&local_sym);CHKERRQ(ierr); 2769796d55SStefano Zampini ierr = MPI_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 2869796d55SStefano Zampini PetscFunctionReturn(0); 2969796d55SStefano Zampini } 3069796d55SStefano Zampini 3169796d55SStefano Zampini #undef __FUNCT__ 3269796d55SStefano Zampini #define __FUNCT__ "MatIsSymmetric_IS" 3369796d55SStefano Zampini PetscErrorCode MatIsSymmetric_IS(Mat A,PetscReal tol,PetscBool *flg) 3469796d55SStefano Zampini { 3569796d55SStefano Zampini PetscErrorCode ierr; 3669796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 3769796d55SStefano Zampini PetscBool local_sym; 3869796d55SStefano Zampini 3969796d55SStefano Zampini PetscFunctionBegin; 4069796d55SStefano Zampini ierr = MatIsSymmetric(matis->A,tol,&local_sym);CHKERRQ(ierr); 4169796d55SStefano Zampini ierr = MPI_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 4269796d55SStefano Zampini PetscFunctionReturn(0); 4369796d55SStefano Zampini } 4469796d55SStefano Zampini 4569796d55SStefano Zampini #undef __FUNCT__ 46b4319ba4SBarry Smith #define __FUNCT__ "MatDestroy_IS" 47dfbe8321SBarry Smith PetscErrorCode MatDestroy_IS(Mat A) 48b4319ba4SBarry Smith { 49dfbe8321SBarry Smith PetscErrorCode ierr; 50b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 51b4319ba4SBarry Smith 52b4319ba4SBarry Smith PetscFunctionBegin; 536bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 546bf464f9SBarry Smith ierr = VecScatterDestroy(&b->ctx);CHKERRQ(ierr); 556bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 566bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 576bf464f9SBarry Smith ierr = ISLocalToGlobalMappingDestroy(&b->mapping);CHKERRQ(ierr); 58bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 59dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 60bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 61b4319ba4SBarry Smith PetscFunctionReturn(0); 62b4319ba4SBarry Smith } 63b4319ba4SBarry Smith 64b4319ba4SBarry Smith #undef __FUNCT__ 65b4319ba4SBarry Smith #define __FUNCT__ "MatMult_IS" 66dfbe8321SBarry Smith PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 67b4319ba4SBarry Smith { 68dfbe8321SBarry Smith PetscErrorCode ierr; 69b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 70b4319ba4SBarry Smith PetscScalar zero = 0.0; 71b4319ba4SBarry Smith 72b4319ba4SBarry Smith PetscFunctionBegin; 73b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 74ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 75ca9f406cSSatish Balay ierr = VecScatterEnd(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 76b4319ba4SBarry Smith 77b4319ba4SBarry Smith /* multiply the local matrix */ 78b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 79b4319ba4SBarry Smith 80b4319ba4SBarry Smith /* scatter product back into global memory */ 812dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 82ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 83ca9f406cSSatish Balay ierr = VecScatterEnd(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 84b4319ba4SBarry Smith PetscFunctionReturn(0); 85b4319ba4SBarry Smith } 86b4319ba4SBarry Smith 87b4319ba4SBarry Smith #undef __FUNCT__ 882e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultAdd_IS" 892e74eeadSLisandro Dalcin static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 902e74eeadSLisandro Dalcin { 91650997f4SStefano Zampini Vec temp_vec; 922e74eeadSLisandro Dalcin PetscErrorCode ierr; 932e74eeadSLisandro Dalcin 942e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 95650997f4SStefano Zampini if (v3 != v2) { 96650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 97650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 98650997f4SStefano Zampini } else { 99650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 100650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 101650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 102650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 103650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 104650997f4SStefano Zampini } 1052e74eeadSLisandro Dalcin PetscFunctionReturn(0); 1062e74eeadSLisandro Dalcin } 1072e74eeadSLisandro Dalcin 1082e74eeadSLisandro Dalcin #undef __FUNCT__ 1092e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTranspose_IS" 1102e74eeadSLisandro Dalcin PetscErrorCode MatMultTranspose_IS(Mat A,Vec x,Vec y) 1112e74eeadSLisandro Dalcin { 1122e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 1132e74eeadSLisandro Dalcin PetscErrorCode ierr; 1142e74eeadSLisandro Dalcin 1152e74eeadSLisandro Dalcin PetscFunctionBegin; /* y = A' * x */ 1162e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 117ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 118ca9f406cSSatish Balay ierr = VecScatterEnd(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1192e74eeadSLisandro Dalcin 1202e74eeadSLisandro Dalcin /* multiply the local matrix */ 1212e74eeadSLisandro Dalcin ierr = MatMultTranspose(is->A,is->x,is->y);CHKERRQ(ierr); 1222e74eeadSLisandro Dalcin 1232e74eeadSLisandro Dalcin /* scatter product back into global vector */ 1242e74eeadSLisandro Dalcin ierr = VecSet(y,0);CHKERRQ(ierr); 125ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 126ca9f406cSSatish Balay ierr = VecScatterEnd(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1272e74eeadSLisandro Dalcin PetscFunctionReturn(0); 1282e74eeadSLisandro Dalcin } 1292e74eeadSLisandro Dalcin 1302e74eeadSLisandro Dalcin #undef __FUNCT__ 1312e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTransposeAdd_IS" 1322e74eeadSLisandro Dalcin PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 1332e74eeadSLisandro Dalcin { 134650997f4SStefano Zampini Vec temp_vec; 1352e74eeadSLisandro Dalcin PetscErrorCode ierr; 1362e74eeadSLisandro Dalcin 1372e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 138650997f4SStefano Zampini if (v3 != v2) { 139650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 140650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 141650997f4SStefano Zampini } else { 142650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 143650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 144650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 145650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 146650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 147650997f4SStefano Zampini } 1482e74eeadSLisandro Dalcin PetscFunctionReturn(0); 1492e74eeadSLisandro Dalcin } 1502e74eeadSLisandro Dalcin 1512e74eeadSLisandro Dalcin #undef __FUNCT__ 152b4319ba4SBarry Smith #define __FUNCT__ "MatView_IS" 153dfbe8321SBarry Smith PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 154b4319ba4SBarry Smith { 155b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 156dfbe8321SBarry Smith PetscErrorCode ierr; 157b4319ba4SBarry Smith PetscViewer sviewer; 158b4319ba4SBarry Smith 159b4319ba4SBarry Smith PetscFunctionBegin; 160*dd2fa690SBarry Smith ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); 161b4319ba4SBarry Smith ierr = PetscViewerGetSingleton(viewer,&sviewer);CHKERRQ(ierr); 162b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 163b4319ba4SBarry Smith ierr = PetscViewerRestoreSingleton(viewer,&sviewer);CHKERRQ(ierr); 164b4319ba4SBarry Smith PetscFunctionReturn(0); 165b4319ba4SBarry Smith } 166b4319ba4SBarry Smith 167b4319ba4SBarry Smith #undef __FUNCT__ 168b4319ba4SBarry Smith #define __FUNCT__ "MatSetLocalToGlobalMapping_IS" 169784ac674SJed Brown PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 170b4319ba4SBarry Smith { 171dfbe8321SBarry Smith PetscErrorCode ierr; 1724e4c7dbeSStefano Zampini PetscInt n,bs; 173b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 174b4319ba4SBarry Smith IS from,to; 175b4319ba4SBarry Smith Vec global; 176b4319ba4SBarry Smith 177b4319ba4SBarry Smith PetscFunctionBegin; 178e7e72b3dSBarry Smith if (is->mapping) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix"); 179784ac674SJed Brown PetscCheckSameComm(A,1,rmapping,2); 180ce94432eSBarry Smith if (rmapping != cmapping) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MATIS requires the row and column mappings to be identical"); 181784ac674SJed Brown ierr = PetscObjectReference((PetscObject)rmapping);CHKERRQ(ierr); 1826bf464f9SBarry Smith ierr = ISLocalToGlobalMappingDestroy(&is->mapping);CHKERRQ(ierr); 183784ac674SJed Brown is->mapping = rmapping; 184b4319ba4SBarry Smith 185b4319ba4SBarry Smith /* Create the local matrix A */ 186784ac674SJed Brown ierr = ISLocalToGlobalMappingGetSize(rmapping,&n);CHKERRQ(ierr); 1874e4c7dbeSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 188f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 189f69a0ea3SMatthew Knepley ierr = MatSetSizes(is->A,n,n,n,n);CHKERRQ(ierr); 1904e4c7dbeSStefano Zampini ierr = MatSetBlockSize(is->A,bs);CHKERRQ(ierr); 191ff130e51SJed Brown ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 192ff130e51SJed Brown ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 193b4319ba4SBarry Smith ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 194b4319ba4SBarry Smith 195b4319ba4SBarry Smith /* Create the local work vectors */ 1964e4c7dbeSStefano Zampini ierr = VecCreate(PETSC_COMM_SELF,&is->x);CHKERRQ(ierr); 1974e4c7dbeSStefano Zampini ierr = VecSetBlockSize(is->x,bs);CHKERRQ(ierr); 1984e4c7dbeSStefano Zampini ierr = VecSetSizes(is->x,n,n);CHKERRQ(ierr); 199ff130e51SJed Brown ierr = VecSetOptionsPrefix(is->x,((PetscObject)A)->prefix);CHKERRQ(ierr); 200ff130e51SJed Brown ierr = VecAppendOptionsPrefix(is->x,"is_");CHKERRQ(ierr); 2014e4c7dbeSStefano Zampini ierr = VecSetFromOptions(is->x);CHKERRQ(ierr); 202b4319ba4SBarry Smith ierr = VecDuplicate(is->x,&is->y);CHKERRQ(ierr); 203b4319ba4SBarry Smith 204b4319ba4SBarry Smith /* setup the global to local scatter */ 205b4319ba4SBarry Smith ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&to);CHKERRQ(ierr); 206784ac674SJed Brown ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); 2070298fd71SBarry Smith ierr = MatGetVecs(A,&global,NULL);CHKERRQ(ierr); 208b4319ba4SBarry Smith ierr = VecScatterCreate(global,from,is->x,to,&is->ctx);CHKERRQ(ierr); 2096bf464f9SBarry Smith ierr = VecDestroy(&global);CHKERRQ(ierr); 2106bf464f9SBarry Smith ierr = ISDestroy(&to);CHKERRQ(ierr); 2116bf464f9SBarry Smith ierr = ISDestroy(&from);CHKERRQ(ierr); 212b4319ba4SBarry Smith PetscFunctionReturn(0); 213b4319ba4SBarry Smith } 214b4319ba4SBarry Smith 2152e74eeadSLisandro Dalcin #undef __FUNCT__ 2162e74eeadSLisandro Dalcin #define __FUNCT__ "MatSetValues_IS" 2172e74eeadSLisandro Dalcin PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 2182e74eeadSLisandro Dalcin { 2192e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 2202e74eeadSLisandro Dalcin PetscInt rows_l[2048],cols_l[2048]; 2212e74eeadSLisandro Dalcin PetscErrorCode ierr; 2222e74eeadSLisandro Dalcin 2232e74eeadSLisandro Dalcin PetscFunctionBegin; 2242e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 225f23aa3ddSBarry Smith if (m > 2048 || n > 2048) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Number of row/column indices must be <= 2048: they are %D %D",m,n); 2262e74eeadSLisandro Dalcin #endif 2272e74eeadSLisandro Dalcin ierr = ISG2LMapApply(is->mapping,m,rows,rows_l);CHKERRQ(ierr); 2282e74eeadSLisandro Dalcin ierr = ISG2LMapApply(is->mapping,n,cols,cols_l);CHKERRQ(ierr); 2292e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 2302e74eeadSLisandro Dalcin PetscFunctionReturn(0); 2312e74eeadSLisandro Dalcin } 2322e74eeadSLisandro Dalcin 2332e74eeadSLisandro Dalcin #undef ISG2LMapSetUp 2342e74eeadSLisandro Dalcin #undef ISG2LMapApply 235b4319ba4SBarry Smith 236b4319ba4SBarry Smith #undef __FUNCT__ 237b4319ba4SBarry Smith #define __FUNCT__ "MatSetValuesLocal_IS" 23813f74950SBarry Smith PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 239b4319ba4SBarry Smith { 240dfbe8321SBarry Smith PetscErrorCode ierr; 241b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 242b4319ba4SBarry Smith 243b4319ba4SBarry Smith PetscFunctionBegin; 244b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 245b4319ba4SBarry Smith PetscFunctionReturn(0); 246b4319ba4SBarry Smith } 247b4319ba4SBarry Smith 248b4319ba4SBarry Smith #undef __FUNCT__ 249f0006bf2SLisandro Dalcin #define __FUNCT__ "MatSetValuesBlockedLocal_IS" 250f0006bf2SLisandro Dalcin PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 251f0006bf2SLisandro Dalcin { 252f0006bf2SLisandro Dalcin PetscErrorCode ierr; 253f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 254f0006bf2SLisandro Dalcin 255f0006bf2SLisandro Dalcin PetscFunctionBegin; 256f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 257f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 258f0006bf2SLisandro Dalcin } 259f0006bf2SLisandro Dalcin 260f0006bf2SLisandro Dalcin #undef __FUNCT__ 2612e74eeadSLisandro Dalcin #define __FUNCT__ "MatZeroRows_IS" 2622b40b63fSBarry Smith PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2632e74eeadSLisandro Dalcin { 2642e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 2650298fd71SBarry Smith PetscInt n_l = 0, *rows_l = NULL; 2662e74eeadSLisandro Dalcin PetscErrorCode ierr; 2672e74eeadSLisandro Dalcin 2682e74eeadSLisandro Dalcin PetscFunctionBegin; 269ce94432eSBarry Smith if (x && b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support"); 2702e74eeadSLisandro Dalcin if (n) { 2712e74eeadSLisandro Dalcin ierr = PetscMalloc(n*sizeof(PetscInt),&rows_l);CHKERRQ(ierr); 2722e74eeadSLisandro Dalcin ierr = ISGlobalToLocalMappingApply(is->mapping,IS_GTOLM_DROP,n,rows,&n_l,rows_l);CHKERRQ(ierr); 2732e74eeadSLisandro Dalcin } 2742b40b63fSBarry Smith ierr = MatZeroRowsLocal(A,n_l,rows_l,diag,x,b);CHKERRQ(ierr); 275c31cb41cSBarry Smith ierr = PetscFree(rows_l);CHKERRQ(ierr); 2762e74eeadSLisandro Dalcin PetscFunctionReturn(0); 2772e74eeadSLisandro Dalcin } 2782e74eeadSLisandro Dalcin 2792e74eeadSLisandro Dalcin #undef __FUNCT__ 280b4319ba4SBarry Smith #define __FUNCT__ "MatZeroRowsLocal_IS" 2812b40b63fSBarry Smith PetscErrorCode MatZeroRowsLocal_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 282b4319ba4SBarry Smith { 283b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 284dfbe8321SBarry Smith PetscErrorCode ierr; 285f4df32b1SMatthew Knepley PetscInt i; 286b4319ba4SBarry Smith PetscScalar *array; 287b4319ba4SBarry Smith 288b4319ba4SBarry Smith PetscFunctionBegin; 289ce94432eSBarry Smith if (x && b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support"); 290b4319ba4SBarry Smith { 291b4319ba4SBarry Smith /* 292b4319ba4SBarry Smith Set up is->x as a "counting vector". This is in order to MatMult_IS 293b4319ba4SBarry Smith work properly in the interface nodes. 294b4319ba4SBarry Smith */ 295b4319ba4SBarry Smith Vec counter; 296b4319ba4SBarry Smith PetscScalar one=1.0, zero=0.0; 2970298fd71SBarry Smith ierr = MatGetVecs(A,&counter,NULL);CHKERRQ(ierr); 2982dcb1b2aSMatthew Knepley ierr = VecSet(counter,zero);CHKERRQ(ierr); 2992dcb1b2aSMatthew Knepley ierr = VecSet(is->x,one);CHKERRQ(ierr); 300ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,is->x,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 301ca9f406cSSatish Balay ierr = VecScatterEnd (is->ctx,is->x,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 302ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,counter,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 303ca9f406cSSatish Balay ierr = VecScatterEnd (is->ctx,counter,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3046bf464f9SBarry Smith ierr = VecDestroy(&counter);CHKERRQ(ierr); 305b4319ba4SBarry Smith } 306958c9bccSBarry Smith if (!n) { 307b4319ba4SBarry Smith is->pure_neumann = PETSC_TRUE; 308b4319ba4SBarry Smith } else { 309b4319ba4SBarry Smith is->pure_neumann = PETSC_FALSE; 3102205254eSKarl Rupp 311b4319ba4SBarry Smith ierr = VecGetArray(is->x,&array);CHKERRQ(ierr); 3122b40b63fSBarry Smith ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 313b4319ba4SBarry Smith for (i=0; i<n; i++) { 314f4df32b1SMatthew Knepley ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 315b4319ba4SBarry Smith } 316b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 317b4319ba4SBarry Smith ierr = MatAssemblyEnd (is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 318b4319ba4SBarry Smith ierr = VecRestoreArray(is->x,&array);CHKERRQ(ierr); 319b4319ba4SBarry Smith } 320b4319ba4SBarry Smith PetscFunctionReturn(0); 321b4319ba4SBarry Smith } 322b4319ba4SBarry Smith 323b4319ba4SBarry Smith #undef __FUNCT__ 324b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyBegin_IS" 325dfbe8321SBarry Smith PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 326b4319ba4SBarry Smith { 327b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 328dfbe8321SBarry Smith PetscErrorCode ierr; 329b4319ba4SBarry Smith 330b4319ba4SBarry Smith PetscFunctionBegin; 331b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 332b4319ba4SBarry Smith PetscFunctionReturn(0); 333b4319ba4SBarry Smith } 334b4319ba4SBarry Smith 335b4319ba4SBarry Smith #undef __FUNCT__ 336b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyEnd_IS" 337dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 338b4319ba4SBarry Smith { 339b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 340dfbe8321SBarry Smith PetscErrorCode ierr; 341b4319ba4SBarry Smith 342b4319ba4SBarry Smith PetscFunctionBegin; 343b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 344b4319ba4SBarry Smith PetscFunctionReturn(0); 345b4319ba4SBarry Smith } 346b4319ba4SBarry Smith 347b4319ba4SBarry Smith #undef __FUNCT__ 348b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat_IS" 3497087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 350b4319ba4SBarry Smith { 351b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 352b4319ba4SBarry Smith 353b4319ba4SBarry Smith PetscFunctionBegin; 354b4319ba4SBarry Smith *local = is->A; 355b4319ba4SBarry Smith PetscFunctionReturn(0); 356b4319ba4SBarry Smith } 357b4319ba4SBarry Smith 358b4319ba4SBarry Smith #undef __FUNCT__ 359b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat" 360b4319ba4SBarry Smith /*@ 361b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 362b4319ba4SBarry Smith 363b4319ba4SBarry Smith Input Parameter: 364b4319ba4SBarry Smith . mat - the matrix 365b4319ba4SBarry Smith 366b4319ba4SBarry Smith Output Parameter: 367b4319ba4SBarry Smith . local - the local matrix usually MATSEQAIJ 368b4319ba4SBarry Smith 369b4319ba4SBarry Smith Level: advanced 370b4319ba4SBarry Smith 371b4319ba4SBarry Smith Notes: 372b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 373b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 374b4319ba4SBarry Smith of the MatSetValues() operation. 375b4319ba4SBarry Smith 376b4319ba4SBarry Smith .seealso: MATIS 377b4319ba4SBarry Smith @*/ 3787087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 379b4319ba4SBarry Smith { 3804ac538c5SBarry Smith PetscErrorCode ierr; 381b4319ba4SBarry Smith 382b4319ba4SBarry Smith PetscFunctionBegin; 3830700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 384b4319ba4SBarry Smith PetscValidPointer(local,2); 3854ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 386b4319ba4SBarry Smith PetscFunctionReturn(0); 387b4319ba4SBarry Smith } 388b4319ba4SBarry Smith 3893b03a366Sstefano_zampini #undef __FUNCT__ 3903b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat_IS" 3913b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 3923b03a366Sstefano_zampini { 3933b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 3943b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 3953b03a366Sstefano_zampini PetscErrorCode ierr; 3963b03a366Sstefano_zampini 3973b03a366Sstefano_zampini PetscFunctionBegin; 3984e4c7dbeSStefano Zampini if (is->A) { 3993b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 4003b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 401f23aa3ddSBarry Smith if (orows != nrows || ocols != ncols) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local MATIS matrix should be of size %dx%d (you passed a %dx%d matrix)\n",orows,ocols,nrows,ncols); 4024e4c7dbeSStefano Zampini } 4033b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 4043b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 4053b03a366Sstefano_zampini is->A = local; 4063b03a366Sstefano_zampini PetscFunctionReturn(0); 4073b03a366Sstefano_zampini } 4083b03a366Sstefano_zampini 4093b03a366Sstefano_zampini #undef __FUNCT__ 4103b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat" 4113b03a366Sstefano_zampini /*@ 4123b03a366Sstefano_zampini MatISSetLocalMat - Set the local matrix stored inside a MATIS matrix. 4133b03a366Sstefano_zampini 4143b03a366Sstefano_zampini Input Parameter: 4153b03a366Sstefano_zampini . mat - the matrix 4163b03a366Sstefano_zampini . local - the local matrix usually MATSEQAIJ 4173b03a366Sstefano_zampini 4183b03a366Sstefano_zampini Output Parameter: 4193b03a366Sstefano_zampini 4203b03a366Sstefano_zampini Level: advanced 4213b03a366Sstefano_zampini 4223b03a366Sstefano_zampini Notes: 4233b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 4243b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 4253b03a366Sstefano_zampini 4263b03a366Sstefano_zampini .seealso: MATIS 4273b03a366Sstefano_zampini @*/ 4283b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 4293b03a366Sstefano_zampini { 4303b03a366Sstefano_zampini PetscErrorCode ierr; 4313b03a366Sstefano_zampini 4323b03a366Sstefano_zampini PetscFunctionBegin; 4333b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4343b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 4353b03a366Sstefano_zampini PetscFunctionReturn(0); 4363b03a366Sstefano_zampini } 4373b03a366Sstefano_zampini 4386726f965SBarry Smith #undef __FUNCT__ 4396726f965SBarry Smith #define __FUNCT__ "MatZeroEntries_IS" 4406726f965SBarry Smith PetscErrorCode MatZeroEntries_IS(Mat A) 4416726f965SBarry Smith { 4426726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 4436726f965SBarry Smith PetscErrorCode ierr; 4446726f965SBarry Smith 4456726f965SBarry Smith PetscFunctionBegin; 4466726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 4476726f965SBarry Smith PetscFunctionReturn(0); 4486726f965SBarry Smith } 4496726f965SBarry Smith 4506726f965SBarry Smith #undef __FUNCT__ 4512e74eeadSLisandro Dalcin #define __FUNCT__ "MatScale_IS" 4522e74eeadSLisandro Dalcin PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 4532e74eeadSLisandro Dalcin { 4542e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 4552e74eeadSLisandro Dalcin PetscErrorCode ierr; 4562e74eeadSLisandro Dalcin 4572e74eeadSLisandro Dalcin PetscFunctionBegin; 4582e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 4592e74eeadSLisandro Dalcin PetscFunctionReturn(0); 4602e74eeadSLisandro Dalcin } 4612e74eeadSLisandro Dalcin 4622e74eeadSLisandro Dalcin #undef __FUNCT__ 4632e74eeadSLisandro Dalcin #define __FUNCT__ "MatGetDiagonal_IS" 4642e74eeadSLisandro Dalcin PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 4652e74eeadSLisandro Dalcin { 4662e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 4672e74eeadSLisandro Dalcin PetscErrorCode ierr; 4682e74eeadSLisandro Dalcin 4692e74eeadSLisandro Dalcin PetscFunctionBegin; 4702e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 4712e74eeadSLisandro Dalcin ierr = MatGetDiagonal(is->A,is->x);CHKERRQ(ierr); 4722e74eeadSLisandro Dalcin 4732e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 4742e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 475ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,is->x,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 476ca9f406cSSatish Balay ierr = VecScatterEnd (is->ctx,is->x,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4772e74eeadSLisandro Dalcin PetscFunctionReturn(0); 4782e74eeadSLisandro Dalcin } 4792e74eeadSLisandro Dalcin 4802e74eeadSLisandro Dalcin #undef __FUNCT__ 4816726f965SBarry Smith #define __FUNCT__ "MatSetOption_IS" 482ace3abfcSBarry Smith PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 4836726f965SBarry Smith { 4846726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 4856726f965SBarry Smith PetscErrorCode ierr; 4866726f965SBarry Smith 4876726f965SBarry Smith PetscFunctionBegin; 4884e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 4896726f965SBarry Smith PetscFunctionReturn(0); 4906726f965SBarry Smith } 4916726f965SBarry Smith 492284134d9SBarry Smith #undef __FUNCT__ 493284134d9SBarry Smith #define __FUNCT__ "MatCreateIS" 494284134d9SBarry Smith /*@ 495284134d9SBarry Smith MatCreateIS - Creates a "process" unassmembled matrix, it is assembled on each 496284134d9SBarry Smith process but not across processes. 497284134d9SBarry Smith 498284134d9SBarry Smith Input Parameters: 499284134d9SBarry Smith + comm - MPI communicator that will share the matrix 5004e4c7dbeSStefano Zampini . bs - local and global block size of the matrix 501284134d9SBarry Smith . m,n,M,N - local and/or global sizes of the the left and right vector used in matrix vector products 502284134d9SBarry Smith - map - mapping that defines the global number for each local number 503284134d9SBarry Smith 504284134d9SBarry Smith Output Parameter: 505284134d9SBarry Smith . A - the resulting matrix 506284134d9SBarry Smith 5078e6c10adSSatish Balay Level: advanced 5088e6c10adSSatish Balay 509284134d9SBarry Smith Notes: See MATIS for more details 5108cda6cd7SBarry Smith m and n are NOT related to the size of the map, they are the size of the part of the vector owned 5118cda6cd7SBarry Smith by that process. m + nghosts (or n + nghosts) is the length of map since map maps all local points 5128cda6cd7SBarry Smith plus the ghost points to global indices. 513284134d9SBarry Smith 514284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 515284134d9SBarry Smith @*/ 5164e4c7dbeSStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping map,Mat *A) 517284134d9SBarry Smith { 518284134d9SBarry Smith PetscErrorCode ierr; 519284134d9SBarry Smith 520284134d9SBarry Smith PetscFunctionBegin; 521284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 522d3ee2243SStefano Zampini ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 523284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 524284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 5253b03a366Sstefano_zampini ierr = MatSetUp(*A);CHKERRQ(ierr); 526784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(*A,map,map);CHKERRQ(ierr); 527284134d9SBarry Smith PetscFunctionReturn(0); 528284134d9SBarry Smith } 529284134d9SBarry Smith 530b4319ba4SBarry Smith /*MC 531b4319ba4SBarry Smith MATIS - MATIS = "is" - A matrix type to be used for using the Neumann-Neumann type preconditioners. 532b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 533b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 534b4319ba4SBarry Smith product is handled "implicitly". 535b4319ba4SBarry Smith 536b4319ba4SBarry Smith Operations Provided: 5376726f965SBarry Smith + MatMult() 5382e74eeadSLisandro Dalcin . MatMultAdd() 5392e74eeadSLisandro Dalcin . MatMultTranspose() 5402e74eeadSLisandro Dalcin . MatMultTransposeAdd() 5416726f965SBarry Smith . MatZeroEntries() 5426726f965SBarry Smith . MatSetOption() 5432e74eeadSLisandro Dalcin . MatZeroRows() 5446726f965SBarry Smith . MatZeroRowsLocal() 5452e74eeadSLisandro Dalcin . MatSetValues() 5466726f965SBarry Smith . MatSetValuesLocal() 5472e74eeadSLisandro Dalcin . MatScale() 5482e74eeadSLisandro Dalcin . MatGetDiagonal() 5496726f965SBarry Smith - MatSetLocalToGlobalMapping() 550b4319ba4SBarry Smith 551b4319ba4SBarry Smith Options Database Keys: 552b4319ba4SBarry Smith . -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 553b4319ba4SBarry Smith 554b4319ba4SBarry Smith Notes: Options prefix for the inner matrix are given by -is_mat_xxx 555b4319ba4SBarry Smith 556b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 557b4319ba4SBarry Smith 558b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 559b4319ba4SBarry Smith MatISGetLocalMat() 560b4319ba4SBarry Smith 561b4319ba4SBarry Smith Level: advanced 562b4319ba4SBarry Smith 563b4319ba4SBarry Smith .seealso: PC, MatISGetLocalMat(), MatSetLocalToGlobalMapping() 564b4319ba4SBarry Smith 565b4319ba4SBarry Smith M*/ 566b4319ba4SBarry Smith 567b4319ba4SBarry Smith #undef __FUNCT__ 568b4319ba4SBarry Smith #define __FUNCT__ "MatCreate_IS" 5698cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 570b4319ba4SBarry Smith { 571dfbe8321SBarry Smith PetscErrorCode ierr; 572b4319ba4SBarry Smith Mat_IS *b; 573b4319ba4SBarry Smith 574b4319ba4SBarry Smith PetscFunctionBegin; 57538f2d2fdSLisandro Dalcin ierr = PetscNewLog(A,Mat_IS,&b);CHKERRQ(ierr); 576b4319ba4SBarry Smith A->data = (void*)b; 577b4319ba4SBarry Smith ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 578b4319ba4SBarry Smith 579b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 5802e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 5812e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 5822e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 583b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 584b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 5852e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 586b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 587f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 5882e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 589b4319ba4SBarry Smith A->ops->zerorowslocal = MatZeroRowsLocal_IS; 590b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 591b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 592b4319ba4SBarry Smith A->ops->view = MatView_IS; 5936726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 5942e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 5952e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 5966726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 59769796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 59869796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 599b4319ba4SBarry Smith 60026283091SBarry Smith ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 60126283091SBarry Smith ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 602b4319ba4SBarry Smith 603b4319ba4SBarry Smith b->A = 0; 604b4319ba4SBarry Smith b->ctx = 0; 605b4319ba4SBarry Smith b->x = 0; 606b4319ba4SBarry Smith b->y = 0; 607bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 608bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 60917667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 610b4319ba4SBarry Smith PetscFunctionReturn(0); 611b4319ba4SBarry Smith } 612