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; 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 = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 166 ierr = MatSetSizes(is->A,n,n,n,n);CHKERRQ(ierr); 167 ierr = MatSetOptionsPrefix(is->A,"is");CHKERRQ(ierr); 168 ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 169 170 /* Create the local work vectors */ 171 ierr = VecCreateSeq(PETSC_COMM_SELF,n,&is->x);CHKERRQ(ierr); 172 ierr = VecDuplicate(is->x,&is->y);CHKERRQ(ierr); 173 174 /* setup the global to local scatter */ 175 ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&to);CHKERRQ(ierr); 176 ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); 177 ierr = VecCreateMPIWithArray(((PetscObject)A)->comm,A->cmap->n,A->cmap->N,PETSC_NULL,&global);CHKERRQ(ierr); 178 ierr = VecScatterCreate(global,from,is->x,to,&is->ctx);CHKERRQ(ierr); 179 ierr = VecDestroy(&global);CHKERRQ(ierr); 180 ierr = ISDestroy(&to);CHKERRQ(ierr); 181 ierr = ISDestroy(&from);CHKERRQ(ierr); 182 PetscFunctionReturn(0); 183 } 184 185 #define ISG2LMapApply(mapping,n,in,out) 0;\ 186 if (!(mapping)->globals) {\ 187 PetscErrorCode _ierr = ISGlobalToLocalMappingApply((mapping),IS_GTOLM_MASK,0,0,0,0);CHKERRQ(_ierr);\ 188 }\ 189 {\ 190 PetscInt _i,*_globals = (mapping)->globals,_start = (mapping)->globalstart,_end = (mapping)->globalend;\ 191 for (_i=0; _i<n; _i++) {\ 192 if (in[_i] < 0) out[_i] = in[_i];\ 193 else if (in[_i] < _start) out[_i] = -1;\ 194 else if (in[_i] > _end) out[_i] = -1;\ 195 else out[_i] = _globals[in[_i] - _start];\ 196 }\ 197 } 198 199 #undef __FUNCT__ 200 #define __FUNCT__ "MatSetValues_IS" 201 PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 202 { 203 Mat_IS *is = (Mat_IS*)mat->data; 204 PetscInt rows_l[2048],cols_l[2048]; 205 PetscErrorCode ierr; 206 207 PetscFunctionBegin; 208 #if defined(PETSC_USE_DEBUG) 209 if (m > 2048 || n > 2048) { 210 SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Number of row/column indices must be <= 2048: they are %D %D",m,n); 211 } 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 = PETSC_NULL; 240 PetscErrorCode ierr; 241 242 PetscFunctionBegin; 243 if (x && b) SETERRQ(((PetscObject)A)->comm,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(((PetscObject)A)->comm,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 = VecCreateMPI(((PetscObject)A)->comm,A->cmap->n,A->cmap->N,&counter);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 ierr = VecGetArray(is->x,&array);CHKERRQ(ierr); 285 ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 286 for (i=0; i<n; i++) { 287 ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 288 } 289 ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 290 ierr = MatAssemblyEnd (is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 291 ierr = VecRestoreArray(is->x,&array);CHKERRQ(ierr); 292 } 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 #undef __FUNCT__ 366 #define __FUNCT__ "MatZeroEntries_IS" 367 PetscErrorCode MatZeroEntries_IS(Mat A) 368 { 369 Mat_IS *a = (Mat_IS*)A->data; 370 PetscErrorCode ierr; 371 372 PetscFunctionBegin; 373 ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 374 PetscFunctionReturn(0); 375 } 376 377 #undef __FUNCT__ 378 #define __FUNCT__ "MatScale_IS" 379 PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 380 { 381 Mat_IS *is = (Mat_IS*)A->data; 382 PetscErrorCode ierr; 383 384 PetscFunctionBegin; 385 ierr = MatScale(is->A,a);CHKERRQ(ierr); 386 PetscFunctionReturn(0); 387 } 388 389 #undef __FUNCT__ 390 #define __FUNCT__ "MatGetDiagonal_IS" 391 PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 392 { 393 Mat_IS *is = (Mat_IS*)A->data; 394 PetscErrorCode ierr; 395 396 PetscFunctionBegin; 397 /* get diagonal of the local matrix */ 398 ierr = MatGetDiagonal(is->A,is->x);CHKERRQ(ierr); 399 400 /* scatter diagonal back into global vector */ 401 ierr = VecSet(v,0);CHKERRQ(ierr); 402 ierr = VecScatterBegin(is->ctx,is->x,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 403 ierr = VecScatterEnd (is->ctx,is->x,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 404 PetscFunctionReturn(0); 405 } 406 407 #undef __FUNCT__ 408 #define __FUNCT__ "MatSetOption_IS" 409 PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 410 { 411 Mat_IS *a = (Mat_IS*)A->data; 412 PetscErrorCode ierr; 413 414 PetscFunctionBegin; 415 ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 416 PetscFunctionReturn(0); 417 } 418 419 #undef __FUNCT__ 420 #define __FUNCT__ "MatCreateIS" 421 /*@ 422 MatCreateIS - Creates a "process" unassmembled matrix, it is assembled on each 423 process but not across processes. 424 425 Input Parameters: 426 + comm - MPI communicator that will share the matrix 427 . m,n,M,N - local and/or global sizes of the the left and right vector used in matrix vector products 428 - map - mapping that defines the global number for each local number 429 430 Output Parameter: 431 . A - the resulting matrix 432 433 Level: advanced 434 435 Notes: See MATIS for more details 436 m and n are NOT related to the size of the map, they are the size of the part of the vector owned 437 by that process. m + nghosts (or n + nghosts) is the length of map since map maps all local points 438 plus the ghost points to global indices. 439 440 .seealso: MATIS, MatSetLocalToGlobalMapping() 441 @*/ 442 PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping map,Mat *A) 443 { 444 PetscErrorCode ierr; 445 446 PetscFunctionBegin; 447 ierr = MatCreate(comm,A);CHKERRQ(ierr); 448 ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 449 ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 450 ierr = MatSetLocalToGlobalMapping(*A,map,map);CHKERRQ(ierr); 451 PetscFunctionReturn(0); 452 } 453 454 /*MC 455 MATIS - MATIS = "is" - A matrix type to be used for using the Neumann-Neumann type preconditioners. 456 This stores the matrices in globally unassembled form. Each processor 457 assembles only its local Neumann problem and the parallel matrix vector 458 product is handled "implicitly". 459 460 Operations Provided: 461 + MatMult() 462 . MatMultAdd() 463 . MatMultTranspose() 464 . MatMultTransposeAdd() 465 . MatZeroEntries() 466 . MatSetOption() 467 . MatZeroRows() 468 . MatZeroRowsLocal() 469 . MatSetValues() 470 . MatSetValuesLocal() 471 . MatScale() 472 . MatGetDiagonal() 473 - MatSetLocalToGlobalMapping() 474 475 Options Database Keys: 476 . -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 477 478 Notes: Options prefix for the inner matrix are given by -is_mat_xxx 479 480 You must call MatSetLocalToGlobalMapping() before using this matrix type. 481 482 You can do matrix preallocation on the local matrix after you obtain it with 483 MatISGetLocalMat() 484 485 Level: advanced 486 487 .seealso: PC, MatISGetLocalMat(), MatSetLocalToGlobalMapping() 488 489 M*/ 490 491 EXTERN_C_BEGIN 492 #undef __FUNCT__ 493 #define __FUNCT__ "MatCreate_IS" 494 PetscErrorCode MatCreate_IS(Mat A) 495 { 496 PetscErrorCode ierr; 497 Mat_IS *b; 498 499 PetscFunctionBegin; 500 ierr = PetscNewLog(A,Mat_IS,&b);CHKERRQ(ierr); 501 A->data = (void*)b; 502 ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 503 504 A->ops->mult = MatMult_IS; 505 A->ops->multadd = MatMultAdd_IS; 506 A->ops->multtranspose = MatMultTranspose_IS; 507 A->ops->multtransposeadd = MatMultTransposeAdd_IS; 508 A->ops->destroy = MatDestroy_IS; 509 A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 510 A->ops->setvalues = MatSetValues_IS; 511 A->ops->setvalueslocal = MatSetValuesLocal_IS; 512 A->ops->zerorows = MatZeroRows_IS; 513 A->ops->zerorowslocal = MatZeroRowsLocal_IS; 514 A->ops->assemblybegin = MatAssemblyBegin_IS; 515 A->ops->assemblyend = MatAssemblyEnd_IS; 516 A->ops->view = MatView_IS; 517 A->ops->zeroentries = MatZeroEntries_IS; 518 A->ops->scale = MatScale_IS; 519 A->ops->getdiagonal = MatGetDiagonal_IS; 520 A->ops->setoption = MatSetOption_IS; 521 522 ierr = PetscLayoutSetBlockSize(A->rmap,1);CHKERRQ(ierr); 523 ierr = PetscLayoutSetBlockSize(A->cmap,1);CHKERRQ(ierr); 524 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 525 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 526 527 b->A = 0; 528 b->ctx = 0; 529 b->x = 0; 530 b->y = 0; 531 ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatISGetLocalMat_C","MatISGetLocalMat_IS",MatISGetLocalMat_IS);CHKERRQ(ierr); 532 ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 533 534 PetscFunctionReturn(0); 535 } 536 EXTERN_C_END 537