1 #include <petsc/private/dmnetworkimpl.h> /*I "petscdmnetwork.h" I*/ 2 #include <petscdmplex.h> 3 #include <petscsf.h> 4 5 /*@ 6 DMNetworkGetPlex - Gets the Plex DM associated with this network DM 7 8 Not collective 9 10 Input Parameters: 11 + netdm - the dm object 12 - plexmdm - the plex dm object 13 14 Level: Advanced 15 16 .seealso: DMNetworkCreate() 17 @*/ 18 PetscErrorCode DMNetworkGetPlex(DM netdm, DM *plexdm) 19 { 20 DM_Network *network = (DM_Network*) netdm->data; 21 22 PetscFunctionBegin; 23 *plexdm = network->plex; 24 PetscFunctionReturn(0); 25 } 26 27 /*@ 28 DMNetworkSetSizes - Sets the local and global vertices and edges. 29 30 Collective on DM 31 32 Input Parameters: 33 + dm - the dm object 34 . nV - number of local vertices 35 . nE - number of local edges 36 . NV - number of global vertices (or PETSC_DETERMINE) 37 - NE - number of global edges (or PETSC_DETERMINE) 38 39 Notes 40 If one processor calls this with NV (NE) of PETSC_DECIDE then all processors must, otherwise the prgram will hang. 41 42 You cannot change the sizes once they have been set 43 44 Level: intermediate 45 46 .seealso: DMNetworkCreate() 47 @*/ 48 PetscErrorCode DMNetworkSetSizes(DM dm, PetscInt nV, PetscInt nE, PetscInt NV, PetscInt NE) 49 { 50 PetscErrorCode ierr; 51 DM_Network *network = (DM_Network*) dm->data; 52 PetscInt a[2],b[2]; 53 54 PetscFunctionBegin; 55 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 56 if (NV > 0) PetscValidLogicalCollectiveInt(dm,NV,4); 57 if (NE > 0) PetscValidLogicalCollectiveInt(dm,NE,5); 58 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); 59 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); 60 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); 61 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); 62 if (NE < 0 || NV < 0) { 63 a[0] = nV; a[1] = nE; 64 ierr = MPIU_Allreduce(a,b,2,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 65 NV = b[0]; NE = b[1]; 66 } 67 network->nNodes = nV; 68 network->NNodes = NV; 69 network->nEdges = nE; 70 network->NEdges = NE; 71 PetscFunctionReturn(0); 72 } 73 74 /*@ 75 DMNetworkSetEdgeList - Sets the list of local edges (vertex connectivity) for the network 76 77 Logically collective on DM 78 79 Input Parameters: 80 . edges - list of edges 81 82 Notes: 83 There is no copy involved in this operation, only the pointer is referenced. The edgelist should 84 not be destroyed before the call to DMNetworkLayoutSetUp 85 86 Level: intermediate 87 88 .seealso: DMNetworkCreate, DMNetworkSetSizes 89 @*/ 90 PetscErrorCode DMNetworkSetEdgeList(DM dm, int edgelist[]) 91 { 92 DM_Network *network = (DM_Network*) dm->data; 93 94 PetscFunctionBegin; 95 network->edges = edgelist; 96 PetscFunctionReturn(0); 97 } 98 99 /*@ 100 DMNetworkLayoutSetUp - Sets up the bare layout (graph) for the network 101 102 Collective on DM 103 104 Input Parameters 105 . DM - the dmnetwork object 106 107 Notes: 108 This routine should be called after the network sizes and edgelists have been provided. It creates 109 the bare layout of the network and sets up the network to begin insertion of components. 110 111 All the components should be registered before calling this routine. 112 113 Level: intermediate 114 115 .seealso: DMNetworkSetSizes, DMNetworkSetEdgeList 116 @*/ 117 PetscErrorCode DMNetworkLayoutSetUp(DM dm) 118 { 119 PetscErrorCode ierr; 120 DM_Network *network = (DM_Network*) dm->data; 121 PetscInt dim = 1; /* One dimensional network */ 122 PetscInt numCorners=2; 123 PetscInt spacedim=2; 124 double *vertexcoords=NULL; 125 PetscInt i; 126 PetscInt ndata; 127 128 PetscFunctionBegin; 129 if (network->nNodes) { 130 ierr = PetscCalloc1(numCorners*network->nNodes,&vertexcoords);CHKERRQ(ierr); 131 } 132 ierr = DMPlexCreateFromCellList(PetscObjectComm((PetscObject)dm),dim,network->nEdges,network->nNodes,numCorners,PETSC_FALSE,network->edges,spacedim,vertexcoords,&network->plex);CHKERRQ(ierr); 133 if (network->nNodes) { 134 ierr = PetscFree(vertexcoords);CHKERRQ(ierr); 135 } 136 ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr); 137 ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr); 138 ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr); 139 140 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DataSection);CHKERRQ(ierr); 141 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DofSection);CHKERRQ(ierr); 142 ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr); 143 ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr); 144 145 146 147 network->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 148 ierr = PetscCalloc1(network->pEnd-network->pStart,&network->header);CHKERRQ(ierr); 149 for (i = network->pStart; i < network->pEnd; i++) { 150 network->header[i].ndata = 0; 151 ndata = network->header[i].ndata; 152 ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr); 153 network->header[i].offset[ndata] = 0; 154 } 155 ierr = PetscMalloc1(network->pEnd-network->pStart,&network->cvalue);CHKERRQ(ierr); 156 PetscFunctionReturn(0); 157 } 158 159 /*@C 160 DMNetworkRegisterComponent - Registers the network component 161 162 Logically collective on DM 163 164 Input Parameters 165 + dm - the network object 166 . name - the component name 167 - size - the storage size in bytes for this component data 168 169 Output Parameters 170 . key - an integer key that defines the component 171 172 Notes 173 This routine should be called by all processors before calling DMNetworkLayoutSetup(). 174 175 Level: intermediate 176 177 .seealso: DMNetworkLayoutSetUp, DMNetworkCreate 178 @*/ 179 PetscErrorCode DMNetworkRegisterComponent(DM dm,const char *name,PetscInt size,PetscInt *key) 180 { 181 PetscErrorCode ierr; 182 DM_Network *network = (DM_Network*) dm->data; 183 DMNetworkComponent *component=&network->component[network->ncomponent]; 184 PetscBool flg=PETSC_FALSE; 185 PetscInt i; 186 187 PetscFunctionBegin; 188 189 for (i=0; i < network->ncomponent; i++) { 190 ierr = PetscStrcmp(component->name,name,&flg);CHKERRQ(ierr); 191 if (flg) { 192 *key = i; 193 PetscFunctionReturn(0); 194 } 195 } 196 197 ierr = PetscStrcpy(component->name,name);CHKERRQ(ierr); 198 component->size = size/sizeof(DMNetworkComponentGenericDataType); 199 *key = network->ncomponent; 200 network->ncomponent++; 201 PetscFunctionReturn(0); 202 } 203 204 /*@ 205 DMNetworkGetVertexRange - Get the bounds [start, end) for the vertices. 206 207 Not Collective 208 209 Input Parameters: 210 + dm - The DMNetwork object 211 212 Output Paramters: 213 + vStart - The first vertex point 214 - vEnd - One beyond the last vertex point 215 216 Level: intermediate 217 218 .seealso: DMNetworkGetEdgeRange 219 @*/ 220 PetscErrorCode DMNetworkGetVertexRange(DM dm,PetscInt *vStart,PetscInt *vEnd) 221 { 222 DM_Network *network = (DM_Network*)dm->data; 223 224 PetscFunctionBegin; 225 if (vStart) *vStart = network->vStart; 226 if (vEnd) *vEnd = network->vEnd; 227 PetscFunctionReturn(0); 228 } 229 230 /*@ 231 DMNetworkGetEdgeRange - Get the bounds [start, end) for the edges. 232 233 Not Collective 234 235 Input Parameters: 236 + dm - The DMNetwork object 237 238 Output Paramters: 239 + eStart - The first edge point 240 - eEnd - One beyond the last edge point 241 242 Level: intermediate 243 244 .seealso: DMNetworkGetVertexRange 245 @*/ 246 PetscErrorCode DMNetworkGetEdgeRange(DM dm,PetscInt *eStart,PetscInt *eEnd) 247 { 248 DM_Network *network = (DM_Network*)dm->data; 249 250 PetscFunctionBegin; 251 if (eStart) *eStart = network->eStart; 252 if (eEnd) *eEnd = network->eEnd; 253 PetscFunctionReturn(0); 254 } 255 256 /*@ 257 DMNetworkAddComponent - Adds a network component at the given point (vertex/edge) 258 259 Not Collective 260 261 Input Parameters: 262 + dm - The DMNetwork object 263 . p - vertex/edge point 264 . componentkey - component key returned while registering the component 265 - compvalue - pointer to the data structure for the component 266 267 Level: intermediate 268 269 .seealso: DMNetworkGetVertexRange, DMNetworkGetEdgeRange, DMNetworkRegisterComponent 270 @*/ 271 PetscErrorCode DMNetworkAddComponent(DM dm, PetscInt p,PetscInt componentkey,void* compvalue) 272 { 273 DM_Network *network = (DM_Network*)dm->data; 274 DMNetworkComponent *component = &network->component[componentkey]; 275 DMNetworkComponentHeader header = &network->header[p]; 276 DMNetworkComponentValue cvalue = &network->cvalue[p]; 277 PetscErrorCode ierr; 278 279 PetscFunctionBegin; 280 if (header->ndata == MAX_DATA_AT_POINT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Number of components at a point exceeds the max %D",MAX_DATA_AT_POINT); 281 282 header->size[header->ndata] = component->size; 283 ierr = PetscSectionAddDof(network->DataSection,p,component->size);CHKERRQ(ierr); 284 header->key[header->ndata] = componentkey; 285 if (header->ndata != 0) header->offset[header->ndata] = header->offset[header->ndata-1] + header->size[header->ndata-1]; 286 287 cvalue->data[header->ndata] = (void*)compvalue; 288 header->ndata++; 289 PetscFunctionReturn(0); 290 } 291 292 /*@ 293 DMNetworkGetNumComponents - Get the number of components at a vertex/edge 294 295 Not Collective 296 297 Input Parameters: 298 + dm - The DMNetwork object 299 . p - vertex/edge point 300 301 Output Parameters: 302 . numcomponents - Number of components at the vertex/edge 303 304 Level: intermediate 305 306 .seealso: DMNetworkRegisterComponent, DMNetworkAddComponent 307 @*/ 308 PetscErrorCode DMNetworkGetNumComponents(DM dm,PetscInt p,PetscInt *numcomponents) 309 { 310 PetscErrorCode ierr; 311 PetscInt offset; 312 DM_Network *network = (DM_Network*)dm->data; 313 314 PetscFunctionBegin; 315 ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 316 *numcomponents = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 317 PetscFunctionReturn(0); 318 } 319 320 /*@ 321 DMNetworkGetComponentTypeOffset - Gets the type along with the offset for indexing the 322 component value from the component data array 323 324 Not Collective 325 326 Input Parameters: 327 + dm - The DMNetwork object 328 . p - vertex/edge point 329 - compnum - component number 330 331 Output Parameters: 332 + compkey - the key obtained when registering the component 333 - offset - offset into the component data array associated with the vertex/edge point 334 335 Notes: 336 Typical usage: 337 338 DMNetworkGetComponentDataArray(dm, &arr); 339 DMNetworkGetVertex/EdgeRange(dm,&Start,&End); 340 Loop over vertices or edges 341 DMNetworkGetNumComponents(dm,v,&numcomps); 342 Loop over numcomps 343 DMNetworkGetComponentTypeOffset(dm,v,compnum,&key,&offset); 344 compdata = (UserCompDataType)(arr+offset); 345 346 Level: intermediate 347 348 .seealso: DMNetworkGetNumComponents, DMNetworkGetComponentDataArray, 349 @*/ 350 PetscErrorCode DMNetworkGetComponentTypeOffset(DM dm,PetscInt p, PetscInt compnum, PetscInt *compkey, PetscInt *offset) 351 { 352 PetscErrorCode ierr; 353 PetscInt offsetp; 354 DMNetworkComponentHeader header; 355 DM_Network *network = (DM_Network*)dm->data; 356 357 PetscFunctionBegin; 358 ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 359 header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 360 if (compkey) *compkey = header->key[compnum]; 361 if (offset) *offset = offsetp+network->dataheadersize+header->offset[compnum]; 362 PetscFunctionReturn(0); 363 } 364 365 /*@ 366 DMNetworkGetVariableOffset - Get the offset for accessing the variable associated with the given vertex/edge from the local vector. 367 368 Not Collective 369 370 Input Parameters: 371 + dm - The DMNetwork object 372 - p - the edge/vertex point 373 374 Output Parameters: 375 . offset - the offset 376 377 Level: intermediate 378 379 .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 380 @*/ 381 PetscErrorCode DMNetworkGetVariableOffset(DM dm,PetscInt p,PetscInt *offset) 382 { 383 PetscErrorCode ierr; 384 DM_Network *network = (DM_Network*)dm->data; 385 386 PetscFunctionBegin; 387 ierr = PetscSectionGetOffset(network->plex->defaultSection,p,offset);CHKERRQ(ierr); 388 PetscFunctionReturn(0); 389 } 390 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->plex->defaultGlobalSection,p,offsetg);CHKERRQ(ierr); 414 if (*offsetg < 0) *offsetg = -(*offsetg + 1); /* Convert to actual global offset for ghost node */ 415 PetscFunctionReturn(0); 416 } 417 418 /*@ 419 DMNetworkGetEdgeOffset - Get the offset for accessing the variable associated with the given edge from the local subvector. 420 421 Not Collective 422 423 Input Parameters: 424 + dm - The DMNetwork object 425 - p - the edge point 426 427 Output Parameters: 428 . offset - the offset 429 430 Level: intermediate 431 432 .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 433 @*/ 434 PetscErrorCode DMNetworkGetEdgeOffset(DM dm,PetscInt p,PetscInt *offset) 435 { 436 PetscErrorCode ierr; 437 DM_Network *network = (DM_Network*)dm->data; 438 439 PetscFunctionBegin; 440 441 ierr = PetscSectionGetOffset(network->edge.DofSection,p,offset);CHKERRQ(ierr); 442 PetscFunctionReturn(0); 443 } 444 445 /*@ 446 DMNetworkGetVertexOffset - Get the offset for accessing the variable associated with the given vertex from the local subvector. 447 448 Not Collective 449 450 Input Parameters: 451 + dm - The DMNetwork object 452 - p - the vertex point 453 454 Output Parameters: 455 . offset - the offset 456 457 Level: intermediate 458 459 .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 460 @*/ 461 PetscErrorCode DMNetworkGetVertexOffset(DM dm,PetscInt p,PetscInt *offset) 462 { 463 PetscErrorCode ierr; 464 DM_Network *network = (DM_Network*)dm->data; 465 466 PetscFunctionBegin; 467 468 p -= network->vStart; 469 470 ierr = PetscSectionGetOffset(network->vertex.DofSection,p,offset);CHKERRQ(ierr); 471 PetscFunctionReturn(0); 472 } 473 /*@ 474 DMNetworkAddNumVariables - Add number of variables associated with a given point. 475 476 Not Collective 477 478 Input Parameters: 479 + dm - The DMNetworkObject 480 . p - the vertex/edge point 481 - nvar - number of additional variables 482 483 Level: intermediate 484 485 .seealso: DMNetworkSetNumVariables 486 @*/ 487 PetscErrorCode DMNetworkAddNumVariables(DM dm,PetscInt p,PetscInt nvar) 488 { 489 PetscErrorCode ierr; 490 DM_Network *network = (DM_Network*)dm->data; 491 492 PetscFunctionBegin; 493 ierr = PetscSectionAddDof(network->DofSection,p,nvar);CHKERRQ(ierr); 494 PetscFunctionReturn(0); 495 } 496 497 /*@ 498 DMNetworkGetNumVariables - Gets number of variables for a vertex/edge point. 499 500 Not Collective 501 502 Input Parameters: 503 + dm - The DMNetworkObject 504 - p - the vertex/edge point 505 506 Output Parameters: 507 . nvar - number of variables 508 509 Level: intermediate 510 511 .seealso: DMNetworkAddNumVariables, DMNetworkSddNumVariables 512 @*/ 513 PetscErrorCode DMNetworkGetNumVariables(DM dm,PetscInt p,PetscInt *nvar) 514 { 515 PetscErrorCode ierr; 516 DM_Network *network = (DM_Network*)dm->data; 517 518 PetscFunctionBegin; 519 ierr = PetscSectionGetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 520 PetscFunctionReturn(0); 521 } 522 523 /*@ 524 DMNetworkSetNumVariables - Sets number of variables for a vertex/edge point. 525 526 Not Collective 527 528 Input Parameters: 529 + dm - The DMNetworkObject 530 . p - the vertex/edge point 531 - nvar - number of variables 532 533 Level: intermediate 534 535 .seealso: DMNetworkAddNumVariables 536 @*/ 537 PetscErrorCode DMNetworkSetNumVariables(DM dm,PetscInt p,PetscInt nvar) 538 { 539 PetscErrorCode ierr; 540 DM_Network *network = (DM_Network*)dm->data; 541 542 PetscFunctionBegin; 543 ierr = PetscSectionSetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 544 PetscFunctionReturn(0); 545 } 546 547 /* Sets up the array that holds the data for all components and its associated section. This 548 function is called during DMSetUp() */ 549 PetscErrorCode DMNetworkComponentSetUp(DM dm) 550 { 551 PetscErrorCode ierr; 552 DM_Network *network = (DM_Network*)dm->data; 553 PetscInt arr_size; 554 PetscInt p,offset,offsetp; 555 DMNetworkComponentHeader header; 556 DMNetworkComponentValue cvalue; 557 DMNetworkComponentGenericDataType *componentdataarray; 558 PetscInt ncomp, i; 559 560 PetscFunctionBegin; 561 ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr); 562 ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr); 563 ierr = PetscMalloc1(arr_size,&network->componentdataarray);CHKERRQ(ierr); 564 componentdataarray = network->componentdataarray; 565 for (p = network->pStart; p < network->pEnd; p++) { 566 ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 567 /* Copy header */ 568 header = &network->header[p]; 569 ierr = PetscMemcpy(componentdataarray+offsetp,header,network->dataheadersize*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 570 /* Copy data */ 571 cvalue = &network->cvalue[p]; 572 ncomp = header->ndata; 573 for (i = 0; i < ncomp; i++) { 574 offset = offsetp + network->dataheadersize + header->offset[i]; 575 ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 576 } 577 } 578 PetscFunctionReturn(0); 579 } 580 581 /* Sets up the section for dofs. This routine is called during DMSetUp() */ 582 PetscErrorCode DMNetworkVariablesSetUp(DM dm) 583 { 584 PetscErrorCode ierr; 585 DM_Network *network = (DM_Network*)dm->data; 586 587 PetscFunctionBegin; 588 ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr); 589 PetscFunctionReturn(0); 590 } 591 592 /*@C 593 DMNetworkGetComponentDataArray - Returns the component data array 594 595 Not Collective 596 597 Input Parameters: 598 . dm - The DMNetwork Object 599 600 Output Parameters: 601 . componentdataarray - array that holds data for all components 602 603 Level: intermediate 604 605 .seealso: DMNetworkGetComponentTypeOffset, DMNetworkGetNumComponents 606 @*/ 607 PetscErrorCode DMNetworkGetComponentDataArray(DM dm,DMNetworkComponentGenericDataType **componentdataarray) 608 { 609 DM_Network *network = (DM_Network*)dm->data; 610 611 PetscFunctionBegin; 612 *componentdataarray = network->componentdataarray; 613 PetscFunctionReturn(0); 614 } 615 616 /* Get a subsection from a range of points */ 617 PetscErrorCode DMNetworkGetSubSection_private(PetscSection master, PetscInt pstart, PetscInt pend,PetscSection *subsection) 618 { 619 PetscErrorCode ierr; 620 PetscInt i, nvar; 621 622 PetscFunctionBegin; 623 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)master), subsection);CHKERRQ(ierr); 624 ierr = PetscSectionSetChart(*subsection, 0, pend - pstart);CHKERRQ(ierr); 625 for (i = pstart; i < pend; i++) { 626 ierr = PetscSectionGetDof(master,i,&nvar);CHKERRQ(ierr); 627 ierr = PetscSectionSetDof(*subsection, i - pstart, nvar);CHKERRQ(ierr); 628 } 629 630 ierr = PetscSectionSetUp(*subsection);CHKERRQ(ierr); 631 PetscFunctionReturn(0); 632 } 633 634 /* Create a submap of points with a GlobalToLocal structure */ 635 PetscErrorCode DMNetworkSetSubMap_private(PetscInt pstart, PetscInt pend, ISLocalToGlobalMapping *map) 636 { 637 PetscErrorCode ierr; 638 PetscInt i, *subpoints; 639 640 PetscFunctionBegin; 641 /* Create index sets to map from "points" to "subpoints" */ 642 ierr = PetscMalloc1(pend - pstart, &subpoints);CHKERRQ(ierr); 643 for (i = pstart; i < pend; i++) { 644 subpoints[i - pstart] = i; 645 } 646 ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,pend-pstart,subpoints,PETSC_COPY_VALUES,map);CHKERRQ(ierr); 647 ierr = PetscFree(subpoints);CHKERRQ(ierr); 648 PetscFunctionReturn(0); 649 } 650 651 /*@ 652 DMNetworkAssembleGraphStructures - Assembles vertex and edge data structures. Must be called after DMNetworkDistribute. 653 654 Collective 655 656 Input Parameters: 657 . dm - The DMNetworkObject 658 659 Note: the routine will create alternative orderings for the vertices and edges. Assume global network points are: 660 661 points = [0 1 2 3 4 5 6] 662 663 where edges = [0, 3] and vertices = [4, 6]. The new orderings will be specific to the subset (i.e vertices = [0, 2]). 664 665 With this new ordering a local PetscSection, global PetscSection and PetscSF will be created specific to the subset. 666 667 Level: intermediate 668 669 @*/ 670 PetscErrorCode DMNetworkAssembleGraphStructures(DM dm) 671 { 672 PetscErrorCode ierr; 673 MPI_Comm comm; 674 PetscMPIInt rank, size; 675 DM_Network *network = (DM_Network*)dm->data; 676 677 PetscFunctionBegin; 678 ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 679 ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 680 ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 681 682 /* Create maps for vertices and edges */ 683 ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 684 ierr = DMNetworkSetSubMap_private(network->eStart,network->eEnd,&network->edge.mapping);CHKERRQ(ierr); 685 686 /* Create local sub-sections */ 687 ierr = DMNetworkGetSubSection_private(network->DofSection,network->vStart,network->vEnd,&network->vertex.DofSection);CHKERRQ(ierr); 688 ierr = DMNetworkGetSubSection_private(network->DofSection,network->eStart,network->eEnd,&network->edge.DofSection);CHKERRQ(ierr); 689 690 if (size > 1) { 691 ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 692 ierr = PetscSectionCreateGlobalSection(network->vertex.DofSection, network->vertex.sf, PETSC_FALSE, PETSC_FALSE, &network->vertex.GlobalDofSection);CHKERRQ(ierr); 693 ierr = PetscSFGetSubSF(network->plex->sf, network->edge.mapping, &network->edge.sf);CHKERRQ(ierr); 694 ierr = PetscSectionCreateGlobalSection(network->edge.DofSection, network->edge.sf, PETSC_FALSE, PETSC_FALSE, &network->edge.GlobalDofSection);CHKERRQ(ierr); 695 } else { 696 /* create structures for vertex */ 697 ierr = PetscSectionClone(network->vertex.DofSection,&network->vertex.GlobalDofSection);CHKERRQ(ierr); 698 /* create structures for edge */ 699 ierr = PetscSectionClone(network->edge.DofSection,&network->edge.GlobalDofSection);CHKERRQ(ierr); 700 } 701 702 703 /* Add viewers */ 704 ierr = PetscObjectSetName((PetscObject)network->edge.GlobalDofSection,"Global edge dof section");CHKERRQ(ierr); 705 ierr = PetscObjectSetName((PetscObject)network->vertex.GlobalDofSection,"Global vertex dof section");CHKERRQ(ierr); 706 ierr = PetscSectionViewFromOptions(network->edge.GlobalDofSection, NULL, "-edge_global_section_view");CHKERRQ(ierr); 707 ierr = PetscSectionViewFromOptions(network->vertex.GlobalDofSection, NULL, "-vertex_global_section_view");CHKERRQ(ierr); 708 709 PetscFunctionReturn(0); 710 } 711 /*@ 712 DMNetworkDistribute - Distributes the network and moves associated component data. 713 714 Collective 715 716 Input Parameter: 717 + DM - the DMNetwork object 718 - overlap - The overlap of partitions, 0 is the default 719 720 Notes: 721 Distributes the network with <overlap>-overlapping partitioning of the edges. 722 723 Level: intermediate 724 725 .seealso: DMNetworkCreate 726 @*/ 727 PetscErrorCode DMNetworkDistribute(DM *dm, PetscInt overlap) 728 { 729 MPI_Comm comm; 730 PetscErrorCode ierr; 731 PetscMPIInt size; 732 DM_Network *oldDMnetwork = (DM_Network*)((*dm)->data); 733 DM_Network *newDMnetwork; 734 PetscSF pointsf; 735 DM newDM; 736 737 PetscFunctionBegin; 738 739 ierr = PetscObjectGetComm((PetscObject)*dm,&comm);CHKERRQ(ierr); 740 ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 741 742 if (size == 1) PetscFunctionReturn(0); 743 744 ierr = DMNetworkCreate(PetscObjectComm((PetscObject)*dm),&newDM);CHKERRQ(ierr); 745 newDMnetwork = (DM_Network*)newDM->data; 746 newDMnetwork->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 747 /* Distribute plex dm and dof section */ 748 ierr = DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr); 749 /* Distribute dof section */ 750 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)*dm),&newDMnetwork->DofSection);CHKERRQ(ierr); 751 ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr); 752 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)*dm),&newDMnetwork->DataSection);CHKERRQ(ierr); 753 /* Distribute data and associated section */ 754 ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPIU_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr); 755 756 757 ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr); 758 ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr); 759 ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr); 760 newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart; 761 newDMnetwork->nNodes = newDMnetwork->vEnd - newDMnetwork->vStart; 762 newDMnetwork->NNodes = oldDMnetwork->NNodes; 763 newDMnetwork->NEdges = oldDMnetwork->NEdges; 764 765 /* Set Dof section as the default section for dm */ 766 ierr = DMSetDefaultSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr); 767 ierr = DMGetDefaultGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr); 768 769 /* Destroy point SF */ 770 ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr); 771 772 ierr = DMDestroy(dm);CHKERRQ(ierr); 773 *dm = newDM; 774 775 PetscFunctionReturn(0); 776 } 777 778 /*@C 779 PetscSFGetSubSF - Returns an SF for a specific subset of points. Leaves are re-numbered to reflect the new ordering. 780 781 Input Parameters: 782 + masterSF - the original SF structure 783 - map - a ISLocalToGlobal mapping that contains the subset of points 784 785 Output Parameters: 786 . subSF - a subset of the masterSF for the desired subset. 787 */ 788 789 PetscErrorCode PetscSFGetSubSF(PetscSF mastersf, ISLocalToGlobalMapping map, PetscSF *subSF) { 790 791 PetscErrorCode ierr; 792 PetscInt nroots, nleaves, *ilocal_sub; 793 PetscInt i, *ilocal_map, nroots_sub, nleaves_sub = 0; 794 PetscInt *local_points, *remote_points; 795 PetscSFNode *iremote_sub; 796 const PetscInt *ilocal; 797 const PetscSFNode *iremote; 798 799 PetscFunctionBegin; 800 ierr = PetscSFGetGraph(mastersf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr); 801 802 /* Look for leaves that pertain to the subset of points. Get the local ordering */ 803 ierr = PetscMalloc1(nleaves,&ilocal_map);CHKERRQ(ierr); 804 ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nleaves,ilocal,NULL,ilocal_map);CHKERRQ(ierr); 805 for (i = 0; i < nleaves; i++) { 806 if (ilocal_map[i] != -1) nleaves_sub += 1; 807 } 808 /* Re-number ilocal with subset numbering. Need information from roots */ 809 ierr = PetscMalloc2(nroots,&local_points,nroots,&remote_points);CHKERRQ(ierr); 810 for (i = 0; i < nroots; i++) local_points[i] = i; 811 ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nroots,local_points,NULL,local_points);CHKERRQ(ierr); 812 ierr = PetscSFBcastBegin(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr); 813 ierr = PetscSFBcastEnd(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr); 814 /* Fill up graph using local (that is, local to the subset) numbering. */ 815 ierr = PetscMalloc1(nleaves_sub,&ilocal_sub);CHKERRQ(ierr); 816 ierr = PetscMalloc1(nleaves_sub,&iremote_sub);CHKERRQ(ierr); 817 nleaves_sub = 0; 818 for (i = 0; i < nleaves; i++) { 819 if (ilocal_map[i] != -1) { 820 ilocal_sub[nleaves_sub] = ilocal_map[i]; 821 iremote_sub[nleaves_sub].rank = iremote[i].rank; 822 iremote_sub[nleaves_sub].index = remote_points[ilocal[i]]; 823 nleaves_sub += 1; 824 } 825 } 826 ierr = PetscFree2(local_points,remote_points);CHKERRQ(ierr); 827 ierr = ISLocalToGlobalMappingGetSize(map,&nroots_sub);CHKERRQ(ierr); 828 829 /* Create new subSF */ 830 ierr = PetscSFCreate(PETSC_COMM_WORLD,subSF);CHKERRQ(ierr); 831 ierr = PetscSFSetFromOptions(*subSF);CHKERRQ(ierr); 832 ierr = PetscSFSetGraph(*subSF,nroots_sub,nleaves_sub,ilocal_sub,PETSC_OWN_POINTER,iremote_sub,PETSC_COPY_VALUES);CHKERRQ(ierr); 833 ierr = PetscFree(ilocal_map);CHKERRQ(ierr); 834 ierr = PetscFree(iremote_sub);CHKERRQ(ierr); 835 836 PetscFunctionReturn(0); 837 } 838 839 840 /*@C 841 DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point 842 843 Not Collective 844 845 Input Parameters: 846 + dm - The DMNetwork object 847 - p - the vertex point 848 849 Output Paramters: 850 + nedges - number of edges connected to this vertex point 851 - edges - List of edge points 852 853 Level: intermediate 854 855 Fortran Notes: 856 Since it returns an array, this routine is only available in Fortran 90, and you must 857 include petsc.h90 in your code. 858 859 .seealso: DMNetworkCreate, DMNetworkGetConnectedNodes 860 @*/ 861 PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[]) 862 { 863 PetscErrorCode ierr; 864 DM_Network *network = (DM_Network*)dm->data; 865 866 PetscFunctionBegin; 867 ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr); 868 ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr); 869 PetscFunctionReturn(0); 870 } 871 872 /*@C 873 DMNetworkGetConnectedNodes - Return the connected vertices for this edge point 874 875 Not Collective 876 877 Input Parameters: 878 + dm - The DMNetwork object 879 - p - the edge point 880 881 Output Paramters: 882 . vertices - vertices connected to this edge 883 884 Level: intermediate 885 886 Fortran Notes: 887 Since it returns an array, this routine is only available in Fortran 90, and you must 888 include petsc.h90 in your code. 889 890 .seealso: DMNetworkCreate, DMNetworkGetSupportingEdges 891 @*/ 892 PetscErrorCode DMNetworkGetConnectedNodes(DM dm,PetscInt edge,const PetscInt *vertices[]) 893 { 894 PetscErrorCode ierr; 895 DM_Network *network = (DM_Network*)dm->data; 896 897 PetscFunctionBegin; 898 ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr); 899 PetscFunctionReturn(0); 900 } 901 902 /*@ 903 DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex 904 905 Not Collective 906 907 Input Parameters: 908 + dm - The DMNetwork object 909 . p - the vertex point 910 911 Output Parameter: 912 . isghost - TRUE if the vertex is a ghost point 913 914 Level: intermediate 915 916 .seealso: DMNetworkCreate, DMNetworkGetConnectedNodes, DMNetworkGetVertexRange 917 @*/ 918 PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost) 919 { 920 PetscErrorCode ierr; 921 DM_Network *network = (DM_Network*)dm->data; 922 PetscInt offsetg; 923 PetscSection sectiong; 924 925 PetscFunctionBegin; 926 *isghost = PETSC_FALSE; 927 ierr = DMGetDefaultGlobalSection(network->plex,§iong);CHKERRQ(ierr); 928 ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr); 929 if (offsetg < 0) *isghost = PETSC_TRUE; 930 PetscFunctionReturn(0); 931 } 932 933 PetscErrorCode DMSetUp_Network(DM dm) 934 { 935 PetscErrorCode ierr; 936 DM_Network *network=(DM_Network*)dm->data; 937 938 PetscFunctionBegin; 939 ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr); 940 ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr); 941 942 ierr = DMSetDefaultSection(network->plex,network->DofSection);CHKERRQ(ierr); 943 ierr = DMGetDefaultGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr); 944 PetscFunctionReturn(0); 945 } 946 947 /*@ 948 DMNetworkHasJacobian - Sets global flag for using user's sub Jacobian matrices 949 -- replaced by DMNetworkSetOption(network,userjacobian,PETSC_TURE)? 950 951 Collective 952 953 Input Parameters: 954 + dm - The DMNetwork object 955 . eflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for edges 956 - vflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for vertices 957 958 Level: intermediate 959 960 @*/ 961 PetscErrorCode DMNetworkHasJacobian(DM dm,PetscBool eflg,PetscBool vflg) 962 { 963 DM_Network *network=(DM_Network*)dm->data; 964 965 PetscFunctionBegin; 966 network->userEdgeJacobian = eflg; 967 network->userVertexJacobian = vflg; 968 PetscFunctionReturn(0); 969 } 970 971 /*@ 972 DMNetworkEdgeSetMatrix - Sets user-provided Jacobian matrices for this edge to the network 973 974 Not Collective 975 976 Input Parameters: 977 + dm - The DMNetwork object 978 . p - the edge point 979 - J - array (size = 3) of Jacobian submatrices for this edge point: 980 J[0]: this edge 981 J[1] and J[2]: connected vertices, obtained by calling DMNetworkGetConnectedNodes() 982 983 Level: intermediate 984 985 .seealso: DMNetworkVertexSetMatrix 986 @*/ 987 PetscErrorCode DMNetworkEdgeSetMatrix(DM dm,PetscInt p,Mat J[]) 988 { 989 PetscErrorCode ierr; 990 DM_Network *network=(DM_Network*)dm->data; 991 992 PetscFunctionBegin; 993 if (!network->userEdgeJacobian) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkEdgeSetMatrix"); 994 if (!network->Je) { 995 ierr = PetscCalloc1(3*network->nEdges,&network->Je);CHKERRQ(ierr); 996 } 997 network->Je[3*p] = J[0]; 998 network->Je[3*p+1] = J[1]; 999 network->Je[3*p+2] = J[2]; 1000 PetscFunctionReturn(0); 1001 } 1002 1003 /*@ 1004 DMNetworkVertexSetMatrix - Sets user-provided Jacobian matrix for this vertex to the network 1005 1006 Not Collective 1007 1008 Input Parameters: 1009 + dm - The DMNetwork object 1010 . p - the vertex point 1011 - J - array of Jacobian (size = 2*(num of supporting edges) + 1) submatrices for this vertex point: 1012 J[0]: this vertex 1013 J[1+2*i]: i-th supporting edge 1014 J[1+2*i+1]: i-th connected vertex 1015 1016 Level: intermediate 1017 1018 .seealso: DMNetworkEdgeSetMatrix 1019 @*/ 1020 PetscErrorCode DMNetworkVertexSetMatrix(DM dm,PetscInt p,Mat J[]) 1021 { 1022 PetscErrorCode ierr; 1023 DM_Network *network=(DM_Network*)dm->data; 1024 PetscInt i,*vptr,nedges,vStart,vEnd; 1025 const PetscInt *edges; 1026 1027 PetscFunctionBegin; 1028 if (!network->userVertexJacobian) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkVertexSetMatrix"); 1029 1030 ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 1031 1032 if (!network->Jv) { 1033 PetscInt nNodes = network->nNodes,nedges_total; 1034 /* count nvertex_total */ 1035 nedges_total = 0; 1036 ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 1037 ierr = PetscMalloc1(nNodes+1,&vptr);CHKERRQ(ierr); 1038 1039 vptr[0] = 0; 1040 for (i=0; i<nNodes; i++) { 1041 ierr = DMNetworkGetSupportingEdges(dm,i+vStart,&nedges,&edges);CHKERRQ(ierr); 1042 nedges_total += nedges; 1043 vptr[i+1] = vptr[i] + 2*nedges + 1; 1044 } 1045 1046 ierr = PetscCalloc1(2*nedges_total+nNodes,&network->Jv);CHKERRQ(ierr); 1047 network->Jvptr = vptr; 1048 } 1049 1050 vptr = network->Jvptr; 1051 network->Jv[vptr[p-vStart]] = J[0]; /* Set Jacobian for this vertex */ 1052 1053 /* Set Jacobian for each supporting edge and connected vertex */ 1054 ierr = DMNetworkGetSupportingEdges(dm,p,&nedges,&edges);CHKERRQ(ierr); 1055 for (i=1; i<=2*nedges; i++) network->Jv[vptr[p-vStart]+i] = J[i]; 1056 PetscFunctionReturn(0); 1057 } 1058 1059 PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 1060 { 1061 PetscErrorCode ierr; 1062 PetscInt j; 1063 PetscScalar val=(PetscScalar)ncols; 1064 1065 PetscFunctionBegin; 1066 if (!ghost) { 1067 for (j=0; j<nrows; j++) { 1068 ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 1069 } 1070 } else { 1071 for (j=0; j<nrows; j++) { 1072 ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 1073 } 1074 } 1075 PetscFunctionReturn(0); 1076 } 1077 1078 PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 1079 { 1080 PetscErrorCode ierr; 1081 PetscInt j,ncols_u; 1082 PetscScalar val; 1083 1084 PetscFunctionBegin; 1085 if (!ghost) { 1086 for (j=0; j<nrows; j++) { 1087 ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 1088 val = (PetscScalar)ncols_u; 1089 ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 1090 ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 1091 } 1092 } else { 1093 for (j=0; j<nrows; j++) { 1094 ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 1095 val = (PetscScalar)ncols_u; 1096 ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 1097 ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 1098 } 1099 } 1100 PetscFunctionReturn(0); 1101 } 1102 1103 PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 1104 { 1105 PetscErrorCode ierr; 1106 1107 PetscFunctionBegin; 1108 if (Ju) { 1109 ierr = MatSetPreallocationUserblock_private(Ju,nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 1110 } else { 1111 ierr = MatSetPreallocationDenseblock_private(nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 1112 } 1113 PetscFunctionReturn(0); 1114 } 1115 1116 PETSC_STATIC_INLINE PetscErrorCode MatSetDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 1117 { 1118 PetscErrorCode ierr; 1119 PetscInt j,*cols; 1120 PetscScalar *zeros; 1121 1122 PetscFunctionBegin; 1123 ierr = PetscCalloc2(ncols,&cols,nrows*ncols,&zeros);CHKERRQ(ierr); 1124 for (j=0; j<ncols; j++) cols[j] = j+ cstart; 1125 ierr = MatSetValues(*J,nrows,rows,ncols,cols,zeros,INSERT_VALUES);CHKERRQ(ierr); 1126 ierr = PetscFree2(cols,zeros);CHKERRQ(ierr); 1127 PetscFunctionReturn(0); 1128 } 1129 1130 PETSC_STATIC_INLINE PetscErrorCode MatSetUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 1131 { 1132 PetscErrorCode ierr; 1133 PetscInt j,M,N,row,col,ncols_u; 1134 const PetscInt *cols; 1135 PetscScalar zero=0.0; 1136 1137 PetscFunctionBegin; 1138 ierr = MatGetSize(Ju,&M,&N);CHKERRQ(ierr); 1139 if (nrows != M || ncols != N) SETERRQ4(PetscObjectComm((PetscObject)Ju),PETSC_ERR_USER,"%D by %D must equal %D by %D",nrows,ncols,M,N); 1140 1141 for (row=0; row<nrows; row++) { 1142 ierr = MatGetRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 1143 for (j=0; j<ncols_u; j++) { 1144 col = cols[j] + cstart; 1145 ierr = MatSetValues(*J,1,&rows[row],1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr); 1146 } 1147 ierr = MatRestoreRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 1148 } 1149 PetscFunctionReturn(0); 1150 } 1151 1152 PETSC_STATIC_INLINE PetscErrorCode MatSetblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 1153 { 1154 PetscErrorCode ierr; 1155 1156 PetscFunctionBegin; 1157 if (Ju) { 1158 ierr = MatSetUserblock_private(Ju,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 1159 } else { 1160 ierr = MatSetDenseblock_private(nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 1161 } 1162 PetscFunctionReturn(0); 1163 } 1164 1165 1166 /* Creates a GlobalToLocal mapping with a Local and Global section. This is akin to the routine DMGetLocalToGlobalMapping but without the need of providing a dm. 1167 */ 1168 PetscErrorCode CreateSubGlobalToLocalMapping_private(PetscSection globalsec, PetscSection localsec, ISLocalToGlobalMapping *ltog) 1169 { 1170 PetscErrorCode ierr; 1171 PetscInt i, size, dof; 1172 PetscInt *glob2loc; 1173 1174 PetscFunctionBegin; 1175 ierr = PetscSectionGetStorageSize(localsec,&size);CHKERRQ(ierr); 1176 ierr = PetscMalloc1(size,&glob2loc);CHKERRQ(ierr); 1177 1178 for (i = 0; i < size; i++) { 1179 ierr = PetscSectionGetOffset(globalsec,i,&dof);CHKERRQ(ierr); 1180 dof = (dof >= 0) ? dof : -(dof + 1); 1181 glob2loc[i] = dof; 1182 } 1183 1184 ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,size,glob2loc,PETSC_OWN_POINTER,ltog);CHKERRQ(ierr); 1185 #if 0 1186 ierr = PetscIntView(size,glob2loc,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 1187 #endif 1188 PetscFunctionReturn(0); 1189 } 1190 1191 PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J) 1192 { 1193 PetscErrorCode ierr; 1194 PetscMPIInt rank, size; 1195 DM_Network *network = (DM_Network*) dm->data; 1196 PetscInt eStart,eEnd,vStart,vEnd,rstart,nrows,*rows,localSize; 1197 PetscInt cstart,ncols,j,e,v; 1198 PetscBool ghost,ghost_vc,ghost2,isNest; 1199 Mat Juser; 1200 PetscSection sectionGlobal; 1201 PetscInt nedges,*vptr=NULL,vc,*rows_v; /* suppress maybe-uninitialized warning */ 1202 const PetscInt *edges,*cone; 1203 MPI_Comm comm; 1204 MatType mtype; 1205 Vec vd_nz,vo_nz; 1206 PetscInt *dnnz,*onnz; 1207 PetscScalar *vdnz,*vonz; 1208 1209 PetscFunctionBegin; 1210 mtype = dm->mattype; 1211 ierr = PetscStrcmp(mtype, MATNEST, &isNest);CHKERRQ(ierr); 1212 1213 if (isNest) { 1214 /* ierr = DMCreateMatrix_Network_Nest(); */ 1215 PetscInt eDof, vDof; 1216 Mat j11, j12, j21, j22, bA[2][2]; 1217 ISLocalToGlobalMapping eISMap, vISMap; 1218 1219 ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 1220 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 1221 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 1222 1223 ierr = PetscSectionGetConstrainedStorageSize(network->edge.GlobalDofSection,&eDof);CHKERRQ(ierr); 1224 ierr = PetscSectionGetConstrainedStorageSize(network->vertex.GlobalDofSection,&vDof);CHKERRQ(ierr); 1225 1226 ierr = MatCreate(PETSC_COMM_WORLD, &j11);CHKERRQ(ierr); 1227 ierr = MatSetSizes(j11, eDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 1228 ierr = MatSetType(j11, MATMPIAIJ);CHKERRQ(ierr); 1229 1230 ierr = MatCreate(PETSC_COMM_WORLD, &j12);CHKERRQ(ierr); 1231 ierr = MatSetSizes(j12, eDof, vDof, PETSC_DETERMINE ,PETSC_DETERMINE);CHKERRQ(ierr); 1232 ierr = MatSetType(j12, MATMPIAIJ);CHKERRQ(ierr); 1233 1234 ierr = MatCreate(PETSC_COMM_WORLD, &j21);CHKERRQ(ierr); 1235 ierr = MatSetSizes(j21, vDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 1236 ierr = MatSetType(j21, MATMPIAIJ);CHKERRQ(ierr); 1237 1238 ierr = MatCreate(PETSC_COMM_WORLD, &j22);CHKERRQ(ierr); 1239 ierr = MatSetSizes(j22, vDof, vDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 1240 ierr = MatSetType(j22, MATMPIAIJ);CHKERRQ(ierr); 1241 1242 bA[0][0] = j11; 1243 bA[0][1] = j12; 1244 bA[1][0] = j21; 1245 bA[1][1] = j22; 1246 1247 ierr = CreateSubGlobalToLocalMapping_private(network->edge.GlobalDofSection,network->edge.DofSection,&eISMap);CHKERRQ(ierr); 1248 ierr = CreateSubGlobalToLocalMapping_private(network->vertex.GlobalDofSection,network->vertex.DofSection,&vISMap);CHKERRQ(ierr); 1249 1250 ierr = MatSetLocalToGlobalMapping(j11,eISMap,eISMap);CHKERRQ(ierr); 1251 ierr = MatSetLocalToGlobalMapping(j12,eISMap,vISMap);CHKERRQ(ierr); 1252 ierr = MatSetLocalToGlobalMapping(j21,vISMap,eISMap);CHKERRQ(ierr); 1253 ierr = MatSetLocalToGlobalMapping(j22,vISMap,vISMap);CHKERRQ(ierr); 1254 1255 ierr = MatSetUp(j11);CHKERRQ(ierr); 1256 ierr = MatSetUp(j12);CHKERRQ(ierr); 1257 ierr = MatSetUp(j21);CHKERRQ(ierr); 1258 ierr = MatSetUp(j22);CHKERRQ(ierr); 1259 1260 ierr = MatCreateNest(PETSC_COMM_WORLD,2,NULL,2,NULL,&bA[0][0],J);CHKERRQ(ierr); 1261 ierr = MatSetUp(*J);CHKERRQ(ierr); 1262 ierr = MatNestSetVecType(*J,VECNEST);CHKERRQ(ierr); 1263 ierr = MatDestroy(&j11);CHKERRQ(ierr); 1264 ierr = MatDestroy(&j12);CHKERRQ(ierr); 1265 ierr = MatDestroy(&j21);CHKERRQ(ierr); 1266 ierr = MatDestroy(&j22);CHKERRQ(ierr); 1267 1268 ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1269 ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1270 1271 /* Free structures */ 1272 ierr = ISLocalToGlobalMappingDestroy(&eISMap);CHKERRQ(ierr); 1273 ierr = ISLocalToGlobalMappingDestroy(&vISMap);CHKERRQ(ierr); 1274 1275 PetscFunctionReturn(0); 1276 } else if (!network->userEdgeJacobian && !network->userVertexJacobian) { 1277 /* user does not provide Jacobian blocks */ 1278 ierr = DMCreateMatrix(network->plex,J);CHKERRQ(ierr); 1279 ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 1280 PetscFunctionReturn(0); 1281 } 1282 1283 ierr = MatCreate(PetscObjectComm((PetscObject)dm),J);CHKERRQ(ierr); 1284 ierr = DMGetDefaultGlobalSection(network->plex,§ionGlobal);CHKERRQ(ierr); 1285 ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal,&localSize);CHKERRQ(ierr); 1286 ierr = MatSetSizes(*J,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 1287 1288 ierr = MatSetType(*J,MATAIJ);CHKERRQ(ierr); 1289 ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 1290 1291 /* (1) Set matrix preallocation */ 1292 /*------------------------------*/ 1293 ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 1294 ierr = VecCreate(comm,&vd_nz);CHKERRQ(ierr); 1295 ierr = VecSetSizes(vd_nz,localSize,PETSC_DECIDE);CHKERRQ(ierr); 1296 ierr = VecSetFromOptions(vd_nz);CHKERRQ(ierr); 1297 ierr = VecSet(vd_nz,0.0);CHKERRQ(ierr); 1298 ierr = VecDuplicate(vd_nz,&vo_nz);CHKERRQ(ierr); 1299 1300 /* Set preallocation for edges */ 1301 /*-----------------------------*/ 1302 ierr = DMNetworkGetEdgeRange(dm,&eStart,&eEnd);CHKERRQ(ierr); 1303 1304 ierr = PetscMalloc1(localSize,&rows);CHKERRQ(ierr); 1305 for (e=eStart; e<eEnd; e++) { 1306 /* Get row indices */ 1307 ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr); 1308 ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr); 1309 if (nrows) { 1310 if (!network->Je) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Uer must provide Je"); 1311 for (j=0; j<nrows; j++) rows[j] = j + rstart; 1312 1313 /* Set preallocation for conntected vertices */ 1314 ierr = DMNetworkGetConnectedNodes(dm,e,&cone);CHKERRQ(ierr); 1315 for (v=0; v<2; v++) { 1316 ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr); 1317 1318 Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 1319 ierr = DMNetworkIsGhostVertex(dm,cone[v],&ghost);CHKERRQ(ierr); 1320 ierr = MatSetPreallocationblock_private(Juser,nrows,rows,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 1321 } 1322 1323 /* Set preallocation for edge self */ 1324 cstart = rstart; 1325 Juser = network->Je[3*e]; /* Jacobian(e,e) */ 1326 ierr = MatSetPreallocationblock_private(Juser,nrows,rows,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 1327 } 1328 } 1329 1330 /* Set preallocation for vertices */ 1331 /*--------------------------------*/ 1332 ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 1333 if (vEnd - vStart) { 1334 if (!network->Jv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Uer must provide Jv"); 1335 vptr = network->Jvptr; 1336 if (!vptr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Uer must provide vptr"); 1337 } 1338 1339 for (v=vStart; v<vEnd; v++) { 1340 /* Get row indices */ 1341 ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr); 1342 ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr); 1343 if (!nrows) continue; 1344 1345 ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 1346 if (ghost) { 1347 ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 1348 } else { 1349 rows_v = rows; 1350 } 1351 1352 for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 1353 1354 /* Get supporting edges and connected vertices */ 1355 ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 1356 1357 for (e=0; e<nedges; e++) { 1358 /* Supporting edges */ 1359 ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr); 1360 ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr); 1361 1362 Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 1363 ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 1364 1365 /* Connected vertices */ 1366 ierr = DMNetworkGetConnectedNodes(dm,edges[e],&cone);CHKERRQ(ierr); 1367 vc = (v == cone[0]) ? cone[1]:cone[0]; 1368 ierr = DMNetworkIsGhostVertex(dm,vc,&ghost_vc);CHKERRQ(ierr); 1369 1370 ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr); 1371 1372 Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 1373 if (ghost_vc||ghost) { 1374 ghost2 = PETSC_TRUE; 1375 } else { 1376 ghost2 = PETSC_FALSE; 1377 } 1378 ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost2,vd_nz,vo_nz);CHKERRQ(ierr); 1379 } 1380 1381 /* Set preallocation for vertex self */ 1382 ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 1383 if (!ghost) { 1384 ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr); 1385 Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 1386 ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 1387 } 1388 if (ghost) { 1389 ierr = PetscFree(rows_v);CHKERRQ(ierr); 1390 } 1391 } 1392 1393 ierr = VecAssemblyBegin(vd_nz);CHKERRQ(ierr); 1394 ierr = VecAssemblyBegin(vo_nz);CHKERRQ(ierr); 1395 1396 ierr = PetscMalloc2(localSize,&dnnz,localSize,&onnz);CHKERRQ(ierr); 1397 1398 ierr = VecAssemblyEnd(vd_nz);CHKERRQ(ierr); 1399 ierr = VecAssemblyEnd(vo_nz);CHKERRQ(ierr); 1400 1401 ierr = VecGetArray(vd_nz,&vdnz);CHKERRQ(ierr); 1402 ierr = VecGetArray(vo_nz,&vonz);CHKERRQ(ierr); 1403 for (j=0; j<localSize; j++) { 1404 dnnz[j] = (PetscInt)PetscRealPart(vdnz[j]); 1405 onnz[j] = (PetscInt)PetscRealPart(vonz[j]); 1406 } 1407 ierr = VecRestoreArray(vd_nz,&vdnz);CHKERRQ(ierr); 1408 ierr = VecRestoreArray(vo_nz,&vonz);CHKERRQ(ierr); 1409 ierr = VecDestroy(&vd_nz);CHKERRQ(ierr); 1410 ierr = VecDestroy(&vo_nz);CHKERRQ(ierr); 1411 1412 ierr = MatSeqAIJSetPreallocation(*J,0,dnnz);CHKERRQ(ierr); 1413 ierr = MatMPIAIJSetPreallocation(*J,0,dnnz,0,onnz);CHKERRQ(ierr); 1414 ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 1415 1416 ierr = PetscFree2(dnnz,onnz);CHKERRQ(ierr); 1417 1418 /* (2) Set matrix entries for edges */ 1419 /*----------------------------------*/ 1420 for (e=eStart; e<eEnd; e++) { 1421 /* Get row indices */ 1422 ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr); 1423 ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr); 1424 if (nrows) { 1425 if (!network->Je) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Uer must provide Je"); 1426 1427 for (j=0; j<nrows; j++) rows[j] = j + rstart; 1428 1429 /* Set matrix entries for conntected vertices */ 1430 ierr = DMNetworkGetConnectedNodes(dm,e,&cone);CHKERRQ(ierr); 1431 for (v=0; v<2; v++) { 1432 ierr = DMNetworkGetVariableGlobalOffset(dm,cone[v],&cstart);CHKERRQ(ierr); 1433 ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr); 1434 1435 Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 1436 ierr = MatSetblock_private(Juser,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 1437 } 1438 1439 /* Set matrix entries for edge self */ 1440 cstart = rstart; 1441 Juser = network->Je[3*e]; /* Jacobian(e,e) */ 1442 ierr = MatSetblock_private(Juser,nrows,rows,nrows,cstart,J);CHKERRQ(ierr); 1443 } 1444 } 1445 1446 /* Set matrix entries for vertices */ 1447 /*---------------------------------*/ 1448 for (v=vStart; v<vEnd; v++) { 1449 /* Get row indices */ 1450 ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr); 1451 ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr); 1452 if (!nrows) continue; 1453 1454 ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 1455 if (ghost) { 1456 ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 1457 } else { 1458 rows_v = rows; 1459 } 1460 for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 1461 1462 /* Get supporting edges and connected vertices */ 1463 ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 1464 1465 for (e=0; e<nedges; e++) { 1466 /* Supporting edges */ 1467 ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr); 1468 ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr); 1469 1470 Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 1471 ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 1472 1473 /* Connected vertices */ 1474 ierr = DMNetworkGetConnectedNodes(dm,edges[e],&cone);CHKERRQ(ierr); 1475 vc = (v == cone[0]) ? cone[1]:cone[0]; 1476 1477 ierr = DMNetworkGetVariableGlobalOffset(dm,vc,&cstart);CHKERRQ(ierr); 1478 ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr); 1479 1480 Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 1481 ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 1482 } 1483 1484 /* Set matrix entries for vertex self */ 1485 if (!ghost) { 1486 ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr); 1487 Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 1488 ierr = MatSetblock_private(Juser,nrows,rows_v,nrows,cstart,J);CHKERRQ(ierr); 1489 } 1490 if (ghost) { 1491 ierr = PetscFree(rows_v);CHKERRQ(ierr); 1492 } 1493 } 1494 ierr = PetscFree(rows);CHKERRQ(ierr); 1495 1496 ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1497 ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1498 1499 ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 1500 PetscFunctionReturn(0); 1501 } 1502 1503 PetscErrorCode DMDestroy_Network(DM dm) 1504 { 1505 PetscErrorCode ierr; 1506 DM_Network *network = (DM_Network*) dm->data; 1507 1508 PetscFunctionBegin; 1509 if (--network->refct > 0) PetscFunctionReturn(0); 1510 if (network->Je) { 1511 ierr = PetscFree(network->Je);CHKERRQ(ierr); 1512 } 1513 if (network->Jv) { 1514 ierr = PetscFree(network->Jvptr);CHKERRQ(ierr); 1515 ierr = PetscFree(network->Jv);CHKERRQ(ierr); 1516 } 1517 1518 ierr = ISLocalToGlobalMappingDestroy(&network->vertex.mapping);CHKERRQ(ierr); 1519 ierr = PetscSectionDestroy(&network->vertex.DofSection);CHKERRQ(ierr); 1520 ierr = PetscSectionDestroy(&network->vertex.GlobalDofSection);CHKERRQ(ierr); 1521 if (network->vertex.sf) { 1522 ierr = PetscSFDestroy(&network->vertex.sf);CHKERRQ(ierr); 1523 } 1524 /* edge */ 1525 ierr = ISLocalToGlobalMappingDestroy(&network->edge.mapping);CHKERRQ(ierr); 1526 ierr = PetscSectionDestroy(&network->edge.DofSection);CHKERRQ(ierr); 1527 ierr = PetscSectionDestroy(&network->edge.GlobalDofSection);CHKERRQ(ierr); 1528 if (network->edge.sf) { 1529 ierr = PetscSFDestroy(&network->edge.sf);CHKERRQ(ierr); 1530 } 1531 ierr = DMDestroy(&network->plex);CHKERRQ(ierr); 1532 network->edges = NULL; 1533 ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr); 1534 ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr); 1535 1536 ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr); 1537 ierr = PetscFree(network->cvalue);CHKERRQ(ierr); 1538 ierr = PetscFree(network->header);CHKERRQ(ierr); 1539 ierr = PetscFree(network);CHKERRQ(ierr); 1540 PetscFunctionReturn(0); 1541 } 1542 1543 PetscErrorCode DMView_Network(DM dm, PetscViewer viewer) 1544 { 1545 PetscErrorCode ierr; 1546 DM_Network *network = (DM_Network*) dm->data; 1547 1548 PetscFunctionBegin; 1549 ierr = DMView(network->plex,viewer);CHKERRQ(ierr); 1550 PetscFunctionReturn(0); 1551 } 1552 1553 PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l) 1554 { 1555 PetscErrorCode ierr; 1556 DM_Network *network = (DM_Network*) dm->data; 1557 1558 PetscFunctionBegin; 1559 ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr); 1560 PetscFunctionReturn(0); 1561 } 1562 1563 PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l) 1564 { 1565 PetscErrorCode ierr; 1566 DM_Network *network = (DM_Network*) dm->data; 1567 1568 PetscFunctionBegin; 1569 ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr); 1570 PetscFunctionReturn(0); 1571 } 1572 1573 PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g) 1574 { 1575 PetscErrorCode ierr; 1576 DM_Network *network = (DM_Network*) dm->data; 1577 1578 PetscFunctionBegin; 1579 ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr); 1580 PetscFunctionReturn(0); 1581 } 1582 1583 PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g) 1584 { 1585 PetscErrorCode ierr; 1586 DM_Network *network = (DM_Network*) dm->data; 1587 1588 PetscFunctionBegin; 1589 ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr); 1590 PetscFunctionReturn(0); 1591 } 1592