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*/ 16afcb2eb5SJed Brown #include <petsc-private/isimpl.h> 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; 266bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 276bf464f9SBarry Smith ierr = VecScatterDestroy(&b->ctx);CHKERRQ(ierr); 286bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 296bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 306bf464f9SBarry Smith ierr = ISLocalToGlobalMappingDestroy(&b->mapping);CHKERRQ(ierr); 31bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 32dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 330298fd71SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C","",NULL);CHKERRQ(ierr); 34b4319ba4SBarry Smith PetscFunctionReturn(0); 35b4319ba4SBarry Smith } 36b4319ba4SBarry Smith 37b4319ba4SBarry Smith #undef __FUNCT__ 38b4319ba4SBarry Smith #define __FUNCT__ "MatMult_IS" 39dfbe8321SBarry Smith PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 40b4319ba4SBarry Smith { 41dfbe8321SBarry Smith PetscErrorCode ierr; 42b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 43b4319ba4SBarry Smith PetscScalar zero = 0.0; 44b4319ba4SBarry Smith 45b4319ba4SBarry Smith PetscFunctionBegin; 46b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 47ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 48ca9f406cSSatish Balay ierr = VecScatterEnd(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 49b4319ba4SBarry Smith 50b4319ba4SBarry Smith /* multiply the local matrix */ 51b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 52b4319ba4SBarry Smith 53b4319ba4SBarry Smith /* scatter product back into global memory */ 542dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 55ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 56ca9f406cSSatish Balay ierr = VecScatterEnd(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 57b4319ba4SBarry Smith PetscFunctionReturn(0); 58b4319ba4SBarry Smith } 59b4319ba4SBarry Smith 60b4319ba4SBarry Smith #undef __FUNCT__ 612e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultAdd_IS" 622e74eeadSLisandro Dalcin static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 632e74eeadSLisandro Dalcin { 64650997f4SStefano Zampini Vec temp_vec; 652e74eeadSLisandro Dalcin PetscErrorCode ierr; 662e74eeadSLisandro Dalcin 672e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 68650997f4SStefano Zampini if (v3 != v2) { 69650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 70650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 71650997f4SStefano Zampini } else { 72650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 73650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 74650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 75650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 76650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 77650997f4SStefano Zampini } 782e74eeadSLisandro Dalcin PetscFunctionReturn(0); 792e74eeadSLisandro Dalcin } 802e74eeadSLisandro Dalcin 812e74eeadSLisandro Dalcin #undef __FUNCT__ 822e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTranspose_IS" 832e74eeadSLisandro Dalcin PetscErrorCode MatMultTranspose_IS(Mat A,Vec x,Vec y) 842e74eeadSLisandro Dalcin { 852e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 862e74eeadSLisandro Dalcin PetscErrorCode ierr; 872e74eeadSLisandro Dalcin 882e74eeadSLisandro Dalcin PetscFunctionBegin; /* y = A' * x */ 892e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 90ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 91ca9f406cSSatish Balay ierr = VecScatterEnd(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 922e74eeadSLisandro Dalcin 932e74eeadSLisandro Dalcin /* multiply the local matrix */ 942e74eeadSLisandro Dalcin ierr = MatMultTranspose(is->A,is->x,is->y);CHKERRQ(ierr); 952e74eeadSLisandro Dalcin 962e74eeadSLisandro Dalcin /* scatter product back into global vector */ 972e74eeadSLisandro Dalcin ierr = VecSet(y,0);CHKERRQ(ierr); 98ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 99ca9f406cSSatish Balay ierr = VecScatterEnd(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1002e74eeadSLisandro Dalcin PetscFunctionReturn(0); 1012e74eeadSLisandro Dalcin } 1022e74eeadSLisandro Dalcin 1032e74eeadSLisandro Dalcin #undef __FUNCT__ 1042e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTransposeAdd_IS" 1052e74eeadSLisandro Dalcin PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 1062e74eeadSLisandro Dalcin { 107650997f4SStefano Zampini Vec temp_vec; 1082e74eeadSLisandro Dalcin PetscErrorCode ierr; 1092e74eeadSLisandro Dalcin 1102e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 111650997f4SStefano Zampini if (v3 != v2) { 112650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 113650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 114650997f4SStefano Zampini } else { 115650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 116650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 117650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 118650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 119650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 120650997f4SStefano Zampini } 1212e74eeadSLisandro Dalcin PetscFunctionReturn(0); 1222e74eeadSLisandro Dalcin } 1232e74eeadSLisandro Dalcin 1242e74eeadSLisandro Dalcin #undef __FUNCT__ 125b4319ba4SBarry Smith #define __FUNCT__ "MatView_IS" 126dfbe8321SBarry Smith PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 127b4319ba4SBarry Smith { 128b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 129dfbe8321SBarry Smith PetscErrorCode ierr; 130b4319ba4SBarry Smith PetscViewer sviewer; 131b4319ba4SBarry Smith 132b4319ba4SBarry Smith PetscFunctionBegin; 133b4319ba4SBarry Smith ierr = PetscViewerGetSingleton(viewer,&sviewer);CHKERRQ(ierr); 134b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 135b4319ba4SBarry Smith ierr = PetscViewerRestoreSingleton(viewer,&sviewer);CHKERRQ(ierr); 136b4319ba4SBarry Smith PetscFunctionReturn(0); 137b4319ba4SBarry Smith } 138b4319ba4SBarry Smith 139b4319ba4SBarry Smith #undef __FUNCT__ 140b4319ba4SBarry Smith #define __FUNCT__ "MatSetLocalToGlobalMapping_IS" 141784ac674SJed Brown PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 142b4319ba4SBarry Smith { 143dfbe8321SBarry Smith PetscErrorCode ierr; 1444e4c7dbeSStefano Zampini PetscInt n,bs; 145b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 146b4319ba4SBarry Smith IS from,to; 147b4319ba4SBarry Smith Vec global; 148b4319ba4SBarry Smith 149b4319ba4SBarry Smith PetscFunctionBegin; 150e7e72b3dSBarry Smith if (is->mapping) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix"); 151784ac674SJed Brown PetscCheckSameComm(A,1,rmapping,2); 152*ce94432eSBarry Smith if (rmapping != cmapping) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MATIS requires the row and column mappings to be identical"); 153784ac674SJed Brown ierr = PetscObjectReference((PetscObject)rmapping);CHKERRQ(ierr); 1546bf464f9SBarry Smith ierr = ISLocalToGlobalMappingDestroy(&is->mapping);CHKERRQ(ierr); 155784ac674SJed Brown is->mapping = rmapping; 156b4319ba4SBarry Smith 157b4319ba4SBarry Smith /* Create the local matrix A */ 158784ac674SJed Brown ierr = ISLocalToGlobalMappingGetSize(rmapping,&n);CHKERRQ(ierr); 1594e4c7dbeSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 160f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 161f69a0ea3SMatthew Knepley ierr = MatSetSizes(is->A,n,n,n,n);CHKERRQ(ierr); 1624e4c7dbeSStefano Zampini ierr = MatSetBlockSize(is->A,bs);CHKERRQ(ierr); 163ff130e51SJed Brown ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 164ff130e51SJed Brown ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 165b4319ba4SBarry Smith ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 166b4319ba4SBarry Smith 167b4319ba4SBarry Smith /* Create the local work vectors */ 1684e4c7dbeSStefano Zampini ierr = VecCreate(PETSC_COMM_SELF,&is->x);CHKERRQ(ierr); 1694e4c7dbeSStefano Zampini ierr = VecSetBlockSize(is->x,bs);CHKERRQ(ierr); 1704e4c7dbeSStefano Zampini ierr = VecSetSizes(is->x,n,n);CHKERRQ(ierr); 171ff130e51SJed Brown ierr = VecSetOptionsPrefix(is->x,((PetscObject)A)->prefix);CHKERRQ(ierr); 172ff130e51SJed Brown ierr = VecAppendOptionsPrefix(is->x,"is_");CHKERRQ(ierr); 1734e4c7dbeSStefano Zampini ierr = VecSetFromOptions(is->x);CHKERRQ(ierr); 174b4319ba4SBarry Smith ierr = VecDuplicate(is->x,&is->y);CHKERRQ(ierr); 175b4319ba4SBarry Smith 176b4319ba4SBarry Smith /* setup the global to local scatter */ 177b4319ba4SBarry Smith ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&to);CHKERRQ(ierr); 178784ac674SJed Brown ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); 1790298fd71SBarry Smith ierr = MatGetVecs(A,&global,NULL);CHKERRQ(ierr); 180b4319ba4SBarry Smith ierr = VecScatterCreate(global,from,is->x,to,&is->ctx);CHKERRQ(ierr); 1816bf464f9SBarry Smith ierr = VecDestroy(&global);CHKERRQ(ierr); 1826bf464f9SBarry Smith ierr = ISDestroy(&to);CHKERRQ(ierr); 1836bf464f9SBarry Smith ierr = ISDestroy(&from);CHKERRQ(ierr); 184b4319ba4SBarry Smith PetscFunctionReturn(0); 185b4319ba4SBarry Smith } 186b4319ba4SBarry Smith 1872e74eeadSLisandro Dalcin #define ISG2LMapApply(mapping,n,in,out) 0; \ 1882e74eeadSLisandro Dalcin if (!(mapping)->globals) { \ 1892e74eeadSLisandro Dalcin PetscErrorCode _ierr = ISGlobalToLocalMappingApply((mapping),IS_GTOLM_MASK,0,0,0,0);CHKERRQ(_ierr); \ 1902e74eeadSLisandro Dalcin } \ 1912e74eeadSLisandro Dalcin { \ 1922e74eeadSLisandro Dalcin PetscInt _i,*_globals = (mapping)->globals,_start = (mapping)->globalstart,_end = (mapping)->globalend; \ 1932e74eeadSLisandro Dalcin for (_i=0; _i<n; _i++) { \ 1942e74eeadSLisandro Dalcin if (in[_i] < 0) out[_i] = in[_i]; \ 1952e74eeadSLisandro Dalcin else if (in[_i] < _start) out[_i] = -1; \ 1962e74eeadSLisandro Dalcin else if (in[_i] > _end) out[_i] = -1; \ 1972e74eeadSLisandro Dalcin else out[_i] = _globals[in[_i] - _start]; \ 1982e74eeadSLisandro Dalcin } \ 1992e74eeadSLisandro Dalcin } 2002e74eeadSLisandro Dalcin 2012e74eeadSLisandro Dalcin #undef __FUNCT__ 2022e74eeadSLisandro Dalcin #define __FUNCT__ "MatSetValues_IS" 2032e74eeadSLisandro Dalcin PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 2042e74eeadSLisandro Dalcin { 2052e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 2062e74eeadSLisandro Dalcin PetscInt rows_l[2048],cols_l[2048]; 2072e74eeadSLisandro Dalcin PetscErrorCode ierr; 2082e74eeadSLisandro Dalcin 2092e74eeadSLisandro Dalcin PetscFunctionBegin; 2102e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 211f23aa3ddSBarry 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); 2122e74eeadSLisandro Dalcin #endif 2132e74eeadSLisandro Dalcin ierr = ISG2LMapApply(is->mapping,m,rows,rows_l);CHKERRQ(ierr); 2142e74eeadSLisandro Dalcin ierr = ISG2LMapApply(is->mapping,n,cols,cols_l);CHKERRQ(ierr); 2152e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 2162e74eeadSLisandro Dalcin PetscFunctionReturn(0); 2172e74eeadSLisandro Dalcin } 2182e74eeadSLisandro Dalcin 2192e74eeadSLisandro Dalcin #undef ISG2LMapSetUp 2202e74eeadSLisandro Dalcin #undef ISG2LMapApply 221b4319ba4SBarry Smith 222b4319ba4SBarry Smith #undef __FUNCT__ 223b4319ba4SBarry Smith #define __FUNCT__ "MatSetValuesLocal_IS" 22413f74950SBarry Smith PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 225b4319ba4SBarry Smith { 226dfbe8321SBarry Smith PetscErrorCode ierr; 227b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 228b4319ba4SBarry Smith 229b4319ba4SBarry Smith PetscFunctionBegin; 230b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 231b4319ba4SBarry Smith PetscFunctionReturn(0); 232b4319ba4SBarry Smith } 233b4319ba4SBarry Smith 234b4319ba4SBarry Smith #undef __FUNCT__ 2352e74eeadSLisandro Dalcin #define __FUNCT__ "MatZeroRows_IS" 2362b40b63fSBarry Smith PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2372e74eeadSLisandro Dalcin { 2382e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 2390298fd71SBarry Smith PetscInt n_l = 0, *rows_l = NULL; 2402e74eeadSLisandro Dalcin PetscErrorCode ierr; 2412e74eeadSLisandro Dalcin 2422e74eeadSLisandro Dalcin PetscFunctionBegin; 243*ce94432eSBarry Smith if (x && b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support"); 2442e74eeadSLisandro Dalcin if (n) { 2452e74eeadSLisandro Dalcin ierr = PetscMalloc(n*sizeof(PetscInt),&rows_l);CHKERRQ(ierr); 2462e74eeadSLisandro Dalcin ierr = ISGlobalToLocalMappingApply(is->mapping,IS_GTOLM_DROP,n,rows,&n_l,rows_l);CHKERRQ(ierr); 2472e74eeadSLisandro Dalcin } 2482b40b63fSBarry Smith ierr = MatZeroRowsLocal(A,n_l,rows_l,diag,x,b);CHKERRQ(ierr); 249c31cb41cSBarry Smith ierr = PetscFree(rows_l);CHKERRQ(ierr); 2502e74eeadSLisandro Dalcin PetscFunctionReturn(0); 2512e74eeadSLisandro Dalcin } 2522e74eeadSLisandro Dalcin 2532e74eeadSLisandro Dalcin #undef __FUNCT__ 254b4319ba4SBarry Smith #define __FUNCT__ "MatZeroRowsLocal_IS" 2552b40b63fSBarry Smith PetscErrorCode MatZeroRowsLocal_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 256b4319ba4SBarry Smith { 257b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 258dfbe8321SBarry Smith PetscErrorCode ierr; 259f4df32b1SMatthew Knepley PetscInt i; 260b4319ba4SBarry Smith PetscScalar *array; 261b4319ba4SBarry Smith 262b4319ba4SBarry Smith PetscFunctionBegin; 263*ce94432eSBarry Smith if (x && b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support"); 264b4319ba4SBarry Smith { 265b4319ba4SBarry Smith /* 266b4319ba4SBarry Smith Set up is->x as a "counting vector". This is in order to MatMult_IS 267b4319ba4SBarry Smith work properly in the interface nodes. 268b4319ba4SBarry Smith */ 269b4319ba4SBarry Smith Vec counter; 270b4319ba4SBarry Smith PetscScalar one=1.0, zero=0.0; 2710298fd71SBarry Smith ierr = MatGetVecs(A,&counter,NULL);CHKERRQ(ierr); 2722dcb1b2aSMatthew Knepley ierr = VecSet(counter,zero);CHKERRQ(ierr); 2732dcb1b2aSMatthew Knepley ierr = VecSet(is->x,one);CHKERRQ(ierr); 274ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,is->x,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 275ca9f406cSSatish Balay ierr = VecScatterEnd (is->ctx,is->x,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 276ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,counter,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 277ca9f406cSSatish Balay ierr = VecScatterEnd (is->ctx,counter,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2786bf464f9SBarry Smith ierr = VecDestroy(&counter);CHKERRQ(ierr); 279b4319ba4SBarry Smith } 280958c9bccSBarry Smith if (!n) { 281b4319ba4SBarry Smith is->pure_neumann = PETSC_TRUE; 282b4319ba4SBarry Smith } else { 283b4319ba4SBarry Smith is->pure_neumann = PETSC_FALSE; 2842205254eSKarl Rupp 285b4319ba4SBarry Smith ierr = VecGetArray(is->x,&array);CHKERRQ(ierr); 2862b40b63fSBarry Smith ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 287b4319ba4SBarry Smith for (i=0; i<n; i++) { 288f4df32b1SMatthew Knepley ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 289b4319ba4SBarry Smith } 290b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 291b4319ba4SBarry Smith ierr = MatAssemblyEnd (is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 292b4319ba4SBarry Smith ierr = VecRestoreArray(is->x,&array);CHKERRQ(ierr); 293b4319ba4SBarry Smith } 294b4319ba4SBarry Smith PetscFunctionReturn(0); 295b4319ba4SBarry Smith } 296b4319ba4SBarry Smith 297b4319ba4SBarry Smith #undef __FUNCT__ 298b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyBegin_IS" 299dfbe8321SBarry Smith PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 300b4319ba4SBarry Smith { 301b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 302dfbe8321SBarry Smith PetscErrorCode ierr; 303b4319ba4SBarry Smith 304b4319ba4SBarry Smith PetscFunctionBegin; 305b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 306b4319ba4SBarry Smith PetscFunctionReturn(0); 307b4319ba4SBarry Smith } 308b4319ba4SBarry Smith 309b4319ba4SBarry Smith #undef __FUNCT__ 310b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyEnd_IS" 311dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 312b4319ba4SBarry Smith { 313b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 314dfbe8321SBarry Smith PetscErrorCode ierr; 315b4319ba4SBarry Smith 316b4319ba4SBarry Smith PetscFunctionBegin; 317b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 318b4319ba4SBarry Smith PetscFunctionReturn(0); 319b4319ba4SBarry Smith } 320b4319ba4SBarry Smith 321b4319ba4SBarry Smith EXTERN_C_BEGIN 322b4319ba4SBarry Smith #undef __FUNCT__ 323b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat_IS" 3247087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 325b4319ba4SBarry Smith { 326b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 327b4319ba4SBarry Smith 328b4319ba4SBarry Smith PetscFunctionBegin; 329b4319ba4SBarry Smith *local = is->A; 330b4319ba4SBarry Smith PetscFunctionReturn(0); 331b4319ba4SBarry Smith } 332b4319ba4SBarry Smith EXTERN_C_END 333b4319ba4SBarry Smith 334b4319ba4SBarry Smith #undef __FUNCT__ 335b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat" 336b4319ba4SBarry Smith /*@ 337b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 338b4319ba4SBarry Smith 339b4319ba4SBarry Smith Input Parameter: 340b4319ba4SBarry Smith . mat - the matrix 341b4319ba4SBarry Smith 342b4319ba4SBarry Smith Output Parameter: 343b4319ba4SBarry Smith . local - the local matrix usually MATSEQAIJ 344b4319ba4SBarry Smith 345b4319ba4SBarry Smith Level: advanced 346b4319ba4SBarry Smith 347b4319ba4SBarry Smith Notes: 348b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 349b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 350b4319ba4SBarry Smith of the MatSetValues() operation. 351b4319ba4SBarry Smith 352b4319ba4SBarry Smith .seealso: MATIS 353b4319ba4SBarry Smith @*/ 3547087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 355b4319ba4SBarry Smith { 3564ac538c5SBarry Smith PetscErrorCode ierr; 357b4319ba4SBarry Smith 358b4319ba4SBarry Smith PetscFunctionBegin; 3590700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 360b4319ba4SBarry Smith PetscValidPointer(local,2); 3614ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 362b4319ba4SBarry Smith PetscFunctionReturn(0); 363b4319ba4SBarry Smith } 364b4319ba4SBarry Smith 3653b03a366Sstefano_zampini EXTERN_C_BEGIN 3663b03a366Sstefano_zampini #undef __FUNCT__ 3673b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat_IS" 3683b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 3693b03a366Sstefano_zampini { 3703b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 3713b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 3723b03a366Sstefano_zampini PetscErrorCode ierr; 3733b03a366Sstefano_zampini 3743b03a366Sstefano_zampini PetscFunctionBegin; 3754e4c7dbeSStefano Zampini if (is->A) { 3763b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 3773b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 378f23aa3ddSBarry 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); 3794e4c7dbeSStefano Zampini } 3803b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 3813b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 3823b03a366Sstefano_zampini is->A = local; 3833b03a366Sstefano_zampini PetscFunctionReturn(0); 3843b03a366Sstefano_zampini } 3853b03a366Sstefano_zampini EXTERN_C_END 3863b03a366Sstefano_zampini 3873b03a366Sstefano_zampini #undef __FUNCT__ 3883b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat" 3893b03a366Sstefano_zampini /*@ 3903b03a366Sstefano_zampini MatISSetLocalMat - Set the local matrix stored inside a MATIS matrix. 3913b03a366Sstefano_zampini 3923b03a366Sstefano_zampini Input Parameter: 3933b03a366Sstefano_zampini . mat - the matrix 3943b03a366Sstefano_zampini . local - the local matrix usually MATSEQAIJ 3953b03a366Sstefano_zampini 3963b03a366Sstefano_zampini Output Parameter: 3973b03a366Sstefano_zampini 3983b03a366Sstefano_zampini Level: advanced 3993b03a366Sstefano_zampini 4003b03a366Sstefano_zampini Notes: 4013b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 4023b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 4033b03a366Sstefano_zampini 4043b03a366Sstefano_zampini .seealso: MATIS 4053b03a366Sstefano_zampini @*/ 4063b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 4073b03a366Sstefano_zampini { 4083b03a366Sstefano_zampini PetscErrorCode ierr; 4093b03a366Sstefano_zampini 4103b03a366Sstefano_zampini PetscFunctionBegin; 4113b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4123b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 4133b03a366Sstefano_zampini PetscFunctionReturn(0); 4143b03a366Sstefano_zampini } 4153b03a366Sstefano_zampini 4166726f965SBarry Smith #undef __FUNCT__ 4176726f965SBarry Smith #define __FUNCT__ "MatZeroEntries_IS" 4186726f965SBarry Smith PetscErrorCode MatZeroEntries_IS(Mat A) 4196726f965SBarry Smith { 4206726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 4216726f965SBarry Smith PetscErrorCode ierr; 4226726f965SBarry Smith 4236726f965SBarry Smith PetscFunctionBegin; 4246726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 4256726f965SBarry Smith PetscFunctionReturn(0); 4266726f965SBarry Smith } 4276726f965SBarry Smith 4286726f965SBarry Smith #undef __FUNCT__ 4292e74eeadSLisandro Dalcin #define __FUNCT__ "MatScale_IS" 4302e74eeadSLisandro Dalcin PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 4312e74eeadSLisandro Dalcin { 4322e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 4332e74eeadSLisandro Dalcin PetscErrorCode ierr; 4342e74eeadSLisandro Dalcin 4352e74eeadSLisandro Dalcin PetscFunctionBegin; 4362e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 4372e74eeadSLisandro Dalcin PetscFunctionReturn(0); 4382e74eeadSLisandro Dalcin } 4392e74eeadSLisandro Dalcin 4402e74eeadSLisandro Dalcin #undef __FUNCT__ 4412e74eeadSLisandro Dalcin #define __FUNCT__ "MatGetDiagonal_IS" 4422e74eeadSLisandro Dalcin PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 4432e74eeadSLisandro Dalcin { 4442e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 4452e74eeadSLisandro Dalcin PetscErrorCode ierr; 4462e74eeadSLisandro Dalcin 4472e74eeadSLisandro Dalcin PetscFunctionBegin; 4482e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 4492e74eeadSLisandro Dalcin ierr = MatGetDiagonal(is->A,is->x);CHKERRQ(ierr); 4502e74eeadSLisandro Dalcin 4512e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 4522e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 453ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,is->x,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 454ca9f406cSSatish Balay ierr = VecScatterEnd (is->ctx,is->x,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4552e74eeadSLisandro Dalcin PetscFunctionReturn(0); 4562e74eeadSLisandro Dalcin } 4572e74eeadSLisandro Dalcin 4582e74eeadSLisandro Dalcin #undef __FUNCT__ 4596726f965SBarry Smith #define __FUNCT__ "MatSetOption_IS" 460ace3abfcSBarry Smith PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 4616726f965SBarry Smith { 4626726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 4636726f965SBarry Smith PetscErrorCode ierr; 4646726f965SBarry Smith 4656726f965SBarry Smith PetscFunctionBegin; 4664e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 4676726f965SBarry Smith PetscFunctionReturn(0); 4686726f965SBarry Smith } 4696726f965SBarry Smith 470284134d9SBarry Smith #undef __FUNCT__ 471284134d9SBarry Smith #define __FUNCT__ "MatCreateIS" 472284134d9SBarry Smith /*@ 473284134d9SBarry Smith MatCreateIS - Creates a "process" unassmembled matrix, it is assembled on each 474284134d9SBarry Smith process but not across processes. 475284134d9SBarry Smith 476284134d9SBarry Smith Input Parameters: 477284134d9SBarry Smith + comm - MPI communicator that will share the matrix 4784e4c7dbeSStefano Zampini . bs - local and global block size of the matrix 479284134d9SBarry Smith . m,n,M,N - local and/or global sizes of the the left and right vector used in matrix vector products 480284134d9SBarry Smith - map - mapping that defines the global number for each local number 481284134d9SBarry Smith 482284134d9SBarry Smith Output Parameter: 483284134d9SBarry Smith . A - the resulting matrix 484284134d9SBarry Smith 4858e6c10adSSatish Balay Level: advanced 4868e6c10adSSatish Balay 487284134d9SBarry Smith Notes: See MATIS for more details 4888cda6cd7SBarry Smith m and n are NOT related to the size of the map, they are the size of the part of the vector owned 4898cda6cd7SBarry Smith by that process. m + nghosts (or n + nghosts) is the length of map since map maps all local points 4908cda6cd7SBarry Smith plus the ghost points to global indices. 491284134d9SBarry Smith 492284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 493284134d9SBarry Smith @*/ 4944e4c7dbeSStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping map,Mat *A) 495284134d9SBarry Smith { 496284134d9SBarry Smith PetscErrorCode ierr; 497284134d9SBarry Smith 498284134d9SBarry Smith PetscFunctionBegin; 499284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 500d3ee2243SStefano Zampini ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 501284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 502284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 5033b03a366Sstefano_zampini ierr = MatSetUp(*A);CHKERRQ(ierr); 504784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(*A,map,map);CHKERRQ(ierr); 505284134d9SBarry Smith PetscFunctionReturn(0); 506284134d9SBarry Smith } 507284134d9SBarry Smith 508b4319ba4SBarry Smith /*MC 509b4319ba4SBarry Smith MATIS - MATIS = "is" - A matrix type to be used for using the Neumann-Neumann type preconditioners. 510b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 511b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 512b4319ba4SBarry Smith product is handled "implicitly". 513b4319ba4SBarry Smith 514b4319ba4SBarry Smith Operations Provided: 5156726f965SBarry Smith + MatMult() 5162e74eeadSLisandro Dalcin . MatMultAdd() 5172e74eeadSLisandro Dalcin . MatMultTranspose() 5182e74eeadSLisandro Dalcin . MatMultTransposeAdd() 5196726f965SBarry Smith . MatZeroEntries() 5206726f965SBarry Smith . MatSetOption() 5212e74eeadSLisandro Dalcin . MatZeroRows() 5226726f965SBarry Smith . MatZeroRowsLocal() 5232e74eeadSLisandro Dalcin . MatSetValues() 5246726f965SBarry Smith . MatSetValuesLocal() 5252e74eeadSLisandro Dalcin . MatScale() 5262e74eeadSLisandro Dalcin . MatGetDiagonal() 5276726f965SBarry Smith - MatSetLocalToGlobalMapping() 528b4319ba4SBarry Smith 529b4319ba4SBarry Smith Options Database Keys: 530b4319ba4SBarry Smith . -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 531b4319ba4SBarry Smith 532b4319ba4SBarry Smith Notes: Options prefix for the inner matrix are given by -is_mat_xxx 533b4319ba4SBarry Smith 534b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 535b4319ba4SBarry Smith 536b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 537b4319ba4SBarry Smith MatISGetLocalMat() 538b4319ba4SBarry Smith 539b4319ba4SBarry Smith Level: advanced 540b4319ba4SBarry Smith 541b4319ba4SBarry Smith .seealso: PC, MatISGetLocalMat(), MatSetLocalToGlobalMapping() 542b4319ba4SBarry Smith 543b4319ba4SBarry Smith M*/ 544b4319ba4SBarry Smith 545b4319ba4SBarry Smith EXTERN_C_BEGIN 546b4319ba4SBarry Smith #undef __FUNCT__ 547b4319ba4SBarry Smith #define __FUNCT__ "MatCreate_IS" 5487087cfbeSBarry Smith PetscErrorCode MatCreate_IS(Mat A) 549b4319ba4SBarry Smith { 550dfbe8321SBarry Smith PetscErrorCode ierr; 551b4319ba4SBarry Smith Mat_IS *b; 552b4319ba4SBarry Smith 553b4319ba4SBarry Smith PetscFunctionBegin; 55438f2d2fdSLisandro Dalcin ierr = PetscNewLog(A,Mat_IS,&b);CHKERRQ(ierr); 555b4319ba4SBarry Smith A->data = (void*)b; 556b4319ba4SBarry Smith ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 557b4319ba4SBarry Smith 558b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 5592e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 5602e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 5612e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 562b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 563b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 5642e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 565b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 5662e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 567b4319ba4SBarry Smith A->ops->zerorowslocal = MatZeroRowsLocal_IS; 568b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 569b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 570b4319ba4SBarry Smith A->ops->view = MatView_IS; 5716726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 5722e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 5732e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 5746726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 575b4319ba4SBarry Smith 57626283091SBarry Smith ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 57726283091SBarry Smith ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 578b4319ba4SBarry Smith 579b4319ba4SBarry Smith b->A = 0; 580b4319ba4SBarry Smith b->ctx = 0; 581b4319ba4SBarry Smith b->x = 0; 582b4319ba4SBarry Smith b->y = 0; 583b4319ba4SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatISGetLocalMat_C","MatISGetLocalMat_IS",MatISGetLocalMat_IS);CHKERRQ(ierr); 5843b03a366Sstefano_zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatISSetLocalMat_C","MatISSetLocalMat_IS",MatISSetLocalMat_IS);CHKERRQ(ierr); 58517667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 586b4319ba4SBarry Smith PetscFunctionReturn(0); 587b4319ba4SBarry Smith } 588b4319ba4SBarry Smith EXTERN_C_END 589