1 2 #include "packimpl.h" /*I "petscdmcomposite.h" I*/ 3 4 #undef __FUNCT__ 5 #define __FUNCT__ "DMCompositeSetCoupling" 6 /*@C 7 DMCompositeSetCoupling - Sets user provided routines that compute the coupling between the 8 seperate components (DMs) in a DMto build the correct matrix nonzero structure. 9 10 11 Logically Collective on MPI_Comm 12 13 Input Parameter: 14 + dm - the composite object 15 - formcouplelocations - routine to set the nonzero locations in the matrix 16 17 Level: advanced 18 19 Notes: See DMSetApplicationContext() and DMGetApplicationContext() for how to get user information into 20 this routine 21 22 @*/ 23 PetscErrorCode DMCompositeSetCoupling(DM dm,PetscErrorCode (*FormCoupleLocations)(DM,Mat,PetscInt*,PetscInt*,PetscInt,PetscInt,PetscInt,PetscInt)) 24 { 25 DM_Composite *com = (DM_Composite*)dm->data; 26 27 PetscFunctionBegin; 28 com->FormCoupleLocations = FormCoupleLocations; 29 PetscFunctionReturn(0); 30 } 31 32 #undef __FUNCT__ 33 #define __FUNCT__ "DMDestroy_Composite" 34 PetscErrorCode DMDestroy_Composite(DM dm) 35 { 36 PetscErrorCode ierr; 37 struct DMCompositeLink *next, *prev; 38 DM_Composite *com = (DM_Composite *)dm->data; 39 40 PetscFunctionBegin; 41 next = com->next; 42 while (next) { 43 prev = next; 44 next = next->next; 45 ierr = DMDestroy(&prev->dm);CHKERRQ(ierr); 46 ierr = PetscFree(prev->grstarts);CHKERRQ(ierr); 47 ierr = PetscFree(prev);CHKERRQ(ierr); 48 } 49 PetscFunctionReturn(0); 50 } 51 52 #undef __FUNCT__ 53 #define __FUNCT__ "DMView_Composite" 54 PetscErrorCode DMView_Composite(DM dm,PetscViewer v) 55 { 56 PetscErrorCode ierr; 57 PetscBool iascii; 58 DM_Composite *com = (DM_Composite *)dm->data; 59 60 PetscFunctionBegin; 61 ierr = PetscTypeCompare((PetscObject)v,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 62 if (iascii) { 63 struct DMCompositeLink *lnk = com->next; 64 PetscInt i; 65 66 ierr = PetscViewerASCIIPrintf(v,"DM (%s)\n",((PetscObject)dm)->prefix?((PetscObject)dm)->prefix:"no prefix");CHKERRQ(ierr); 67 ierr = PetscViewerASCIIPrintf(v," contains %D DMs\n",com->nDM);CHKERRQ(ierr); 68 ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr); 69 for (i=0; lnk; lnk=lnk->next,i++) { 70 ierr = PetscViewerASCIIPrintf(v,"Link %D: DM of type %s\n",i,((PetscObject)lnk->dm)->type_name);CHKERRQ(ierr); 71 ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr); 72 ierr = DMView(lnk->dm,v);CHKERRQ(ierr); 73 ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr); 74 } 75 ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr); 76 } 77 PetscFunctionReturn(0); 78 } 79 80 /* --------------------------------------------------------------------------------------*/ 81 #undef __FUNCT__ 82 #define __FUNCT__ "DMSetUp_Composite" 83 PetscErrorCode DMSetUp_Composite(DM dm) 84 { 85 PetscErrorCode ierr; 86 PetscInt nprev = 0; 87 PetscMPIInt rank,size; 88 DM_Composite *com = (DM_Composite*)dm->data; 89 struct DMCompositeLink *next = com->next; 90 PetscLayout map; 91 92 PetscFunctionBegin; 93 if (com->setup) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Packer has already been setup"); 94 ierr = PetscLayoutCreate(((PetscObject)dm)->comm,&map);CHKERRQ(ierr); 95 ierr = PetscLayoutSetLocalSize(map,com->n);CHKERRQ(ierr); 96 ierr = PetscLayoutSetSize(map,PETSC_DETERMINE);CHKERRQ(ierr); 97 ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 98 ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 99 ierr = PetscLayoutGetSize(map,&com->N);CHKERRQ(ierr); 100 ierr = PetscLayoutGetRange(map,&com->rstart,PETSC_NULL);CHKERRQ(ierr); 101 ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 102 103 /* now set the rstart for each linked vector */ 104 ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 105 ierr = MPI_Comm_size(((PetscObject)dm)->comm,&size);CHKERRQ(ierr); 106 while (next) { 107 next->rstart = nprev; 108 nprev += next->n; 109 next->grstart = com->rstart + next->rstart; 110 ierr = PetscMalloc(size*sizeof(PetscInt),&next->grstarts);CHKERRQ(ierr); 111 ierr = MPI_Allgather(&next->grstart,1,MPIU_INT,next->grstarts,1,MPIU_INT,((PetscObject)dm)->comm);CHKERRQ(ierr); 112 next = next->next; 113 } 114 com->setup = PETSC_TRUE; 115 PetscFunctionReturn(0); 116 } 117 118 /* ----------------------------------------------------------------------------------*/ 119 120 #include <stdarg.h> 121 122 #undef __FUNCT__ 123 #define __FUNCT__ "DMCompositeGetNumberDM" 124 /*@C 125 DMCompositeGetNumberDM - Get's the number of DM objects in the DMComposite 126 representation. 127 128 Not Collective 129 130 Input Parameter: 131 . dm - the packer object 132 133 Output Parameter: 134 . nDM - the number of DMs 135 136 Level: beginner 137 138 @*/ 139 PetscErrorCode DMCompositeGetNumberDM(DM dm,PetscInt *nDM) 140 { 141 DM_Composite *com = (DM_Composite*)dm->data; 142 PetscFunctionBegin; 143 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 144 *nDM = com->nDM; 145 PetscFunctionReturn(0); 146 } 147 148 149 #undef __FUNCT__ 150 #define __FUNCT__ "DMCompositeGetAccess" 151 /*@C 152 DMCompositeGetAccess - Allows one to access the individual packed vectors in their global 153 representation. 154 155 Collective on DMComposite 156 157 Input Parameters: 158 + dm - the packer object 159 - gvec - the global vector 160 161 Output Parameters: 162 . Vec* ... - the packed parallel vectors, PETSC_NULL for those that are not needed 163 164 Notes: Use DMCompositeRestoreAccess() to return the vectors when you no longer need them 165 166 Level: advanced 167 168 @*/ 169 PetscErrorCode DMCompositeGetAccess(DM dm,Vec gvec,...) 170 { 171 va_list Argp; 172 PetscErrorCode ierr; 173 struct DMCompositeLink *next; 174 DM_Composite *com = (DM_Composite*)dm->data; 175 176 PetscFunctionBegin; 177 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 178 PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 179 next = com->next; 180 if (!com->setup) { 181 ierr = DMSetUp(dm);CHKERRQ(ierr); 182 } 183 184 /* loop over packed objects, handling one at at time */ 185 va_start(Argp,gvec); 186 while (next) { 187 Vec *vec; 188 vec = va_arg(Argp, Vec*); 189 if (vec) { 190 PetscScalar *array; 191 ierr = DMGetGlobalVector(next->dm,vec);CHKERRQ(ierr); 192 ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 193 ierr = VecPlaceArray(*vec,array+next->rstart);CHKERRQ(ierr); 194 ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 195 } 196 next = next->next; 197 } 198 va_end(Argp); 199 PetscFunctionReturn(0); 200 } 201 202 #undef __FUNCT__ 203 #define __FUNCT__ "DMCompositeRestoreAccess" 204 /*@C 205 DMCompositeRestoreAccess - Returns the vectors obtained with DMCompositeGetAccess() 206 representation. 207 208 Collective on DMComposite 209 210 Input Parameters: 211 + dm - the packer object 212 . gvec - the global vector 213 - Vec* ... - the individual parallel vectors, PETSC_NULL for those that are not needed 214 215 Level: advanced 216 217 .seealso DMCompositeAddDM(), DMCreateGlobalVector(), 218 DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeScatter(), 219 DMCompositeRestoreAccess(), DMCompositeGetAccess() 220 221 @*/ 222 PetscErrorCode DMCompositeRestoreAccess(DM dm,Vec gvec,...) 223 { 224 va_list Argp; 225 PetscErrorCode ierr; 226 struct DMCompositeLink *next; 227 DM_Composite *com = (DM_Composite*)dm->data; 228 229 PetscFunctionBegin; 230 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 231 PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 232 next = com->next; 233 if (!com->setup) { 234 ierr = DMSetUp(dm);CHKERRQ(ierr); 235 } 236 237 /* loop over packed objects, handling one at at time */ 238 va_start(Argp,gvec); 239 while (next) { 240 Vec *vec; 241 vec = va_arg(Argp, Vec*); 242 if (vec) { 243 ierr = VecResetArray(*vec);CHKERRQ(ierr); 244 ierr = DMRestoreGlobalVector(next->dm,vec);CHKERRQ(ierr); 245 } 246 next = next->next; 247 } 248 va_end(Argp); 249 PetscFunctionReturn(0); 250 } 251 252 #undef __FUNCT__ 253 #define __FUNCT__ "DMCompositeScatter" 254 /*@C 255 DMCompositeScatter - Scatters from a global packed vector into its individual local vectors 256 257 Collective on DMComposite 258 259 Input Parameters: 260 + dm - the packer object 261 . gvec - the global vector 262 - Vec ... - the individual sequential vectors, PETSC_NULL for those that are not needed 263 264 Level: advanced 265 266 .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 267 DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 268 DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 269 270 @*/ 271 PetscErrorCode DMCompositeScatter(DM dm,Vec gvec,...) 272 { 273 va_list Argp; 274 PetscErrorCode ierr; 275 struct DMCompositeLink *next; 276 PetscInt cnt; 277 DM_Composite *com = (DM_Composite*)dm->data; 278 279 PetscFunctionBegin; 280 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 281 PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 282 if (!com->setup) { 283 ierr = DMSetUp(dm);CHKERRQ(ierr); 284 } 285 286 /* loop over packed objects, handling one at at time */ 287 va_start(Argp,gvec); 288 for (cnt=3,next=com->next; next; cnt++,next=next->next) { 289 Vec local; 290 local = va_arg(Argp, Vec); 291 if (local) { 292 Vec global; 293 PetscScalar *array; 294 PetscValidHeaderSpecific(local,VEC_CLASSID,cnt); 295 ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 296 ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 297 ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr); 298 ierr = DMGlobalToLocalBegin(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr); 299 ierr = DMGlobalToLocalEnd(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr); 300 ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 301 ierr = VecResetArray(global);CHKERRQ(ierr); 302 ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 303 } 304 } 305 va_end(Argp); 306 PetscFunctionReturn(0); 307 } 308 309 #undef __FUNCT__ 310 #define __FUNCT__ "DMCompositeGather" 311 /*@C 312 DMCompositeGather - Gathers into a global packed vector from its individual local vectors 313 314 Collective on DMComposite 315 316 Input Parameter: 317 + dm - the packer object 318 . gvec - the global vector 319 - Vec ... - the individual sequential vectors, PETSC_NULL for any that are not needed 320 321 Level: advanced 322 323 .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 324 DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 325 DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 326 327 @*/ 328 PetscErrorCode DMCompositeGather(DM dm,Vec gvec,InsertMode imode,...) 329 { 330 va_list Argp; 331 PetscErrorCode ierr; 332 struct DMCompositeLink *next; 333 DM_Composite *com = (DM_Composite*)dm->data; 334 PetscInt cnt; 335 336 PetscFunctionBegin; 337 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 338 PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 339 if (!com->setup) { 340 ierr = DMSetUp(dm);CHKERRQ(ierr); 341 } 342 343 /* loop over packed objects, handling one at at time */ 344 va_start(Argp,imode); 345 for (cnt=3,next=com->next; next; cnt++,next=next->next) { 346 Vec local; 347 local = va_arg(Argp, Vec); 348 if (local) { 349 PetscScalar *array; 350 Vec global; 351 PetscValidHeaderSpecific(local,VEC_CLASSID,cnt); 352 ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 353 ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 354 ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr); 355 ierr = DMLocalToGlobalBegin(next->dm,local,imode,global);CHKERRQ(ierr); 356 ierr = DMLocalToGlobalEnd(next->dm,local,imode,global);CHKERRQ(ierr); 357 ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 358 ierr = VecResetArray(global);CHKERRQ(ierr); 359 ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 360 } 361 } 362 va_end(Argp); 363 PetscFunctionReturn(0); 364 } 365 366 #undef __FUNCT__ 367 #define __FUNCT__ "DMCompositeAddDM" 368 /*@C 369 DMCompositeAddDM - adds a DM vector to a DMComposite 370 371 Collective on DMComposite 372 373 Input Parameter: 374 + dm - the packer object 375 - dm - the DM object, if the DM is a da you will need to caste it with a (DM) 376 377 Level: advanced 378 379 .seealso DMDestroy(), DMCompositeGather(), DMCompositeAddDM(), DMCreateGlobalVector(), 380 DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 381 DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 382 383 @*/ 384 PetscErrorCode DMCompositeAddDM(DM dmc,DM dm) 385 { 386 PetscErrorCode ierr; 387 PetscInt n,nlocal; 388 struct DMCompositeLink *mine,*next; 389 Vec global,local; 390 DM_Composite *com = (DM_Composite*)dmc->data; 391 392 PetscFunctionBegin; 393 PetscValidHeaderSpecific(dmc,DM_CLASSID,1); 394 PetscValidHeaderSpecific(dm,DM_CLASSID,2); 395 next = com->next; 396 if (com->setup) SETERRQ(((PetscObject)dmc)->comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot add a DM once you have used the DMComposite"); 397 398 /* create new link */ 399 ierr = PetscNew(struct DMCompositeLink,&mine);CHKERRQ(ierr); 400 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 401 ierr = DMGetGlobalVector(dm,&global);CHKERRQ(ierr); 402 ierr = VecGetLocalSize(global,&n);CHKERRQ(ierr); 403 ierr = DMRestoreGlobalVector(dm,&global);CHKERRQ(ierr); 404 ierr = DMGetLocalVector(dm,&local);CHKERRQ(ierr); 405 ierr = VecGetSize(local,&nlocal);CHKERRQ(ierr); 406 ierr = DMRestoreLocalVector(dm,&local);CHKERRQ(ierr); 407 mine->n = n; 408 mine->nlocal = nlocal; 409 mine->dm = dm; 410 mine->next = PETSC_NULL; 411 com->n += n; 412 413 /* add to end of list */ 414 if (!next) { 415 com->next = mine; 416 } else { 417 while (next->next) next = next->next; 418 next->next = mine; 419 } 420 com->nDM++; 421 com->nmine++; 422 PetscFunctionReturn(0); 423 } 424 425 extern PetscErrorCode VecView_MPI(Vec,PetscViewer); 426 EXTERN_C_BEGIN 427 #undef __FUNCT__ 428 #define __FUNCT__ "VecView_DMComposite" 429 PetscErrorCode VecView_DMComposite(Vec gvec,PetscViewer viewer) 430 { 431 DM dm; 432 PetscErrorCode ierr; 433 struct DMCompositeLink *next; 434 PetscBool isdraw; 435 DM_Composite *com; 436 437 PetscFunctionBegin; 438 ierr = PetscObjectQuery((PetscObject)gvec,"DM",(PetscObject*)&dm);CHKERRQ(ierr); 439 if (!dm) SETERRQ(((PetscObject)gvec)->comm,PETSC_ERR_ARG_WRONG,"Vector not generated from a DMComposite"); 440 com = (DM_Composite*)dm->data; 441 next = com->next; 442 443 ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 444 if (!isdraw) { 445 /* do I really want to call this? */ 446 ierr = VecView_MPI(gvec,viewer);CHKERRQ(ierr); 447 } else { 448 PetscInt cnt = 0; 449 450 /* loop over packed objects, handling one at at time */ 451 while (next) { 452 Vec vec; 453 PetscScalar *array; 454 PetscInt bs; 455 456 /* Should use VecGetSubVector() eventually, but would need to forward the DM for that to work */ 457 ierr = DMGetGlobalVector(next->dm,&vec);CHKERRQ(ierr); 458 ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 459 ierr = VecPlaceArray(vec,array+next->rstart);CHKERRQ(ierr); 460 ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 461 ierr = VecView(vec,viewer);CHKERRQ(ierr); 462 ierr = VecGetBlockSize(vec,&bs);CHKERRQ(ierr); 463 ierr = VecResetArray(vec);CHKERRQ(ierr); 464 ierr = DMRestoreGlobalVector(next->dm,&vec);CHKERRQ(ierr); 465 ierr = PetscViewerDrawBaseAdd(viewer,bs);CHKERRQ(ierr); 466 cnt += bs; 467 next = next->next; 468 } 469 ierr = PetscViewerDrawBaseAdd(viewer,-cnt);CHKERRQ(ierr); 470 } 471 PetscFunctionReturn(0); 472 } 473 EXTERN_C_END 474 475 476 #undef __FUNCT__ 477 #define __FUNCT__ "DMCreateGlobalVector_Composite" 478 PetscErrorCode DMCreateGlobalVector_Composite(DM dm,Vec *gvec) 479 { 480 PetscErrorCode ierr; 481 DM_Composite *com = (DM_Composite*)dm->data; 482 483 PetscFunctionBegin; 484 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 485 ierr = DMSetUp(dm);CHKERRQ(ierr); 486 ierr = VecCreateMPI(((PetscObject)dm)->comm,com->n,com->N,gvec);CHKERRQ(ierr); 487 ierr = PetscObjectCompose((PetscObject)*gvec,"DM",(PetscObject)dm);CHKERRQ(ierr); 488 ierr = VecSetOperation(*gvec,VECOP_VIEW,(void(*)(void))VecView_DMComposite);CHKERRQ(ierr); 489 PetscFunctionReturn(0); 490 } 491 492 #undef __FUNCT__ 493 #define __FUNCT__ "DMCreateLocalVector_Composite" 494 PetscErrorCode DMCreateLocalVector_Composite(DM dm,Vec *lvec) 495 { 496 PetscErrorCode ierr; 497 DM_Composite *com = (DM_Composite*)dm->data; 498 499 PetscFunctionBegin; 500 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 501 if (!com->setup) { 502 ierr = DMSetUp(dm);CHKERRQ(ierr); 503 } 504 ierr = VecCreateSeq(((PetscObject)dm)->comm,com->nghost,lvec);CHKERRQ(ierr); 505 ierr = PetscObjectCompose((PetscObject)*lvec,"DM",(PetscObject)dm);CHKERRQ(ierr); 506 PetscFunctionReturn(0); 507 } 508 509 #undef __FUNCT__ 510 #define __FUNCT__ "DMCompositeGetISLocalToGlobalMappings" 511 /*@C 512 DMCompositeGetISLocalToGlobalMappings - gets an ISLocalToGlobalMapping for each DM in the DMComposite, maps to the composite global space 513 514 Collective on DM 515 516 Input Parameter: 517 . dm - the packer object 518 519 Output Parameters: 520 . ltogs - the individual mappings for each packed vector. Note that this includes 521 all the ghost points that individual ghosted DMDA's may have. 522 523 Level: advanced 524 525 Notes: 526 Each entry of ltogs should be destroyed with ISLocalToGlobalMappingDestroy(), the ltogs array should be freed with PetscFree(). 527 528 .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 529 DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(), 530 DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries() 531 532 @*/ 533 PetscErrorCode DMCompositeGetISLocalToGlobalMappings(DM dm,ISLocalToGlobalMapping **ltogs) 534 { 535 PetscErrorCode ierr; 536 PetscInt i,*idx,n,cnt; 537 struct DMCompositeLink *next; 538 PetscMPIInt rank; 539 DM_Composite *com = (DM_Composite*)dm->data; 540 541 PetscFunctionBegin; 542 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 543 ierr = PetscMalloc((com->nDM)*sizeof(ISLocalToGlobalMapping),ltogs);CHKERRQ(ierr); 544 next = com->next; 545 ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 546 547 /* loop over packed objects, handling one at at time */ 548 cnt = 0; 549 while (next) { 550 ISLocalToGlobalMapping ltog; 551 PetscMPIInt size; 552 const PetscInt *suboff,*indices; 553 Vec global; 554 555 /* Get sub-DM global indices for each local dof */ 556 ierr = DMGetLocalToGlobalMapping(next->dm,<og);CHKERRQ(ierr); 557 ierr = ISLocalToGlobalMappingGetSize(ltog,&n);CHKERRQ(ierr); 558 ierr = ISLocalToGlobalMappingGetIndices(ltog,&indices);CHKERRQ(ierr); 559 ierr = PetscMalloc(n*sizeof(PetscInt),&idx);CHKERRQ(ierr); 560 561 /* Get the offsets for the sub-DM global vector */ 562 ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 563 ierr = VecGetOwnershipRanges(global,&suboff);CHKERRQ(ierr); 564 ierr = MPI_Comm_size(((PetscObject)global)->comm,&size);CHKERRQ(ierr); 565 566 /* Shift the sub-DM definition of the global space to the composite global space */ 567 for (i=0; i<n; i++) { 568 PetscInt subi = indices[i],lo = 0,hi = size,t; 569 /* Binary search to find which rank owns subi */ 570 while (hi-lo > 1) { 571 t = lo + (hi-lo)/2; 572 if (suboff[t] > subi) hi = t; 573 else lo = t; 574 } 575 idx[i] = subi - suboff[lo] + next->grstarts[lo]; 576 } 577 ierr = ISLocalToGlobalMappingRestoreIndices(ltog,&indices);CHKERRQ(ierr); 578 ierr = ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm,n,idx,PETSC_OWN_POINTER,&(*ltogs)[cnt]);CHKERRQ(ierr); 579 ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 580 next = next->next; 581 cnt++; 582 } 583 PetscFunctionReturn(0); 584 } 585 586 #undef __FUNCT__ 587 #define __FUNCT__ "DMCompositeGetLocalISs" 588 /*@C 589 DMCompositeGetLocalISs - Gets index sets for each component of a composite local vector 590 591 Not Collective 592 593 Input Arguments: 594 . dm - composite DM 595 596 Output Arguments: 597 . is - array of serial index sets for each each component of the DMComposite 598 599 Level: intermediate 600 601 Notes: 602 At present, a composite local vector does not normally exist. This function is used to provide index sets for 603 MatGetLocalSubMatrix(). In the future, the scatters for each entry in the DMComposite may be be merged into a single 604 scatter to a composite local vector. The user should not typically need to know which is being done. 605 606 To get the composite global indices at all local points (including ghosts), use DMCompositeGetISLocalToGlobalMappings(). 607 608 To get index sets for pieces of the composite global vector, use DMCompositeGetGlobalISs(). 609 610 Each returned IS should be destroyed with ISDestroy(), the array should be freed with PetscFree(). 611 612 .seealso: DMCompositeGetGlobalISs(), DMCompositeGetISLocalToGlobalMappings(), MatGetLocalSubMatrix(), MatCreateLocalRef() 613 @*/ 614 PetscErrorCode DMCompositeGetLocalISs(DM dm,IS **is) 615 { 616 PetscErrorCode ierr; 617 DM_Composite *com = (DM_Composite*)dm->data; 618 struct DMCompositeLink *link; 619 PetscInt cnt,start; 620 621 PetscFunctionBegin; 622 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 623 PetscValidPointer(is,2); 624 ierr = PetscMalloc(com->nmine*sizeof(IS),is);CHKERRQ(ierr); 625 for (cnt=0,start=0,link=com->next; link; start+=link->nlocal,cnt++,link=link->next) { 626 PetscInt bs; 627 ierr = ISCreateStride(PETSC_COMM_SELF,link->nlocal,start,1,&(*is)[cnt]);CHKERRQ(ierr); 628 ierr = DMGetBlockSize(link->dm,&bs);CHKERRQ(ierr); 629 ierr = ISSetBlockSize((*is)[cnt],bs);CHKERRQ(ierr); 630 } 631 PetscFunctionReturn(0); 632 } 633 634 #undef __FUNCT__ 635 #define __FUNCT__ "DMCompositeGetGlobalISs" 636 /*@C 637 DMCompositeGetGlobalISs - Gets the index sets for each composed object 638 639 Collective on DMComposite 640 641 Input Parameter: 642 . dm - the packer object 643 644 Output Parameters: 645 . is - the array of index sets 646 647 Level: advanced 648 649 Notes: 650 The is entries should be destroyed with ISDestroy(), the is array should be freed with PetscFree() 651 652 These could be used to extract a subset of vector entries for a "multi-physics" preconditioner 653 654 Use DMCompositeGetLocalISs() for index sets in the packed local numbering, and 655 DMCompositeGetISLocalToGlobalMappings() for to map local sub-DM (including ghost) indices to packed global 656 indices. 657 658 .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 659 DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(), 660 DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries() 661 662 @*/ 663 664 PetscErrorCode DMCompositeGetGlobalISs(DM dm,IS *is[]) 665 { 666 PetscErrorCode ierr; 667 PetscInt cnt = 0,*idx,i; 668 struct DMCompositeLink *next; 669 PetscMPIInt rank; 670 DM_Composite *com = (DM_Composite*)dm->data; 671 672 PetscFunctionBegin; 673 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 674 ierr = PetscMalloc((com->nDM)*sizeof(IS),is);CHKERRQ(ierr); 675 next = com->next; 676 ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 677 678 /* loop over packed objects, handling one at at time */ 679 while (next) { 680 ierr = PetscMalloc(next->n*sizeof(PetscInt),&idx);CHKERRQ(ierr); 681 for (i=0; i<next->n; i++) idx[i] = next->grstart + i; 682 ierr = ISCreateGeneral(((PetscObject)dm)->comm,next->n,idx,PETSC_OWN_POINTER,&(*is)[cnt]);CHKERRQ(ierr); 683 cnt++; 684 next = next->next; 685 } 686 PetscFunctionReturn(0); 687 } 688 689 /* -------------------------------------------------------------------------------------*/ 690 #undef __FUNCT__ 691 #define __FUNCT__ "DMCompositeGetLocalVectors" 692 /*@C 693 DMCompositeGetLocalVectors - Gets local vectors for each part of a DMComposite. 694 Use DMCompositeRestoreLocalVectors() to return them. 695 696 Not Collective 697 698 Input Parameter: 699 . dm - the packer object 700 701 Output Parameter: 702 . Vec ... - the individual sequential Vecs 703 704 Level: advanced 705 706 .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 707 DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 708 DMCompositeRestoreLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries() 709 710 @*/ 711 PetscErrorCode DMCompositeGetLocalVectors(DM dm,...) 712 { 713 va_list Argp; 714 PetscErrorCode ierr; 715 struct DMCompositeLink *next; 716 DM_Composite *com = (DM_Composite*)dm->data; 717 718 PetscFunctionBegin; 719 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 720 next = com->next; 721 /* loop over packed objects, handling one at at time */ 722 va_start(Argp,dm); 723 while (next) { 724 Vec *vec; 725 vec = va_arg(Argp, Vec*); 726 ierr = DMGetLocalVector(next->dm,vec);CHKERRQ(ierr); 727 next = next->next; 728 } 729 va_end(Argp); 730 PetscFunctionReturn(0); 731 } 732 733 #undef __FUNCT__ 734 #define __FUNCT__ "DMCompositeRestoreLocalVectors" 735 /*@C 736 DMCompositeRestoreLocalVectors - Restores local vectors for each part of a DMComposite. 737 738 Not Collective 739 740 Input Parameter: 741 . dm - the packer object 742 743 Output Parameter: 744 . Vec ... - the individual sequential Vecs 745 746 Level: advanced 747 748 .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 749 DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 750 DMCompositeGetLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries() 751 752 @*/ 753 PetscErrorCode DMCompositeRestoreLocalVectors(DM dm,...) 754 { 755 va_list Argp; 756 PetscErrorCode ierr; 757 struct DMCompositeLink *next; 758 DM_Composite *com = (DM_Composite*)dm->data; 759 760 PetscFunctionBegin; 761 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 762 next = com->next; 763 /* loop over packed objects, handling one at at time */ 764 va_start(Argp,dm); 765 while (next) { 766 Vec *vec; 767 vec = va_arg(Argp, Vec*); 768 ierr = DMRestoreLocalVector(next->dm,vec);CHKERRQ(ierr); 769 next = next->next; 770 } 771 va_end(Argp); 772 PetscFunctionReturn(0); 773 } 774 775 /* -------------------------------------------------------------------------------------*/ 776 #undef __FUNCT__ 777 #define __FUNCT__ "DMCompositeGetEntries" 778 /*@C 779 DMCompositeGetEntries - Gets the DM for each entry in a DMComposite. 780 781 Not Collective 782 783 Input Parameter: 784 . dm - the packer object 785 786 Output Parameter: 787 . DM ... - the individual entries (DMs) 788 789 Level: advanced 790 791 .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntriesArray() 792 DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 793 DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(), DMCompositeScatter(), 794 DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors() 795 796 @*/ 797 PetscErrorCode DMCompositeGetEntries(DM dm,...) 798 { 799 va_list Argp; 800 struct DMCompositeLink *next; 801 DM_Composite *com = (DM_Composite*)dm->data; 802 803 PetscFunctionBegin; 804 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 805 next = com->next; 806 /* loop over packed objects, handling one at at time */ 807 va_start(Argp,dm); 808 while (next) { 809 DM *dmn; 810 dmn = va_arg(Argp, DM*); 811 if (dmn) *dmn = next->dm; 812 next = next->next; 813 } 814 va_end(Argp); 815 PetscFunctionReturn(0); 816 } 817 818 #undef __FUNCT__ 819 #define __FUNCT__ "DMCompositeGetEntriesArray" 820 /*@ 821 DMCompositeGetEntriesArray - Gets the DM for each entry in a DMComposite. 822 823 Not Collective 824 825 Input Parameter: 826 + dm - the packer object 827 - dms - array of sufficient length (see DMCompositeGetNumberDM()), holds the DMs on output 828 829 Level: advanced 830 831 .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntries() 832 DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 833 DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(), DMCompositeScatter(), 834 DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors() 835 836 @*/ 837 PetscErrorCode DMCompositeGetEntriesArray(DM dm,DM dms[]) 838 { 839 struct DMCompositeLink *next; 840 DM_Composite *com = (DM_Composite*)dm->data; 841 PetscInt i; 842 843 PetscFunctionBegin; 844 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 845 /* loop over packed objects, handling one at at time */ 846 for (next=com->next,i=0; next; next=next->next,i++) dms[i] = next->dm; 847 PetscFunctionReturn(0); 848 } 849 850 #undef __FUNCT__ 851 #define __FUNCT__ "DMRefine_Composite" 852 PetscErrorCode DMRefine_Composite(DM dmi,MPI_Comm comm,DM *fine) 853 { 854 PetscErrorCode ierr; 855 struct DMCompositeLink *next; 856 DM_Composite *com = (DM_Composite*)dmi->data; 857 DM dm; 858 859 PetscFunctionBegin; 860 PetscValidHeaderSpecific(dmi,DM_CLASSID,1); 861 ierr = DMSetUp(dmi);CHKERRQ(ierr); 862 next = com->next; 863 ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr); 864 865 /* loop over packed objects, handling one at at time */ 866 while (next) { 867 ierr = DMRefine(next->dm,comm,&dm);CHKERRQ(ierr); 868 ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr); 869 ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr); 870 next = next->next; 871 } 872 PetscFunctionReturn(0); 873 } 874 875 #undef __FUNCT__ 876 #define __FUNCT__ "DMCoarsen_Composite" 877 PetscErrorCode DMCoarsen_Composite(DM dmi,MPI_Comm comm,DM *fine) 878 { 879 PetscErrorCode ierr; 880 struct DMCompositeLink *next; 881 DM_Composite *com = (DM_Composite*)dmi->data; 882 DM dm; 883 884 PetscFunctionBegin; 885 PetscValidHeaderSpecific(dmi,DM_CLASSID,1); 886 ierr = DMSetUp(dmi);CHKERRQ(ierr); 887 if (!comm) { 888 ierr = PetscObjectGetComm((PetscObject)dmi,&comm);CHKERRQ(ierr); 889 } 890 next = com->next; 891 ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr); 892 893 /* loop over packed objects, handling one at at time */ 894 while (next) { 895 ierr = DMCoarsen(next->dm,comm,&dm);CHKERRQ(ierr); 896 ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr); 897 ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr); 898 next = next->next; 899 } 900 PetscFunctionReturn(0); 901 } 902 903 #undef __FUNCT__ 904 #define __FUNCT__ "DMCreateInterpolation_Composite" 905 PetscErrorCode DMCreateInterpolation_Composite(DM coarse,DM fine,Mat *A,Vec *v) 906 { 907 PetscErrorCode ierr; 908 PetscInt m,n,M,N,nDM,i; 909 struct DMCompositeLink *nextc; 910 struct DMCompositeLink *nextf; 911 Vec gcoarse,gfine,*vecs; 912 DM_Composite *comcoarse = (DM_Composite*)coarse->data; 913 DM_Composite *comfine = (DM_Composite*)fine->data; 914 Mat *mats; 915 916 PetscFunctionBegin; 917 PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 918 PetscValidHeaderSpecific(fine,DM_CLASSID,2); 919 ierr = DMSetUp(coarse);CHKERRQ(ierr); 920 ierr = DMSetUp(fine);CHKERRQ(ierr); 921 /* use global vectors only for determining matrix layout */ 922 ierr = DMGetGlobalVector(coarse,&gcoarse);CHKERRQ(ierr); 923 ierr = DMGetGlobalVector(fine,&gfine);CHKERRQ(ierr); 924 ierr = VecGetLocalSize(gcoarse,&n);CHKERRQ(ierr); 925 ierr = VecGetLocalSize(gfine,&m);CHKERRQ(ierr); 926 ierr = VecGetSize(gcoarse,&N);CHKERRQ(ierr); 927 ierr = VecGetSize(gfine,&M);CHKERRQ(ierr); 928 ierr = DMRestoreGlobalVector(coarse,&gcoarse);CHKERRQ(ierr); 929 ierr = DMRestoreGlobalVector(fine,&gfine);CHKERRQ(ierr); 930 931 nDM = comfine->nDM; 932 if (nDM != comcoarse->nDM) SETERRQ2(((PetscObject)fine)->comm,PETSC_ERR_ARG_INCOMP,"Fine DMComposite has %D entries, but coarse has %D",nDM,comcoarse->nDM); 933 ierr = PetscMalloc(nDM*nDM*sizeof(Mat),&mats);CHKERRQ(ierr); 934 ierr = PetscMemzero(mats,nDM*nDM*sizeof(Mat));CHKERRQ(ierr); 935 if (v) { 936 ierr = PetscMalloc(nDM*sizeof(Vec),&vecs);CHKERRQ(ierr); 937 ierr = PetscMemzero(vecs,nDM*sizeof(Vec));CHKERRQ(ierr); 938 } 939 940 /* loop over packed objects, handling one at at time */ 941 for (nextc=comcoarse->next,nextf=comfine->next,i=0; nextc; nextc=nextc->next,nextf=nextf->next,i++) { 942 if (!v) { 943 ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],PETSC_NULL);CHKERRQ(ierr); 944 } else { 945 ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],&vecs[i]);CHKERRQ(ierr); 946 } 947 } 948 ierr = MatCreateNest(((PetscObject)fine)->comm,nDM,PETSC_NULL,nDM,PETSC_NULL,mats,A);CHKERRQ(ierr); 949 if (v) { 950 ierr = VecCreateNest(((PetscObject)fine)->comm,nDM,PETSC_NULL,vecs,v);CHKERRQ(ierr); 951 } 952 for (i=0; i<nDM*nDM; i++) {ierr = MatDestroy(&mats[i]);CHKERRQ(ierr);} 953 ierr = PetscFree(mats);CHKERRQ(ierr); 954 if (v) { 955 for (i=0; i<nDM; i++) {ierr = VecDestroy(&vecs[i]);CHKERRQ(ierr);} 956 ierr = PetscFree(vecs);CHKERRQ(ierr); 957 } 958 PetscFunctionReturn(0); 959 } 960 961 #undef __FUNCT__ 962 #define __FUNCT__ "DMCreateLocalToGlobalMapping_Composite" 963 static PetscErrorCode DMCreateLocalToGlobalMapping_Composite(DM dm) 964 { 965 DM_Composite *com = (DM_Composite*)dm->data; 966 ISLocalToGlobalMapping *ltogs; 967 PetscInt i; 968 PetscErrorCode ierr; 969 970 PetscFunctionBegin; 971 /* Set the ISLocalToGlobalMapping on the new matrix */ 972 ierr = DMCompositeGetISLocalToGlobalMappings(dm,<ogs);CHKERRQ(ierr); 973 ierr = ISLocalToGlobalMappingConcatenate(((PetscObject)dm)->comm,com->nDM,ltogs,&dm->ltogmap);CHKERRQ(ierr); 974 for (i=0; i<com->nDM; i++) {ierr = ISLocalToGlobalMappingDestroy(<ogs[i]);CHKERRQ(ierr);} 975 ierr = PetscFree(ltogs);CHKERRQ(ierr); 976 PetscFunctionReturn(0); 977 } 978 979 980 #undef __FUNCT__ 981 #define __FUNCT__ "DMCreateColoring_Composite" 982 PetscErrorCode DMCreateColoring_Composite(DM dm,ISColoringType ctype,const MatType mtype,ISColoring *coloring) 983 { 984 PetscErrorCode ierr; 985 PetscInt n,i,cnt; 986 ISColoringValue *colors; 987 PetscBool dense = PETSC_FALSE; 988 ISColoringValue maxcol = 0; 989 DM_Composite *com = (DM_Composite*)dm->data; 990 991 PetscFunctionBegin; 992 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 993 if (ctype == IS_COLORING_GHOSTED) { 994 SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Currently you must use -dmmg_iscoloring_type global" ); 995 } else if (ctype == IS_COLORING_GLOBAL) { 996 n = com->n; 997 } else SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Unknown ISColoringType"); 998 ierr = PetscMalloc(n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); /* freed in ISColoringDestroy() */ 999 1000 ierr = PetscOptionsGetBool(PETSC_NULL,"-dmcomposite_dense_jacobian",&dense,PETSC_NULL);CHKERRQ(ierr); 1001 if (dense) { 1002 for (i=0; i<n; i++) { 1003 colors[i] = (ISColoringValue)(com->rstart + i); 1004 } 1005 maxcol = com->N; 1006 } else { 1007 struct DMCompositeLink *next = com->next; 1008 PetscMPIInt rank; 1009 1010 ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 1011 cnt = 0; 1012 while (next) { 1013 ISColoring lcoloring; 1014 1015 ierr = DMCreateColoring(next->dm,IS_COLORING_GLOBAL,mtype,&lcoloring);CHKERRQ(ierr); 1016 for (i=0; i<lcoloring->N; i++) { 1017 colors[cnt++] = maxcol + lcoloring->colors[i]; 1018 } 1019 maxcol += lcoloring->n; 1020 ierr = ISColoringDestroy(&lcoloring);CHKERRQ(ierr); 1021 next = next->next; 1022 } 1023 } 1024 ierr = ISColoringCreate(((PetscObject)dm)->comm,maxcol,n,colors,coloring);CHKERRQ(ierr); 1025 PetscFunctionReturn(0); 1026 } 1027 1028 #undef __FUNCT__ 1029 #define __FUNCT__ "DMGlobalToLocalBegin_Composite" 1030 PetscErrorCode DMGlobalToLocalBegin_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec) 1031 { 1032 PetscErrorCode ierr; 1033 struct DMCompositeLink *next; 1034 PetscInt cnt = 3; 1035 PetscMPIInt rank; 1036 PetscScalar *garray,*larray; 1037 DM_Composite *com = (DM_Composite*)dm->data; 1038 1039 PetscFunctionBegin; 1040 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1041 PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 1042 next = com->next; 1043 if (!com->setup) { 1044 ierr = DMSetUp(dm);CHKERRQ(ierr); 1045 } 1046 ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); 1047 ierr = VecGetArray(gvec,&garray);CHKERRQ(ierr); 1048 ierr = VecGetArray(lvec,&larray);CHKERRQ(ierr); 1049 1050 /* loop over packed objects, handling one at at time */ 1051 while (next) { 1052 Vec local,global; 1053 PetscInt N; 1054 1055 ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 1056 ierr = VecGetLocalSize(global,&N);CHKERRQ(ierr); 1057 ierr = VecPlaceArray(global,garray);CHKERRQ(ierr); 1058 ierr = DMGetLocalVector(next->dm,&local);CHKERRQ(ierr); 1059 ierr = VecPlaceArray(local,larray);CHKERRQ(ierr); 1060 ierr = DMGlobalToLocalBegin(next->dm,global,mode,local);CHKERRQ(ierr); 1061 ierr = DMGlobalToLocalEnd(next->dm,global,mode,local);CHKERRQ(ierr); 1062 ierr = VecResetArray(global);CHKERRQ(ierr); 1063 ierr = VecResetArray(local);CHKERRQ(ierr); 1064 ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 1065 ierr = DMRestoreGlobalVector(next->dm,&local);CHKERRQ(ierr); 1066 cnt++; 1067 larray += next->nlocal; 1068 next = next->next; 1069 } 1070 1071 ierr = VecRestoreArray(gvec,PETSC_NULL);CHKERRQ(ierr); 1072 ierr = VecRestoreArray(lvec,PETSC_NULL);CHKERRQ(ierr); 1073 PetscFunctionReturn(0); 1074 } 1075 1076 #undef __FUNCT__ 1077 #define __FUNCT__ "DMGlobalToLocalEnd_Composite" 1078 PetscErrorCode DMGlobalToLocalEnd_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec) 1079 { 1080 PetscFunctionBegin; 1081 PetscFunctionReturn(0); 1082 } 1083 1084 EXTERN_C_BEGIN 1085 #undef __FUNCT__ 1086 #define __FUNCT__ "DMCreate_Composite" 1087 PetscErrorCode DMCreate_Composite(DM p) 1088 { 1089 PetscErrorCode ierr; 1090 DM_Composite *com; 1091 1092 PetscFunctionBegin; 1093 ierr = PetscNewLog(p,DM_Composite,&com);CHKERRQ(ierr); 1094 p->data = com; 1095 ierr = PetscObjectChangeTypeName((PetscObject)p,"DMComposite");CHKERRQ(ierr); 1096 com->n = 0; 1097 com->next = PETSC_NULL; 1098 com->nDM = 0; 1099 1100 p->ops->createglobalvector = DMCreateGlobalVector_Composite; 1101 p->ops->createlocalvector = DMCreateLocalVector_Composite; 1102 p->ops->createlocaltoglobalmapping = DMCreateLocalToGlobalMapping_Composite; 1103 p->ops->createlocaltoglobalmappingblock = 0; 1104 p->ops->refine = DMRefine_Composite; 1105 p->ops->coarsen = DMCoarsen_Composite; 1106 p->ops->createinterpolation = DMCreateInterpolation_Composite; 1107 p->ops->creatematrix = DMCreateMatrix_Composite; 1108 p->ops->getcoloring = DMCreateColoring_Composite; 1109 p->ops->globaltolocalbegin = DMGlobalToLocalBegin_Composite; 1110 p->ops->globaltolocalend = DMGlobalToLocalEnd_Composite; 1111 p->ops->destroy = DMDestroy_Composite; 1112 p->ops->view = DMView_Composite; 1113 p->ops->setup = DMSetUp_Composite; 1114 PetscFunctionReturn(0); 1115 } 1116 EXTERN_C_END 1117 1118 #undef __FUNCT__ 1119 #define __FUNCT__ "DMCompositeCreate" 1120 /*@C 1121 DMCompositeCreate - Creates a vector packer, used to generate "composite" 1122 vectors made up of several subvectors. 1123 1124 Collective on MPI_Comm 1125 1126 Input Parameter: 1127 . comm - the processors that will share the global vector 1128 1129 Output Parameters: 1130 . packer - the packer object 1131 1132 Level: advanced 1133 1134 .seealso DMDestroy(), DMCompositeAddDM(), DMCompositeScatter(), 1135 DMCompositeGather(), DMCreateGlobalVector(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess() 1136 DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 1137 1138 @*/ 1139 PetscErrorCode DMCompositeCreate(MPI_Comm comm,DM *packer) 1140 { 1141 PetscErrorCode ierr; 1142 1143 PetscFunctionBegin; 1144 PetscValidPointer(packer,2); 1145 ierr = DMCreate(comm,packer);CHKERRQ(ierr); 1146 ierr = DMSetType(*packer,DMCOMPOSITE);CHKERRQ(ierr); 1147 PetscFunctionReturn(0); 1148 } 1149