1af0996ceSBarry Smith #include <petsc/private/dmnetworkimpl.h> /*I "petscdmnetwork.h" I*/ 25f2c45f1SShri Abhyankar 35f2c45f1SShri Abhyankar /*@ 4556ed216SShri Abhyankar DMNetworkGetPlex - Gets the Plex DM associated with this network DM 5556ed216SShri Abhyankar 6556ed216SShri Abhyankar Not collective 7556ed216SShri Abhyankar 8556ed216SShri Abhyankar Input Parameters: 9556ed216SShri Abhyankar + netdm - the dm object 10556ed216SShri Abhyankar - plexmdm - the plex dm object 11556ed216SShri Abhyankar 12556ed216SShri Abhyankar Level: Advanced 13556ed216SShri Abhyankar 14556ed216SShri Abhyankar .seealso: DMNetworkCreate() 15556ed216SShri Abhyankar @*/ 16556ed216SShri Abhyankar PetscErrorCode DMNetworkGetPlex(DM netdm, DM *plexdm) 17556ed216SShri Abhyankar { 18556ed216SShri Abhyankar DM_Network *network = (DM_Network*) netdm->data; 19556ed216SShri Abhyankar 20556ed216SShri Abhyankar PetscFunctionBegin; 21556ed216SShri Abhyankar *plexdm = network->plex; 22556ed216SShri Abhyankar PetscFunctionReturn(0); 23556ed216SShri Abhyankar } 24556ed216SShri Abhyankar 25556ed216SShri Abhyankar /*@ 2672c3e9f7SHong Zhang DMNetworkGetSizes - Gets the the number of subnetworks and coupling subnetworks 2772c3e9f7SHong Zhang 2872c3e9f7SHong Zhang Collective on dm 2972c3e9f7SHong Zhang 3072c3e9f7SHong Zhang Input Parameters: 3172c3e9f7SHong Zhang + dm - the dm object 3272c3e9f7SHong Zhang . Nsubnet - global number of subnetworks 3372c3e9f7SHong Zhang - NsubnetCouple - global number of coupling subnetworks 3472c3e9f7SHong Zhang 3597bb938eSShri Abhyankar Level: beginner 3672c3e9f7SHong Zhang 3772c3e9f7SHong Zhang .seealso: DMNetworkCreate() 3872c3e9f7SHong Zhang @*/ 3972c3e9f7SHong Zhang PetscErrorCode DMNetworkGetSizes(DM netdm, PetscInt *Nsubnet, PetscInt *Ncsubnet) 4072c3e9f7SHong Zhang { 4172c3e9f7SHong Zhang DM_Network *network = (DM_Network*) netdm->data; 4272c3e9f7SHong Zhang 4372c3e9f7SHong Zhang PetscFunctionBegin; 4472c3e9f7SHong Zhang *Nsubnet = network->nsubnet; 4572c3e9f7SHong Zhang *Ncsubnet = network->ncsubnet; 4672c3e9f7SHong Zhang PetscFunctionReturn(0); 4772c3e9f7SHong Zhang } 4872c3e9f7SHong Zhang 4972c3e9f7SHong Zhang /*@ 50e2aaf10cSShri Abhyankar DMNetworkSetSizes - Sets the number of subnetworks, local and global vertices and edges for each subnetwork. 515f2c45f1SShri Abhyankar 52d083f849SBarry Smith Collective on dm 535f2c45f1SShri Abhyankar 545f2c45f1SShri Abhyankar Input Parameters: 555f2c45f1SShri Abhyankar + dm - the dm object 56caf410d2SHong Zhang . Nsubnet - global number of subnetworks 57caf410d2SHong Zhang . nV - number of local vertices for each subnetwork 58caf410d2SHong Zhang . nE - number of local edges for each subnetwork 59caf410d2SHong Zhang . NsubnetCouple - global number of coupling subnetworks 60caf410d2SHong Zhang - nec - number of local edges for each coupling subnetwork 615f2c45f1SShri Abhyankar 62caf410d2SHong Zhang You cannot change the sizes once they have been set. nV, nE are arrays of length Nsubnet, and nec is array of length NsubnetCouple. 635f2c45f1SShri Abhyankar 6497bb938eSShri Abhyankar Level: beginner 651b266c99SBarry Smith 661b266c99SBarry Smith .seealso: DMNetworkCreate() 675f2c45f1SShri Abhyankar @*/ 68caf410d2SHong Zhang PetscErrorCode DMNetworkSetSizes(DM dm,PetscInt Nsubnet,PetscInt nV[], PetscInt nE[],PetscInt NsubnetCouple,PetscInt nec[]) 695f2c45f1SShri Abhyankar { 705f2c45f1SShri Abhyankar PetscErrorCode ierr; 715f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 72e2aaf10cSShri Abhyankar PetscInt a[2],b[2],i; 735f2c45f1SShri Abhyankar 745f2c45f1SShri Abhyankar PetscFunctionBegin; 755f2c45f1SShri Abhyankar PetscValidHeaderSpecific(dm,DM_CLASSID,1); 76e2aaf10cSShri Abhyankar if (Nsubnet <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of subnetworks %D cannot be less than 1",Nsubnet); 777765340cSHong Zhang if (NsubnetCouple < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of coupling subnetworks %D cannot be less than 0",NsubnetCouple); 787765340cSHong Zhang 79caf410d2SHong Zhang PetscValidLogicalCollectiveInt(dm,Nsubnet,2); 80caf410d2SHong Zhang if (NsubnetCouple) PetscValidLogicalCollectiveInt(dm,NsubnetCouple,5); 817765340cSHong Zhang if (network->nsubnet != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Network sizes alread set, cannot resize the network"); 827765340cSHong Zhang 83caf410d2SHong Zhang if (!nV || !nE) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Local vertex size or edge size must be provided"); 84f025b11dSHong Zhang 85caf410d2SHong Zhang network->nsubnet = Nsubnet + NsubnetCouple; 86caf410d2SHong Zhang network->ncsubnet = NsubnetCouple; 87caf410d2SHong Zhang ierr = PetscCalloc1(Nsubnet+NsubnetCouple,&network->subnet);CHKERRQ(ierr); 88caf410d2SHong Zhang 89caf410d2SHong Zhang /* ---------------------------------------------------------- 90caf410d2SHong Zhang p=v or e; P=V or E 91caf410d2SHong Zhang subnet[0].pStart = 0 92caf410d2SHong Zhang subnet[i+1].pStart = subnet[i].pEnd = subnet[i].pStart + (nE[i] or NV[i]) 93caf410d2SHong Zhang ----------------------------------------------------------------------- */ 94caf410d2SHong Zhang for (i=0; i < Nsubnet; i++) { 95caf410d2SHong Zhang /* Get global number of vertices and edges for subnet[i] */ 96caf410d2SHong Zhang a[0] = nV[i]; a[1] = nE[i]; /* local number of vertices (excluding ghost) and edges */ 977765340cSHong Zhang ierr = MPIU_Allreduce(a,b,2,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 98071fcb05SBarry Smith network->subnet[i].Nvtx = b[0]; 99071fcb05SBarry Smith network->subnet[i].Nedge = b[1]; 1007765340cSHong Zhang 101caf410d2SHong Zhang network->subnet[i].nvtx = nV[i]; /* local nvtx, without ghost */ 1027765340cSHong Zhang 103caf410d2SHong Zhang /* global subnet[].vStart and vEnd, used by DMNetworkLayoutSetUp() */ 104caf410d2SHong Zhang network->subnet[i].vStart = network->NVertices; 1057765340cSHong Zhang network->subnet[i].vEnd = network->subnet[i].vStart + network->subnet[i].Nvtx; 106caf410d2SHong Zhang 107caf410d2SHong Zhang network->nVertices += nV[i]; 1087765340cSHong Zhang network->NVertices += network->subnet[i].Nvtx; 1097765340cSHong Zhang 1107765340cSHong Zhang network->subnet[i].nedge = nE[i]; 1117765340cSHong Zhang network->subnet[i].eStart = network->nEdges; 112caf410d2SHong Zhang network->subnet[i].eEnd = network->subnet[i].eStart + nE[i]; 113caf410d2SHong Zhang network->nEdges += nE[i]; 114caf410d2SHong Zhang network->NEdges += network->subnet[i].Nedge; 115caf410d2SHong Zhang } 116caf410d2SHong Zhang 117caf410d2SHong Zhang /* coupling subnetwork */ 118caf410d2SHong Zhang for (; i < Nsubnet+NsubnetCouple; i++) { 119caf410d2SHong Zhang /* Get global number of coupling edges for subnet[i] */ 120caf410d2SHong Zhang ierr = MPIU_Allreduce(nec+(i-Nsubnet),&network->subnet[i].Nedge,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 121caf410d2SHong Zhang 122caf410d2SHong Zhang network->subnet[i].nvtx = 0; /* We design coupling subnetwork such that it does not have its own vertices */ 123caf410d2SHong Zhang network->subnet[i].vStart = network->nVertices; 124caf410d2SHong Zhang network->subnet[i].vEnd = network->subnet[i].vStart; 125caf410d2SHong Zhang 126caf410d2SHong Zhang network->subnet[i].nedge = nec[i-Nsubnet]; 127caf410d2SHong Zhang network->subnet[i].eStart = network->nEdges; 128caf410d2SHong Zhang network->subnet[i].eEnd = network->subnet[i].eStart + nec[i-Nsubnet]; 129caf410d2SHong Zhang network->nEdges += nec[i-Nsubnet]; 1307765340cSHong Zhang network->NEdges += network->subnet[i].Nedge; 1317765340cSHong Zhang } 1327765340cSHong Zhang PetscFunctionReturn(0); 1337765340cSHong Zhang } 1347765340cSHong Zhang 1355f2c45f1SShri Abhyankar /*@ 1365f2c45f1SShri Abhyankar DMNetworkSetEdgeList - Sets the list of local edges (vertex connectivity) for the network 1375f2c45f1SShri Abhyankar 138d083f849SBarry Smith Logically collective on dm 1395f2c45f1SShri Abhyankar 1405f2c45f1SShri Abhyankar Input Parameters: 141e3e68989SHong Zhang + dm - the dm object 142e3e68989SHong Zhang . edgelist - list of edges for each subnetwork 143e3e68989SHong Zhang - edgelistCouple - list of edges for each coupling subnetwork 1445f2c45f1SShri Abhyankar 1455f2c45f1SShri Abhyankar Notes: 1465f2c45f1SShri Abhyankar There is no copy involved in this operation, only the pointer is referenced. The edgelist should 1475f2c45f1SShri Abhyankar not be destroyed before the call to DMNetworkLayoutSetUp 1485f2c45f1SShri Abhyankar 14997bb938eSShri Abhyankar Level: beginner 1505f2c45f1SShri Abhyankar 151e3e68989SHong Zhang Example usage: 152e3e68989SHong Zhang Consider the following 2 separate networks and a coupling network: 153e3e68989SHong Zhang 154e3e68989SHong Zhang .vb 155e3e68989SHong Zhang network 0: v0 -> v1 -> v2 -> v3 156e3e68989SHong Zhang network 1: v1 -> v2 -> v0 157e3e68989SHong Zhang coupling network: network 1: v2 -> network 0: v0 158e3e68989SHong Zhang .ve 159e3e68989SHong Zhang 160e3e68989SHong Zhang The resulting input 161e3e68989SHong Zhang edgelist[0] = [0 1 | 1 2 | 2 3]; 162e3e68989SHong Zhang edgelist[1] = [1 2 | 2 0] 163e3e68989SHong Zhang edgelistCouple[0] = [(network)1 (v)2 (network)0 (v)0]. 164e3e68989SHong Zhang 1655f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkSetSizes 1665f2c45f1SShri Abhyankar @*/ 1674e18019cSBarry Smith PetscErrorCode DMNetworkSetEdgeList(DM dm,PetscInt *edgelist[],PetscInt *edgelistCouple[]) 1685f2c45f1SShri Abhyankar { 1695f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 17072c3e9f7SHong Zhang PetscInt i; 1715f2c45f1SShri Abhyankar 1725f2c45f1SShri Abhyankar PetscFunctionBegin; 17372c3e9f7SHong Zhang for (i=0; i < (network->nsubnet-network->ncsubnet); i++) network->subnet[i].edgelist = edgelist[i]; 17472c3e9f7SHong Zhang if (network->ncsubnet) { 17572c3e9f7SHong Zhang PetscInt j = 0; 17672c3e9f7SHong Zhang if (!edgelistCouple) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Must provide edgelist_couple"); 17772c3e9f7SHong Zhang while (i < network->nsubnet) network->subnet[i++].edgelist = edgelistCouple[j++]; 178e3e68989SHong Zhang } 1795f2c45f1SShri Abhyankar PetscFunctionReturn(0); 1805f2c45f1SShri Abhyankar } 1815f2c45f1SShri Abhyankar 1825f2c45f1SShri Abhyankar /*@ 1835f2c45f1SShri Abhyankar DMNetworkLayoutSetUp - Sets up the bare layout (graph) for the network 1845f2c45f1SShri Abhyankar 185d083f849SBarry Smith Collective on dm 1865f2c45f1SShri Abhyankar 1877a7aea1fSJed Brown Input Parameters: 1885f2c45f1SShri Abhyankar . DM - the dmnetwork object 1895f2c45f1SShri Abhyankar 1905f2c45f1SShri Abhyankar Notes: 1915f2c45f1SShri Abhyankar This routine should be called after the network sizes and edgelists have been provided. It creates 1925f2c45f1SShri Abhyankar the bare layout of the network and sets up the network to begin insertion of components. 1935f2c45f1SShri Abhyankar 1945f2c45f1SShri Abhyankar All the components should be registered before calling this routine. 1955f2c45f1SShri Abhyankar 19697bb938eSShri Abhyankar Level: beginner 1975f2c45f1SShri Abhyankar 1985f2c45f1SShri Abhyankar .seealso: DMNetworkSetSizes, DMNetworkSetEdgeList 1995f2c45f1SShri Abhyankar @*/ 2005f2c45f1SShri Abhyankar PetscErrorCode DMNetworkLayoutSetUp(DM dm) 2015f2c45f1SShri Abhyankar { 2025f2c45f1SShri Abhyankar PetscErrorCode ierr; 2035f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 2048e71b177SVaclav Hapla PetscInt numCorners=2,dim = 1; /* One dimensional network */ 205caf410d2SHong Zhang PetscInt i,j,ctr,nsubnet,*eowners,np,*edges,*subnetvtx,vStart; 206caf410d2SHong Zhang PetscInt k,netid,vid, *vidxlTog,*edgelist_couple=NULL; 207caf410d2SHong Zhang const PetscInt *cone; 208caf410d2SHong Zhang MPI_Comm comm; 209caf410d2SHong Zhang PetscMPIInt size,rank; 2106500d4abSHong Zhang 2116500d4abSHong Zhang PetscFunctionBegin; 212caf410d2SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 213*ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 214*ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 2156500d4abSHong Zhang 216caf410d2SHong Zhang /* Create the local edgelist for the network by concatenating local input edgelists of the subnetworks */ 2178e71b177SVaclav Hapla ierr = PetscCalloc1(2*network->nEdges,&edges);CHKERRQ(ierr); 2187765340cSHong Zhang nsubnet = network->nsubnet - network->ncsubnet; 219caf410d2SHong Zhang ctr = 0; 2207765340cSHong Zhang for (i=0; i < nsubnet; i++) { 2216500d4abSHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 222ba38b151SHong Zhang edges[2*ctr] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j]; 223ba38b151SHong Zhang edges[2*ctr+1] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j+1]; 2246500d4abSHong Zhang ctr++; 2256500d4abSHong Zhang } 2266500d4abSHong Zhang } 2277765340cSHong Zhang 228caf410d2SHong Zhang /* Append local coupling edgelists of the subnetworks */ 2297765340cSHong Zhang i = nsubnet; /* netid of coupling subnet */ 2307765340cSHong Zhang nsubnet = network->nsubnet; 2317765340cSHong Zhang while (i < nsubnet) { 232991cf414SHong Zhang edgelist_couple = network->subnet[i].edgelist; 23372c3e9f7SHong Zhang 2346500d4abSHong Zhang k = 0; 2356500d4abSHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 2366500d4abSHong Zhang netid = edgelist_couple[k]; vid = edgelist_couple[k+1]; 237caf410d2SHong Zhang edges[2*ctr] = network->subnet[netid].vStart + vid; k += 2; 2386500d4abSHong Zhang 2396500d4abSHong Zhang netid = edgelist_couple[k]; vid = edgelist_couple[k+1]; 240caf410d2SHong Zhang edges[2*ctr+1] = network->subnet[netid].vStart + vid; k+=2; 2416500d4abSHong Zhang ctr++; 2426500d4abSHong Zhang } 2437765340cSHong Zhang i++; 2447765340cSHong Zhang } 245caf410d2SHong Zhang /* 246caf410d2SHong Zhang if (rank == 0) { 247caf410d2SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF,"[%d] edgelist:\n",rank); 2486500d4abSHong Zhang for (i=0; i < network->nEdges; i++) { 249caf410d2SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF,"[%D %D]",edges[2*i],edges[2*i+1]);CHKERRQ(ierr); 2506500d4abSHong Zhang printf("\n"); 2516500d4abSHong Zhang } 252caf410d2SHong Zhang } 253caf410d2SHong Zhang */ 2546500d4abSHong Zhang 255caf410d2SHong Zhang /* Create network->plex */ 2568e71b177SVaclav Hapla ierr = DMCreate(comm,&network->plex);CHKERRQ(ierr); 2578e71b177SVaclav Hapla ierr = DMSetType(network->plex,DMPLEX);CHKERRQ(ierr); 2588e71b177SVaclav Hapla ierr = DMSetDimension(network->plex,dim);CHKERRQ(ierr); 259caf410d2SHong Zhang if (size == 1) { 2605e488331SVaclav Hapla ierr = DMPlexBuildFromCellList(network->plex,network->nEdges,network->nVertices,numCorners,edges);CHKERRQ(ierr); 261caf410d2SHong Zhang } else { 26225b6865aSVaclav Hapla ierr = DMPlexBuildFromCellListParallel(network->plex,network->nEdges,network->nVertices,network->NVertices,numCorners,edges,NULL);CHKERRQ(ierr); 263acdb140fSBarry Smith } 2646500d4abSHong Zhang 2656500d4abSHong Zhang ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr); 2666500d4abSHong Zhang ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr); 2676500d4abSHong Zhang ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr); 268caf410d2SHong Zhang vStart = network->vStart; 2696500d4abSHong Zhang 270caf410d2SHong Zhang ierr = PetscSectionCreate(comm,&network->DataSection);CHKERRQ(ierr); 271caf410d2SHong Zhang ierr = PetscSectionCreate(comm,&network->DofSection);CHKERRQ(ierr); 2726500d4abSHong Zhang ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr); 2736500d4abSHong Zhang ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr); 2746500d4abSHong Zhang 275caf410d2SHong Zhang network->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 276caf410d2SHong Zhang np = network->pEnd - network->pStart; 277caf410d2SHong Zhang ierr = PetscCalloc2(np,&network->header,np,&network->cvalue);CHKERRQ(ierr); 278caf410d2SHong Zhang 279caf410d2SHong Zhang /* Create vidxlTog: maps local vertex index to global index */ 280caf410d2SHong Zhang np = network->vEnd - vStart; 281caf410d2SHong Zhang ierr = PetscMalloc2(np,&vidxlTog,size+1,&eowners);CHKERRQ(ierr); 282caf410d2SHong Zhang ctr = 0; 283caf410d2SHong Zhang for (i=network->eStart; i<network->eEnd; i++) { 284caf410d2SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,i,&cone);CHKERRQ(ierr); 285caf410d2SHong Zhang vidxlTog[cone[0] - vStart] = edges[2*ctr]; 286caf410d2SHong Zhang vidxlTog[cone[1] - vStart] = edges[2*ctr+1]; 287caf410d2SHong Zhang ctr++; 288caf410d2SHong Zhang } 2898e71b177SVaclav Hapla ierr = PetscFree(edges);CHKERRQ(ierr); 290caf410d2SHong Zhang 2916500d4abSHong Zhang /* Create vertices and edges array for the subnetworks */ 2926500d4abSHong Zhang for (j=0; j < network->nsubnet; j++) { 2936500d4abSHong Zhang ierr = PetscCalloc1(network->subnet[j].nedge,&network->subnet[j].edges);CHKERRQ(ierr); 294caf410d2SHong Zhang 2956500d4abSHong Zhang /* Temporarily setting nvtx and nedge to 0 so we can use them as counters in the below for loop. 2966500d4abSHong Zhang These get updated when the vertices and edges are added. */ 297caf410d2SHong Zhang network->subnet[j].nvtx = 0; 298caf410d2SHong Zhang network->subnet[j].nedge = 0; 2996500d4abSHong Zhang } 300caf410d2SHong Zhang ierr = PetscCalloc1(np,&network->subnetvtx);CHKERRQ(ierr); 3016500d4abSHong Zhang 302caf410d2SHong Zhang 303caf410d2SHong Zhang /* Get edge ownership */ 304caf410d2SHong Zhang np = network->eEnd - network->eStart; 305*ffc4695bSBarry Smith ierr = MPI_Allgather(&np,1,MPIU_INT,eowners+1,1,MPIU_INT,comm);CHKERRMPI(ierr); 306caf410d2SHong Zhang eowners[0] = 0; 307caf410d2SHong Zhang for (i=2; i<=size; i++) eowners[i] += eowners[i-1]; 308caf410d2SHong Zhang 309caf410d2SHong Zhang i = 0; j = 0; 310caf410d2SHong Zhang while (i < np) { /* local edges, including coupling edges */ 311caf410d2SHong Zhang network->header[i].index = i + eowners[rank]; /* Global edge index */ 312caf410d2SHong Zhang 313caf410d2SHong Zhang if (j < network->nsubnet && i < network->subnet[j].eEnd) { 3146500d4abSHong Zhang network->header[i].subnetid = j; /* Subnetwork id */ 3156500d4abSHong Zhang network->subnet[j].edges[network->subnet[j].nedge++] = i; 316caf410d2SHong Zhang 317caf410d2SHong Zhang network->header[i].ndata = 0; 318caf410d2SHong Zhang ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr); 319caf410d2SHong Zhang network->header[i].offset[0] = 0; 3209988b915SShri Abhyankar network->header[i].offsetvarrel[0] = 0; 321caf410d2SHong Zhang i++; 322caf410d2SHong Zhang } 323caf410d2SHong Zhang if (i >= network->subnet[j].eEnd) j++; 324caf410d2SHong Zhang } 325caf410d2SHong Zhang 326caf410d2SHong Zhang /* Count network->subnet[*].nvtx */ 327caf410d2SHong Zhang for (i=vStart; i<network->vEnd; i++) { /* local vertices, including ghosts */ 328caf410d2SHong Zhang k = vidxlTog[i-vStart]; 329caf410d2SHong Zhang for (j=0; j < network->nsubnet; j++) { 330caf410d2SHong Zhang if (network->subnet[j].vStart <= k && k < network->subnet[j].vEnd) { 331caf410d2SHong Zhang network->subnet[j].nvtx++; 3326500d4abSHong Zhang break; 3336500d4abSHong Zhang } 3346500d4abSHong Zhang } 3356500d4abSHong Zhang } 3366500d4abSHong Zhang 337caf410d2SHong Zhang /* Set network->subnet[*].vertices on array network->subnetvtx */ 338caf410d2SHong Zhang subnetvtx = network->subnetvtx; 3396500d4abSHong Zhang for (j=0; j<network->nsubnet; j++) { 340caf410d2SHong Zhang network->subnet[j].vertices = subnetvtx; 341caf410d2SHong Zhang subnetvtx += network->subnet[j].nvtx; 342caf410d2SHong Zhang network->subnet[j].nvtx = 0; 343caf410d2SHong Zhang } 344caf410d2SHong Zhang 345caf410d2SHong Zhang /* Set vertex array for the subnetworks */ 346caf410d2SHong Zhang for (i=vStart; i<network->vEnd; i++) { /* local vertices, including ghosts */ 347caf410d2SHong Zhang network->header[i].index = vidxlTog[i-vStart]; /* Global vertex index */ 348caf410d2SHong Zhang 349caf410d2SHong Zhang k = vidxlTog[i-vStart]; 350caf410d2SHong Zhang for (j=0; j < network->nsubnet; j++) { 351caf410d2SHong Zhang if (network->subnet[j].vStart <= k && k < network->subnet[j].vEnd) { 3526500d4abSHong Zhang network->header[i].subnetid = j; 3536500d4abSHong Zhang network->subnet[j].vertices[network->subnet[j].nvtx++] = i; 3546500d4abSHong Zhang break; 3556500d4abSHong Zhang } 3566500d4abSHong Zhang } 357caf410d2SHong Zhang 3586500d4abSHong Zhang network->header[i].ndata = 0; 3596500d4abSHong Zhang ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr); 360caf410d2SHong Zhang network->header[i].offset[0] = 0; 3619988b915SShri Abhyankar network->header[i].offsetvarrel[0] = 0; 3626500d4abSHong Zhang } 3636500d4abSHong Zhang 364caf410d2SHong Zhang ierr = PetscFree2(vidxlTog,eowners);CHKERRQ(ierr); 3655f2c45f1SShri Abhyankar PetscFunctionReturn(0); 3665f2c45f1SShri Abhyankar } 3675f2c45f1SShri Abhyankar 36894ef8ddeSSatish Balay /*@C 3692727e31bSShri Abhyankar DMNetworkGetSubnetworkInfo - Returns the info for the subnetwork 3702727e31bSShri Abhyankar 3717a7aea1fSJed Brown Input Parameters: 372caf410d2SHong Zhang + dm - the DM object 3732727e31bSShri Abhyankar - id - the ID (integer) of the subnetwork 3742727e31bSShri Abhyankar 3757a7aea1fSJed Brown Output Parameters: 3762727e31bSShri Abhyankar + nv - number of vertices (local) 3772727e31bSShri Abhyankar . ne - number of edges (local) 3782727e31bSShri Abhyankar . vtx - local vertices for this subnetwork 379a2b725a8SWilliam Gropp - edge - local edges for this subnetwork 3802727e31bSShri Abhyankar 3812727e31bSShri Abhyankar Notes: 3822727e31bSShri Abhyankar Cannot call this routine before DMNetworkLayoutSetup() 3832727e31bSShri Abhyankar 38406dd6b0eSSatish Balay Level: intermediate 38506dd6b0eSSatish Balay 3862727e31bSShri Abhyankar .seealso: DMNetworkLayoutSetUp, DMNetworkCreate 3872727e31bSShri Abhyankar @*/ 388caf410d2SHong Zhang PetscErrorCode DMNetworkGetSubnetworkInfo(DM dm,PetscInt id,PetscInt *nv, PetscInt *ne,const PetscInt **vtx, const PetscInt **edge) 3892727e31bSShri Abhyankar { 390caf410d2SHong Zhang DM_Network *network = (DM_Network*)dm->data; 3912727e31bSShri Abhyankar 3922727e31bSShri Abhyankar PetscFunctionBegin; 39372c3e9f7SHong Zhang if (id >= network->nsubnet) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Subnet ID %D exceeds the num of subnets %D",id,network->nsubnet); 3942727e31bSShri Abhyankar *nv = network->subnet[id].nvtx; 3952727e31bSShri Abhyankar *ne = network->subnet[id].nedge; 3962727e31bSShri Abhyankar *vtx = network->subnet[id].vertices; 3972727e31bSShri Abhyankar *edge = network->subnet[id].edges; 3982727e31bSShri Abhyankar PetscFunctionReturn(0); 3992727e31bSShri Abhyankar } 4002727e31bSShri Abhyankar 4012727e31bSShri Abhyankar /*@C 402caf410d2SHong Zhang DMNetworkGetSubnetworkCoupleInfo - Returns the info for the coupling subnetwork 403caf410d2SHong Zhang 4047a7aea1fSJed Brown Input Parameters: 405caf410d2SHong Zhang + dm - the DM object 406caf410d2SHong Zhang - id - the ID (integer) of the coupling subnetwork 407caf410d2SHong Zhang 4087a7aea1fSJed Brown Output Parameters: 409caf410d2SHong Zhang + ne - number of edges (local) 410caf410d2SHong Zhang - edge - local edges for this coupling subnetwork 411caf410d2SHong Zhang 412caf410d2SHong Zhang Notes: 413caf410d2SHong Zhang Cannot call this routine before DMNetworkLayoutSetup() 414caf410d2SHong Zhang 415caf410d2SHong Zhang Level: intermediate 416caf410d2SHong Zhang 417caf410d2SHong Zhang .seealso: DMNetworkGetSubnetworkInfo, DMNetworkLayoutSetUp, DMNetworkCreate 418caf410d2SHong Zhang @*/ 419caf410d2SHong Zhang PetscErrorCode DMNetworkGetSubnetworkCoupleInfo(DM dm,PetscInt id,PetscInt *ne,const PetscInt **edge) 420caf410d2SHong Zhang { 421caf410d2SHong Zhang DM_Network *net = (DM_Network*)dm->data; 42272c3e9f7SHong Zhang PetscInt id1; 423caf410d2SHong Zhang 424caf410d2SHong Zhang PetscFunctionBegin; 42572c3e9f7SHong Zhang if (net->ncsubnet) { 42672c3e9f7SHong Zhang if (id >= net->ncsubnet) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Subnet ID %D exceeds the num of coupling subnets %D",id,net->ncsubnet); 42772c3e9f7SHong Zhang 42872c3e9f7SHong Zhang id1 = id + net->nsubnet - net->ncsubnet; 429caf410d2SHong Zhang *ne = net->subnet[id1].nedge; 430caf410d2SHong Zhang *edge = net->subnet[id1].edges; 43172c3e9f7SHong Zhang } else { 43272c3e9f7SHong Zhang *ne = 0; 43372c3e9f7SHong Zhang *edge = NULL; 43472c3e9f7SHong Zhang } 435caf410d2SHong Zhang PetscFunctionReturn(0); 436caf410d2SHong Zhang } 437caf410d2SHong Zhang 438caf410d2SHong Zhang /*@C 4395f2c45f1SShri Abhyankar DMNetworkRegisterComponent - Registers the network component 4405f2c45f1SShri Abhyankar 441d083f849SBarry Smith Logically collective on dm 4425f2c45f1SShri Abhyankar 4437a7aea1fSJed Brown Input Parameters: 4445f2c45f1SShri Abhyankar + dm - the network object 4455f2c45f1SShri Abhyankar . name - the component name 4465f2c45f1SShri Abhyankar - size - the storage size in bytes for this component data 4475f2c45f1SShri Abhyankar 4487a7aea1fSJed Brown Output Parameters: 4495f2c45f1SShri Abhyankar . key - an integer key that defines the component 4505f2c45f1SShri Abhyankar 4515f2c45f1SShri Abhyankar Notes 4525f2c45f1SShri Abhyankar This routine should be called by all processors before calling DMNetworkLayoutSetup(). 4535f2c45f1SShri Abhyankar 45497bb938eSShri Abhyankar Level: beginner 4555f2c45f1SShri Abhyankar 4565f2c45f1SShri Abhyankar .seealso: DMNetworkLayoutSetUp, DMNetworkCreate 4575f2c45f1SShri Abhyankar @*/ 458caf410d2SHong Zhang PetscErrorCode DMNetworkRegisterComponent(DM dm,const char *name,size_t size,PetscInt *key) 4595f2c45f1SShri Abhyankar { 4605f2c45f1SShri Abhyankar PetscErrorCode ierr; 4615f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 4625f2c45f1SShri Abhyankar DMNetworkComponent *component=&network->component[network->ncomponent]; 4635f2c45f1SShri Abhyankar PetscBool flg=PETSC_FALSE; 4645f2c45f1SShri Abhyankar PetscInt i; 4655f2c45f1SShri Abhyankar 4665f2c45f1SShri Abhyankar PetscFunctionBegin; 4675f2c45f1SShri Abhyankar for (i=0; i < network->ncomponent; i++) { 4685f2c45f1SShri Abhyankar ierr = PetscStrcmp(component->name,name,&flg);CHKERRQ(ierr); 4695f2c45f1SShri Abhyankar if (flg) { 4705f2c45f1SShri Abhyankar *key = i; 4715f2c45f1SShri Abhyankar PetscFunctionReturn(0); 4725f2c45f1SShri Abhyankar } 4736d64e262SShri Abhyankar } 4746d64e262SShri Abhyankar if (network->ncomponent == MAX_COMPONENTS) { 4756d64e262SShri Abhyankar SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Number of components registered exceeds the max %D",MAX_COMPONENTS); 4765f2c45f1SShri Abhyankar } 4775f2c45f1SShri Abhyankar 4785f2c45f1SShri Abhyankar ierr = PetscStrcpy(component->name,name);CHKERRQ(ierr); 4795f2c45f1SShri Abhyankar component->size = size/sizeof(DMNetworkComponentGenericDataType); 4805f2c45f1SShri Abhyankar *key = network->ncomponent; 4815f2c45f1SShri Abhyankar network->ncomponent++; 4825f2c45f1SShri Abhyankar PetscFunctionReturn(0); 4835f2c45f1SShri Abhyankar } 4845f2c45f1SShri Abhyankar 4855f2c45f1SShri Abhyankar /*@ 4865f2c45f1SShri Abhyankar DMNetworkGetVertexRange - Get the bounds [start, end) for the vertices. 4875f2c45f1SShri Abhyankar 4885f2c45f1SShri Abhyankar Not Collective 4895f2c45f1SShri Abhyankar 4905f2c45f1SShri Abhyankar Input Parameters: 491a2b725a8SWilliam Gropp . dm - The DMNetwork object 4925f2c45f1SShri Abhyankar 493fd292e60Sprj- Output Parameters: 4945f2c45f1SShri Abhyankar + vStart - The first vertex point 4955f2c45f1SShri Abhyankar - vEnd - One beyond the last vertex point 4965f2c45f1SShri Abhyankar 49797bb938eSShri Abhyankar Level: beginner 4985f2c45f1SShri Abhyankar 4995f2c45f1SShri Abhyankar .seealso: DMNetworkGetEdgeRange 5005f2c45f1SShri Abhyankar @*/ 5015f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVertexRange(DM dm,PetscInt *vStart,PetscInt *vEnd) 5025f2c45f1SShri Abhyankar { 5035f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 5045f2c45f1SShri Abhyankar 5055f2c45f1SShri Abhyankar PetscFunctionBegin; 5065f2c45f1SShri Abhyankar if (vStart) *vStart = network->vStart; 5075f2c45f1SShri Abhyankar if (vEnd) *vEnd = network->vEnd; 5085f2c45f1SShri Abhyankar PetscFunctionReturn(0); 5095f2c45f1SShri Abhyankar } 5105f2c45f1SShri Abhyankar 5115f2c45f1SShri Abhyankar /*@ 5125f2c45f1SShri Abhyankar DMNetworkGetEdgeRange - Get the bounds [start, end) for the edges. 5135f2c45f1SShri Abhyankar 5145f2c45f1SShri Abhyankar Not Collective 5155f2c45f1SShri Abhyankar 5165f2c45f1SShri Abhyankar Input Parameters: 517a2b725a8SWilliam Gropp . dm - The DMNetwork object 5185f2c45f1SShri Abhyankar 519fd292e60Sprj- Output Parameters: 5205f2c45f1SShri Abhyankar + eStart - The first edge point 5215f2c45f1SShri Abhyankar - eEnd - One beyond the last edge point 5225f2c45f1SShri Abhyankar 52397bb938eSShri Abhyankar Level: beginner 5245f2c45f1SShri Abhyankar 5255f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange 5265f2c45f1SShri Abhyankar @*/ 5275f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetEdgeRange(DM dm,PetscInt *eStart,PetscInt *eEnd) 5285f2c45f1SShri Abhyankar { 5295f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 5305f2c45f1SShri Abhyankar 5315f2c45f1SShri Abhyankar PetscFunctionBegin; 5325f2c45f1SShri Abhyankar if (eStart) *eStart = network->eStart; 5335f2c45f1SShri Abhyankar if (eEnd) *eEnd = network->eEnd; 5345f2c45f1SShri Abhyankar PetscFunctionReturn(0); 5355f2c45f1SShri Abhyankar } 5365f2c45f1SShri Abhyankar 5377b6afd5bSHong Zhang /*@ 538e85e6aecSHong Zhang DMNetworkGetGlobalEdgeIndex - Get the user global numbering for the edge. 5397b6afd5bSHong Zhang 5407b6afd5bSHong Zhang Not Collective 5417b6afd5bSHong Zhang 5427b6afd5bSHong Zhang Input Parameters: 5437b6afd5bSHong Zhang + dm - DMNetwork object 544e85e6aecSHong Zhang - p - edge point 5457b6afd5bSHong Zhang 546fd292e60Sprj- Output Parameters: 547e85e6aecSHong Zhang . index - user global numbering for the edge 5487b6afd5bSHong Zhang 5497b6afd5bSHong Zhang Level: intermediate 5507b6afd5bSHong Zhang 551e85e6aecSHong Zhang .seealso: DMNetworkGetGlobalVertexIndex 5527b6afd5bSHong Zhang @*/ 553e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalEdgeIndex(DM dm,PetscInt p,PetscInt *index) 5547b6afd5bSHong Zhang { 5557b6afd5bSHong Zhang PetscErrorCode ierr; 5567b6afd5bSHong Zhang DM_Network *network = (DM_Network*)dm->data; 5577b6afd5bSHong Zhang PetscInt offsetp; 5587b6afd5bSHong Zhang DMNetworkComponentHeader header; 5597b6afd5bSHong Zhang 5607b6afd5bSHong Zhang PetscFunctionBegin; 561caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 5627b6afd5bSHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 5637b6afd5bSHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 564e85e6aecSHong Zhang *index = header->index; 5657b6afd5bSHong Zhang PetscFunctionReturn(0); 5667b6afd5bSHong Zhang } 5677b6afd5bSHong Zhang 5685f2c45f1SShri Abhyankar /*@ 569e85e6aecSHong Zhang DMNetworkGetGlobalVertexIndex - Get the user global numbering for the vertex. 570e85e6aecSHong Zhang 571e85e6aecSHong Zhang Not Collective 572e85e6aecSHong Zhang 573e85e6aecSHong Zhang Input Parameters: 574e85e6aecSHong Zhang + dm - DMNetwork object 575e85e6aecSHong Zhang - p - vertex point 576e85e6aecSHong Zhang 577fd292e60Sprj- Output Parameters: 578e85e6aecSHong Zhang . index - user global numbering for the vertex 579e85e6aecSHong Zhang 580e85e6aecSHong Zhang Level: intermediate 581e85e6aecSHong Zhang 582e85e6aecSHong Zhang .seealso: DMNetworkGetGlobalEdgeIndex 583e85e6aecSHong Zhang @*/ 584e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalVertexIndex(DM dm,PetscInt p,PetscInt *index) 585e85e6aecSHong Zhang { 586e85e6aecSHong Zhang PetscErrorCode ierr; 587e85e6aecSHong Zhang DM_Network *network = (DM_Network*)dm->data; 588e85e6aecSHong Zhang PetscInt offsetp; 589e85e6aecSHong Zhang DMNetworkComponentHeader header; 590e85e6aecSHong Zhang 591e85e6aecSHong Zhang PetscFunctionBegin; 592caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 593e85e6aecSHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 594e85e6aecSHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 595e85e6aecSHong Zhang *index = header->index; 596e85e6aecSHong Zhang PetscFunctionReturn(0); 597e85e6aecSHong Zhang } 598e85e6aecSHong Zhang 599c3b11c7cSShri Abhyankar /* 600c3b11c7cSShri Abhyankar DMNetworkGetComponentKeyOffset - Gets the type along with the offset for indexing the 601c3b11c7cSShri Abhyankar component value from the component data array 602c3b11c7cSShri Abhyankar 603c3b11c7cSShri Abhyankar Not Collective 604c3b11c7cSShri Abhyankar 605c3b11c7cSShri Abhyankar Input Parameters: 606c3b11c7cSShri Abhyankar + dm - The DMNetwork object 607c3b11c7cSShri Abhyankar . p - vertex/edge point 608c3b11c7cSShri Abhyankar - compnum - component number 609c3b11c7cSShri Abhyankar 610c3b11c7cSShri Abhyankar Output Parameters: 611c3b11c7cSShri Abhyankar + compkey - the key obtained when registering the component 612c3b11c7cSShri Abhyankar - offset - offset into the component data array associated with the vertex/edge point 613c3b11c7cSShri Abhyankar 614c3b11c7cSShri Abhyankar Notes: 615c3b11c7cSShri Abhyankar Typical usage: 616c3b11c7cSShri Abhyankar 617c3b11c7cSShri Abhyankar DMNetworkGetComponentDataArray(dm, &arr); 618c3b11c7cSShri Abhyankar DMNetworkGetVertex/EdgeRange(dm,&Start,&End); 619c3b11c7cSShri Abhyankar Loop over vertices or edges 620c3b11c7cSShri Abhyankar DMNetworkGetNumComponents(dm,v,&numcomps); 621c3b11c7cSShri Abhyankar Loop over numcomps 622c3b11c7cSShri Abhyankar DMNetworkGetComponentKeyOffset(dm,v,compnum,&key,&offset); 623c3b11c7cSShri Abhyankar compdata = (UserCompDataType)(arr+offset); 624c3b11c7cSShri Abhyankar 625c3b11c7cSShri Abhyankar Level: intermediate 626c3b11c7cSShri Abhyankar 627c3b11c7cSShri Abhyankar .seealso: DMNetworkGetNumComponents, DMNetworkGetComponentDataArray, 628c3b11c7cSShri Abhyankar */ 629c3b11c7cSShri Abhyankar PetscErrorCode DMNetworkGetComponentKeyOffset(DM dm,PetscInt p, PetscInt compnum, PetscInt *compkey, PetscInt *offset) 630c3b11c7cSShri Abhyankar { 631c3b11c7cSShri Abhyankar PetscErrorCode ierr; 632c3b11c7cSShri Abhyankar PetscInt offsetp; 633c3b11c7cSShri Abhyankar DMNetworkComponentHeader header; 634c3b11c7cSShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 635c3b11c7cSShri Abhyankar 636c3b11c7cSShri Abhyankar PetscFunctionBegin; 637c3b11c7cSShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 638c3b11c7cSShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 639c3b11c7cSShri Abhyankar if (compkey) *compkey = header->key[compnum]; 640c3b11c7cSShri Abhyankar if (offset) *offset = offsetp+network->dataheadersize+header->offset[compnum]; 641c3b11c7cSShri Abhyankar PetscFunctionReturn(0); 642c3b11c7cSShri Abhyankar } 643c3b11c7cSShri Abhyankar 644c3b11c7cSShri Abhyankar /*@ 645c3b11c7cSShri Abhyankar DMNetworkGetComponent - Returns the network component and its key 646c3b11c7cSShri Abhyankar 647c3b11c7cSShri Abhyankar Not Collective 648c3b11c7cSShri Abhyankar 6497a7aea1fSJed Brown Input Parameters: 650c3b11c7cSShri Abhyankar + dm - DMNetwork object 651c3b11c7cSShri Abhyankar . p - edge or vertex point 652c3b11c7cSShri Abhyankar - compnum - component number 653c3b11c7cSShri Abhyankar 654c3b11c7cSShri Abhyankar Output Parameters: 655c3b11c7cSShri Abhyankar + compkey - the key set for this computing during registration 656c3b11c7cSShri Abhyankar - component - the component data 657c3b11c7cSShri Abhyankar 658c3b11c7cSShri Abhyankar Notes: 659c3b11c7cSShri Abhyankar Typical usage: 660c3b11c7cSShri Abhyankar 661c3b11c7cSShri Abhyankar DMNetworkGetVertex/EdgeRange(dm,&Start,&End); 662c3b11c7cSShri Abhyankar Loop over vertices or edges 663c3b11c7cSShri Abhyankar DMNetworkGetNumComponents(dm,v,&numcomps); 664c3b11c7cSShri Abhyankar Loop over numcomps 665c3b11c7cSShri Abhyankar DMNetworkGetComponent(dm,v,compnum,&key,&component); 666c3b11c7cSShri Abhyankar 66797bb938eSShri Abhyankar Level: beginner 668c3b11c7cSShri Abhyankar 669c3b11c7cSShri Abhyankar .seealso: DMNetworkGetNumComponents, DMNetworkGetVariableOffset 670c3b11c7cSShri Abhyankar @*/ 671c3b11c7cSShri Abhyankar PetscErrorCode DMNetworkGetComponent(DM dm, PetscInt p, PetscInt compnum, PetscInt *key, void **component) 672c3b11c7cSShri Abhyankar { 673c3b11c7cSShri Abhyankar PetscErrorCode ierr; 674c3b11c7cSShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 675e108cb99SStefano Zampini PetscInt offsetd = 0; 676c3b11c7cSShri Abhyankar 677c3b11c7cSShri Abhyankar PetscFunctionBegin; 678c3b11c7cSShri Abhyankar ierr = DMNetworkGetComponentKeyOffset(dm,p,compnum,key,&offsetd);CHKERRQ(ierr); 679c3b11c7cSShri Abhyankar *component = network->componentdataarray+offsetd; 680c3b11c7cSShri Abhyankar PetscFunctionReturn(0); 681c3b11c7cSShri Abhyankar } 682c3b11c7cSShri Abhyankar 683e85e6aecSHong Zhang /*@ 684325661f6SSatish Balay DMNetworkAddComponent - Adds a network component at the given point (vertex/edge) 6855f2c45f1SShri Abhyankar 6865f2c45f1SShri Abhyankar Not Collective 6875f2c45f1SShri Abhyankar 6885f2c45f1SShri Abhyankar Input Parameters: 6895f2c45f1SShri Abhyankar + dm - The DMNetwork object 6905f2c45f1SShri Abhyankar . p - vertex/edge point 6915f2c45f1SShri Abhyankar . componentkey - component key returned while registering the component 6925f2c45f1SShri Abhyankar - compvalue - pointer to the data structure for the component 6935f2c45f1SShri Abhyankar 69497bb938eSShri Abhyankar Level: beginner 6955f2c45f1SShri Abhyankar 6965f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange, DMNetworkGetEdgeRange, DMNetworkRegisterComponent 6975f2c45f1SShri Abhyankar @*/ 6985f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddComponent(DM dm, PetscInt p,PetscInt componentkey,void* compvalue) 6995f2c45f1SShri Abhyankar { 7005f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 70143a39a44SBarry Smith DMNetworkComponent *component = &network->component[componentkey]; 7025f2c45f1SShri Abhyankar DMNetworkComponentHeader header = &network->header[p]; 7035f2c45f1SShri Abhyankar DMNetworkComponentValue cvalue = &network->cvalue[p]; 7045f2c45f1SShri Abhyankar PetscErrorCode ierr; 7055f2c45f1SShri Abhyankar 7065f2c45f1SShri Abhyankar PetscFunctionBegin; 707fa58f0a9SHong Zhang 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); 708fa58f0a9SHong Zhang 70943a39a44SBarry Smith header->size[header->ndata] = component->size; 71043a39a44SBarry Smith ierr = PetscSectionAddDof(network->DataSection,p,component->size);CHKERRQ(ierr); 7115f2c45f1SShri Abhyankar header->key[header->ndata] = componentkey; 7125f2c45f1SShri Abhyankar if (header->ndata != 0) header->offset[header->ndata] = header->offset[header->ndata-1] + header->size[header->ndata-1]; 7139988b915SShri Abhyankar header->nvar[header->ndata] = 0; 7145f2c45f1SShri Abhyankar 7155f2c45f1SShri Abhyankar cvalue->data[header->ndata] = (void*)compvalue; 7165f2c45f1SShri Abhyankar header->ndata++; 7175f2c45f1SShri Abhyankar PetscFunctionReturn(0); 7185f2c45f1SShri Abhyankar } 7195f2c45f1SShri Abhyankar 7205f2c45f1SShri Abhyankar /*@ 7219988b915SShri Abhyankar DMNetworkSetComponentNumVariables - Sets the number of variables for a component 7229988b915SShri Abhyankar 7239988b915SShri Abhyankar Not Collective 7249988b915SShri Abhyankar 7259988b915SShri Abhyankar Input Parameters: 7269988b915SShri Abhyankar + dm - The DMNetwork object 7279988b915SShri Abhyankar . p - vertex/edge point 7289988b915SShri Abhyankar . compnum - component number (First component added = 0, second = 1, ...) 7299988b915SShri Abhyankar - nvar - number of variables for the component 7309988b915SShri Abhyankar 73197bb938eSShri Abhyankar Level: beginner 7329988b915SShri Abhyankar 7339dacc45bSShrirang Abhyankar .seealso: DMNetworkAddComponent(), DMNetworkGetNumComponents(),DMNetworkRegisterComponent() 7349988b915SShri Abhyankar @*/ 7359988b915SShri Abhyankar PetscErrorCode DMNetworkSetComponentNumVariables(DM dm, PetscInt p,PetscInt compnum,PetscInt nvar) 7369988b915SShri Abhyankar { 7379988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 7389988b915SShri Abhyankar DMNetworkComponentHeader header = &network->header[p]; 7399988b915SShri Abhyankar PetscErrorCode ierr; 7409988b915SShri Abhyankar 7419988b915SShri Abhyankar PetscFunctionBegin; 7429988b915SShri Abhyankar ierr = DMNetworkAddNumVariables(dm,p,nvar);CHKERRQ(ierr); 7439988b915SShri Abhyankar header->nvar[compnum] = nvar; 7449988b915SShri Abhyankar if (compnum != 0) header->offsetvarrel[compnum] = header->offsetvarrel[compnum-1] + header->nvar[compnum-1]; 7459988b915SShri Abhyankar PetscFunctionReturn(0); 7469988b915SShri Abhyankar } 7479988b915SShri Abhyankar 7489988b915SShri Abhyankar /*@ 7495f2c45f1SShri Abhyankar DMNetworkGetNumComponents - Get the number of components at a vertex/edge 7505f2c45f1SShri Abhyankar 7515f2c45f1SShri Abhyankar Not Collective 7525f2c45f1SShri Abhyankar 7535f2c45f1SShri Abhyankar Input Parameters: 7545f2c45f1SShri Abhyankar + dm - The DMNetwork object 755a2b725a8SWilliam Gropp - p - vertex/edge point 7565f2c45f1SShri Abhyankar 7575f2c45f1SShri Abhyankar Output Parameters: 7585f2c45f1SShri Abhyankar . numcomponents - Number of components at the vertex/edge 7595f2c45f1SShri Abhyankar 76097bb938eSShri Abhyankar Level: beginner 7615f2c45f1SShri Abhyankar 7625f2c45f1SShri Abhyankar .seealso: DMNetworkRegisterComponent, DMNetworkAddComponent 7635f2c45f1SShri Abhyankar @*/ 7645f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetNumComponents(DM dm,PetscInt p,PetscInt *numcomponents) 7655f2c45f1SShri Abhyankar { 7665f2c45f1SShri Abhyankar PetscErrorCode ierr; 7675f2c45f1SShri Abhyankar PetscInt offset; 7685f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 7695f2c45f1SShri Abhyankar 7705f2c45f1SShri Abhyankar PetscFunctionBegin; 7715f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 7725f2c45f1SShri Abhyankar *numcomponents = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 7735f2c45f1SShri Abhyankar PetscFunctionReturn(0); 7745f2c45f1SShri Abhyankar } 7755f2c45f1SShri Abhyankar 7765f2c45f1SShri Abhyankar /*@ 7775f2c45f1SShri Abhyankar DMNetworkGetVariableOffset - Get the offset for accessing the variable associated with the given vertex/edge from the local vector. 7785f2c45f1SShri Abhyankar 7795f2c45f1SShri Abhyankar Not Collective 7805f2c45f1SShri Abhyankar 7815f2c45f1SShri Abhyankar Input Parameters: 7825f2c45f1SShri Abhyankar + dm - The DMNetwork object 7835f2c45f1SShri Abhyankar - p - the edge/vertex point 7845f2c45f1SShri Abhyankar 7855f2c45f1SShri Abhyankar Output Parameters: 7865f2c45f1SShri Abhyankar . offset - the offset 7875f2c45f1SShri Abhyankar 78897bb938eSShri Abhyankar Level: beginner 7895f2c45f1SShri Abhyankar 7905f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 7915f2c45f1SShri Abhyankar @*/ 7925f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableOffset(DM dm,PetscInt p,PetscInt *offset) 7935f2c45f1SShri Abhyankar { 7945f2c45f1SShri Abhyankar PetscErrorCode ierr; 7955f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 7965f2c45f1SShri Abhyankar 7975f2c45f1SShri Abhyankar PetscFunctionBegin; 7981bb6d2a8SBarry Smith ierr = PetscSectionGetOffset(network->plex->localSection,p,offset);CHKERRQ(ierr); 7995f2c45f1SShri Abhyankar PetscFunctionReturn(0); 8005f2c45f1SShri Abhyankar } 8015f2c45f1SShri Abhyankar 8025f2c45f1SShri Abhyankar /*@ 8035f2c45f1SShri Abhyankar DMNetworkGetVariableGlobalOffset - Get the global offset for the variable associated with the given vertex/edge from the global vector. 8045f2c45f1SShri Abhyankar 8055f2c45f1SShri Abhyankar Not Collective 8065f2c45f1SShri Abhyankar 8075f2c45f1SShri Abhyankar Input Parameters: 8085f2c45f1SShri Abhyankar + dm - The DMNetwork object 8095f2c45f1SShri Abhyankar - p - the edge/vertex point 8105f2c45f1SShri Abhyankar 8115f2c45f1SShri Abhyankar Output Parameters: 8125f2c45f1SShri Abhyankar . offsetg - the offset 8135f2c45f1SShri Abhyankar 81497bb938eSShri Abhyankar Level: beginner 8155f2c45f1SShri Abhyankar 8165f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableOffset, DMGetLocalVector 8175f2c45f1SShri Abhyankar @*/ 8185f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableGlobalOffset(DM dm,PetscInt p,PetscInt *offsetg) 8195f2c45f1SShri Abhyankar { 8205f2c45f1SShri Abhyankar PetscErrorCode ierr; 8215f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 8225f2c45f1SShri Abhyankar 8235f2c45f1SShri Abhyankar PetscFunctionBegin; 8241bb6d2a8SBarry Smith ierr = PetscSectionGetOffset(network->plex->globalSection,p,offsetg);CHKERRQ(ierr); 8256fefedf4SHong Zhang if (*offsetg < 0) *offsetg = -(*offsetg + 1); /* Convert to actual global offset for ghost vertex */ 8265f2c45f1SShri Abhyankar PetscFunctionReturn(0); 8275f2c45f1SShri Abhyankar } 8285f2c45f1SShri Abhyankar 82924121865SAdrian Maldonado /*@ 8309988b915SShri Abhyankar DMNetworkGetComponentVariableOffset - Get the offset for accessing the variable associated with a component for the given vertex/edge from the local vector. 8319988b915SShri Abhyankar 8329988b915SShri Abhyankar Not Collective 8339988b915SShri Abhyankar 8349988b915SShri Abhyankar Input Parameters: 8359988b915SShri Abhyankar + dm - The DMNetwork object 8367d928bffSSatish Balay . p - the edge/vertex point 8377d928bffSSatish Balay - compnum - component number 8389988b915SShri Abhyankar 8399988b915SShri Abhyankar Output Parameters: 8409988b915SShri Abhyankar . offset - the offset 8419988b915SShri Abhyankar 8429988b915SShri Abhyankar Level: intermediate 8439988b915SShri Abhyankar 8449dacc45bSShrirang Abhyankar .seealso: DMNetworkGetVariableGlobalOffset(), DMGetLocalVector(), DMNetworkSetComponentNumVariables() 8459988b915SShri Abhyankar @*/ 8469988b915SShri Abhyankar PetscErrorCode DMNetworkGetComponentVariableOffset(DM dm,PetscInt p,PetscInt compnum,PetscInt *offset) 8479988b915SShri Abhyankar { 8489988b915SShri Abhyankar PetscErrorCode ierr; 8499988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 8509988b915SShri Abhyankar PetscInt offsetp,offsetd; 8519988b915SShri Abhyankar DMNetworkComponentHeader header; 8529988b915SShri Abhyankar 8539988b915SShri Abhyankar PetscFunctionBegin; 8549988b915SShri Abhyankar ierr = DMNetworkGetVariableOffset(dm,p,&offsetp);CHKERRQ(ierr); 8559988b915SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetd);CHKERRQ(ierr); 8569988b915SShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetd); 8579988b915SShri Abhyankar *offset = offsetp + header->offsetvarrel[compnum]; 8589988b915SShri Abhyankar PetscFunctionReturn(0); 8599988b915SShri Abhyankar } 8609988b915SShri Abhyankar 8619988b915SShri Abhyankar /*@ 8629988b915SShri Abhyankar DMNetworkGetComponentVariableGlobalOffset - Get the global offset for accessing the variable associated with a component for the given vertex/edge from the local vector. 8639988b915SShri Abhyankar 8649988b915SShri Abhyankar Not Collective 8659988b915SShri Abhyankar 8669988b915SShri Abhyankar Input Parameters: 8679988b915SShri Abhyankar + dm - The DMNetwork object 8687d928bffSSatish Balay . p - the edge/vertex point 8697d928bffSSatish Balay - compnum - component number 8709988b915SShri Abhyankar 8719988b915SShri Abhyankar Output Parameters: 8729988b915SShri Abhyankar . offsetg - the global offset 8739988b915SShri Abhyankar 8749988b915SShri Abhyankar Level: intermediate 8759988b915SShri Abhyankar 8769dacc45bSShrirang Abhyankar .seealso: DMNetworkGetVariableGlobalOffset(), DMNetworkGetComponentVariableOffset(), DMGetLocalVector(), DMNetworkSetComponentNumVariables() 8779988b915SShri Abhyankar @*/ 8789988b915SShri Abhyankar PetscErrorCode DMNetworkGetComponentVariableGlobalOffset(DM dm,PetscInt p,PetscInt compnum,PetscInt *offsetg) 8799988b915SShri Abhyankar { 8809988b915SShri Abhyankar PetscErrorCode ierr; 8819988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 8829988b915SShri Abhyankar PetscInt offsetp,offsetd; 8839988b915SShri Abhyankar DMNetworkComponentHeader header; 8849988b915SShri Abhyankar 8859988b915SShri Abhyankar PetscFunctionBegin; 8869988b915SShri Abhyankar ierr = DMNetworkGetVariableGlobalOffset(dm,p,&offsetp);CHKERRQ(ierr); 8879988b915SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetd);CHKERRQ(ierr); 8889988b915SShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetd); 8899988b915SShri Abhyankar *offsetg = offsetp + header->offsetvarrel[compnum]; 8909988b915SShri Abhyankar PetscFunctionReturn(0); 8919988b915SShri Abhyankar } 8929988b915SShri Abhyankar 8939988b915SShri Abhyankar /*@ 89424121865SAdrian Maldonado DMNetworkGetEdgeOffset - Get the offset for accessing the variable associated with the given edge from the local subvector. 89524121865SAdrian Maldonado 89624121865SAdrian Maldonado Not Collective 89724121865SAdrian Maldonado 89824121865SAdrian Maldonado Input Parameters: 89924121865SAdrian Maldonado + dm - The DMNetwork object 90024121865SAdrian Maldonado - p - the edge point 90124121865SAdrian Maldonado 90224121865SAdrian Maldonado Output Parameters: 90324121865SAdrian Maldonado . offset - the offset 90424121865SAdrian Maldonado 90524121865SAdrian Maldonado Level: intermediate 90624121865SAdrian Maldonado 90724121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 90824121865SAdrian Maldonado @*/ 90924121865SAdrian Maldonado PetscErrorCode DMNetworkGetEdgeOffset(DM dm,PetscInt p,PetscInt *offset) 91024121865SAdrian Maldonado { 91124121865SAdrian Maldonado PetscErrorCode ierr; 91224121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 91324121865SAdrian Maldonado 91424121865SAdrian Maldonado PetscFunctionBegin; 91524121865SAdrian Maldonado 91624121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->edge.DofSection,p,offset);CHKERRQ(ierr); 91724121865SAdrian Maldonado PetscFunctionReturn(0); 91824121865SAdrian Maldonado } 91924121865SAdrian Maldonado 92024121865SAdrian Maldonado /*@ 92124121865SAdrian Maldonado DMNetworkGetVertexOffset - Get the offset for accessing the variable associated with the given vertex from the local subvector. 92224121865SAdrian Maldonado 92324121865SAdrian Maldonado Not Collective 92424121865SAdrian Maldonado 92524121865SAdrian Maldonado Input Parameters: 92624121865SAdrian Maldonado + dm - The DMNetwork object 92724121865SAdrian Maldonado - p - the vertex point 92824121865SAdrian Maldonado 92924121865SAdrian Maldonado Output Parameters: 93024121865SAdrian Maldonado . offset - the offset 93124121865SAdrian Maldonado 93224121865SAdrian Maldonado Level: intermediate 93324121865SAdrian Maldonado 93424121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 93524121865SAdrian Maldonado @*/ 93624121865SAdrian Maldonado PetscErrorCode DMNetworkGetVertexOffset(DM dm,PetscInt p,PetscInt *offset) 93724121865SAdrian Maldonado { 93824121865SAdrian Maldonado PetscErrorCode ierr; 93924121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 94024121865SAdrian Maldonado 94124121865SAdrian Maldonado PetscFunctionBegin; 94224121865SAdrian Maldonado 94324121865SAdrian Maldonado p -= network->vStart; 94424121865SAdrian Maldonado 94524121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->vertex.DofSection,p,offset);CHKERRQ(ierr); 94624121865SAdrian Maldonado PetscFunctionReturn(0); 94724121865SAdrian Maldonado } 9485f2c45f1SShri Abhyankar /*@ 9495f2c45f1SShri Abhyankar DMNetworkAddNumVariables - Add number of variables associated with a given point. 9505f2c45f1SShri Abhyankar 9515f2c45f1SShri Abhyankar Not Collective 9525f2c45f1SShri Abhyankar 9535f2c45f1SShri Abhyankar Input Parameters: 9545f2c45f1SShri Abhyankar + dm - The DMNetworkObject 9555f2c45f1SShri Abhyankar . p - the vertex/edge point 9565f2c45f1SShri Abhyankar - nvar - number of additional variables 9575f2c45f1SShri Abhyankar 95897bb938eSShri Abhyankar Level: beginner 9595f2c45f1SShri Abhyankar 9605f2c45f1SShri Abhyankar .seealso: DMNetworkSetNumVariables 9615f2c45f1SShri Abhyankar @*/ 9625f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddNumVariables(DM dm,PetscInt p,PetscInt nvar) 9635f2c45f1SShri Abhyankar { 9645f2c45f1SShri Abhyankar PetscErrorCode ierr; 9655f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 9665f2c45f1SShri Abhyankar 9675f2c45f1SShri Abhyankar PetscFunctionBegin; 9685f2c45f1SShri Abhyankar ierr = PetscSectionAddDof(network->DofSection,p,nvar);CHKERRQ(ierr); 9695f2c45f1SShri Abhyankar PetscFunctionReturn(0); 9705f2c45f1SShri Abhyankar } 9715f2c45f1SShri Abhyankar 97227f51fceSHong Zhang /*@ 97327f51fceSHong Zhang DMNetworkGetNumVariables - Gets number of variables for a vertex/edge point. 97427f51fceSHong Zhang 97527f51fceSHong Zhang Not Collective 97627f51fceSHong Zhang 97727f51fceSHong Zhang Input Parameters: 97827f51fceSHong Zhang + dm - The DMNetworkObject 97927f51fceSHong Zhang - p - the vertex/edge point 98027f51fceSHong Zhang 98127f51fceSHong Zhang Output Parameters: 98227f51fceSHong Zhang . nvar - number of variables 98327f51fceSHong Zhang 98497bb938eSShri Abhyankar Level: beginner 98527f51fceSHong Zhang 98627f51fceSHong Zhang .seealso: DMNetworkAddNumVariables, DMNetworkSddNumVariables 98727f51fceSHong Zhang @*/ 98827f51fceSHong Zhang PetscErrorCode DMNetworkGetNumVariables(DM dm,PetscInt p,PetscInt *nvar) 98927f51fceSHong Zhang { 99027f51fceSHong Zhang PetscErrorCode ierr; 99127f51fceSHong Zhang DM_Network *network = (DM_Network*)dm->data; 99227f51fceSHong Zhang 99327f51fceSHong Zhang PetscFunctionBegin; 99427f51fceSHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 99527f51fceSHong Zhang PetscFunctionReturn(0); 99627f51fceSHong Zhang } 99727f51fceSHong Zhang 9985f2c45f1SShri Abhyankar /*@ 9995f2c45f1SShri Abhyankar DMNetworkSetNumVariables - Sets number of variables for a vertex/edge point. 10005f2c45f1SShri Abhyankar 10015f2c45f1SShri Abhyankar Not Collective 10025f2c45f1SShri Abhyankar 10035f2c45f1SShri Abhyankar Input Parameters: 10045f2c45f1SShri Abhyankar + dm - The DMNetworkObject 10055f2c45f1SShri Abhyankar . p - the vertex/edge point 10065f2c45f1SShri Abhyankar - nvar - number of variables 10075f2c45f1SShri Abhyankar 100897bb938eSShri Abhyankar Level: beginner 10095f2c45f1SShri Abhyankar 10105f2c45f1SShri Abhyankar .seealso: DMNetworkAddNumVariables 10115f2c45f1SShri Abhyankar @*/ 10125f2c45f1SShri Abhyankar PetscErrorCode DMNetworkSetNumVariables(DM dm,PetscInt p,PetscInt nvar) 10135f2c45f1SShri Abhyankar { 10145f2c45f1SShri Abhyankar PetscErrorCode ierr; 10155f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10165f2c45f1SShri Abhyankar 10175f2c45f1SShri Abhyankar PetscFunctionBegin; 10185f2c45f1SShri Abhyankar ierr = PetscSectionSetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 10195f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10205f2c45f1SShri Abhyankar } 10215f2c45f1SShri Abhyankar 10225f2c45f1SShri Abhyankar /* Sets up the array that holds the data for all components and its associated section. This 10235f2c45f1SShri Abhyankar function is called during DMSetUp() */ 10245f2c45f1SShri Abhyankar PetscErrorCode DMNetworkComponentSetUp(DM dm) 10255f2c45f1SShri Abhyankar { 10265f2c45f1SShri Abhyankar PetscErrorCode ierr; 10275f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 1028e53b5ba3SHong Zhang PetscInt arr_size,p,offset,offsetp,ncomp,i; 10295f2c45f1SShri Abhyankar DMNetworkComponentHeader header; 10305f2c45f1SShri Abhyankar DMNetworkComponentValue cvalue; 10315f2c45f1SShri Abhyankar DMNetworkComponentGenericDataType *componentdataarray; 10325f2c45f1SShri Abhyankar 10335f2c45f1SShri Abhyankar PetscFunctionBegin; 10345f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr); 10355f2c45f1SShri Abhyankar ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr); 103675b160a0SShri Abhyankar ierr = PetscMalloc1(arr_size,&network->componentdataarray);CHKERRQ(ierr); 10375f2c45f1SShri Abhyankar componentdataarray = network->componentdataarray; 10385f2c45f1SShri Abhyankar for (p = network->pStart; p < network->pEnd; p++) { 10395f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 10405f2c45f1SShri Abhyankar /* Copy header */ 10415f2c45f1SShri Abhyankar header = &network->header[p]; 1042302440fdSBarry Smith ierr = PetscMemcpy(componentdataarray+offsetp,header,network->dataheadersize*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 10435f2c45f1SShri Abhyankar /* Copy data */ 10445f2c45f1SShri Abhyankar cvalue = &network->cvalue[p]; 10455f2c45f1SShri Abhyankar ncomp = header->ndata; 10465f2c45f1SShri Abhyankar for (i = 0; i < ncomp; i++) { 10475f2c45f1SShri Abhyankar offset = offsetp + network->dataheadersize + header->offset[i]; 1048302440fdSBarry Smith ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 10495f2c45f1SShri Abhyankar } 10505f2c45f1SShri Abhyankar } 10515f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10525f2c45f1SShri Abhyankar } 10535f2c45f1SShri Abhyankar 10545f2c45f1SShri Abhyankar /* Sets up the section for dofs. This routine is called during DMSetUp() */ 10555f2c45f1SShri Abhyankar PetscErrorCode DMNetworkVariablesSetUp(DM dm) 10565f2c45f1SShri Abhyankar { 10575f2c45f1SShri Abhyankar PetscErrorCode ierr; 10585f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10595f2c45f1SShri Abhyankar 10605f2c45f1SShri Abhyankar PetscFunctionBegin; 10615f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr); 10625f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10635f2c45f1SShri Abhyankar } 10645f2c45f1SShri Abhyankar 106597bb938eSShri Abhyankar /* 10665f2c45f1SShri Abhyankar DMNetworkGetComponentDataArray - Returns the component data array 10675f2c45f1SShri Abhyankar 10685f2c45f1SShri Abhyankar Not Collective 10695f2c45f1SShri Abhyankar 10705f2c45f1SShri Abhyankar Input Parameters: 10715f2c45f1SShri Abhyankar . dm - The DMNetwork Object 10725f2c45f1SShri Abhyankar 10735f2c45f1SShri Abhyankar Output Parameters: 10745f2c45f1SShri Abhyankar . componentdataarray - array that holds data for all components 10755f2c45f1SShri Abhyankar 10765f2c45f1SShri Abhyankar Level: intermediate 10775f2c45f1SShri Abhyankar 1078a730d845SHong Zhang .seealso: DMNetworkGetComponentKeyOffset, DMNetworkGetNumComponents 107997bb938eSShri Abhyankar */ 10805f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetComponentDataArray(DM dm,DMNetworkComponentGenericDataType **componentdataarray) 10815f2c45f1SShri Abhyankar { 10825f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10835f2c45f1SShri Abhyankar 10845f2c45f1SShri Abhyankar PetscFunctionBegin; 10855f2c45f1SShri Abhyankar *componentdataarray = network->componentdataarray; 10865f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10875f2c45f1SShri Abhyankar } 10885f2c45f1SShri Abhyankar 108924121865SAdrian Maldonado /* Get a subsection from a range of points */ 109024121865SAdrian Maldonado PetscErrorCode DMNetworkGetSubSection_private(PetscSection master, PetscInt pstart, PetscInt pend,PetscSection *subsection) 109124121865SAdrian Maldonado { 109224121865SAdrian Maldonado PetscErrorCode ierr; 109324121865SAdrian Maldonado PetscInt i, nvar; 109424121865SAdrian Maldonado 109524121865SAdrian Maldonado PetscFunctionBegin; 109624121865SAdrian Maldonado ierr = PetscSectionCreate(PetscObjectComm((PetscObject)master), subsection);CHKERRQ(ierr); 109724121865SAdrian Maldonado ierr = PetscSectionSetChart(*subsection, 0, pend - pstart);CHKERRQ(ierr); 109824121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 109924121865SAdrian Maldonado ierr = PetscSectionGetDof(master,i,&nvar);CHKERRQ(ierr); 110024121865SAdrian Maldonado ierr = PetscSectionSetDof(*subsection, i - pstart, nvar);CHKERRQ(ierr); 110124121865SAdrian Maldonado } 110224121865SAdrian Maldonado 110324121865SAdrian Maldonado ierr = PetscSectionSetUp(*subsection);CHKERRQ(ierr); 110424121865SAdrian Maldonado PetscFunctionReturn(0); 110524121865SAdrian Maldonado } 110624121865SAdrian Maldonado 110724121865SAdrian Maldonado /* Create a submap of points with a GlobalToLocal structure */ 110824121865SAdrian Maldonado PetscErrorCode DMNetworkSetSubMap_private(PetscInt pstart, PetscInt pend, ISLocalToGlobalMapping *map) 110924121865SAdrian Maldonado { 111024121865SAdrian Maldonado PetscErrorCode ierr; 111124121865SAdrian Maldonado PetscInt i, *subpoints; 111224121865SAdrian Maldonado 111324121865SAdrian Maldonado PetscFunctionBegin; 111424121865SAdrian Maldonado /* Create index sets to map from "points" to "subpoints" */ 111524121865SAdrian Maldonado ierr = PetscMalloc1(pend - pstart, &subpoints);CHKERRQ(ierr); 111624121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 111724121865SAdrian Maldonado subpoints[i - pstart] = i; 111824121865SAdrian Maldonado } 1119459726d8SSatish Balay ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,pend-pstart,subpoints,PETSC_COPY_VALUES,map);CHKERRQ(ierr); 112024121865SAdrian Maldonado ierr = PetscFree(subpoints);CHKERRQ(ierr); 112124121865SAdrian Maldonado PetscFunctionReturn(0); 112224121865SAdrian Maldonado } 112324121865SAdrian Maldonado 112424121865SAdrian Maldonado /*@ 112524121865SAdrian Maldonado DMNetworkAssembleGraphStructures - Assembles vertex and edge data structures. Must be called after DMNetworkDistribute. 112624121865SAdrian Maldonado 112724121865SAdrian Maldonado Collective 112824121865SAdrian Maldonado 112924121865SAdrian Maldonado Input Parameters: 113024121865SAdrian Maldonado . dm - The DMNetworkObject 113124121865SAdrian Maldonado 113224121865SAdrian Maldonado Note: the routine will create alternative orderings for the vertices and edges. Assume global network points are: 113324121865SAdrian Maldonado 113424121865SAdrian Maldonado points = [0 1 2 3 4 5 6] 113524121865SAdrian Maldonado 1136caf410d2SHong Zhang where edges = [0,1,2,3] and vertices = [4,5,6]. The new orderings will be specific to the subset (i.e vertices = [0,1,2] <- [4,5,6]). 113724121865SAdrian Maldonado 113824121865SAdrian Maldonado With this new ordering a local PetscSection, global PetscSection and PetscSF will be created specific to the subset. 113924121865SAdrian Maldonado 114024121865SAdrian Maldonado Level: intermediate 114124121865SAdrian Maldonado 114224121865SAdrian Maldonado @*/ 114324121865SAdrian Maldonado PetscErrorCode DMNetworkAssembleGraphStructures(DM dm) 114424121865SAdrian Maldonado { 114524121865SAdrian Maldonado PetscErrorCode ierr; 114624121865SAdrian Maldonado MPI_Comm comm; 11479852e123SBarry Smith PetscMPIInt rank, size; 114824121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 114924121865SAdrian Maldonado 1150eab1376dSHong Zhang PetscFunctionBegin; 115124121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 1152*ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 1153*ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 115424121865SAdrian Maldonado 115524121865SAdrian Maldonado /* Create maps for vertices and edges */ 115624121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 115724121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->eStart,network->eEnd,&network->edge.mapping);CHKERRQ(ierr); 115824121865SAdrian Maldonado 115924121865SAdrian Maldonado /* Create local sub-sections */ 116024121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->vStart,network->vEnd,&network->vertex.DofSection);CHKERRQ(ierr); 116124121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->eStart,network->eEnd,&network->edge.DofSection);CHKERRQ(ierr); 116224121865SAdrian Maldonado 11639852e123SBarry Smith if (size > 1) { 116424121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 116522bbedd7SHong Zhang 116624121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->vertex.DofSection, network->vertex.sf, PETSC_FALSE, PETSC_FALSE, &network->vertex.GlobalDofSection);CHKERRQ(ierr); 116724121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->edge.mapping, &network->edge.sf);CHKERRQ(ierr); 116824121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->edge.DofSection, network->edge.sf, PETSC_FALSE, PETSC_FALSE, &network->edge.GlobalDofSection);CHKERRQ(ierr); 116924121865SAdrian Maldonado } else { 117024121865SAdrian Maldonado /* create structures for vertex */ 117124121865SAdrian Maldonado ierr = PetscSectionClone(network->vertex.DofSection,&network->vertex.GlobalDofSection);CHKERRQ(ierr); 117224121865SAdrian Maldonado /* create structures for edge */ 117324121865SAdrian Maldonado ierr = PetscSectionClone(network->edge.DofSection,&network->edge.GlobalDofSection);CHKERRQ(ierr); 117424121865SAdrian Maldonado } 117524121865SAdrian Maldonado 117624121865SAdrian Maldonado /* Add viewers */ 117724121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->edge.GlobalDofSection,"Global edge dof section");CHKERRQ(ierr); 117824121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->vertex.GlobalDofSection,"Global vertex dof section");CHKERRQ(ierr); 117924121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->edge.GlobalDofSection, NULL, "-edge_global_section_view");CHKERRQ(ierr); 118024121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->vertex.GlobalDofSection, NULL, "-vertex_global_section_view");CHKERRQ(ierr); 118124121865SAdrian Maldonado PetscFunctionReturn(0); 118224121865SAdrian Maldonado } 11837b6afd5bSHong Zhang 11845f2c45f1SShri Abhyankar /*@ 11855f2c45f1SShri Abhyankar DMNetworkDistribute - Distributes the network and moves associated component data. 11865f2c45f1SShri Abhyankar 11875f2c45f1SShri Abhyankar Collective 11885f2c45f1SShri Abhyankar 11895f2c45f1SShri Abhyankar Input Parameter: 1190d3464fd4SAdrian Maldonado + DM - the DMNetwork object 11915f2c45f1SShri Abhyankar - overlap - The overlap of partitions, 0 is the default 11925f2c45f1SShri Abhyankar 11935f2c45f1SShri Abhyankar Notes: 11948b171c8eSHong Zhang Distributes the network with <overlap>-overlapping partitioning of the edges. 11955f2c45f1SShri Abhyankar 11965f2c45f1SShri Abhyankar Level: intermediate 11975f2c45f1SShri Abhyankar 11985f2c45f1SShri Abhyankar .seealso: DMNetworkCreate 11995f2c45f1SShri Abhyankar @*/ 1200d3464fd4SAdrian Maldonado PetscErrorCode DMNetworkDistribute(DM *dm,PetscInt overlap) 12015f2c45f1SShri Abhyankar { 1202d3464fd4SAdrian Maldonado MPI_Comm comm; 12035f2c45f1SShri Abhyankar PetscErrorCode ierr; 1204d3464fd4SAdrian Maldonado PetscMPIInt size; 1205d3464fd4SAdrian Maldonado DM_Network *oldDMnetwork = (DM_Network*)((*dm)->data); 1206d3464fd4SAdrian Maldonado DM_Network *newDMnetwork; 1207caf410d2SHong Zhang PetscSF pointsf=NULL; 12085f2c45f1SShri Abhyankar DM newDM; 1209caf410d2SHong Zhang PetscInt j,e,v,offset,*subnetvtx; 121051ac5effSHong Zhang PetscPartitioner part; 1211b9c6e19dSShri Abhyankar DMNetworkComponentHeader header; 12125f2c45f1SShri Abhyankar 12135f2c45f1SShri Abhyankar PetscFunctionBegin; 1214d3464fd4SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)*dm,&comm);CHKERRQ(ierr); 1215*ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 1216d3464fd4SAdrian Maldonado if (size == 1) PetscFunctionReturn(0); 1217d3464fd4SAdrian Maldonado 1218d3464fd4SAdrian Maldonado ierr = DMNetworkCreate(PetscObjectComm((PetscObject)*dm),&newDM);CHKERRQ(ierr); 12195f2c45f1SShri Abhyankar newDMnetwork = (DM_Network*)newDM->data; 12205f2c45f1SShri Abhyankar newDMnetwork->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 122151ac5effSHong Zhang 122251ac5effSHong Zhang /* Enable runtime options for petscpartitioner */ 122351ac5effSHong Zhang ierr = DMPlexGetPartitioner(oldDMnetwork->plex,&part);CHKERRQ(ierr); 122451ac5effSHong Zhang ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); 122551ac5effSHong Zhang 12265f2c45f1SShri Abhyankar /* Distribute plex dm and dof section */ 122780cf41d5SMatthew G. Knepley ierr = DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr); 122851ac5effSHong Zhang 12295f2c45f1SShri Abhyankar /* Distribute dof section */ 1230d3464fd4SAdrian Maldonado ierr = PetscSectionCreate(PetscObjectComm((PetscObject)*dm),&newDMnetwork->DofSection);CHKERRQ(ierr); 12315f2c45f1SShri Abhyankar ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr); 1232d3464fd4SAdrian Maldonado ierr = PetscSectionCreate(PetscObjectComm((PetscObject)*dm),&newDMnetwork->DataSection);CHKERRQ(ierr); 123351ac5effSHong Zhang 12345f2c45f1SShri Abhyankar /* Distribute data and associated section */ 123531da1fc8SHong Zhang ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPIU_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr); 123624121865SAdrian Maldonado 12375f2c45f1SShri Abhyankar ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr); 12385f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr); 12395f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr); 12405f2c45f1SShri Abhyankar newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart; 12416fefedf4SHong Zhang newDMnetwork->nVertices = newDMnetwork->vEnd - newDMnetwork->vStart; 12426fefedf4SHong Zhang newDMnetwork->NVertices = oldDMnetwork->NVertices; 12435f2c45f1SShri Abhyankar newDMnetwork->NEdges = oldDMnetwork->NEdges; 124424121865SAdrian Maldonado 12451bb6d2a8SBarry Smith /* Set Dof section as the section for dm */ 124692fd8e1eSJed Brown ierr = DMSetLocalSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr); 1247e87a4003SBarry Smith ierr = DMGetGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr); 12485f2c45f1SShri Abhyankar 1249b9c6e19dSShri Abhyankar /* Set up subnetwork info in the newDM */ 1250b9c6e19dSShri Abhyankar newDMnetwork->nsubnet = oldDMnetwork->nsubnet; 1251caf410d2SHong Zhang newDMnetwork->ncsubnet = oldDMnetwork->ncsubnet; 1252b9c6e19dSShri Abhyankar ierr = PetscCalloc1(newDMnetwork->nsubnet,&newDMnetwork->subnet);CHKERRQ(ierr); 1253b9c6e19dSShri Abhyankar /* Copy over the global number of vertices and edges in each subnetwork. Note that these are already 1254b9c6e19dSShri Abhyankar calculated in DMNetworkLayoutSetUp() 1255b9c6e19dSShri Abhyankar */ 1256b9c6e19dSShri Abhyankar for (j=0; j < newDMnetwork->nsubnet; j++) { 1257b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nvtx = oldDMnetwork->subnet[j].Nvtx; 1258b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nedge = oldDMnetwork->subnet[j].Nedge; 1259b9c6e19dSShri Abhyankar } 1260b9c6e19dSShri Abhyankar 1261b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++) { 1262b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 1263b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1264b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nedge++; 1265b9c6e19dSShri Abhyankar } 1266b9c6e19dSShri Abhyankar 1267b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++) { 1268b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1269b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1270b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nvtx++; 1271b9c6e19dSShri Abhyankar } 1272b9c6e19dSShri Abhyankar 1273b9c6e19dSShri Abhyankar /* Now create the vertices and edge arrays for the subnetworks */ 1274caf410d2SHong Zhang ierr = PetscCalloc1(newDMnetwork->vEnd-newDMnetwork->vStart,&newDMnetwork->subnetvtx);CHKERRQ(ierr); 1275caf410d2SHong Zhang subnetvtx = newDMnetwork->subnetvtx; 1276caf410d2SHong Zhang 1277b9c6e19dSShri Abhyankar for (j=0; j<newDMnetwork->nsubnet; j++) { 1278b9c6e19dSShri Abhyankar ierr = PetscCalloc1(newDMnetwork->subnet[j].nedge,&newDMnetwork->subnet[j].edges);CHKERRQ(ierr); 1279caf410d2SHong Zhang newDMnetwork->subnet[j].vertices = subnetvtx; 1280caf410d2SHong Zhang subnetvtx += newDMnetwork->subnet[j].nvtx; 1281caf410d2SHong Zhang 1282b9c6e19dSShri Abhyankar /* Temporarily setting nvtx and nedge to 0 so we can use them as counters in the below for loop. 1283b9c6e19dSShri Abhyankar These get updated when the vertices and edges are added. */ 1284b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].nvtx = newDMnetwork->subnet[j].nedge = 0; 1285b9c6e19dSShri Abhyankar } 1286b9c6e19dSShri Abhyankar 1287b9c6e19dSShri Abhyankar /* Set the vertices and edges in each subnetwork */ 1288b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++) { 1289b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 1290b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1291b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].edges[newDMnetwork->subnet[header->subnetid].nedge++] = e; 1292b9c6e19dSShri Abhyankar } 1293b9c6e19dSShri Abhyankar 1294b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++) { 1295b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1296b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1297b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].vertices[newDMnetwork->subnet[header->subnetid].nvtx++] = v; 1298b9c6e19dSShri Abhyankar } 1299b9c6e19dSShri Abhyankar 1300caf410d2SHong Zhang newDM->setupcalled = (*dm)->setupcalled; 130122bbedd7SHong Zhang newDMnetwork->distributecalled = PETSC_TRUE; 1302caf410d2SHong Zhang 130324121865SAdrian Maldonado /* Destroy point SF */ 130424121865SAdrian Maldonado ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr); 130524121865SAdrian Maldonado 1306d3464fd4SAdrian Maldonado ierr = DMDestroy(dm);CHKERRQ(ierr); 1307d3464fd4SAdrian Maldonado *dm = newDM; 13085f2c45f1SShri Abhyankar PetscFunctionReturn(0); 13095f2c45f1SShri Abhyankar } 13105f2c45f1SShri Abhyankar 131124121865SAdrian Maldonado /*@C 131224121865SAdrian Maldonado PetscSFGetSubSF - Returns an SF for a specific subset of points. Leaves are re-numbered to reflect the new ordering. 131324121865SAdrian Maldonado 131424121865SAdrian Maldonado Input Parameters: 131524121865SAdrian Maldonado + masterSF - the original SF structure 131624121865SAdrian Maldonado - map - a ISLocalToGlobal mapping that contains the subset of points 131724121865SAdrian Maldonado 131824121865SAdrian Maldonado Output Parameters: 131924121865SAdrian Maldonado . subSF - a subset of the masterSF for the desired subset. 1320ee300463SSatish Balay 1321ee300463SSatish Balay Level: intermediate 13227d928bffSSatish Balay @*/ 132324121865SAdrian Maldonado PetscErrorCode PetscSFGetSubSF(PetscSF mastersf, ISLocalToGlobalMapping map, PetscSF *subSF) { 132424121865SAdrian Maldonado 132524121865SAdrian Maldonado PetscErrorCode ierr; 132624121865SAdrian Maldonado PetscInt nroots, nleaves, *ilocal_sub; 132724121865SAdrian Maldonado PetscInt i, *ilocal_map, nroots_sub, nleaves_sub = 0; 132824121865SAdrian Maldonado PetscInt *local_points, *remote_points; 132924121865SAdrian Maldonado PetscSFNode *iremote_sub; 133024121865SAdrian Maldonado const PetscInt *ilocal; 133124121865SAdrian Maldonado const PetscSFNode *iremote; 133224121865SAdrian Maldonado 133324121865SAdrian Maldonado PetscFunctionBegin; 133424121865SAdrian Maldonado ierr = PetscSFGetGraph(mastersf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr); 133524121865SAdrian Maldonado 133624121865SAdrian Maldonado /* Look for leaves that pertain to the subset of points. Get the local ordering */ 133724121865SAdrian Maldonado ierr = PetscMalloc1(nleaves,&ilocal_map);CHKERRQ(ierr); 133824121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nleaves,ilocal,NULL,ilocal_map);CHKERRQ(ierr); 133924121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 134024121865SAdrian Maldonado if (ilocal_map[i] != -1) nleaves_sub += 1; 134124121865SAdrian Maldonado } 134224121865SAdrian Maldonado /* Re-number ilocal with subset numbering. Need information from roots */ 134324121865SAdrian Maldonado ierr = PetscMalloc2(nroots,&local_points,nroots,&remote_points);CHKERRQ(ierr); 134424121865SAdrian Maldonado for (i = 0; i < nroots; i++) local_points[i] = i; 134524121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nroots,local_points,NULL,local_points);CHKERRQ(ierr); 134624121865SAdrian Maldonado ierr = PetscSFBcastBegin(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr); 134724121865SAdrian Maldonado ierr = PetscSFBcastEnd(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr); 134824121865SAdrian Maldonado /* Fill up graph using local (that is, local to the subset) numbering. */ 13494b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&ilocal_sub);CHKERRQ(ierr); 13504b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&iremote_sub);CHKERRQ(ierr); 135124121865SAdrian Maldonado nleaves_sub = 0; 135224121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 135324121865SAdrian Maldonado if (ilocal_map[i] != -1) { 135424121865SAdrian Maldonado ilocal_sub[nleaves_sub] = ilocal_map[i]; 13554b70a8deSAdrian Maldonado iremote_sub[nleaves_sub].rank = iremote[i].rank; 135624121865SAdrian Maldonado iremote_sub[nleaves_sub].index = remote_points[ilocal[i]]; 135724121865SAdrian Maldonado nleaves_sub += 1; 135824121865SAdrian Maldonado } 135924121865SAdrian Maldonado } 136024121865SAdrian Maldonado ierr = PetscFree2(local_points,remote_points);CHKERRQ(ierr); 136124121865SAdrian Maldonado ierr = ISLocalToGlobalMappingGetSize(map,&nroots_sub);CHKERRQ(ierr); 136224121865SAdrian Maldonado 136324121865SAdrian Maldonado /* Create new subSF */ 136424121865SAdrian Maldonado ierr = PetscSFCreate(PETSC_COMM_WORLD,subSF);CHKERRQ(ierr); 136524121865SAdrian Maldonado ierr = PetscSFSetFromOptions(*subSF);CHKERRQ(ierr); 13664b70a8deSAdrian Maldonado ierr = PetscSFSetGraph(*subSF,nroots_sub,nleaves_sub,ilocal_sub,PETSC_OWN_POINTER,iremote_sub,PETSC_COPY_VALUES);CHKERRQ(ierr); 136724121865SAdrian Maldonado ierr = PetscFree(ilocal_map);CHKERRQ(ierr); 13684b70a8deSAdrian Maldonado ierr = PetscFree(iremote_sub);CHKERRQ(ierr); 136924121865SAdrian Maldonado PetscFunctionReturn(0); 137024121865SAdrian Maldonado } 137124121865SAdrian Maldonado 13725f2c45f1SShri Abhyankar /*@C 13735f2c45f1SShri Abhyankar DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point 13745f2c45f1SShri Abhyankar 13755f2c45f1SShri Abhyankar Not Collective 13765f2c45f1SShri Abhyankar 13775f2c45f1SShri Abhyankar Input Parameters: 13785f2c45f1SShri Abhyankar + dm - The DMNetwork object 13795f2c45f1SShri Abhyankar - p - the vertex point 13805f2c45f1SShri Abhyankar 1381fd292e60Sprj- Output Parameters: 13825f2c45f1SShri Abhyankar + nedges - number of edges connected to this vertex point 13835f2c45f1SShri Abhyankar - edges - List of edge points 13845f2c45f1SShri Abhyankar 138597bb938eSShri Abhyankar Level: beginner 13865f2c45f1SShri Abhyankar 13875f2c45f1SShri Abhyankar Fortran Notes: 13885f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 13895f2c45f1SShri Abhyankar include petsc.h90 in your code. 13905f2c45f1SShri Abhyankar 1391d842c372SHong Zhang .seealso: DMNetworkCreate, DMNetworkGetConnectedVertices 13925f2c45f1SShri Abhyankar @*/ 13935f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[]) 13945f2c45f1SShri Abhyankar { 13955f2c45f1SShri Abhyankar PetscErrorCode ierr; 13965f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 13975f2c45f1SShri Abhyankar 13985f2c45f1SShri Abhyankar PetscFunctionBegin; 13995f2c45f1SShri Abhyankar ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr); 14005f2c45f1SShri Abhyankar ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr); 14015f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14025f2c45f1SShri Abhyankar } 14035f2c45f1SShri Abhyankar 14045f2c45f1SShri Abhyankar /*@C 1405d842c372SHong Zhang DMNetworkGetConnectedVertices - Return the connected vertices for this edge point 14065f2c45f1SShri Abhyankar 14075f2c45f1SShri Abhyankar Not Collective 14085f2c45f1SShri Abhyankar 14095f2c45f1SShri Abhyankar Input Parameters: 14105f2c45f1SShri Abhyankar + dm - The DMNetwork object 14115f2c45f1SShri Abhyankar - p - the edge point 14125f2c45f1SShri Abhyankar 1413fd292e60Sprj- Output Parameters: 14145f2c45f1SShri Abhyankar . vertices - vertices connected to this edge 14155f2c45f1SShri Abhyankar 141697bb938eSShri Abhyankar Level: beginner 14175f2c45f1SShri Abhyankar 14185f2c45f1SShri Abhyankar Fortran Notes: 14195f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 14205f2c45f1SShri Abhyankar include petsc.h90 in your code. 14215f2c45f1SShri Abhyankar 14225f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkGetSupportingEdges 14235f2c45f1SShri Abhyankar @*/ 1424d842c372SHong Zhang PetscErrorCode DMNetworkGetConnectedVertices(DM dm,PetscInt edge,const PetscInt *vertices[]) 14255f2c45f1SShri Abhyankar { 14265f2c45f1SShri Abhyankar PetscErrorCode ierr; 14275f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 14285f2c45f1SShri Abhyankar 14295f2c45f1SShri Abhyankar PetscFunctionBegin; 14305f2c45f1SShri Abhyankar ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr); 14315f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14325f2c45f1SShri Abhyankar } 14335f2c45f1SShri Abhyankar 14345f2c45f1SShri Abhyankar /*@ 14355f2c45f1SShri Abhyankar DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex 14365f2c45f1SShri Abhyankar 14375f2c45f1SShri Abhyankar Not Collective 14385f2c45f1SShri Abhyankar 14395f2c45f1SShri Abhyankar Input Parameters: 14405f2c45f1SShri Abhyankar + dm - The DMNetwork object 1441a2b725a8SWilliam Gropp - p - the vertex point 14425f2c45f1SShri Abhyankar 14435f2c45f1SShri Abhyankar Output Parameter: 14445f2c45f1SShri Abhyankar . isghost - TRUE if the vertex is a ghost point 14455f2c45f1SShri Abhyankar 144697bb938eSShri Abhyankar Level: beginner 14475f2c45f1SShri Abhyankar 1448d842c372SHong Zhang .seealso: DMNetworkCreate, DMNetworkGetConnectedVertices, DMNetworkGetVertexRange 14495f2c45f1SShri Abhyankar @*/ 14505f2c45f1SShri Abhyankar PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost) 14515f2c45f1SShri Abhyankar { 14525f2c45f1SShri Abhyankar PetscErrorCode ierr; 14535f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 14545f2c45f1SShri Abhyankar PetscInt offsetg; 14555f2c45f1SShri Abhyankar PetscSection sectiong; 14565f2c45f1SShri Abhyankar 14575f2c45f1SShri Abhyankar PetscFunctionBegin; 1458caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 14595f2c45f1SShri Abhyankar *isghost = PETSC_FALSE; 1460e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§iong);CHKERRQ(ierr); 14615f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr); 14625f2c45f1SShri Abhyankar if (offsetg < 0) *isghost = PETSC_TRUE; 14635f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14645f2c45f1SShri Abhyankar } 14655f2c45f1SShri Abhyankar 14665f2c45f1SShri Abhyankar PetscErrorCode DMSetUp_Network(DM dm) 14675f2c45f1SShri Abhyankar { 14685f2c45f1SShri Abhyankar PetscErrorCode ierr; 14695f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 14705f2c45f1SShri Abhyankar 14715f2c45f1SShri Abhyankar PetscFunctionBegin; 14725f2c45f1SShri Abhyankar ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr); 14735f2c45f1SShri Abhyankar ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr); 14745f2c45f1SShri Abhyankar 147592fd8e1eSJed Brown ierr = DMSetLocalSection(network->plex,network->DofSection);CHKERRQ(ierr); 1476e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr); 14779e1d080bSHong Zhang 14789e1d080bSHong Zhang dm->setupcalled = PETSC_TRUE; 14799e1d080bSHong Zhang ierr = DMViewFromOptions(dm,NULL,"-dm_view");CHKERRQ(ierr); 14805f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14815f2c45f1SShri Abhyankar } 14825f2c45f1SShri Abhyankar 14831ad426b7SHong Zhang /*@ 148417df6e9eSHong Zhang DMNetworkHasJacobian - Sets global flag for using user's sub Jacobian matrices 14851ad426b7SHong Zhang -- replaced by DMNetworkSetOption(network,userjacobian,PETSC_TURE)? 14861ad426b7SHong Zhang 14871ad426b7SHong Zhang Collective 14881ad426b7SHong Zhang 14891ad426b7SHong Zhang Input Parameters: 149083b2e829SHong Zhang + dm - The DMNetwork object 149183b2e829SHong Zhang . eflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for edges 149283b2e829SHong Zhang - vflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for vertices 14931ad426b7SHong Zhang 14941ad426b7SHong Zhang Level: intermediate 14951ad426b7SHong Zhang 14961ad426b7SHong Zhang @*/ 149783b2e829SHong Zhang PetscErrorCode DMNetworkHasJacobian(DM dm,PetscBool eflg,PetscBool vflg) 14981ad426b7SHong Zhang { 14991ad426b7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 15008675203cSHong Zhang PetscErrorCode ierr; 150166b4e0ffSHong Zhang PetscInt nVertices = network->nVertices; 15021ad426b7SHong Zhang 15031ad426b7SHong Zhang PetscFunctionBegin; 150483b2e829SHong Zhang network->userEdgeJacobian = eflg; 150583b2e829SHong Zhang network->userVertexJacobian = vflg; 15068675203cSHong Zhang 15078675203cSHong Zhang if (eflg && !network->Je) { 15088675203cSHong Zhang ierr = PetscCalloc1(3*network->nEdges,&network->Je);CHKERRQ(ierr); 15098675203cSHong Zhang } 15108675203cSHong Zhang 151166b4e0ffSHong Zhang if (vflg && !network->Jv && nVertices) { 15128675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 151366b4e0ffSHong Zhang PetscInt nedges_total; 15148675203cSHong Zhang const PetscInt *edges; 15158675203cSHong Zhang 15168675203cSHong Zhang /* count nvertex_total */ 15178675203cSHong Zhang nedges_total = 0; 15188675203cSHong Zhang ierr = PetscMalloc1(nVertices+1,&vptr);CHKERRQ(ierr); 15198675203cSHong Zhang 15208675203cSHong Zhang vptr[0] = 0; 15218675203cSHong Zhang for (i=0; i<nVertices; i++) { 15228675203cSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,i+vStart,&nedges,&edges);CHKERRQ(ierr); 15238675203cSHong Zhang nedges_total += nedges; 15248675203cSHong Zhang vptr[i+1] = vptr[i] + 2*nedges + 1; 15258675203cSHong Zhang } 15268675203cSHong Zhang 15278675203cSHong Zhang ierr = PetscCalloc1(2*nedges_total+nVertices,&network->Jv);CHKERRQ(ierr); 15288675203cSHong Zhang network->Jvptr = vptr; 15298675203cSHong Zhang } 15301ad426b7SHong Zhang PetscFunctionReturn(0); 15311ad426b7SHong Zhang } 15321ad426b7SHong Zhang 15331ad426b7SHong Zhang /*@ 153483b2e829SHong Zhang DMNetworkEdgeSetMatrix - Sets user-provided Jacobian matrices for this edge to the network 153583b2e829SHong Zhang 153683b2e829SHong Zhang Not Collective 153783b2e829SHong Zhang 153883b2e829SHong Zhang Input Parameters: 153983b2e829SHong Zhang + dm - The DMNetwork object 154083b2e829SHong Zhang . p - the edge point 15413e97b6e8SHong Zhang - J - array (size = 3) of Jacobian submatrices for this edge point: 15423e97b6e8SHong Zhang J[0]: this edge 1543d842c372SHong Zhang J[1] and J[2]: connected vertices, obtained by calling DMNetworkGetConnectedVertices() 154483b2e829SHong Zhang 154597bb938eSShri Abhyankar Level: advanced 154683b2e829SHong Zhang 154783b2e829SHong Zhang .seealso: DMNetworkVertexSetMatrix 154883b2e829SHong Zhang @*/ 154983b2e829SHong Zhang PetscErrorCode DMNetworkEdgeSetMatrix(DM dm,PetscInt p,Mat J[]) 155083b2e829SHong Zhang { 155183b2e829SHong Zhang DM_Network *network=(DM_Network*)dm->data; 155283b2e829SHong Zhang 155383b2e829SHong Zhang PetscFunctionBegin; 15548675203cSHong Zhang if (!network->Je) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkEdgeSetMatrix"); 15558675203cSHong Zhang 15568675203cSHong Zhang if (J) { 1557883e35e8SHong Zhang network->Je[3*p] = J[0]; 1558883e35e8SHong Zhang network->Je[3*p+1] = J[1]; 1559883e35e8SHong Zhang network->Je[3*p+2] = J[2]; 15608675203cSHong Zhang } 156183b2e829SHong Zhang PetscFunctionReturn(0); 156283b2e829SHong Zhang } 156383b2e829SHong Zhang 156483b2e829SHong Zhang /*@ 156576ddfea5SHong Zhang DMNetworkVertexSetMatrix - Sets user-provided Jacobian matrix for this vertex to the network 15661ad426b7SHong Zhang 15671ad426b7SHong Zhang Not Collective 15681ad426b7SHong Zhang 15691ad426b7SHong Zhang Input Parameters: 15701ad426b7SHong Zhang + dm - The DMNetwork object 15711ad426b7SHong Zhang . p - the vertex point 15723e97b6e8SHong Zhang - J - array of Jacobian (size = 2*(num of supporting edges) + 1) submatrices for this vertex point: 15733e97b6e8SHong Zhang J[0]: this vertex 15743e97b6e8SHong Zhang J[1+2*i]: i-th supporting edge 15753e97b6e8SHong Zhang J[1+2*i+1]: i-th connected vertex 15761ad426b7SHong Zhang 157797bb938eSShri Abhyankar Level: advanced 15781ad426b7SHong Zhang 157983b2e829SHong Zhang .seealso: DMNetworkEdgeSetMatrix 15801ad426b7SHong Zhang @*/ 1581883e35e8SHong Zhang PetscErrorCode DMNetworkVertexSetMatrix(DM dm,PetscInt p,Mat J[]) 15825f2c45f1SShri Abhyankar { 15835f2c45f1SShri Abhyankar PetscErrorCode ierr; 15845f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 15858675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 1586883e35e8SHong Zhang const PetscInt *edges; 15875f2c45f1SShri Abhyankar 15885f2c45f1SShri Abhyankar PetscFunctionBegin; 15898675203cSHong Zhang if (!network->Jv) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkVertexSetMatrix"); 1590883e35e8SHong Zhang 15918675203cSHong Zhang if (J) { 1592883e35e8SHong Zhang vptr = network->Jvptr; 15933e97b6e8SHong Zhang network->Jv[vptr[p-vStart]] = J[0]; /* Set Jacobian for this vertex */ 15943e97b6e8SHong Zhang 15953e97b6e8SHong Zhang /* Set Jacobian for each supporting edge and connected vertex */ 1596883e35e8SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,p,&nedges,&edges);CHKERRQ(ierr); 1597883e35e8SHong Zhang for (i=1; i<=2*nedges; i++) network->Jv[vptr[p-vStart]+i] = J[i]; 15988675203cSHong Zhang } 1599883e35e8SHong Zhang PetscFunctionReturn(0); 1600883e35e8SHong Zhang } 1601883e35e8SHong Zhang 1602e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 16035cf7da58SHong Zhang { 16045cf7da58SHong Zhang PetscErrorCode ierr; 16055cf7da58SHong Zhang PetscInt j; 16065cf7da58SHong Zhang PetscScalar val=(PetscScalar)ncols; 16075cf7da58SHong Zhang 16085cf7da58SHong Zhang PetscFunctionBegin; 16095cf7da58SHong Zhang if (!ghost) { 16105cf7da58SHong Zhang for (j=0; j<nrows; j++) { 16115cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 16125cf7da58SHong Zhang } 16135cf7da58SHong Zhang } else { 16145cf7da58SHong Zhang for (j=0; j<nrows; j++) { 16155cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 16165cf7da58SHong Zhang } 16175cf7da58SHong Zhang } 16185cf7da58SHong Zhang PetscFunctionReturn(0); 16195cf7da58SHong Zhang } 16205cf7da58SHong Zhang 1621e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 16225cf7da58SHong Zhang { 16235cf7da58SHong Zhang PetscErrorCode ierr; 16245cf7da58SHong Zhang PetscInt j,ncols_u; 16255cf7da58SHong Zhang PetscScalar val; 16265cf7da58SHong Zhang 16275cf7da58SHong Zhang PetscFunctionBegin; 16285cf7da58SHong Zhang if (!ghost) { 16295cf7da58SHong Zhang for (j=0; j<nrows; j++) { 16305cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 16315cf7da58SHong Zhang val = (PetscScalar)ncols_u; 16325cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 16335cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 16345cf7da58SHong Zhang } 16355cf7da58SHong Zhang } else { 16365cf7da58SHong Zhang for (j=0; j<nrows; j++) { 16375cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 16385cf7da58SHong Zhang val = (PetscScalar)ncols_u; 16395cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 16405cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 16415cf7da58SHong Zhang } 16425cf7da58SHong Zhang } 16435cf7da58SHong Zhang PetscFunctionReturn(0); 16445cf7da58SHong Zhang } 16455cf7da58SHong Zhang 1646e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 16475cf7da58SHong Zhang { 16485cf7da58SHong Zhang PetscErrorCode ierr; 16495cf7da58SHong Zhang 16505cf7da58SHong Zhang PetscFunctionBegin; 16515cf7da58SHong Zhang if (Ju) { 16525cf7da58SHong Zhang ierr = MatSetPreallocationUserblock_private(Ju,nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 16535cf7da58SHong Zhang } else { 16545cf7da58SHong Zhang ierr = MatSetPreallocationDenseblock_private(nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 16555cf7da58SHong Zhang } 16565cf7da58SHong Zhang PetscFunctionReturn(0); 16575cf7da58SHong Zhang } 16585cf7da58SHong Zhang 1659e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 1660883e35e8SHong Zhang { 1661883e35e8SHong Zhang PetscErrorCode ierr; 1662883e35e8SHong Zhang PetscInt j,*cols; 1663883e35e8SHong Zhang PetscScalar *zeros; 1664883e35e8SHong Zhang 1665883e35e8SHong Zhang PetscFunctionBegin; 1666883e35e8SHong Zhang ierr = PetscCalloc2(ncols,&cols,nrows*ncols,&zeros);CHKERRQ(ierr); 1667883e35e8SHong Zhang for (j=0; j<ncols; j++) cols[j] = j+ cstart; 1668883e35e8SHong Zhang ierr = MatSetValues(*J,nrows,rows,ncols,cols,zeros,INSERT_VALUES);CHKERRQ(ierr); 1669883e35e8SHong Zhang ierr = PetscFree2(cols,zeros);CHKERRQ(ierr); 16701ad426b7SHong Zhang PetscFunctionReturn(0); 16711ad426b7SHong Zhang } 1672a4e85ca8SHong Zhang 1673e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 16743e97b6e8SHong Zhang { 16753e97b6e8SHong Zhang PetscErrorCode ierr; 16763e97b6e8SHong Zhang PetscInt j,M,N,row,col,ncols_u; 16773e97b6e8SHong Zhang const PetscInt *cols; 16783e97b6e8SHong Zhang PetscScalar zero=0.0; 16793e97b6e8SHong Zhang 16803e97b6e8SHong Zhang PetscFunctionBegin; 16813e97b6e8SHong Zhang ierr = MatGetSize(Ju,&M,&N);CHKERRQ(ierr); 16823e97b6e8SHong 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); 16833e97b6e8SHong Zhang 16843e97b6e8SHong Zhang for (row=0; row<nrows; row++) { 16853e97b6e8SHong Zhang ierr = MatGetRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 16863e97b6e8SHong Zhang for (j=0; j<ncols_u; j++) { 16873e97b6e8SHong Zhang col = cols[j] + cstart; 16883e97b6e8SHong Zhang ierr = MatSetValues(*J,1,&rows[row],1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr); 16893e97b6e8SHong Zhang } 16903e97b6e8SHong Zhang ierr = MatRestoreRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 16913e97b6e8SHong Zhang } 16923e97b6e8SHong Zhang PetscFunctionReturn(0); 16933e97b6e8SHong Zhang } 16941ad426b7SHong Zhang 1695e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 1696a4e85ca8SHong Zhang { 1697a4e85ca8SHong Zhang PetscErrorCode ierr; 1698f4431b8cSHong Zhang 1699a4e85ca8SHong Zhang PetscFunctionBegin; 1700a4e85ca8SHong Zhang if (Ju) { 1701a4e85ca8SHong Zhang ierr = MatSetUserblock_private(Ju,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 1702a4e85ca8SHong Zhang } else { 1703a4e85ca8SHong Zhang ierr = MatSetDenseblock_private(nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 1704a4e85ca8SHong Zhang } 1705a4e85ca8SHong Zhang PetscFunctionReturn(0); 1706a4e85ca8SHong Zhang } 1707a4e85ca8SHong Zhang 170824121865SAdrian Maldonado /* 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. 170924121865SAdrian Maldonado */ 171024121865SAdrian Maldonado PetscErrorCode CreateSubGlobalToLocalMapping_private(PetscSection globalsec, PetscSection localsec, ISLocalToGlobalMapping *ltog) 171124121865SAdrian Maldonado { 171224121865SAdrian Maldonado PetscErrorCode ierr; 171324121865SAdrian Maldonado PetscInt i,size,dof; 171424121865SAdrian Maldonado PetscInt *glob2loc; 171524121865SAdrian Maldonado 171624121865SAdrian Maldonado PetscFunctionBegin; 171724121865SAdrian Maldonado ierr = PetscSectionGetStorageSize(localsec,&size);CHKERRQ(ierr); 171824121865SAdrian Maldonado ierr = PetscMalloc1(size,&glob2loc);CHKERRQ(ierr); 171924121865SAdrian Maldonado 172024121865SAdrian Maldonado for (i = 0; i < size; i++) { 172124121865SAdrian Maldonado ierr = PetscSectionGetOffset(globalsec,i,&dof);CHKERRQ(ierr); 172224121865SAdrian Maldonado dof = (dof >= 0) ? dof : -(dof + 1); 172324121865SAdrian Maldonado glob2loc[i] = dof; 172424121865SAdrian Maldonado } 172524121865SAdrian Maldonado 172624121865SAdrian Maldonado ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,size,glob2loc,PETSC_OWN_POINTER,ltog);CHKERRQ(ierr); 172724121865SAdrian Maldonado #if 0 172824121865SAdrian Maldonado ierr = PetscIntView(size,glob2loc,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 172924121865SAdrian Maldonado #endif 173024121865SAdrian Maldonado PetscFunctionReturn(0); 173124121865SAdrian Maldonado } 173224121865SAdrian Maldonado 173301ad2aeeSHong Zhang #include <petsc/private/matimpl.h> 17349e1d080bSHong Zhang 17359e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network_Nest(DM dm,Mat *J) 17361ad426b7SHong Zhang { 17371ad426b7SHong Zhang PetscErrorCode ierr; 17381ad426b7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 17399e1d080bSHong Zhang PetscMPIInt rank, size; 174024121865SAdrian Maldonado PetscInt eDof,vDof; 174124121865SAdrian Maldonado Mat j11,j12,j21,j22,bA[2][2]; 17429e1d080bSHong Zhang MPI_Comm comm; 174324121865SAdrian Maldonado ISLocalToGlobalMapping eISMap,vISMap; 174424121865SAdrian Maldonado 17459e1d080bSHong Zhang PetscFunctionBegin; 174624121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 1747*ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 1748*ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 174924121865SAdrian Maldonado 175024121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->edge.GlobalDofSection,&eDof);CHKERRQ(ierr); 175124121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->vertex.GlobalDofSection,&vDof);CHKERRQ(ierr); 175224121865SAdrian Maldonado 175301ad2aeeSHong Zhang ierr = MatCreate(comm, &j11);CHKERRQ(ierr); 175424121865SAdrian Maldonado ierr = MatSetSizes(j11, eDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 175524121865SAdrian Maldonado ierr = MatSetType(j11, MATMPIAIJ);CHKERRQ(ierr); 175624121865SAdrian Maldonado 175701ad2aeeSHong Zhang ierr = MatCreate(comm, &j12);CHKERRQ(ierr); 175824121865SAdrian Maldonado ierr = MatSetSizes(j12, eDof, vDof, PETSC_DETERMINE ,PETSC_DETERMINE);CHKERRQ(ierr); 175924121865SAdrian Maldonado ierr = MatSetType(j12, MATMPIAIJ);CHKERRQ(ierr); 176024121865SAdrian Maldonado 176101ad2aeeSHong Zhang ierr = MatCreate(comm, &j21);CHKERRQ(ierr); 176224121865SAdrian Maldonado ierr = MatSetSizes(j21, vDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 176324121865SAdrian Maldonado ierr = MatSetType(j21, MATMPIAIJ);CHKERRQ(ierr); 176424121865SAdrian Maldonado 176501ad2aeeSHong Zhang ierr = MatCreate(comm, &j22);CHKERRQ(ierr); 176624121865SAdrian Maldonado ierr = MatSetSizes(j22, vDof, vDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 176724121865SAdrian Maldonado ierr = MatSetType(j22, MATMPIAIJ);CHKERRQ(ierr); 176824121865SAdrian Maldonado 17693f6a6bdaSHong Zhang bA[0][0] = j11; 17703f6a6bdaSHong Zhang bA[0][1] = j12; 17713f6a6bdaSHong Zhang bA[1][0] = j21; 17723f6a6bdaSHong Zhang bA[1][1] = j22; 177324121865SAdrian Maldonado 177424121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->edge.GlobalDofSection,network->edge.DofSection,&eISMap);CHKERRQ(ierr); 177524121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->vertex.GlobalDofSection,network->vertex.DofSection,&vISMap);CHKERRQ(ierr); 177624121865SAdrian Maldonado 177724121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j11,eISMap,eISMap);CHKERRQ(ierr); 177824121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j12,eISMap,vISMap);CHKERRQ(ierr); 177924121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j21,vISMap,eISMap);CHKERRQ(ierr); 178024121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j22,vISMap,vISMap);CHKERRQ(ierr); 178124121865SAdrian Maldonado 178224121865SAdrian Maldonado ierr = MatSetUp(j11);CHKERRQ(ierr); 178324121865SAdrian Maldonado ierr = MatSetUp(j12);CHKERRQ(ierr); 178424121865SAdrian Maldonado ierr = MatSetUp(j21);CHKERRQ(ierr); 178524121865SAdrian Maldonado ierr = MatSetUp(j22);CHKERRQ(ierr); 178624121865SAdrian Maldonado 178701ad2aeeSHong Zhang ierr = MatCreateNest(comm,2,NULL,2,NULL,&bA[0][0],J);CHKERRQ(ierr); 178824121865SAdrian Maldonado ierr = MatSetUp(*J);CHKERRQ(ierr); 178924121865SAdrian Maldonado ierr = MatNestSetVecType(*J,VECNEST);CHKERRQ(ierr); 179024121865SAdrian Maldonado ierr = MatDestroy(&j11);CHKERRQ(ierr); 179124121865SAdrian Maldonado ierr = MatDestroy(&j12);CHKERRQ(ierr); 179224121865SAdrian Maldonado ierr = MatDestroy(&j21);CHKERRQ(ierr); 179324121865SAdrian Maldonado ierr = MatDestroy(&j22);CHKERRQ(ierr); 179424121865SAdrian Maldonado 179524121865SAdrian Maldonado ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 179624121865SAdrian Maldonado ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17979e1d080bSHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 179824121865SAdrian Maldonado 179924121865SAdrian Maldonado /* Free structures */ 180024121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&eISMap);CHKERRQ(ierr); 180124121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&vISMap);CHKERRQ(ierr); 180224121865SAdrian Maldonado PetscFunctionReturn(0); 18039e1d080bSHong Zhang } 18049e1d080bSHong Zhang 18059e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J) 18069e1d080bSHong Zhang { 18079e1d080bSHong Zhang PetscErrorCode ierr; 18089e1d080bSHong Zhang DM_Network *network = (DM_Network*)dm->data; 18099e1d080bSHong Zhang PetscInt eStart,eEnd,vStart,vEnd,rstart,nrows,*rows,localSize; 18109e1d080bSHong Zhang PetscInt cstart,ncols,j,e,v; 18119e1d080bSHong Zhang PetscBool ghost,ghost_vc,ghost2,isNest; 18129e1d080bSHong Zhang Mat Juser; 18139e1d080bSHong Zhang PetscSection sectionGlobal; 18149e1d080bSHong Zhang PetscInt nedges,*vptr=NULL,vc,*rows_v; /* suppress maybe-uninitialized warning */ 18159e1d080bSHong Zhang const PetscInt *edges,*cone; 18169e1d080bSHong Zhang MPI_Comm comm; 18179e1d080bSHong Zhang MatType mtype; 18189e1d080bSHong Zhang Vec vd_nz,vo_nz; 18199e1d080bSHong Zhang PetscInt *dnnz,*onnz; 18209e1d080bSHong Zhang PetscScalar *vdnz,*vonz; 18219e1d080bSHong Zhang 18229e1d080bSHong Zhang PetscFunctionBegin; 18239e1d080bSHong Zhang mtype = dm->mattype; 18249e1d080bSHong Zhang ierr = PetscStrcmp(mtype,MATNEST,&isNest);CHKERRQ(ierr); 18259e1d080bSHong Zhang if (isNest) { 18269e1d080bSHong Zhang ierr = DMCreateMatrix_Network_Nest(dm,J);CHKERRQ(ierr); 1827c6b011d8SStefano Zampini ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 18289e1d080bSHong Zhang PetscFunctionReturn(0); 18299e1d080bSHong Zhang } 18309e1d080bSHong Zhang 18319e1d080bSHong Zhang if (!network->userEdgeJacobian && !network->userVertexJacobian) { 1832a4e85ca8SHong Zhang /* user does not provide Jacobian blocks */ 18339e1d080bSHong Zhang ierr = DMCreateMatrix_Plex(network->plex,J);CHKERRQ(ierr); 1834bfbc38dcSHong Zhang ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 18351ad426b7SHong Zhang PetscFunctionReturn(0); 18361ad426b7SHong Zhang } 18371ad426b7SHong Zhang 1838bfbc38dcSHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)dm),J);CHKERRQ(ierr); 1839e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§ionGlobal);CHKERRQ(ierr); 1840bfbc38dcSHong Zhang ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal,&localSize);CHKERRQ(ierr); 1841bfbc38dcSHong Zhang ierr = MatSetSizes(*J,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 18422a945128SHong Zhang 18432a945128SHong Zhang ierr = MatSetType(*J,MATAIJ);CHKERRQ(ierr); 18442a945128SHong Zhang ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 184589898e50SHong Zhang 184689898e50SHong Zhang /* (1) Set matrix preallocation */ 184789898e50SHong Zhang /*------------------------------*/ 1848840c2264SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 1849840c2264SHong Zhang ierr = VecCreate(comm,&vd_nz);CHKERRQ(ierr); 1850840c2264SHong Zhang ierr = VecSetSizes(vd_nz,localSize,PETSC_DECIDE);CHKERRQ(ierr); 1851840c2264SHong Zhang ierr = VecSetFromOptions(vd_nz);CHKERRQ(ierr); 1852840c2264SHong Zhang ierr = VecSet(vd_nz,0.0);CHKERRQ(ierr); 1853840c2264SHong Zhang ierr = VecDuplicate(vd_nz,&vo_nz);CHKERRQ(ierr); 1854840c2264SHong Zhang 185589898e50SHong Zhang /* Set preallocation for edges */ 185689898e50SHong Zhang /*-----------------------------*/ 1857840c2264SHong Zhang ierr = DMNetworkGetEdgeRange(dm,&eStart,&eEnd);CHKERRQ(ierr); 1858840c2264SHong Zhang 1859bdcb62a2SHong Zhang ierr = PetscMalloc1(localSize,&rows);CHKERRQ(ierr); 1860840c2264SHong Zhang for (e=eStart; e<eEnd; e++) { 1861840c2264SHong Zhang /* Get row indices */ 1862840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr); 1863840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr); 1864840c2264SHong Zhang if (nrows) { 1865840c2264SHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 1866840c2264SHong Zhang 18675cf7da58SHong Zhang /* Set preallocation for conntected vertices */ 1868d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 1869840c2264SHong Zhang for (v=0; v<2; v++) { 1870840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr); 1871840c2264SHong Zhang 18728675203cSHong Zhang if (network->Je) { 1873840c2264SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 18748675203cSHong Zhang } else Juser = NULL; 1875840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,cone[v],&ghost);CHKERRQ(ierr); 18765cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 1877840c2264SHong Zhang } 1878840c2264SHong Zhang 187989898e50SHong Zhang /* Set preallocation for edge self */ 1880840c2264SHong Zhang cstart = rstart; 18818675203cSHong Zhang if (network->Je) { 1882840c2264SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 18838675203cSHong Zhang } else Juser = NULL; 18845cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 1885840c2264SHong Zhang } 1886840c2264SHong Zhang } 1887840c2264SHong Zhang 188889898e50SHong Zhang /* Set preallocation for vertices */ 188989898e50SHong Zhang /*--------------------------------*/ 1890840c2264SHong Zhang ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 18918675203cSHong Zhang if (vEnd - vStart) vptr = network->Jvptr; 1892840c2264SHong Zhang 1893840c2264SHong Zhang for (v=vStart; v<vEnd; v++) { 1894840c2264SHong Zhang /* Get row indices */ 1895840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr); 1896840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr); 1897840c2264SHong Zhang if (!nrows) continue; 1898840c2264SHong Zhang 1899bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 1900bdcb62a2SHong Zhang if (ghost) { 1901bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 1902bdcb62a2SHong Zhang } else { 1903bdcb62a2SHong Zhang rows_v = rows; 1904bdcb62a2SHong Zhang } 1905bdcb62a2SHong Zhang 1906bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 1907840c2264SHong Zhang 1908840c2264SHong Zhang /* Get supporting edges and connected vertices */ 1909840c2264SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 1910840c2264SHong Zhang 1911840c2264SHong Zhang for (e=0; e<nedges; e++) { 1912840c2264SHong Zhang /* Supporting edges */ 1913840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr); 1914840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr); 1915840c2264SHong Zhang 19168675203cSHong Zhang if (network->Jv) { 1917840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 19188675203cSHong Zhang } else Juser = NULL; 1919bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 1920840c2264SHong Zhang 1921840c2264SHong Zhang /* Connected vertices */ 1922d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 1923840c2264SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 1924840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,vc,&ghost_vc);CHKERRQ(ierr); 1925840c2264SHong Zhang 1926840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr); 1927840c2264SHong Zhang 19288675203cSHong Zhang if (network->Jv) { 1929840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 19308675203cSHong Zhang } else Juser = NULL; 1931e102a522SHong Zhang if (ghost_vc||ghost) { 1932e102a522SHong Zhang ghost2 = PETSC_TRUE; 1933e102a522SHong Zhang } else { 1934e102a522SHong Zhang ghost2 = PETSC_FALSE; 1935e102a522SHong Zhang } 1936e102a522SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost2,vd_nz,vo_nz);CHKERRQ(ierr); 1937840c2264SHong Zhang } 1938840c2264SHong Zhang 193989898e50SHong Zhang /* Set preallocation for vertex self */ 1940840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 1941840c2264SHong Zhang if (!ghost) { 1942840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr); 19438675203cSHong Zhang if (network->Jv) { 1944840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 19458675203cSHong Zhang } else Juser = NULL; 1946bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 1947840c2264SHong Zhang } 1948bdcb62a2SHong Zhang if (ghost) { 1949bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 1950bdcb62a2SHong Zhang } 1951840c2264SHong Zhang } 1952840c2264SHong Zhang 1953840c2264SHong Zhang ierr = VecAssemblyBegin(vd_nz);CHKERRQ(ierr); 1954840c2264SHong Zhang ierr = VecAssemblyBegin(vo_nz);CHKERRQ(ierr); 19555cf7da58SHong Zhang 19565cf7da58SHong Zhang ierr = PetscMalloc2(localSize,&dnnz,localSize,&onnz);CHKERRQ(ierr); 19575cf7da58SHong Zhang 19585cf7da58SHong Zhang ierr = VecAssemblyEnd(vd_nz);CHKERRQ(ierr); 1959840c2264SHong Zhang ierr = VecAssemblyEnd(vo_nz);CHKERRQ(ierr); 1960840c2264SHong Zhang 1961840c2264SHong Zhang ierr = VecGetArray(vd_nz,&vdnz);CHKERRQ(ierr); 1962840c2264SHong Zhang ierr = VecGetArray(vo_nz,&vonz);CHKERRQ(ierr); 1963840c2264SHong Zhang for (j=0; j<localSize; j++) { 1964e102a522SHong Zhang dnnz[j] = (PetscInt)PetscRealPart(vdnz[j]); 1965e102a522SHong Zhang onnz[j] = (PetscInt)PetscRealPart(vonz[j]); 1966840c2264SHong Zhang } 1967840c2264SHong Zhang ierr = VecRestoreArray(vd_nz,&vdnz);CHKERRQ(ierr); 1968840c2264SHong Zhang ierr = VecRestoreArray(vo_nz,&vonz);CHKERRQ(ierr); 1969840c2264SHong Zhang ierr = VecDestroy(&vd_nz);CHKERRQ(ierr); 1970840c2264SHong Zhang ierr = VecDestroy(&vo_nz);CHKERRQ(ierr); 1971840c2264SHong Zhang 19725cf7da58SHong Zhang ierr = MatSeqAIJSetPreallocation(*J,0,dnnz);CHKERRQ(ierr); 19735cf7da58SHong Zhang ierr = MatMPIAIJSetPreallocation(*J,0,dnnz,0,onnz);CHKERRQ(ierr); 19745cf7da58SHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 19755cf7da58SHong Zhang 19765cf7da58SHong Zhang ierr = PetscFree2(dnnz,onnz);CHKERRQ(ierr); 19775cf7da58SHong Zhang 197889898e50SHong Zhang /* (2) Set matrix entries for edges */ 197989898e50SHong Zhang /*----------------------------------*/ 19801ad426b7SHong Zhang for (e=eStart; e<eEnd; e++) { 1981bfbc38dcSHong Zhang /* Get row indices */ 19821ad426b7SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr); 198317df6e9eSHong Zhang ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr); 19844b976069SHong Zhang if (nrows) { 198517df6e9eSHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 19861ad426b7SHong Zhang 1987bfbc38dcSHong Zhang /* Set matrix entries for conntected vertices */ 1988d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 1989bfbc38dcSHong Zhang for (v=0; v<2; v++) { 1990bfbc38dcSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,cone[v],&cstart);CHKERRQ(ierr); 1991883e35e8SHong Zhang ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr); 19923e97b6e8SHong Zhang 19938675203cSHong Zhang if (network->Je) { 1994a4e85ca8SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 19958675203cSHong Zhang } else Juser = NULL; 1996a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 1997bfbc38dcSHong Zhang } 199817df6e9eSHong Zhang 1999bfbc38dcSHong Zhang /* Set matrix entries for edge self */ 20003e97b6e8SHong Zhang cstart = rstart; 20018675203cSHong Zhang if (network->Je) { 2002a4e85ca8SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 20038675203cSHong Zhang } else Juser = NULL; 2004a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,nrows,cstart,J);CHKERRQ(ierr); 20051ad426b7SHong Zhang } 20064b976069SHong Zhang } 20071ad426b7SHong Zhang 2008bfbc38dcSHong Zhang /* Set matrix entries for vertices */ 200983b2e829SHong Zhang /*---------------------------------*/ 20101ad426b7SHong Zhang for (v=vStart; v<vEnd; v++) { 2011bfbc38dcSHong Zhang /* Get row indices */ 2012596e729fSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr); 2013596e729fSHong Zhang ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr); 20144b976069SHong Zhang if (!nrows) continue; 2015596e729fSHong Zhang 2016bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 2017bdcb62a2SHong Zhang if (ghost) { 2018bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 2019bdcb62a2SHong Zhang } else { 2020bdcb62a2SHong Zhang rows_v = rows; 2021bdcb62a2SHong Zhang } 2022bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 2023596e729fSHong Zhang 2024bfbc38dcSHong Zhang /* Get supporting edges and connected vertices */ 2025596e729fSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 2026596e729fSHong Zhang 2027596e729fSHong Zhang for (e=0; e<nedges; e++) { 2028bfbc38dcSHong Zhang /* Supporting edges */ 2029596e729fSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr); 2030596e729fSHong Zhang ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr); 2031596e729fSHong Zhang 20328675203cSHong Zhang if (network->Jv) { 2033a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 20348675203cSHong Zhang } else Juser = NULL; 2035bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 2036596e729fSHong Zhang 2037bfbc38dcSHong Zhang /* Connected vertices */ 2038d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 20392a945128SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 20402a945128SHong Zhang 204144aca652SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,vc,&cstart);CHKERRQ(ierr); 204244aca652SHong Zhang ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr); 2043a4e85ca8SHong Zhang 20448675203cSHong Zhang if (network->Jv) { 2045a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 20468675203cSHong Zhang } else Juser = NULL; 2047bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 2048596e729fSHong Zhang } 2049596e729fSHong Zhang 2050bfbc38dcSHong Zhang /* Set matrix entries for vertex self */ 20511ad426b7SHong Zhang if (!ghost) { 2052596e729fSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr); 20538675203cSHong Zhang if (network->Jv) { 2054a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 20558675203cSHong Zhang } else Juser = NULL; 2056bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,nrows,cstart,J);CHKERRQ(ierr); 2057bdcb62a2SHong Zhang } 2058bdcb62a2SHong Zhang if (ghost) { 2059bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 2060bdcb62a2SHong Zhang } 20611ad426b7SHong Zhang } 2062a4e85ca8SHong Zhang ierr = PetscFree(rows);CHKERRQ(ierr); 2063bdcb62a2SHong Zhang 20641ad426b7SHong Zhang ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20651ad426b7SHong Zhang ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2066dd6f46cdSHong Zhang 20675f2c45f1SShri Abhyankar ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 20685f2c45f1SShri Abhyankar PetscFunctionReturn(0); 20695f2c45f1SShri Abhyankar } 20705f2c45f1SShri Abhyankar 20715f2c45f1SShri Abhyankar PetscErrorCode DMDestroy_Network(DM dm) 20725f2c45f1SShri Abhyankar { 20735f2c45f1SShri Abhyankar PetscErrorCode ierr; 20745f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 20752727e31bSShri Abhyankar PetscInt j; 20765f2c45f1SShri Abhyankar 20775f2c45f1SShri Abhyankar PetscFunctionBegin; 20788415c774SShri Abhyankar if (--network->refct > 0) PetscFunctionReturn(0); 207983b2e829SHong Zhang if (network->Je) { 208083b2e829SHong Zhang ierr = PetscFree(network->Je);CHKERRQ(ierr); 208183b2e829SHong Zhang } 208283b2e829SHong Zhang if (network->Jv) { 2083883e35e8SHong Zhang ierr = PetscFree(network->Jvptr);CHKERRQ(ierr); 208483b2e829SHong Zhang ierr = PetscFree(network->Jv);CHKERRQ(ierr); 20851ad426b7SHong Zhang } 208613c2a604SAdrian Maldonado 208713c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->vertex.mapping);CHKERRQ(ierr); 208813c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.DofSection);CHKERRQ(ierr); 208913c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.GlobalDofSection);CHKERRQ(ierr); 2090f5427c60SHong Zhang if (network->vltog) { 2091f5427c60SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 2092f5427c60SHong Zhang } 209313c2a604SAdrian Maldonado if (network->vertex.sf) { 209413c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->vertex.sf);CHKERRQ(ierr); 209513c2a604SAdrian Maldonado } 209613c2a604SAdrian Maldonado /* edge */ 209713c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->edge.mapping);CHKERRQ(ierr); 209813c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.DofSection);CHKERRQ(ierr); 209913c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.GlobalDofSection);CHKERRQ(ierr); 210013c2a604SAdrian Maldonado if (network->edge.sf) { 210113c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->edge.sf);CHKERRQ(ierr); 210213c2a604SAdrian Maldonado } 21035f2c45f1SShri Abhyankar ierr = DMDestroy(&network->plex);CHKERRQ(ierr); 21045f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr); 21055f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr); 210683b2e829SHong Zhang 21072727e31bSShri Abhyankar for (j=0; j<network->nsubnet; j++) { 21082727e31bSShri Abhyankar ierr = PetscFree(network->subnet[j].edges);CHKERRQ(ierr); 21092727e31bSShri Abhyankar } 2110caf410d2SHong Zhang ierr = PetscFree(network->subnetvtx);CHKERRQ(ierr); 2111caf410d2SHong Zhang 2112e2aaf10cSShri Abhyankar ierr = PetscFree(network->subnet);CHKERRQ(ierr); 21135f2c45f1SShri Abhyankar ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr); 2114caf410d2SHong Zhang ierr = PetscFree2(network->header,network->cvalue);CHKERRQ(ierr); 21155f2c45f1SShri Abhyankar ierr = PetscFree(network);CHKERRQ(ierr); 21165f2c45f1SShri Abhyankar PetscFunctionReturn(0); 21175f2c45f1SShri Abhyankar } 21185f2c45f1SShri Abhyankar 21195f2c45f1SShri Abhyankar PetscErrorCode DMView_Network(DM dm,PetscViewer viewer) 21205f2c45f1SShri Abhyankar { 21215f2c45f1SShri Abhyankar PetscErrorCode ierr; 21225f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 2123caf410d2SHong Zhang PetscBool iascii; 2124caf410d2SHong Zhang PetscMPIInt rank; 2125caf410d2SHong Zhang PetscInt p,nsubnet; 21265f2c45f1SShri Abhyankar 21275f2c45f1SShri Abhyankar PetscFunctionBegin; 2128caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 2129*ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRMPI(ierr); 2130caf410d2SHong Zhang PetscValidHeaderSpecific(dm,DM_CLASSID, 1); 2131caf410d2SHong Zhang PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2132caf410d2SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 2133caf410d2SHong Zhang if (iascii) { 2134caf410d2SHong Zhang const PetscInt *cone,*vtx,*edges; 2135caf410d2SHong Zhang PetscInt vfrom,vto,i,j,nv,ne; 2136caf410d2SHong Zhang 2137caf410d2SHong Zhang nsubnet = network->nsubnet - network->ncsubnet; /* num of subnetworks */ 2138caf410d2SHong Zhang ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 2139caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " [%d] nsubnet: %D; nsubnetCouple: %D; nEdges: %D; nVertices: %D\n",rank,nsubnet,network->ncsubnet,network->nEdges,network->nVertices);CHKERRQ(ierr); 2140caf410d2SHong Zhang 2141caf410d2SHong Zhang for (i=0; i<nsubnet; i++) { 2142caf410d2SHong Zhang ierr = DMNetworkGetSubnetworkInfo(dm,i,&nv,&ne,&vtx,&edges);CHKERRQ(ierr); 2143caf410d2SHong Zhang if (ne) { 2144caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " Subnet %D: nEdges %D, nVertices %D\n",i,ne,nv);CHKERRQ(ierr); 2145caf410d2SHong Zhang for (j=0; j<ne; j++) { 2146caf410d2SHong Zhang p = edges[j]; 2147caf410d2SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,p,&cone);CHKERRQ(ierr); 2148caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[0],&vfrom);CHKERRQ(ierr); 2149caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[1],&vto);CHKERRQ(ierr); 2150caf410d2SHong Zhang ierr = DMNetworkGetGlobalEdgeIndex(dm,edges[j],&p);CHKERRQ(ierr); 2151caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " edge %D: %D----> %D\n",p,vfrom,vto);CHKERRQ(ierr); 2152caf410d2SHong Zhang } 2153caf410d2SHong Zhang } 2154caf410d2SHong Zhang } 2155caf410d2SHong Zhang /* Coupling subnets */ 2156caf410d2SHong Zhang nsubnet = network->nsubnet; 2157caf410d2SHong Zhang for (; i<nsubnet; i++) { 2158caf410d2SHong Zhang ierr = DMNetworkGetSubnetworkInfo(dm,i,&nv,&ne,&vtx,&edges);CHKERRQ(ierr); 2159caf410d2SHong Zhang if (ne) { 2160caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " Subnet %D (couple): nEdges %D, nVertices %D\n",i,ne,nv);CHKERRQ(ierr); 2161caf410d2SHong Zhang for (j=0; j<ne; j++) { 2162caf410d2SHong Zhang p = edges[j]; 2163caf410d2SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,p,&cone);CHKERRQ(ierr); 2164caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[0],&vfrom);CHKERRQ(ierr); 2165caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[1],&vto);CHKERRQ(ierr); 2166d5c9c0c4SHong Zhang ierr = DMNetworkGetGlobalEdgeIndex(dm,edges[j],&p);CHKERRQ(ierr); 2167caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " edge %D: %D----> %D\n",p,vfrom,vto);CHKERRQ(ierr); 2168caf410d2SHong Zhang } 2169caf410d2SHong Zhang } 2170caf410d2SHong Zhang } 2171caf410d2SHong Zhang ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2172caf410d2SHong Zhang ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 2173caf410d2SHong Zhang } else SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMNetwork writing", ((PetscObject)viewer)->type_name); 21745f2c45f1SShri Abhyankar PetscFunctionReturn(0); 21755f2c45f1SShri Abhyankar } 21765f2c45f1SShri Abhyankar 21775f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l) 21785f2c45f1SShri Abhyankar { 21795f2c45f1SShri Abhyankar PetscErrorCode ierr; 21805f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 21815f2c45f1SShri Abhyankar 21825f2c45f1SShri Abhyankar PetscFunctionBegin; 21835f2c45f1SShri Abhyankar ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr); 21845f2c45f1SShri Abhyankar PetscFunctionReturn(0); 21855f2c45f1SShri Abhyankar } 21865f2c45f1SShri Abhyankar 21875f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l) 21885f2c45f1SShri Abhyankar { 21895f2c45f1SShri Abhyankar PetscErrorCode ierr; 21905f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 21915f2c45f1SShri Abhyankar 21925f2c45f1SShri Abhyankar PetscFunctionBegin; 21935f2c45f1SShri Abhyankar ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr); 21945f2c45f1SShri Abhyankar PetscFunctionReturn(0); 21955f2c45f1SShri Abhyankar } 21965f2c45f1SShri Abhyankar 21975f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g) 21985f2c45f1SShri Abhyankar { 21995f2c45f1SShri Abhyankar PetscErrorCode ierr; 22005f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 22015f2c45f1SShri Abhyankar 22025f2c45f1SShri Abhyankar PetscFunctionBegin; 22035f2c45f1SShri Abhyankar ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr); 22045f2c45f1SShri Abhyankar PetscFunctionReturn(0); 22055f2c45f1SShri Abhyankar } 22065f2c45f1SShri Abhyankar 22075f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g) 22085f2c45f1SShri Abhyankar { 22095f2c45f1SShri Abhyankar PetscErrorCode ierr; 22105f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 22115f2c45f1SShri Abhyankar 22125f2c45f1SShri Abhyankar PetscFunctionBegin; 22135f2c45f1SShri Abhyankar ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr); 22145f2c45f1SShri Abhyankar PetscFunctionReturn(0); 22155f2c45f1SShri Abhyankar } 221622bbedd7SHong Zhang 221722bbedd7SHong Zhang /*@ 221864238763SRodolfo Oliveira DMNetworkGetVertexLocalToGlobalOrdering - Get vertex global index 221922bbedd7SHong Zhang 222022bbedd7SHong Zhang Not collective 222122bbedd7SHong Zhang 22227a7aea1fSJed Brown Input Parameters: 222322bbedd7SHong Zhang + dm - the dm object 222422bbedd7SHong Zhang - vloc - local vertex ordering, start from 0 222522bbedd7SHong Zhang 22267a7aea1fSJed Brown Output Parameters: 2227f0fc11ceSJed Brown . vg - global vertex ordering, start from 0 222822bbedd7SHong Zhang 222997bb938eSShri Abhyankar Level: advanced 223022bbedd7SHong Zhang 223122bbedd7SHong Zhang .seealso: DMNetworkSetVertexLocalToGlobalOrdering() 223222bbedd7SHong Zhang @*/ 223322bbedd7SHong Zhang PetscErrorCode DMNetworkGetVertexLocalToGlobalOrdering(DM dm,PetscInt vloc,PetscInt *vg) 223422bbedd7SHong Zhang { 223522bbedd7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 223622bbedd7SHong Zhang PetscInt *vltog = network->vltog; 223722bbedd7SHong Zhang 223822bbedd7SHong Zhang PetscFunctionBegin; 223922bbedd7SHong Zhang if (!vltog) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkSetVertexLocalToGlobalOrdering() first"); 224022bbedd7SHong Zhang *vg = vltog[vloc]; 224122bbedd7SHong Zhang PetscFunctionReturn(0); 224222bbedd7SHong Zhang } 224322bbedd7SHong Zhang 224422bbedd7SHong Zhang /*@ 224564238763SRodolfo Oliveira DMNetworkSetVertexLocalToGlobalOrdering - Create and setup vertex local to global map 224622bbedd7SHong Zhang 224722bbedd7SHong Zhang Collective 224822bbedd7SHong Zhang 224922bbedd7SHong Zhang Input Parameters: 2250f0fc11ceSJed Brown . dm - the dm object 225122bbedd7SHong Zhang 225297bb938eSShri Abhyankar Level: advanced 225322bbedd7SHong Zhang 225463029d29SHong Zhang .seealso: DMNetworkGetGlobalVertexIndex() 225522bbedd7SHong Zhang @*/ 225622bbedd7SHong Zhang PetscErrorCode DMNetworkSetVertexLocalToGlobalOrdering(DM dm) 225722bbedd7SHong Zhang { 225822bbedd7SHong Zhang PetscErrorCode ierr; 225922bbedd7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 226022bbedd7SHong Zhang MPI_Comm comm; 226163029d29SHong Zhang PetscMPIInt rank,size,*displs,*recvcounts,remoterank; 226222bbedd7SHong Zhang PetscBool ghost; 226363029d29SHong Zhang PetscInt *vltog,nroots,nleaves,i,*vrange,k,N,lidx; 226422bbedd7SHong Zhang const PetscSFNode *iremote; 226522bbedd7SHong Zhang PetscSF vsf; 226663029d29SHong Zhang Vec Vleaves,Vleaves_seq; 226763029d29SHong Zhang VecScatter ctx; 226863029d29SHong Zhang PetscScalar *varr,val; 226963029d29SHong Zhang const PetscScalar *varr_read; 227022bbedd7SHong Zhang 227122bbedd7SHong Zhang PetscFunctionBegin; 227222bbedd7SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 2273*ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 2274*ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 227522bbedd7SHong Zhang 227622bbedd7SHong Zhang if (size == 1) { 227722bbedd7SHong Zhang nroots = network->vEnd - network->vStart; 227822bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 227922bbedd7SHong Zhang for (i=0; i<nroots; i++) vltog[i] = i; 228022bbedd7SHong Zhang network->vltog = vltog; 228122bbedd7SHong Zhang PetscFunctionReturn(0); 228222bbedd7SHong Zhang } 228322bbedd7SHong Zhang 228422bbedd7SHong Zhang if (!network->distributecalled) SETERRQ(comm, PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkDistribute() first"); 228522bbedd7SHong Zhang if (network->vltog) { 228622bbedd7SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 228722bbedd7SHong Zhang } 228822bbedd7SHong Zhang 228922bbedd7SHong Zhang ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 229022bbedd7SHong Zhang ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 229122bbedd7SHong Zhang vsf = network->vertex.sf; 229222bbedd7SHong Zhang 229322bbedd7SHong Zhang ierr = PetscMalloc3(size+1,&vrange,size+1,&displs,size,&recvcounts);CHKERRQ(ierr); 2294f5427c60SHong Zhang ierr = PetscSFGetGraph(vsf,&nroots,&nleaves,NULL,&iremote);CHKERRQ(ierr); 229522bbedd7SHong Zhang 229622bbedd7SHong Zhang for (i=0; i<size; i++) { displs[i] = i; recvcounts[i] = 1;} 229722bbedd7SHong Zhang 229822bbedd7SHong Zhang i = nroots - nleaves; /* local number of vertices, excluding ghosts */ 229922bbedd7SHong Zhang vrange[0] = 0; 2300*ffc4695bSBarry Smith ierr = MPI_Allgatherv(&i,1,MPIU_INT,vrange+1,recvcounts,displs,MPIU_INT,comm);CHKERRMPI(ierr); 230167dd800bSHong Zhang for (i=2; i<size+1; i++) {vrange[i] += vrange[i-1];} 230222bbedd7SHong Zhang 230322bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 230422bbedd7SHong Zhang network->vltog = vltog; 230522bbedd7SHong Zhang 230663029d29SHong Zhang /* Set vltog for non-ghost vertices */ 230763029d29SHong Zhang k = 0; 230822bbedd7SHong Zhang for (i=0; i<nroots; i++) { 230922bbedd7SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 231063029d29SHong Zhang if (ghost) continue; 231163029d29SHong Zhang vltog[i] = vrange[rank] + k++; 231222bbedd7SHong Zhang } 2313f5427c60SHong Zhang ierr = PetscFree3(vrange,displs,recvcounts);CHKERRQ(ierr); 231463029d29SHong Zhang 231563029d29SHong Zhang /* Set vltog for ghost vertices */ 231663029d29SHong Zhang /* (a) create parallel Vleaves and sequential Vleaves_seq to convert local iremote[*].index to global index */ 231763029d29SHong Zhang ierr = VecCreate(comm,&Vleaves);CHKERRQ(ierr); 231863029d29SHong Zhang ierr = VecSetSizes(Vleaves,2*nleaves,PETSC_DETERMINE);CHKERRQ(ierr); 231963029d29SHong Zhang ierr = VecSetFromOptions(Vleaves);CHKERRQ(ierr); 232063029d29SHong Zhang ierr = VecGetArray(Vleaves,&varr);CHKERRQ(ierr); 232163029d29SHong Zhang for (i=0; i<nleaves; i++) { 232263029d29SHong Zhang varr[2*i] = (PetscScalar)(iremote[i].rank); /* rank of remote process */ 232363029d29SHong Zhang varr[2*i+1] = (PetscScalar)(iremote[i].index); /* local index in remote process */ 232463029d29SHong Zhang } 232563029d29SHong Zhang ierr = VecRestoreArray(Vleaves,&varr);CHKERRQ(ierr); 232663029d29SHong Zhang 232763029d29SHong Zhang /* (b) scatter local info to remote processes via VecScatter() */ 232863029d29SHong Zhang ierr = VecScatterCreateToAll(Vleaves,&ctx,&Vleaves_seq);CHKERRQ(ierr); 232963029d29SHong Zhang ierr = VecScatterBegin(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 233063029d29SHong Zhang ierr = VecScatterEnd(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 233163029d29SHong Zhang 233263029d29SHong Zhang /* (c) convert local indices to global indices in parallel vector Vleaves */ 233363029d29SHong Zhang ierr = VecGetSize(Vleaves_seq,&N);CHKERRQ(ierr); 233463029d29SHong Zhang ierr = VecGetArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 233563029d29SHong Zhang for (i=0; i<N; i+=2) { 23362e4cff2eSHong Zhang remoterank = (PetscMPIInt)PetscRealPart(varr_read[i]); 233763029d29SHong Zhang if (remoterank == rank) { 233863029d29SHong Zhang k = i+1; /* row number */ 23392e4cff2eSHong Zhang lidx = (PetscInt)PetscRealPart(varr_read[i+1]); 234063029d29SHong Zhang val = (PetscScalar)vltog[lidx]; /* global index for non-ghost vertex computed above */ 234163029d29SHong Zhang ierr = VecSetValues(Vleaves,1,&k,&val,INSERT_VALUES);CHKERRQ(ierr); 234263029d29SHong Zhang } 234363029d29SHong Zhang } 234463029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 234563029d29SHong Zhang ierr = VecAssemblyBegin(Vleaves);CHKERRQ(ierr); 234663029d29SHong Zhang ierr = VecAssemblyEnd(Vleaves);CHKERRQ(ierr); 234763029d29SHong Zhang 234863029d29SHong Zhang /* (d) Set vltog for ghost vertices by copying local values of Vleaves */ 234963029d29SHong Zhang ierr = VecGetArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 235063029d29SHong Zhang k = 0; 235163029d29SHong Zhang for (i=0; i<nroots; i++) { 235263029d29SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 235363029d29SHong Zhang if (!ghost) continue; 23542e4cff2eSHong Zhang vltog[i] = (PetscInt)PetscRealPart(varr_read[2*k+1]); k++; 235563029d29SHong Zhang } 235663029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 235763029d29SHong Zhang 235863029d29SHong Zhang ierr = VecDestroy(&Vleaves);CHKERRQ(ierr); 235963029d29SHong Zhang ierr = VecDestroy(&Vleaves_seq);CHKERRQ(ierr); 236063029d29SHong Zhang ierr = VecScatterDestroy(&ctx);CHKERRQ(ierr); 236122bbedd7SHong Zhang PetscFunctionReturn(0); 236222bbedd7SHong Zhang } 2363