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