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 = MPI_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 = PetscMalloc1(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 = PetscMalloc1((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 ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 351 header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 352 *compkey = header->key[compnum]; 353 *offset = offsetp+network->dataheadersize+header->offset[compnum]; 354 PetscFunctionReturn(0); 355 } 356 357 #undef __FUNCT__ 358 #define __FUNCT__ "DMNetworkGetVariableOffset" 359 /*@ 360 DMNetworkGetVariableOffset - Get the offset for accessing the variable associated with the given vertex/edge from the local vector. 361 362 Not Collective 363 364 Input Parameters: 365 + dm - The DMNetwork object 366 - p - the edge/vertex point 367 368 Output Parameters: 369 . offset - the offset 370 371 Level: intermediate 372 373 .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 374 @*/ 375 PetscErrorCode DMNetworkGetVariableOffset(DM dm,PetscInt p,PetscInt *offset) 376 { 377 PetscErrorCode ierr; 378 DM_Network *network = (DM_Network*)dm->data; 379 380 PetscFunctionBegin; 381 ierr = PetscSectionGetOffset(network->DofSection,p,offset);CHKERRQ(ierr); 382 PetscFunctionReturn(0); 383 } 384 385 #undef __FUNCT__ 386 #define __FUNCT__ "DMNetworkGetVariableGlobalOffset" 387 /*@ 388 DMNetworkGetVariableGlobalOffset - Get the global offset for the variable associated with the given vertex/edge from the global vector. 389 390 Not Collective 391 392 Input Parameters: 393 + dm - The DMNetwork object 394 - p - the edge/vertex point 395 396 Output Parameters: 397 . offsetg - the offset 398 399 Level: intermediate 400 401 .seealso: DMNetworkGetVariableOffset, DMGetLocalVector 402 @*/ 403 PetscErrorCode DMNetworkGetVariableGlobalOffset(DM dm,PetscInt p,PetscInt *offsetg) 404 { 405 PetscErrorCode ierr; 406 DM_Network *network = (DM_Network*)dm->data; 407 408 PetscFunctionBegin; 409 ierr = PetscSectionGetOffset(network->GlobalDofSection,p,offsetg);CHKERRQ(ierr); 410 PetscFunctionReturn(0); 411 } 412 413 #undef __FUNCT__ 414 #define __FUNCT__ "DMNetworkAddNumVariables" 415 /*@ 416 DMNetworkAddNumVariables - Add number of variables associated with a given point. 417 418 Not Collective 419 420 Input Parameters: 421 + dm - The DMNetworkObject 422 . p - the vertex/edge point 423 - nvar - number of additional variables 424 425 Level: intermediate 426 427 .seealso: DMNetworkSetNumVariables 428 @*/ 429 PetscErrorCode DMNetworkAddNumVariables(DM dm,PetscInt p,PetscInt nvar) 430 { 431 PetscErrorCode ierr; 432 DM_Network *network = (DM_Network*)dm->data; 433 434 PetscFunctionBegin; 435 ierr = PetscSectionAddDof(network->DofSection,p,nvar);CHKERRQ(ierr); 436 PetscFunctionReturn(0); 437 } 438 439 #undef __FUNCT__ 440 #define __FUNCT__ "DMNetworkAddNumVariables" 441 /*@ 442 DMNetworkSetNumVariables - Sets number of variables for a vertex/edge point. 443 444 Not Collective 445 446 Input Parameters: 447 + dm - The DMNetworkObject 448 . p - the vertex/edge point 449 - nvar - number of variables 450 451 Level: intermediate 452 453 .seealso: DMNetworkAddNumVariables 454 @*/ 455 PetscErrorCode DMNetworkSetNumVariables(DM dm,PetscInt p,PetscInt nvar) 456 { 457 PetscErrorCode ierr; 458 DM_Network *network = (DM_Network*)dm->data; 459 460 PetscFunctionBegin; 461 ierr = PetscSectionSetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 462 PetscFunctionReturn(0); 463 } 464 465 /* Sets up the array that holds the data for all components and its associated section. This 466 function is called during DMSetUp() */ 467 #undef __FUNCT__ 468 #define __FUNCT__ "DMNetworkComponentSetUp" 469 PetscErrorCode DMNetworkComponentSetUp(DM dm) 470 { 471 PetscErrorCode ierr; 472 DM_Network *network = (DM_Network*)dm->data; 473 PetscInt arr_size; 474 PetscInt p,offset,offsetp; 475 DMNetworkComponentHeader header; 476 DMNetworkComponentValue cvalue; 477 DMNetworkComponentGenericDataType *componentdataarray; 478 PetscInt ncomp, i; 479 480 PetscFunctionBegin; 481 ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr); 482 ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr); 483 ierr = PetscMalloc1(arr_size,&network->componentdataarray);CHKERRQ(ierr); 484 componentdataarray = network->componentdataarray; 485 for (p = network->pStart; p < network->pEnd; p++) { 486 ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 487 /* Copy header */ 488 header = &network->header[p]; 489 ierr = PetscMemcpy(componentdataarray+offsetp,header,network->dataheadersize*sizeof(DMNetworkComponentGenericDataType)); 490 /* Copy data */ 491 cvalue = &network->cvalue[p]; 492 ncomp = header->ndata; 493 for (i = 0; i < ncomp; i++) { 494 offset = offsetp + network->dataheadersize + header->offset[i]; 495 ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType)); 496 } 497 } 498 PetscFunctionReturn(0); 499 } 500 501 /* Sets up the section for dofs. This routine is called during DMSetUp() */ 502 #undef __FUNCT__ 503 #define __FUNCT__ "DMNetworkVariablesSetUp" 504 PetscErrorCode DMNetworkVariablesSetUp(DM dm) 505 { 506 PetscErrorCode ierr; 507 DM_Network *network = (DM_Network*)dm->data; 508 509 PetscFunctionBegin; 510 ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr); 511 PetscFunctionReturn(0); 512 } 513 514 #undef __FUNCT__ 515 #define __FUNCT__ "DMNetworkGetComponentDataArray" 516 /*@C 517 DMNetworkGetComponentDataArray - Returns the component data array 518 519 Not Collective 520 521 Input Parameters: 522 . dm - The DMNetwork Object 523 524 Output Parameters: 525 . componentdataarray - array that holds data for all components 526 527 Level: intermediate 528 529 .seealso: DMNetworkGetComponentTypeOffset, DMNetworkGetNumComponents 530 @*/ 531 PetscErrorCode DMNetworkGetComponentDataArray(DM dm,DMNetworkComponentGenericDataType **componentdataarray) 532 { 533 DM_Network *network = (DM_Network*)dm->data; 534 535 PetscFunctionBegin; 536 *componentdataarray = network->componentdataarray; 537 PetscFunctionReturn(0); 538 } 539 540 #undef __FUNCT__ 541 #define __FUNCT__ "DMNetworkDistribute" 542 /*@ 543 DMNetworkDistribute - Distributes the network and moves associated component data. 544 545 Collective 546 547 Input Parameter: 548 + oldDM - the original DMNetwork object 549 . partitioner - The partitioning package, or NULL for the default 550 - overlap - The overlap of partitions, 0 is the default 551 552 Output Parameter: 553 . distDM - the distributed DMNetwork object 554 555 Notes: 556 This routine should be called only when using multiple processors. 557 558 Distributes the network with a non-overlapping partitioning of the edges. 559 560 Level: intermediate 561 562 .seealso: DMNetworkCreate 563 @*/ 564 PetscErrorCode DMNetworkDistribute(DM oldDM, const char partitioner[], PetscInt overlap,DM *distDM) 565 { 566 PetscErrorCode ierr; 567 DM_Network *oldDMnetwork = (DM_Network*)oldDM->data; 568 PetscSF pointsf; 569 DM newDM; 570 DM_Network *newDMnetwork; 571 572 PetscFunctionBegin; 573 ierr = DMNetworkCreate(PetscObjectComm((PetscObject)oldDM),&newDM);CHKERRQ(ierr); 574 newDMnetwork = (DM_Network*)newDM->data; 575 newDMnetwork->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 576 /* Distribute plex dm and dof section */ 577 ierr = DMPlexDistribute(oldDMnetwork->plex,partitioner,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr); 578 /* Distribute dof section */ 579 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)oldDM),&newDMnetwork->DofSection);CHKERRQ(ierr); 580 ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr); 581 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)oldDM),&newDMnetwork->DataSection);CHKERRQ(ierr); 582 /* Distribute data and associated section */ 583 ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPI_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr); 584 /* Destroy point SF */ 585 ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr); 586 587 ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr); 588 ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr); 589 ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr); 590 newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart; 591 newDMnetwork->nNodes = newDMnetwork->vEnd - newDMnetwork->vStart; 592 newDMnetwork->NNodes = oldDMnetwork->NNodes; 593 newDMnetwork->NEdges = oldDMnetwork->NEdges; 594 /* Set Dof section as the default section for dm */ 595 ierr = DMSetDefaultSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr); 596 ierr = DMGetDefaultGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr); 597 598 *distDM = newDM; 599 PetscFunctionReturn(0); 600 } 601 602 #undef __FUNCT__ 603 #define __FUNCT__ "DMNetworkGetSupportingEdges" 604 /*@C 605 DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point 606 607 Not Collective 608 609 Input Parameters: 610 + dm - The DMNetwork object 611 - p - the vertex point 612 613 Output Paramters: 614 + nedges - number of edges connected to this vertex point 615 - edges - List of edge points 616 617 Level: intermediate 618 619 Fortran Notes: 620 Since it returns an array, this routine is only available in Fortran 90, and you must 621 include petsc.h90 in your code. 622 623 .seealso: DMNetworkCreate, DMNetworkGetConnectedNodes 624 @*/ 625 PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[]) 626 { 627 PetscErrorCode ierr; 628 DM_Network *network = (DM_Network*)dm->data; 629 630 PetscFunctionBegin; 631 ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr); 632 ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr); 633 PetscFunctionReturn(0); 634 } 635 636 #undef __FUNCT__ 637 #define __FUNCT__ "DMNetworkGetConnectedNodes" 638 /*@C 639 DMNetworkGetConnectedNodes - Return the connected edges for this edge point 640 641 Not Collective 642 643 Input Parameters: 644 + dm - The DMNetwork object 645 - p - the edge point 646 647 Output Paramters: 648 . vertices - vertices connected to this edge 649 650 Level: intermediate 651 652 Fortran Notes: 653 Since it returns an array, this routine is only available in Fortran 90, and you must 654 include petsc.h90 in your code. 655 656 .seealso: DMNetworkCreate, DMNetworkGetSupportingEdges 657 @*/ 658 PetscErrorCode DMNetworkGetConnectedNodes(DM dm,PetscInt edge,const PetscInt *vertices[]) 659 { 660 PetscErrorCode ierr; 661 DM_Network *network = (DM_Network*)dm->data; 662 663 PetscFunctionBegin; 664 ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr); 665 PetscFunctionReturn(0); 666 } 667 668 #undef __FUNCT__ 669 #define __FUNCT__ "DMNetworkIsGhostVertex" 670 /*@ 671 DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex 672 673 Not Collective 674 675 Input Parameters: 676 + dm - The DMNetwork object 677 . p - the vertex point 678 679 Output Parameter: 680 . isghost - TRUE if the vertex is a ghost point 681 682 Level: intermediate 683 684 .seealso: DMNetworkCreate, DMNetworkGetConnectedNodes, DMNetworkGetVertexRange 685 @*/ 686 PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost) 687 { 688 PetscErrorCode ierr; 689 DM_Network *network = (DM_Network*)dm->data; 690 PetscInt offsetg; 691 PetscSection sectiong; 692 693 PetscFunctionBegin; 694 *isghost = PETSC_FALSE; 695 ierr = DMGetDefaultGlobalSection(network->plex,§iong);CHKERRQ(ierr); 696 ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr); 697 if (offsetg < 0) *isghost = PETSC_TRUE; 698 PetscFunctionReturn(0); 699 } 700 701 #undef __FUNCT__ 702 #define __FUNCT__ "DMSetUp_Network" 703 PetscErrorCode DMSetUp_Network(DM dm) 704 { 705 PetscErrorCode ierr; 706 DM_Network *network=(DM_Network*)dm->data; 707 708 PetscFunctionBegin; 709 ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr); 710 ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr); 711 712 ierr = DMSetDefaultSection(network->plex,network->DofSection);CHKERRQ(ierr); 713 ierr = DMGetDefaultGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr); 714 PetscFunctionReturn(0); 715 } 716 717 #undef __FUNCT__ 718 #define __FUNCT__ "DMCreateMatrix_Network" 719 PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J) 720 { 721 PetscErrorCode ierr; 722 DM_Network *network = (DM_Network*) dm->data; 723 724 PetscFunctionBegin; 725 ierr = DMCreateMatrix(network->plex,J);CHKERRQ(ierr); 726 ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 727 PetscFunctionReturn(0); 728 } 729 730 #undef __FUNCT__ 731 #define __FUNCT__ "DMDestroy_Network" 732 PetscErrorCode DMDestroy_Network(DM dm) 733 { 734 PetscErrorCode ierr; 735 DM_Network *network = (DM_Network*) dm->data; 736 737 PetscFunctionBegin; 738 ierr = DMDestroy(&network->plex);CHKERRQ(ierr); 739 network->edges = NULL; 740 ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr); 741 ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr); 742 /* ierr = PetscSectionDestroy(&network->GlobalDofSection);CHKERRQ(ierr); */ 743 ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr); 744 ierr = PetscFree(network->cvalue);CHKERRQ(ierr); 745 ierr = PetscFree(network->header);CHKERRQ(ierr); 746 ierr = PetscFree(network);CHKERRQ(ierr); 747 PetscFunctionReturn(0); 748 } 749 750 #undef __FUNCT__ 751 #define __FUNCT__ "DMView_Network" 752 PetscErrorCode DMView_Network(DM dm, PetscViewer viewer) 753 { 754 PetscErrorCode ierr; 755 DM_Network *network = (DM_Network*) dm->data; 756 757 PetscFunctionBegin; 758 ierr = DMView(network->plex,viewer);CHKERRQ(ierr); 759 PetscFunctionReturn(0); 760 } 761 762 #undef __FUNCT__ 763 #define __FUNCT__ "DMGlobalToLocalBegin_Network" 764 PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l) 765 { 766 PetscErrorCode ierr; 767 DM_Network *network = (DM_Network*) dm->data; 768 769 PetscFunctionBegin; 770 ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr); 771 PetscFunctionReturn(0); 772 } 773 774 #undef __FUNCT__ 775 #define __FUNCT__ "DMGlobalToLocalEnd_Network" 776 PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l) 777 { 778 PetscErrorCode ierr; 779 DM_Network *network = (DM_Network*) dm->data; 780 781 PetscFunctionBegin; 782 ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr); 783 PetscFunctionReturn(0); 784 } 785 786 #undef __FUNCT__ 787 #define __FUNCT__ "DMLocalToGlobalBegin_Network" 788 PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g) 789 { 790 PetscErrorCode ierr; 791 DM_Network *network = (DM_Network*) dm->data; 792 793 PetscFunctionBegin; 794 ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr); 795 PetscFunctionReturn(0); 796 } 797 798 #undef __FUNCT__ 799 #define __FUNCT__ "DMLocalToGlobalEnd_Network" 800 PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g) 801 { 802 PetscErrorCode ierr; 803 DM_Network *network = (DM_Network*) dm->data; 804 805 PetscFunctionBegin; 806 ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr); 807 PetscFunctionReturn(0); 808 } 809