1be1d678aSKris Buschelman #define PETSCMAT_DLL 2be1d678aSKris Buschelman 3b4319ba4SBarry Smith /* 4b4319ba4SBarry Smith Creates a matrix class for using the Neumann-Neumann type preconditioners. 5b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 6b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 7b4319ba4SBarry Smith product is handled "implicitly". 8b4319ba4SBarry Smith 9b4319ba4SBarry Smith We provide: 10b4319ba4SBarry Smith MatMult() 11b4319ba4SBarry Smith 12b4319ba4SBarry Smith Currently this allows for only one subdomain per processor. 13b4319ba4SBarry Smith 14b4319ba4SBarry Smith */ 15b4319ba4SBarry Smith 167c4f633dSBarry Smith #include "../src/mat/impls/is/matis.h" /*I "petscmat.h" I*/ 17b4319ba4SBarry Smith 18b4319ba4SBarry Smith #undef __FUNCT__ 19b4319ba4SBarry Smith #define __FUNCT__ "MatDestroy_IS" 20dfbe8321SBarry Smith PetscErrorCode MatDestroy_IS(Mat A) 21b4319ba4SBarry Smith { 22dfbe8321SBarry Smith PetscErrorCode ierr; 23b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 24b4319ba4SBarry Smith 25b4319ba4SBarry Smith PetscFunctionBegin; 26b4319ba4SBarry Smith if (b->A) { 27b4319ba4SBarry Smith ierr = MatDestroy(b->A);CHKERRQ(ierr); 28b4319ba4SBarry Smith } 29b4319ba4SBarry Smith if (b->ctx) { 30b4319ba4SBarry Smith ierr = VecScatterDestroy(b->ctx);CHKERRQ(ierr); 31b4319ba4SBarry Smith } 32b4319ba4SBarry Smith if (b->x) { 33b4319ba4SBarry Smith ierr = VecDestroy(b->x);CHKERRQ(ierr); 34b4319ba4SBarry Smith } 35b4319ba4SBarry Smith if (b->y) { 36b4319ba4SBarry Smith ierr = VecDestroy(b->y);CHKERRQ(ierr); 37b4319ba4SBarry Smith } 38b4319ba4SBarry Smith if (b->mapping) { 39b4319ba4SBarry Smith ierr = ISLocalToGlobalMappingDestroy(b->mapping);CHKERRQ(ierr); 40b4319ba4SBarry Smith } 41b4319ba4SBarry Smith ierr = PetscFree(b);CHKERRQ(ierr); 42dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 43901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C","",PETSC_NULL);CHKERRQ(ierr); 44b4319ba4SBarry Smith PetscFunctionReturn(0); 45b4319ba4SBarry Smith } 46b4319ba4SBarry Smith 47b4319ba4SBarry Smith #undef __FUNCT__ 48b4319ba4SBarry Smith #define __FUNCT__ "MatMult_IS" 49dfbe8321SBarry Smith PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 50b4319ba4SBarry Smith { 51dfbe8321SBarry Smith PetscErrorCode ierr; 52b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 53b4319ba4SBarry Smith PetscScalar zero = 0.0; 54b4319ba4SBarry Smith 55b4319ba4SBarry Smith PetscFunctionBegin; 56b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 57ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 58ca9f406cSSatish Balay ierr = VecScatterEnd(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 59b4319ba4SBarry Smith 60b4319ba4SBarry Smith /* multiply the local matrix */ 61b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 62b4319ba4SBarry Smith 63b4319ba4SBarry Smith /* scatter product back into global memory */ 642dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 65ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 66ca9f406cSSatish Balay ierr = VecScatterEnd(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 67b4319ba4SBarry Smith 68b4319ba4SBarry Smith PetscFunctionReturn(0); 69b4319ba4SBarry Smith } 70b4319ba4SBarry Smith 71b4319ba4SBarry Smith #undef __FUNCT__ 722e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultAdd_IS" 732e74eeadSLisandro Dalcin static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 742e74eeadSLisandro Dalcin { 752e74eeadSLisandro Dalcin PetscErrorCode ierr; 762e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 772e74eeadSLisandro Dalcin 782e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 792e74eeadSLisandro Dalcin /* scatter the global vector v1 into the local work vector */ 80ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,v1,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 81ca9f406cSSatish Balay ierr = VecScatterEnd (is->ctx,v1,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 82ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,v2,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 83ca9f406cSSatish Balay ierr = VecScatterEnd (is->ctx,v2,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 842e74eeadSLisandro Dalcin 852e74eeadSLisandro Dalcin /* multiply the local matrix */ 862e74eeadSLisandro Dalcin ierr = MatMultAdd(is->A,is->x,is->y,is->y);CHKERRQ(ierr); 872e74eeadSLisandro Dalcin 882e74eeadSLisandro Dalcin /* scatter result back into global vector */ 892e74eeadSLisandro Dalcin ierr = VecSet(v3,0);CHKERRQ(ierr); 90ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,is->y,v3,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 91ca9f406cSSatish Balay ierr = VecScatterEnd (is->ctx,is->y,v3,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 922e74eeadSLisandro Dalcin PetscFunctionReturn(0); 932e74eeadSLisandro Dalcin } 942e74eeadSLisandro Dalcin 952e74eeadSLisandro Dalcin #undef __FUNCT__ 962e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTranspose_IS" 972e74eeadSLisandro Dalcin PetscErrorCode MatMultTranspose_IS(Mat A,Vec x,Vec y) 982e74eeadSLisandro Dalcin { 992e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 1002e74eeadSLisandro Dalcin PetscErrorCode ierr; 1012e74eeadSLisandro Dalcin 1022e74eeadSLisandro Dalcin PetscFunctionBegin; /* y = A' * x */ 1032e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 104ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 105ca9f406cSSatish Balay ierr = VecScatterEnd(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1062e74eeadSLisandro Dalcin 1072e74eeadSLisandro Dalcin /* multiply the local matrix */ 1082e74eeadSLisandro Dalcin ierr = MatMultTranspose(is->A,is->x,is->y);CHKERRQ(ierr); 1092e74eeadSLisandro Dalcin 1102e74eeadSLisandro Dalcin /* scatter product back into global vector */ 1112e74eeadSLisandro Dalcin ierr = VecSet(y,0);CHKERRQ(ierr); 112ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 113ca9f406cSSatish Balay ierr = VecScatterEnd(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1142e74eeadSLisandro Dalcin PetscFunctionReturn(0); 1152e74eeadSLisandro Dalcin } 1162e74eeadSLisandro Dalcin 1172e74eeadSLisandro Dalcin #undef __FUNCT__ 1182e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTransposeAdd_IS" 1192e74eeadSLisandro Dalcin PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 1202e74eeadSLisandro Dalcin { 1212e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 1222e74eeadSLisandro Dalcin PetscErrorCode ierr; 1232e74eeadSLisandro Dalcin 1242e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 1252e74eeadSLisandro Dalcin /* scatter the global vectors v1 and v2 into the local work vectors */ 126ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,v1,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 127ca9f406cSSatish Balay ierr = VecScatterEnd (is->ctx,v1,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 128ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,v2,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 129ca9f406cSSatish Balay ierr = VecScatterEnd (is->ctx,v2,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1302e74eeadSLisandro Dalcin 1312e74eeadSLisandro Dalcin /* multiply the local matrix */ 1322e74eeadSLisandro Dalcin ierr = MatMultTransposeAdd(is->A,is->x,is->y,is->y);CHKERRQ(ierr); 1332e74eeadSLisandro Dalcin 1342e74eeadSLisandro Dalcin /* scatter result back into global vector */ 1352e74eeadSLisandro Dalcin ierr = VecSet(v3,0);CHKERRQ(ierr); 136ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,is->y,v3,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 137ca9f406cSSatish Balay ierr = VecScatterEnd (is->ctx,is->y,v3,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1382e74eeadSLisandro Dalcin PetscFunctionReturn(0); 1392e74eeadSLisandro Dalcin } 1402e74eeadSLisandro Dalcin 1412e74eeadSLisandro Dalcin #undef __FUNCT__ 142b4319ba4SBarry Smith #define __FUNCT__ "MatView_IS" 143dfbe8321SBarry Smith PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 144b4319ba4SBarry Smith { 145b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 146dfbe8321SBarry Smith PetscErrorCode ierr; 147b4319ba4SBarry Smith PetscViewer sviewer; 148b4319ba4SBarry Smith 149b4319ba4SBarry Smith PetscFunctionBegin; 150b4319ba4SBarry Smith ierr = PetscViewerGetSingleton(viewer,&sviewer);CHKERRQ(ierr); 151b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 152b4319ba4SBarry Smith ierr = PetscViewerRestoreSingleton(viewer,&sviewer);CHKERRQ(ierr); 153b4319ba4SBarry Smith PetscFunctionReturn(0); 154b4319ba4SBarry Smith } 155b4319ba4SBarry Smith 156b4319ba4SBarry Smith #undef __FUNCT__ 157b4319ba4SBarry Smith #define __FUNCT__ "MatSetLocalToGlobalMapping_IS" 158*784ac674SJed Brown PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 159b4319ba4SBarry Smith { 160dfbe8321SBarry Smith PetscErrorCode ierr; 16113f74950SBarry Smith PetscInt n; 162b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 163b4319ba4SBarry Smith IS from,to; 164b4319ba4SBarry Smith Vec global; 165b4319ba4SBarry Smith 166b4319ba4SBarry Smith PetscFunctionBegin; 167e7e72b3dSBarry Smith if (is->mapping) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix"); 168*784ac674SJed Brown PetscCheckSameComm(A,1,rmapping,2); 169*784ac674SJed Brown if (rmapping != cmapping) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MATIS requires the row and column mappings to be identical"); 170*784ac674SJed Brown ierr = PetscObjectReference((PetscObject)rmapping);CHKERRQ(ierr); 171c3122656SLisandro Dalcin if (is->mapping) { ierr = ISLocalToGlobalMappingDestroy(is->mapping);CHKERRQ(ierr); } 172*784ac674SJed Brown is->mapping = rmapping; 173b4319ba4SBarry Smith 174b4319ba4SBarry Smith /* Create the local matrix A */ 175*784ac674SJed Brown ierr = ISLocalToGlobalMappingGetSize(rmapping,&n);CHKERRQ(ierr); 176f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 177f69a0ea3SMatthew Knepley ierr = MatSetSizes(is->A,n,n,n,n);CHKERRQ(ierr); 1782e74eeadSLisandro Dalcin ierr = MatSetOptionsPrefix(is->A,"is");CHKERRQ(ierr); 179b4319ba4SBarry Smith ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 180b4319ba4SBarry Smith 181b4319ba4SBarry Smith /* Create the local work vectors */ 182b4319ba4SBarry Smith ierr = VecCreateSeq(PETSC_COMM_SELF,n,&is->x);CHKERRQ(ierr); 183b4319ba4SBarry Smith ierr = VecDuplicate(is->x,&is->y);CHKERRQ(ierr); 184b4319ba4SBarry Smith 185b4319ba4SBarry Smith /* setup the global to local scatter */ 186b4319ba4SBarry Smith ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&to);CHKERRQ(ierr); 187*784ac674SJed Brown ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); 188d0f46423SBarry Smith ierr = VecCreateMPIWithArray(((PetscObject)A)->comm,A->cmap->n,A->cmap->N,PETSC_NULL,&global);CHKERRQ(ierr); 189b4319ba4SBarry Smith ierr = VecScatterCreate(global,from,is->x,to,&is->ctx);CHKERRQ(ierr); 190b4319ba4SBarry Smith ierr = VecDestroy(global);CHKERRQ(ierr); 191b4319ba4SBarry Smith ierr = ISDestroy(to);CHKERRQ(ierr); 192b4319ba4SBarry Smith ierr = ISDestroy(from);CHKERRQ(ierr); 193b4319ba4SBarry Smith PetscFunctionReturn(0); 194b4319ba4SBarry Smith } 195b4319ba4SBarry Smith 1962e74eeadSLisandro Dalcin #define ISG2LMapApply(mapping,n,in,out) 0;\ 1972e74eeadSLisandro Dalcin if (!(mapping)->globals) {\ 1982e74eeadSLisandro Dalcin PetscErrorCode _ierr = ISGlobalToLocalMappingApply((mapping),IS_GTOLM_MASK,0,0,0,0);CHKERRQ(_ierr);\ 1992e74eeadSLisandro Dalcin }\ 2002e74eeadSLisandro Dalcin {\ 2012e74eeadSLisandro Dalcin PetscInt _i,*_globals = (mapping)->globals,_start = (mapping)->globalstart,_end = (mapping)->globalend;\ 2022e74eeadSLisandro Dalcin for (_i=0; _i<n; _i++) {\ 2032e74eeadSLisandro Dalcin if (in[_i] < 0) out[_i] = in[_i];\ 2042e74eeadSLisandro Dalcin else if (in[_i] < _start) out[_i] = -1;\ 2052e74eeadSLisandro Dalcin else if (in[_i] > _end) out[_i] = -1;\ 2062e74eeadSLisandro Dalcin else out[_i] = _globals[in[_i] - _start];\ 2072e74eeadSLisandro Dalcin }\ 2082e74eeadSLisandro Dalcin } 2092e74eeadSLisandro Dalcin 2102e74eeadSLisandro Dalcin #undef __FUNCT__ 2112e74eeadSLisandro Dalcin #define __FUNCT__ "MatSetValues_IS" 2122e74eeadSLisandro Dalcin PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 2132e74eeadSLisandro Dalcin { 2142e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 2152e74eeadSLisandro Dalcin PetscInt rows_l[2048],cols_l[2048]; 2162e74eeadSLisandro Dalcin PetscErrorCode ierr; 2172e74eeadSLisandro Dalcin 2182e74eeadSLisandro Dalcin PetscFunctionBegin; 2192e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 2202e74eeadSLisandro Dalcin if (m > 2048 || n > 2048) { 221e32f2f54SBarry Smith SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Number of row/column indices must be <= 2048: they are %D %D",m,n); 2222e74eeadSLisandro Dalcin } 2232e74eeadSLisandro Dalcin #endif 2242e74eeadSLisandro Dalcin ierr = ISG2LMapApply(is->mapping,m,rows,rows_l);CHKERRQ(ierr); 2252e74eeadSLisandro Dalcin ierr = ISG2LMapApply(is->mapping,n,cols,cols_l);CHKERRQ(ierr); 2262e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 2272e74eeadSLisandro Dalcin PetscFunctionReturn(0); 2282e74eeadSLisandro Dalcin } 2292e74eeadSLisandro Dalcin 2302e74eeadSLisandro Dalcin #undef ISG2LMapSetUp 2312e74eeadSLisandro Dalcin #undef ISG2LMapApply 232b4319ba4SBarry Smith 233b4319ba4SBarry Smith #undef __FUNCT__ 234b4319ba4SBarry Smith #define __FUNCT__ "MatSetValuesLocal_IS" 23513f74950SBarry Smith PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 236b4319ba4SBarry Smith { 237dfbe8321SBarry Smith PetscErrorCode ierr; 238b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 239b4319ba4SBarry Smith 240b4319ba4SBarry Smith PetscFunctionBegin; 241b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 242b4319ba4SBarry Smith PetscFunctionReturn(0); 243b4319ba4SBarry Smith } 244b4319ba4SBarry Smith 245b4319ba4SBarry Smith #undef __FUNCT__ 2462e74eeadSLisandro Dalcin #define __FUNCT__ "MatZeroRows_IS" 2472b40b63fSBarry Smith PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2482e74eeadSLisandro Dalcin { 2492e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 2502e74eeadSLisandro Dalcin PetscInt n_l=0, *rows_l = PETSC_NULL; 2512e74eeadSLisandro Dalcin PetscErrorCode ierr; 2522e74eeadSLisandro Dalcin 2532e74eeadSLisandro Dalcin PetscFunctionBegin; 25497b48c8fSBarry Smith if (x && b) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"No support"); 2552e74eeadSLisandro Dalcin if (n) { 2562e74eeadSLisandro Dalcin ierr = PetscMalloc(n*sizeof(PetscInt),&rows_l);CHKERRQ(ierr); 2572e74eeadSLisandro Dalcin ierr = ISGlobalToLocalMappingApply(is->mapping,IS_GTOLM_DROP,n,rows,&n_l,rows_l);CHKERRQ(ierr); 2582e74eeadSLisandro Dalcin } 2592b40b63fSBarry Smith ierr = MatZeroRowsLocal(A,n_l,rows_l,diag,x,b);CHKERRQ(ierr); 2602e74eeadSLisandro Dalcin if (rows_l) { ierr = PetscFree(rows_l);CHKERRQ(ierr); } 2612e74eeadSLisandro Dalcin PetscFunctionReturn(0); 2622e74eeadSLisandro Dalcin } 2632e74eeadSLisandro Dalcin 2642e74eeadSLisandro Dalcin #undef __FUNCT__ 265b4319ba4SBarry Smith #define __FUNCT__ "MatZeroRowsLocal_IS" 2662b40b63fSBarry Smith PetscErrorCode MatZeroRowsLocal_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 267b4319ba4SBarry Smith { 268b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 269dfbe8321SBarry Smith PetscErrorCode ierr; 270f4df32b1SMatthew Knepley PetscInt i; 271b4319ba4SBarry Smith PetscScalar *array; 272b4319ba4SBarry Smith 273b4319ba4SBarry Smith PetscFunctionBegin; 2749c3e2b52SBarry Smith if (x && b) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"No support"); 275b4319ba4SBarry Smith { 276b4319ba4SBarry Smith /* 277b4319ba4SBarry Smith Set up is->x as a "counting vector". This is in order to MatMult_IS 278b4319ba4SBarry Smith work properly in the interface nodes. 279b4319ba4SBarry Smith */ 280b4319ba4SBarry Smith Vec counter; 281b4319ba4SBarry Smith PetscScalar one=1.0, zero=0.0; 282d0f46423SBarry Smith ierr = VecCreateMPI(((PetscObject)A)->comm,A->cmap->n,A->cmap->N,&counter);CHKERRQ(ierr); 2832dcb1b2aSMatthew Knepley ierr = VecSet(counter,zero);CHKERRQ(ierr); 2842dcb1b2aSMatthew Knepley ierr = VecSet(is->x,one);CHKERRQ(ierr); 285ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,is->x,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 286ca9f406cSSatish Balay ierr = VecScatterEnd (is->ctx,is->x,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 287ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,counter,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 288ca9f406cSSatish Balay ierr = VecScatterEnd (is->ctx,counter,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 289b4319ba4SBarry Smith ierr = VecDestroy(counter);CHKERRQ(ierr); 290b4319ba4SBarry Smith } 291958c9bccSBarry Smith if (!n) { 292b4319ba4SBarry Smith is->pure_neumann = PETSC_TRUE; 293b4319ba4SBarry Smith } else { 294b4319ba4SBarry Smith is->pure_neumann = PETSC_FALSE; 295b4319ba4SBarry Smith ierr = VecGetArray(is->x,&array);CHKERRQ(ierr); 2962b40b63fSBarry Smith ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 297b4319ba4SBarry Smith for (i=0; i<n; i++) { 298f4df32b1SMatthew Knepley ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 299b4319ba4SBarry Smith } 300b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 301b4319ba4SBarry Smith ierr = MatAssemblyEnd (is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 302b4319ba4SBarry Smith ierr = VecRestoreArray(is->x,&array);CHKERRQ(ierr); 303b4319ba4SBarry Smith } 304b4319ba4SBarry Smith 305b4319ba4SBarry Smith PetscFunctionReturn(0); 306b4319ba4SBarry Smith } 307b4319ba4SBarry Smith 308b4319ba4SBarry Smith #undef __FUNCT__ 309b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyBegin_IS" 310dfbe8321SBarry Smith PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 311b4319ba4SBarry Smith { 312b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 313dfbe8321SBarry Smith PetscErrorCode ierr; 314b4319ba4SBarry Smith 315b4319ba4SBarry Smith PetscFunctionBegin; 316b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 317b4319ba4SBarry Smith PetscFunctionReturn(0); 318b4319ba4SBarry Smith } 319b4319ba4SBarry Smith 320b4319ba4SBarry Smith #undef __FUNCT__ 321b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyEnd_IS" 322dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 323b4319ba4SBarry Smith { 324b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 325dfbe8321SBarry Smith PetscErrorCode ierr; 326b4319ba4SBarry Smith 327b4319ba4SBarry Smith PetscFunctionBegin; 328b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 329b4319ba4SBarry Smith PetscFunctionReturn(0); 330b4319ba4SBarry Smith } 331b4319ba4SBarry Smith 332b4319ba4SBarry Smith EXTERN_C_BEGIN 333b4319ba4SBarry Smith #undef __FUNCT__ 334b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat_IS" 335be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatISGetLocalMat_IS(Mat mat,Mat *local) 336b4319ba4SBarry Smith { 337b4319ba4SBarry Smith Mat_IS *is = (Mat_IS *)mat->data; 338b4319ba4SBarry Smith 339b4319ba4SBarry Smith PetscFunctionBegin; 340b4319ba4SBarry Smith *local = is->A; 341b4319ba4SBarry Smith PetscFunctionReturn(0); 342b4319ba4SBarry Smith } 343b4319ba4SBarry Smith EXTERN_C_END 344b4319ba4SBarry Smith 345b4319ba4SBarry Smith #undef __FUNCT__ 346b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat" 347b4319ba4SBarry Smith /*@ 348b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 349b4319ba4SBarry Smith 350b4319ba4SBarry Smith Input Parameter: 351b4319ba4SBarry Smith . mat - the matrix 352b4319ba4SBarry Smith 353b4319ba4SBarry Smith Output Parameter: 354b4319ba4SBarry Smith . local - the local matrix usually MATSEQAIJ 355b4319ba4SBarry Smith 356b4319ba4SBarry Smith Level: advanced 357b4319ba4SBarry Smith 358b4319ba4SBarry Smith Notes: 359b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 360b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 361b4319ba4SBarry Smith of the MatSetValues() operation. 362b4319ba4SBarry Smith 363b4319ba4SBarry Smith .seealso: MATIS 364b4319ba4SBarry Smith @*/ 365be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatISGetLocalMat(Mat mat,Mat *local) 366b4319ba4SBarry Smith { 3674ac538c5SBarry Smith PetscErrorCode ierr; 368b4319ba4SBarry Smith 369b4319ba4SBarry Smith PetscFunctionBegin; 3700700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 371b4319ba4SBarry Smith PetscValidPointer(local,2); 3724ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat *),(mat,local));CHKERRQ(ierr); 373b4319ba4SBarry Smith PetscFunctionReturn(0); 374b4319ba4SBarry Smith } 375b4319ba4SBarry Smith 3766726f965SBarry Smith #undef __FUNCT__ 3776726f965SBarry Smith #define __FUNCT__ "MatZeroEntries_IS" 3786726f965SBarry Smith PetscErrorCode MatZeroEntries_IS(Mat A) 3796726f965SBarry Smith { 3806726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 3816726f965SBarry Smith PetscErrorCode ierr; 3826726f965SBarry Smith 3836726f965SBarry Smith PetscFunctionBegin; 3846726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 3856726f965SBarry Smith PetscFunctionReturn(0); 3866726f965SBarry Smith } 3876726f965SBarry Smith 3886726f965SBarry Smith #undef __FUNCT__ 3892e74eeadSLisandro Dalcin #define __FUNCT__ "MatScale_IS" 3902e74eeadSLisandro Dalcin PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 3912e74eeadSLisandro Dalcin { 3922e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 3932e74eeadSLisandro Dalcin PetscErrorCode ierr; 3942e74eeadSLisandro Dalcin 3952e74eeadSLisandro Dalcin PetscFunctionBegin; 3962e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 3972e74eeadSLisandro Dalcin PetscFunctionReturn(0); 3982e74eeadSLisandro Dalcin } 3992e74eeadSLisandro Dalcin 4002e74eeadSLisandro Dalcin #undef __FUNCT__ 4012e74eeadSLisandro Dalcin #define __FUNCT__ "MatGetDiagonal_IS" 4022e74eeadSLisandro Dalcin PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 4032e74eeadSLisandro Dalcin { 4042e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 4052e74eeadSLisandro Dalcin PetscErrorCode ierr; 4062e74eeadSLisandro Dalcin 4072e74eeadSLisandro Dalcin PetscFunctionBegin; 4082e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 4092e74eeadSLisandro Dalcin ierr = MatGetDiagonal(is->A,is->x);CHKERRQ(ierr); 4102e74eeadSLisandro Dalcin 4112e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 4122e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 413ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,is->x,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 414ca9f406cSSatish Balay ierr = VecScatterEnd (is->ctx,is->x,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4152e74eeadSLisandro Dalcin PetscFunctionReturn(0); 4162e74eeadSLisandro Dalcin } 4172e74eeadSLisandro Dalcin 4182e74eeadSLisandro Dalcin #undef __FUNCT__ 4196726f965SBarry Smith #define __FUNCT__ "MatSetOption_IS" 420ace3abfcSBarry Smith PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 4216726f965SBarry Smith { 4226726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 4236726f965SBarry Smith PetscErrorCode ierr; 4246726f965SBarry Smith 4256726f965SBarry Smith PetscFunctionBegin; 4264e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 4276726f965SBarry Smith PetscFunctionReturn(0); 4286726f965SBarry Smith } 4296726f965SBarry Smith 430284134d9SBarry Smith #undef __FUNCT__ 431284134d9SBarry Smith #define __FUNCT__ "MatCreateIS" 432284134d9SBarry Smith /*@ 433284134d9SBarry Smith MatCreateIS - Creates a "process" unassmembled matrix, it is assembled on each 434284134d9SBarry Smith process but not across processes. 435284134d9SBarry Smith 436284134d9SBarry Smith Input Parameters: 437284134d9SBarry Smith + comm - MPI communicator that will share the matrix 438284134d9SBarry Smith . m,n,M,N - local and/or global sizes of the the left and right vector used in matrix vector products 439284134d9SBarry Smith - map - mapping that defines the global number for each local number 440284134d9SBarry Smith 441284134d9SBarry Smith Output Parameter: 442284134d9SBarry Smith . A - the resulting matrix 443284134d9SBarry Smith 4448e6c10adSSatish Balay Level: advanced 4458e6c10adSSatish Balay 446284134d9SBarry Smith Notes: See MATIS for more details 4478cda6cd7SBarry Smith m and n are NOT related to the size of the map, they are the size of the part of the vector owned 4488cda6cd7SBarry Smith by that process. m + nghosts (or n + nghosts) is the length of map since map maps all local points 4498cda6cd7SBarry Smith plus the ghost points to global indices. 450284134d9SBarry Smith 451284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 452284134d9SBarry Smith @*/ 453284134d9SBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatCreateIS(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping map,Mat *A) 454284134d9SBarry Smith { 455284134d9SBarry Smith PetscErrorCode ierr; 456284134d9SBarry Smith 457284134d9SBarry Smith PetscFunctionBegin; 458284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 459284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 460284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 461*784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(*A,map,map);CHKERRQ(ierr); 462284134d9SBarry Smith PetscFunctionReturn(0); 463284134d9SBarry Smith } 464284134d9SBarry Smith 465b4319ba4SBarry Smith /*MC 466b4319ba4SBarry Smith MATIS - MATIS = "is" - A matrix type to be used for using the Neumann-Neumann type preconditioners. 467b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 468b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 469b4319ba4SBarry Smith product is handled "implicitly". 470b4319ba4SBarry Smith 471b4319ba4SBarry Smith Operations Provided: 4726726f965SBarry Smith + MatMult() 4732e74eeadSLisandro Dalcin . MatMultAdd() 4742e74eeadSLisandro Dalcin . MatMultTranspose() 4752e74eeadSLisandro Dalcin . MatMultTransposeAdd() 4766726f965SBarry Smith . MatZeroEntries() 4776726f965SBarry Smith . MatSetOption() 4782e74eeadSLisandro Dalcin . MatZeroRows() 4796726f965SBarry Smith . MatZeroRowsLocal() 4802e74eeadSLisandro Dalcin . MatSetValues() 4816726f965SBarry Smith . MatSetValuesLocal() 4822e74eeadSLisandro Dalcin . MatScale() 4832e74eeadSLisandro Dalcin . MatGetDiagonal() 4846726f965SBarry Smith - MatSetLocalToGlobalMapping() 485b4319ba4SBarry Smith 486b4319ba4SBarry Smith Options Database Keys: 487b4319ba4SBarry Smith . -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 488b4319ba4SBarry Smith 489b4319ba4SBarry Smith Notes: Options prefix for the inner matrix are given by -is_mat_xxx 490b4319ba4SBarry Smith 491b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 492b4319ba4SBarry Smith 493b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 494b4319ba4SBarry Smith MatISGetLocalMat() 495b4319ba4SBarry Smith 496b4319ba4SBarry Smith Level: advanced 497b4319ba4SBarry Smith 498b4319ba4SBarry Smith .seealso: PC, MatISGetLocalMat(), MatSetLocalToGlobalMapping() 499b4319ba4SBarry Smith 500b4319ba4SBarry Smith M*/ 501b4319ba4SBarry Smith 502b4319ba4SBarry Smith EXTERN_C_BEGIN 503b4319ba4SBarry Smith #undef __FUNCT__ 504b4319ba4SBarry Smith #define __FUNCT__ "MatCreate_IS" 505be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_IS(Mat A) 506b4319ba4SBarry Smith { 507dfbe8321SBarry Smith PetscErrorCode ierr; 508b4319ba4SBarry Smith Mat_IS *b; 509b4319ba4SBarry Smith 510b4319ba4SBarry Smith PetscFunctionBegin; 51138f2d2fdSLisandro Dalcin ierr = PetscNewLog(A,Mat_IS,&b);CHKERRQ(ierr); 512b4319ba4SBarry Smith A->data = (void*)b; 513b4319ba4SBarry Smith ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 514b4319ba4SBarry Smith 515b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 5162e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 5172e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 5182e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 519b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 520b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 5212e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 522b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 5232e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 524b4319ba4SBarry Smith A->ops->zerorowslocal = MatZeroRowsLocal_IS; 525b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 526b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 527b4319ba4SBarry Smith A->ops->view = MatView_IS; 5286726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 5292e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 5302e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 5316726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 532b4319ba4SBarry Smith 53326283091SBarry Smith ierr = PetscLayoutSetBlockSize(A->rmap,1);CHKERRQ(ierr); 53426283091SBarry Smith ierr = PetscLayoutSetBlockSize(A->cmap,1);CHKERRQ(ierr); 53526283091SBarry Smith ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 53626283091SBarry Smith ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 537b4319ba4SBarry Smith 538b4319ba4SBarry Smith b->A = 0; 539b4319ba4SBarry Smith b->ctx = 0; 540b4319ba4SBarry Smith b->x = 0; 541b4319ba4SBarry Smith b->y = 0; 542b4319ba4SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatISGetLocalMat_C","MatISGetLocalMat_IS",MatISGetLocalMat_IS);CHKERRQ(ierr); 54317667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 544b4319ba4SBarry Smith 545b4319ba4SBarry Smith PetscFunctionReturn(0); 546b4319ba4SBarry Smith } 547b4319ba4SBarry Smith EXTERN_C_END 548