1 2 #include <../src/dm/impls/composite/packimpl.h> /*I "petscdmcomposite.h" I*/ 3 #include <petsc/private/isimpl.h> 4 #include <petsc/private/glvisviewerimpl.h> 5 #include <petscds.h> 6 7 /*@C 8 DMCompositeSetCoupling - Sets user provided routines that compute the coupling between the 9 separate components (DMs) in a DMto build the correct matrix nonzero structure. 10 11 12 Logically Collective on MPI_Comm 13 14 Input Parameter: 15 + dm - the composite object 16 - formcouplelocations - routine to set the nonzero locations in the matrix 17 18 Level: advanced 19 20 Not available from Fortran 21 22 Notes: 23 See DMSetApplicationContext() and DMGetApplicationContext() for how to get user information into 24 this routine 25 26 @*/ 27 PetscErrorCode DMCompositeSetCoupling(DM dm,PetscErrorCode (*FormCoupleLocations)(DM,Mat,PetscInt*,PetscInt*,PetscInt,PetscInt,PetscInt,PetscInt)) 28 { 29 DM_Composite *com = (DM_Composite*)dm->data; 30 PetscBool flg; 31 PetscErrorCode ierr; 32 33 PetscFunctionBegin; 34 ierr = PetscObjectTypeCompare((PetscObject)dm,DMCOMPOSITE,&flg);CHKERRQ(ierr); 35 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 36 com->FormCoupleLocations = FormCoupleLocations; 37 PetscFunctionReturn(0); 38 } 39 40 PetscErrorCode DMDestroy_Composite(DM dm) 41 { 42 PetscErrorCode ierr; 43 struct DMCompositeLink *next, *prev; 44 DM_Composite *com = (DM_Composite*)dm->data; 45 46 PetscFunctionBegin; 47 next = com->next; 48 while (next) { 49 prev = next; 50 next = next->next; 51 ierr = DMDestroy(&prev->dm);CHKERRQ(ierr); 52 ierr = PetscFree(prev->grstarts);CHKERRQ(ierr); 53 ierr = PetscFree(prev);CHKERRQ(ierr); 54 } 55 ierr = PetscObjectComposeFunction((PetscObject)dm,"DMSetUpGLVisViewer_C",NULL);CHKERRQ(ierr); 56 /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */ 57 ierr = PetscFree(com);CHKERRQ(ierr); 58 PetscFunctionReturn(0); 59 } 60 61 PetscErrorCode DMView_Composite(DM dm,PetscViewer v) 62 { 63 PetscErrorCode ierr; 64 PetscBool iascii; 65 DM_Composite *com = (DM_Composite*)dm->data; 66 67 PetscFunctionBegin; 68 ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 69 if (iascii) { 70 struct DMCompositeLink *lnk = com->next; 71 PetscInt i; 72 73 ierr = PetscViewerASCIIPrintf(v,"DM (%s)\n",((PetscObject)dm)->prefix ? ((PetscObject)dm)->prefix : "no prefix");CHKERRQ(ierr); 74 ierr = PetscViewerASCIIPrintf(v," contains %D DMs\n",com->nDM);CHKERRQ(ierr); 75 ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr); 76 for (i=0; lnk; lnk=lnk->next,i++) { 77 ierr = PetscViewerASCIIPrintf(v,"Link %D: DM of type %s\n",i,((PetscObject)lnk->dm)->type_name);CHKERRQ(ierr); 78 ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr); 79 ierr = DMView(lnk->dm,v);CHKERRQ(ierr); 80 ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr); 81 } 82 ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr); 83 } 84 PetscFunctionReturn(0); 85 } 86 87 /* --------------------------------------------------------------------------------------*/ 88 PetscErrorCode DMSetUp_Composite(DM dm) 89 { 90 PetscErrorCode ierr; 91 PetscInt nprev = 0; 92 PetscMPIInt rank,size; 93 DM_Composite *com = (DM_Composite*)dm->data; 94 struct DMCompositeLink *next = com->next; 95 PetscLayout map; 96 97 PetscFunctionBegin; 98 if (com->setup) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Packer has already been setup"); 99 ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)dm),&map);CHKERRQ(ierr); 100 ierr = PetscLayoutSetLocalSize(map,com->n);CHKERRQ(ierr); 101 ierr = PetscLayoutSetSize(map,PETSC_DETERMINE);CHKERRQ(ierr); 102 ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 103 ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 104 ierr = PetscLayoutGetSize(map,&com->N);CHKERRQ(ierr); 105 ierr = PetscLayoutGetRange(map,&com->rstart,NULL);CHKERRQ(ierr); 106 ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 107 108 /* now set the rstart for each linked vector */ 109 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 110 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&size);CHKERRQ(ierr); 111 while (next) { 112 next->rstart = nprev; 113 nprev += next->n; 114 next->grstart = com->rstart + next->rstart; 115 ierr = PetscMalloc1(size,&next->grstarts);CHKERRQ(ierr); 116 ierr = MPI_Allgather(&next->grstart,1,MPIU_INT,next->grstarts,1,MPIU_INT,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 117 next = next->next; 118 } 119 com->setup = PETSC_TRUE; 120 PetscFunctionReturn(0); 121 } 122 123 /* ----------------------------------------------------------------------------------*/ 124 125 /*@ 126 DMCompositeGetNumberDM - Get's the number of DM objects in the DMComposite 127 representation. 128 129 Not Collective 130 131 Input Parameter: 132 . dm - the packer object 133 134 Output Parameter: 135 . nDM - the number of DMs 136 137 Level: beginner 138 139 @*/ 140 PetscErrorCode DMCompositeGetNumberDM(DM dm,PetscInt *nDM) 141 { 142 DM_Composite *com = (DM_Composite*)dm->data; 143 PetscBool flg; 144 PetscErrorCode ierr; 145 146 PetscFunctionBegin; 147 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 148 ierr = PetscObjectTypeCompare((PetscObject)dm,DMCOMPOSITE,&flg);CHKERRQ(ierr); 149 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 150 *nDM = com->nDM; 151 PetscFunctionReturn(0); 152 } 153 154 155 /*@C 156 DMCompositeGetAccess - Allows one to access the individual packed vectors in their global 157 representation. 158 159 Collective on DMComposite 160 161 Input Parameters: 162 + dm - the packer object 163 - gvec - the global vector 164 165 Output Parameters: 166 . Vec* ... - the packed parallel vectors, NULL for those that are not needed 167 168 Notes: 169 Use DMCompositeRestoreAccess() to return the vectors when you no longer need them 170 171 Fortran Notes: 172 173 Fortran callers must use numbered versions of this routine, e.g., DMCompositeGetAccess4(dm,gvec,vec1,vec2,vec3,vec4) 174 or use the alternative interface DMCompositeGetAccessArray(). 175 176 Level: advanced 177 178 .seealso: DMCompositeGetEntries(), DMCompositeScatter() 179 @*/ 180 PetscErrorCode DMCompositeGetAccess(DM dm,Vec gvec,...) 181 { 182 va_list Argp; 183 PetscErrorCode ierr; 184 struct DMCompositeLink *next; 185 DM_Composite *com = (DM_Composite*)dm->data; 186 PetscInt readonly; 187 PetscBool flg; 188 189 PetscFunctionBegin; 190 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 191 PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 192 ierr = PetscObjectTypeCompare((PetscObject)dm,DMCOMPOSITE,&flg);CHKERRQ(ierr); 193 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 194 next = com->next; 195 if (!com->setup) { 196 ierr = DMSetUp(dm);CHKERRQ(ierr); 197 } 198 199 ierr = VecLockGet(gvec,&readonly);CHKERRQ(ierr); 200 /* loop over packed objects, handling one at at time */ 201 va_start(Argp,gvec); 202 while (next) { 203 Vec *vec; 204 vec = va_arg(Argp, Vec*); 205 if (vec) { 206 ierr = DMGetGlobalVector(next->dm,vec);CHKERRQ(ierr); 207 if (readonly) { 208 const PetscScalar *array; 209 ierr = VecGetArrayRead(gvec,&array);CHKERRQ(ierr); 210 ierr = VecPlaceArray(*vec,array+next->rstart);CHKERRQ(ierr); 211 ierr = VecLockPush(*vec);CHKERRQ(ierr); 212 ierr = VecRestoreArrayRead(gvec,&array);CHKERRQ(ierr); 213 } else { 214 PetscScalar *array; 215 ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 216 ierr = VecPlaceArray(*vec,array+next->rstart);CHKERRQ(ierr); 217 ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 218 } 219 } 220 next = next->next; 221 } 222 va_end(Argp); 223 PetscFunctionReturn(0); 224 } 225 226 /*@C 227 DMCompositeGetAccessArray - Allows one to access the individual packed vectors in their global 228 representation. 229 230 Collective on DMComposite 231 232 Input Parameters: 233 + dm - the packer object 234 . pvec - packed vector 235 . nwanted - number of vectors wanted 236 - wanted - sorted array of vectors wanted, or NULL to get all vectors 237 238 Output Parameters: 239 . vecs - array of requested global vectors (must be allocated) 240 241 Notes: 242 Use DMCompositeRestoreAccessArray() to return the vectors when you no longer need them 243 244 Level: advanced 245 246 .seealso: DMCompositeGetAccess(), DMCompositeGetEntries(), DMCompositeScatter(), DMCompositeGather() 247 @*/ 248 PetscErrorCode DMCompositeGetAccessArray(DM dm,Vec pvec,PetscInt nwanted,const PetscInt *wanted,Vec *vecs) 249 { 250 PetscErrorCode ierr; 251 struct DMCompositeLink *link; 252 PetscInt i,wnum; 253 DM_Composite *com = (DM_Composite*)dm->data; 254 PetscInt readonly; 255 PetscBool flg; 256 257 PetscFunctionBegin; 258 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 259 PetscValidHeaderSpecific(pvec,VEC_CLASSID,2); 260 ierr = PetscObjectTypeCompare((PetscObject)dm,DMCOMPOSITE,&flg);CHKERRQ(ierr); 261 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 262 if (!com->setup) { 263 ierr = DMSetUp(dm);CHKERRQ(ierr); 264 } 265 266 ierr = VecLockGet(pvec,&readonly);CHKERRQ(ierr); 267 for (i=0,wnum=0,link=com->next; link && wnum<nwanted; i++,link=link->next) { 268 if (!wanted || i == wanted[wnum]) { 269 Vec v; 270 ierr = DMGetGlobalVector(link->dm,&v);CHKERRQ(ierr); 271 if (readonly) { 272 const PetscScalar *array; 273 ierr = VecGetArrayRead(pvec,&array);CHKERRQ(ierr); 274 ierr = VecPlaceArray(v,array+link->rstart);CHKERRQ(ierr); 275 ierr = VecLockPush(v);CHKERRQ(ierr); 276 ierr = VecRestoreArrayRead(pvec,&array);CHKERRQ(ierr); 277 } else { 278 PetscScalar *array; 279 ierr = VecGetArray(pvec,&array);CHKERRQ(ierr); 280 ierr = VecPlaceArray(v,array+link->rstart);CHKERRQ(ierr); 281 ierr = VecRestoreArray(pvec,&array);CHKERRQ(ierr); 282 } 283 vecs[wnum++] = v; 284 } 285 } 286 PetscFunctionReturn(0); 287 } 288 289 /*@C 290 DMCompositeGetLocalAccessArray - Allows one to access the individual 291 packed vectors in their local representation. 292 293 Collective on DMComposite. 294 295 Input Parameters: 296 + dm - the packer object 297 . pvec - packed vector 298 . nwanted - number of vectors wanted 299 - wanted - sorted array of vectors wanted, or NULL to get all vectors 300 301 Output Parameters: 302 . vecs - array of requested local vectors (must be allocated) 303 304 Notes: 305 Use DMCompositeRestoreLocalAccessArray() to return the vectors 306 when you no longer need them. 307 308 Level: advanced 309 310 .seealso: DMCompositeRestoreLocalAccessArray(), DMCompositeGetAccess(), 311 DMCompositeGetEntries(), DMCompositeScatter(), DMCompositeGather() 312 @*/ 313 PetscErrorCode DMCompositeGetLocalAccessArray(DM dm,Vec pvec,PetscInt nwanted,const PetscInt *wanted,Vec *vecs) 314 { 315 PetscErrorCode ierr; 316 struct DMCompositeLink *link; 317 PetscInt i,wnum; 318 DM_Composite *com = (DM_Composite*)dm->data; 319 PetscInt readonly; 320 PetscInt nlocal = 0; 321 PetscBool flg; 322 323 PetscFunctionBegin; 324 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 325 PetscValidHeaderSpecific(pvec,VEC_CLASSID,2); 326 ierr = PetscObjectTypeCompare((PetscObject)dm,DMCOMPOSITE,&flg);CHKERRQ(ierr); 327 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 328 if (!com->setup) { 329 ierr = DMSetUp(dm);CHKERRQ(ierr); 330 } 331 332 ierr = VecLockGet(pvec,&readonly);CHKERRQ(ierr); 333 for (i=0,wnum=0,link=com->next; link && wnum<nwanted; i++,link=link->next) { 334 if (!wanted || i == wanted[wnum]) { 335 Vec v; 336 ierr = DMGetLocalVector(link->dm,&v);CHKERRQ(ierr); 337 if (readonly) { 338 const PetscScalar *array; 339 ierr = VecGetArrayRead(pvec,&array);CHKERRQ(ierr); 340 ierr = VecPlaceArray(v,array+nlocal);CHKERRQ(ierr); 341 ierr = VecLockPush(v);CHKERRQ(ierr); 342 ierr = VecRestoreArrayRead(pvec,&array);CHKERRQ(ierr); 343 } else { 344 PetscScalar *array; 345 ierr = VecGetArray(pvec,&array);CHKERRQ(ierr); 346 ierr = VecPlaceArray(v,array+nlocal);CHKERRQ(ierr); 347 ierr = VecRestoreArray(pvec,&array);CHKERRQ(ierr); 348 } 349 vecs[wnum++] = v; 350 } 351 352 nlocal += link->nlocal; 353 } 354 355 PetscFunctionReturn(0); 356 } 357 358 /*@C 359 DMCompositeRestoreAccess - Returns the vectors obtained with DMCompositeGetAccess() 360 representation. 361 362 Collective on DMComposite 363 364 Input Parameters: 365 + dm - the packer object 366 . gvec - the global vector 367 - Vec* ... - the individual parallel vectors, NULL for those that are not needed 368 369 Level: advanced 370 371 .seealso DMCompositeAddDM(), DMCreateGlobalVector(), 372 DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeScatter(), 373 DMCompositeRestoreAccess(), DMCompositeGetAccess() 374 375 @*/ 376 PetscErrorCode DMCompositeRestoreAccess(DM dm,Vec gvec,...) 377 { 378 va_list Argp; 379 PetscErrorCode ierr; 380 struct DMCompositeLink *next; 381 DM_Composite *com = (DM_Composite*)dm->data; 382 PetscInt readonly; 383 PetscBool flg; 384 385 PetscFunctionBegin; 386 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 387 PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 388 ierr = PetscObjectTypeCompare((PetscObject)dm,DMCOMPOSITE,&flg);CHKERRQ(ierr); 389 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 390 next = com->next; 391 if (!com->setup) { 392 ierr = DMSetUp(dm);CHKERRQ(ierr); 393 } 394 395 ierr = VecLockGet(gvec,&readonly);CHKERRQ(ierr); 396 /* loop over packed objects, handling one at at time */ 397 va_start(Argp,gvec); 398 while (next) { 399 Vec *vec; 400 vec = va_arg(Argp, Vec*); 401 if (vec) { 402 ierr = VecResetArray(*vec);CHKERRQ(ierr); 403 if (readonly) { 404 ierr = VecLockPop(*vec);CHKERRQ(ierr); 405 } 406 ierr = DMRestoreGlobalVector(next->dm,vec);CHKERRQ(ierr); 407 } 408 next = next->next; 409 } 410 va_end(Argp); 411 PetscFunctionReturn(0); 412 } 413 414 /*@C 415 DMCompositeRestoreAccessArray - Returns the vectors obtained with DMCompositeGetAccessArray() 416 417 Collective on DMComposite 418 419 Input Parameters: 420 + dm - the packer object 421 . pvec - packed vector 422 . nwanted - number of vectors wanted 423 . wanted - sorted array of vectors wanted, or NULL to get all vectors 424 - vecs - array of global vectors to return 425 426 Level: advanced 427 428 .seealso: DMCompositeRestoreAccess(), DMCompositeRestoreEntries(), DMCompositeScatter(), DMCompositeGather() 429 @*/ 430 PetscErrorCode DMCompositeRestoreAccessArray(DM dm,Vec pvec,PetscInt nwanted,const PetscInt *wanted,Vec *vecs) 431 { 432 PetscErrorCode ierr; 433 struct DMCompositeLink *link; 434 PetscInt i,wnum; 435 DM_Composite *com = (DM_Composite*)dm->data; 436 PetscInt readonly; 437 PetscBool flg; 438 439 PetscFunctionBegin; 440 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 441 PetscValidHeaderSpecific(pvec,VEC_CLASSID,2); 442 ierr = PetscObjectTypeCompare((PetscObject)dm,DMCOMPOSITE,&flg);CHKERRQ(ierr); 443 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 444 if (!com->setup) { 445 ierr = DMSetUp(dm);CHKERRQ(ierr); 446 } 447 448 ierr = VecLockGet(pvec,&readonly);CHKERRQ(ierr); 449 for (i=0,wnum=0,link=com->next; link && wnum<nwanted; i++,link=link->next) { 450 if (!wanted || i == wanted[wnum]) { 451 ierr = VecResetArray(vecs[wnum]);CHKERRQ(ierr); 452 if (readonly) { 453 ierr = VecLockPop(vecs[wnum]);CHKERRQ(ierr); 454 } 455 ierr = DMRestoreGlobalVector(link->dm,&vecs[wnum]);CHKERRQ(ierr); 456 wnum++; 457 } 458 } 459 PetscFunctionReturn(0); 460 } 461 462 /*@C 463 DMCompositeRestoreLocalAccessArray - Returns the vectors obtained with DMCompositeGetLocalAccessArray(). 464 465 Collective on DMComposite. 466 467 Input Parameters: 468 + dm - the packer object 469 . pvec - packed vector 470 . nwanted - number of vectors wanted 471 . wanted - sorted array of vectors wanted, or NULL to restore all vectors 472 - vecs - array of local vectors to return 473 474 Level: advanced 475 476 Notes: 477 nwanted and wanted must match the values given to DMCompositeGetLocalAccessArray() 478 otherwise the call will fail. 479 480 .seealso: DMCompositeGetLocalAccessArray(), DMCompositeRestoreAccessArray(), 481 DMCompositeRestoreAccess(), DMCompositeRestoreEntries(), 482 DMCompositeScatter(), DMCompositeGather() 483 @*/ 484 PetscErrorCode DMCompositeRestoreLocalAccessArray(DM dm,Vec pvec,PetscInt nwanted,const PetscInt *wanted,Vec *vecs) 485 { 486 PetscErrorCode ierr; 487 struct DMCompositeLink *link; 488 PetscInt i,wnum; 489 DM_Composite *com = (DM_Composite*)dm->data; 490 PetscInt readonly; 491 PetscBool flg; 492 493 PetscFunctionBegin; 494 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 495 PetscValidHeaderSpecific(pvec,VEC_CLASSID,2); 496 ierr = PetscObjectTypeCompare((PetscObject)dm,DMCOMPOSITE,&flg);CHKERRQ(ierr); 497 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 498 if (!com->setup) { 499 ierr = DMSetUp(dm);CHKERRQ(ierr); 500 } 501 502 ierr = VecLockGet(pvec,&readonly);CHKERRQ(ierr); 503 for (i=0,wnum=0,link=com->next; link && wnum<nwanted; i++,link=link->next) { 504 if (!wanted || i == wanted[wnum]) { 505 ierr = VecResetArray(vecs[wnum]);CHKERRQ(ierr); 506 if (readonly) { 507 ierr = VecLockPop(vecs[wnum]);CHKERRQ(ierr); 508 } 509 ierr = DMRestoreLocalVector(link->dm,&vecs[wnum]);CHKERRQ(ierr); 510 wnum++; 511 } 512 } 513 PetscFunctionReturn(0); 514 } 515 516 /*@C 517 DMCompositeScatter - Scatters from a global packed vector into its individual local vectors 518 519 Collective on DMComposite 520 521 Input Parameters: 522 + dm - the packer object 523 . gvec - the global vector 524 - Vec ... - the individual sequential vectors, NULL for those that are not needed 525 526 Level: advanced 527 528 Notes: 529 DMCompositeScatterArray() is a non-variadic alternative that is often more convenient for library callers and is 530 accessible from Fortran. 531 532 .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 533 DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 534 DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 535 DMCompositeScatterArray() 536 537 @*/ 538 PetscErrorCode DMCompositeScatter(DM dm,Vec gvec,...) 539 { 540 va_list Argp; 541 PetscErrorCode ierr; 542 struct DMCompositeLink *next; 543 PetscInt cnt; 544 DM_Composite *com = (DM_Composite*)dm->data; 545 PetscBool flg; 546 547 PetscFunctionBegin; 548 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 549 PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 550 ierr = PetscObjectTypeCompare((PetscObject)dm,DMCOMPOSITE,&flg);CHKERRQ(ierr); 551 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 552 if (!com->setup) { 553 ierr = DMSetUp(dm);CHKERRQ(ierr); 554 } 555 556 /* loop over packed objects, handling one at at time */ 557 va_start(Argp,gvec); 558 for (cnt=3,next=com->next; next; cnt++,next=next->next) { 559 Vec local; 560 local = va_arg(Argp, Vec); 561 if (local) { 562 Vec global; 563 const PetscScalar *array; 564 PetscValidHeaderSpecific(local,VEC_CLASSID,cnt); 565 ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 566 ierr = VecGetArrayRead(gvec,&array);CHKERRQ(ierr); 567 ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr); 568 ierr = DMGlobalToLocalBegin(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr); 569 ierr = DMGlobalToLocalEnd(next->dm,global,INSERT_VALUES,local);CHKERRQ(ierr); 570 ierr = VecRestoreArrayRead(gvec,&array);CHKERRQ(ierr); 571 ierr = VecResetArray(global);CHKERRQ(ierr); 572 ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 573 } 574 } 575 va_end(Argp); 576 PetscFunctionReturn(0); 577 } 578 579 /*@ 580 DMCompositeScatterArray - Scatters from a global packed vector into its individual local vectors 581 582 Collective on DMComposite 583 584 Input Parameters: 585 + dm - the packer object 586 . gvec - the global vector 587 . lvecs - array of local vectors, NULL for any that are not needed 588 589 Level: advanced 590 591 Note: 592 This is a non-variadic alternative to DMCompositeScatter() 593 594 .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector() 595 DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 596 DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 597 598 @*/ 599 PetscErrorCode DMCompositeScatterArray(DM dm,Vec gvec,Vec *lvecs) 600 { 601 PetscErrorCode ierr; 602 struct DMCompositeLink *next; 603 PetscInt i; 604 DM_Composite *com = (DM_Composite*)dm->data; 605 PetscBool flg; 606 607 PetscFunctionBegin; 608 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 609 PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 610 ierr = PetscObjectTypeCompare((PetscObject)dm,DMCOMPOSITE,&flg);CHKERRQ(ierr); 611 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 612 if (!com->setup) { 613 ierr = DMSetUp(dm);CHKERRQ(ierr); 614 } 615 616 /* loop over packed objects, handling one at at time */ 617 for (i=0,next=com->next; next; next=next->next,i++) { 618 if (lvecs[i]) { 619 Vec global; 620 const PetscScalar *array; 621 PetscValidHeaderSpecific(lvecs[i],VEC_CLASSID,3); 622 ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 623 ierr = VecGetArrayRead(gvec,&array);CHKERRQ(ierr); 624 ierr = VecPlaceArray(global,(PetscScalar*)array+next->rstart);CHKERRQ(ierr); 625 ierr = DMGlobalToLocalBegin(next->dm,global,INSERT_VALUES,lvecs[i]);CHKERRQ(ierr); 626 ierr = DMGlobalToLocalEnd(next->dm,global,INSERT_VALUES,lvecs[i]);CHKERRQ(ierr); 627 ierr = VecRestoreArrayRead(gvec,&array);CHKERRQ(ierr); 628 ierr = VecResetArray(global);CHKERRQ(ierr); 629 ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 630 } 631 } 632 PetscFunctionReturn(0); 633 } 634 635 /*@C 636 DMCompositeGather - Gathers into a global packed vector from its individual local vectors 637 638 Collective on DMComposite 639 640 Input Parameter: 641 + dm - the packer object 642 . gvec - the global vector 643 . imode - INSERT_VALUES or ADD_VALUES 644 - Vec ... - the individual sequential vectors, NULL for any that are not needed 645 646 Level: advanced 647 648 Not available from Fortran, Fortran users can use DMCompositeGatherArray() 649 650 .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 651 DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 652 DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 653 654 @*/ 655 PetscErrorCode DMCompositeGather(DM dm,InsertMode imode,Vec gvec,...) 656 { 657 va_list Argp; 658 PetscErrorCode ierr; 659 struct DMCompositeLink *next; 660 DM_Composite *com = (DM_Composite*)dm->data; 661 PetscInt cnt; 662 PetscBool flg; 663 664 PetscFunctionBegin; 665 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 666 PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 667 ierr = PetscObjectTypeCompare((PetscObject)dm,DMCOMPOSITE,&flg);CHKERRQ(ierr); 668 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 669 if (!com->setup) { 670 ierr = DMSetUp(dm);CHKERRQ(ierr); 671 } 672 673 /* loop over packed objects, handling one at at time */ 674 va_start(Argp,gvec); 675 for (cnt=3,next=com->next; next; cnt++,next=next->next) { 676 Vec local; 677 local = va_arg(Argp, Vec); 678 if (local) { 679 PetscScalar *array; 680 Vec global; 681 PetscValidHeaderSpecific(local,VEC_CLASSID,cnt); 682 ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 683 ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 684 ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr); 685 ierr = DMLocalToGlobalBegin(next->dm,local,imode,global);CHKERRQ(ierr); 686 ierr = DMLocalToGlobalEnd(next->dm,local,imode,global);CHKERRQ(ierr); 687 ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 688 ierr = VecResetArray(global);CHKERRQ(ierr); 689 ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 690 } 691 } 692 va_end(Argp); 693 PetscFunctionReturn(0); 694 } 695 696 /*@ 697 DMCompositeGatherArray - Gathers into a global packed vector from its individual local vectors 698 699 Collective on DMComposite 700 701 Input Parameter: 702 + dm - the packer object 703 . gvec - the global vector 704 . imode - INSERT_VALUES or ADD_VALUES 705 - lvecs - the individual sequential vectors, NULL for any that are not needed 706 707 Level: advanced 708 709 Notes: 710 This is a non-variadic alternative to DMCompositeGather(). 711 712 .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 713 DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 714 DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries(), 715 @*/ 716 PetscErrorCode DMCompositeGatherArray(DM dm,InsertMode imode,Vec gvec,Vec *lvecs) 717 { 718 PetscErrorCode ierr; 719 struct DMCompositeLink *next; 720 DM_Composite *com = (DM_Composite*)dm->data; 721 PetscInt i; 722 PetscBool flg; 723 724 PetscFunctionBegin; 725 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 726 PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 727 ierr = PetscObjectTypeCompare((PetscObject)dm,DMCOMPOSITE,&flg);CHKERRQ(ierr); 728 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 729 if (!com->setup) { 730 ierr = DMSetUp(dm);CHKERRQ(ierr); 731 } 732 733 /* loop over packed objects, handling one at at time */ 734 for (next=com->next,i=0; next; next=next->next,i++) { 735 if (lvecs[i]) { 736 PetscScalar *array; 737 Vec global; 738 PetscValidHeaderSpecific(lvecs[i],VEC_CLASSID,3); 739 ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 740 ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); 741 ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr); 742 ierr = DMLocalToGlobalBegin(next->dm,lvecs[i],imode,global);CHKERRQ(ierr); 743 ierr = DMLocalToGlobalEnd(next->dm,lvecs[i],imode,global);CHKERRQ(ierr); 744 ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); 745 ierr = VecResetArray(global);CHKERRQ(ierr); 746 ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 747 } 748 } 749 PetscFunctionReturn(0); 750 } 751 752 /*@ 753 DMCompositeAddDM - adds a DM vector to a DMComposite 754 755 Collective on DMComposite 756 757 Input Parameter: 758 + dmc - the DMComposite (packer) object 759 - dm - the DM object 760 761 Level: advanced 762 763 .seealso DMDestroy(), DMCompositeGather(), DMCompositeAddDM(), DMCreateGlobalVector(), 764 DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 765 DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 766 767 @*/ 768 PetscErrorCode DMCompositeAddDM(DM dmc,DM dm) 769 { 770 PetscErrorCode ierr; 771 PetscInt n,nlocal; 772 struct DMCompositeLink *mine,*next; 773 Vec global,local; 774 DM_Composite *com = (DM_Composite*)dmc->data; 775 PetscBool flg; 776 777 PetscFunctionBegin; 778 PetscValidHeaderSpecific(dmc,DM_CLASSID,1); 779 PetscValidHeaderSpecific(dm,DM_CLASSID,2); 780 ierr = PetscObjectTypeCompare((PetscObject)dmc,DMCOMPOSITE,&flg);CHKERRQ(ierr); 781 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 782 next = com->next; 783 if (com->setup) SETERRQ(PetscObjectComm((PetscObject)dmc),PETSC_ERR_ARG_WRONGSTATE,"Cannot add a DM once you have used the DMComposite"); 784 785 /* create new link */ 786 ierr = PetscNew(&mine);CHKERRQ(ierr); 787 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 788 ierr = DMGetGlobalVector(dm,&global);CHKERRQ(ierr); 789 ierr = VecGetLocalSize(global,&n);CHKERRQ(ierr); 790 ierr = DMRestoreGlobalVector(dm,&global);CHKERRQ(ierr); 791 ierr = DMGetLocalVector(dm,&local);CHKERRQ(ierr); 792 ierr = VecGetSize(local,&nlocal);CHKERRQ(ierr); 793 ierr = DMRestoreLocalVector(dm,&local);CHKERRQ(ierr); 794 795 mine->n = n; 796 mine->nlocal = nlocal; 797 mine->dm = dm; 798 mine->next = NULL; 799 com->n += n; 800 com->nghost += nlocal; 801 802 /* add to end of list */ 803 if (!next) com->next = mine; 804 else { 805 while (next->next) next = next->next; 806 next->next = mine; 807 } 808 com->nDM++; 809 com->nmine++; 810 PetscFunctionReturn(0); 811 } 812 813 #include <petscdraw.h> 814 PETSC_EXTERN PetscErrorCode VecView_MPI(Vec,PetscViewer); 815 PetscErrorCode VecView_DMComposite(Vec gvec,PetscViewer viewer) 816 { 817 DM dm; 818 PetscErrorCode ierr; 819 struct DMCompositeLink *next; 820 PetscBool isdraw; 821 DM_Composite *com; 822 823 PetscFunctionBegin; 824 ierr = VecGetDM(gvec, &dm);CHKERRQ(ierr); 825 if (!dm) SETERRQ(PetscObjectComm((PetscObject)gvec),PETSC_ERR_ARG_WRONG,"Vector not generated from a DMComposite"); 826 com = (DM_Composite*)dm->data; 827 next = com->next; 828 829 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 830 if (!isdraw) { 831 /* do I really want to call this? */ 832 ierr = VecView_MPI(gvec,viewer);CHKERRQ(ierr); 833 } else { 834 PetscInt cnt = 0; 835 836 /* loop over packed objects, handling one at at time */ 837 while (next) { 838 Vec vec; 839 const PetscScalar *array; 840 PetscInt bs; 841 842 /* Should use VecGetSubVector() eventually, but would need to forward the DM for that to work */ 843 ierr = DMGetGlobalVector(next->dm,&vec);CHKERRQ(ierr); 844 ierr = VecGetArrayRead(gvec,&array);CHKERRQ(ierr); 845 ierr = VecPlaceArray(vec,(PetscScalar*)array+next->rstart);CHKERRQ(ierr); 846 ierr = VecRestoreArrayRead(gvec,&array);CHKERRQ(ierr); 847 ierr = VecView(vec,viewer);CHKERRQ(ierr); 848 ierr = VecResetArray(vec);CHKERRQ(ierr); 849 ierr = VecGetBlockSize(vec,&bs);CHKERRQ(ierr); 850 ierr = DMRestoreGlobalVector(next->dm,&vec);CHKERRQ(ierr); 851 ierr = PetscViewerDrawBaseAdd(viewer,bs);CHKERRQ(ierr); 852 cnt += bs; 853 next = next->next; 854 } 855 ierr = PetscViewerDrawBaseAdd(viewer,-cnt);CHKERRQ(ierr); 856 } 857 PetscFunctionReturn(0); 858 } 859 860 PetscErrorCode DMCreateGlobalVector_Composite(DM dm,Vec *gvec) 861 { 862 PetscErrorCode ierr; 863 DM_Composite *com = (DM_Composite*)dm->data; 864 865 PetscFunctionBegin; 866 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 867 ierr = DMSetUp(dm);CHKERRQ(ierr); 868 ierr = VecCreateMPI(PetscObjectComm((PetscObject)dm),com->n,com->N,gvec);CHKERRQ(ierr); 869 ierr = VecSetDM(*gvec, dm);CHKERRQ(ierr); 870 ierr = VecSetOperation(*gvec,VECOP_VIEW,(void (*)(void))VecView_DMComposite);CHKERRQ(ierr); 871 PetscFunctionReturn(0); 872 } 873 874 PetscErrorCode DMCreateLocalVector_Composite(DM dm,Vec *lvec) 875 { 876 PetscErrorCode ierr; 877 DM_Composite *com = (DM_Composite*)dm->data; 878 879 PetscFunctionBegin; 880 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 881 if (!com->setup) { 882 ierr = DMSetUp(dm);CHKERRQ(ierr); 883 } 884 ierr = VecCreateSeq(PETSC_COMM_SELF,com->nghost,lvec);CHKERRQ(ierr); 885 ierr = VecSetDM(*lvec, dm);CHKERRQ(ierr); 886 PetscFunctionReturn(0); 887 } 888 889 /*@C 890 DMCompositeGetISLocalToGlobalMappings - gets an ISLocalToGlobalMapping for each DM in the DMComposite, maps to the composite global space 891 892 Collective on DM 893 894 Input Parameter: 895 . dm - the packer object 896 897 Output Parameters: 898 . ltogs - the individual mappings for each packed vector. Note that this includes 899 all the ghost points that individual ghosted DMDA's may have. 900 901 Level: advanced 902 903 Notes: 904 Each entry of ltogs should be destroyed with ISLocalToGlobalMappingDestroy(), the ltogs array should be freed with PetscFree(). 905 906 Not available from Fortran 907 908 .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 909 DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(), 910 DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries() 911 912 @*/ 913 PetscErrorCode DMCompositeGetISLocalToGlobalMappings(DM dm,ISLocalToGlobalMapping **ltogs) 914 { 915 PetscErrorCode ierr; 916 PetscInt i,*idx,n,cnt; 917 struct DMCompositeLink *next; 918 PetscMPIInt rank; 919 DM_Composite *com = (DM_Composite*)dm->data; 920 PetscBool flg; 921 922 PetscFunctionBegin; 923 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 924 ierr = PetscObjectTypeCompare((PetscObject)dm,DMCOMPOSITE,&flg);CHKERRQ(ierr); 925 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 926 ierr = DMSetUp(dm);CHKERRQ(ierr); 927 ierr = PetscMalloc1(com->nDM,ltogs);CHKERRQ(ierr); 928 next = com->next; 929 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 930 931 /* loop over packed objects, handling one at at time */ 932 cnt = 0; 933 while (next) { 934 ISLocalToGlobalMapping ltog; 935 PetscMPIInt size; 936 const PetscInt *suboff,*indices; 937 Vec global; 938 939 /* Get sub-DM global indices for each local dof */ 940 ierr = DMGetLocalToGlobalMapping(next->dm,<og);CHKERRQ(ierr); 941 ierr = ISLocalToGlobalMappingGetSize(ltog,&n);CHKERRQ(ierr); 942 ierr = ISLocalToGlobalMappingGetIndices(ltog,&indices);CHKERRQ(ierr); 943 ierr = PetscMalloc1(n,&idx);CHKERRQ(ierr); 944 945 /* Get the offsets for the sub-DM global vector */ 946 ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 947 ierr = VecGetOwnershipRanges(global,&suboff);CHKERRQ(ierr); 948 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)global),&size);CHKERRQ(ierr); 949 950 /* Shift the sub-DM definition of the global space to the composite global space */ 951 for (i=0; i<n; i++) { 952 PetscInt subi = indices[i],lo = 0,hi = size,t; 953 /* Binary search to find which rank owns subi */ 954 while (hi-lo > 1) { 955 t = lo + (hi-lo)/2; 956 if (suboff[t] > subi) hi = t; 957 else lo = t; 958 } 959 idx[i] = subi - suboff[lo] + next->grstarts[lo]; 960 } 961 ierr = ISLocalToGlobalMappingRestoreIndices(ltog,&indices);CHKERRQ(ierr); 962 ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm),1,n,idx,PETSC_OWN_POINTER,&(*ltogs)[cnt]);CHKERRQ(ierr); 963 ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 964 next = next->next; 965 cnt++; 966 } 967 PetscFunctionReturn(0); 968 } 969 970 /*@C 971 DMCompositeGetLocalISs - Gets index sets for each component of a composite local vector 972 973 Not Collective 974 975 Input Arguments: 976 . dm - composite DM 977 978 Output Arguments: 979 . is - array of serial index sets for each each component of the DMComposite 980 981 Level: intermediate 982 983 Notes: 984 At present, a composite local vector does not normally exist. This function is used to provide index sets for 985 MatGetLocalSubMatrix(). In the future, the scatters for each entry in the DMComposite may be be merged into a single 986 scatter to a composite local vector. The user should not typically need to know which is being done. 987 988 To get the composite global indices at all local points (including ghosts), use DMCompositeGetISLocalToGlobalMappings(). 989 990 To get index sets for pieces of the composite global vector, use DMCompositeGetGlobalISs(). 991 992 Each returned IS should be destroyed with ISDestroy(), the array should be freed with PetscFree(). 993 994 Not available from Fortran 995 996 .seealso: DMCompositeGetGlobalISs(), DMCompositeGetISLocalToGlobalMappings(), MatGetLocalSubMatrix(), MatCreateLocalRef() 997 @*/ 998 PetscErrorCode DMCompositeGetLocalISs(DM dm,IS **is) 999 { 1000 PetscErrorCode ierr; 1001 DM_Composite *com = (DM_Composite*)dm->data; 1002 struct DMCompositeLink *link; 1003 PetscInt cnt,start; 1004 PetscBool flg; 1005 1006 PetscFunctionBegin; 1007 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1008 PetscValidPointer(is,2); 1009 ierr = PetscObjectTypeCompare((PetscObject)dm,DMCOMPOSITE,&flg);CHKERRQ(ierr); 1010 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 1011 ierr = PetscMalloc1(com->nmine,is);CHKERRQ(ierr); 1012 for (cnt=0,start=0,link=com->next; link; start+=link->nlocal,cnt++,link=link->next) { 1013 PetscInt bs; 1014 ierr = ISCreateStride(PETSC_COMM_SELF,link->nlocal,start,1,&(*is)[cnt]);CHKERRQ(ierr); 1015 ierr = DMGetBlockSize(link->dm,&bs);CHKERRQ(ierr); 1016 ierr = ISSetBlockSize((*is)[cnt],bs);CHKERRQ(ierr); 1017 } 1018 PetscFunctionReturn(0); 1019 } 1020 1021 /*@C 1022 DMCompositeGetGlobalISs - Gets the index sets for each composed object 1023 1024 Collective on DMComposite 1025 1026 Input Parameter: 1027 . dm - the packer object 1028 1029 Output Parameters: 1030 . is - the array of index sets 1031 1032 Level: advanced 1033 1034 Notes: 1035 The is entries should be destroyed with ISDestroy(), the is array should be freed with PetscFree() 1036 1037 These could be used to extract a subset of vector entries for a "multi-physics" preconditioner 1038 1039 Use DMCompositeGetLocalISs() for index sets in the packed local numbering, and 1040 DMCompositeGetISLocalToGlobalMappings() for to map local sub-DM (including ghost) indices to packed global 1041 indices. 1042 1043 Fortran Notes: 1044 1045 The output argument 'is' must be an allocated array of sufficient length, which can be learned using DMCompositeGetNumberDM(). 1046 1047 .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 1048 DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(), 1049 DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries() 1050 1051 @*/ 1052 PetscErrorCode DMCompositeGetGlobalISs(DM dm,IS *is[]) 1053 { 1054 PetscErrorCode ierr; 1055 PetscInt cnt = 0; 1056 struct DMCompositeLink *next; 1057 PetscMPIInt rank; 1058 DM_Composite *com = (DM_Composite*)dm->data; 1059 PetscBool flg; 1060 1061 PetscFunctionBegin; 1062 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1063 ierr = PetscObjectTypeCompare((PetscObject)dm,DMCOMPOSITE,&flg);CHKERRQ(ierr); 1064 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 1065 if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() before"); 1066 ierr = PetscMalloc1(com->nDM,is);CHKERRQ(ierr); 1067 next = com->next; 1068 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 1069 1070 /* loop over packed objects, handling one at at time */ 1071 while (next) { 1072 ierr = ISCreateStride(PetscObjectComm((PetscObject)dm),next->n,next->grstart,1,&(*is)[cnt]);CHKERRQ(ierr); 1073 if (dm->prob) { 1074 MatNullSpace space; 1075 Mat pmat; 1076 PetscObject disc; 1077 PetscInt Nf; 1078 1079 ierr = PetscDSGetNumFields(dm->prob, &Nf);CHKERRQ(ierr); 1080 if (cnt < Nf) { 1081 ierr = PetscDSGetDiscretization(dm->prob, cnt, &disc);CHKERRQ(ierr); 1082 ierr = PetscObjectQuery(disc, "nullspace", (PetscObject*) &space);CHKERRQ(ierr); 1083 if (space) {ierr = PetscObjectCompose((PetscObject) (*is)[cnt], "nullspace", (PetscObject) space);CHKERRQ(ierr);} 1084 ierr = PetscObjectQuery(disc, "nearnullspace", (PetscObject*) &space);CHKERRQ(ierr); 1085 if (space) {ierr = PetscObjectCompose((PetscObject) (*is)[cnt], "nearnullspace", (PetscObject) space);CHKERRQ(ierr);} 1086 ierr = PetscObjectQuery(disc, "pmat", (PetscObject*) &pmat);CHKERRQ(ierr); 1087 if (pmat) {ierr = PetscObjectCompose((PetscObject) (*is)[cnt], "pmat", (PetscObject) pmat);CHKERRQ(ierr);} 1088 } 1089 } 1090 cnt++; 1091 next = next->next; 1092 } 1093 PetscFunctionReturn(0); 1094 } 1095 1096 PetscErrorCode DMCreateFieldIS_Composite(DM dm, PetscInt *numFields,char ***fieldNames, IS **fields) 1097 { 1098 PetscInt nDM; 1099 DM *dms; 1100 PetscInt i; 1101 PetscErrorCode ierr; 1102 1103 PetscFunctionBegin; 1104 ierr = DMCompositeGetNumberDM(dm, &nDM);CHKERRQ(ierr); 1105 if (numFields) *numFields = nDM; 1106 ierr = DMCompositeGetGlobalISs(dm, fields);CHKERRQ(ierr); 1107 if (fieldNames) { 1108 ierr = PetscMalloc1(nDM, &dms);CHKERRQ(ierr); 1109 ierr = PetscMalloc1(nDM, fieldNames);CHKERRQ(ierr); 1110 ierr = DMCompositeGetEntriesArray(dm, dms);CHKERRQ(ierr); 1111 for (i=0; i<nDM; i++) { 1112 char buf[256]; 1113 const char *splitname; 1114 1115 /* Split naming precedence: object name, prefix, number */ 1116 splitname = ((PetscObject) dm)->name; 1117 if (!splitname) { 1118 ierr = PetscObjectGetOptionsPrefix((PetscObject)dms[i],&splitname);CHKERRQ(ierr); 1119 if (splitname) { 1120 size_t len; 1121 ierr = PetscStrncpy(buf,splitname,sizeof(buf));CHKERRQ(ierr); 1122 buf[sizeof(buf) - 1] = 0; 1123 ierr = PetscStrlen(buf,&len);CHKERRQ(ierr); 1124 if (buf[len-1] == '_') buf[len-1] = 0; /* Remove trailing underscore if it was used */ 1125 splitname = buf; 1126 } 1127 } 1128 if (!splitname) { 1129 ierr = PetscSNPrintf(buf,sizeof(buf),"%D",i);CHKERRQ(ierr); 1130 splitname = buf; 1131 } 1132 ierr = PetscStrallocpy(splitname,&(*fieldNames)[i]);CHKERRQ(ierr); 1133 } 1134 ierr = PetscFree(dms);CHKERRQ(ierr); 1135 } 1136 PetscFunctionReturn(0); 1137 } 1138 1139 /* 1140 This could take over from DMCreateFieldIS(), as it is more general, 1141 making DMCreateFieldIS() a special case -- calling with dmlist == NULL; 1142 At this point it's probably best to be less intrusive, however. 1143 */ 1144 PetscErrorCode DMCreateFieldDecomposition_Composite(DM dm, PetscInt *len,char ***namelist, IS **islist, DM **dmlist) 1145 { 1146 PetscInt nDM; 1147 PetscInt i; 1148 PetscErrorCode ierr; 1149 1150 PetscFunctionBegin; 1151 ierr = DMCreateFieldIS_Composite(dm, len, namelist, islist);CHKERRQ(ierr); 1152 if (dmlist) { 1153 ierr = DMCompositeGetNumberDM(dm, &nDM);CHKERRQ(ierr); 1154 ierr = PetscMalloc1(nDM, dmlist);CHKERRQ(ierr); 1155 ierr = DMCompositeGetEntriesArray(dm, *dmlist);CHKERRQ(ierr); 1156 for (i=0; i<nDM; i++) { 1157 ierr = PetscObjectReference((PetscObject)((*dmlist)[i]));CHKERRQ(ierr); 1158 } 1159 } 1160 PetscFunctionReturn(0); 1161 } 1162 1163 1164 1165 /* -------------------------------------------------------------------------------------*/ 1166 /*@C 1167 DMCompositeGetLocalVectors - Gets local vectors for each part of a DMComposite. 1168 Use DMCompositeRestoreLocalVectors() to return them. 1169 1170 Not Collective 1171 1172 Input Parameter: 1173 . dm - the packer object 1174 1175 Output Parameter: 1176 . Vec ... - the individual sequential Vecs 1177 1178 Level: advanced 1179 1180 Not available from Fortran 1181 1182 .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 1183 DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 1184 DMCompositeRestoreLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries() 1185 1186 @*/ 1187 PetscErrorCode DMCompositeGetLocalVectors(DM dm,...) 1188 { 1189 va_list Argp; 1190 PetscErrorCode ierr; 1191 struct DMCompositeLink *next; 1192 DM_Composite *com = (DM_Composite*)dm->data; 1193 PetscBool flg; 1194 1195 PetscFunctionBegin; 1196 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1197 ierr = PetscObjectTypeCompare((PetscObject)dm,DMCOMPOSITE,&flg);CHKERRQ(ierr); 1198 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 1199 next = com->next; 1200 /* loop over packed objects, handling one at at time */ 1201 va_start(Argp,dm); 1202 while (next) { 1203 Vec *vec; 1204 vec = va_arg(Argp, Vec*); 1205 if (vec) {ierr = DMGetLocalVector(next->dm,vec);CHKERRQ(ierr);} 1206 next = next->next; 1207 } 1208 va_end(Argp); 1209 PetscFunctionReturn(0); 1210 } 1211 1212 /*@C 1213 DMCompositeRestoreLocalVectors - Restores local vectors for each part of a DMComposite. 1214 1215 Not Collective 1216 1217 Input Parameter: 1218 . dm - the packer object 1219 1220 Output Parameter: 1221 . Vec ... - the individual sequential Vecs 1222 1223 Level: advanced 1224 1225 Not available from Fortran 1226 1227 .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), 1228 DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 1229 DMCompositeGetLocalVectors(), DMCompositeScatter(), DMCompositeGetEntries() 1230 1231 @*/ 1232 PetscErrorCode DMCompositeRestoreLocalVectors(DM dm,...) 1233 { 1234 va_list Argp; 1235 PetscErrorCode ierr; 1236 struct DMCompositeLink *next; 1237 DM_Composite *com = (DM_Composite*)dm->data; 1238 PetscBool flg; 1239 1240 PetscFunctionBegin; 1241 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1242 ierr = PetscObjectTypeCompare((PetscObject)dm,DMCOMPOSITE,&flg);CHKERRQ(ierr); 1243 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 1244 next = com->next; 1245 /* loop over packed objects, handling one at at time */ 1246 va_start(Argp,dm); 1247 while (next) { 1248 Vec *vec; 1249 vec = va_arg(Argp, Vec*); 1250 if (vec) {ierr = DMRestoreLocalVector(next->dm,vec);CHKERRQ(ierr);} 1251 next = next->next; 1252 } 1253 va_end(Argp); 1254 PetscFunctionReturn(0); 1255 } 1256 1257 /* -------------------------------------------------------------------------------------*/ 1258 /*@C 1259 DMCompositeGetEntries - Gets the DM for each entry in a DMComposite. 1260 1261 Not Collective 1262 1263 Input Parameter: 1264 . dm - the packer object 1265 1266 Output Parameter: 1267 . DM ... - the individual entries (DMs) 1268 1269 Level: advanced 1270 1271 Fortran Notes: 1272 Available as DMCompositeGetEntries() for one output DM, DMCompositeGetEntries2() for 2, etc 1273 1274 .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntriesArray() 1275 DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 1276 DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(), DMCompositeScatter(), 1277 DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors() 1278 1279 @*/ 1280 PetscErrorCode DMCompositeGetEntries(DM dm,...) 1281 { 1282 va_list Argp; 1283 struct DMCompositeLink *next; 1284 DM_Composite *com = (DM_Composite*)dm->data; 1285 PetscBool flg; 1286 PetscErrorCode ierr; 1287 1288 PetscFunctionBegin; 1289 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1290 ierr = PetscObjectTypeCompare((PetscObject)dm,DMCOMPOSITE,&flg);CHKERRQ(ierr); 1291 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 1292 next = com->next; 1293 /* loop over packed objects, handling one at at time */ 1294 va_start(Argp,dm); 1295 while (next) { 1296 DM *dmn; 1297 dmn = va_arg(Argp, DM*); 1298 if (dmn) *dmn = next->dm; 1299 next = next->next; 1300 } 1301 va_end(Argp); 1302 PetscFunctionReturn(0); 1303 } 1304 1305 /*@C 1306 DMCompositeGetEntriesArray - Gets the DM for each entry in a DMComposite. 1307 1308 Not Collective 1309 1310 Input Parameter: 1311 . dm - the packer object 1312 1313 Output Parameter: 1314 . dms - array of sufficient length (see DMCompositeGetNumberDM()) to hold the individual DMs 1315 1316 Level: advanced 1317 1318 .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGetEntries() 1319 DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), 1320 DMCompositeRestoreLocalVectors(), DMCompositeGetLocalVectors(), DMCompositeScatter(), 1321 DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors() 1322 1323 @*/ 1324 PetscErrorCode DMCompositeGetEntriesArray(DM dm,DM dms[]) 1325 { 1326 struct DMCompositeLink *next; 1327 DM_Composite *com = (DM_Composite*)dm->data; 1328 PetscInt i; 1329 PetscBool flg; 1330 PetscErrorCode ierr; 1331 1332 PetscFunctionBegin; 1333 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1334 ierr = PetscObjectTypeCompare((PetscObject)dm,DMCOMPOSITE,&flg);CHKERRQ(ierr); 1335 if (!flg) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for type %s",((PetscObject)dm)->type_name); 1336 /* loop over packed objects, handling one at at time */ 1337 for (next=com->next,i=0; next; next=next->next,i++) dms[i] = next->dm; 1338 PetscFunctionReturn(0); 1339 } 1340 1341 typedef struct { 1342 DM dm; 1343 PetscViewer *subv; 1344 Vec *vecs; 1345 } GLVisViewerCtx; 1346 1347 static PetscErrorCode DestroyGLVisViewerCtx_Private(void *vctx) 1348 { 1349 GLVisViewerCtx *ctx = (GLVisViewerCtx*)vctx; 1350 PetscInt i,n; 1351 PetscErrorCode ierr; 1352 1353 PetscFunctionBegin; 1354 ierr = DMCompositeGetNumberDM(ctx->dm,&n);CHKERRQ(ierr); 1355 for (i = 0; i < n; i++) { 1356 ierr = PetscViewerDestroy(&ctx->subv[i]);CHKERRQ(ierr); 1357 } 1358 ierr = PetscFree2(ctx->subv,ctx->vecs);CHKERRQ(ierr); 1359 ierr = DMDestroy(&ctx->dm);CHKERRQ(ierr); 1360 ierr = PetscFree(ctx);CHKERRQ(ierr); 1361 PetscFunctionReturn(0); 1362 } 1363 1364 static PetscErrorCode DMCompositeSampleGLVisFields_Private(PetscObject oX, PetscInt nf, PetscObject oXfield[], void *vctx) 1365 { 1366 Vec X = (Vec)oX; 1367 GLVisViewerCtx *ctx = (GLVisViewerCtx*)vctx; 1368 PetscInt i,n,cumf; 1369 PetscErrorCode ierr; 1370 1371 PetscFunctionBegin; 1372 ierr = DMCompositeGetNumberDM(ctx->dm,&n);CHKERRQ(ierr); 1373 ierr = DMCompositeGetAccessArray(ctx->dm,X,n,NULL,ctx->vecs);CHKERRQ(ierr); 1374 for (i = 0, cumf = 0; i < n; i++) { 1375 PetscErrorCode (*g2l)(PetscObject,PetscInt,PetscObject[],void*); 1376 void *fctx; 1377 PetscInt nfi; 1378 1379 ierr = PetscViewerGLVisGetFields_Private(ctx->subv[i],&nfi,NULL,NULL,&g2l,NULL,&fctx);CHKERRQ(ierr); 1380 if (!nfi) continue; 1381 if (g2l) { 1382 ierr = (*g2l)((PetscObject)ctx->vecs[i],nfi,oXfield+cumf,fctx);CHKERRQ(ierr); 1383 } else { 1384 ierr = VecCopy(ctx->vecs[i],(Vec)(oXfield[cumf]));CHKERRQ(ierr); 1385 } 1386 cumf += nfi; 1387 } 1388 ierr = DMCompositeRestoreAccessArray(ctx->dm,X,n,NULL,ctx->vecs);CHKERRQ(ierr); 1389 PetscFunctionReturn(0); 1390 } 1391 1392 static PetscErrorCode DMSetUpGLVisViewer_Composite(PetscObject odm, PetscViewer viewer) 1393 { 1394 DM dm = (DM)odm, *dms; 1395 Vec *Ufds; 1396 GLVisViewerCtx *ctx; 1397 PetscInt i,n,tnf,*sdim; 1398 char **fecs; 1399 PetscErrorCode ierr; 1400 1401 PetscFunctionBegin; 1402 ierr = PetscNew(&ctx);CHKERRQ(ierr); 1403 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 1404 ctx->dm = dm; 1405 ierr = DMCompositeGetNumberDM(dm,&n);CHKERRQ(ierr); 1406 ierr = PetscMalloc1(n,&dms);CHKERRQ(ierr); 1407 ierr = DMCompositeGetEntriesArray(dm,dms);CHKERRQ(ierr); 1408 ierr = PetscMalloc2(n,&ctx->subv,n,&ctx->vecs);CHKERRQ(ierr); 1409 for (i = 0, tnf = 0; i < n; i++) { 1410 PetscInt nf; 1411 1412 ierr = PetscViewerCreate(PetscObjectComm(odm),&ctx->subv[i]);CHKERRQ(ierr); 1413 ierr = PetscViewerSetType(ctx->subv[i],PETSCVIEWERGLVIS);CHKERRQ(ierr); 1414 ierr = PetscViewerGLVisSetDM_Private(ctx->subv[i],(PetscObject)dms[i]);CHKERRQ(ierr); 1415 ierr = PetscViewerGLVisGetFields_Private(ctx->subv[i],&nf,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); 1416 tnf += nf; 1417 } 1418 ierr = PetscFree(dms);CHKERRQ(ierr); 1419 ierr = PetscMalloc3(tnf,&fecs,tnf,&sdim,tnf,&Ufds);CHKERRQ(ierr); 1420 for (i = 0, tnf = 0; i < n; i++) { 1421 PetscInt *sd,nf,f; 1422 const char **fec; 1423 Vec *Uf; 1424 1425 ierr = PetscViewerGLVisGetFields_Private(ctx->subv[i],&nf,&fec,&sd,NULL,(PetscObject**)&Uf,NULL);CHKERRQ(ierr); 1426 for (f = 0; f < nf; f++) { 1427 ierr = PetscStrallocpy(fec[f],&fecs[tnf+f]);CHKERRQ(ierr); 1428 Ufds[tnf+f] = Uf[f]; 1429 sdim[tnf+f] = sd[f]; 1430 } 1431 tnf += nf; 1432 } 1433 ierr = PetscViewerGLVisSetFields(viewer,tnf,(const char**)fecs,sdim,DMCompositeSampleGLVisFields_Private,(PetscObject*)Ufds,ctx,DestroyGLVisViewerCtx_Private);CHKERRQ(ierr); 1434 for (i = 0; i < tnf; i++) { 1435 ierr = PetscFree(fecs[i]);CHKERRQ(ierr); 1436 } 1437 ierr = PetscFree3(fecs,sdim,Ufds);CHKERRQ(ierr); 1438 PetscFunctionReturn(0); 1439 } 1440 1441 PetscErrorCode DMRefine_Composite(DM dmi,MPI_Comm comm,DM *fine) 1442 { 1443 PetscErrorCode ierr; 1444 struct DMCompositeLink *next; 1445 DM_Composite *com = (DM_Composite*)dmi->data; 1446 DM dm; 1447 1448 PetscFunctionBegin; 1449 PetscValidHeaderSpecific(dmi,DM_CLASSID,1); 1450 if (comm == MPI_COMM_NULL) { 1451 ierr = PetscObjectGetComm((PetscObject)dmi,&comm);CHKERRQ(ierr); 1452 } 1453 ierr = DMSetUp(dmi);CHKERRQ(ierr); 1454 next = com->next; 1455 ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr); 1456 1457 /* loop over packed objects, handling one at at time */ 1458 while (next) { 1459 ierr = DMRefine(next->dm,comm,&dm);CHKERRQ(ierr); 1460 ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr); 1461 ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr); 1462 next = next->next; 1463 } 1464 PetscFunctionReturn(0); 1465 } 1466 1467 PetscErrorCode DMCoarsen_Composite(DM dmi,MPI_Comm comm,DM *fine) 1468 { 1469 PetscErrorCode ierr; 1470 struct DMCompositeLink *next; 1471 DM_Composite *com = (DM_Composite*)dmi->data; 1472 DM dm; 1473 1474 PetscFunctionBegin; 1475 PetscValidHeaderSpecific(dmi,DM_CLASSID,1); 1476 ierr = DMSetUp(dmi);CHKERRQ(ierr); 1477 if (comm == MPI_COMM_NULL) { 1478 ierr = PetscObjectGetComm((PetscObject)dmi,&comm);CHKERRQ(ierr); 1479 } 1480 next = com->next; 1481 ierr = DMCompositeCreate(comm,fine);CHKERRQ(ierr); 1482 1483 /* loop over packed objects, handling one at at time */ 1484 while (next) { 1485 ierr = DMCoarsen(next->dm,comm,&dm);CHKERRQ(ierr); 1486 ierr = DMCompositeAddDM(*fine,dm);CHKERRQ(ierr); 1487 ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr); 1488 next = next->next; 1489 } 1490 PetscFunctionReturn(0); 1491 } 1492 1493 PetscErrorCode DMCreateInterpolation_Composite(DM coarse,DM fine,Mat *A,Vec *v) 1494 { 1495 PetscErrorCode ierr; 1496 PetscInt m,n,M,N,nDM,i; 1497 struct DMCompositeLink *nextc; 1498 struct DMCompositeLink *nextf; 1499 Vec gcoarse,gfine,*vecs; 1500 DM_Composite *comcoarse = (DM_Composite*)coarse->data; 1501 DM_Composite *comfine = (DM_Composite*)fine->data; 1502 Mat *mats; 1503 1504 PetscFunctionBegin; 1505 PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 1506 PetscValidHeaderSpecific(fine,DM_CLASSID,2); 1507 ierr = DMSetUp(coarse);CHKERRQ(ierr); 1508 ierr = DMSetUp(fine);CHKERRQ(ierr); 1509 /* use global vectors only for determining matrix layout */ 1510 ierr = DMGetGlobalVector(coarse,&gcoarse);CHKERRQ(ierr); 1511 ierr = DMGetGlobalVector(fine,&gfine);CHKERRQ(ierr); 1512 ierr = VecGetLocalSize(gcoarse,&n);CHKERRQ(ierr); 1513 ierr = VecGetLocalSize(gfine,&m);CHKERRQ(ierr); 1514 ierr = VecGetSize(gcoarse,&N);CHKERRQ(ierr); 1515 ierr = VecGetSize(gfine,&M);CHKERRQ(ierr); 1516 ierr = DMRestoreGlobalVector(coarse,&gcoarse);CHKERRQ(ierr); 1517 ierr = DMRestoreGlobalVector(fine,&gfine);CHKERRQ(ierr); 1518 1519 nDM = comfine->nDM; 1520 if (nDM != comcoarse->nDM) SETERRQ2(PetscObjectComm((PetscObject)fine),PETSC_ERR_ARG_INCOMP,"Fine DMComposite has %D entries, but coarse has %D",nDM,comcoarse->nDM); 1521 ierr = PetscCalloc1(nDM*nDM,&mats);CHKERRQ(ierr); 1522 if (v) { 1523 ierr = PetscCalloc1(nDM,&vecs);CHKERRQ(ierr); 1524 } 1525 1526 /* loop over packed objects, handling one at at time */ 1527 for (nextc=comcoarse->next,nextf=comfine->next,i=0; nextc; nextc=nextc->next,nextf=nextf->next,i++) { 1528 if (!v) { 1529 ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],NULL);CHKERRQ(ierr); 1530 } else { 1531 ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],&vecs[i]);CHKERRQ(ierr); 1532 } 1533 } 1534 ierr = MatCreateNest(PetscObjectComm((PetscObject)fine),nDM,NULL,nDM,NULL,mats,A);CHKERRQ(ierr); 1535 if (v) { 1536 ierr = VecCreateNest(PetscObjectComm((PetscObject)fine),nDM,NULL,vecs,v);CHKERRQ(ierr); 1537 } 1538 for (i=0; i<nDM*nDM; i++) {ierr = MatDestroy(&mats[i]);CHKERRQ(ierr);} 1539 ierr = PetscFree(mats);CHKERRQ(ierr); 1540 if (v) { 1541 for (i=0; i<nDM; i++) {ierr = VecDestroy(&vecs[i]);CHKERRQ(ierr);} 1542 ierr = PetscFree(vecs);CHKERRQ(ierr); 1543 } 1544 PetscFunctionReturn(0); 1545 } 1546 1547 static PetscErrorCode DMGetLocalToGlobalMapping_Composite(DM dm) 1548 { 1549 DM_Composite *com = (DM_Composite*)dm->data; 1550 ISLocalToGlobalMapping *ltogs; 1551 PetscInt i; 1552 PetscErrorCode ierr; 1553 1554 PetscFunctionBegin; 1555 /* Set the ISLocalToGlobalMapping on the new matrix */ 1556 ierr = DMCompositeGetISLocalToGlobalMappings(dm,<ogs);CHKERRQ(ierr); 1557 ierr = ISLocalToGlobalMappingConcatenate(PetscObjectComm((PetscObject)dm),com->nDM,ltogs,&dm->ltogmap);CHKERRQ(ierr); 1558 for (i=0; i<com->nDM; i++) {ierr = ISLocalToGlobalMappingDestroy(<ogs[i]);CHKERRQ(ierr);} 1559 ierr = PetscFree(ltogs);CHKERRQ(ierr); 1560 PetscFunctionReturn(0); 1561 } 1562 1563 1564 PetscErrorCode DMCreateColoring_Composite(DM dm,ISColoringType ctype,ISColoring *coloring) 1565 { 1566 PetscErrorCode ierr; 1567 PetscInt n,i,cnt; 1568 ISColoringValue *colors; 1569 PetscBool dense = PETSC_FALSE; 1570 ISColoringValue maxcol = 0; 1571 DM_Composite *com = (DM_Composite*)dm->data; 1572 1573 PetscFunctionBegin; 1574 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1575 if (ctype == IS_COLORING_LOCAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only global coloring supported"); 1576 else if (ctype == IS_COLORING_GLOBAL) { 1577 n = com->n; 1578 } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Unknown ISColoringType"); 1579 ierr = PetscMalloc1(n,&colors);CHKERRQ(ierr); /* freed in ISColoringDestroy() */ 1580 1581 ierr = PetscOptionsGetBool(((PetscObject)dm)->options,((PetscObject)dm)->prefix,"-dmcomposite_dense_jacobian",&dense,NULL);CHKERRQ(ierr); 1582 if (dense) { 1583 for (i=0; i<n; i++) { 1584 colors[i] = (ISColoringValue)(com->rstart + i); 1585 } 1586 maxcol = com->N; 1587 } else { 1588 struct DMCompositeLink *next = com->next; 1589 PetscMPIInt rank; 1590 1591 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 1592 cnt = 0; 1593 while (next) { 1594 ISColoring lcoloring; 1595 1596 ierr = DMCreateColoring(next->dm,IS_COLORING_GLOBAL,&lcoloring);CHKERRQ(ierr); 1597 for (i=0; i<lcoloring->N; i++) { 1598 colors[cnt++] = maxcol + lcoloring->colors[i]; 1599 } 1600 maxcol += lcoloring->n; 1601 ierr = ISColoringDestroy(&lcoloring);CHKERRQ(ierr); 1602 next = next->next; 1603 } 1604 } 1605 ierr = ISColoringCreate(PetscObjectComm((PetscObject)dm),maxcol,n,colors,PETSC_OWN_POINTER,coloring);CHKERRQ(ierr); 1606 PetscFunctionReturn(0); 1607 } 1608 1609 PetscErrorCode DMGlobalToLocalBegin_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec) 1610 { 1611 PetscErrorCode ierr; 1612 struct DMCompositeLink *next; 1613 PetscScalar *garray,*larray; 1614 DM_Composite *com = (DM_Composite*)dm->data; 1615 1616 PetscFunctionBegin; 1617 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1618 PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 1619 1620 if (!com->setup) { 1621 ierr = DMSetUp(dm);CHKERRQ(ierr); 1622 } 1623 1624 ierr = VecGetArray(gvec,&garray);CHKERRQ(ierr); 1625 ierr = VecGetArray(lvec,&larray);CHKERRQ(ierr); 1626 1627 /* loop over packed objects, handling one at at time */ 1628 next = com->next; 1629 while (next) { 1630 Vec local,global; 1631 PetscInt N; 1632 1633 ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 1634 ierr = VecGetLocalSize(global,&N);CHKERRQ(ierr); 1635 ierr = VecPlaceArray(global,garray);CHKERRQ(ierr); 1636 ierr = DMGetLocalVector(next->dm,&local);CHKERRQ(ierr); 1637 ierr = VecPlaceArray(local,larray);CHKERRQ(ierr); 1638 ierr = DMGlobalToLocalBegin(next->dm,global,mode,local);CHKERRQ(ierr); 1639 ierr = DMGlobalToLocalEnd(next->dm,global,mode,local);CHKERRQ(ierr); 1640 ierr = VecResetArray(global);CHKERRQ(ierr); 1641 ierr = VecResetArray(local);CHKERRQ(ierr); 1642 ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 1643 ierr = DMRestoreLocalVector(next->dm,&local);CHKERRQ(ierr); 1644 1645 larray += next->nlocal; 1646 garray += next->n; 1647 next = next->next; 1648 } 1649 1650 ierr = VecRestoreArray(gvec,NULL);CHKERRQ(ierr); 1651 ierr = VecRestoreArray(lvec,NULL);CHKERRQ(ierr); 1652 PetscFunctionReturn(0); 1653 } 1654 1655 PetscErrorCode DMGlobalToLocalEnd_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec) 1656 { 1657 PetscFunctionBegin; 1658 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1659 PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); 1660 PetscValidHeaderSpecific(lvec,VEC_CLASSID,4); 1661 PetscFunctionReturn(0); 1662 } 1663 1664 PetscErrorCode DMLocalToGlobalBegin_Composite(DM dm,Vec lvec,InsertMode mode,Vec gvec) 1665 { 1666 PetscErrorCode ierr; 1667 struct DMCompositeLink *next; 1668 PetscScalar *larray,*garray; 1669 DM_Composite *com = (DM_Composite*)dm->data; 1670 1671 PetscFunctionBegin; 1672 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1673 PetscValidHeaderSpecific(lvec,VEC_CLASSID,2); 1674 PetscValidHeaderSpecific(gvec,VEC_CLASSID,4); 1675 1676 if (!com->setup) { 1677 ierr = DMSetUp(dm);CHKERRQ(ierr); 1678 } 1679 1680 ierr = VecGetArray(lvec,&larray);CHKERRQ(ierr); 1681 ierr = VecGetArray(gvec,&garray);CHKERRQ(ierr); 1682 1683 /* loop over packed objects, handling one at at time */ 1684 next = com->next; 1685 while (next) { 1686 Vec global,local; 1687 1688 ierr = DMGetLocalVector(next->dm,&local);CHKERRQ(ierr); 1689 ierr = VecPlaceArray(local,larray);CHKERRQ(ierr); 1690 ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); 1691 ierr = VecPlaceArray(global,garray);CHKERRQ(ierr); 1692 ierr = DMLocalToGlobalBegin(next->dm,local,mode,global);CHKERRQ(ierr); 1693 ierr = DMLocalToGlobalEnd(next->dm,local,mode,global);CHKERRQ(ierr); 1694 ierr = VecResetArray(local);CHKERRQ(ierr); 1695 ierr = VecResetArray(global);CHKERRQ(ierr); 1696 ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); 1697 ierr = DMRestoreLocalVector(next->dm,&local);CHKERRQ(ierr); 1698 1699 garray += next->n; 1700 larray += next->nlocal; 1701 next = next->next; 1702 } 1703 1704 ierr = VecRestoreArray(gvec,NULL);CHKERRQ(ierr); 1705 ierr = VecRestoreArray(lvec,NULL);CHKERRQ(ierr); 1706 1707 PetscFunctionReturn(0); 1708 } 1709 1710 PetscErrorCode DMLocalToGlobalEnd_Composite(DM dm,Vec lvec,InsertMode mode,Vec gvec) 1711 { 1712 PetscFunctionBegin; 1713 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1714 PetscValidHeaderSpecific(lvec,VEC_CLASSID,2); 1715 PetscValidHeaderSpecific(gvec,VEC_CLASSID,4); 1716 PetscFunctionReturn(0); 1717 } 1718 1719 PetscErrorCode DMLocalToLocalBegin_Composite(DM dm,Vec vec1,InsertMode mode,Vec vec2) 1720 { 1721 PetscErrorCode ierr; 1722 struct DMCompositeLink *next; 1723 PetscScalar *array1,*array2; 1724 DM_Composite *com = (DM_Composite*)dm->data; 1725 1726 PetscFunctionBegin; 1727 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1728 PetscValidHeaderSpecific(vec1,VEC_CLASSID,2); 1729 PetscValidHeaderSpecific(vec2,VEC_CLASSID,4); 1730 1731 if (!com->setup) { 1732 ierr = DMSetUp(dm);CHKERRQ(ierr); 1733 } 1734 1735 ierr = VecGetArray(vec1,&array1);CHKERRQ(ierr); 1736 ierr = VecGetArray(vec2,&array2);CHKERRQ(ierr); 1737 1738 /* loop over packed objects, handling one at at time */ 1739 next = com->next; 1740 while (next) { 1741 Vec local1,local2; 1742 1743 ierr = DMGetLocalVector(next->dm,&local1);CHKERRQ(ierr); 1744 ierr = VecPlaceArray(local1,array1);CHKERRQ(ierr); 1745 ierr = DMGetLocalVector(next->dm,&local2);CHKERRQ(ierr); 1746 ierr = VecPlaceArray(local2,array2);CHKERRQ(ierr); 1747 ierr = DMLocalToLocalBegin(next->dm,local1,mode,local2);CHKERRQ(ierr); 1748 ierr = DMLocalToLocalEnd(next->dm,local1,mode,local2);CHKERRQ(ierr); 1749 ierr = VecResetArray(local2);CHKERRQ(ierr); 1750 ierr = DMRestoreLocalVector(next->dm,&local2);CHKERRQ(ierr); 1751 ierr = VecResetArray(local1);CHKERRQ(ierr); 1752 ierr = DMRestoreLocalVector(next->dm,&local1);CHKERRQ(ierr); 1753 1754 array1 += next->nlocal; 1755 array2 += next->nlocal; 1756 next = next->next; 1757 } 1758 1759 ierr = VecRestoreArray(vec1,NULL);CHKERRQ(ierr); 1760 ierr = VecRestoreArray(vec2,NULL);CHKERRQ(ierr); 1761 1762 PetscFunctionReturn(0); 1763 } 1764 1765 PetscErrorCode DMLocalToLocalEnd_Composite(DM dm,Vec lvec,InsertMode mode,Vec gvec) 1766 { 1767 PetscFunctionBegin; 1768 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1769 PetscValidHeaderSpecific(lvec,VEC_CLASSID,2); 1770 PetscValidHeaderSpecific(gvec,VEC_CLASSID,4); 1771 PetscFunctionReturn(0); 1772 } 1773 1774 /*MC 1775 DMCOMPOSITE = "composite" - A DM object that is used to manage data for a collection of DMs 1776 1777 Level: intermediate 1778 1779 .seealso: DMType, DM, DMDACreate(), DMCreate(), DMSetType(), DMCompositeCreate() 1780 M*/ 1781 1782 1783 PETSC_EXTERN PetscErrorCode DMCreate_Composite(DM p) 1784 { 1785 PetscErrorCode ierr; 1786 DM_Composite *com; 1787 1788 PetscFunctionBegin; 1789 ierr = PetscNewLog(p,&com);CHKERRQ(ierr); 1790 p->data = com; 1791 ierr = PetscObjectChangeTypeName((PetscObject)p,"DMComposite");CHKERRQ(ierr); 1792 com->n = 0; 1793 com->nghost = 0; 1794 com->next = NULL; 1795 com->nDM = 0; 1796 1797 p->ops->createglobalvector = DMCreateGlobalVector_Composite; 1798 p->ops->createlocalvector = DMCreateLocalVector_Composite; 1799 p->ops->getlocaltoglobalmapping = DMGetLocalToGlobalMapping_Composite; 1800 p->ops->createfieldis = DMCreateFieldIS_Composite; 1801 p->ops->createfielddecomposition = DMCreateFieldDecomposition_Composite; 1802 p->ops->refine = DMRefine_Composite; 1803 p->ops->coarsen = DMCoarsen_Composite; 1804 p->ops->createinterpolation = DMCreateInterpolation_Composite; 1805 p->ops->creatematrix = DMCreateMatrix_Composite; 1806 p->ops->getcoloring = DMCreateColoring_Composite; 1807 p->ops->globaltolocalbegin = DMGlobalToLocalBegin_Composite; 1808 p->ops->globaltolocalend = DMGlobalToLocalEnd_Composite; 1809 p->ops->localtoglobalbegin = DMLocalToGlobalBegin_Composite; 1810 p->ops->localtoglobalend = DMLocalToGlobalEnd_Composite; 1811 p->ops->localtolocalbegin = DMLocalToLocalBegin_Composite; 1812 p->ops->localtolocalend = DMLocalToLocalEnd_Composite; 1813 p->ops->destroy = DMDestroy_Composite; 1814 p->ops->view = DMView_Composite; 1815 p->ops->setup = DMSetUp_Composite; 1816 1817 ierr = PetscObjectComposeFunction((PetscObject)p,"DMSetUpGLVisViewer_C",DMSetUpGLVisViewer_Composite);CHKERRQ(ierr); 1818 PetscFunctionReturn(0); 1819 } 1820 1821 /*@ 1822 DMCompositeCreate - Creates a vector packer, used to generate "composite" 1823 vectors made up of several subvectors. 1824 1825 Collective on MPI_Comm 1826 1827 Input Parameter: 1828 . comm - the processors that will share the global vector 1829 1830 Output Parameters: 1831 . packer - the packer object 1832 1833 Level: advanced 1834 1835 .seealso DMDestroy(), DMCompositeAddDM(), DMCompositeScatter(), DMCOMPOSITE,DMCreate() 1836 DMCompositeGather(), DMCreateGlobalVector(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess() 1837 DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() 1838 1839 @*/ 1840 PetscErrorCode DMCompositeCreate(MPI_Comm comm,DM *packer) 1841 { 1842 PetscErrorCode ierr; 1843 1844 PetscFunctionBegin; 1845 PetscValidPointer(packer,2); 1846 ierr = DMCreate(comm,packer);CHKERRQ(ierr); 1847 ierr = DMSetType(*packer,DMCOMPOSITE);CHKERRQ(ierr); 1848 PetscFunctionReturn(0); 1849 } 1850