1 #include <petsc/private/dmnetworkimpl.h> /*I "petscdmnetwork.h" I*/ 2 #include <petscdmplex.h> 3 #include <petscsf.h> 4 5 #undef __FUNCT__ 6 #define __FUNCT__ "DMNetworkSetSizes" 7 /*@ 8 DMNetworkSetSizes - Sets the local and global vertices and edges. 9 10 Collective on DM 11 12 Input Parameters: 13 + dm - the dm object 14 . nV - number of local vertices 15 . nE - number of local edges 16 . NV - number of global vertices (or PETSC_DETERMINE) 17 - NE - number of global edges (or PETSC_DETERMINE) 18 19 Notes 20 If one processor calls this with NV (NE) of PETSC_DECIDE then all processors must, otherwise the prgram will hang. 21 22 You cannot change the sizes once they have been set 23 24 Level: intermediate 25 26 .seealso: DMNetworkCreate 27 @*/ 28 PetscErrorCode DMNetworkSetSizes(DM dm, PetscInt nV, PetscInt nE, PetscInt NV, PetscInt NE) 29 { 30 PetscErrorCode ierr; 31 DM_Network *network = (DM_Network*) dm->data; 32 PetscInt a[2],b[2]; 33 34 PetscFunctionBegin; 35 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 36 if (NV > 0) PetscValidLogicalCollectiveInt(dm,NV,4); 37 if (NE > 0) PetscValidLogicalCollectiveInt(dm,NE,5); 38 if (NV > 0 && nV > NV) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local vertex size %D cannot be larger than global vertex size %D",nV,NV); 39 if (NE > 0 && nE > NE) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local edge size %D cannot be larger than global edge size %D",nE,NE); 40 if ((network->nNodes >= 0 || network->NNodes >= 0) && (network->nNodes != nV || network->NNodes != NV)) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot change/reset vertex sizes to %D local %D global after previously setting them to %D local %D global",nV,NV,network->nNodes,network->NNodes); 41 if ((network->nEdges >= 0 || network->NEdges >= 0) && (network->nEdges != nE || network->NEdges != NE)) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot change/reset edge sizes to %D local %D global after previously setting them to %D local %D global",nE,NE,network->nEdges,network->NEdges); 42 if (NE < 0 || NV < 0) { 43 a[0] = nV; a[1] = nE; 44 ierr = MPIU_Allreduce(a,b,2,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 45 NV = b[0]; NE = b[1]; 46 } 47 network->nNodes = nV; 48 network->NNodes = NV; 49 network->nEdges = nE; 50 network->NEdges = NE; 51 PetscFunctionReturn(0); 52 } 53 54 #undef __FUNCT__ 55 #define __FUNCT__ "DMNetworkSetEdgeList" 56 /*@ 57 DMNetworkSetEdgeList - Sets the list of local edges (vertex connectivity) for the network 58 59 Logically collective on DM 60 61 Input Parameters: 62 . edges - list of edges 63 64 Notes: 65 There is no copy involved in this operation, only the pointer is referenced. The edgelist should 66 not be destroyed before the call to DMNetworkLayoutSetUp 67 68 Level: intermediate 69 70 .seealso: DMNetworkCreate, DMNetworkSetSizes 71 @*/ 72 PetscErrorCode DMNetworkSetEdgeList(DM dm, int edgelist[]) 73 { 74 DM_Network *network = (DM_Network*) dm->data; 75 76 PetscFunctionBegin; 77 network->edges = edgelist; 78 PetscFunctionReturn(0); 79 } 80 81 #undef __FUNCT__ 82 #define __FUNCT__ "DMNetworkLayoutSetUp" 83 /*@ 84 DMNetworkLayoutSetUp - Sets up the bare layout (graph) for the network 85 86 Collective on DM 87 88 Input Parameters 89 . DM - the dmnetwork object 90 91 Notes: 92 This routine should be called after the network sizes and edgelists have been provided. It creates 93 the bare layout of the network and sets up the network to begin insertion of components. 94 95 All the components should be registered before calling this routine. 96 97 Level: intermediate 98 99 .seealso: DMNetworkSetSizes, DMNetworkSetEdgeList 100 @*/ 101 PetscErrorCode DMNetworkLayoutSetUp(DM dm) 102 { 103 PetscErrorCode ierr; 104 DM_Network *network = (DM_Network*) dm->data; 105 PetscInt dim = 1; /* One dimensional network */ 106 PetscInt numCorners=2; 107 PetscInt spacedim=2; 108 double *vertexcoords=NULL; 109 PetscInt i; 110 PetscInt ndata; 111 112 PetscFunctionBegin; 113 if (network->nNodes) { 114 ierr = PetscCalloc1(numCorners*network->nNodes,&vertexcoords);CHKERRQ(ierr); 115 } 116 ierr = DMPlexCreateFromCellList(PetscObjectComm((PetscObject)dm),dim,network->nEdges,network->nNodes,numCorners,PETSC_FALSE,network->edges,spacedim,vertexcoords,&network->plex);CHKERRQ(ierr); 117 if (network->nNodes) { 118 ierr = PetscFree(vertexcoords);CHKERRQ(ierr); 119 } 120 ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr); 121 ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr); 122 ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr); 123 124 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DataSection);CHKERRQ(ierr); 125 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DofSection);CHKERRQ(ierr); 126 ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr); 127 ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr); 128 129 network->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 130 ierr = PetscCalloc1(network->pEnd-network->pStart,&network->header);CHKERRQ(ierr); 131 for (i = network->pStart; i < network->pEnd; i++) { 132 network->header[i].ndata = 0; 133 ndata = network->header[i].ndata; 134 ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr); 135 network->header[i].offset[ndata] = 0; 136 } 137 ierr = PetscMalloc1(network->pEnd-network->pStart,&network->cvalue);CHKERRQ(ierr); 138 PetscFunctionReturn(0); 139 } 140 141 #undef __FUNCT__ 142 #define __FUNCT__ "DMNetworkRegisterComponent" 143 /*@ 144 DMNetworkRegisterComponent - Registers the network component 145 146 Logically collective on DM 147 148 Input Parameters 149 + dm - the network object 150 . name - the component name 151 - size - the storage size in bytes for this component data 152 153 Output Parameters 154 . key - an integer key that defines the component 155 156 Notes 157 This routine should be called by all processors before calling DMNetworkLayoutSetup(). 158 159 Level: intermediate 160 161 .seealso: DMNetworkLayoutSetUp, DMNetworkCreate 162 @*/ 163 PetscErrorCode DMNetworkRegisterComponent(DM dm,const char *name,PetscInt size,PetscInt *key) 164 { 165 PetscErrorCode ierr; 166 DM_Network *network = (DM_Network*) dm->data; 167 DMNetworkComponent *component=&network->component[network->ncomponent]; 168 PetscBool flg=PETSC_FALSE; 169 PetscInt i; 170 171 PetscFunctionBegin; 172 173 for (i=0; i < network->ncomponent; i++) { 174 ierr = PetscStrcmp(component->name,name,&flg);CHKERRQ(ierr); 175 if (flg) { 176 *key = i; 177 PetscFunctionReturn(0); 178 } 179 } 180 181 ierr = PetscStrcpy(component->name,name);CHKERRQ(ierr); 182 component->size = size/sizeof(DMNetworkComponentGenericDataType); 183 *key = network->ncomponent; 184 network->ncomponent++; 185 PetscFunctionReturn(0); 186 } 187 188 #undef __FUNCT__ 189 #define __FUNCT__ "DMNetworkGetVertexRange" 190 /*@ 191 DMNetworkGetVertexRange - Get the bounds [start, end) for the vertices. 192 193 Not Collective 194 195 Input Parameters: 196 + dm - The DMNetwork object 197 198 Output Paramters: 199 + vStart - The first vertex point 200 - vEnd - One beyond the last vertex point 201 202 Level: intermediate 203 204 .seealso: DMNetworkGetEdgeRange 205 @*/ 206 PetscErrorCode DMNetworkGetVertexRange(DM dm,PetscInt *vStart,PetscInt *vEnd) 207 { 208 DM_Network *network = (DM_Network*)dm->data; 209 210 PetscFunctionBegin; 211 if (vStart) *vStart = network->vStart; 212 if (vEnd) *vEnd = network->vEnd; 213 PetscFunctionReturn(0); 214 } 215 216 #undef __FUNCT__ 217 #define __FUNCT__ "DMNetworkGetEdgeRange" 218 /*@ 219 DMNetworkGetEdgeRange - Get the bounds [start, end) for the edges. 220 221 Not Collective 222 223 Input Parameters: 224 + dm - The DMNetwork object 225 226 Output Paramters: 227 + eStart - The first edge point 228 - eEnd - One beyond the last edge point 229 230 Level: intermediate 231 232 .seealso: DMNetworkGetVertexRange 233 @*/ 234 PetscErrorCode DMNetworkGetEdgeRange(DM dm,PetscInt *eStart,PetscInt *eEnd) 235 { 236 DM_Network *network = (DM_Network*)dm->data; 237 238 PetscFunctionBegin; 239 if (eStart) *eStart = network->eStart; 240 if (eEnd) *eEnd = network->eEnd; 241 PetscFunctionReturn(0); 242 } 243 244 #undef __FUNCT__ 245 #define __FUNCT__ "DMNetworkAddComponent" 246 /*@ 247 DMNetworkAddComponent - Adds a network component at the given point (vertex/edge) 248 249 Not Collective 250 251 Input Parameters: 252 + dm - The DMNetwork object 253 . p - vertex/edge point 254 . componentkey - component key returned while registering the component 255 - compvalue - pointer to the data structure for the component 256 257 Level: intermediate 258 259 .seealso: DMNetworkGetVertexRange, DMNetworkGetEdgeRange, DMNetworkRegisterComponent 260 @*/ 261 PetscErrorCode DMNetworkAddComponent(DM dm, PetscInt p,PetscInt componentkey,void* compvalue) 262 { 263 DM_Network *network = (DM_Network*)dm->data; 264 DMNetworkComponent *component = &network->component[componentkey]; 265 DMNetworkComponentHeader header = &network->header[p]; 266 DMNetworkComponentValue cvalue = &network->cvalue[p]; 267 PetscErrorCode ierr; 268 269 PetscFunctionBegin; 270 header->size[header->ndata] = component->size; 271 ierr = PetscSectionAddDof(network->DataSection,p,component->size);CHKERRQ(ierr); 272 header->key[header->ndata] = componentkey; 273 if (header->ndata != 0) header->offset[header->ndata] = header->offset[header->ndata-1] + header->size[header->ndata-1]; 274 275 cvalue->data[header->ndata] = (void*)compvalue; 276 header->ndata++; 277 PetscFunctionReturn(0); 278 } 279 280 #undef __FUNCT__ 281 #define __FUNCT__ "DMNetworkGetNumComponents" 282 /*@ 283 DMNetworkGetNumComponents - Get the number of components at a vertex/edge 284 285 Not Collective 286 287 Input Parameters: 288 + dm - The DMNetwork object 289 . p - vertex/edge point 290 291 Output Parameters: 292 . numcomponents - Number of components at the vertex/edge 293 294 Level: intermediate 295 296 .seealso: DMNetworkRegisterComponent, DMNetworkAddComponent 297 @*/ 298 PetscErrorCode DMNetworkGetNumComponents(DM dm,PetscInt p,PetscInt *numcomponents) 299 { 300 PetscErrorCode ierr; 301 PetscInt offset; 302 DM_Network *network = (DM_Network*)dm->data; 303 304 PetscFunctionBegin; 305 ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 306 *numcomponents = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 307 PetscFunctionReturn(0); 308 } 309 310 #undef __FUNCT__ 311 #define __FUNCT__ "DMNetworkGetComponentTypeOffset" 312 /*@ 313 DMNetworkGetComponentTypeOffset - Gets the type along with the offset for indexing the 314 component value from the component data array 315 316 Not Collective 317 318 Input Parameters: 319 + dm - The DMNetwork object 320 . p - vertex/edge point 321 - compnum - component number 322 323 Output Parameters: 324 + compkey - the key obtained when registering the component 325 - offset - offset into the component data array associated with the vertex/edge point 326 327 Notes: 328 Typical usage: 329 330 DMNetworkGetComponentDataArray(dm, &arr); 331 DMNetworkGetVertex/EdgeRange(dm,&Start,&End); 332 Loop over vertices or edges 333 DMNetworkGetNumComponents(dm,v,&numcomps); 334 Loop over numcomps 335 DMNetworkGetComponentTypeOffset(dm,v,compnum,&key,&offset); 336 compdata = (UserCompDataType)(arr+offset); 337 338 Level: intermediate 339 340 .seealso: DMNetworkGetNumComponents, DMNetworkGetComponentDataArray, 341 @*/ 342 PetscErrorCode DMNetworkGetComponentTypeOffset(DM dm,PetscInt p, PetscInt compnum, PetscInt *compkey, PetscInt *offset) 343 { 344 PetscErrorCode ierr; 345 PetscInt offsetp; 346 DMNetworkComponentHeader header; 347 DM_Network *network = (DM_Network*)dm->data; 348 349 PetscFunctionBegin; 350 if (network->dataheadersize*sizeof(DMNetworkComponentGenericDataType) % sizeof(PetscScalar)) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_PLIB,"Network dataheadersize %D is not divisible by sizeof(PetscScalar) %D",network->dataheadersize,(PetscInt)sizeof(PetscScalar)); 351 ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 352 if (offsetp*sizeof(DMNetworkComponentGenericDataType) % sizeof(PetscScalar)) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_PLIB,"Offsetp %D is not divisible by sizeof(PetscScalar) %D",offsetp,(PetscInt)sizeof(PetscScalar)); 353 header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 354 *compkey = header->key[compnum]; 355 if (header->offset[compnum]*sizeof(DMNetworkComponentGenericDataType) % sizeof(PetscScalar)) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_PLIB,"header offset[compnum] %D is not divisible by sizeof(PetscScalar) %D",header->offset[compnum],(PetscInt)sizeof(PetscScalar)); 356 *offset = offsetp+network->dataheadersize+header->offset[compnum]; 357 if (*offset*sizeof(DMNetworkComponentGenericDataType) % sizeof(PetscScalar)) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_PLIB,"Offset %D is not divisible by sizeof(PetscScalar) %D",*offset,(PetscInt)sizeof(PetscScalar)); 358 PetscFunctionReturn(0); 359 } 360 361 #undef __FUNCT__ 362 #define __FUNCT__ "DMNetworkGetVariableOffset" 363 /*@ 364 DMNetworkGetVariableOffset - Get the offset for accessing the variable associated with the given vertex/edge from the local vector. 365 366 Not Collective 367 368 Input Parameters: 369 + dm - The DMNetwork object 370 - p - the edge/vertex point 371 372 Output Parameters: 373 . offset - the offset 374 375 Level: intermediate 376 377 .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 378 @*/ 379 PetscErrorCode DMNetworkGetVariableOffset(DM dm,PetscInt p,PetscInt *offset) 380 { 381 PetscErrorCode ierr; 382 DM_Network *network = (DM_Network*)dm->data; 383 384 PetscFunctionBegin; 385 ierr = PetscSectionGetOffset(network->DofSection,p,offset);CHKERRQ(ierr); 386 PetscFunctionReturn(0); 387 } 388 389 #undef __FUNCT__ 390 #define __FUNCT__ "DMNetworkGetVariableGlobalOffset" 391 /*@ 392 DMNetworkGetVariableGlobalOffset - Get the global offset for the variable associated with the given vertex/edge from the global vector. 393 394 Not Collective 395 396 Input Parameters: 397 + dm - The DMNetwork object 398 - p - the edge/vertex point 399 400 Output Parameters: 401 . offsetg - the offset 402 403 Level: intermediate 404 405 .seealso: DMNetworkGetVariableOffset, DMGetLocalVector 406 @*/ 407 PetscErrorCode DMNetworkGetVariableGlobalOffset(DM dm,PetscInt p,PetscInt *offsetg) 408 { 409 PetscErrorCode ierr; 410 DM_Network *network = (DM_Network*)dm->data; 411 412 PetscFunctionBegin; 413 ierr = PetscSectionGetOffset(network->GlobalDofSection,p,offsetg);CHKERRQ(ierr); 414 PetscFunctionReturn(0); 415 } 416 417 #undef __FUNCT__ 418 #define __FUNCT__ "DMNetworkAddNumVariables" 419 /*@ 420 DMNetworkAddNumVariables - Add number of variables associated with a given point. 421 422 Not Collective 423 424 Input Parameters: 425 + dm - The DMNetworkObject 426 . p - the vertex/edge point 427 - nvar - number of additional variables 428 429 Level: intermediate 430 431 .seealso: DMNetworkSetNumVariables 432 @*/ 433 PetscErrorCode DMNetworkAddNumVariables(DM dm,PetscInt p,PetscInt nvar) 434 { 435 PetscErrorCode ierr; 436 DM_Network *network = (DM_Network*)dm->data; 437 438 PetscFunctionBegin; 439 ierr = PetscSectionAddDof(network->DofSection,p,nvar);CHKERRQ(ierr); 440 PetscFunctionReturn(0); 441 } 442 443 #undef __FUNCT__ 444 #define __FUNCT__ "DMNetworkGetNumVariables" 445 /*@ 446 DMNetworkGetNumVariables - Gets number of variables for a vertex/edge point. 447 448 Not Collective 449 450 Input Parameters: 451 + dm - The DMNetworkObject 452 - p - the vertex/edge point 453 454 Output Parameters: 455 . nvar - number of variables 456 457 Level: intermediate 458 459 .seealso: DMNetworkAddNumVariables, DMNetworkSddNumVariables 460 @*/ 461 PetscErrorCode DMNetworkGetNumVariables(DM dm,PetscInt p,PetscInt *nvar) 462 { 463 PetscErrorCode ierr; 464 DM_Network *network = (DM_Network*)dm->data; 465 466 PetscFunctionBegin; 467 ierr = PetscSectionGetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 468 PetscFunctionReturn(0); 469 } 470 471 #undef __FUNCT__ 472 #define __FUNCT__ "DMNetworkSetNumVariables" 473 /*@ 474 DMNetworkSetNumVariables - Sets number of variables for a vertex/edge point. 475 476 Not Collective 477 478 Input Parameters: 479 + dm - The DMNetworkObject 480 . p - the vertex/edge point 481 - nvar - number of variables 482 483 Level: intermediate 484 485 .seealso: DMNetworkAddNumVariables 486 @*/ 487 PetscErrorCode DMNetworkSetNumVariables(DM dm,PetscInt p,PetscInt nvar) 488 { 489 PetscErrorCode ierr; 490 DM_Network *network = (DM_Network*)dm->data; 491 492 PetscFunctionBegin; 493 ierr = PetscSectionSetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 494 PetscFunctionReturn(0); 495 } 496 497 /* Sets up the array that holds the data for all components and its associated section. This 498 function is called during DMSetUp() */ 499 #undef __FUNCT__ 500 #define __FUNCT__ "DMNetworkComponentSetUp" 501 PetscErrorCode DMNetworkComponentSetUp(DM dm) 502 { 503 PetscErrorCode ierr; 504 DM_Network *network = (DM_Network*)dm->data; 505 PetscInt arr_size; 506 PetscInt p,offset,offsetp; 507 DMNetworkComponentHeader header; 508 DMNetworkComponentValue cvalue; 509 DMNetworkComponentGenericDataType *componentdataarray; 510 PetscInt ncomp, i; 511 512 PetscFunctionBegin; 513 ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr); 514 ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr); 515 ierr = PetscMalloc1(arr_size,&network->componentdataarray);CHKERRQ(ierr); 516 componentdataarray = network->componentdataarray; 517 for (p = network->pStart; p < network->pEnd; p++) { 518 ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 519 /* Copy header */ 520 header = &network->header[p]; 521 ierr = PetscMemcpy(componentdataarray+offsetp,header,network->dataheadersize*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 522 /* Copy data */ 523 cvalue = &network->cvalue[p]; 524 ncomp = header->ndata; 525 for (i = 0; i < ncomp; i++) { 526 offset = offsetp + network->dataheadersize + header->offset[i]; 527 ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 528 } 529 } 530 PetscFunctionReturn(0); 531 } 532 533 /* Sets up the section for dofs. This routine is called during DMSetUp() */ 534 #undef __FUNCT__ 535 #define __FUNCT__ "DMNetworkVariablesSetUp" 536 PetscErrorCode DMNetworkVariablesSetUp(DM dm) 537 { 538 PetscErrorCode ierr; 539 DM_Network *network = (DM_Network*)dm->data; 540 541 PetscFunctionBegin; 542 ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr); 543 PetscFunctionReturn(0); 544 } 545 546 #undef __FUNCT__ 547 #define __FUNCT__ "DMNetworkGetComponentDataArray" 548 /*@C 549 DMNetworkGetComponentDataArray - Returns the component data array 550 551 Not Collective 552 553 Input Parameters: 554 . dm - The DMNetwork Object 555 556 Output Parameters: 557 . componentdataarray - array that holds data for all components 558 559 Level: intermediate 560 561 .seealso: DMNetworkGetComponentTypeOffset, DMNetworkGetNumComponents 562 @*/ 563 PetscErrorCode DMNetworkGetComponentDataArray(DM dm,DMNetworkComponentGenericDataType **componentdataarray) 564 { 565 DM_Network *network = (DM_Network*)dm->data; 566 567 PetscFunctionBegin; 568 *componentdataarray = network->componentdataarray; 569 PetscFunctionReturn(0); 570 } 571 572 #undef __FUNCT__ 573 #define __FUNCT__ "DMNetworkDistribute" 574 /*@ 575 DMNetworkDistribute - Distributes the network and moves associated component data. 576 577 Collective 578 579 Input Parameter: 580 + oldDM - the original DMNetwork object 581 - overlap - The overlap of partitions, 0 is the default 582 583 Output Parameter: 584 . distDM - the distributed DMNetwork object 585 586 Notes: 587 This routine should be called only when using multiple processors. 588 589 Distributes the network with <overlap>-overlapping partitioning of the edges. 590 591 Level: intermediate 592 593 .seealso: DMNetworkCreate 594 @*/ 595 PetscErrorCode DMNetworkDistribute(DM oldDM, PetscInt overlap,DM *distDM) 596 { 597 PetscErrorCode ierr; 598 DM_Network *oldDMnetwork = (DM_Network*)oldDM->data; 599 PetscSF pointsf; 600 DM newDM; 601 DM_Network *newDMnetwork; 602 603 PetscFunctionBegin; 604 ierr = DMNetworkCreate(PetscObjectComm((PetscObject)oldDM),&newDM);CHKERRQ(ierr); 605 newDMnetwork = (DM_Network*)newDM->data; 606 newDMnetwork->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 607 /* Distribute plex dm and dof section */ 608 ierr = DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr); 609 /* Distribute dof section */ 610 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)oldDM),&newDMnetwork->DofSection);CHKERRQ(ierr); 611 ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr); 612 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)oldDM),&newDMnetwork->DataSection);CHKERRQ(ierr); 613 /* Distribute data and associated section */ 614 ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPIU_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr); 615 /* Destroy point SF */ 616 ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr); 617 618 ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr); 619 ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr); 620 ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr); 621 newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart; 622 newDMnetwork->nNodes = newDMnetwork->vEnd - newDMnetwork->vStart; 623 newDMnetwork->NNodes = oldDMnetwork->NNodes; 624 newDMnetwork->NEdges = oldDMnetwork->NEdges; 625 /* Set Dof section as the default section for dm */ 626 ierr = DMSetDefaultSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr); 627 ierr = DMGetDefaultGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr); 628 629 *distDM = newDM; 630 PetscFunctionReturn(0); 631 } 632 633 #undef __FUNCT__ 634 #define __FUNCT__ "DMNetworkGetSupportingEdges" 635 /*@C 636 DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point 637 638 Not Collective 639 640 Input Parameters: 641 + dm - The DMNetwork object 642 - p - the vertex point 643 644 Output Paramters: 645 + nedges - number of edges connected to this vertex point 646 - edges - List of edge points 647 648 Level: intermediate 649 650 Fortran Notes: 651 Since it returns an array, this routine is only available in Fortran 90, and you must 652 include petsc.h90 in your code. 653 654 .seealso: DMNetworkCreate, DMNetworkGetConnectedNodes 655 @*/ 656 PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[]) 657 { 658 PetscErrorCode ierr; 659 DM_Network *network = (DM_Network*)dm->data; 660 661 PetscFunctionBegin; 662 ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr); 663 ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr); 664 PetscFunctionReturn(0); 665 } 666 667 #undef __FUNCT__ 668 #define __FUNCT__ "DMNetworkGetConnectedNodes" 669 /*@C 670 DMNetworkGetConnectedNodes - Return the connected edges for this edge point 671 672 Not Collective 673 674 Input Parameters: 675 + dm - The DMNetwork object 676 - p - the edge point 677 678 Output Paramters: 679 . vertices - vertices connected to this edge 680 681 Level: intermediate 682 683 Fortran Notes: 684 Since it returns an array, this routine is only available in Fortran 90, and you must 685 include petsc.h90 in your code. 686 687 .seealso: DMNetworkCreate, DMNetworkGetSupportingEdges 688 @*/ 689 PetscErrorCode DMNetworkGetConnectedNodes(DM dm,PetscInt edge,const PetscInt *vertices[]) 690 { 691 PetscErrorCode ierr; 692 DM_Network *network = (DM_Network*)dm->data; 693 694 PetscFunctionBegin; 695 ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr); 696 PetscFunctionReturn(0); 697 } 698 699 #undef __FUNCT__ 700 #define __FUNCT__ "DMNetworkIsGhostVertex" 701 /*@ 702 DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex 703 704 Not Collective 705 706 Input Parameters: 707 + dm - The DMNetwork object 708 . p - the vertex point 709 710 Output Parameter: 711 . isghost - TRUE if the vertex is a ghost point 712 713 Level: intermediate 714 715 .seealso: DMNetworkCreate, DMNetworkGetConnectedNodes, DMNetworkGetVertexRange 716 @*/ 717 PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost) 718 { 719 PetscErrorCode ierr; 720 DM_Network *network = (DM_Network*)dm->data; 721 PetscInt offsetg; 722 PetscSection sectiong; 723 724 PetscFunctionBegin; 725 *isghost = PETSC_FALSE; 726 ierr = DMGetDefaultGlobalSection(network->plex,§iong);CHKERRQ(ierr); 727 ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr); 728 if (offsetg < 0) *isghost = PETSC_TRUE; 729 PetscFunctionReturn(0); 730 } 731 732 #undef __FUNCT__ 733 #define __FUNCT__ "DMSetUp_Network" 734 PetscErrorCode DMSetUp_Network(DM dm) 735 { 736 PetscErrorCode ierr; 737 DM_Network *network=(DM_Network*)dm->data; 738 739 PetscFunctionBegin; 740 ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr); 741 ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr); 742 743 ierr = DMSetDefaultSection(network->plex,network->DofSection);CHKERRQ(ierr); 744 ierr = DMGetDefaultGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr); 745 PetscFunctionReturn(0); 746 } 747 748 #undef __FUNCT__ 749 #define __FUNCT__ "DMCreateMatrix_Network" 750 PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J) 751 { 752 PetscErrorCode ierr; 753 DM_Network *network = (DM_Network*) dm->data; 754 755 PetscFunctionBegin; 756 ierr = DMCreateMatrix(network->plex,J);CHKERRQ(ierr); 757 ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 758 PetscFunctionReturn(0); 759 } 760 761 #undef __FUNCT__ 762 #define __FUNCT__ "DMDestroy_Network" 763 PetscErrorCode DMDestroy_Network(DM dm) 764 { 765 PetscErrorCode ierr; 766 DM_Network *network = (DM_Network*) dm->data; 767 768 PetscFunctionBegin; 769 if (--network->refct > 0) PetscFunctionReturn(0); 770 ierr = DMDestroy(&network->plex);CHKERRQ(ierr); 771 network->edges = NULL; 772 ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr); 773 ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr); 774 /* ierr = PetscSectionDestroy(&network->GlobalDofSection);CHKERRQ(ierr); */ 775 ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr); 776 ierr = PetscFree(network->cvalue);CHKERRQ(ierr); 777 ierr = PetscFree(network->header);CHKERRQ(ierr); 778 ierr = PetscFree(network);CHKERRQ(ierr); 779 PetscFunctionReturn(0); 780 } 781 782 #undef __FUNCT__ 783 #define __FUNCT__ "DMView_Network" 784 PetscErrorCode DMView_Network(DM dm, PetscViewer viewer) 785 { 786 PetscErrorCode ierr; 787 DM_Network *network = (DM_Network*) dm->data; 788 789 PetscFunctionBegin; 790 ierr = DMView(network->plex,viewer);CHKERRQ(ierr); 791 PetscFunctionReturn(0); 792 } 793 794 #undef __FUNCT__ 795 #define __FUNCT__ "DMGlobalToLocalBegin_Network" 796 PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l) 797 { 798 PetscErrorCode ierr; 799 DM_Network *network = (DM_Network*) dm->data; 800 801 PetscFunctionBegin; 802 ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr); 803 PetscFunctionReturn(0); 804 } 805 806 #undef __FUNCT__ 807 #define __FUNCT__ "DMGlobalToLocalEnd_Network" 808 PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l) 809 { 810 PetscErrorCode ierr; 811 DM_Network *network = (DM_Network*) dm->data; 812 813 PetscFunctionBegin; 814 ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr); 815 PetscFunctionReturn(0); 816 } 817 818 #undef __FUNCT__ 819 #define __FUNCT__ "DMLocalToGlobalBegin_Network" 820 PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g) 821 { 822 PetscErrorCode ierr; 823 DM_Network *network = (DM_Network*) dm->data; 824 825 PetscFunctionBegin; 826 ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr); 827 PetscFunctionReturn(0); 828 } 829 830 #undef __FUNCT__ 831 #define __FUNCT__ "DMLocalToGlobalEnd_Network" 832 PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g) 833 { 834 PetscErrorCode ierr; 835 DM_Network *network = (DM_Network*) dm->data; 836 837 PetscFunctionBegin; 838 ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr); 839 PetscFunctionReturn(0); 840 } 841