1 #define PETSCMAT_DLL 2 3 /* 4 Creates a matrix class for using the Neumann-Neumann type preconditioners. 5 This stores the matrices in globally unassembled form. Each processor 6 assembles only its local Neumann problem and the parallel matrix vector 7 product is handled "implicitly". 8 9 We provide: 10 MatMult() 11 12 Currently this allows for only one subdomain per processor. 13 14 */ 15 16 #include "../src/mat/impls/is/matis.h" /*I "petscmat.h" I*/ 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 if (b->A) { 27 ierr = MatDestroy(b->A);CHKERRQ(ierr); 28 } 29 if (b->ctx) { 30 ierr = VecScatterDestroy(b->ctx);CHKERRQ(ierr); 31 } 32 if (b->x) { 33 ierr = VecDestroy(b->x);CHKERRQ(ierr); 34 } 35 if (b->y) { 36 ierr = VecDestroy(b->y);CHKERRQ(ierr); 37 } 38 if (b->mapping) { 39 ierr = ISLocalToGlobalMappingDestroy(b->mapping);CHKERRQ(ierr); 40 } 41 ierr = PetscFree(b);CHKERRQ(ierr); 42 ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 43 ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C","",PETSC_NULL);CHKERRQ(ierr); 44 PetscFunctionReturn(0); 45 } 46 47 #undef __FUNCT__ 48 #define __FUNCT__ "MatMult_IS" 49 PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 50 { 51 PetscErrorCode ierr; 52 Mat_IS *is = (Mat_IS*)A->data; 53 PetscScalar zero = 0.0; 54 55 PetscFunctionBegin; 56 /* scatter the global vector x into the local work vector */ 57 ierr = VecScatterBegin(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 58 ierr = VecScatterEnd(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 59 60 /* multiply the local matrix */ 61 ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 62 63 /* scatter product back into global memory */ 64 ierr = VecSet(y,zero);CHKERRQ(ierr); 65 ierr = VecScatterBegin(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 66 ierr = VecScatterEnd(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 67 68 PetscFunctionReturn(0); 69 } 70 71 #undef __FUNCT__ 72 #define __FUNCT__ "MatMultAdd_IS" 73 static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 74 { 75 PetscErrorCode ierr; 76 Mat_IS *is = (Mat_IS*)A->data; 77 78 PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 79 /* scatter the global vector v1 into the local work vector */ 80 ierr = VecScatterBegin(is->ctx,v1,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 81 ierr = VecScatterEnd (is->ctx,v1,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 82 ierr = VecScatterBegin(is->ctx,v2,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 83 ierr = VecScatterEnd (is->ctx,v2,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 84 85 /* multiply the local matrix */ 86 ierr = MatMultAdd(is->A,is->x,is->y,is->y);CHKERRQ(ierr); 87 88 /* scatter result back into global vector */ 89 ierr = VecSet(v3,0);CHKERRQ(ierr); 90 ierr = VecScatterBegin(is->ctx,is->y,v3,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 91 ierr = VecScatterEnd (is->ctx,is->y,v3,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 92 PetscFunctionReturn(0); 93 } 94 95 #undef __FUNCT__ 96 #define __FUNCT__ "MatMultTranspose_IS" 97 PetscErrorCode MatMultTranspose_IS(Mat A,Vec x,Vec y) 98 { 99 Mat_IS *is = (Mat_IS*)A->data; 100 PetscErrorCode ierr; 101 102 PetscFunctionBegin; /* y = A' * x */ 103 /* scatter the global vector x into the local work vector */ 104 ierr = VecScatterBegin(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 105 ierr = VecScatterEnd(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 106 107 /* multiply the local matrix */ 108 ierr = MatMultTranspose(is->A,is->x,is->y);CHKERRQ(ierr); 109 110 /* scatter product back into global vector */ 111 ierr = VecSet(y,0);CHKERRQ(ierr); 112 ierr = VecScatterBegin(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 113 ierr = VecScatterEnd(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 114 PetscFunctionReturn(0); 115 } 116 117 #undef __FUNCT__ 118 #define __FUNCT__ "MatMultTransposeAdd_IS" 119 PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 120 { 121 Mat_IS *is = (Mat_IS*)A->data; 122 PetscErrorCode ierr; 123 124 PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 125 /* scatter the global vectors v1 and v2 into the local work vectors */ 126 ierr = VecScatterBegin(is->ctx,v1,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 127 ierr = VecScatterEnd (is->ctx,v1,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 128 ierr = VecScatterBegin(is->ctx,v2,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 129 ierr = VecScatterEnd (is->ctx,v2,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 130 131 /* multiply the local matrix */ 132 ierr = MatMultTransposeAdd(is->A,is->x,is->y,is->y);CHKERRQ(ierr); 133 134 /* scatter result back into global vector */ 135 ierr = VecSet(v3,0);CHKERRQ(ierr); 136 ierr = VecScatterBegin(is->ctx,is->y,v3,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 137 ierr = VecScatterEnd (is->ctx,is->y,v3,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 138 PetscFunctionReturn(0); 139 } 140 141 #undef __FUNCT__ 142 #define __FUNCT__ "MatView_IS" 143 PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 144 { 145 Mat_IS *a = (Mat_IS*)A->data; 146 PetscErrorCode ierr; 147 PetscViewer sviewer; 148 149 PetscFunctionBegin; 150 ierr = PetscViewerGetSingleton(viewer,&sviewer);CHKERRQ(ierr); 151 ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 152 ierr = PetscViewerRestoreSingleton(viewer,&sviewer);CHKERRQ(ierr); 153 PetscFunctionReturn(0); 154 } 155 156 #undef __FUNCT__ 157 #define __FUNCT__ "MatSetLocalToGlobalMapping_IS" 158 PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping mapping) 159 { 160 PetscErrorCode ierr; 161 PetscInt n; 162 Mat_IS *is = (Mat_IS*)A->data; 163 IS from,to; 164 Vec global; 165 166 PetscFunctionBegin; 167 if (is->mapping) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix"); 168 PetscCheckSameComm(A,1,mapping,2); 169 ierr = PetscObjectReference((PetscObject)mapping);CHKERRQ(ierr); 170 if (is->mapping) { ierr = ISLocalToGlobalMappingDestroy(is->mapping);CHKERRQ(ierr); } 171 is->mapping = mapping; 172 173 /* Create the local matrix A */ 174 ierr = ISLocalToGlobalMappingGetSize(mapping,&n);CHKERRQ(ierr); 175 ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 176 ierr = MatSetSizes(is->A,n,n,n,n);CHKERRQ(ierr); 177 ierr = MatSetOptionsPrefix(is->A,"is");CHKERRQ(ierr); 178 ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 179 180 /* Create the local work vectors */ 181 ierr = VecCreateSeq(PETSC_COMM_SELF,n,&is->x);CHKERRQ(ierr); 182 ierr = VecDuplicate(is->x,&is->y);CHKERRQ(ierr); 183 184 /* setup the global to local scatter */ 185 ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&to);CHKERRQ(ierr); 186 ierr = ISLocalToGlobalMappingApplyIS(mapping,to,&from);CHKERRQ(ierr); 187 ierr = VecCreateMPIWithArray(((PetscObject)A)->comm,A->cmap->n,A->cmap->N,PETSC_NULL,&global);CHKERRQ(ierr); 188 ierr = VecScatterCreate(global,from,is->x,to,&is->ctx);CHKERRQ(ierr); 189 ierr = VecDestroy(global);CHKERRQ(ierr); 190 ierr = ISDestroy(to);CHKERRQ(ierr); 191 ierr = ISDestroy(from);CHKERRQ(ierr); 192 PetscFunctionReturn(0); 193 } 194 195 #define ISG2LMapApply(mapping,n,in,out) 0;\ 196 if (!(mapping)->globals) {\ 197 PetscErrorCode _ierr = ISGlobalToLocalMappingApply((mapping),IS_GTOLM_MASK,0,0,0,0);CHKERRQ(_ierr);\ 198 }\ 199 {\ 200 PetscInt _i,*_globals = (mapping)->globals,_start = (mapping)->globalstart,_end = (mapping)->globalend;\ 201 for (_i=0; _i<n; _i++) {\ 202 if (in[_i] < 0) out[_i] = in[_i];\ 203 else if (in[_i] < _start) out[_i] = -1;\ 204 else if (in[_i] > _end) out[_i] = -1;\ 205 else out[_i] = _globals[in[_i] - _start];\ 206 }\ 207 } 208 209 #undef __FUNCT__ 210 #define __FUNCT__ "MatSetValues_IS" 211 PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 212 { 213 Mat_IS *is = (Mat_IS*)mat->data; 214 PetscInt rows_l[2048],cols_l[2048]; 215 PetscErrorCode ierr; 216 217 PetscFunctionBegin; 218 #if defined(PETSC_USE_DEBUG) 219 if (m > 2048 || n > 2048) { 220 SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Number of row/column indices must be <= 2048: they are %D %D",m,n); 221 } 222 #endif 223 ierr = ISG2LMapApply(is->mapping,m,rows,rows_l);CHKERRQ(ierr); 224 ierr = ISG2LMapApply(is->mapping,n,cols,cols_l);CHKERRQ(ierr); 225 ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 226 PetscFunctionReturn(0); 227 } 228 229 #undef ISG2LMapSetUp 230 #undef ISG2LMapApply 231 232 #undef __FUNCT__ 233 #define __FUNCT__ "MatSetValuesLocal_IS" 234 PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 235 { 236 PetscErrorCode ierr; 237 Mat_IS *is = (Mat_IS*)A->data; 238 239 PetscFunctionBegin; 240 ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 241 PetscFunctionReturn(0); 242 } 243 244 #undef __FUNCT__ 245 #define __FUNCT__ "MatZeroRows_IS" 246 PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag) 247 { 248 Mat_IS *is = (Mat_IS*)A->data; 249 PetscInt n_l=0, *rows_l = PETSC_NULL; 250 PetscErrorCode ierr; 251 252 PetscFunctionBegin; 253 if (n) { 254 ierr = PetscMalloc(n*sizeof(PetscInt),&rows_l);CHKERRQ(ierr); 255 ierr = ISGlobalToLocalMappingApply(is->mapping,IS_GTOLM_DROP,n,rows,&n_l,rows_l);CHKERRQ(ierr); 256 } 257 ierr = MatZeroRowsLocal(A,n_l,rows_l,diag);CHKERRQ(ierr); 258 if (rows_l) { ierr = PetscFree(rows_l);CHKERRQ(ierr); } 259 PetscFunctionReturn(0); 260 } 261 262 #undef __FUNCT__ 263 #define __FUNCT__ "MatZeroRowsLocal_IS" 264 PetscErrorCode MatZeroRowsLocal_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag) 265 { 266 Mat_IS *is = (Mat_IS*)A->data; 267 PetscErrorCode ierr; 268 PetscInt i; 269 PetscScalar *array; 270 271 PetscFunctionBegin; 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 = VecCreateMPI(((PetscObject)A)->comm,A->cmap->n,A->cmap->N,&counter);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);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 PETSCMAT_DLLEXPORT 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 PETSCMAT_DLLEXPORT MatISGetLocalMat(Mat mat,Mat *local) 363 { 364 PetscErrorCode ierr,(*f)(Mat,Mat *); 365 366 PetscFunctionBegin; 367 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 368 PetscValidPointer(local,2); 369 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatISGetLocalMat_C",(void (**)(void))&f);CHKERRQ(ierr); 370 if (f) { 371 ierr = (*f)(mat,local);CHKERRQ(ierr); 372 } else { 373 local = 0; 374 } 375 PetscFunctionReturn(0); 376 } 377 378 #undef __FUNCT__ 379 #define __FUNCT__ "MatZeroEntries_IS" 380 PetscErrorCode MatZeroEntries_IS(Mat A) 381 { 382 Mat_IS *a = (Mat_IS*)A->data; 383 PetscErrorCode ierr; 384 385 PetscFunctionBegin; 386 ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 387 PetscFunctionReturn(0); 388 } 389 390 #undef __FUNCT__ 391 #define __FUNCT__ "MatScale_IS" 392 PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 393 { 394 Mat_IS *is = (Mat_IS*)A->data; 395 PetscErrorCode ierr; 396 397 PetscFunctionBegin; 398 ierr = MatScale(is->A,a);CHKERRQ(ierr); 399 PetscFunctionReturn(0); 400 } 401 402 #undef __FUNCT__ 403 #define __FUNCT__ "MatGetDiagonal_IS" 404 PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 405 { 406 Mat_IS *is = (Mat_IS*)A->data; 407 PetscErrorCode ierr; 408 409 PetscFunctionBegin; 410 /* get diagonal of the local matrix */ 411 ierr = MatGetDiagonal(is->A,is->x);CHKERRQ(ierr); 412 413 /* scatter diagonal back into global vector */ 414 ierr = VecSet(v,0);CHKERRQ(ierr); 415 ierr = VecScatterBegin(is->ctx,is->x,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 416 ierr = VecScatterEnd (is->ctx,is->x,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 417 PetscFunctionReturn(0); 418 } 419 420 #undef __FUNCT__ 421 #define __FUNCT__ "MatSetOption_IS" 422 PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscTruth flg) 423 { 424 Mat_IS *a = (Mat_IS*)A->data; 425 PetscErrorCode ierr; 426 427 PetscFunctionBegin; 428 ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 429 PetscFunctionReturn(0); 430 } 431 432 #undef __FUNCT__ 433 #define __FUNCT__ "MatCreateIS" 434 /*@ 435 MatCreateIS - Creates a "process" unassmembled matrix, it is assembled on each 436 process but not across processes. 437 438 Input Parameters: 439 + comm - MPI communicator that will share the matrix 440 . m,n,M,N - local and/or global sizes of the the left and right vector used in matrix vector products 441 - map - mapping that defines the global number for each local number 442 443 Output Parameter: 444 . A - the resulting matrix 445 446 Level: advanced 447 448 Notes: See MATIS for more details 449 m and n are NOT related to the size of the map, they are the size of the part of the vector owned 450 by that process. m + nghosts (or n + nghosts) is the length of map since map maps all local points 451 plus the ghost points to global indices. 452 453 .seealso: MATIS, MatSetLocalToGlobalMapping() 454 @*/ 455 PetscErrorCode PETSCMAT_DLLEXPORT MatCreateIS(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping map,Mat *A) 456 { 457 PetscErrorCode ierr; 458 459 PetscFunctionBegin; 460 ierr = MatCreate(comm,A);CHKERRQ(ierr); 461 ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 462 ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 463 ierr = MatSetLocalToGlobalMapping(*A,map);CHKERRQ(ierr); 464 PetscFunctionReturn(0); 465 } 466 467 /*MC 468 MATIS - MATIS = "is" - A matrix type to be used for using the Neumann-Neumann type preconditioners. 469 This stores the matrices in globally unassembled form. Each processor 470 assembles only its local Neumann problem and the parallel matrix vector 471 product is handled "implicitly". 472 473 Operations Provided: 474 + MatMult() 475 . MatMultAdd() 476 . MatMultTranspose() 477 . MatMultTransposeAdd() 478 . MatZeroEntries() 479 . MatSetOption() 480 . MatZeroRows() 481 . MatZeroRowsLocal() 482 . MatSetValues() 483 . MatSetValuesLocal() 484 . MatScale() 485 . MatGetDiagonal() 486 - MatSetLocalToGlobalMapping() 487 488 Options Database Keys: 489 . -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 490 491 Notes: Options prefix for the inner matrix are given by -is_mat_xxx 492 493 You must call MatSetLocalToGlobalMapping() before using this matrix type. 494 495 You can do matrix preallocation on the local matrix after you obtain it with 496 MatISGetLocalMat() 497 498 Level: advanced 499 500 .seealso: PC, MatISGetLocalMat(), MatSetLocalToGlobalMapping() 501 502 M*/ 503 504 EXTERN_C_BEGIN 505 #undef __FUNCT__ 506 #define __FUNCT__ "MatCreate_IS" 507 PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_IS(Mat A) 508 { 509 PetscErrorCode ierr; 510 Mat_IS *b; 511 512 PetscFunctionBegin; 513 ierr = PetscNewLog(A,Mat_IS,&b);CHKERRQ(ierr); 514 A->data = (void*)b; 515 ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 516 A->mapping = 0; 517 518 A->ops->mult = MatMult_IS; 519 A->ops->multadd = MatMultAdd_IS; 520 A->ops->multtranspose = MatMultTranspose_IS; 521 A->ops->multtransposeadd = MatMultTransposeAdd_IS; 522 A->ops->destroy = MatDestroy_IS; 523 A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 524 A->ops->setvalues = MatSetValues_IS; 525 A->ops->setvalueslocal = MatSetValuesLocal_IS; 526 A->ops->zerorows = MatZeroRows_IS; 527 A->ops->zerorowslocal = MatZeroRowsLocal_IS; 528 A->ops->assemblybegin = MatAssemblyBegin_IS; 529 A->ops->assemblyend = MatAssemblyEnd_IS; 530 A->ops->view = MatView_IS; 531 A->ops->zeroentries = MatZeroEntries_IS; 532 A->ops->scale = MatScale_IS; 533 A->ops->getdiagonal = MatGetDiagonal_IS; 534 A->ops->setoption = MatSetOption_IS; 535 536 ierr = PetscLayoutSetBlockSize(A->rmap,1);CHKERRQ(ierr); 537 ierr = PetscLayoutSetBlockSize(A->cmap,1);CHKERRQ(ierr); 538 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 539 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 540 541 b->A = 0; 542 b->ctx = 0; 543 b->x = 0; 544 b->y = 0; 545 ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatISGetLocalMat_C","MatISGetLocalMat_IS",MatISGetLocalMat_IS);CHKERRQ(ierr); 546 ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 547 548 PetscFunctionReturn(0); 549 } 550 EXTERN_C_END 551