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 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__ "DMNetworkGetNumVariables" 441 /*@ 442 DMNetworkGetNumVariables - Gets 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 450 Output Parameters: 451 . nvar - number of variables 452 453 Level: intermediate 454 455 .seealso: DMNetworkAddNumVariables, DMNetworkSddNumVariables 456 @*/ 457 PetscErrorCode DMNetworkGetNumVariables(DM dm,PetscInt p,PetscInt *nvar) 458 { 459 PetscErrorCode ierr; 460 DM_Network *network = (DM_Network*)dm->data; 461 462 PetscFunctionBegin; 463 ierr = PetscSectionGetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 464 PetscFunctionReturn(0); 465 } 466 467 #undef __FUNCT__ 468 #define __FUNCT__ "DMNetworkSetNumVariables" 469 /*@ 470 DMNetworkSetNumVariables - Sets number of variables for a vertex/edge point. 471 472 Not Collective 473 474 Input Parameters: 475 + dm - The DMNetworkObject 476 . p - the vertex/edge point 477 - nvar - number of variables 478 479 Level: intermediate 480 481 .seealso: DMNetworkAddNumVariables 482 @*/ 483 PetscErrorCode DMNetworkSetNumVariables(DM dm,PetscInt p,PetscInt nvar) 484 { 485 PetscErrorCode ierr; 486 DM_Network *network = (DM_Network*)dm->data; 487 488 PetscFunctionBegin; 489 ierr = PetscSectionSetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 490 PetscFunctionReturn(0); 491 } 492 493 /* Sets up the array that holds the data for all components and its associated section. This 494 function is called during DMSetUp() */ 495 #undef __FUNCT__ 496 #define __FUNCT__ "DMNetworkComponentSetUp" 497 PetscErrorCode DMNetworkComponentSetUp(DM dm) 498 { 499 PetscErrorCode ierr; 500 DM_Network *network = (DM_Network*)dm->data; 501 PetscInt arr_size; 502 PetscInt p,offset,offsetp; 503 DMNetworkComponentHeader header; 504 DMNetworkComponentValue cvalue; 505 DMNetworkComponentGenericDataType *componentdataarray; 506 PetscInt ncomp, i; 507 508 PetscFunctionBegin; 509 ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr); 510 ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr); 511 ierr = PetscMalloc1(arr_size,&network->componentdataarray);CHKERRQ(ierr); 512 componentdataarray = network->componentdataarray; 513 for (p = network->pStart; p < network->pEnd; p++) { 514 ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 515 /* Copy header */ 516 header = &network->header[p]; 517 ierr = PetscMemcpy(componentdataarray+offsetp,header,network->dataheadersize*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 518 /* Copy data */ 519 cvalue = &network->cvalue[p]; 520 ncomp = header->ndata; 521 for (i = 0; i < ncomp; i++) { 522 offset = offsetp + network->dataheadersize + header->offset[i]; 523 ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 524 } 525 } 526 PetscFunctionReturn(0); 527 } 528 529 /* Sets up the section for dofs. This routine is called during DMSetUp() */ 530 #undef __FUNCT__ 531 #define __FUNCT__ "DMNetworkVariablesSetUp" 532 PetscErrorCode DMNetworkVariablesSetUp(DM dm) 533 { 534 PetscErrorCode ierr; 535 DM_Network *network = (DM_Network*)dm->data; 536 537 PetscFunctionBegin; 538 ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr); 539 PetscFunctionReturn(0); 540 } 541 542 #undef __FUNCT__ 543 #define __FUNCT__ "DMNetworkGetComponentDataArray" 544 /*@C 545 DMNetworkGetComponentDataArray - Returns the component data array 546 547 Not Collective 548 549 Input Parameters: 550 . dm - The DMNetwork Object 551 552 Output Parameters: 553 . componentdataarray - array that holds data for all components 554 555 Level: intermediate 556 557 .seealso: DMNetworkGetComponentTypeOffset, DMNetworkGetNumComponents 558 @*/ 559 PetscErrorCode DMNetworkGetComponentDataArray(DM dm,DMNetworkComponentGenericDataType **componentdataarray) 560 { 561 DM_Network *network = (DM_Network*)dm->data; 562 563 PetscFunctionBegin; 564 *componentdataarray = network->componentdataarray; 565 PetscFunctionReturn(0); 566 } 567 568 #undef __FUNCT__ 569 #define __FUNCT__ "DMNetworkDistribute" 570 /*@ 571 DMNetworkDistribute - Distributes the network and moves associated component data. 572 573 Collective 574 575 Input Parameter: 576 + oldDM - the original DMNetwork object 577 - overlap - The overlap of partitions, 0 is the default 578 579 Output Parameter: 580 . distDM - the distributed DMNetwork object 581 582 Notes: 583 This routine should be called only when using multiple processors. 584 585 Distributes the network with <overlap>-overlapping partitioning of the edges. 586 587 Level: intermediate 588 589 .seealso: DMNetworkCreate 590 @*/ 591 PetscErrorCode DMNetworkDistribute(DM oldDM, PetscInt overlap,DM *distDM) 592 { 593 PetscErrorCode ierr; 594 DM_Network *oldDMnetwork = (DM_Network*)oldDM->data; 595 PetscSF pointsf; 596 DM newDM; 597 DM_Network *newDMnetwork; 598 599 PetscFunctionBegin; 600 ierr = DMNetworkCreate(PetscObjectComm((PetscObject)oldDM),&newDM);CHKERRQ(ierr); 601 newDMnetwork = (DM_Network*)newDM->data; 602 newDMnetwork->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 603 /* Distribute plex dm and dof section */ 604 ierr = DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr); 605 /* Distribute dof section */ 606 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)oldDM),&newDMnetwork->DofSection);CHKERRQ(ierr); 607 ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr); 608 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)oldDM),&newDMnetwork->DataSection);CHKERRQ(ierr); 609 /* Distribute data and associated section */ 610 ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPIU_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr); 611 /* Destroy point SF */ 612 ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr); 613 614 ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr); 615 ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr); 616 ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr); 617 newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart; 618 newDMnetwork->nNodes = newDMnetwork->vEnd - newDMnetwork->vStart; 619 newDMnetwork->NNodes = oldDMnetwork->NNodes; 620 newDMnetwork->NEdges = oldDMnetwork->NEdges; 621 /* Set Dof section as the default section for dm */ 622 ierr = DMSetDefaultSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr); 623 ierr = DMGetDefaultGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr); 624 625 *distDM = newDM; 626 PetscFunctionReturn(0); 627 } 628 629 #undef __FUNCT__ 630 #define __FUNCT__ "DMNetworkGetSupportingEdges" 631 /*@C 632 DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point 633 634 Not Collective 635 636 Input Parameters: 637 + dm - The DMNetwork object 638 - p - the vertex point 639 640 Output Paramters: 641 + nedges - number of edges connected to this vertex point 642 - edges - List of edge points 643 644 Level: intermediate 645 646 Fortran Notes: 647 Since it returns an array, this routine is only available in Fortran 90, and you must 648 include petsc.h90 in your code. 649 650 .seealso: DMNetworkCreate, DMNetworkGetConnectedNodes 651 @*/ 652 PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[]) 653 { 654 PetscErrorCode ierr; 655 DM_Network *network = (DM_Network*)dm->data; 656 657 PetscFunctionBegin; 658 ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr); 659 ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr); 660 PetscFunctionReturn(0); 661 } 662 663 #undef __FUNCT__ 664 #define __FUNCT__ "DMNetworkGetConnectedNodes" 665 /*@C 666 DMNetworkGetConnectedNodes - Return the connected vertices for this edge point 667 668 Not Collective 669 670 Input Parameters: 671 + dm - The DMNetwork object 672 - p - the edge point 673 674 Output Paramters: 675 . vertices - vertices connected to this edge 676 677 Level: intermediate 678 679 Fortran Notes: 680 Since it returns an array, this routine is only available in Fortran 90, and you must 681 include petsc.h90 in your code. 682 683 .seealso: DMNetworkCreate, DMNetworkGetSupportingEdges 684 @*/ 685 PetscErrorCode DMNetworkGetConnectedNodes(DM dm,PetscInt edge,const PetscInt *vertices[]) 686 { 687 PetscErrorCode ierr; 688 DM_Network *network = (DM_Network*)dm->data; 689 690 PetscFunctionBegin; 691 ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr); 692 PetscFunctionReturn(0); 693 } 694 695 #undef __FUNCT__ 696 #define __FUNCT__ "DMNetworkIsGhostVertex" 697 /*@ 698 DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex 699 700 Not Collective 701 702 Input Parameters: 703 + dm - The DMNetwork object 704 . p - the vertex point 705 706 Output Parameter: 707 . isghost - TRUE if the vertex is a ghost point 708 709 Level: intermediate 710 711 .seealso: DMNetworkCreate, DMNetworkGetConnectedNodes, DMNetworkGetVertexRange 712 @*/ 713 PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost) 714 { 715 PetscErrorCode ierr; 716 DM_Network *network = (DM_Network*)dm->data; 717 PetscInt offsetg; 718 PetscSection sectiong; 719 720 PetscFunctionBegin; 721 *isghost = PETSC_FALSE; 722 ierr = DMGetDefaultGlobalSection(network->plex,§iong);CHKERRQ(ierr); 723 ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr); 724 if (offsetg < 0) *isghost = PETSC_TRUE; 725 PetscFunctionReturn(0); 726 } 727 728 #undef __FUNCT__ 729 #define __FUNCT__ "DMSetUp_Network" 730 PetscErrorCode DMSetUp_Network(DM dm) 731 { 732 PetscErrorCode ierr; 733 DM_Network *network=(DM_Network*)dm->data; 734 735 PetscFunctionBegin; 736 ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr); 737 ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr); 738 739 ierr = DMSetDefaultSection(network->plex,network->DofSection);CHKERRQ(ierr); 740 ierr = DMGetDefaultGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr); 741 PetscFunctionReturn(0); 742 } 743 744 #undef __FUNCT__ 745 #define __FUNCT__ "DMNetworkHasJacobian" 746 /*@ 747 DMNetworkHasJacobian - Sets global flag for using user's sub Jacobian matrices 748 -- replaced by DMNetworkSetOption(network,userjacobian,PETSC_TURE)? 749 750 Collective 751 752 Input Parameters: 753 + dm - The DMNetwork object 754 . eflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for edges 755 - vflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for vertices 756 757 Level: intermediate 758 759 @*/ 760 PetscErrorCode DMNetworkHasJacobian(DM dm,PetscBool eflg,PetscBool vflg) 761 { 762 DM_Network *network=(DM_Network*)dm->data; 763 764 PetscFunctionBegin; 765 network->userEdgeJacobian = eflg; 766 network->userVertexJacobian = vflg; 767 PetscFunctionReturn(0); 768 } 769 770 #undef __FUNCT__ 771 #define __FUNCT__ "DMNetworkEdgeSetMatrix" 772 /*@ 773 DMNetworkEdgeSetMatrix - Sets user-provided Jacobian matrices for this edge to the network 774 775 Not Collective 776 777 Input Parameters: 778 + dm - The DMNetwork object 779 . p - the edge point 780 - J - array of Jacobian three submatrices for this edge point: 781 J[0]: this edge; 782 J[1] and J[2]: connected vertices, obtained by calling DMNetworkGetConnectedNodes(); 783 784 Level: intermediate 785 786 .seealso: DMNetworkVertexSetMatrix 787 @*/ 788 PetscErrorCode DMNetworkEdgeSetMatrix(DM dm,PetscInt p,Mat J[]) 789 { 790 PetscErrorCode ierr; 791 DM_Network *network=(DM_Network*)dm->data; 792 793 PetscFunctionBegin; 794 if (!network->userEdgeJacobian) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkEdgeSetMatrix"); 795 if (!network->Je) { 796 ierr = PetscCalloc1(3*network->nEdges,&network->Je);CHKERRQ(ierr); 797 } 798 network->Je[3*p] = J[0]; 799 network->Je[3*p+1] = J[1]; 800 network->Je[3*p+2] = J[2]; 801 PetscFunctionReturn(0); 802 } 803 804 #undef __FUNCT__ 805 #define __FUNCT__ "DMNetworkVertexSetMatrix" 806 /*@ 807 DMNetworkVetexSetMatrix - Sets user-provided Jacobian matrix for this vertex to the network 808 809 Not Collective 810 811 Input Parameters: 812 + dm - The DMNetwork object 813 . p - the vertex point 814 - J - array of Jacobian submatrices: 815 816 Level: intermediate 817 818 .seealso: DMNetworkEdgeSetMatrix 819 @*/ 820 PetscErrorCode DMNetworkVertexSetMatrix(DM dm,PetscInt p,Mat J[]) 821 { 822 PetscErrorCode ierr; 823 DM_Network *network=(DM_Network*)dm->data; 824 PetscInt i,vStart,vEnd,*vptr,nedges; 825 const PetscInt *edges; 826 827 PetscFunctionBegin; 828 if (!network->userVertexJacobian) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkVertexSetMatrix"); 829 830 ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 831 if (!network->Jv) { 832 /* count nvertex_total */ 833 PetscInt *vptr,v,nedges_total = 0; 834 ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 835 ierr = PetscMalloc1(vEnd-vStart+1,&vptr);CHKERRQ(ierr); 836 i = 1; 837 vptr[0] = 0; 838 for (v=vStart; v<vEnd; v++) { 839 ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 840 nedges_total += nedges; 841 vptr[i] = vptr[i-1] + 2*nedges + 1; i++; 842 } 843 ierr = PetscCalloc1(2*nedges_total+network->nNodes,&network->Jv);CHKERRQ(ierr); 844 network->Jvptr = vptr; 845 } 846 847 vptr=network->Jvptr; 848 network->Jv[vptr[p-vStart]] = J[0]; 849 ierr = DMNetworkGetSupportingEdges(dm,p,&nedges,&edges);CHKERRQ(ierr); 850 for (i=1; i<=2*nedges; i++) network->Jv[vptr[p-vStart]+i] = J[i]; 851 PetscFunctionReturn(0); 852 } 853 854 #undef __FUNCT__ 855 #define __FUNCT__ "MatSetDenseblock_private" 856 PetscErrorCode MatSetDenseblock_private(Mat *J,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart) 857 { 858 PetscErrorCode ierr; 859 PetscInt j,*cols; 860 PetscScalar *zeros; 861 862 PetscFunctionBegin; 863 ierr = PetscCalloc2(ncols,&cols,nrows*ncols,&zeros);CHKERRQ(ierr); 864 for (j=0; j<ncols; j++) cols[j] = j+ cstart; 865 ierr = MatSetValues(*J,nrows,rows,ncols,cols,zeros,INSERT_VALUES);CHKERRQ(ierr); 866 ierr = PetscFree2(cols,zeros);CHKERRQ(ierr); 867 PetscFunctionReturn(0); 868 } 869 870 #undef __FUNCT__ 871 #define __FUNCT__ "DMCreateMatrix_Network" 872 PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J) 873 { 874 PetscErrorCode ierr; 875 DM_Network *network = (DM_Network*) dm->data; 876 PetscInt eStart,eEnd,vStart,vEnd,rstart,rend,row,row_e,nrows,localSize; 877 PetscInt cstart,ncols,col,j,e,v,*dnz,*onz,*dnzu,*onzu; 878 const PetscInt *cols; 879 PetscScalar zero = 0.0; 880 PetscBool ghost; 881 Mat Je,Jv; 882 PetscSection sectionGlobal; 883 PetscInt nedges; 884 const PetscInt *edges; 885 886 PetscFunctionBegin; 887 if (!network->userEdgeJacobian && !network->userVertexJacobian) { /* user does not provide Jacobian blocks */ 888 ierr = DMCreateMatrix(network->plex,J);CHKERRQ(ierr); 889 ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 890 PetscFunctionReturn(0); 891 } 892 893 ierr = MatCreate(PetscObjectComm((PetscObject)dm),J);CHKERRQ(ierr); 894 ierr = DMGetDefaultGlobalSection(network->plex,§ionGlobal);CHKERRQ(ierr); 895 ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal,&localSize);CHKERRQ(ierr); 896 ierr = MatSetSizes(*J,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 897 898 ierr = MatSetType(*J,MATAIJ);CHKERRQ(ierr); 899 ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 900 901 /* Preallocation - submatrix for an element (edge/vertex) is allocated as a dense block, see DMCreateMatrix_Plex() */ 902 ierr = PetscCalloc4(localSize,&dnz,localSize,&onz,localSize,&dnzu,localSize,&onzu);CHKERRQ(ierr); 903 ierr = DMPlexPreallocateOperator(network->plex,1,dnz,onz,dnzu,onzu,*J,PETSC_FALSE);CHKERRQ(ierr); 904 ierr = PetscFree4(dnz,onz,dnzu,onzu);CHKERRQ(ierr); 905 906 /* Set matrix entries for edges */ 907 /*------------------------------*/ 908 ierr = DMNetworkGetEdgeRange(dm,&eStart,&eEnd);CHKERRQ(ierr); 909 for (e=eStart; e<eEnd; e++) { 910 /* Get row indices */ 911 ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr); 912 ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr); 913 914 PetscInt rows[nrows]; 915 for (j=0; j<nrows; j++) rows[j] = j + rstart; 916 917 /* Set matrix entries for conntected vertices */ 918 const PetscInt *cone; 919 ierr = DMNetworkGetConnectedNodes(dm,e,&cone);CHKERRQ(ierr); 920 921 for (v=0; v<2; v++) { 922 ierr = DMNetworkIsGhostVertex(dm,cone[v],&ghost);CHKERRQ(ierr); 923 ierr = DMNetworkGetVariableGlobalOffset(dm,cone[v],&cstart);CHKERRQ(ierr); 924 if (ghost) cstart = -(cstart + 1); /* Convert to actual global offset for ghost nodes */ 925 926 Je = network->Je[3*e+1+v]; 927 if (Je) { /* use user-provided Je */ 928 rend = rstart + nrows; 929 for (row = rstart; row<rend; row++) { 930 row_e = row - rstart; 931 ierr = MatGetRow(Je,row_e,&ncols,&cols,NULL);CHKERRQ(ierr); 932 for (j=0; j<ncols; j++) { 933 col = cols[j] + cstart; 934 ierr = MatSetValues(*J,1,&row,1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr); 935 } 936 } 937 ierr = MatRestoreRow(Je,row_e,&ncols,&cols,NULL);CHKERRQ(ierr); 938 939 } else { /* use dense block */ 940 ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr); 941 ierr = MatSetDenseblock_private(J,nrows,rows,ncols,cstart);CHKERRQ(ierr); 942 } 943 } 944 945 /* Set matrix entries for edge self */ 946 Je = network->Je[3*e]; 947 if (Je) { /* use user-provided Je */ 948 PetscInt M,N; 949 ierr = MatGetSize(Je,&M,&N);CHKERRQ(ierr); 950 if (nrows != M || nrows != N) SETERRQ3(PetscObjectComm((PetscObject)Je),PETSC_ERR_USER,"%D must equal %D and %D",nrows,M,N); 951 952 rend = rstart + nrows; 953 for (row=rstart; row<rend; row++) { 954 row_e = row - rstart; 955 ierr = MatGetRow(Je,row_e,&ncols,&cols,NULL);CHKERRQ(ierr); 956 for (j=0; j<ncols; j++) { 957 col = cols[j] + rstart; 958 ierr = MatSetValues(*J,1,&row,1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr); 959 } 960 ierr = MatRestoreRow(Je,row_e,&ncols,&cols,NULL);CHKERRQ(ierr); 961 } 962 } else { /* set a dense block */ 963 PetscInt cstart; 964 ierr = DMNetworkGetVariableGlobalOffset(dm,e,&cstart);CHKERRQ(ierr); 965 ierr = MatSetDenseblock_private(J,nrows,rows,nrows,cstart);CHKERRQ(ierr); 966 } 967 } 968 969 /* Set matrix entries for vertices */ 970 /*---------------------------------*/ 971 ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 972 for (v=vStart; v<vEnd; v++) { 973 /* Get row indices */ 974 ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 975 ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr); 976 if (ghost) rstart = -(rstart + 1); /* Convert to actual global offset for ghost nodes */ 977 ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr); 978 979 PetscInt rows[nrows]; 980 for (j=0; j<nrows; j++) rows[j] = j + rstart; 981 982 /* Get supporting edges and connected vertices */ 983 ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 984 985 for (e=0; e<nedges; e++) { 986 /* Supporting edges */ 987 ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr); 988 ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr); 989 990 PetscInt *vptr = network->Jvptr; 991 Jv = network->Jv[vptr[v-vStart]+2*e+1]; 992 if (Jv) { /* use user-provided Je */ 993 PetscInt M,N; 994 ierr = MatGetSize(Jv,&M,&N);CHKERRQ(ierr); 995 if (nrows != M) SETERRQ2(PetscObjectComm((PetscObject)Jv),PETSC_ERR_USER,"%D must equal %D",nrows,M); 996 if (ncols != N) SETERRQ2(PetscObjectComm((PetscObject)Jv),PETSC_ERR_USER,"%D must equal %D",ncols,N); 997 998 ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr); 999 rend = rstart + nrows; 1000 for (row=rstart; row<rend; row++) { 1001 row_e = row - rstart; 1002 ierr = MatGetRow(Jv,row_e,&ncols,&cols,NULL);CHKERRQ(ierr); 1003 for (j=0; j<ncols; j++) { 1004 col = cols[j] + cstart; 1005 ierr = MatSetValues(*J,1,&row,1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr); 1006 } 1007 ierr = MatRestoreRow(Jv,row_e,&ncols,&cols,NULL);CHKERRQ(ierr); 1008 } 1009 } else { /* use dense block */ 1010 ierr = MatSetDenseblock_private(J,nrows,rows,ncols,cstart);CHKERRQ(ierr); 1011 } 1012 1013 /* Connected vertices */ 1014 const PetscInt *cone; 1015 PetscInt vc; 1016 ierr = DMNetworkGetConnectedNodes(dm,edges[e],&cone);CHKERRQ(ierr); 1017 vc = (v == cone[0]) ? cone[1]:cone[0]; 1018 1019 ierr = DMNetworkIsGhostVertex(dm,vc,&ghost);CHKERRQ(ierr); 1020 ierr = DMNetworkGetVariableGlobalOffset(dm,vc,&cstart);CHKERRQ(ierr); 1021 if (ghost) cstart = -(cstart + 1); /* Convert to actual global offset for ghost nodes */ 1022 ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr); 1023 ierr = MatSetDenseblock_private(J,nrows,rows,ncols,cstart);CHKERRQ(ierr); 1024 } 1025 1026 /* Set matrix entries for vertex self */ 1027 ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 1028 if (!ghost) { 1029 PetscInt cstart; 1030 ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr); 1031 ierr = MatSetDenseblock_private(J,nrows,rows,nrows,cstart);CHKERRQ(ierr); 1032 } 1033 } 1034 ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1035 ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1036 #if 0 1037 printf("\nMatrix J:\n"); 1038 ierr = MatView(*J,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 1039 #endif 1040 ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 1041 PetscFunctionReturn(0); 1042 } 1043 1044 #undef __FUNCT__ 1045 #define __FUNCT__ "DMDestroy_Network" 1046 PetscErrorCode DMDestroy_Network(DM dm) 1047 { 1048 PetscErrorCode ierr; 1049 DM_Network *network = (DM_Network*) dm->data; 1050 PetscInt i; 1051 1052 PetscFunctionBegin; 1053 if (--network->refct > 0) PetscFunctionReturn(0); 1054 if (network->Je) { 1055 for (i=0; i<3*network->nEdges; i++) { 1056 ierr = MatDestroy(&network->Je[i]);CHKERRQ(ierr); 1057 } 1058 ierr = PetscFree(network->Je);CHKERRQ(ierr); 1059 } 1060 if (network->Jv) { 1061 PetscInt v,vStart,vEnd,nedges,*vptr=network->Jvptr; 1062 const PetscInt *edges; 1063 ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 1064 for (v=vStart; v<vEnd; v++) { 1065 ierr = MatDestroy(&network->Jv[vptr[v-vStart]]);CHKERRQ(ierr); 1066 ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 1067 for (i=0; i<2*nedges; i++) { 1068 ierr = MatDestroy(&network->Jv[vptr[v-vStart]+i+1]);CHKERRQ(ierr); 1069 } 1070 } 1071 ierr = PetscFree(network->Jvptr);CHKERRQ(ierr); 1072 ierr = PetscFree(network->Jv);CHKERRQ(ierr); 1073 } 1074 ierr = DMDestroy(&network->plex);CHKERRQ(ierr); 1075 network->edges = NULL; 1076 ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr); 1077 ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr); 1078 1079 ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr); 1080 ierr = PetscFree(network->cvalue);CHKERRQ(ierr); 1081 ierr = PetscFree(network->header);CHKERRQ(ierr); 1082 ierr = PetscFree(network);CHKERRQ(ierr); 1083 PetscFunctionReturn(0); 1084 } 1085 1086 #undef __FUNCT__ 1087 #define __FUNCT__ "DMView_Network" 1088 PetscErrorCode DMView_Network(DM dm, PetscViewer viewer) 1089 { 1090 PetscErrorCode ierr; 1091 DM_Network *network = (DM_Network*) dm->data; 1092 1093 PetscFunctionBegin; 1094 ierr = DMView(network->plex,viewer);CHKERRQ(ierr); 1095 PetscFunctionReturn(0); 1096 } 1097 1098 #undef __FUNCT__ 1099 #define __FUNCT__ "DMGlobalToLocalBegin_Network" 1100 PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l) 1101 { 1102 PetscErrorCode ierr; 1103 DM_Network *network = (DM_Network*) dm->data; 1104 1105 PetscFunctionBegin; 1106 ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr); 1107 PetscFunctionReturn(0); 1108 } 1109 1110 #undef __FUNCT__ 1111 #define __FUNCT__ "DMGlobalToLocalEnd_Network" 1112 PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l) 1113 { 1114 PetscErrorCode ierr; 1115 DM_Network *network = (DM_Network*) dm->data; 1116 1117 PetscFunctionBegin; 1118 ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr); 1119 PetscFunctionReturn(0); 1120 } 1121 1122 #undef __FUNCT__ 1123 #define __FUNCT__ "DMLocalToGlobalBegin_Network" 1124 PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g) 1125 { 1126 PetscErrorCode ierr; 1127 DM_Network *network = (DM_Network*) dm->data; 1128 1129 PetscFunctionBegin; 1130 ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr); 1131 PetscFunctionReturn(0); 1132 } 1133 1134 #undef __FUNCT__ 1135 #define __FUNCT__ "DMLocalToGlobalEnd_Network" 1136 PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g) 1137 { 1138 PetscErrorCode ierr; 1139 DM_Network *network = (DM_Network*) dm->data; 1140 1141 PetscFunctionBegin; 1142 ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr); 1143 PetscFunctionReturn(0); 1144 } 1145