1 2 /* 3 Creates a matrix class for using the Neumann-Neumann type preconditioners. 4 This stores the matrices in globally unassembled form. Each processor 5 assembles only its local Neumann problem and the parallel matrix vector 6 product is handled "implicitly". 7 8 We provide: 9 MatMult() 10 11 Currently this allows for only one subdomain per processor. 12 13 */ 14 15 #include <../src/mat/impls/is/matis.h> /*I "petscmat.h" I*/ 16 17 #undef __FUNCT__ 18 #define __FUNCT__ "MatDestroy_IS" 19 PetscErrorCode MatDestroy_IS(Mat A) 20 { 21 PetscErrorCode ierr; 22 Mat_IS *b = (Mat_IS*)A->data; 23 24 PetscFunctionBegin; 25 ierr = MatDestroy(&b->A);CHKERRQ(ierr); 26 ierr = VecScatterDestroy(&b->ctx);CHKERRQ(ierr); 27 ierr = VecDestroy(&b->x);CHKERRQ(ierr); 28 ierr = VecDestroy(&b->y);CHKERRQ(ierr); 29 ierr = ISLocalToGlobalMappingDestroy(&b->mapping);CHKERRQ(ierr); 30 ierr = PetscFree(A->data);CHKERRQ(ierr); 31 ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 32 ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C","",PETSC_NULL);CHKERRQ(ierr); 33 PetscFunctionReturn(0); 34 } 35 36 #undef __FUNCT__ 37 #define __FUNCT__ "MatMult_IS" 38 PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 39 { 40 PetscErrorCode ierr; 41 Mat_IS *is = (Mat_IS*)A->data; 42 PetscScalar zero = 0.0; 43 44 PetscFunctionBegin; 45 /* scatter the global vector x into the local work vector */ 46 ierr = VecScatterBegin(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 47 ierr = VecScatterEnd(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 48 49 /* multiply the local matrix */ 50 ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 51 52 /* scatter product back into global memory */ 53 ierr = VecSet(y,zero);CHKERRQ(ierr); 54 ierr = VecScatterBegin(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 55 ierr = VecScatterEnd(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 56 57 PetscFunctionReturn(0); 58 } 59 60 #undef __FUNCT__ 61 #define __FUNCT__ "MatMultAdd_IS" 62 static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 63 { 64 PetscErrorCode ierr; 65 Mat_IS *is = (Mat_IS*)A->data; 66 67 PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 68 /* scatter the global vector v1 into the local work vector */ 69 ierr = VecScatterBegin(is->ctx,v1,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 70 ierr = VecScatterEnd (is->ctx,v1,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 71 ierr = VecScatterBegin(is->ctx,v2,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 72 ierr = VecScatterEnd (is->ctx,v2,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 73 74 /* multiply the local matrix */ 75 ierr = MatMultAdd(is->A,is->x,is->y,is->y);CHKERRQ(ierr); 76 77 /* scatter result back into global vector */ 78 ierr = VecSet(v3,0);CHKERRQ(ierr); 79 ierr = VecScatterBegin(is->ctx,is->y,v3,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 80 ierr = VecScatterEnd (is->ctx,is->y,v3,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 81 PetscFunctionReturn(0); 82 } 83 84 #undef __FUNCT__ 85 #define __FUNCT__ "MatMultTranspose_IS" 86 PetscErrorCode MatMultTranspose_IS(Mat A,Vec x,Vec y) 87 { 88 Mat_IS *is = (Mat_IS*)A->data; 89 PetscErrorCode ierr; 90 91 PetscFunctionBegin; /* y = A' * x */ 92 /* scatter the global vector x into the local work vector */ 93 ierr = VecScatterBegin(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 94 ierr = VecScatterEnd(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 95 96 /* multiply the local matrix */ 97 ierr = MatMultTranspose(is->A,is->x,is->y);CHKERRQ(ierr); 98 99 /* scatter product back into global vector */ 100 ierr = VecSet(y,0);CHKERRQ(ierr); 101 ierr = VecScatterBegin(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 102 ierr = VecScatterEnd(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 103 PetscFunctionReturn(0); 104 } 105 106 #undef __FUNCT__ 107 #define __FUNCT__ "MatMultTransposeAdd_IS" 108 PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 109 { 110 Mat_IS *is = (Mat_IS*)A->data; 111 PetscErrorCode ierr; 112 113 PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 114 /* scatter the global vectors v1 and v2 into the local work vectors */ 115 ierr = VecScatterBegin(is->ctx,v1,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 116 ierr = VecScatterEnd (is->ctx,v1,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 117 ierr = VecScatterBegin(is->ctx,v2,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 118 ierr = VecScatterEnd (is->ctx,v2,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 119 120 /* multiply the local matrix */ 121 ierr = MatMultTransposeAdd(is->A,is->x,is->y,is->y);CHKERRQ(ierr); 122 123 /* scatter result back into global vector */ 124 ierr = VecSet(v3,0);CHKERRQ(ierr); 125 ierr = VecScatterBegin(is->ctx,is->y,v3,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 126 ierr = VecScatterEnd (is->ctx,is->y,v3,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 127 PetscFunctionReturn(0); 128 } 129 130 #undef __FUNCT__ 131 #define __FUNCT__ "MatView_IS" 132 PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 133 { 134 Mat_IS *a = (Mat_IS*)A->data; 135 PetscErrorCode ierr; 136 PetscViewer sviewer; 137 138 PetscFunctionBegin; 139 ierr = PetscViewerGetSingleton(viewer,&sviewer);CHKERRQ(ierr); 140 ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 141 ierr = PetscViewerRestoreSingleton(viewer,&sviewer);CHKERRQ(ierr); 142 PetscFunctionReturn(0); 143 } 144 145 #undef __FUNCT__ 146 #define __FUNCT__ "MatSetLocalToGlobalMapping_IS" 147 PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 148 { 149 PetscErrorCode ierr; 150 PetscInt n,bs; 151 Mat_IS *is = (Mat_IS*)A->data; 152 IS from,to; 153 Vec global; 154 155 PetscFunctionBegin; 156 if (is->mapping) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix"); 157 PetscCheckSameComm(A,1,rmapping,2); 158 if (rmapping != cmapping) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MATIS requires the row and column mappings to be identical"); 159 ierr = PetscObjectReference((PetscObject)rmapping);CHKERRQ(ierr); 160 ierr = ISLocalToGlobalMappingDestroy(&is->mapping);CHKERRQ(ierr); 161 is->mapping = rmapping; 162 163 /* Create the local matrix A */ 164 ierr = ISLocalToGlobalMappingGetSize(rmapping,&n);CHKERRQ(ierr); 165 ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 166 ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 167 ierr = MatSetSizes(is->A,n,n,n,n);CHKERRQ(ierr); 168 ierr = MatSetBlockSize(is->A,bs);CHKERRQ(ierr); 169 ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 170 ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 171 ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 172 173 /* Create the local work vectors */ 174 ierr = VecCreate(PETSC_COMM_SELF,&is->x);CHKERRQ(ierr); 175 ierr = VecSetBlockSize(is->x,bs);CHKERRQ(ierr); 176 ierr = VecSetSizes(is->x,n,n);CHKERRQ(ierr); 177 ierr = VecSetOptionsPrefix(is->x,((PetscObject)A)->prefix);CHKERRQ(ierr); 178 ierr = VecAppendOptionsPrefix(is->x,"is_");CHKERRQ(ierr); 179 ierr = VecSetFromOptions(is->x);CHKERRQ(ierr); 180 ierr = VecDuplicate(is->x,&is->y);CHKERRQ(ierr); 181 182 /* setup the global to local scatter */ 183 ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&to);CHKERRQ(ierr); 184 ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); 185 ierr = MatGetVecs(A,&global,PETSC_NULL);CHKERRQ(ierr); 186 ierr = VecScatterCreate(global,from,is->x,to,&is->ctx);CHKERRQ(ierr); 187 ierr = VecDestroy(&global);CHKERRQ(ierr); 188 ierr = ISDestroy(&to);CHKERRQ(ierr); 189 ierr = ISDestroy(&from);CHKERRQ(ierr); 190 PetscFunctionReturn(0); 191 } 192 193 #define ISG2LMapApply(mapping,n,in,out) 0;\ 194 if (!(mapping)->globals) {\ 195 PetscErrorCode _ierr = ISGlobalToLocalMappingApply((mapping),IS_GTOLM_MASK,0,0,0,0);CHKERRQ(_ierr);\ 196 }\ 197 {\ 198 PetscInt _i,*_globals = (mapping)->globals,_start = (mapping)->globalstart,_end = (mapping)->globalend;\ 199 for (_i=0; _i<n; _i++) {\ 200 if (in[_i] < 0) out[_i] = in[_i];\ 201 else if (in[_i] < _start) out[_i] = -1;\ 202 else if (in[_i] > _end) out[_i] = -1;\ 203 else out[_i] = _globals[in[_i] - _start];\ 204 }\ 205 } 206 207 #undef __FUNCT__ 208 #define __FUNCT__ "MatSetValues_IS" 209 PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 210 { 211 Mat_IS *is = (Mat_IS*)mat->data; 212 PetscInt rows_l[2048],cols_l[2048]; 213 PetscErrorCode ierr; 214 215 PetscFunctionBegin; 216 #if defined(PETSC_USE_DEBUG) 217 if (m > 2048 || n > 2048) { 218 SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Number of row/column indices must be <= 2048: they are %D %D",m,n); 219 } 220 #endif 221 ierr = ISG2LMapApply(is->mapping,m,rows,rows_l);CHKERRQ(ierr); 222 ierr = ISG2LMapApply(is->mapping,n,cols,cols_l);CHKERRQ(ierr); 223 ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 224 PetscFunctionReturn(0); 225 } 226 227 #undef ISG2LMapSetUp 228 #undef ISG2LMapApply 229 230 #undef __FUNCT__ 231 #define __FUNCT__ "MatSetValuesLocal_IS" 232 PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 233 { 234 PetscErrorCode ierr; 235 Mat_IS *is = (Mat_IS*)A->data; 236 237 PetscFunctionBegin; 238 ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 239 PetscFunctionReturn(0); 240 } 241 242 #undef __FUNCT__ 243 #define __FUNCT__ "MatZeroRows_IS" 244 PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 245 { 246 Mat_IS *is = (Mat_IS*)A->data; 247 PetscInt n_l=0, *rows_l = PETSC_NULL; 248 PetscErrorCode ierr; 249 250 PetscFunctionBegin; 251 if (x && b) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"No support"); 252 if (n) { 253 ierr = PetscMalloc(n*sizeof(PetscInt),&rows_l);CHKERRQ(ierr); 254 ierr = ISGlobalToLocalMappingApply(is->mapping,IS_GTOLM_DROP,n,rows,&n_l,rows_l);CHKERRQ(ierr); 255 } 256 ierr = MatZeroRowsLocal(A,n_l,rows_l,diag,x,b);CHKERRQ(ierr); 257 ierr = PetscFree(rows_l);CHKERRQ(ierr); 258 PetscFunctionReturn(0); 259 } 260 261 #undef __FUNCT__ 262 #define __FUNCT__ "MatZeroRowsLocal_IS" 263 PetscErrorCode MatZeroRowsLocal_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 264 { 265 Mat_IS *is = (Mat_IS*)A->data; 266 PetscErrorCode ierr; 267 PetscInt i; 268 PetscScalar *array; 269 270 PetscFunctionBegin; 271 if (x && b) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"No support"); 272 { 273 /* 274 Set up is->x as a "counting vector". This is in order to MatMult_IS 275 work properly in the interface nodes. 276 */ 277 Vec counter; 278 PetscScalar one=1.0, zero=0.0; 279 ierr = MatGetVecs(A,&counter,PETSC_NULL);CHKERRQ(ierr); 280 ierr = VecSet(counter,zero);CHKERRQ(ierr); 281 ierr = VecSet(is->x,one);CHKERRQ(ierr); 282 ierr = VecScatterBegin(is->ctx,is->x,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 283 ierr = VecScatterEnd (is->ctx,is->x,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 284 ierr = VecScatterBegin(is->ctx,counter,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 285 ierr = VecScatterEnd (is->ctx,counter,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 286 ierr = VecDestroy(&counter);CHKERRQ(ierr); 287 } 288 if (!n) { 289 is->pure_neumann = PETSC_TRUE; 290 } else { 291 is->pure_neumann = PETSC_FALSE; 292 ierr = VecGetArray(is->x,&array);CHKERRQ(ierr); 293 ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 294 for (i=0; i<n; i++) { 295 ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 296 } 297 ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 298 ierr = MatAssemblyEnd (is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 299 ierr = VecRestoreArray(is->x,&array);CHKERRQ(ierr); 300 } 301 302 PetscFunctionReturn(0); 303 } 304 305 #undef __FUNCT__ 306 #define __FUNCT__ "MatAssemblyBegin_IS" 307 PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 308 { 309 Mat_IS *is = (Mat_IS*)A->data; 310 PetscErrorCode ierr; 311 312 PetscFunctionBegin; 313 ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 314 PetscFunctionReturn(0); 315 } 316 317 #undef __FUNCT__ 318 #define __FUNCT__ "MatAssemblyEnd_IS" 319 PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 320 { 321 Mat_IS *is = (Mat_IS*)A->data; 322 PetscErrorCode ierr; 323 324 PetscFunctionBegin; 325 ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 326 PetscFunctionReturn(0); 327 } 328 329 EXTERN_C_BEGIN 330 #undef __FUNCT__ 331 #define __FUNCT__ "MatISGetLocalMat_IS" 332 PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 333 { 334 Mat_IS *is = (Mat_IS *)mat->data; 335 336 PetscFunctionBegin; 337 *local = is->A; 338 PetscFunctionReturn(0); 339 } 340 EXTERN_C_END 341 342 #undef __FUNCT__ 343 #define __FUNCT__ "MatISGetLocalMat" 344 /*@ 345 MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 346 347 Input Parameter: 348 . mat - the matrix 349 350 Output Parameter: 351 . local - the local matrix usually MATSEQAIJ 352 353 Level: advanced 354 355 Notes: 356 This can be called if you have precomputed the nonzero structure of the 357 matrix and want to provide it to the inner matrix object to improve the performance 358 of the MatSetValues() operation. 359 360 .seealso: MATIS 361 @*/ 362 PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 363 { 364 PetscErrorCode ierr; 365 366 PetscFunctionBegin; 367 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 368 PetscValidPointer(local,2); 369 ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat *),(mat,local));CHKERRQ(ierr); 370 PetscFunctionReturn(0); 371 } 372 373 EXTERN_C_BEGIN 374 #undef __FUNCT__ 375 #define __FUNCT__ "MatISSetLocalMat_IS" 376 PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 377 { 378 Mat_IS *is = (Mat_IS *)mat->data; 379 PetscInt nrows,ncols,orows,ocols; 380 PetscErrorCode ierr; 381 382 PetscFunctionBegin; 383 if(is->A) { 384 ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 385 ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 386 if(orows != nrows || ocols != ncols ) { 387 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); 388 } 389 } 390 ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 391 ierr = MatDestroy(&is->A);CHKERRQ(ierr); 392 is->A = local; 393 394 PetscFunctionReturn(0); 395 } 396 EXTERN_C_END 397 398 #undef __FUNCT__ 399 #define __FUNCT__ "MatISSetLocalMat" 400 /*@ 401 MatISSetLocalMat - Set the local matrix stored inside a MATIS matrix. 402 403 Input Parameter: 404 . mat - the matrix 405 . local - the local matrix usually MATSEQAIJ 406 407 Output Parameter: 408 409 Level: advanced 410 411 Notes: 412 This can be called if you have precomputed the local matrix and 413 want to provide it to the matrix object MATIS. 414 415 .seealso: MATIS 416 @*/ 417 PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 418 { 419 PetscErrorCode ierr; 420 421 PetscFunctionBegin; 422 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 423 ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 424 PetscFunctionReturn(0); 425 } 426 427 #undef __FUNCT__ 428 #define __FUNCT__ "MatZeroEntries_IS" 429 PetscErrorCode MatZeroEntries_IS(Mat A) 430 { 431 Mat_IS *a = (Mat_IS*)A->data; 432 PetscErrorCode ierr; 433 434 PetscFunctionBegin; 435 ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 436 PetscFunctionReturn(0); 437 } 438 439 #undef __FUNCT__ 440 #define __FUNCT__ "MatScale_IS" 441 PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 442 { 443 Mat_IS *is = (Mat_IS*)A->data; 444 PetscErrorCode ierr; 445 446 PetscFunctionBegin; 447 ierr = MatScale(is->A,a);CHKERRQ(ierr); 448 PetscFunctionReturn(0); 449 } 450 451 #undef __FUNCT__ 452 #define __FUNCT__ "MatGetDiagonal_IS" 453 PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 454 { 455 Mat_IS *is = (Mat_IS*)A->data; 456 PetscErrorCode ierr; 457 458 PetscFunctionBegin; 459 /* get diagonal of the local matrix */ 460 ierr = MatGetDiagonal(is->A,is->x);CHKERRQ(ierr); 461 462 /* scatter diagonal back into global vector */ 463 ierr = VecSet(v,0);CHKERRQ(ierr); 464 ierr = VecScatterBegin(is->ctx,is->x,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 465 ierr = VecScatterEnd (is->ctx,is->x,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 466 PetscFunctionReturn(0); 467 } 468 469 #undef __FUNCT__ 470 #define __FUNCT__ "MatSetOption_IS" 471 PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 472 { 473 Mat_IS *a = (Mat_IS*)A->data; 474 PetscErrorCode ierr; 475 476 PetscFunctionBegin; 477 ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 478 PetscFunctionReturn(0); 479 } 480 481 #undef __FUNCT__ 482 #define __FUNCT__ "MatCreateIS" 483 /*@ 484 MatCreateIS - Creates a "process" unassmembled matrix, it is assembled on each 485 process but not across processes. 486 487 Input Parameters: 488 + comm - MPI communicator that will share the matrix 489 . bs - local and global block size of the matrix 490 . m,n,M,N - local and/or global sizes of the the left and right vector used in matrix vector products 491 - map - mapping that defines the global number for each local number 492 493 Output Parameter: 494 . A - the resulting matrix 495 496 Level: advanced 497 498 Notes: See MATIS for more details 499 m and n are NOT related to the size of the map, they are the size of the part of the vector owned 500 by that process. m + nghosts (or n + nghosts) is the length of map since map maps all local points 501 plus the ghost points to global indices. 502 503 .seealso: MATIS, MatSetLocalToGlobalMapping() 504 @*/ 505 PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping map,Mat *A) 506 { 507 PetscErrorCode ierr; 508 509 PetscFunctionBegin; 510 ierr = MatCreate(comm,A);CHKERRQ(ierr); 511 ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 512 ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 513 ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 514 ierr = MatSetUp(*A);CHKERRQ(ierr); 515 ierr = MatSetLocalToGlobalMapping(*A,map,map);CHKERRQ(ierr); 516 PetscFunctionReturn(0); 517 } 518 519 /*MC 520 MATIS - MATIS = "is" - A matrix type to be used for using the Neumann-Neumann type preconditioners. 521 This stores the matrices in globally unassembled form. Each processor 522 assembles only its local Neumann problem and the parallel matrix vector 523 product is handled "implicitly". 524 525 Operations Provided: 526 + MatMult() 527 . MatMultAdd() 528 . MatMultTranspose() 529 . MatMultTransposeAdd() 530 . MatZeroEntries() 531 . MatSetOption() 532 . MatZeroRows() 533 . MatZeroRowsLocal() 534 . MatSetValues() 535 . MatSetValuesLocal() 536 . MatScale() 537 . MatGetDiagonal() 538 - MatSetLocalToGlobalMapping() 539 540 Options Database Keys: 541 . -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 542 543 Notes: Options prefix for the inner matrix are given by -is_mat_xxx 544 545 You must call MatSetLocalToGlobalMapping() before using this matrix type. 546 547 You can do matrix preallocation on the local matrix after you obtain it with 548 MatISGetLocalMat() 549 550 Level: advanced 551 552 .seealso: PC, MatISGetLocalMat(), MatSetLocalToGlobalMapping() 553 554 M*/ 555 556 EXTERN_C_BEGIN 557 #undef __FUNCT__ 558 #define __FUNCT__ "MatCreate_IS" 559 PetscErrorCode MatCreate_IS(Mat A) 560 { 561 PetscErrorCode ierr; 562 Mat_IS *b; 563 564 PetscFunctionBegin; 565 ierr = PetscNewLog(A,Mat_IS,&b);CHKERRQ(ierr); 566 A->data = (void*)b; 567 ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 568 569 A->ops->mult = MatMult_IS; 570 A->ops->multadd = MatMultAdd_IS; 571 A->ops->multtranspose = MatMultTranspose_IS; 572 A->ops->multtransposeadd = MatMultTransposeAdd_IS; 573 A->ops->destroy = MatDestroy_IS; 574 A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 575 A->ops->setvalues = MatSetValues_IS; 576 A->ops->setvalueslocal = MatSetValuesLocal_IS; 577 A->ops->zerorows = MatZeroRows_IS; 578 A->ops->zerorowslocal = MatZeroRowsLocal_IS; 579 A->ops->assemblybegin = MatAssemblyBegin_IS; 580 A->ops->assemblyend = MatAssemblyEnd_IS; 581 A->ops->view = MatView_IS; 582 A->ops->zeroentries = MatZeroEntries_IS; 583 A->ops->scale = MatScale_IS; 584 A->ops->getdiagonal = MatGetDiagonal_IS; 585 A->ops->setoption = MatSetOption_IS; 586 587 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 588 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 589 590 b->A = 0; 591 b->ctx = 0; 592 b->x = 0; 593 b->y = 0; 594 ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatISGetLocalMat_C","MatISGetLocalMat_IS",MatISGetLocalMat_IS);CHKERRQ(ierr); 595 ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatISSetLocalMat_C","MatISSetLocalMat_IS",MatISSetLocalMat_IS);CHKERRQ(ierr); 596 ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 597 598 PetscFunctionReturn(0); 599 } 600 EXTERN_C_END 601