1af0996ceSBarry Smith #include <petsc/private/dmnetworkimpl.h> /*I "petscdmnetwork.h" I*/ 25f2c45f1SShri Abhyankar #include <petscdmplex.h> 35f2c45f1SShri Abhyankar #include <petscsf.h> 45f2c45f1SShri Abhyankar 55f2c45f1SShri Abhyankar #undef __FUNCT__ 65f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkSetSizes" 75f2c45f1SShri Abhyankar /*@ 85f2c45f1SShri Abhyankar DMNetworkSetSizes - Sets the local and global vertices and edges. 95f2c45f1SShri Abhyankar 105f2c45f1SShri Abhyankar Collective on DM 115f2c45f1SShri Abhyankar 125f2c45f1SShri Abhyankar Input Parameters: 135f2c45f1SShri Abhyankar + dm - the dm object 145f2c45f1SShri Abhyankar . nV - number of local vertices 155f2c45f1SShri Abhyankar . nE - number of local edges 165f2c45f1SShri Abhyankar . NV - number of global vertices (or PETSC_DETERMINE) 175f2c45f1SShri Abhyankar - NE - number of global edges (or PETSC_DETERMINE) 185f2c45f1SShri Abhyankar 195f2c45f1SShri Abhyankar Notes 205f2c45f1SShri Abhyankar If one processor calls this with NV (NE) of PETSC_DECIDE then all processors must, otherwise the prgram will hang. 215f2c45f1SShri Abhyankar 225f2c45f1SShri Abhyankar You cannot change the sizes once they have been set 235f2c45f1SShri Abhyankar 245f2c45f1SShri Abhyankar Level: intermediate 255f2c45f1SShri Abhyankar 265f2c45f1SShri Abhyankar .seealso: DMNetworkCreate 275f2c45f1SShri Abhyankar @*/ 285f2c45f1SShri Abhyankar PetscErrorCode DMNetworkSetSizes(DM dm, PetscInt nV, PetscInt nE, PetscInt NV, PetscInt NE) 295f2c45f1SShri Abhyankar { 305f2c45f1SShri Abhyankar PetscErrorCode ierr; 315f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 325f2c45f1SShri Abhyankar PetscInt a[2],b[2]; 335f2c45f1SShri Abhyankar 345f2c45f1SShri Abhyankar PetscFunctionBegin; 355f2c45f1SShri Abhyankar PetscValidHeaderSpecific(dm,DM_CLASSID,1); 365f2c45f1SShri Abhyankar if (NV > 0) PetscValidLogicalCollectiveInt(dm,NV,4); 375f2c45f1SShri Abhyankar if (NE > 0) PetscValidLogicalCollectiveInt(dm,NE,5); 385f2c45f1SShri Abhyankar 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); 395f2c45f1SShri Abhyankar 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); 405f2c45f1SShri Abhyankar 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); 415f2c45f1SShri Abhyankar 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); 425f2c45f1SShri Abhyankar if (NE < 0 || NV < 0) { 435f2c45f1SShri Abhyankar a[0] = nV; a[1] = nE; 44b2566f29SBarry Smith ierr = MPIU_Allreduce(a,b,2,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 455f2c45f1SShri Abhyankar NV = b[0]; NE = b[1]; 465f2c45f1SShri Abhyankar } 475f2c45f1SShri Abhyankar network->nNodes = nV; 485f2c45f1SShri Abhyankar network->NNodes = NV; 495f2c45f1SShri Abhyankar network->nEdges = nE; 505f2c45f1SShri Abhyankar network->NEdges = NE; 515f2c45f1SShri Abhyankar PetscFunctionReturn(0); 525f2c45f1SShri Abhyankar } 535f2c45f1SShri Abhyankar 545f2c45f1SShri Abhyankar #undef __FUNCT__ 555f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkSetEdgeList" 565f2c45f1SShri Abhyankar /*@ 575f2c45f1SShri Abhyankar DMNetworkSetEdgeList - Sets the list of local edges (vertex connectivity) for the network 585f2c45f1SShri Abhyankar 595f2c45f1SShri Abhyankar Logically collective on DM 605f2c45f1SShri Abhyankar 615f2c45f1SShri Abhyankar Input Parameters: 625f2c45f1SShri Abhyankar . edges - list of edges 635f2c45f1SShri Abhyankar 645f2c45f1SShri Abhyankar Notes: 655f2c45f1SShri Abhyankar There is no copy involved in this operation, only the pointer is referenced. The edgelist should 665f2c45f1SShri Abhyankar not be destroyed before the call to DMNetworkLayoutSetUp 675f2c45f1SShri Abhyankar 685f2c45f1SShri Abhyankar Level: intermediate 695f2c45f1SShri Abhyankar 705f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkSetSizes 715f2c45f1SShri Abhyankar @*/ 725f2c45f1SShri Abhyankar PetscErrorCode DMNetworkSetEdgeList(DM dm, int edgelist[]) 735f2c45f1SShri Abhyankar { 745f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 755f2c45f1SShri Abhyankar 765f2c45f1SShri Abhyankar PetscFunctionBegin; 775f2c45f1SShri Abhyankar network->edges = edgelist; 785f2c45f1SShri Abhyankar PetscFunctionReturn(0); 795f2c45f1SShri Abhyankar } 805f2c45f1SShri Abhyankar 815f2c45f1SShri Abhyankar #undef __FUNCT__ 825f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkLayoutSetUp" 835f2c45f1SShri Abhyankar /*@ 845f2c45f1SShri Abhyankar DMNetworkLayoutSetUp - Sets up the bare layout (graph) for the network 855f2c45f1SShri Abhyankar 865f2c45f1SShri Abhyankar Collective on DM 875f2c45f1SShri Abhyankar 885f2c45f1SShri Abhyankar Input Parameters 895f2c45f1SShri Abhyankar . DM - the dmnetwork object 905f2c45f1SShri Abhyankar 915f2c45f1SShri Abhyankar Notes: 925f2c45f1SShri Abhyankar This routine should be called after the network sizes and edgelists have been provided. It creates 935f2c45f1SShri Abhyankar the bare layout of the network and sets up the network to begin insertion of components. 945f2c45f1SShri Abhyankar 955f2c45f1SShri Abhyankar All the components should be registered before calling this routine. 965f2c45f1SShri Abhyankar 975f2c45f1SShri Abhyankar Level: intermediate 985f2c45f1SShri Abhyankar 995f2c45f1SShri Abhyankar .seealso: DMNetworkSetSizes, DMNetworkSetEdgeList 1005f2c45f1SShri Abhyankar @*/ 1015f2c45f1SShri Abhyankar PetscErrorCode DMNetworkLayoutSetUp(DM dm) 1025f2c45f1SShri Abhyankar { 1035f2c45f1SShri Abhyankar PetscErrorCode ierr; 1045f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 1055f2c45f1SShri Abhyankar PetscInt dim = 1; /* One dimensional network */ 1065f2c45f1SShri Abhyankar PetscInt numCorners=2; 1075f2c45f1SShri Abhyankar PetscInt spacedim=2; 1085f2c45f1SShri Abhyankar double *vertexcoords=NULL; 1095f2c45f1SShri Abhyankar PetscInt i; 1105f2c45f1SShri Abhyankar PetscInt ndata; 1115f2c45f1SShri Abhyankar 1125f2c45f1SShri Abhyankar PetscFunctionBegin; 1135f2c45f1SShri Abhyankar if (network->nNodes) { 1149045477aSSatish Balay ierr = PetscCalloc1(numCorners*network->nNodes,&vertexcoords);CHKERRQ(ierr); 1155f2c45f1SShri Abhyankar } 1165f2c45f1SShri Abhyankar ierr = DMPlexCreateFromCellList(PetscObjectComm((PetscObject)dm),dim,network->nEdges,network->nNodes,numCorners,PETSC_FALSE,network->edges,spacedim,vertexcoords,&network->plex);CHKERRQ(ierr); 1175f2c45f1SShri Abhyankar if (network->nNodes) { 1185f2c45f1SShri Abhyankar ierr = PetscFree(vertexcoords);CHKERRQ(ierr); 1195f2c45f1SShri Abhyankar } 1205f2c45f1SShri Abhyankar ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr); 1215f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr); 1225f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr); 1235f2c45f1SShri Abhyankar 1245f2c45f1SShri Abhyankar ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DataSection);CHKERRQ(ierr); 1255f2c45f1SShri Abhyankar ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DofSection);CHKERRQ(ierr); 1265f2c45f1SShri Abhyankar ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr); 1275f2c45f1SShri Abhyankar ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr); 1285f2c45f1SShri Abhyankar 1295f2c45f1SShri Abhyankar network->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 1306caa05f4SBarry Smith ierr = PetscCalloc1(network->pEnd-network->pStart,&network->header);CHKERRQ(ierr); 1315f2c45f1SShri Abhyankar for (i = network->pStart; i < network->pEnd; i++) { 1325f2c45f1SShri Abhyankar network->header[i].ndata = 0; 1335f2c45f1SShri Abhyankar ndata = network->header[i].ndata; 1345f2c45f1SShri Abhyankar ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr); 1355f2c45f1SShri Abhyankar network->header[i].offset[ndata] = 0; 1365f2c45f1SShri Abhyankar } 137854ce69bSBarry Smith ierr = PetscMalloc1(network->pEnd-network->pStart,&network->cvalue);CHKERRQ(ierr); 1385f2c45f1SShri Abhyankar PetscFunctionReturn(0); 1395f2c45f1SShri Abhyankar } 1405f2c45f1SShri Abhyankar 1415f2c45f1SShri Abhyankar #undef __FUNCT__ 1425f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkRegisterComponent" 1435f2c45f1SShri Abhyankar /*@ 1445f2c45f1SShri Abhyankar DMNetworkRegisterComponent - Registers the network component 1455f2c45f1SShri Abhyankar 1465f2c45f1SShri Abhyankar Logically collective on DM 1475f2c45f1SShri Abhyankar 1485f2c45f1SShri Abhyankar Input Parameters 1495f2c45f1SShri Abhyankar + dm - the network object 1505f2c45f1SShri Abhyankar . name - the component name 1515f2c45f1SShri Abhyankar - size - the storage size in bytes for this component data 1525f2c45f1SShri Abhyankar 1535f2c45f1SShri Abhyankar Output Parameters 1545f2c45f1SShri Abhyankar . key - an integer key that defines the component 1555f2c45f1SShri Abhyankar 1565f2c45f1SShri Abhyankar Notes 1575f2c45f1SShri Abhyankar This routine should be called by all processors before calling DMNetworkLayoutSetup(). 1585f2c45f1SShri Abhyankar 1595f2c45f1SShri Abhyankar Level: intermediate 1605f2c45f1SShri Abhyankar 1615f2c45f1SShri Abhyankar .seealso: DMNetworkLayoutSetUp, DMNetworkCreate 1625f2c45f1SShri Abhyankar @*/ 1635f2c45f1SShri Abhyankar PetscErrorCode DMNetworkRegisterComponent(DM dm,const char *name,PetscInt size,PetscInt *key) 1645f2c45f1SShri Abhyankar { 1655f2c45f1SShri Abhyankar PetscErrorCode ierr; 1665f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 1675f2c45f1SShri Abhyankar DMNetworkComponent *component=&network->component[network->ncomponent]; 1685f2c45f1SShri Abhyankar PetscBool flg=PETSC_FALSE; 1695f2c45f1SShri Abhyankar PetscInt i; 1705f2c45f1SShri Abhyankar 1715f2c45f1SShri Abhyankar PetscFunctionBegin; 1725f2c45f1SShri Abhyankar 1735f2c45f1SShri Abhyankar for (i=0; i < network->ncomponent; i++) { 1745f2c45f1SShri Abhyankar ierr = PetscStrcmp(component->name,name,&flg);CHKERRQ(ierr); 1755f2c45f1SShri Abhyankar if (flg) { 1765f2c45f1SShri Abhyankar *key = i; 1775f2c45f1SShri Abhyankar PetscFunctionReturn(0); 1785f2c45f1SShri Abhyankar } 1795f2c45f1SShri Abhyankar } 1805f2c45f1SShri Abhyankar 1815f2c45f1SShri Abhyankar ierr = PetscStrcpy(component->name,name);CHKERRQ(ierr); 1825f2c45f1SShri Abhyankar component->size = size/sizeof(DMNetworkComponentGenericDataType); 1835f2c45f1SShri Abhyankar *key = network->ncomponent; 1845f2c45f1SShri Abhyankar network->ncomponent++; 1855f2c45f1SShri Abhyankar PetscFunctionReturn(0); 1865f2c45f1SShri Abhyankar } 1875f2c45f1SShri Abhyankar 1885f2c45f1SShri Abhyankar #undef __FUNCT__ 1895f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetVertexRange" 1905f2c45f1SShri Abhyankar /*@ 1915f2c45f1SShri Abhyankar DMNetworkGetVertexRange - Get the bounds [start, end) for the vertices. 1925f2c45f1SShri Abhyankar 1935f2c45f1SShri Abhyankar Not Collective 1945f2c45f1SShri Abhyankar 1955f2c45f1SShri Abhyankar Input Parameters: 1965f2c45f1SShri Abhyankar + dm - The DMNetwork object 1975f2c45f1SShri Abhyankar 1985f2c45f1SShri Abhyankar Output Paramters: 1995f2c45f1SShri Abhyankar + vStart - The first vertex point 2005f2c45f1SShri Abhyankar - vEnd - One beyond the last vertex point 2015f2c45f1SShri Abhyankar 2025f2c45f1SShri Abhyankar Level: intermediate 2035f2c45f1SShri Abhyankar 2045f2c45f1SShri Abhyankar .seealso: DMNetworkGetEdgeRange 2055f2c45f1SShri Abhyankar @*/ 2065f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVertexRange(DM dm,PetscInt *vStart,PetscInt *vEnd) 2075f2c45f1SShri Abhyankar { 2085f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 2095f2c45f1SShri Abhyankar 2105f2c45f1SShri Abhyankar PetscFunctionBegin; 2115f2c45f1SShri Abhyankar if (vStart) *vStart = network->vStart; 2125f2c45f1SShri Abhyankar if (vEnd) *vEnd = network->vEnd; 2135f2c45f1SShri Abhyankar PetscFunctionReturn(0); 2145f2c45f1SShri Abhyankar } 2155f2c45f1SShri Abhyankar 2165f2c45f1SShri Abhyankar #undef __FUNCT__ 2175f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetEdgeRange" 2185f2c45f1SShri Abhyankar /*@ 2195f2c45f1SShri Abhyankar DMNetworkGetEdgeRange - Get the bounds [start, end) for the edges. 2205f2c45f1SShri Abhyankar 2215f2c45f1SShri Abhyankar Not Collective 2225f2c45f1SShri Abhyankar 2235f2c45f1SShri Abhyankar Input Parameters: 2245f2c45f1SShri Abhyankar + dm - The DMNetwork object 2255f2c45f1SShri Abhyankar 2265f2c45f1SShri Abhyankar Output Paramters: 2275f2c45f1SShri Abhyankar + eStart - The first edge point 2285f2c45f1SShri Abhyankar - eEnd - One beyond the last edge point 2295f2c45f1SShri Abhyankar 2305f2c45f1SShri Abhyankar Level: intermediate 2315f2c45f1SShri Abhyankar 2325f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange 2335f2c45f1SShri Abhyankar @*/ 2345f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetEdgeRange(DM dm,PetscInt *eStart,PetscInt *eEnd) 2355f2c45f1SShri Abhyankar { 2365f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 2375f2c45f1SShri Abhyankar 2385f2c45f1SShri Abhyankar PetscFunctionBegin; 2395f2c45f1SShri Abhyankar if (eStart) *eStart = network->eStart; 2405f2c45f1SShri Abhyankar if (eEnd) *eEnd = network->eEnd; 2415f2c45f1SShri Abhyankar PetscFunctionReturn(0); 2425f2c45f1SShri Abhyankar } 2435f2c45f1SShri Abhyankar 2445f2c45f1SShri Abhyankar #undef __FUNCT__ 2455f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkAddComponent" 2465f2c45f1SShri Abhyankar /*@ 2475f2c45f1SShri Abhyankar DMNetworkAddComponent - Adds a network component at the given point (vertex/edge) 2485f2c45f1SShri Abhyankar 2495f2c45f1SShri Abhyankar Not Collective 2505f2c45f1SShri Abhyankar 2515f2c45f1SShri Abhyankar Input Parameters: 2525f2c45f1SShri Abhyankar + dm - The DMNetwork object 2535f2c45f1SShri Abhyankar . p - vertex/edge point 2545f2c45f1SShri Abhyankar . componentkey - component key returned while registering the component 2555f2c45f1SShri Abhyankar - compvalue - pointer to the data structure for the component 2565f2c45f1SShri Abhyankar 2575f2c45f1SShri Abhyankar Level: intermediate 2585f2c45f1SShri Abhyankar 2595f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange, DMNetworkGetEdgeRange, DMNetworkRegisterComponent 2605f2c45f1SShri Abhyankar @*/ 2615f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddComponent(DM dm, PetscInt p,PetscInt componentkey,void* compvalue) 2625f2c45f1SShri Abhyankar { 2635f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 26443a39a44SBarry Smith DMNetworkComponent *component = &network->component[componentkey]; 2655f2c45f1SShri Abhyankar DMNetworkComponentHeader header = &network->header[p]; 2665f2c45f1SShri Abhyankar DMNetworkComponentValue cvalue = &network->cvalue[p]; 2675f2c45f1SShri Abhyankar PetscErrorCode ierr; 2685f2c45f1SShri Abhyankar 2695f2c45f1SShri Abhyankar PetscFunctionBegin; 27043a39a44SBarry Smith header->size[header->ndata] = component->size; 27143a39a44SBarry Smith ierr = PetscSectionAddDof(network->DataSection,p,component->size);CHKERRQ(ierr); 2725f2c45f1SShri Abhyankar header->key[header->ndata] = componentkey; 2735f2c45f1SShri Abhyankar if (header->ndata != 0) header->offset[header->ndata] = header->offset[header->ndata-1] + header->size[header->ndata-1]; 2745f2c45f1SShri Abhyankar 2755f2c45f1SShri Abhyankar cvalue->data[header->ndata] = (void*)compvalue; 2765f2c45f1SShri Abhyankar header->ndata++; 2775f2c45f1SShri Abhyankar PetscFunctionReturn(0); 2785f2c45f1SShri Abhyankar } 2795f2c45f1SShri Abhyankar 2805f2c45f1SShri Abhyankar #undef __FUNCT__ 2815f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetNumComponents" 2825f2c45f1SShri Abhyankar /*@ 2835f2c45f1SShri Abhyankar DMNetworkGetNumComponents - Get the number of components at a vertex/edge 2845f2c45f1SShri Abhyankar 2855f2c45f1SShri Abhyankar Not Collective 2865f2c45f1SShri Abhyankar 2875f2c45f1SShri Abhyankar Input Parameters: 2885f2c45f1SShri Abhyankar + dm - The DMNetwork object 2895f2c45f1SShri Abhyankar . p - vertex/edge point 2905f2c45f1SShri Abhyankar 2915f2c45f1SShri Abhyankar Output Parameters: 2925f2c45f1SShri Abhyankar . numcomponents - Number of components at the vertex/edge 2935f2c45f1SShri Abhyankar 2945f2c45f1SShri Abhyankar Level: intermediate 2955f2c45f1SShri Abhyankar 2965f2c45f1SShri Abhyankar .seealso: DMNetworkRegisterComponent, DMNetworkAddComponent 2975f2c45f1SShri Abhyankar @*/ 2985f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetNumComponents(DM dm,PetscInt p,PetscInt *numcomponents) 2995f2c45f1SShri Abhyankar { 3005f2c45f1SShri Abhyankar PetscErrorCode ierr; 3015f2c45f1SShri Abhyankar PetscInt offset; 3025f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 3035f2c45f1SShri Abhyankar 3045f2c45f1SShri Abhyankar PetscFunctionBegin; 3055f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 3065f2c45f1SShri Abhyankar *numcomponents = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 3075f2c45f1SShri Abhyankar PetscFunctionReturn(0); 3085f2c45f1SShri Abhyankar } 3095f2c45f1SShri Abhyankar 3105f2c45f1SShri Abhyankar #undef __FUNCT__ 3115f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetComponentTypeOffset" 3125f2c45f1SShri Abhyankar /*@ 3135f2c45f1SShri Abhyankar DMNetworkGetComponentTypeOffset - Gets the type along with the offset for indexing the 3145f2c45f1SShri Abhyankar component value from the component data array 3155f2c45f1SShri Abhyankar 3165f2c45f1SShri Abhyankar Not Collective 3175f2c45f1SShri Abhyankar 3185f2c45f1SShri Abhyankar Input Parameters: 3195f2c45f1SShri Abhyankar + dm - The DMNetwork object 3205f2c45f1SShri Abhyankar . p - vertex/edge point 3215f2c45f1SShri Abhyankar - compnum - component number 3225f2c45f1SShri Abhyankar 3235f2c45f1SShri Abhyankar Output Parameters: 3245f2c45f1SShri Abhyankar + compkey - the key obtained when registering the component 3255f2c45f1SShri Abhyankar - offset - offset into the component data array associated with the vertex/edge point 3265f2c45f1SShri Abhyankar 3275f2c45f1SShri Abhyankar Notes: 3285f2c45f1SShri Abhyankar Typical usage: 3295f2c45f1SShri Abhyankar 3305f2c45f1SShri Abhyankar DMNetworkGetComponentDataArray(dm, &arr); 3315f2c45f1SShri Abhyankar DMNetworkGetVertex/EdgeRange(dm,&Start,&End); 3325f2c45f1SShri Abhyankar Loop over vertices or edges 3335f2c45f1SShri Abhyankar DMNetworkGetNumComponents(dm,v,&numcomps); 3345f2c45f1SShri Abhyankar Loop over numcomps 3355f2c45f1SShri Abhyankar DMNetworkGetComponentTypeOffset(dm,v,compnum,&key,&offset); 3365f2c45f1SShri Abhyankar compdata = (UserCompDataType)(arr+offset); 3375f2c45f1SShri Abhyankar 3385f2c45f1SShri Abhyankar Level: intermediate 3395f2c45f1SShri Abhyankar 3405f2c45f1SShri Abhyankar .seealso: DMNetworkGetNumComponents, DMNetworkGetComponentDataArray, 3415f2c45f1SShri Abhyankar @*/ 3425f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetComponentTypeOffset(DM dm,PetscInt p, PetscInt compnum, PetscInt *compkey, PetscInt *offset) 3435f2c45f1SShri Abhyankar { 3445f2c45f1SShri Abhyankar PetscErrorCode ierr; 3455f2c45f1SShri Abhyankar PetscInt offsetp; 3465f2c45f1SShri Abhyankar DMNetworkComponentHeader header; 3475f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 3485f2c45f1SShri Abhyankar 3495f2c45f1SShri Abhyankar PetscFunctionBegin; 3505f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 3515f2c45f1SShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 3525f2c45f1SShri Abhyankar *compkey = header->key[compnum]; 3535f2c45f1SShri Abhyankar *offset = offsetp+network->dataheadersize+header->offset[compnum]; 3545f2c45f1SShri Abhyankar PetscFunctionReturn(0); 3555f2c45f1SShri Abhyankar } 3565f2c45f1SShri Abhyankar 3575f2c45f1SShri Abhyankar #undef __FUNCT__ 3585f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetVariableOffset" 3595f2c45f1SShri Abhyankar /*@ 3605f2c45f1SShri Abhyankar DMNetworkGetVariableOffset - Get the offset for accessing the variable associated with the given vertex/edge from the local vector. 3615f2c45f1SShri Abhyankar 3625f2c45f1SShri Abhyankar Not Collective 3635f2c45f1SShri Abhyankar 3645f2c45f1SShri Abhyankar Input Parameters: 3655f2c45f1SShri Abhyankar + dm - The DMNetwork object 3665f2c45f1SShri Abhyankar - p - the edge/vertex point 3675f2c45f1SShri Abhyankar 3685f2c45f1SShri Abhyankar Output Parameters: 3695f2c45f1SShri Abhyankar . offset - the offset 3705f2c45f1SShri Abhyankar 3715f2c45f1SShri Abhyankar Level: intermediate 3725f2c45f1SShri Abhyankar 3735f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 3745f2c45f1SShri Abhyankar @*/ 3755f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableOffset(DM dm,PetscInt p,PetscInt *offset) 3765f2c45f1SShri Abhyankar { 3775f2c45f1SShri Abhyankar PetscErrorCode ierr; 3785f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 3795f2c45f1SShri Abhyankar 3805f2c45f1SShri Abhyankar PetscFunctionBegin; 3815f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DofSection,p,offset);CHKERRQ(ierr); 3825f2c45f1SShri Abhyankar PetscFunctionReturn(0); 3835f2c45f1SShri Abhyankar } 3845f2c45f1SShri Abhyankar 3855f2c45f1SShri Abhyankar #undef __FUNCT__ 3865f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetVariableGlobalOffset" 3875f2c45f1SShri Abhyankar /*@ 3885f2c45f1SShri Abhyankar DMNetworkGetVariableGlobalOffset - Get the global offset for the variable associated with the given vertex/edge from the global vector. 3895f2c45f1SShri Abhyankar 3905f2c45f1SShri Abhyankar Not Collective 3915f2c45f1SShri Abhyankar 3925f2c45f1SShri Abhyankar Input Parameters: 3935f2c45f1SShri Abhyankar + dm - The DMNetwork object 3945f2c45f1SShri Abhyankar - p - the edge/vertex point 3955f2c45f1SShri Abhyankar 3965f2c45f1SShri Abhyankar Output Parameters: 3975f2c45f1SShri Abhyankar . offsetg - the offset 3985f2c45f1SShri Abhyankar 3995f2c45f1SShri Abhyankar Level: intermediate 4005f2c45f1SShri Abhyankar 4015f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableOffset, DMGetLocalVector 4025f2c45f1SShri Abhyankar @*/ 4035f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableGlobalOffset(DM dm,PetscInt p,PetscInt *offsetg) 4045f2c45f1SShri Abhyankar { 4055f2c45f1SShri Abhyankar PetscErrorCode ierr; 4065f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 4075f2c45f1SShri Abhyankar 4085f2c45f1SShri Abhyankar PetscFunctionBegin; 4095f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->GlobalDofSection,p,offsetg);CHKERRQ(ierr); 4105f2c45f1SShri Abhyankar PetscFunctionReturn(0); 4115f2c45f1SShri Abhyankar } 4125f2c45f1SShri Abhyankar 4135f2c45f1SShri Abhyankar #undef __FUNCT__ 4145f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkAddNumVariables" 4155f2c45f1SShri Abhyankar /*@ 4165f2c45f1SShri Abhyankar DMNetworkAddNumVariables - Add number of variables associated with a given point. 4175f2c45f1SShri Abhyankar 4185f2c45f1SShri Abhyankar Not Collective 4195f2c45f1SShri Abhyankar 4205f2c45f1SShri Abhyankar Input Parameters: 4215f2c45f1SShri Abhyankar + dm - The DMNetworkObject 4225f2c45f1SShri Abhyankar . p - the vertex/edge point 4235f2c45f1SShri Abhyankar - nvar - number of additional variables 4245f2c45f1SShri Abhyankar 4255f2c45f1SShri Abhyankar Level: intermediate 4265f2c45f1SShri Abhyankar 4275f2c45f1SShri Abhyankar .seealso: DMNetworkSetNumVariables 4285f2c45f1SShri Abhyankar @*/ 4295f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddNumVariables(DM dm,PetscInt p,PetscInt nvar) 4305f2c45f1SShri Abhyankar { 4315f2c45f1SShri Abhyankar PetscErrorCode ierr; 4325f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 4335f2c45f1SShri Abhyankar 4345f2c45f1SShri Abhyankar PetscFunctionBegin; 4355f2c45f1SShri Abhyankar ierr = PetscSectionAddDof(network->DofSection,p,nvar);CHKERRQ(ierr); 4365f2c45f1SShri Abhyankar PetscFunctionReturn(0); 4375f2c45f1SShri Abhyankar } 4385f2c45f1SShri Abhyankar 4395f2c45f1SShri Abhyankar #undef __FUNCT__ 44027f51fceSHong Zhang #define __FUNCT__ "DMNetworkGetNumVariables" 44127f51fceSHong Zhang /*@ 44227f51fceSHong Zhang DMNetworkGetNumVariables - Gets number of variables for a vertex/edge point. 44327f51fceSHong Zhang 44427f51fceSHong Zhang Not Collective 44527f51fceSHong Zhang 44627f51fceSHong Zhang Input Parameters: 44727f51fceSHong Zhang + dm - The DMNetworkObject 44827f51fceSHong Zhang - p - the vertex/edge point 44927f51fceSHong Zhang 45027f51fceSHong Zhang Output Parameters: 45127f51fceSHong Zhang . nvar - number of variables 45227f51fceSHong Zhang 45327f51fceSHong Zhang Level: intermediate 45427f51fceSHong Zhang 45527f51fceSHong Zhang .seealso: DMNetworkAddNumVariables, DMNetworkSddNumVariables 45627f51fceSHong Zhang @*/ 45727f51fceSHong Zhang PetscErrorCode DMNetworkGetNumVariables(DM dm,PetscInt p,PetscInt *nvar) 45827f51fceSHong Zhang { 45927f51fceSHong Zhang PetscErrorCode ierr; 46027f51fceSHong Zhang DM_Network *network = (DM_Network*)dm->data; 46127f51fceSHong Zhang 46227f51fceSHong Zhang PetscFunctionBegin; 46327f51fceSHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 46427f51fceSHong Zhang PetscFunctionReturn(0); 46527f51fceSHong Zhang } 46627f51fceSHong Zhang 46727f51fceSHong Zhang #undef __FUNCT__ 468662b5b01SHong Zhang #define __FUNCT__ "DMNetworkSetNumVariables" 4695f2c45f1SShri Abhyankar /*@ 4705f2c45f1SShri Abhyankar DMNetworkSetNumVariables - Sets number of variables for a vertex/edge point. 4715f2c45f1SShri Abhyankar 4725f2c45f1SShri Abhyankar Not Collective 4735f2c45f1SShri Abhyankar 4745f2c45f1SShri Abhyankar Input Parameters: 4755f2c45f1SShri Abhyankar + dm - The DMNetworkObject 4765f2c45f1SShri Abhyankar . p - the vertex/edge point 4775f2c45f1SShri Abhyankar - nvar - number of variables 4785f2c45f1SShri Abhyankar 4795f2c45f1SShri Abhyankar Level: intermediate 4805f2c45f1SShri Abhyankar 4815f2c45f1SShri Abhyankar .seealso: DMNetworkAddNumVariables 4825f2c45f1SShri Abhyankar @*/ 4835f2c45f1SShri Abhyankar PetscErrorCode DMNetworkSetNumVariables(DM dm,PetscInt p,PetscInt nvar) 4845f2c45f1SShri Abhyankar { 4855f2c45f1SShri Abhyankar PetscErrorCode ierr; 4865f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 4875f2c45f1SShri Abhyankar 4885f2c45f1SShri Abhyankar PetscFunctionBegin; 4895f2c45f1SShri Abhyankar ierr = PetscSectionSetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 4905f2c45f1SShri Abhyankar PetscFunctionReturn(0); 4915f2c45f1SShri Abhyankar } 4925f2c45f1SShri Abhyankar 4935f2c45f1SShri Abhyankar /* Sets up the array that holds the data for all components and its associated section. This 4945f2c45f1SShri Abhyankar function is called during DMSetUp() */ 4955f2c45f1SShri Abhyankar #undef __FUNCT__ 4965f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkComponentSetUp" 4975f2c45f1SShri Abhyankar PetscErrorCode DMNetworkComponentSetUp(DM dm) 4985f2c45f1SShri Abhyankar { 4995f2c45f1SShri Abhyankar PetscErrorCode ierr; 5005f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 5015f2c45f1SShri Abhyankar PetscInt arr_size; 5025f2c45f1SShri Abhyankar PetscInt p,offset,offsetp; 5035f2c45f1SShri Abhyankar DMNetworkComponentHeader header; 5045f2c45f1SShri Abhyankar DMNetworkComponentValue cvalue; 5055f2c45f1SShri Abhyankar DMNetworkComponentGenericDataType *componentdataarray; 5065f2c45f1SShri Abhyankar PetscInt ncomp, i; 5075f2c45f1SShri Abhyankar 5085f2c45f1SShri Abhyankar PetscFunctionBegin; 5095f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr); 5105f2c45f1SShri Abhyankar ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr); 51175b160a0SShri Abhyankar ierr = PetscMalloc1(arr_size,&network->componentdataarray);CHKERRQ(ierr); 5125f2c45f1SShri Abhyankar componentdataarray = network->componentdataarray; 5135f2c45f1SShri Abhyankar for (p = network->pStart; p < network->pEnd; p++) { 5145f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 5155f2c45f1SShri Abhyankar /* Copy header */ 5165f2c45f1SShri Abhyankar header = &network->header[p]; 517302440fdSBarry Smith ierr = PetscMemcpy(componentdataarray+offsetp,header,network->dataheadersize*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 5185f2c45f1SShri Abhyankar /* Copy data */ 5195f2c45f1SShri Abhyankar cvalue = &network->cvalue[p]; 5205f2c45f1SShri Abhyankar ncomp = header->ndata; 5215f2c45f1SShri Abhyankar for (i = 0; i < ncomp; i++) { 5225f2c45f1SShri Abhyankar offset = offsetp + network->dataheadersize + header->offset[i]; 523302440fdSBarry Smith ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 5245f2c45f1SShri Abhyankar } 5255f2c45f1SShri Abhyankar } 5265f2c45f1SShri Abhyankar PetscFunctionReturn(0); 5275f2c45f1SShri Abhyankar } 5285f2c45f1SShri Abhyankar 5295f2c45f1SShri Abhyankar /* Sets up the section for dofs. This routine is called during DMSetUp() */ 5305f2c45f1SShri Abhyankar #undef __FUNCT__ 5315f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkVariablesSetUp" 5325f2c45f1SShri Abhyankar PetscErrorCode DMNetworkVariablesSetUp(DM dm) 5335f2c45f1SShri Abhyankar { 5345f2c45f1SShri Abhyankar PetscErrorCode ierr; 5355f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 5365f2c45f1SShri Abhyankar 5375f2c45f1SShri Abhyankar PetscFunctionBegin; 5385f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr); 5395f2c45f1SShri Abhyankar PetscFunctionReturn(0); 5405f2c45f1SShri Abhyankar } 5415f2c45f1SShri Abhyankar 5425f2c45f1SShri Abhyankar #undef __FUNCT__ 5435f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetComponentDataArray" 5445f2c45f1SShri Abhyankar /*@C 5455f2c45f1SShri Abhyankar DMNetworkGetComponentDataArray - Returns the component data array 5465f2c45f1SShri Abhyankar 5475f2c45f1SShri Abhyankar Not Collective 5485f2c45f1SShri Abhyankar 5495f2c45f1SShri Abhyankar Input Parameters: 5505f2c45f1SShri Abhyankar . dm - The DMNetwork Object 5515f2c45f1SShri Abhyankar 5525f2c45f1SShri Abhyankar Output Parameters: 5535f2c45f1SShri Abhyankar . componentdataarray - array that holds data for all components 5545f2c45f1SShri Abhyankar 5555f2c45f1SShri Abhyankar Level: intermediate 5565f2c45f1SShri Abhyankar 5575f2c45f1SShri Abhyankar .seealso: DMNetworkGetComponentTypeOffset, DMNetworkGetNumComponents 5585f2c45f1SShri Abhyankar @*/ 5595f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetComponentDataArray(DM dm,DMNetworkComponentGenericDataType **componentdataarray) 5605f2c45f1SShri Abhyankar { 5615f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 5625f2c45f1SShri Abhyankar 5635f2c45f1SShri Abhyankar PetscFunctionBegin; 5645f2c45f1SShri Abhyankar *componentdataarray = network->componentdataarray; 5655f2c45f1SShri Abhyankar PetscFunctionReturn(0); 5665f2c45f1SShri Abhyankar } 5675f2c45f1SShri Abhyankar 5685f2c45f1SShri Abhyankar #undef __FUNCT__ 5695f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkDistribute" 5705f2c45f1SShri Abhyankar /*@ 5715f2c45f1SShri Abhyankar DMNetworkDistribute - Distributes the network and moves associated component data. 5725f2c45f1SShri Abhyankar 5735f2c45f1SShri Abhyankar Collective 5745f2c45f1SShri Abhyankar 5755f2c45f1SShri Abhyankar Input Parameter: 5765f2c45f1SShri Abhyankar + oldDM - the original DMNetwork object 5775f2c45f1SShri Abhyankar - overlap - The overlap of partitions, 0 is the default 5785f2c45f1SShri Abhyankar 5795f2c45f1SShri Abhyankar Output Parameter: 5805f2c45f1SShri Abhyankar . distDM - the distributed DMNetwork object 5815f2c45f1SShri Abhyankar 5825f2c45f1SShri Abhyankar Notes: 5835f2c45f1SShri Abhyankar This routine should be called only when using multiple processors. 5845f2c45f1SShri Abhyankar 5858b171c8eSHong Zhang Distributes the network with <overlap>-overlapping partitioning of the edges. 5865f2c45f1SShri Abhyankar 5875f2c45f1SShri Abhyankar Level: intermediate 5885f2c45f1SShri Abhyankar 5895f2c45f1SShri Abhyankar .seealso: DMNetworkCreate 5905f2c45f1SShri Abhyankar @*/ 59180cf41d5SMatthew G. Knepley PetscErrorCode DMNetworkDistribute(DM oldDM, PetscInt overlap,DM *distDM) 5925f2c45f1SShri Abhyankar { 5935f2c45f1SShri Abhyankar PetscErrorCode ierr; 5945f2c45f1SShri Abhyankar DM_Network *oldDMnetwork = (DM_Network*)oldDM->data; 5955f2c45f1SShri Abhyankar PetscSF pointsf; 5965f2c45f1SShri Abhyankar DM newDM; 5975f2c45f1SShri Abhyankar DM_Network *newDMnetwork; 5985f2c45f1SShri Abhyankar 5995f2c45f1SShri Abhyankar PetscFunctionBegin; 6005f2c45f1SShri Abhyankar ierr = DMNetworkCreate(PetscObjectComm((PetscObject)oldDM),&newDM);CHKERRQ(ierr); 6015f2c45f1SShri Abhyankar newDMnetwork = (DM_Network*)newDM->data; 6025f2c45f1SShri Abhyankar newDMnetwork->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 6035f2c45f1SShri Abhyankar /* Distribute plex dm and dof section */ 60480cf41d5SMatthew G. Knepley ierr = DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr); 6055f2c45f1SShri Abhyankar /* Distribute dof section */ 6065f2c45f1SShri Abhyankar ierr = PetscSectionCreate(PetscObjectComm((PetscObject)oldDM),&newDMnetwork->DofSection);CHKERRQ(ierr); 6075f2c45f1SShri Abhyankar ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr); 6085f2c45f1SShri Abhyankar ierr = PetscSectionCreate(PetscObjectComm((PetscObject)oldDM),&newDMnetwork->DataSection);CHKERRQ(ierr); 6095f2c45f1SShri Abhyankar /* Distribute data and associated section */ 61031da1fc8SHong Zhang ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPIU_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr); 6115f2c45f1SShri Abhyankar /* Destroy point SF */ 6125f2c45f1SShri Abhyankar ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr); 6135f2c45f1SShri Abhyankar 6145f2c45f1SShri Abhyankar ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr); 6155f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr); 6165f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr); 6175f2c45f1SShri Abhyankar newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart; 6185f2c45f1SShri Abhyankar newDMnetwork->nNodes = newDMnetwork->vEnd - newDMnetwork->vStart; 6195f2c45f1SShri Abhyankar newDMnetwork->NNodes = oldDMnetwork->NNodes; 6205f2c45f1SShri Abhyankar newDMnetwork->NEdges = oldDMnetwork->NEdges; 6215f2c45f1SShri Abhyankar /* Set Dof section as the default section for dm */ 6225f2c45f1SShri Abhyankar ierr = DMSetDefaultSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr); 6235f2c45f1SShri Abhyankar ierr = DMGetDefaultGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr); 6245f2c45f1SShri Abhyankar 6255f2c45f1SShri Abhyankar *distDM = newDM; 6265f2c45f1SShri Abhyankar PetscFunctionReturn(0); 6275f2c45f1SShri Abhyankar } 6285f2c45f1SShri Abhyankar 6295f2c45f1SShri Abhyankar #undef __FUNCT__ 6305f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetSupportingEdges" 6315f2c45f1SShri Abhyankar /*@C 6325f2c45f1SShri Abhyankar DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point 6335f2c45f1SShri Abhyankar 6345f2c45f1SShri Abhyankar Not Collective 6355f2c45f1SShri Abhyankar 6365f2c45f1SShri Abhyankar Input Parameters: 6375f2c45f1SShri Abhyankar + dm - The DMNetwork object 6385f2c45f1SShri Abhyankar - p - the vertex point 6395f2c45f1SShri Abhyankar 6405f2c45f1SShri Abhyankar Output Paramters: 6415f2c45f1SShri Abhyankar + nedges - number of edges connected to this vertex point 6425f2c45f1SShri Abhyankar - edges - List of edge points 6435f2c45f1SShri Abhyankar 6445f2c45f1SShri Abhyankar Level: intermediate 6455f2c45f1SShri Abhyankar 6465f2c45f1SShri Abhyankar Fortran Notes: 6475f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 6485f2c45f1SShri Abhyankar include petsc.h90 in your code. 6495f2c45f1SShri Abhyankar 6505f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkGetConnectedNodes 6515f2c45f1SShri Abhyankar @*/ 6525f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[]) 6535f2c45f1SShri Abhyankar { 6545f2c45f1SShri Abhyankar PetscErrorCode ierr; 6555f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 6565f2c45f1SShri Abhyankar 6575f2c45f1SShri Abhyankar PetscFunctionBegin; 6585f2c45f1SShri Abhyankar ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr); 6595f2c45f1SShri Abhyankar ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr); 6605f2c45f1SShri Abhyankar PetscFunctionReturn(0); 6615f2c45f1SShri Abhyankar } 6625f2c45f1SShri Abhyankar 6635f2c45f1SShri Abhyankar #undef __FUNCT__ 6645f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetConnectedNodes" 6655f2c45f1SShri Abhyankar /*@C 666596e729fSHong Zhang DMNetworkGetConnectedNodes - Return the connected vertices for this edge point 6675f2c45f1SShri Abhyankar 6685f2c45f1SShri Abhyankar Not Collective 6695f2c45f1SShri Abhyankar 6705f2c45f1SShri Abhyankar Input Parameters: 6715f2c45f1SShri Abhyankar + dm - The DMNetwork object 6725f2c45f1SShri Abhyankar - p - the edge point 6735f2c45f1SShri Abhyankar 6745f2c45f1SShri Abhyankar Output Paramters: 6755f2c45f1SShri Abhyankar . vertices - vertices connected to this edge 6765f2c45f1SShri Abhyankar 6775f2c45f1SShri Abhyankar Level: intermediate 6785f2c45f1SShri Abhyankar 6795f2c45f1SShri Abhyankar Fortran Notes: 6805f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 6815f2c45f1SShri Abhyankar include petsc.h90 in your code. 6825f2c45f1SShri Abhyankar 6835f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkGetSupportingEdges 6845f2c45f1SShri Abhyankar @*/ 6855f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetConnectedNodes(DM dm,PetscInt edge,const PetscInt *vertices[]) 6865f2c45f1SShri Abhyankar { 6875f2c45f1SShri Abhyankar PetscErrorCode ierr; 6885f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 6895f2c45f1SShri Abhyankar 6905f2c45f1SShri Abhyankar PetscFunctionBegin; 6915f2c45f1SShri Abhyankar ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr); 6925f2c45f1SShri Abhyankar PetscFunctionReturn(0); 6935f2c45f1SShri Abhyankar } 6945f2c45f1SShri Abhyankar 6955f2c45f1SShri Abhyankar #undef __FUNCT__ 6965f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkIsGhostVertex" 6975f2c45f1SShri Abhyankar /*@ 6985f2c45f1SShri Abhyankar DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex 6995f2c45f1SShri Abhyankar 7005f2c45f1SShri Abhyankar Not Collective 7015f2c45f1SShri Abhyankar 7025f2c45f1SShri Abhyankar Input Parameters: 7035f2c45f1SShri Abhyankar + dm - The DMNetwork object 7045f2c45f1SShri Abhyankar . p - the vertex point 7055f2c45f1SShri Abhyankar 7065f2c45f1SShri Abhyankar Output Parameter: 7075f2c45f1SShri Abhyankar . isghost - TRUE if the vertex is a ghost point 7085f2c45f1SShri Abhyankar 7095f2c45f1SShri Abhyankar Level: intermediate 7105f2c45f1SShri Abhyankar 7115f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkGetConnectedNodes, DMNetworkGetVertexRange 7125f2c45f1SShri Abhyankar @*/ 7135f2c45f1SShri Abhyankar PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost) 7145f2c45f1SShri Abhyankar { 7155f2c45f1SShri Abhyankar PetscErrorCode ierr; 7165f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 7175f2c45f1SShri Abhyankar PetscInt offsetg; 7185f2c45f1SShri Abhyankar PetscSection sectiong; 7195f2c45f1SShri Abhyankar 7205f2c45f1SShri Abhyankar PetscFunctionBegin; 7215f2c45f1SShri Abhyankar *isghost = PETSC_FALSE; 7225f2c45f1SShri Abhyankar ierr = DMGetDefaultGlobalSection(network->plex,§iong);CHKERRQ(ierr); 7235f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr); 7245f2c45f1SShri Abhyankar if (offsetg < 0) *isghost = PETSC_TRUE; 7255f2c45f1SShri Abhyankar PetscFunctionReturn(0); 7265f2c45f1SShri Abhyankar } 7275f2c45f1SShri Abhyankar 7285f2c45f1SShri Abhyankar #undef __FUNCT__ 7295f2c45f1SShri Abhyankar #define __FUNCT__ "DMSetUp_Network" 7305f2c45f1SShri Abhyankar PetscErrorCode DMSetUp_Network(DM dm) 7315f2c45f1SShri Abhyankar { 7325f2c45f1SShri Abhyankar PetscErrorCode ierr; 7335f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 7345f2c45f1SShri Abhyankar 7355f2c45f1SShri Abhyankar PetscFunctionBegin; 7365f2c45f1SShri Abhyankar ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr); 7375f2c45f1SShri Abhyankar ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr); 7385f2c45f1SShri Abhyankar 7395f2c45f1SShri Abhyankar ierr = DMSetDefaultSection(network->plex,network->DofSection);CHKERRQ(ierr); 7405f2c45f1SShri Abhyankar ierr = DMGetDefaultGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr); 7415f2c45f1SShri Abhyankar PetscFunctionReturn(0); 7425f2c45f1SShri Abhyankar } 7435f2c45f1SShri Abhyankar 7445f2c45f1SShri Abhyankar #undef __FUNCT__ 74517df6e9eSHong Zhang #define __FUNCT__ "DMNetworkHasJacobian" 7461ad426b7SHong Zhang /*@ 74717df6e9eSHong Zhang DMNetworkHasJacobian - Sets global flag for using user's sub Jacobian matrices 7481ad426b7SHong Zhang -- replaced by DMNetworkSetOption(network,userjacobian,PETSC_TURE)? 7491ad426b7SHong Zhang 7501ad426b7SHong Zhang Collective 7511ad426b7SHong Zhang 7521ad426b7SHong Zhang Input Parameters: 75383b2e829SHong Zhang + dm - The DMNetwork object 75483b2e829SHong Zhang . eflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for edges 75583b2e829SHong Zhang - vflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for vertices 7561ad426b7SHong Zhang 7571ad426b7SHong Zhang Level: intermediate 7581ad426b7SHong Zhang 7591ad426b7SHong Zhang @*/ 76083b2e829SHong Zhang PetscErrorCode DMNetworkHasJacobian(DM dm,PetscBool eflg,PetscBool vflg) 7611ad426b7SHong Zhang { 7621ad426b7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 7631ad426b7SHong Zhang 7641ad426b7SHong Zhang PetscFunctionBegin; 76583b2e829SHong Zhang network->userEdgeJacobian = eflg; 76683b2e829SHong Zhang network->userVertexJacobian = vflg; 7671ad426b7SHong Zhang PetscFunctionReturn(0); 7681ad426b7SHong Zhang } 7691ad426b7SHong Zhang 7701ad426b7SHong Zhang #undef __FUNCT__ 77183b2e829SHong Zhang #define __FUNCT__ "DMNetworkEdgeSetMatrix" 7721ad426b7SHong Zhang /*@ 77383b2e829SHong Zhang DMNetworkEdgeSetMatrix - Sets user-provided Jacobian matrices for this edge to the network 77483b2e829SHong Zhang 77583b2e829SHong Zhang Not Collective 77683b2e829SHong Zhang 77783b2e829SHong Zhang Input Parameters: 77883b2e829SHong Zhang + dm - The DMNetwork object 77983b2e829SHong Zhang . p - the edge point 7803e97b6e8SHong Zhang - J - array (size = 3) of Jacobian submatrices for this edge point: 7813e97b6e8SHong Zhang J[0]: this edge 7823e97b6e8SHong Zhang J[1] and J[2]: connected vertices, obtained by calling DMNetworkGetConnectedNodes() 78383b2e829SHong Zhang 78483b2e829SHong Zhang Level: intermediate 78583b2e829SHong Zhang 78683b2e829SHong Zhang .seealso: DMNetworkVertexSetMatrix 78783b2e829SHong Zhang @*/ 78883b2e829SHong Zhang PetscErrorCode DMNetworkEdgeSetMatrix(DM dm,PetscInt p,Mat J[]) 78983b2e829SHong Zhang { 79083b2e829SHong Zhang PetscErrorCode ierr; 79183b2e829SHong Zhang DM_Network *network=(DM_Network*)dm->data; 79283b2e829SHong Zhang 79383b2e829SHong Zhang PetscFunctionBegin; 794883e35e8SHong Zhang if (!network->userEdgeJacobian) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkEdgeSetMatrix"); 79583b2e829SHong Zhang if (!network->Je) { 796883e35e8SHong Zhang ierr = PetscCalloc1(3*network->nEdges,&network->Je);CHKERRQ(ierr); 79783b2e829SHong Zhang } 798883e35e8SHong Zhang network->Je[3*p] = J[0]; 799883e35e8SHong Zhang network->Je[3*p+1] = J[1]; 800883e35e8SHong Zhang network->Je[3*p+2] = J[2]; 80183b2e829SHong Zhang PetscFunctionReturn(0); 80283b2e829SHong Zhang } 80383b2e829SHong Zhang 80483b2e829SHong Zhang #undef __FUNCT__ 805883e35e8SHong Zhang #define __FUNCT__ "DMNetworkVertexSetMatrix" 80683b2e829SHong Zhang /*@ 80776ddfea5SHong Zhang DMNetworkVertexSetMatrix - Sets user-provided Jacobian matrix for this vertex to the network 8081ad426b7SHong Zhang 8091ad426b7SHong Zhang Not Collective 8101ad426b7SHong Zhang 8111ad426b7SHong Zhang Input Parameters: 8121ad426b7SHong Zhang + dm - The DMNetwork object 8131ad426b7SHong Zhang . p - the vertex point 8143e97b6e8SHong Zhang - J - array of Jacobian (size = 2*(num of supporting edges) + 1) submatrices for this vertex point: 8153e97b6e8SHong Zhang J[0]: this vertex 8163e97b6e8SHong Zhang J[1+2*i]: i-th supporting edge 8173e97b6e8SHong Zhang J[1+2*i+1]: i-th connected vertex 8181ad426b7SHong Zhang 8191ad426b7SHong Zhang Level: intermediate 8201ad426b7SHong Zhang 82183b2e829SHong Zhang .seealso: DMNetworkEdgeSetMatrix 8221ad426b7SHong Zhang @*/ 823883e35e8SHong Zhang PetscErrorCode DMNetworkVertexSetMatrix(DM dm,PetscInt p,Mat J[]) 8245f2c45f1SShri Abhyankar { 8255f2c45f1SShri Abhyankar PetscErrorCode ierr; 8265f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 8273e97b6e8SHong Zhang PetscInt i,v,vStart,vEnd,*vptr,nedges,nedges_total; 828883e35e8SHong Zhang const PetscInt *edges; 8295f2c45f1SShri Abhyankar 8305f2c45f1SShri Abhyankar PetscFunctionBegin; 831883e35e8SHong Zhang if (!network->userVertexJacobian) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkVertexSetMatrix"); 832883e35e8SHong Zhang 833883e35e8SHong Zhang ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 83483b2e829SHong Zhang if (!network->Jv) { 835883e35e8SHong Zhang /* count nvertex_total */ 8363e97b6e8SHong Zhang nedges_total = 0; 837883e35e8SHong Zhang ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 838883e35e8SHong Zhang ierr = PetscMalloc1(vEnd-vStart+1,&vptr);CHKERRQ(ierr); 839883e35e8SHong Zhang i = 1; 840883e35e8SHong Zhang vptr[0] = 0; 841883e35e8SHong Zhang for (v=vStart; v<vEnd; v++) { 842883e35e8SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 843883e35e8SHong Zhang nedges_total += nedges; 844883e35e8SHong Zhang vptr[i] = vptr[i-1] + 2*nedges + 1; i++; 8451ad426b7SHong Zhang } 8463e97b6e8SHong Zhang 847883e35e8SHong Zhang ierr = PetscCalloc1(2*nedges_total+network->nNodes,&network->Jv);CHKERRQ(ierr); 848883e35e8SHong Zhang network->Jvptr = vptr; 849883e35e8SHong Zhang } 850883e35e8SHong Zhang 851883e35e8SHong Zhang vptr = network->Jvptr; 8523e97b6e8SHong Zhang network->Jv[vptr[p-vStart]] = J[0]; /* Set Jacobian for this vertex */ 8533e97b6e8SHong Zhang 8543e97b6e8SHong Zhang /* Set Jacobian for each supporting edge and connected vertex */ 855883e35e8SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,p,&nedges,&edges);CHKERRQ(ierr); 856883e35e8SHong Zhang for (i=1; i<=2*nedges; i++) network->Jv[vptr[p-vStart]+i] = J[i]; 857883e35e8SHong Zhang PetscFunctionReturn(0); 858883e35e8SHong Zhang } 859883e35e8SHong Zhang 860883e35e8SHong Zhang #undef __FUNCT__ 861883e35e8SHong Zhang #define __FUNCT__ "MatSetDenseblock_private" 8623e97b6e8SHong Zhang PetscErrorCode MatSetDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 863883e35e8SHong Zhang { 864883e35e8SHong Zhang PetscErrorCode ierr; 865883e35e8SHong Zhang PetscInt j,*cols; 866883e35e8SHong Zhang PetscScalar *zeros; 867883e35e8SHong Zhang 868883e35e8SHong Zhang PetscFunctionBegin; 869883e35e8SHong Zhang ierr = PetscCalloc2(ncols,&cols,nrows*ncols,&zeros);CHKERRQ(ierr); 870883e35e8SHong Zhang for (j=0; j<ncols; j++) cols[j] = j+ cstart; 871883e35e8SHong Zhang ierr = MatSetValues(*J,nrows,rows,ncols,cols,zeros,INSERT_VALUES);CHKERRQ(ierr); 872883e35e8SHong Zhang ierr = PetscFree2(cols,zeros);CHKERRQ(ierr); 8731ad426b7SHong Zhang PetscFunctionReturn(0); 8741ad426b7SHong Zhang } 875*a4e85ca8SHong Zhang 8763e97b6e8SHong Zhang #undef __FUNCT__ 8773e97b6e8SHong Zhang #define __FUNCT__ "MatSetUserblock_private" 8783e97b6e8SHong Zhang PetscErrorCode MatSetUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 8793e97b6e8SHong Zhang { 8803e97b6e8SHong Zhang PetscErrorCode ierr; 8813e97b6e8SHong Zhang PetscInt j,M,N,row,col,ncols_u; 8823e97b6e8SHong Zhang const PetscInt *cols; 8833e97b6e8SHong Zhang PetscScalar zero=0.0; 8843e97b6e8SHong Zhang 8853e97b6e8SHong Zhang PetscFunctionBegin; 8863e97b6e8SHong Zhang ierr = MatGetSize(Ju,&M,&N);CHKERRQ(ierr); 8873e97b6e8SHong Zhang if (nrows != M || ncols != N) SETERRQ4(PetscObjectComm((PetscObject)Ju),PETSC_ERR_USER,"%D by %D must equal %D by %D",nrows,ncols,M,N); 8883e97b6e8SHong Zhang 8893e97b6e8SHong Zhang for (row=0; row<nrows; row++) { 8903e97b6e8SHong Zhang ierr = MatGetRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 8913e97b6e8SHong Zhang for (j=0; j<ncols_u; j++) { 8923e97b6e8SHong Zhang col = cols[j] + cstart; 8933e97b6e8SHong Zhang ierr = MatSetValues(*J,1,&rows[row],1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr); 8943e97b6e8SHong Zhang } 8953e97b6e8SHong Zhang ierr = MatRestoreRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 8963e97b6e8SHong Zhang } 8973e97b6e8SHong Zhang PetscFunctionReturn(0); 8983e97b6e8SHong Zhang } 8991ad426b7SHong Zhang 9001ad426b7SHong Zhang #undef __FUNCT__ 901*a4e85ca8SHong Zhang #define __FUNCT__ "MatSetblock_private" 902*a4e85ca8SHong Zhang PetscErrorCode MatSetblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 903*a4e85ca8SHong Zhang { 904*a4e85ca8SHong Zhang PetscErrorCode ierr; 905*a4e85ca8SHong Zhang PetscFunctionBegin; 906*a4e85ca8SHong Zhang if (Ju) { 907*a4e85ca8SHong Zhang ierr = MatSetUserblock_private(Ju,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 908*a4e85ca8SHong Zhang } else { 909*a4e85ca8SHong Zhang ierr = MatSetDenseblock_private(nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 910*a4e85ca8SHong Zhang } 911*a4e85ca8SHong Zhang PetscFunctionReturn(0); 912*a4e85ca8SHong Zhang } 913*a4e85ca8SHong Zhang 914*a4e85ca8SHong Zhang #undef __FUNCT__ 9151ad426b7SHong Zhang #define __FUNCT__ "DMCreateMatrix_Network" 9161ad426b7SHong Zhang PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J) 9171ad426b7SHong Zhang { 9181ad426b7SHong Zhang PetscErrorCode ierr; 9191ad426b7SHong Zhang DM_Network *network = (DM_Network*) dm->data; 920*a4e85ca8SHong Zhang PetscInt eStart,eEnd,vStart,vEnd,rstart,nrows,*rows,localSize; 9213e97b6e8SHong Zhang PetscInt cstart,ncols,j,e,v,*dnz,*onz,*dnzu,*onzu; 9221ad426b7SHong Zhang PetscBool ghost; 923*a4e85ca8SHong Zhang Mat Juser; 924bfbc38dcSHong Zhang PetscSection sectionGlobal; 925*a4e85ca8SHong Zhang PetscInt nedges,*vptr,vc; 926*a4e85ca8SHong Zhang const PetscInt *edges,*cone; 9271ad426b7SHong Zhang 9281ad426b7SHong Zhang PetscFunctionBegin; 929*a4e85ca8SHong Zhang if (!network->userEdgeJacobian && !network->userVertexJacobian) { 930*a4e85ca8SHong Zhang /* user does not provide Jacobian blocks */ 931bfbc38dcSHong Zhang ierr = DMCreateMatrix(network->plex,J);CHKERRQ(ierr); 932bfbc38dcSHong Zhang ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 9331ad426b7SHong Zhang PetscFunctionReturn(0); 9341ad426b7SHong Zhang } 9351ad426b7SHong Zhang 936bfbc38dcSHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)dm),J);CHKERRQ(ierr); 9372a945128SHong Zhang ierr = DMGetDefaultGlobalSection(network->plex,§ionGlobal);CHKERRQ(ierr); 938bfbc38dcSHong Zhang ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal,&localSize);CHKERRQ(ierr); 939bfbc38dcSHong Zhang ierr = MatSetSizes(*J,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 9402a945128SHong Zhang 9412a945128SHong Zhang ierr = MatSetType(*J,MATAIJ);CHKERRQ(ierr); 9422a945128SHong Zhang ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 9431ad426b7SHong Zhang 944*a4e85ca8SHong Zhang /* Preallocation - submatrix for an element (edge/vertex) is allocated as a dense block, 945*a4e85ca8SHong Zhang see DMCreateMatrix_Plex() */ 946bfbc38dcSHong Zhang ierr = PetscCalloc4(localSize,&dnz,localSize,&onz,localSize,&dnzu,localSize,&onzu);CHKERRQ(ierr); 947bfbc38dcSHong Zhang ierr = DMPlexPreallocateOperator(network->plex,1,dnz,onz,dnzu,onzu,*J,PETSC_FALSE);CHKERRQ(ierr); 948bfbc38dcSHong Zhang ierr = PetscFree4(dnz,onz,dnzu,onzu);CHKERRQ(ierr); 949bfbc38dcSHong Zhang 950bfbc38dcSHong Zhang /* Set matrix entries for edges */ 95183b2e829SHong Zhang /*------------------------------*/ 952bfbc38dcSHong Zhang ierr = DMNetworkGetEdgeRange(dm,&eStart,&eEnd);CHKERRQ(ierr); 9531ad426b7SHong Zhang for (e=eStart; e<eEnd; e++) { 954bfbc38dcSHong Zhang /* Get row indices */ 9551ad426b7SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr); 95617df6e9eSHong Zhang ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr); 957*a4e85ca8SHong Zhang ierr = PetscMalloc1(nrows,&rows);CHKERRQ(ierr); 95817df6e9eSHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 9591ad426b7SHong Zhang 960bfbc38dcSHong Zhang /* Set matrix entries for conntected vertices */ 96117df6e9eSHong Zhang ierr = DMNetworkGetConnectedNodes(dm,e,&cone);CHKERRQ(ierr); 962bfbc38dcSHong Zhang for (v=0; v<2; v++) { 963bfbc38dcSHong Zhang ierr = DMNetworkIsGhostVertex(dm,cone[v],&ghost);CHKERRQ(ierr); 964bfbc38dcSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,cone[v],&cstart);CHKERRQ(ierr); 965bfbc38dcSHong Zhang if (ghost) cstart = -(cstart + 1); /* Convert to actual global offset for ghost nodes */ 966883e35e8SHong Zhang ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr); 9673e97b6e8SHong Zhang 968*a4e85ca8SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 969*a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 970bfbc38dcSHong Zhang } 97117df6e9eSHong Zhang 972bfbc38dcSHong Zhang /* Set matrix entries for edge self */ 9733e97b6e8SHong Zhang cstart = rstart; 974*a4e85ca8SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 975*a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,nrows,cstart,J);CHKERRQ(ierr); 976*a4e85ca8SHong Zhang 977*a4e85ca8SHong Zhang ierr = PetscFree(rows);CHKERRQ(ierr); 9781ad426b7SHong Zhang } 9791ad426b7SHong Zhang 980bfbc38dcSHong Zhang /* Set matrix entries for vertices */ 98183b2e829SHong Zhang /*---------------------------------*/ 982bfbc38dcSHong Zhang ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 9831ad426b7SHong Zhang for (v=vStart; v<vEnd; v++) { 984bfbc38dcSHong Zhang /* Get row indices */ 9852a945128SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 986596e729fSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr); 9872a945128SHong Zhang if (ghost) rstart = -(rstart + 1); /* Convert to actual global offset for ghost nodes */ 988596e729fSHong Zhang ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr); 989596e729fSHong Zhang 990*a4e85ca8SHong Zhang ierr = PetscMalloc1(nrows,&rows);CHKERRQ(ierr); 991596e729fSHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 992596e729fSHong Zhang 993bfbc38dcSHong Zhang /* Get supporting edges and connected vertices */ 994596e729fSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 995596e729fSHong Zhang 996596e729fSHong Zhang for (e=0; e<nedges; e++) { 997bfbc38dcSHong Zhang /* Supporting edges */ 998596e729fSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr); 999596e729fSHong Zhang ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr); 1000596e729fSHong Zhang 1001*a4e85ca8SHong Zhang vptr = network->Jvptr; 1002*a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 1003*a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 1004596e729fSHong Zhang 1005bfbc38dcSHong Zhang /* Connected vertices */ 100644aca652SHong Zhang ierr = DMNetworkGetConnectedNodes(dm,edges[e],&cone);CHKERRQ(ierr); 10072a945128SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 10082a945128SHong Zhang 100944aca652SHong Zhang ierr = DMNetworkIsGhostVertex(dm,vc,&ghost);CHKERRQ(ierr); 101044aca652SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,vc,&cstart);CHKERRQ(ierr); 101144aca652SHong Zhang if (ghost) cstart = -(cstart + 1); /* Convert to actual global offset for ghost nodes */ 101244aca652SHong Zhang ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr); 1013*a4e85ca8SHong Zhang 1014*a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 1015*a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,nrows,cstart,J);CHKERRQ(ierr); 1016596e729fSHong Zhang } 1017596e729fSHong Zhang 1018bfbc38dcSHong Zhang /* Set matrix entries for vertex self */ 10191ad426b7SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 10201ad426b7SHong Zhang if (!ghost) { 1021596e729fSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr); 1022*a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 1023*a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,nrows,cstart,J);CHKERRQ(ierr); 10241ad426b7SHong Zhang } 1025*a4e85ca8SHong Zhang ierr = PetscFree(rows);CHKERRQ(ierr); 10261ad426b7SHong Zhang } 10271ad426b7SHong Zhang ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10281ad426b7SHong Zhang ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10292a945128SHong Zhang #if 0 1030bfbc38dcSHong Zhang printf("\nMatrix J:\n"); 10312a945128SHong Zhang ierr = MatView(*J,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 10322a945128SHong Zhang #endif 10335f2c45f1SShri Abhyankar ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 10345f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10355f2c45f1SShri Abhyankar } 10365f2c45f1SShri Abhyankar 10375f2c45f1SShri Abhyankar #undef __FUNCT__ 10385f2c45f1SShri Abhyankar #define __FUNCT__ "DMDestroy_Network" 10395f2c45f1SShri Abhyankar PetscErrorCode DMDestroy_Network(DM dm) 10405f2c45f1SShri Abhyankar { 10415f2c45f1SShri Abhyankar PetscErrorCode ierr; 10425f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 104383b2e829SHong Zhang PetscInt i; 10445f2c45f1SShri Abhyankar 10455f2c45f1SShri Abhyankar PetscFunctionBegin; 10468415c774SShri Abhyankar if (--network->refct > 0) PetscFunctionReturn(0); 104783b2e829SHong Zhang if (network->Je) { 1048883e35e8SHong Zhang for (i=0; i<3*network->nEdges; i++) { 104983b2e829SHong Zhang ierr = MatDestroy(&network->Je[i]);CHKERRQ(ierr); 10501ad426b7SHong Zhang } 105183b2e829SHong Zhang ierr = PetscFree(network->Je);CHKERRQ(ierr); 105283b2e829SHong Zhang } 105383b2e829SHong Zhang if (network->Jv) { 1054883e35e8SHong Zhang PetscInt v,vStart,vEnd,nedges,*vptr=network->Jvptr; 1055883e35e8SHong Zhang const PetscInt *edges; 1056883e35e8SHong Zhang ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 1057883e35e8SHong Zhang for (v=vStart; v<vEnd; v++) { 1058883e35e8SHong Zhang ierr = MatDestroy(&network->Jv[vptr[v-vStart]]);CHKERRQ(ierr); 1059883e35e8SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 1060883e35e8SHong Zhang for (i=0; i<2*nedges; i++) { 1061883e35e8SHong Zhang ierr = MatDestroy(&network->Jv[vptr[v-vStart]+i+1]);CHKERRQ(ierr); 106283b2e829SHong Zhang } 1063883e35e8SHong Zhang } 1064883e35e8SHong Zhang ierr = PetscFree(network->Jvptr);CHKERRQ(ierr); 106583b2e829SHong Zhang ierr = PetscFree(network->Jv);CHKERRQ(ierr); 10661ad426b7SHong Zhang } 10675f2c45f1SShri Abhyankar ierr = DMDestroy(&network->plex);CHKERRQ(ierr); 10685f2c45f1SShri Abhyankar network->edges = NULL; 10695f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr); 10705f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr); 107183b2e829SHong Zhang 10725f2c45f1SShri Abhyankar ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr); 10735f2c45f1SShri Abhyankar ierr = PetscFree(network->cvalue);CHKERRQ(ierr); 10745f2c45f1SShri Abhyankar ierr = PetscFree(network->header);CHKERRQ(ierr); 10755f2c45f1SShri Abhyankar ierr = PetscFree(network);CHKERRQ(ierr); 10765f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10775f2c45f1SShri Abhyankar } 10785f2c45f1SShri Abhyankar 10795f2c45f1SShri Abhyankar #undef __FUNCT__ 10805f2c45f1SShri Abhyankar #define __FUNCT__ "DMView_Network" 10815f2c45f1SShri Abhyankar PetscErrorCode DMView_Network(DM dm, PetscViewer viewer) 10825f2c45f1SShri Abhyankar { 10835f2c45f1SShri Abhyankar PetscErrorCode ierr; 10845f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 10855f2c45f1SShri Abhyankar 10865f2c45f1SShri Abhyankar PetscFunctionBegin; 10875f2c45f1SShri Abhyankar ierr = DMView(network->plex,viewer);CHKERRQ(ierr); 10885f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10895f2c45f1SShri Abhyankar } 10905f2c45f1SShri Abhyankar 10915f2c45f1SShri Abhyankar #undef __FUNCT__ 10925f2c45f1SShri Abhyankar #define __FUNCT__ "DMGlobalToLocalBegin_Network" 10935f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l) 10945f2c45f1SShri Abhyankar { 10955f2c45f1SShri Abhyankar PetscErrorCode ierr; 10965f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 10975f2c45f1SShri Abhyankar 10985f2c45f1SShri Abhyankar PetscFunctionBegin; 10995f2c45f1SShri Abhyankar ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr); 11005f2c45f1SShri Abhyankar PetscFunctionReturn(0); 11015f2c45f1SShri Abhyankar } 11025f2c45f1SShri Abhyankar 11035f2c45f1SShri Abhyankar #undef __FUNCT__ 11045f2c45f1SShri Abhyankar #define __FUNCT__ "DMGlobalToLocalEnd_Network" 11055f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l) 11065f2c45f1SShri Abhyankar { 11075f2c45f1SShri Abhyankar PetscErrorCode ierr; 11085f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 11095f2c45f1SShri Abhyankar 11105f2c45f1SShri Abhyankar PetscFunctionBegin; 11115f2c45f1SShri Abhyankar ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr); 11125f2c45f1SShri Abhyankar PetscFunctionReturn(0); 11135f2c45f1SShri Abhyankar } 11145f2c45f1SShri Abhyankar 11155f2c45f1SShri Abhyankar #undef __FUNCT__ 11165f2c45f1SShri Abhyankar #define __FUNCT__ "DMLocalToGlobalBegin_Network" 11175f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g) 11185f2c45f1SShri Abhyankar { 11195f2c45f1SShri Abhyankar PetscErrorCode ierr; 11205f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 11215f2c45f1SShri Abhyankar 11225f2c45f1SShri Abhyankar PetscFunctionBegin; 11235f2c45f1SShri Abhyankar ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr); 11245f2c45f1SShri Abhyankar PetscFunctionReturn(0); 11255f2c45f1SShri Abhyankar } 11265f2c45f1SShri Abhyankar 11275f2c45f1SShri Abhyankar #undef __FUNCT__ 11285f2c45f1SShri Abhyankar #define __FUNCT__ "DMLocalToGlobalEnd_Network" 11295f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g) 11305f2c45f1SShri Abhyankar { 11315f2c45f1SShri Abhyankar PetscErrorCode ierr; 11325f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 11335f2c45f1SShri Abhyankar 11345f2c45f1SShri Abhyankar PetscFunctionBegin; 11355f2c45f1SShri Abhyankar ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr); 11365f2c45f1SShri Abhyankar PetscFunctionReturn(0); 11375f2c45f1SShri Abhyankar } 1138