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