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