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 3572c3e9f7SHong Zhang Level: Intermediate 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 641b266c99SBarry Smith Level: intermediate 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 1495f2c45f1SShri Abhyankar Level: intermediate 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 1875f2c45f1SShri Abhyankar 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 1965f2c45f1SShri Abhyankar Level: intermediate 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; 204caf410d2SHong Zhang PetscInt numCorners=2,spacedim=2,dim = 1; /* One dimensional network */ 2053ebf9fb9SHong Zhang PetscReal *vertexcoords=NULL; 206caf410d2SHong Zhang PetscInt i,j,ctr,nsubnet,*eowners,np,*edges,*subnetvtx,vStart; 207caf410d2SHong Zhang PetscInt k,netid,vid, *vidxlTog,*edgelist_couple=NULL; 208caf410d2SHong Zhang const PetscInt *cone; 209caf410d2SHong Zhang MPI_Comm comm; 210caf410d2SHong Zhang PetscMPIInt size,rank; 2116500d4abSHong Zhang 2126500d4abSHong Zhang PetscFunctionBegin; 213caf410d2SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 214caf410d2SHong Zhang ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 215caf410d2SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 2166500d4abSHong Zhang 217caf410d2SHong Zhang /* Create the local edgelist for the network by concatenating local input edgelists of the subnetworks */ 218caf410d2SHong Zhang ierr = PetscCalloc2(numCorners*network->nVertices,&vertexcoords,2*network->nEdges,&edges);CHKERRQ(ierr); 2197765340cSHong Zhang nsubnet = network->nsubnet - network->ncsubnet; 220caf410d2SHong Zhang ctr = 0; 2217765340cSHong Zhang for (i=0; i < nsubnet; i++) { 2226500d4abSHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 223ba38b151SHong Zhang edges[2*ctr] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j]; 224ba38b151SHong Zhang edges[2*ctr+1] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j+1]; 2256500d4abSHong Zhang ctr++; 2266500d4abSHong Zhang } 2276500d4abSHong Zhang } 2287765340cSHong Zhang 229caf410d2SHong Zhang /* Append local coupling edgelists of the subnetworks */ 2307765340cSHong Zhang i = nsubnet; /* netid of coupling subnet */ 2317765340cSHong Zhang nsubnet = network->nsubnet; 2327765340cSHong Zhang while (i < nsubnet) { 233991cf414SHong Zhang edgelist_couple = network->subnet[i].edgelist; 23472c3e9f7SHong Zhang 2356500d4abSHong Zhang k = 0; 2366500d4abSHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 2376500d4abSHong Zhang netid = edgelist_couple[k]; vid = edgelist_couple[k+1]; 238caf410d2SHong Zhang edges[2*ctr] = network->subnet[netid].vStart + vid; k += 2; 2396500d4abSHong Zhang 2406500d4abSHong Zhang netid = edgelist_couple[k]; vid = edgelist_couple[k+1]; 241caf410d2SHong Zhang edges[2*ctr+1] = network->subnet[netid].vStart + vid; k+=2; 2426500d4abSHong Zhang ctr++; 2436500d4abSHong Zhang } 2447765340cSHong Zhang i++; 2457765340cSHong Zhang } 246caf410d2SHong Zhang /* 247caf410d2SHong Zhang if (rank == 0) { 248caf410d2SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF,"[%d] edgelist:\n",rank); 2496500d4abSHong Zhang for(i=0; i < network->nEdges; i++) { 250caf410d2SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF,"[%D %D]",edges[2*i],edges[2*i+1]);CHKERRQ(ierr); 2516500d4abSHong Zhang printf("\n"); 2526500d4abSHong Zhang } 253caf410d2SHong Zhang } 254caf410d2SHong Zhang */ 2556500d4abSHong Zhang 256caf410d2SHong Zhang /* Create network->plex */ 257acdb140fSBarry Smith #if defined(PETSC_USE_64BIT_INDICES) 258acdb140fSBarry Smith { 259caf410d2SHong Zhang int *edges64; 260caf410d2SHong Zhang np = network->nEdges*numCorners; 261caf410d2SHong Zhang ierr = PetscMalloc1(np,&edges64);CHKERRQ(ierr); 262caf410d2SHong Zhang for (i=0; i<np; i++) edges64[i] = (int)edges[i]; 263caf410d2SHong Zhang 264caf410d2SHong Zhang if (size == 1) { 265caf410d2SHong Zhang ierr = DMPlexCreateFromCellList(comm,dim,network->nEdges,network->nVertices,numCorners,PETSC_FALSE,(const int*)edges64,spacedim,(const double*)vertexcoords,&network->plex);CHKERRQ(ierr); 266caf410d2SHong Zhang } else { 2673ebf9fb9SHong Zhang ierr = DMPlexCreateFromCellListParallel(comm,dim,network->nEdges,network->nVertices,numCorners,PETSC_FALSE,(const int*)edges64,spacedim,(const PetscReal*)vertexcoords,NULL,&network->plex);CHKERRQ(ierr); 268acdb140fSBarry Smith } 269caf410d2SHong Zhang ierr = PetscFree(edges64);CHKERRQ(ierr); 270acdb140fSBarry Smith } 271acdb140fSBarry Smith #else 272caf410d2SHong Zhang if (size == 1) { 273caf410d2SHong Zhang ierr = DMPlexCreateFromCellList(comm,dim,network->nEdges,network->nVertices,numCorners,PETSC_FALSE,(const int*)edges,spacedim,(const double*)vertexcoords,&network->plex);CHKERRQ(ierr); 274caf410d2SHong Zhang } else { 2753ebf9fb9SHong Zhang ierr = DMPlexCreateFromCellListParallel(comm,dim,network->nEdges,network->nVertices,numCorners,PETSC_FALSE,(const int*)edges,spacedim,(const PetscReal*)vertexcoords,NULL,&network->plex);CHKERRQ(ierr); 2766500d4abSHong Zhang } 277caf410d2SHong Zhang #endif 2786500d4abSHong Zhang 2796500d4abSHong Zhang ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr); 2806500d4abSHong Zhang ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr); 2816500d4abSHong Zhang ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr); 282caf410d2SHong Zhang vStart = network->vStart; 2836500d4abSHong Zhang 284caf410d2SHong Zhang ierr = PetscSectionCreate(comm,&network->DataSection);CHKERRQ(ierr); 285caf410d2SHong Zhang ierr = PetscSectionCreate(comm,&network->DofSection);CHKERRQ(ierr); 2866500d4abSHong Zhang ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr); 2876500d4abSHong Zhang ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr); 2886500d4abSHong Zhang 289caf410d2SHong Zhang network->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 290caf410d2SHong Zhang np = network->pEnd - network->pStart; 291caf410d2SHong Zhang ierr = PetscCalloc2(np,&network->header,np,&network->cvalue);CHKERRQ(ierr); 292caf410d2SHong Zhang 293caf410d2SHong Zhang /* Create vidxlTog: maps local vertex index to global index */ 294caf410d2SHong Zhang np = network->vEnd - vStart; 295caf410d2SHong Zhang ierr = PetscMalloc2(np,&vidxlTog,size+1,&eowners);CHKERRQ(ierr); 296caf410d2SHong Zhang ctr = 0; 297caf410d2SHong Zhang for (i=network->eStart; i<network->eEnd; i++) { 298caf410d2SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,i,&cone);CHKERRQ(ierr); 299caf410d2SHong Zhang vidxlTog[cone[0] - vStart] = edges[2*ctr]; 300caf410d2SHong Zhang vidxlTog[cone[1] - vStart] = edges[2*ctr+1]; 301caf410d2SHong Zhang ctr++; 302caf410d2SHong Zhang } 303caf410d2SHong Zhang ierr = PetscFree2(vertexcoords,edges);CHKERRQ(ierr); 304caf410d2SHong Zhang 3056500d4abSHong Zhang /* Create vertices and edges array for the subnetworks */ 3066500d4abSHong Zhang for (j=0; j < network->nsubnet; j++) { 3076500d4abSHong Zhang ierr = PetscCalloc1(network->subnet[j].nedge,&network->subnet[j].edges);CHKERRQ(ierr); 308caf410d2SHong Zhang 3096500d4abSHong Zhang /* Temporarily setting nvtx and nedge to 0 so we can use them as counters in the below for loop. 3106500d4abSHong Zhang These get updated when the vertices and edges are added. */ 311caf410d2SHong Zhang network->subnet[j].nvtx = 0; 312caf410d2SHong Zhang network->subnet[j].nedge = 0; 3136500d4abSHong Zhang } 314caf410d2SHong Zhang ierr = PetscCalloc1(np,&network->subnetvtx);CHKERRQ(ierr); 3156500d4abSHong Zhang 316caf410d2SHong Zhang 317caf410d2SHong Zhang /* Get edge ownership */ 318caf410d2SHong Zhang np = network->eEnd - network->eStart; 319caf410d2SHong Zhang ierr = MPI_Allgather(&np,1,MPIU_INT,eowners+1,1,MPIU_INT,comm);CHKERRQ(ierr); 320caf410d2SHong Zhang eowners[0] = 0; 321caf410d2SHong Zhang for (i=2; i<=size; i++) eowners[i] += eowners[i-1]; 322caf410d2SHong Zhang 323caf410d2SHong Zhang i = 0; j = 0; 324caf410d2SHong Zhang while (i < np) { /* local edges, including coupling edges */ 325caf410d2SHong Zhang network->header[i].index = i + eowners[rank]; /* Global edge index */ 326caf410d2SHong Zhang 327caf410d2SHong Zhang if (j < network->nsubnet && i < network->subnet[j].eEnd) { 3286500d4abSHong Zhang network->header[i].subnetid = j; /* Subnetwork id */ 3296500d4abSHong Zhang network->subnet[j].edges[network->subnet[j].nedge++] = i; 330caf410d2SHong Zhang 331caf410d2SHong Zhang network->header[i].ndata = 0; 332caf410d2SHong Zhang ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr); 333caf410d2SHong Zhang network->header[i].offset[0] = 0; 334*9988b915SShri Abhyankar network->header[i].offsetvarrel[0] = 0; 335caf410d2SHong Zhang i++; 336caf410d2SHong Zhang } 337caf410d2SHong Zhang if (i >= network->subnet[j].eEnd) j++; 338caf410d2SHong Zhang } 339caf410d2SHong Zhang 340caf410d2SHong Zhang /* Count network->subnet[*].nvtx */ 341caf410d2SHong Zhang for (i=vStart; i<network->vEnd; i++) { /* local vertices, including ghosts */ 342caf410d2SHong Zhang k = vidxlTog[i-vStart]; 343caf410d2SHong Zhang for (j=0; j < network->nsubnet; j++) { 344caf410d2SHong Zhang if (network->subnet[j].vStart <= k && k < network->subnet[j].vEnd) { 345caf410d2SHong Zhang network->subnet[j].nvtx++; 3466500d4abSHong Zhang break; 3476500d4abSHong Zhang } 3486500d4abSHong Zhang } 3496500d4abSHong Zhang } 3506500d4abSHong Zhang 351caf410d2SHong Zhang /* Set network->subnet[*].vertices on array network->subnetvtx */ 352caf410d2SHong Zhang subnetvtx = network->subnetvtx; 3536500d4abSHong Zhang for (j=0; j<network->nsubnet; j++) { 354caf410d2SHong Zhang network->subnet[j].vertices = subnetvtx; 355caf410d2SHong Zhang subnetvtx += network->subnet[j].nvtx; 356caf410d2SHong Zhang network->subnet[j].nvtx = 0; 357caf410d2SHong Zhang } 358caf410d2SHong Zhang 359caf410d2SHong Zhang /* Set vertex array for the subnetworks */ 360caf410d2SHong Zhang for (i=vStart; i<network->vEnd; i++) { /* local vertices, including ghosts */ 361caf410d2SHong Zhang network->header[i].index = vidxlTog[i-vStart]; /* Global vertex index */ 362caf410d2SHong Zhang 363caf410d2SHong Zhang k = vidxlTog[i-vStart]; 364caf410d2SHong Zhang for (j=0; j < network->nsubnet; j++) { 365caf410d2SHong Zhang if (network->subnet[j].vStart <= k && k < network->subnet[j].vEnd) { 3666500d4abSHong Zhang network->header[i].subnetid = j; 3676500d4abSHong Zhang network->subnet[j].vertices[network->subnet[j].nvtx++] = i; 3686500d4abSHong Zhang break; 3696500d4abSHong Zhang } 3706500d4abSHong Zhang } 371caf410d2SHong Zhang 3726500d4abSHong Zhang network->header[i].ndata = 0; 3736500d4abSHong Zhang ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr); 374caf410d2SHong Zhang network->header[i].offset[0] = 0; 375*9988b915SShri Abhyankar network->header[i].offsetvarrel[0] = 0; 3766500d4abSHong Zhang } 3776500d4abSHong Zhang 378caf410d2SHong Zhang ierr = PetscFree2(vidxlTog,eowners);CHKERRQ(ierr); 3795f2c45f1SShri Abhyankar PetscFunctionReturn(0); 3805f2c45f1SShri Abhyankar } 3815f2c45f1SShri Abhyankar 38294ef8ddeSSatish Balay /*@C 3832727e31bSShri Abhyankar DMNetworkGetSubnetworkInfo - Returns the info for the subnetwork 3842727e31bSShri Abhyankar 3852727e31bSShri Abhyankar Input Parameters 386caf410d2SHong Zhang + dm - the DM object 3872727e31bSShri Abhyankar - id - the ID (integer) of the subnetwork 3882727e31bSShri Abhyankar 3892727e31bSShri Abhyankar Output Parameters 3902727e31bSShri Abhyankar + nv - number of vertices (local) 3912727e31bSShri Abhyankar . ne - number of edges (local) 3922727e31bSShri Abhyankar . vtx - local vertices for this subnetwork 393a2b725a8SWilliam Gropp - edge - local edges for this subnetwork 3942727e31bSShri Abhyankar 3952727e31bSShri Abhyankar Notes: 3962727e31bSShri Abhyankar Cannot call this routine before DMNetworkLayoutSetup() 3972727e31bSShri Abhyankar 39806dd6b0eSSatish Balay Level: intermediate 39906dd6b0eSSatish Balay 4002727e31bSShri Abhyankar .seealso: DMNetworkLayoutSetUp, DMNetworkCreate 4012727e31bSShri Abhyankar @*/ 402caf410d2SHong Zhang PetscErrorCode DMNetworkGetSubnetworkInfo(DM dm,PetscInt id,PetscInt *nv, PetscInt *ne,const PetscInt **vtx, const PetscInt **edge) 4032727e31bSShri Abhyankar { 404caf410d2SHong Zhang DM_Network *network = (DM_Network*)dm->data; 4052727e31bSShri Abhyankar 4062727e31bSShri Abhyankar PetscFunctionBegin; 40772c3e9f7SHong 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); 4082727e31bSShri Abhyankar *nv = network->subnet[id].nvtx; 4092727e31bSShri Abhyankar *ne = network->subnet[id].nedge; 4102727e31bSShri Abhyankar *vtx = network->subnet[id].vertices; 4112727e31bSShri Abhyankar *edge = network->subnet[id].edges; 4122727e31bSShri Abhyankar PetscFunctionReturn(0); 4132727e31bSShri Abhyankar } 4142727e31bSShri Abhyankar 4152727e31bSShri Abhyankar /*@C 416caf410d2SHong Zhang DMNetworkGetSubnetworkCoupleInfo - Returns the info for the coupling subnetwork 417caf410d2SHong Zhang 418caf410d2SHong Zhang Input Parameters 419caf410d2SHong Zhang + dm - the DM object 420caf410d2SHong Zhang - id - the ID (integer) of the coupling subnetwork 421caf410d2SHong Zhang 422caf410d2SHong Zhang Output Parameters 423caf410d2SHong Zhang + ne - number of edges (local) 424caf410d2SHong Zhang - edge - local edges for this coupling subnetwork 425caf410d2SHong Zhang 426caf410d2SHong Zhang Notes: 427caf410d2SHong Zhang Cannot call this routine before DMNetworkLayoutSetup() 428caf410d2SHong Zhang 429caf410d2SHong Zhang Level: intermediate 430caf410d2SHong Zhang 431caf410d2SHong Zhang .seealso: DMNetworkGetSubnetworkInfo, DMNetworkLayoutSetUp, DMNetworkCreate 432caf410d2SHong Zhang @*/ 433caf410d2SHong Zhang PetscErrorCode DMNetworkGetSubnetworkCoupleInfo(DM dm,PetscInt id,PetscInt *ne,const PetscInt **edge) 434caf410d2SHong Zhang { 435caf410d2SHong Zhang DM_Network *net = (DM_Network*)dm->data; 43672c3e9f7SHong Zhang PetscInt id1; 437caf410d2SHong Zhang 438caf410d2SHong Zhang PetscFunctionBegin; 43972c3e9f7SHong Zhang if (net->ncsubnet) { 44072c3e9f7SHong 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); 44172c3e9f7SHong Zhang 44272c3e9f7SHong Zhang id1 = id + net->nsubnet - net->ncsubnet; 443caf410d2SHong Zhang *ne = net->subnet[id1].nedge; 444caf410d2SHong Zhang *edge = net->subnet[id1].edges; 44572c3e9f7SHong Zhang } else { 44672c3e9f7SHong Zhang *ne = 0; 44772c3e9f7SHong Zhang *edge = NULL; 44872c3e9f7SHong Zhang } 449caf410d2SHong Zhang PetscFunctionReturn(0); 450caf410d2SHong Zhang } 451caf410d2SHong Zhang 452caf410d2SHong Zhang /*@C 4535f2c45f1SShri Abhyankar DMNetworkRegisterComponent - Registers the network component 4545f2c45f1SShri Abhyankar 455d083f849SBarry Smith Logically collective on dm 4565f2c45f1SShri Abhyankar 4575f2c45f1SShri Abhyankar Input Parameters 4585f2c45f1SShri Abhyankar + dm - the network object 4595f2c45f1SShri Abhyankar . name - the component name 4605f2c45f1SShri Abhyankar - size - the storage size in bytes for this component data 4615f2c45f1SShri Abhyankar 4625f2c45f1SShri Abhyankar Output Parameters 4635f2c45f1SShri Abhyankar . key - an integer key that defines the component 4645f2c45f1SShri Abhyankar 4655f2c45f1SShri Abhyankar Notes 4665f2c45f1SShri Abhyankar This routine should be called by all processors before calling DMNetworkLayoutSetup(). 4675f2c45f1SShri Abhyankar 4685f2c45f1SShri Abhyankar Level: intermediate 4695f2c45f1SShri Abhyankar 4705f2c45f1SShri Abhyankar .seealso: DMNetworkLayoutSetUp, DMNetworkCreate 4715f2c45f1SShri Abhyankar @*/ 472caf410d2SHong Zhang PetscErrorCode DMNetworkRegisterComponent(DM dm,const char *name,size_t size,PetscInt *key) 4735f2c45f1SShri Abhyankar { 4745f2c45f1SShri Abhyankar PetscErrorCode ierr; 4755f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 4765f2c45f1SShri Abhyankar DMNetworkComponent *component=&network->component[network->ncomponent]; 4775f2c45f1SShri Abhyankar PetscBool flg=PETSC_FALSE; 4785f2c45f1SShri Abhyankar PetscInt i; 4795f2c45f1SShri Abhyankar 4805f2c45f1SShri Abhyankar PetscFunctionBegin; 4815f2c45f1SShri Abhyankar for (i=0; i < network->ncomponent; i++) { 4825f2c45f1SShri Abhyankar ierr = PetscStrcmp(component->name,name,&flg);CHKERRQ(ierr); 4835f2c45f1SShri Abhyankar if (flg) { 4845f2c45f1SShri Abhyankar *key = i; 4855f2c45f1SShri Abhyankar PetscFunctionReturn(0); 4865f2c45f1SShri Abhyankar } 4876d64e262SShri Abhyankar } 4886d64e262SShri Abhyankar if(network->ncomponent == MAX_COMPONENTS) { 4896d64e262SShri Abhyankar SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Number of components registered exceeds the max %D",MAX_COMPONENTS); 4905f2c45f1SShri Abhyankar } 4915f2c45f1SShri Abhyankar 4925f2c45f1SShri Abhyankar ierr = PetscStrcpy(component->name,name);CHKERRQ(ierr); 4935f2c45f1SShri Abhyankar component->size = size/sizeof(DMNetworkComponentGenericDataType); 4945f2c45f1SShri Abhyankar *key = network->ncomponent; 4955f2c45f1SShri Abhyankar network->ncomponent++; 4965f2c45f1SShri Abhyankar PetscFunctionReturn(0); 4975f2c45f1SShri Abhyankar } 4985f2c45f1SShri Abhyankar 4995f2c45f1SShri Abhyankar /*@ 5005f2c45f1SShri Abhyankar DMNetworkGetVertexRange - Get the bounds [start, end) for the vertices. 5015f2c45f1SShri Abhyankar 5025f2c45f1SShri Abhyankar Not Collective 5035f2c45f1SShri Abhyankar 5045f2c45f1SShri Abhyankar Input Parameters: 505a2b725a8SWilliam Gropp . dm - The DMNetwork object 5065f2c45f1SShri Abhyankar 5075f2c45f1SShri Abhyankar Output Paramters: 5085f2c45f1SShri Abhyankar + vStart - The first vertex point 5095f2c45f1SShri Abhyankar - vEnd - One beyond the last vertex point 5105f2c45f1SShri Abhyankar 5115f2c45f1SShri Abhyankar Level: intermediate 5125f2c45f1SShri Abhyankar 5135f2c45f1SShri Abhyankar .seealso: DMNetworkGetEdgeRange 5145f2c45f1SShri Abhyankar @*/ 5155f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVertexRange(DM dm,PetscInt *vStart,PetscInt *vEnd) 5165f2c45f1SShri Abhyankar { 5175f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 5185f2c45f1SShri Abhyankar 5195f2c45f1SShri Abhyankar PetscFunctionBegin; 5205f2c45f1SShri Abhyankar if (vStart) *vStart = network->vStart; 5215f2c45f1SShri Abhyankar if (vEnd) *vEnd = network->vEnd; 5225f2c45f1SShri Abhyankar PetscFunctionReturn(0); 5235f2c45f1SShri Abhyankar } 5245f2c45f1SShri Abhyankar 5255f2c45f1SShri Abhyankar /*@ 5265f2c45f1SShri Abhyankar DMNetworkGetEdgeRange - Get the bounds [start, end) for the edges. 5275f2c45f1SShri Abhyankar 5285f2c45f1SShri Abhyankar Not Collective 5295f2c45f1SShri Abhyankar 5305f2c45f1SShri Abhyankar Input Parameters: 531a2b725a8SWilliam Gropp . dm - The DMNetwork object 5325f2c45f1SShri Abhyankar 5335f2c45f1SShri Abhyankar Output Paramters: 5345f2c45f1SShri Abhyankar + eStart - The first edge point 5355f2c45f1SShri Abhyankar - eEnd - One beyond the last edge point 5365f2c45f1SShri Abhyankar 5375f2c45f1SShri Abhyankar Level: intermediate 5385f2c45f1SShri Abhyankar 5395f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange 5405f2c45f1SShri Abhyankar @*/ 5415f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetEdgeRange(DM dm,PetscInt *eStart,PetscInt *eEnd) 5425f2c45f1SShri Abhyankar { 5435f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 5445f2c45f1SShri Abhyankar 5455f2c45f1SShri Abhyankar PetscFunctionBegin; 5465f2c45f1SShri Abhyankar if (eStart) *eStart = network->eStart; 5475f2c45f1SShri Abhyankar if (eEnd) *eEnd = network->eEnd; 5485f2c45f1SShri Abhyankar PetscFunctionReturn(0); 5495f2c45f1SShri Abhyankar } 5505f2c45f1SShri Abhyankar 5517b6afd5bSHong Zhang /*@ 552e85e6aecSHong Zhang DMNetworkGetGlobalEdgeIndex - Get the user global numbering for the edge. 5537b6afd5bSHong Zhang 5547b6afd5bSHong Zhang Not Collective 5557b6afd5bSHong Zhang 5567b6afd5bSHong Zhang Input Parameters: 5577b6afd5bSHong Zhang + dm - DMNetwork object 558e85e6aecSHong Zhang - p - edge point 5597b6afd5bSHong Zhang 5607b6afd5bSHong Zhang Output Paramters: 561e85e6aecSHong Zhang . index - user global numbering for the edge 5627b6afd5bSHong Zhang 5637b6afd5bSHong Zhang Level: intermediate 5647b6afd5bSHong Zhang 565e85e6aecSHong Zhang .seealso: DMNetworkGetGlobalVertexIndex 5667b6afd5bSHong Zhang @*/ 567e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalEdgeIndex(DM dm,PetscInt p,PetscInt *index) 5687b6afd5bSHong Zhang { 5697b6afd5bSHong Zhang PetscErrorCode ierr; 5707b6afd5bSHong Zhang DM_Network *network = (DM_Network*)dm->data; 5717b6afd5bSHong Zhang PetscInt offsetp; 5727b6afd5bSHong Zhang DMNetworkComponentHeader header; 5737b6afd5bSHong Zhang 5747b6afd5bSHong Zhang PetscFunctionBegin; 575caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 5767b6afd5bSHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 5777b6afd5bSHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 578e85e6aecSHong Zhang *index = header->index; 5797b6afd5bSHong Zhang PetscFunctionReturn(0); 5807b6afd5bSHong Zhang } 5817b6afd5bSHong Zhang 5825f2c45f1SShri Abhyankar /*@ 583e85e6aecSHong Zhang DMNetworkGetGlobalVertexIndex - Get the user global numbering for the vertex. 584e85e6aecSHong Zhang 585e85e6aecSHong Zhang Not Collective 586e85e6aecSHong Zhang 587e85e6aecSHong Zhang Input Parameters: 588e85e6aecSHong Zhang + dm - DMNetwork object 589e85e6aecSHong Zhang - p - vertex point 590e85e6aecSHong Zhang 591e85e6aecSHong Zhang Output Paramters: 592e85e6aecSHong Zhang . index - user global numbering for the vertex 593e85e6aecSHong Zhang 594e85e6aecSHong Zhang Level: intermediate 595e85e6aecSHong Zhang 596e85e6aecSHong Zhang .seealso: DMNetworkGetGlobalEdgeIndex 597e85e6aecSHong Zhang @*/ 598e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalVertexIndex(DM dm,PetscInt p,PetscInt *index) 599e85e6aecSHong Zhang { 600e85e6aecSHong Zhang PetscErrorCode ierr; 601e85e6aecSHong Zhang DM_Network *network = (DM_Network*)dm->data; 602e85e6aecSHong Zhang PetscInt offsetp; 603e85e6aecSHong Zhang DMNetworkComponentHeader header; 604e85e6aecSHong Zhang 605e85e6aecSHong Zhang PetscFunctionBegin; 606caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 607e85e6aecSHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 608e85e6aecSHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 609e85e6aecSHong Zhang *index = header->index; 610e85e6aecSHong Zhang PetscFunctionReturn(0); 611e85e6aecSHong Zhang } 612e85e6aecSHong Zhang 613c3b11c7cSShri Abhyankar /* 614c3b11c7cSShri Abhyankar DMNetworkGetComponentKeyOffset - Gets the type along with the offset for indexing the 615c3b11c7cSShri Abhyankar component value from the component data array 616c3b11c7cSShri Abhyankar 617c3b11c7cSShri Abhyankar Not Collective 618c3b11c7cSShri Abhyankar 619c3b11c7cSShri Abhyankar Input Parameters: 620c3b11c7cSShri Abhyankar + dm - The DMNetwork object 621c3b11c7cSShri Abhyankar . p - vertex/edge point 622c3b11c7cSShri Abhyankar - compnum - component number 623c3b11c7cSShri Abhyankar 624c3b11c7cSShri Abhyankar Output Parameters: 625c3b11c7cSShri Abhyankar + compkey - the key obtained when registering the component 626c3b11c7cSShri Abhyankar - offset - offset into the component data array associated with the vertex/edge point 627c3b11c7cSShri Abhyankar 628c3b11c7cSShri Abhyankar Notes: 629c3b11c7cSShri Abhyankar Typical usage: 630c3b11c7cSShri Abhyankar 631c3b11c7cSShri Abhyankar DMNetworkGetComponentDataArray(dm, &arr); 632c3b11c7cSShri Abhyankar DMNetworkGetVertex/EdgeRange(dm,&Start,&End); 633c3b11c7cSShri Abhyankar Loop over vertices or edges 634c3b11c7cSShri Abhyankar DMNetworkGetNumComponents(dm,v,&numcomps); 635c3b11c7cSShri Abhyankar Loop over numcomps 636c3b11c7cSShri Abhyankar DMNetworkGetComponentKeyOffset(dm,v,compnum,&key,&offset); 637c3b11c7cSShri Abhyankar compdata = (UserCompDataType)(arr+offset); 638c3b11c7cSShri Abhyankar 639c3b11c7cSShri Abhyankar Level: intermediate 640c3b11c7cSShri Abhyankar 641c3b11c7cSShri Abhyankar .seealso: DMNetworkGetNumComponents, DMNetworkGetComponentDataArray, 642c3b11c7cSShri Abhyankar */ 643c3b11c7cSShri Abhyankar PetscErrorCode DMNetworkGetComponentKeyOffset(DM dm,PetscInt p, PetscInt compnum, PetscInt *compkey, PetscInt *offset) 644c3b11c7cSShri Abhyankar { 645c3b11c7cSShri Abhyankar PetscErrorCode ierr; 646c3b11c7cSShri Abhyankar PetscInt offsetp; 647c3b11c7cSShri Abhyankar DMNetworkComponentHeader header; 648c3b11c7cSShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 649c3b11c7cSShri Abhyankar 650c3b11c7cSShri Abhyankar PetscFunctionBegin; 651c3b11c7cSShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 652c3b11c7cSShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 653c3b11c7cSShri Abhyankar if (compkey) *compkey = header->key[compnum]; 654c3b11c7cSShri Abhyankar if (offset) *offset = offsetp+network->dataheadersize+header->offset[compnum]; 655c3b11c7cSShri Abhyankar PetscFunctionReturn(0); 656c3b11c7cSShri Abhyankar } 657c3b11c7cSShri Abhyankar 658c3b11c7cSShri Abhyankar /*@ 659c3b11c7cSShri Abhyankar DMNetworkGetComponent - Returns the network component and its key 660c3b11c7cSShri Abhyankar 661c3b11c7cSShri Abhyankar Not Collective 662c3b11c7cSShri Abhyankar 663c3b11c7cSShri Abhyankar Input Parameters 664c3b11c7cSShri Abhyankar + dm - DMNetwork object 665c3b11c7cSShri Abhyankar . p - edge or vertex point 666c3b11c7cSShri Abhyankar - compnum - component number 667c3b11c7cSShri Abhyankar 668c3b11c7cSShri Abhyankar Output Parameters: 669c3b11c7cSShri Abhyankar + compkey - the key set for this computing during registration 670c3b11c7cSShri Abhyankar - component - the component data 671c3b11c7cSShri Abhyankar 672c3b11c7cSShri Abhyankar Notes: 673c3b11c7cSShri Abhyankar Typical usage: 674c3b11c7cSShri Abhyankar 675c3b11c7cSShri Abhyankar DMNetworkGetVertex/EdgeRange(dm,&Start,&End); 676c3b11c7cSShri Abhyankar Loop over vertices or edges 677c3b11c7cSShri Abhyankar DMNetworkGetNumComponents(dm,v,&numcomps); 678c3b11c7cSShri Abhyankar Loop over numcomps 679c3b11c7cSShri Abhyankar DMNetworkGetComponent(dm,v,compnum,&key,&component); 680c3b11c7cSShri Abhyankar 681c3b11c7cSShri Abhyankar Level: intermediate 682c3b11c7cSShri Abhyankar 683c3b11c7cSShri Abhyankar .seealso: DMNetworkGetNumComponents, DMNetworkGetVariableOffset 684c3b11c7cSShri Abhyankar @*/ 685c3b11c7cSShri Abhyankar PetscErrorCode DMNetworkGetComponent(DM dm, PetscInt p, PetscInt compnum, PetscInt *key, void **component) 686c3b11c7cSShri Abhyankar { 687c3b11c7cSShri Abhyankar PetscErrorCode ierr; 688c3b11c7cSShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 689e108cb99SStefano Zampini PetscInt offsetd = 0; 690c3b11c7cSShri Abhyankar 691c3b11c7cSShri Abhyankar PetscFunctionBegin; 692c3b11c7cSShri Abhyankar ierr = DMNetworkGetComponentKeyOffset(dm,p,compnum,key,&offsetd);CHKERRQ(ierr); 693c3b11c7cSShri Abhyankar *component = network->componentdataarray+offsetd; 694c3b11c7cSShri Abhyankar PetscFunctionReturn(0); 695c3b11c7cSShri Abhyankar } 696c3b11c7cSShri Abhyankar 697e85e6aecSHong Zhang /*@ 698325661f6SSatish Balay DMNetworkAddComponent - Adds a network component at the given point (vertex/edge) 6995f2c45f1SShri Abhyankar 7005f2c45f1SShri Abhyankar Not Collective 7015f2c45f1SShri Abhyankar 7025f2c45f1SShri Abhyankar Input Parameters: 7035f2c45f1SShri Abhyankar + dm - The DMNetwork object 7045f2c45f1SShri Abhyankar . p - vertex/edge point 7055f2c45f1SShri Abhyankar . componentkey - component key returned while registering the component 7065f2c45f1SShri Abhyankar - compvalue - pointer to the data structure for the component 7075f2c45f1SShri Abhyankar 7085f2c45f1SShri Abhyankar Level: intermediate 7095f2c45f1SShri Abhyankar 7105f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange, DMNetworkGetEdgeRange, DMNetworkRegisterComponent 7115f2c45f1SShri Abhyankar @*/ 7125f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddComponent(DM dm, PetscInt p,PetscInt componentkey,void* compvalue) 7135f2c45f1SShri Abhyankar { 7145f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 71543a39a44SBarry Smith DMNetworkComponent *component = &network->component[componentkey]; 7165f2c45f1SShri Abhyankar DMNetworkComponentHeader header = &network->header[p]; 7175f2c45f1SShri Abhyankar DMNetworkComponentValue cvalue = &network->cvalue[p]; 7185f2c45f1SShri Abhyankar PetscErrorCode ierr; 7195f2c45f1SShri Abhyankar 7205f2c45f1SShri Abhyankar PetscFunctionBegin; 721fa58f0a9SHong 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); 722fa58f0a9SHong Zhang 72343a39a44SBarry Smith header->size[header->ndata] = component->size; 72443a39a44SBarry Smith ierr = PetscSectionAddDof(network->DataSection,p,component->size);CHKERRQ(ierr); 7255f2c45f1SShri Abhyankar header->key[header->ndata] = componentkey; 7265f2c45f1SShri Abhyankar if (header->ndata != 0) header->offset[header->ndata] = header->offset[header->ndata-1] + header->size[header->ndata-1]; 727*9988b915SShri Abhyankar header->nvar[header->ndata] = 0; 7285f2c45f1SShri Abhyankar 7295f2c45f1SShri Abhyankar cvalue->data[header->ndata] = (void*)compvalue; 7305f2c45f1SShri Abhyankar header->ndata++; 7315f2c45f1SShri Abhyankar PetscFunctionReturn(0); 7325f2c45f1SShri Abhyankar } 7335f2c45f1SShri Abhyankar 7345f2c45f1SShri Abhyankar /*@ 735*9988b915SShri Abhyankar DMNetworkSetComponentNumVariables - Sets the number of variables for a component 736*9988b915SShri Abhyankar 737*9988b915SShri Abhyankar Not Collective 738*9988b915SShri Abhyankar 739*9988b915SShri Abhyankar Input Parameters: 740*9988b915SShri Abhyankar + dm - The DMNetwork object 741*9988b915SShri Abhyankar . p - vertex/edge point 742*9988b915SShri Abhyankar . compnum - component number (First component added = 0, second = 1, ...) 743*9988b915SShri Abhyankar - nvar - number of variables for the component 744*9988b915SShri Abhyankar 745*9988b915SShri Abhyankar Level: intermediate 746*9988b915SShri Abhyankar 747*9988b915SShri Abhyankar .seealso: DMNetworkAddComponent, DMNetworkGetNumComponents,DMNetworkRegisterComponent 748*9988b915SShri Abhyankar @*/ 749*9988b915SShri Abhyankar PetscErrorCode DMNetworkSetComponentNumVariables(DM dm, PetscInt p,PetscInt compnum,PetscInt nvar) 750*9988b915SShri Abhyankar { 751*9988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 752*9988b915SShri Abhyankar DMNetworkComponentHeader header = &network->header[p]; 753*9988b915SShri Abhyankar PetscErrorCode ierr; 754*9988b915SShri Abhyankar 755*9988b915SShri Abhyankar PetscFunctionBegin; 756*9988b915SShri Abhyankar 757*9988b915SShri Abhyankar ierr = DMNetworkAddNumVariables(dm,p,nvar);CHKERRQ(ierr); 758*9988b915SShri Abhyankar header->nvar[compnum] = nvar; 759*9988b915SShri Abhyankar if (compnum != 0) header->offsetvarrel[compnum] = header->offsetvarrel[compnum-1] + header->nvar[compnum-1]; 760*9988b915SShri Abhyankar 761*9988b915SShri Abhyankar PetscFunctionReturn(0); 762*9988b915SShri Abhyankar } 763*9988b915SShri Abhyankar 764*9988b915SShri Abhyankar /*@ 7655f2c45f1SShri Abhyankar DMNetworkGetNumComponents - Get the number of components at a vertex/edge 7665f2c45f1SShri Abhyankar 7675f2c45f1SShri Abhyankar Not Collective 7685f2c45f1SShri Abhyankar 7695f2c45f1SShri Abhyankar Input Parameters: 7705f2c45f1SShri Abhyankar + dm - The DMNetwork object 771a2b725a8SWilliam Gropp - p - vertex/edge point 7725f2c45f1SShri Abhyankar 7735f2c45f1SShri Abhyankar Output Parameters: 7745f2c45f1SShri Abhyankar . numcomponents - Number of components at the vertex/edge 7755f2c45f1SShri Abhyankar 7765f2c45f1SShri Abhyankar Level: intermediate 7775f2c45f1SShri Abhyankar 7785f2c45f1SShri Abhyankar .seealso: DMNetworkRegisterComponent, DMNetworkAddComponent 7795f2c45f1SShri Abhyankar @*/ 7805f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetNumComponents(DM dm,PetscInt p,PetscInt *numcomponents) 7815f2c45f1SShri Abhyankar { 7825f2c45f1SShri Abhyankar PetscErrorCode ierr; 7835f2c45f1SShri Abhyankar PetscInt offset; 7845f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 7855f2c45f1SShri Abhyankar 7865f2c45f1SShri Abhyankar PetscFunctionBegin; 7875f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 7885f2c45f1SShri Abhyankar *numcomponents = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 7895f2c45f1SShri Abhyankar PetscFunctionReturn(0); 7905f2c45f1SShri Abhyankar } 7915f2c45f1SShri Abhyankar 7925f2c45f1SShri Abhyankar /*@ 7935f2c45f1SShri Abhyankar DMNetworkGetVariableOffset - Get the offset for accessing the variable associated with the given vertex/edge from the local vector. 7945f2c45f1SShri Abhyankar 7955f2c45f1SShri Abhyankar Not Collective 7965f2c45f1SShri Abhyankar 7975f2c45f1SShri Abhyankar Input Parameters: 7985f2c45f1SShri Abhyankar + dm - The DMNetwork object 7995f2c45f1SShri Abhyankar - p - the edge/vertex point 8005f2c45f1SShri Abhyankar 8015f2c45f1SShri Abhyankar Output Parameters: 8025f2c45f1SShri Abhyankar . offset - the offset 8035f2c45f1SShri Abhyankar 8045f2c45f1SShri Abhyankar Level: intermediate 8055f2c45f1SShri Abhyankar 8065f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 8075f2c45f1SShri Abhyankar @*/ 8085f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableOffset(DM dm,PetscInt p,PetscInt *offset) 8095f2c45f1SShri Abhyankar { 8105f2c45f1SShri Abhyankar PetscErrorCode ierr; 8115f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 8125f2c45f1SShri Abhyankar 8135f2c45f1SShri Abhyankar PetscFunctionBegin; 8141bb6d2a8SBarry Smith ierr = PetscSectionGetOffset(network->plex->localSection,p,offset);CHKERRQ(ierr); 8155f2c45f1SShri Abhyankar PetscFunctionReturn(0); 8165f2c45f1SShri Abhyankar } 8175f2c45f1SShri Abhyankar 8185f2c45f1SShri Abhyankar /*@ 8195f2c45f1SShri Abhyankar DMNetworkGetVariableGlobalOffset - Get the global offset for the variable associated with the given vertex/edge from the global vector. 8205f2c45f1SShri Abhyankar 8215f2c45f1SShri Abhyankar Not Collective 8225f2c45f1SShri Abhyankar 8235f2c45f1SShri Abhyankar Input Parameters: 8245f2c45f1SShri Abhyankar + dm - The DMNetwork object 8255f2c45f1SShri Abhyankar - p - the edge/vertex point 8265f2c45f1SShri Abhyankar 8275f2c45f1SShri Abhyankar Output Parameters: 8285f2c45f1SShri Abhyankar . offsetg - the offset 8295f2c45f1SShri Abhyankar 8305f2c45f1SShri Abhyankar Level: intermediate 8315f2c45f1SShri Abhyankar 8325f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableOffset, DMGetLocalVector 8335f2c45f1SShri Abhyankar @*/ 8345f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableGlobalOffset(DM dm,PetscInt p,PetscInt *offsetg) 8355f2c45f1SShri Abhyankar { 8365f2c45f1SShri Abhyankar PetscErrorCode ierr; 8375f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 8385f2c45f1SShri Abhyankar 8395f2c45f1SShri Abhyankar PetscFunctionBegin; 8401bb6d2a8SBarry Smith ierr = PetscSectionGetOffset(network->plex->globalSection,p,offsetg);CHKERRQ(ierr); 8416fefedf4SHong Zhang if (*offsetg < 0) *offsetg = -(*offsetg + 1); /* Convert to actual global offset for ghost vertex */ 8425f2c45f1SShri Abhyankar PetscFunctionReturn(0); 8435f2c45f1SShri Abhyankar } 8445f2c45f1SShri Abhyankar 84524121865SAdrian Maldonado /*@ 846*9988b915SShri Abhyankar DMNetworkGetComponentVariableOffset - Get the offset for accessing the variable associated with a component for the given vertex/edge from the local vector. 847*9988b915SShri Abhyankar 848*9988b915SShri Abhyankar Not Collective 849*9988b915SShri Abhyankar 850*9988b915SShri Abhyankar Input Parameters: 851*9988b915SShri Abhyankar + dm - The DMNetwork object 852*9988b915SShri Abhyankar . compnum - component number 853*9988b915SShri Abhyankar - p - the edge/vertex point 854*9988b915SShri Abhyankar 855*9988b915SShri Abhyankar Output Parameters: 856*9988b915SShri Abhyankar . offset - the offset 857*9988b915SShri Abhyankar 858*9988b915SShri Abhyankar Level: intermediate 859*9988b915SShri Abhyankar 860*9988b915SShri Abhyankar .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector, DMNetworkSetComponentNumVariables 861*9988b915SShri Abhyankar @*/ 862*9988b915SShri Abhyankar PetscErrorCode DMNetworkGetComponentVariableOffset(DM dm,PetscInt p,PetscInt compnum,PetscInt *offset) 863*9988b915SShri Abhyankar { 864*9988b915SShri Abhyankar PetscErrorCode ierr; 865*9988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 866*9988b915SShri Abhyankar PetscInt offsetp,offsetd; 867*9988b915SShri Abhyankar DMNetworkComponentHeader header; 868*9988b915SShri Abhyankar 869*9988b915SShri Abhyankar PetscFunctionBegin; 870*9988b915SShri Abhyankar ierr = DMNetworkGetVariableOffset(dm,p,&offsetp);CHKERRQ(ierr); 871*9988b915SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetd);CHKERRQ(ierr); 872*9988b915SShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetd); 873*9988b915SShri Abhyankar *offset = offsetp + header->offsetvarrel[compnum]; 874*9988b915SShri Abhyankar PetscFunctionReturn(0); 875*9988b915SShri Abhyankar } 876*9988b915SShri Abhyankar 877*9988b915SShri Abhyankar /*@ 878*9988b915SShri Abhyankar DMNetworkGetComponentVariableGlobalOffset - Get the global offset for accessing the variable associated with a component for the given vertex/edge from the local vector. 879*9988b915SShri Abhyankar 880*9988b915SShri Abhyankar Not Collective 881*9988b915SShri Abhyankar 882*9988b915SShri Abhyankar Input Parameters: 883*9988b915SShri Abhyankar + dm - The DMNetwork object 884*9988b915SShri Abhyankar . compnum - component number 885*9988b915SShri Abhyankar - p - the edge/vertex point 886*9988b915SShri Abhyankar 887*9988b915SShri Abhyankar Output Parameters: 888*9988b915SShri Abhyankar . offsetg - the global offset 889*9988b915SShri Abhyankar 890*9988b915SShri Abhyankar Level: intermediate 891*9988b915SShri Abhyankar 892*9988b915SShri Abhyankar .seealso: DMNetworkGetVariableGlobalOffset, DMNetworkGetComponentVariableOffset, DMGetLocalVector, DMNetworkSetComponentNumVariables 893*9988b915SShri Abhyankar @*/ 894*9988b915SShri Abhyankar PetscErrorCode DMNetworkGetComponentVariableGlobalOffset(DM dm,PetscInt p,PetscInt compnum,PetscInt *offsetg) 895*9988b915SShri Abhyankar { 896*9988b915SShri Abhyankar PetscErrorCode ierr; 897*9988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 898*9988b915SShri Abhyankar PetscInt offsetp,offsetd; 899*9988b915SShri Abhyankar DMNetworkComponentHeader header; 900*9988b915SShri Abhyankar 901*9988b915SShri Abhyankar PetscFunctionBegin; 902*9988b915SShri Abhyankar ierr = DMNetworkGetVariableGlobalOffset(dm,p,&offsetp);CHKERRQ(ierr); 903*9988b915SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetd);CHKERRQ(ierr); 904*9988b915SShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetd); 905*9988b915SShri Abhyankar *offsetg = offsetp + header->offsetvarrel[compnum]; 906*9988b915SShri Abhyankar PetscFunctionReturn(0); 907*9988b915SShri Abhyankar } 908*9988b915SShri Abhyankar 909*9988b915SShri Abhyankar /*@ 91024121865SAdrian Maldonado DMNetworkGetEdgeOffset - Get the offset for accessing the variable associated with the given edge from the local subvector. 91124121865SAdrian Maldonado 91224121865SAdrian Maldonado Not Collective 91324121865SAdrian Maldonado 91424121865SAdrian Maldonado Input Parameters: 91524121865SAdrian Maldonado + dm - The DMNetwork object 91624121865SAdrian Maldonado - p - the edge point 91724121865SAdrian Maldonado 91824121865SAdrian Maldonado Output Parameters: 91924121865SAdrian Maldonado . offset - the offset 92024121865SAdrian Maldonado 92124121865SAdrian Maldonado Level: intermediate 92224121865SAdrian Maldonado 92324121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 92424121865SAdrian Maldonado @*/ 92524121865SAdrian Maldonado PetscErrorCode DMNetworkGetEdgeOffset(DM dm,PetscInt p,PetscInt *offset) 92624121865SAdrian Maldonado { 92724121865SAdrian Maldonado PetscErrorCode ierr; 92824121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 92924121865SAdrian Maldonado 93024121865SAdrian Maldonado PetscFunctionBegin; 93124121865SAdrian Maldonado 93224121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->edge.DofSection,p,offset);CHKERRQ(ierr); 93324121865SAdrian Maldonado PetscFunctionReturn(0); 93424121865SAdrian Maldonado } 93524121865SAdrian Maldonado 93624121865SAdrian Maldonado /*@ 93724121865SAdrian Maldonado DMNetworkGetVertexOffset - Get the offset for accessing the variable associated with the given vertex from the local subvector. 93824121865SAdrian Maldonado 93924121865SAdrian Maldonado Not Collective 94024121865SAdrian Maldonado 94124121865SAdrian Maldonado Input Parameters: 94224121865SAdrian Maldonado + dm - The DMNetwork object 94324121865SAdrian Maldonado - p - the vertex point 94424121865SAdrian Maldonado 94524121865SAdrian Maldonado Output Parameters: 94624121865SAdrian Maldonado . offset - the offset 94724121865SAdrian Maldonado 94824121865SAdrian Maldonado Level: intermediate 94924121865SAdrian Maldonado 95024121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 95124121865SAdrian Maldonado @*/ 95224121865SAdrian Maldonado PetscErrorCode DMNetworkGetVertexOffset(DM dm,PetscInt p,PetscInt *offset) 95324121865SAdrian Maldonado { 95424121865SAdrian Maldonado PetscErrorCode ierr; 95524121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 95624121865SAdrian Maldonado 95724121865SAdrian Maldonado PetscFunctionBegin; 95824121865SAdrian Maldonado 95924121865SAdrian Maldonado p -= network->vStart; 96024121865SAdrian Maldonado 96124121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->vertex.DofSection,p,offset);CHKERRQ(ierr); 96224121865SAdrian Maldonado PetscFunctionReturn(0); 96324121865SAdrian Maldonado } 9645f2c45f1SShri Abhyankar /*@ 9655f2c45f1SShri Abhyankar DMNetworkAddNumVariables - Add number of variables associated with a given point. 9665f2c45f1SShri Abhyankar 9675f2c45f1SShri Abhyankar Not Collective 9685f2c45f1SShri Abhyankar 9695f2c45f1SShri Abhyankar Input Parameters: 9705f2c45f1SShri Abhyankar + dm - The DMNetworkObject 9715f2c45f1SShri Abhyankar . p - the vertex/edge point 9725f2c45f1SShri Abhyankar - nvar - number of additional variables 9735f2c45f1SShri Abhyankar 9745f2c45f1SShri Abhyankar Level: intermediate 9755f2c45f1SShri Abhyankar 9765f2c45f1SShri Abhyankar .seealso: DMNetworkSetNumVariables 9775f2c45f1SShri Abhyankar @*/ 9785f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddNumVariables(DM dm,PetscInt p,PetscInt nvar) 9795f2c45f1SShri Abhyankar { 9805f2c45f1SShri Abhyankar PetscErrorCode ierr; 9815f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 9825f2c45f1SShri Abhyankar 9835f2c45f1SShri Abhyankar PetscFunctionBegin; 9845f2c45f1SShri Abhyankar ierr = PetscSectionAddDof(network->DofSection,p,nvar);CHKERRQ(ierr); 9855f2c45f1SShri Abhyankar PetscFunctionReturn(0); 9865f2c45f1SShri Abhyankar } 9875f2c45f1SShri Abhyankar 98827f51fceSHong Zhang /*@ 98927f51fceSHong Zhang DMNetworkGetNumVariables - Gets number of variables for a vertex/edge point. 99027f51fceSHong Zhang 99127f51fceSHong Zhang Not Collective 99227f51fceSHong Zhang 99327f51fceSHong Zhang Input Parameters: 99427f51fceSHong Zhang + dm - The DMNetworkObject 99527f51fceSHong Zhang - p - the vertex/edge point 99627f51fceSHong Zhang 99727f51fceSHong Zhang Output Parameters: 99827f51fceSHong Zhang . nvar - number of variables 99927f51fceSHong Zhang 100027f51fceSHong Zhang Level: intermediate 100127f51fceSHong Zhang 100227f51fceSHong Zhang .seealso: DMNetworkAddNumVariables, DMNetworkSddNumVariables 100327f51fceSHong Zhang @*/ 100427f51fceSHong Zhang PetscErrorCode DMNetworkGetNumVariables(DM dm,PetscInt p,PetscInt *nvar) 100527f51fceSHong Zhang { 100627f51fceSHong Zhang PetscErrorCode ierr; 100727f51fceSHong Zhang DM_Network *network = (DM_Network*)dm->data; 100827f51fceSHong Zhang 100927f51fceSHong Zhang PetscFunctionBegin; 101027f51fceSHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 101127f51fceSHong Zhang PetscFunctionReturn(0); 101227f51fceSHong Zhang } 101327f51fceSHong Zhang 10145f2c45f1SShri Abhyankar /*@ 10155f2c45f1SShri Abhyankar DMNetworkSetNumVariables - Sets number of variables for a vertex/edge point. 10165f2c45f1SShri Abhyankar 10175f2c45f1SShri Abhyankar Not Collective 10185f2c45f1SShri Abhyankar 10195f2c45f1SShri Abhyankar Input Parameters: 10205f2c45f1SShri Abhyankar + dm - The DMNetworkObject 10215f2c45f1SShri Abhyankar . p - the vertex/edge point 10225f2c45f1SShri Abhyankar - nvar - number of variables 10235f2c45f1SShri Abhyankar 10245f2c45f1SShri Abhyankar Level: intermediate 10255f2c45f1SShri Abhyankar 10265f2c45f1SShri Abhyankar .seealso: DMNetworkAddNumVariables 10275f2c45f1SShri Abhyankar @*/ 10285f2c45f1SShri Abhyankar PetscErrorCode DMNetworkSetNumVariables(DM dm,PetscInt p,PetscInt nvar) 10295f2c45f1SShri Abhyankar { 10305f2c45f1SShri Abhyankar PetscErrorCode ierr; 10315f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10325f2c45f1SShri Abhyankar 10335f2c45f1SShri Abhyankar PetscFunctionBegin; 10345f2c45f1SShri Abhyankar ierr = PetscSectionSetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 10355f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10365f2c45f1SShri Abhyankar } 10375f2c45f1SShri Abhyankar 10385f2c45f1SShri Abhyankar /* Sets up the array that holds the data for all components and its associated section. This 10395f2c45f1SShri Abhyankar function is called during DMSetUp() */ 10405f2c45f1SShri Abhyankar PetscErrorCode DMNetworkComponentSetUp(DM dm) 10415f2c45f1SShri Abhyankar { 10425f2c45f1SShri Abhyankar PetscErrorCode ierr; 10435f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 1044e53b5ba3SHong Zhang PetscInt arr_size,p,offset,offsetp,ncomp,i; 10455f2c45f1SShri Abhyankar DMNetworkComponentHeader header; 10465f2c45f1SShri Abhyankar DMNetworkComponentValue cvalue; 10475f2c45f1SShri Abhyankar DMNetworkComponentGenericDataType *componentdataarray; 10485f2c45f1SShri Abhyankar 10495f2c45f1SShri Abhyankar PetscFunctionBegin; 10505f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr); 10515f2c45f1SShri Abhyankar ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr); 105275b160a0SShri Abhyankar ierr = PetscMalloc1(arr_size,&network->componentdataarray);CHKERRQ(ierr); 10535f2c45f1SShri Abhyankar componentdataarray = network->componentdataarray; 10545f2c45f1SShri Abhyankar for (p = network->pStart; p < network->pEnd; p++) { 10555f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 10565f2c45f1SShri Abhyankar /* Copy header */ 10575f2c45f1SShri Abhyankar header = &network->header[p]; 1058302440fdSBarry Smith ierr = PetscMemcpy(componentdataarray+offsetp,header,network->dataheadersize*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 10595f2c45f1SShri Abhyankar /* Copy data */ 10605f2c45f1SShri Abhyankar cvalue = &network->cvalue[p]; 10615f2c45f1SShri Abhyankar ncomp = header->ndata; 10625f2c45f1SShri Abhyankar for (i = 0; i < ncomp; i++) { 10635f2c45f1SShri Abhyankar offset = offsetp + network->dataheadersize + header->offset[i]; 1064302440fdSBarry Smith ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 10655f2c45f1SShri Abhyankar } 10665f2c45f1SShri Abhyankar } 10675f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10685f2c45f1SShri Abhyankar } 10695f2c45f1SShri Abhyankar 10705f2c45f1SShri Abhyankar /* Sets up the section for dofs. This routine is called during DMSetUp() */ 10715f2c45f1SShri Abhyankar PetscErrorCode DMNetworkVariablesSetUp(DM dm) 10725f2c45f1SShri Abhyankar { 10735f2c45f1SShri Abhyankar PetscErrorCode ierr; 10745f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10755f2c45f1SShri Abhyankar 10765f2c45f1SShri Abhyankar PetscFunctionBegin; 10775f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr); 10785f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10795f2c45f1SShri Abhyankar } 10805f2c45f1SShri Abhyankar 10815f2c45f1SShri Abhyankar /*@C 10825f2c45f1SShri Abhyankar DMNetworkGetComponentDataArray - Returns the component data array 10835f2c45f1SShri Abhyankar 10845f2c45f1SShri Abhyankar Not Collective 10855f2c45f1SShri Abhyankar 10865f2c45f1SShri Abhyankar Input Parameters: 10875f2c45f1SShri Abhyankar . dm - The DMNetwork Object 10885f2c45f1SShri Abhyankar 10895f2c45f1SShri Abhyankar Output Parameters: 10905f2c45f1SShri Abhyankar . componentdataarray - array that holds data for all components 10915f2c45f1SShri Abhyankar 10925f2c45f1SShri Abhyankar Level: intermediate 10935f2c45f1SShri Abhyankar 1094a730d845SHong Zhang .seealso: DMNetworkGetComponentKeyOffset, DMNetworkGetNumComponents 10955f2c45f1SShri Abhyankar @*/ 10965f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetComponentDataArray(DM dm,DMNetworkComponentGenericDataType **componentdataarray) 10975f2c45f1SShri Abhyankar { 10985f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10995f2c45f1SShri Abhyankar 11005f2c45f1SShri Abhyankar PetscFunctionBegin; 11015f2c45f1SShri Abhyankar *componentdataarray = network->componentdataarray; 11025f2c45f1SShri Abhyankar PetscFunctionReturn(0); 11035f2c45f1SShri Abhyankar } 11045f2c45f1SShri Abhyankar 110524121865SAdrian Maldonado /* Get a subsection from a range of points */ 110624121865SAdrian Maldonado PetscErrorCode DMNetworkGetSubSection_private(PetscSection master, PetscInt pstart, PetscInt pend,PetscSection *subsection) 110724121865SAdrian Maldonado { 110824121865SAdrian Maldonado PetscErrorCode ierr; 110924121865SAdrian Maldonado PetscInt i, nvar; 111024121865SAdrian Maldonado 111124121865SAdrian Maldonado PetscFunctionBegin; 111224121865SAdrian Maldonado ierr = PetscSectionCreate(PetscObjectComm((PetscObject)master), subsection);CHKERRQ(ierr); 111324121865SAdrian Maldonado ierr = PetscSectionSetChart(*subsection, 0, pend - pstart);CHKERRQ(ierr); 111424121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 111524121865SAdrian Maldonado ierr = PetscSectionGetDof(master,i,&nvar);CHKERRQ(ierr); 111624121865SAdrian Maldonado ierr = PetscSectionSetDof(*subsection, i - pstart, nvar);CHKERRQ(ierr); 111724121865SAdrian Maldonado } 111824121865SAdrian Maldonado 111924121865SAdrian Maldonado ierr = PetscSectionSetUp(*subsection);CHKERRQ(ierr); 112024121865SAdrian Maldonado PetscFunctionReturn(0); 112124121865SAdrian Maldonado } 112224121865SAdrian Maldonado 112324121865SAdrian Maldonado /* Create a submap of points with a GlobalToLocal structure */ 112424121865SAdrian Maldonado PetscErrorCode DMNetworkSetSubMap_private(PetscInt pstart, PetscInt pend, ISLocalToGlobalMapping *map) 112524121865SAdrian Maldonado { 112624121865SAdrian Maldonado PetscErrorCode ierr; 112724121865SAdrian Maldonado PetscInt i, *subpoints; 112824121865SAdrian Maldonado 112924121865SAdrian Maldonado PetscFunctionBegin; 113024121865SAdrian Maldonado /* Create index sets to map from "points" to "subpoints" */ 113124121865SAdrian Maldonado ierr = PetscMalloc1(pend - pstart, &subpoints);CHKERRQ(ierr); 113224121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 113324121865SAdrian Maldonado subpoints[i - pstart] = i; 113424121865SAdrian Maldonado } 1135459726d8SSatish Balay ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,pend-pstart,subpoints,PETSC_COPY_VALUES,map);CHKERRQ(ierr); 113624121865SAdrian Maldonado ierr = PetscFree(subpoints);CHKERRQ(ierr); 113724121865SAdrian Maldonado PetscFunctionReturn(0); 113824121865SAdrian Maldonado } 113924121865SAdrian Maldonado 114024121865SAdrian Maldonado /*@ 114124121865SAdrian Maldonado DMNetworkAssembleGraphStructures - Assembles vertex and edge data structures. Must be called after DMNetworkDistribute. 114224121865SAdrian Maldonado 114324121865SAdrian Maldonado Collective 114424121865SAdrian Maldonado 114524121865SAdrian Maldonado Input Parameters: 114624121865SAdrian Maldonado . dm - The DMNetworkObject 114724121865SAdrian Maldonado 114824121865SAdrian Maldonado Note: the routine will create alternative orderings for the vertices and edges. Assume global network points are: 114924121865SAdrian Maldonado 115024121865SAdrian Maldonado points = [0 1 2 3 4 5 6] 115124121865SAdrian Maldonado 1152caf410d2SHong 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]). 115324121865SAdrian Maldonado 115424121865SAdrian Maldonado With this new ordering a local PetscSection, global PetscSection and PetscSF will be created specific to the subset. 115524121865SAdrian Maldonado 115624121865SAdrian Maldonado Level: intermediate 115724121865SAdrian Maldonado 115824121865SAdrian Maldonado @*/ 115924121865SAdrian Maldonado PetscErrorCode DMNetworkAssembleGraphStructures(DM dm) 116024121865SAdrian Maldonado { 116124121865SAdrian Maldonado PetscErrorCode ierr; 116224121865SAdrian Maldonado MPI_Comm comm; 11639852e123SBarry Smith PetscMPIInt rank, size; 116424121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 116524121865SAdrian Maldonado 1166eab1376dSHong Zhang PetscFunctionBegin; 116724121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 116824121865SAdrian Maldonado ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 11699852e123SBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 117024121865SAdrian Maldonado 117124121865SAdrian Maldonado /* Create maps for vertices and edges */ 117224121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 117324121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->eStart,network->eEnd,&network->edge.mapping);CHKERRQ(ierr); 117424121865SAdrian Maldonado 117524121865SAdrian Maldonado /* Create local sub-sections */ 117624121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->vStart,network->vEnd,&network->vertex.DofSection);CHKERRQ(ierr); 117724121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->eStart,network->eEnd,&network->edge.DofSection);CHKERRQ(ierr); 117824121865SAdrian Maldonado 11799852e123SBarry Smith if (size > 1) { 118024121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 118122bbedd7SHong Zhang 118224121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->vertex.DofSection, network->vertex.sf, PETSC_FALSE, PETSC_FALSE, &network->vertex.GlobalDofSection);CHKERRQ(ierr); 118324121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->edge.mapping, &network->edge.sf);CHKERRQ(ierr); 118424121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->edge.DofSection, network->edge.sf, PETSC_FALSE, PETSC_FALSE, &network->edge.GlobalDofSection);CHKERRQ(ierr); 118524121865SAdrian Maldonado } else { 118624121865SAdrian Maldonado /* create structures for vertex */ 118724121865SAdrian Maldonado ierr = PetscSectionClone(network->vertex.DofSection,&network->vertex.GlobalDofSection);CHKERRQ(ierr); 118824121865SAdrian Maldonado /* create structures for edge */ 118924121865SAdrian Maldonado ierr = PetscSectionClone(network->edge.DofSection,&network->edge.GlobalDofSection);CHKERRQ(ierr); 119024121865SAdrian Maldonado } 119124121865SAdrian Maldonado 119224121865SAdrian Maldonado /* Add viewers */ 119324121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->edge.GlobalDofSection,"Global edge dof section");CHKERRQ(ierr); 119424121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->vertex.GlobalDofSection,"Global vertex dof section");CHKERRQ(ierr); 119524121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->edge.GlobalDofSection, NULL, "-edge_global_section_view");CHKERRQ(ierr); 119624121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->vertex.GlobalDofSection, NULL, "-vertex_global_section_view");CHKERRQ(ierr); 119724121865SAdrian Maldonado PetscFunctionReturn(0); 119824121865SAdrian Maldonado } 11997b6afd5bSHong Zhang 12005f2c45f1SShri Abhyankar /*@ 12015f2c45f1SShri Abhyankar DMNetworkDistribute - Distributes the network and moves associated component data. 12025f2c45f1SShri Abhyankar 12035f2c45f1SShri Abhyankar Collective 12045f2c45f1SShri Abhyankar 12055f2c45f1SShri Abhyankar Input Parameter: 1206d3464fd4SAdrian Maldonado + DM - the DMNetwork object 12075f2c45f1SShri Abhyankar - overlap - The overlap of partitions, 0 is the default 12085f2c45f1SShri Abhyankar 12095f2c45f1SShri Abhyankar Notes: 12108b171c8eSHong Zhang Distributes the network with <overlap>-overlapping partitioning of the edges. 12115f2c45f1SShri Abhyankar 12125f2c45f1SShri Abhyankar Level: intermediate 12135f2c45f1SShri Abhyankar 12145f2c45f1SShri Abhyankar .seealso: DMNetworkCreate 12155f2c45f1SShri Abhyankar @*/ 1216d3464fd4SAdrian Maldonado PetscErrorCode DMNetworkDistribute(DM *dm,PetscInt overlap) 12175f2c45f1SShri Abhyankar { 1218d3464fd4SAdrian Maldonado MPI_Comm comm; 12195f2c45f1SShri Abhyankar PetscErrorCode ierr; 1220d3464fd4SAdrian Maldonado PetscMPIInt size; 1221d3464fd4SAdrian Maldonado DM_Network *oldDMnetwork = (DM_Network*)((*dm)->data); 1222d3464fd4SAdrian Maldonado DM_Network *newDMnetwork; 1223caf410d2SHong Zhang PetscSF pointsf=NULL; 12245f2c45f1SShri Abhyankar DM newDM; 1225caf410d2SHong Zhang PetscInt j,e,v,offset,*subnetvtx; 122651ac5effSHong Zhang PetscPartitioner part; 1227b9c6e19dSShri Abhyankar DMNetworkComponentHeader header; 12285f2c45f1SShri Abhyankar 12295f2c45f1SShri Abhyankar PetscFunctionBegin; 1230d3464fd4SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)*dm,&comm);CHKERRQ(ierr); 1231d3464fd4SAdrian Maldonado ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 1232d3464fd4SAdrian Maldonado if (size == 1) PetscFunctionReturn(0); 1233d3464fd4SAdrian Maldonado 1234d3464fd4SAdrian Maldonado ierr = DMNetworkCreate(PetscObjectComm((PetscObject)*dm),&newDM);CHKERRQ(ierr); 12355f2c45f1SShri Abhyankar newDMnetwork = (DM_Network*)newDM->data; 12365f2c45f1SShri Abhyankar newDMnetwork->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 123751ac5effSHong Zhang 123851ac5effSHong Zhang /* Enable runtime options for petscpartitioner */ 123951ac5effSHong Zhang ierr = DMPlexGetPartitioner(oldDMnetwork->plex,&part);CHKERRQ(ierr); 124051ac5effSHong Zhang ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); 124151ac5effSHong Zhang 12425f2c45f1SShri Abhyankar /* Distribute plex dm and dof section */ 124380cf41d5SMatthew G. Knepley ierr = DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr); 124451ac5effSHong Zhang 12455f2c45f1SShri Abhyankar /* Distribute dof section */ 1246d3464fd4SAdrian Maldonado ierr = PetscSectionCreate(PetscObjectComm((PetscObject)*dm),&newDMnetwork->DofSection);CHKERRQ(ierr); 12475f2c45f1SShri Abhyankar ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr); 1248d3464fd4SAdrian Maldonado ierr = PetscSectionCreate(PetscObjectComm((PetscObject)*dm),&newDMnetwork->DataSection);CHKERRQ(ierr); 124951ac5effSHong Zhang 12505f2c45f1SShri Abhyankar /* Distribute data and associated section */ 125131da1fc8SHong Zhang ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPIU_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr); 125224121865SAdrian Maldonado 12535f2c45f1SShri Abhyankar ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr); 12545f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr); 12555f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr); 12565f2c45f1SShri Abhyankar newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart; 12576fefedf4SHong Zhang newDMnetwork->nVertices = newDMnetwork->vEnd - newDMnetwork->vStart; 12586fefedf4SHong Zhang newDMnetwork->NVertices = oldDMnetwork->NVertices; 12595f2c45f1SShri Abhyankar newDMnetwork->NEdges = oldDMnetwork->NEdges; 126024121865SAdrian Maldonado 12611bb6d2a8SBarry Smith /* Set Dof section as the section for dm */ 126292fd8e1eSJed Brown ierr = DMSetLocalSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr); 1263e87a4003SBarry Smith ierr = DMGetGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr); 12645f2c45f1SShri Abhyankar 1265b9c6e19dSShri Abhyankar /* Set up subnetwork info in the newDM */ 1266b9c6e19dSShri Abhyankar newDMnetwork->nsubnet = oldDMnetwork->nsubnet; 1267caf410d2SHong Zhang newDMnetwork->ncsubnet = oldDMnetwork->ncsubnet; 1268b9c6e19dSShri Abhyankar ierr = PetscCalloc1(newDMnetwork->nsubnet,&newDMnetwork->subnet);CHKERRQ(ierr); 1269b9c6e19dSShri Abhyankar /* Copy over the global number of vertices and edges in each subnetwork. Note that these are already 1270b9c6e19dSShri Abhyankar calculated in DMNetworkLayoutSetUp() 1271b9c6e19dSShri Abhyankar */ 1272b9c6e19dSShri Abhyankar for(j=0; j < newDMnetwork->nsubnet; j++) { 1273b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nvtx = oldDMnetwork->subnet[j].Nvtx; 1274b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nedge = oldDMnetwork->subnet[j].Nedge; 1275b9c6e19dSShri Abhyankar } 1276b9c6e19dSShri Abhyankar 1277b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++ ) { 1278b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 1279b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1280b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nedge++; 1281b9c6e19dSShri Abhyankar } 1282b9c6e19dSShri Abhyankar 1283b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++ ) { 1284b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1285b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1286b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nvtx++; 1287b9c6e19dSShri Abhyankar } 1288b9c6e19dSShri Abhyankar 1289b9c6e19dSShri Abhyankar /* Now create the vertices and edge arrays for the subnetworks */ 1290caf410d2SHong Zhang ierr = PetscCalloc1(newDMnetwork->vEnd-newDMnetwork->vStart,&newDMnetwork->subnetvtx);CHKERRQ(ierr); 1291caf410d2SHong Zhang subnetvtx = newDMnetwork->subnetvtx; 1292caf410d2SHong Zhang 1293b9c6e19dSShri Abhyankar for (j=0; j<newDMnetwork->nsubnet; j++) { 1294b9c6e19dSShri Abhyankar ierr = PetscCalloc1(newDMnetwork->subnet[j].nedge,&newDMnetwork->subnet[j].edges);CHKERRQ(ierr); 1295caf410d2SHong Zhang newDMnetwork->subnet[j].vertices = subnetvtx; 1296caf410d2SHong Zhang subnetvtx += newDMnetwork->subnet[j].nvtx; 1297caf410d2SHong Zhang 1298b9c6e19dSShri Abhyankar /* Temporarily setting nvtx and nedge to 0 so we can use them as counters in the below for loop. 1299b9c6e19dSShri Abhyankar These get updated when the vertices and edges are added. */ 1300b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].nvtx = newDMnetwork->subnet[j].nedge = 0; 1301b9c6e19dSShri Abhyankar } 1302b9c6e19dSShri Abhyankar 1303b9c6e19dSShri Abhyankar /* Set the vertices and edges in each subnetwork */ 1304b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++ ) { 1305b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 1306b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1307b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].edges[newDMnetwork->subnet[header->subnetid].nedge++] = e; 1308b9c6e19dSShri Abhyankar } 1309b9c6e19dSShri Abhyankar 1310b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++ ) { 1311b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1312b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1313b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].vertices[newDMnetwork->subnet[header->subnetid].nvtx++] = v; 1314b9c6e19dSShri Abhyankar } 1315b9c6e19dSShri Abhyankar 1316caf410d2SHong Zhang newDM->setupcalled = (*dm)->setupcalled; 131722bbedd7SHong Zhang newDMnetwork->distributecalled = PETSC_TRUE; 1318caf410d2SHong Zhang 131924121865SAdrian Maldonado /* Destroy point SF */ 132024121865SAdrian Maldonado ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr); 132124121865SAdrian Maldonado 1322d3464fd4SAdrian Maldonado ierr = DMDestroy(dm);CHKERRQ(ierr); 1323d3464fd4SAdrian Maldonado *dm = newDM; 13245f2c45f1SShri Abhyankar PetscFunctionReturn(0); 13255f2c45f1SShri Abhyankar } 13265f2c45f1SShri Abhyankar 132724121865SAdrian Maldonado /*@C 132824121865SAdrian Maldonado PetscSFGetSubSF - Returns an SF for a specific subset of points. Leaves are re-numbered to reflect the new ordering. 132924121865SAdrian Maldonado 133024121865SAdrian Maldonado Input Parameters: 133124121865SAdrian Maldonado + masterSF - the original SF structure 133224121865SAdrian Maldonado - map - a ISLocalToGlobal mapping that contains the subset of points 133324121865SAdrian Maldonado 133424121865SAdrian Maldonado Output Parameters: 133524121865SAdrian Maldonado . subSF - a subset of the masterSF for the desired subset. 133624121865SAdrian Maldonado */ 133724121865SAdrian Maldonado 133824121865SAdrian Maldonado PetscErrorCode PetscSFGetSubSF(PetscSF mastersf, ISLocalToGlobalMapping map, PetscSF *subSF) { 133924121865SAdrian Maldonado 134024121865SAdrian Maldonado PetscErrorCode ierr; 134124121865SAdrian Maldonado PetscInt nroots, nleaves, *ilocal_sub; 134224121865SAdrian Maldonado PetscInt i, *ilocal_map, nroots_sub, nleaves_sub = 0; 134324121865SAdrian Maldonado PetscInt *local_points, *remote_points; 134424121865SAdrian Maldonado PetscSFNode *iremote_sub; 134524121865SAdrian Maldonado const PetscInt *ilocal; 134624121865SAdrian Maldonado const PetscSFNode *iremote; 134724121865SAdrian Maldonado 134824121865SAdrian Maldonado PetscFunctionBegin; 134924121865SAdrian Maldonado ierr = PetscSFGetGraph(mastersf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr); 135024121865SAdrian Maldonado 135124121865SAdrian Maldonado /* Look for leaves that pertain to the subset of points. Get the local ordering */ 135224121865SAdrian Maldonado ierr = PetscMalloc1(nleaves,&ilocal_map);CHKERRQ(ierr); 135324121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nleaves,ilocal,NULL,ilocal_map);CHKERRQ(ierr); 135424121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 135524121865SAdrian Maldonado if (ilocal_map[i] != -1) nleaves_sub += 1; 135624121865SAdrian Maldonado } 135724121865SAdrian Maldonado /* Re-number ilocal with subset numbering. Need information from roots */ 135824121865SAdrian Maldonado ierr = PetscMalloc2(nroots,&local_points,nroots,&remote_points);CHKERRQ(ierr); 135924121865SAdrian Maldonado for (i = 0; i < nroots; i++) local_points[i] = i; 136024121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nroots,local_points,NULL,local_points);CHKERRQ(ierr); 136124121865SAdrian Maldonado ierr = PetscSFBcastBegin(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr); 136224121865SAdrian Maldonado ierr = PetscSFBcastEnd(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr); 136324121865SAdrian Maldonado /* Fill up graph using local (that is, local to the subset) numbering. */ 13644b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&ilocal_sub);CHKERRQ(ierr); 13654b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&iremote_sub);CHKERRQ(ierr); 136624121865SAdrian Maldonado nleaves_sub = 0; 136724121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 136824121865SAdrian Maldonado if (ilocal_map[i] != -1) { 136924121865SAdrian Maldonado ilocal_sub[nleaves_sub] = ilocal_map[i]; 13704b70a8deSAdrian Maldonado iremote_sub[nleaves_sub].rank = iremote[i].rank; 137124121865SAdrian Maldonado iremote_sub[nleaves_sub].index = remote_points[ilocal[i]]; 137224121865SAdrian Maldonado nleaves_sub += 1; 137324121865SAdrian Maldonado } 137424121865SAdrian Maldonado } 137524121865SAdrian Maldonado ierr = PetscFree2(local_points,remote_points);CHKERRQ(ierr); 137624121865SAdrian Maldonado ierr = ISLocalToGlobalMappingGetSize(map,&nroots_sub);CHKERRQ(ierr); 137724121865SAdrian Maldonado 137824121865SAdrian Maldonado /* Create new subSF */ 137924121865SAdrian Maldonado ierr = PetscSFCreate(PETSC_COMM_WORLD,subSF);CHKERRQ(ierr); 138024121865SAdrian Maldonado ierr = PetscSFSetFromOptions(*subSF);CHKERRQ(ierr); 13814b70a8deSAdrian Maldonado ierr = PetscSFSetGraph(*subSF,nroots_sub,nleaves_sub,ilocal_sub,PETSC_OWN_POINTER,iremote_sub,PETSC_COPY_VALUES);CHKERRQ(ierr); 138224121865SAdrian Maldonado ierr = PetscFree(ilocal_map);CHKERRQ(ierr); 13834b70a8deSAdrian Maldonado ierr = PetscFree(iremote_sub);CHKERRQ(ierr); 138424121865SAdrian Maldonado PetscFunctionReturn(0); 138524121865SAdrian Maldonado } 138624121865SAdrian Maldonado 13875f2c45f1SShri Abhyankar /*@C 13885f2c45f1SShri Abhyankar DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point 13895f2c45f1SShri Abhyankar 13905f2c45f1SShri Abhyankar Not Collective 13915f2c45f1SShri Abhyankar 13925f2c45f1SShri Abhyankar Input Parameters: 13935f2c45f1SShri Abhyankar + dm - The DMNetwork object 13945f2c45f1SShri Abhyankar - p - the vertex point 13955f2c45f1SShri Abhyankar 13965f2c45f1SShri Abhyankar Output Paramters: 13975f2c45f1SShri Abhyankar + nedges - number of edges connected to this vertex point 13985f2c45f1SShri Abhyankar - edges - List of edge points 13995f2c45f1SShri Abhyankar 14005f2c45f1SShri Abhyankar Level: intermediate 14015f2c45f1SShri Abhyankar 14025f2c45f1SShri Abhyankar Fortran Notes: 14035f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 14045f2c45f1SShri Abhyankar include petsc.h90 in your code. 14055f2c45f1SShri Abhyankar 1406d842c372SHong Zhang .seealso: DMNetworkCreate, DMNetworkGetConnectedVertices 14075f2c45f1SShri Abhyankar @*/ 14085f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[]) 14095f2c45f1SShri Abhyankar { 14105f2c45f1SShri Abhyankar PetscErrorCode ierr; 14115f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 14125f2c45f1SShri Abhyankar 14135f2c45f1SShri Abhyankar PetscFunctionBegin; 14145f2c45f1SShri Abhyankar ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr); 14155f2c45f1SShri Abhyankar ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr); 14165f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14175f2c45f1SShri Abhyankar } 14185f2c45f1SShri Abhyankar 14195f2c45f1SShri Abhyankar /*@C 1420d842c372SHong Zhang DMNetworkGetConnectedVertices - Return the connected vertices for this edge point 14215f2c45f1SShri Abhyankar 14225f2c45f1SShri Abhyankar Not Collective 14235f2c45f1SShri Abhyankar 14245f2c45f1SShri Abhyankar Input Parameters: 14255f2c45f1SShri Abhyankar + dm - The DMNetwork object 14265f2c45f1SShri Abhyankar - p - the edge point 14275f2c45f1SShri Abhyankar 14285f2c45f1SShri Abhyankar Output Paramters: 14295f2c45f1SShri Abhyankar . vertices - vertices connected to this edge 14305f2c45f1SShri Abhyankar 14315f2c45f1SShri Abhyankar Level: intermediate 14325f2c45f1SShri Abhyankar 14335f2c45f1SShri Abhyankar Fortran Notes: 14345f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 14355f2c45f1SShri Abhyankar include petsc.h90 in your code. 14365f2c45f1SShri Abhyankar 14375f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkGetSupportingEdges 14385f2c45f1SShri Abhyankar @*/ 1439d842c372SHong Zhang PetscErrorCode DMNetworkGetConnectedVertices(DM dm,PetscInt edge,const PetscInt *vertices[]) 14405f2c45f1SShri Abhyankar { 14415f2c45f1SShri Abhyankar PetscErrorCode ierr; 14425f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 14435f2c45f1SShri Abhyankar 14445f2c45f1SShri Abhyankar PetscFunctionBegin; 14455f2c45f1SShri Abhyankar ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr); 14465f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14475f2c45f1SShri Abhyankar } 14485f2c45f1SShri Abhyankar 14495f2c45f1SShri Abhyankar /*@ 14505f2c45f1SShri Abhyankar DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex 14515f2c45f1SShri Abhyankar 14525f2c45f1SShri Abhyankar Not Collective 14535f2c45f1SShri Abhyankar 14545f2c45f1SShri Abhyankar Input Parameters: 14555f2c45f1SShri Abhyankar + dm - The DMNetwork object 1456a2b725a8SWilliam Gropp - p - the vertex point 14575f2c45f1SShri Abhyankar 14585f2c45f1SShri Abhyankar Output Parameter: 14595f2c45f1SShri Abhyankar . isghost - TRUE if the vertex is a ghost point 14605f2c45f1SShri Abhyankar 14615f2c45f1SShri Abhyankar Level: intermediate 14625f2c45f1SShri Abhyankar 1463d842c372SHong Zhang .seealso: DMNetworkCreate, DMNetworkGetConnectedVertices, DMNetworkGetVertexRange 14645f2c45f1SShri Abhyankar @*/ 14655f2c45f1SShri Abhyankar PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost) 14665f2c45f1SShri Abhyankar { 14675f2c45f1SShri Abhyankar PetscErrorCode ierr; 14685f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 14695f2c45f1SShri Abhyankar PetscInt offsetg; 14705f2c45f1SShri Abhyankar PetscSection sectiong; 14715f2c45f1SShri Abhyankar 14725f2c45f1SShri Abhyankar PetscFunctionBegin; 1473caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 14745f2c45f1SShri Abhyankar *isghost = PETSC_FALSE; 1475e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§iong);CHKERRQ(ierr); 14765f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr); 14775f2c45f1SShri Abhyankar if (offsetg < 0) *isghost = PETSC_TRUE; 14785f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14795f2c45f1SShri Abhyankar } 14805f2c45f1SShri Abhyankar 14815f2c45f1SShri Abhyankar PetscErrorCode DMSetUp_Network(DM dm) 14825f2c45f1SShri Abhyankar { 14835f2c45f1SShri Abhyankar PetscErrorCode ierr; 14845f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 14855f2c45f1SShri Abhyankar 14865f2c45f1SShri Abhyankar PetscFunctionBegin; 14875f2c45f1SShri Abhyankar ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr); 14885f2c45f1SShri Abhyankar ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr); 14895f2c45f1SShri Abhyankar 149092fd8e1eSJed Brown ierr = DMSetLocalSection(network->plex,network->DofSection);CHKERRQ(ierr); 1491e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr); 14929e1d080bSHong Zhang 14939e1d080bSHong Zhang dm->setupcalled = PETSC_TRUE; 14949e1d080bSHong Zhang ierr = DMViewFromOptions(dm,NULL,"-dm_view");CHKERRQ(ierr); 14955f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14965f2c45f1SShri Abhyankar } 14975f2c45f1SShri Abhyankar 14981ad426b7SHong Zhang /*@ 149917df6e9eSHong Zhang DMNetworkHasJacobian - Sets global flag for using user's sub Jacobian matrices 15001ad426b7SHong Zhang -- replaced by DMNetworkSetOption(network,userjacobian,PETSC_TURE)? 15011ad426b7SHong Zhang 15021ad426b7SHong Zhang Collective 15031ad426b7SHong Zhang 15041ad426b7SHong Zhang Input Parameters: 150583b2e829SHong Zhang + dm - The DMNetwork object 150683b2e829SHong Zhang . eflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for edges 150783b2e829SHong Zhang - vflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for vertices 15081ad426b7SHong Zhang 15091ad426b7SHong Zhang Level: intermediate 15101ad426b7SHong Zhang 15111ad426b7SHong Zhang @*/ 151283b2e829SHong Zhang PetscErrorCode DMNetworkHasJacobian(DM dm,PetscBool eflg,PetscBool vflg) 15131ad426b7SHong Zhang { 15141ad426b7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 15158675203cSHong Zhang PetscErrorCode ierr; 151666b4e0ffSHong Zhang PetscInt nVertices = network->nVertices; 15171ad426b7SHong Zhang 15181ad426b7SHong Zhang PetscFunctionBegin; 151983b2e829SHong Zhang network->userEdgeJacobian = eflg; 152083b2e829SHong Zhang network->userVertexJacobian = vflg; 15218675203cSHong Zhang 15228675203cSHong Zhang if (eflg && !network->Je) { 15238675203cSHong Zhang ierr = PetscCalloc1(3*network->nEdges,&network->Je);CHKERRQ(ierr); 15248675203cSHong Zhang } 15258675203cSHong Zhang 152666b4e0ffSHong Zhang if (vflg && !network->Jv && nVertices) { 15278675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 152866b4e0ffSHong Zhang PetscInt nedges_total; 15298675203cSHong Zhang const PetscInt *edges; 15308675203cSHong Zhang 15318675203cSHong Zhang /* count nvertex_total */ 15328675203cSHong Zhang nedges_total = 0; 15338675203cSHong Zhang ierr = PetscMalloc1(nVertices+1,&vptr);CHKERRQ(ierr); 15348675203cSHong Zhang 15358675203cSHong Zhang vptr[0] = 0; 15368675203cSHong Zhang for (i=0; i<nVertices; i++) { 15378675203cSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,i+vStart,&nedges,&edges);CHKERRQ(ierr); 15388675203cSHong Zhang nedges_total += nedges; 15398675203cSHong Zhang vptr[i+1] = vptr[i] + 2*nedges + 1; 15408675203cSHong Zhang } 15418675203cSHong Zhang 15428675203cSHong Zhang ierr = PetscCalloc1(2*nedges_total+nVertices,&network->Jv);CHKERRQ(ierr); 15438675203cSHong Zhang network->Jvptr = vptr; 15448675203cSHong Zhang } 15451ad426b7SHong Zhang PetscFunctionReturn(0); 15461ad426b7SHong Zhang } 15471ad426b7SHong Zhang 15481ad426b7SHong Zhang /*@ 154983b2e829SHong Zhang DMNetworkEdgeSetMatrix - Sets user-provided Jacobian matrices for this edge to the network 155083b2e829SHong Zhang 155183b2e829SHong Zhang Not Collective 155283b2e829SHong Zhang 155383b2e829SHong Zhang Input Parameters: 155483b2e829SHong Zhang + dm - The DMNetwork object 155583b2e829SHong Zhang . p - the edge point 15563e97b6e8SHong Zhang - J - array (size = 3) of Jacobian submatrices for this edge point: 15573e97b6e8SHong Zhang J[0]: this edge 1558d842c372SHong Zhang J[1] and J[2]: connected vertices, obtained by calling DMNetworkGetConnectedVertices() 155983b2e829SHong Zhang 156083b2e829SHong Zhang Level: intermediate 156183b2e829SHong Zhang 156283b2e829SHong Zhang .seealso: DMNetworkVertexSetMatrix 156383b2e829SHong Zhang @*/ 156483b2e829SHong Zhang PetscErrorCode DMNetworkEdgeSetMatrix(DM dm,PetscInt p,Mat J[]) 156583b2e829SHong Zhang { 156683b2e829SHong Zhang DM_Network *network=(DM_Network*)dm->data; 156783b2e829SHong Zhang 156883b2e829SHong Zhang PetscFunctionBegin; 15698675203cSHong Zhang if (!network->Je) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkEdgeSetMatrix"); 15708675203cSHong Zhang 15718675203cSHong Zhang if (J) { 1572883e35e8SHong Zhang network->Je[3*p] = J[0]; 1573883e35e8SHong Zhang network->Je[3*p+1] = J[1]; 1574883e35e8SHong Zhang network->Je[3*p+2] = J[2]; 15758675203cSHong Zhang } 157683b2e829SHong Zhang PetscFunctionReturn(0); 157783b2e829SHong Zhang } 157883b2e829SHong Zhang 157983b2e829SHong Zhang /*@ 158076ddfea5SHong Zhang DMNetworkVertexSetMatrix - Sets user-provided Jacobian matrix for this vertex to the network 15811ad426b7SHong Zhang 15821ad426b7SHong Zhang Not Collective 15831ad426b7SHong Zhang 15841ad426b7SHong Zhang Input Parameters: 15851ad426b7SHong Zhang + dm - The DMNetwork object 15861ad426b7SHong Zhang . p - the vertex point 15873e97b6e8SHong Zhang - J - array of Jacobian (size = 2*(num of supporting edges) + 1) submatrices for this vertex point: 15883e97b6e8SHong Zhang J[0]: this vertex 15893e97b6e8SHong Zhang J[1+2*i]: i-th supporting edge 15903e97b6e8SHong Zhang J[1+2*i+1]: i-th connected vertex 15911ad426b7SHong Zhang 15921ad426b7SHong Zhang Level: intermediate 15931ad426b7SHong Zhang 159483b2e829SHong Zhang .seealso: DMNetworkEdgeSetMatrix 15951ad426b7SHong Zhang @*/ 1596883e35e8SHong Zhang PetscErrorCode DMNetworkVertexSetMatrix(DM dm,PetscInt p,Mat J[]) 15975f2c45f1SShri Abhyankar { 15985f2c45f1SShri Abhyankar PetscErrorCode ierr; 15995f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 16008675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 1601883e35e8SHong Zhang const PetscInt *edges; 16025f2c45f1SShri Abhyankar 16035f2c45f1SShri Abhyankar PetscFunctionBegin; 16048675203cSHong Zhang if (!network->Jv) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkVertexSetMatrix"); 1605883e35e8SHong Zhang 16068675203cSHong Zhang if (J) { 1607883e35e8SHong Zhang vptr = network->Jvptr; 16083e97b6e8SHong Zhang network->Jv[vptr[p-vStart]] = J[0]; /* Set Jacobian for this vertex */ 16093e97b6e8SHong Zhang 16103e97b6e8SHong Zhang /* Set Jacobian for each supporting edge and connected vertex */ 1611883e35e8SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,p,&nedges,&edges);CHKERRQ(ierr); 1612883e35e8SHong Zhang for (i=1; i<=2*nedges; i++) network->Jv[vptr[p-vStart]+i] = J[i]; 16138675203cSHong Zhang } 1614883e35e8SHong Zhang PetscFunctionReturn(0); 1615883e35e8SHong Zhang } 1616883e35e8SHong Zhang 1617e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 16185cf7da58SHong Zhang { 16195cf7da58SHong Zhang PetscErrorCode ierr; 16205cf7da58SHong Zhang PetscInt j; 16215cf7da58SHong Zhang PetscScalar val=(PetscScalar)ncols; 16225cf7da58SHong Zhang 16235cf7da58SHong Zhang PetscFunctionBegin; 16245cf7da58SHong Zhang if (!ghost) { 16255cf7da58SHong Zhang for (j=0; j<nrows; j++) { 16265cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 16275cf7da58SHong Zhang } 16285cf7da58SHong Zhang } else { 16295cf7da58SHong Zhang for (j=0; j<nrows; j++) { 16305cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 16315cf7da58SHong Zhang } 16325cf7da58SHong Zhang } 16335cf7da58SHong Zhang PetscFunctionReturn(0); 16345cf7da58SHong Zhang } 16355cf7da58SHong Zhang 1636e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 16375cf7da58SHong Zhang { 16385cf7da58SHong Zhang PetscErrorCode ierr; 16395cf7da58SHong Zhang PetscInt j,ncols_u; 16405cf7da58SHong Zhang PetscScalar val; 16415cf7da58SHong Zhang 16425cf7da58SHong Zhang PetscFunctionBegin; 16435cf7da58SHong Zhang if (!ghost) { 16445cf7da58SHong Zhang for (j=0; j<nrows; j++) { 16455cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 16465cf7da58SHong Zhang val = (PetscScalar)ncols_u; 16475cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 16485cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 16495cf7da58SHong Zhang } 16505cf7da58SHong Zhang } else { 16515cf7da58SHong Zhang for (j=0; j<nrows; j++) { 16525cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 16535cf7da58SHong Zhang val = (PetscScalar)ncols_u; 16545cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 16555cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 16565cf7da58SHong Zhang } 16575cf7da58SHong Zhang } 16585cf7da58SHong Zhang PetscFunctionReturn(0); 16595cf7da58SHong Zhang } 16605cf7da58SHong Zhang 1661e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 16625cf7da58SHong Zhang { 16635cf7da58SHong Zhang PetscErrorCode ierr; 16645cf7da58SHong Zhang 16655cf7da58SHong Zhang PetscFunctionBegin; 16665cf7da58SHong Zhang if (Ju) { 16675cf7da58SHong Zhang ierr = MatSetPreallocationUserblock_private(Ju,nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 16685cf7da58SHong Zhang } else { 16695cf7da58SHong Zhang ierr = MatSetPreallocationDenseblock_private(nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 16705cf7da58SHong Zhang } 16715cf7da58SHong Zhang PetscFunctionReturn(0); 16725cf7da58SHong Zhang } 16735cf7da58SHong Zhang 1674e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 1675883e35e8SHong Zhang { 1676883e35e8SHong Zhang PetscErrorCode ierr; 1677883e35e8SHong Zhang PetscInt j,*cols; 1678883e35e8SHong Zhang PetscScalar *zeros; 1679883e35e8SHong Zhang 1680883e35e8SHong Zhang PetscFunctionBegin; 1681883e35e8SHong Zhang ierr = PetscCalloc2(ncols,&cols,nrows*ncols,&zeros);CHKERRQ(ierr); 1682883e35e8SHong Zhang for (j=0; j<ncols; j++) cols[j] = j+ cstart; 1683883e35e8SHong Zhang ierr = MatSetValues(*J,nrows,rows,ncols,cols,zeros,INSERT_VALUES);CHKERRQ(ierr); 1684883e35e8SHong Zhang ierr = PetscFree2(cols,zeros);CHKERRQ(ierr); 16851ad426b7SHong Zhang PetscFunctionReturn(0); 16861ad426b7SHong Zhang } 1687a4e85ca8SHong Zhang 1688e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 16893e97b6e8SHong Zhang { 16903e97b6e8SHong Zhang PetscErrorCode ierr; 16913e97b6e8SHong Zhang PetscInt j,M,N,row,col,ncols_u; 16923e97b6e8SHong Zhang const PetscInt *cols; 16933e97b6e8SHong Zhang PetscScalar zero=0.0; 16943e97b6e8SHong Zhang 16953e97b6e8SHong Zhang PetscFunctionBegin; 16963e97b6e8SHong Zhang ierr = MatGetSize(Ju,&M,&N);CHKERRQ(ierr); 16973e97b6e8SHong 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); 16983e97b6e8SHong Zhang 16993e97b6e8SHong Zhang for (row=0; row<nrows; row++) { 17003e97b6e8SHong Zhang ierr = MatGetRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 17013e97b6e8SHong Zhang for (j=0; j<ncols_u; j++) { 17023e97b6e8SHong Zhang col = cols[j] + cstart; 17033e97b6e8SHong Zhang ierr = MatSetValues(*J,1,&rows[row],1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr); 17043e97b6e8SHong Zhang } 17053e97b6e8SHong Zhang ierr = MatRestoreRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 17063e97b6e8SHong Zhang } 17073e97b6e8SHong Zhang PetscFunctionReturn(0); 17083e97b6e8SHong Zhang } 17091ad426b7SHong Zhang 1710e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 1711a4e85ca8SHong Zhang { 1712a4e85ca8SHong Zhang PetscErrorCode ierr; 1713f4431b8cSHong Zhang 1714a4e85ca8SHong Zhang PetscFunctionBegin; 1715a4e85ca8SHong Zhang if (Ju) { 1716a4e85ca8SHong Zhang ierr = MatSetUserblock_private(Ju,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 1717a4e85ca8SHong Zhang } else { 1718a4e85ca8SHong Zhang ierr = MatSetDenseblock_private(nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 1719a4e85ca8SHong Zhang } 1720a4e85ca8SHong Zhang PetscFunctionReturn(0); 1721a4e85ca8SHong Zhang } 1722a4e85ca8SHong Zhang 172324121865SAdrian 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. 172424121865SAdrian Maldonado */ 172524121865SAdrian Maldonado PetscErrorCode CreateSubGlobalToLocalMapping_private(PetscSection globalsec, PetscSection localsec, ISLocalToGlobalMapping *ltog) 172624121865SAdrian Maldonado { 172724121865SAdrian Maldonado PetscErrorCode ierr; 172824121865SAdrian Maldonado PetscInt i,size,dof; 172924121865SAdrian Maldonado PetscInt *glob2loc; 173024121865SAdrian Maldonado 173124121865SAdrian Maldonado PetscFunctionBegin; 173224121865SAdrian Maldonado ierr = PetscSectionGetStorageSize(localsec,&size);CHKERRQ(ierr); 173324121865SAdrian Maldonado ierr = PetscMalloc1(size,&glob2loc);CHKERRQ(ierr); 173424121865SAdrian Maldonado 173524121865SAdrian Maldonado for (i = 0; i < size; i++) { 173624121865SAdrian Maldonado ierr = PetscSectionGetOffset(globalsec,i,&dof);CHKERRQ(ierr); 173724121865SAdrian Maldonado dof = (dof >= 0) ? dof : -(dof + 1); 173824121865SAdrian Maldonado glob2loc[i] = dof; 173924121865SAdrian Maldonado } 174024121865SAdrian Maldonado 174124121865SAdrian Maldonado ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,size,glob2loc,PETSC_OWN_POINTER,ltog);CHKERRQ(ierr); 174224121865SAdrian Maldonado #if 0 174324121865SAdrian Maldonado ierr = PetscIntView(size,glob2loc,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 174424121865SAdrian Maldonado #endif 174524121865SAdrian Maldonado PetscFunctionReturn(0); 174624121865SAdrian Maldonado } 174724121865SAdrian Maldonado 174801ad2aeeSHong Zhang #include <petsc/private/matimpl.h> 17499e1d080bSHong Zhang 17509e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network_Nest(DM dm,Mat *J) 17511ad426b7SHong Zhang { 17521ad426b7SHong Zhang PetscErrorCode ierr; 17531ad426b7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 17549e1d080bSHong Zhang PetscMPIInt rank, size; 175524121865SAdrian Maldonado PetscInt eDof,vDof; 175624121865SAdrian Maldonado Mat j11,j12,j21,j22,bA[2][2]; 17579e1d080bSHong Zhang MPI_Comm comm; 175824121865SAdrian Maldonado ISLocalToGlobalMapping eISMap,vISMap; 175924121865SAdrian Maldonado 17609e1d080bSHong Zhang PetscFunctionBegin; 176124121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 176224121865SAdrian Maldonado ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 176324121865SAdrian Maldonado ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 176424121865SAdrian Maldonado 176524121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->edge.GlobalDofSection,&eDof);CHKERRQ(ierr); 176624121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->vertex.GlobalDofSection,&vDof);CHKERRQ(ierr); 176724121865SAdrian Maldonado 176801ad2aeeSHong Zhang ierr = MatCreate(comm, &j11);CHKERRQ(ierr); 176924121865SAdrian Maldonado ierr = MatSetSizes(j11, eDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 177024121865SAdrian Maldonado ierr = MatSetType(j11, MATMPIAIJ);CHKERRQ(ierr); 177124121865SAdrian Maldonado 177201ad2aeeSHong Zhang ierr = MatCreate(comm, &j12);CHKERRQ(ierr); 177324121865SAdrian Maldonado ierr = MatSetSizes(j12, eDof, vDof, PETSC_DETERMINE ,PETSC_DETERMINE);CHKERRQ(ierr); 177424121865SAdrian Maldonado ierr = MatSetType(j12, MATMPIAIJ);CHKERRQ(ierr); 177524121865SAdrian Maldonado 177601ad2aeeSHong Zhang ierr = MatCreate(comm, &j21);CHKERRQ(ierr); 177724121865SAdrian Maldonado ierr = MatSetSizes(j21, vDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 177824121865SAdrian Maldonado ierr = MatSetType(j21, MATMPIAIJ);CHKERRQ(ierr); 177924121865SAdrian Maldonado 178001ad2aeeSHong Zhang ierr = MatCreate(comm, &j22);CHKERRQ(ierr); 178124121865SAdrian Maldonado ierr = MatSetSizes(j22, vDof, vDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 178224121865SAdrian Maldonado ierr = MatSetType(j22, MATMPIAIJ);CHKERRQ(ierr); 178324121865SAdrian Maldonado 17843f6a6bdaSHong Zhang bA[0][0] = j11; 17853f6a6bdaSHong Zhang bA[0][1] = j12; 17863f6a6bdaSHong Zhang bA[1][0] = j21; 17873f6a6bdaSHong Zhang bA[1][1] = j22; 178824121865SAdrian Maldonado 178924121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->edge.GlobalDofSection,network->edge.DofSection,&eISMap);CHKERRQ(ierr); 179024121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->vertex.GlobalDofSection,network->vertex.DofSection,&vISMap);CHKERRQ(ierr); 179124121865SAdrian Maldonado 179224121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j11,eISMap,eISMap);CHKERRQ(ierr); 179324121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j12,eISMap,vISMap);CHKERRQ(ierr); 179424121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j21,vISMap,eISMap);CHKERRQ(ierr); 179524121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j22,vISMap,vISMap);CHKERRQ(ierr); 179624121865SAdrian Maldonado 179724121865SAdrian Maldonado ierr = MatSetUp(j11);CHKERRQ(ierr); 179824121865SAdrian Maldonado ierr = MatSetUp(j12);CHKERRQ(ierr); 179924121865SAdrian Maldonado ierr = MatSetUp(j21);CHKERRQ(ierr); 180024121865SAdrian Maldonado ierr = MatSetUp(j22);CHKERRQ(ierr); 180124121865SAdrian Maldonado 180201ad2aeeSHong Zhang ierr = MatCreateNest(comm,2,NULL,2,NULL,&bA[0][0],J);CHKERRQ(ierr); 180324121865SAdrian Maldonado ierr = MatSetUp(*J);CHKERRQ(ierr); 180424121865SAdrian Maldonado ierr = MatNestSetVecType(*J,VECNEST);CHKERRQ(ierr); 180524121865SAdrian Maldonado ierr = MatDestroy(&j11);CHKERRQ(ierr); 180624121865SAdrian Maldonado ierr = MatDestroy(&j12);CHKERRQ(ierr); 180724121865SAdrian Maldonado ierr = MatDestroy(&j21);CHKERRQ(ierr); 180824121865SAdrian Maldonado ierr = MatDestroy(&j22);CHKERRQ(ierr); 180924121865SAdrian Maldonado 181024121865SAdrian Maldonado ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 181124121865SAdrian Maldonado ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18129e1d080bSHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 181324121865SAdrian Maldonado 181424121865SAdrian Maldonado /* Free structures */ 181524121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&eISMap);CHKERRQ(ierr); 181624121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&vISMap);CHKERRQ(ierr); 181724121865SAdrian Maldonado PetscFunctionReturn(0); 18189e1d080bSHong Zhang } 18199e1d080bSHong Zhang 18209e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J) 18219e1d080bSHong Zhang { 18229e1d080bSHong Zhang PetscErrorCode ierr; 18239e1d080bSHong Zhang DM_Network *network = (DM_Network*)dm->data; 18249e1d080bSHong Zhang PetscInt eStart,eEnd,vStart,vEnd,rstart,nrows,*rows,localSize; 18259e1d080bSHong Zhang PetscInt cstart,ncols,j,e,v; 18269e1d080bSHong Zhang PetscBool ghost,ghost_vc,ghost2,isNest; 18279e1d080bSHong Zhang Mat Juser; 18289e1d080bSHong Zhang PetscSection sectionGlobal; 18299e1d080bSHong Zhang PetscInt nedges,*vptr=NULL,vc,*rows_v; /* suppress maybe-uninitialized warning */ 18309e1d080bSHong Zhang const PetscInt *edges,*cone; 18319e1d080bSHong Zhang MPI_Comm comm; 18329e1d080bSHong Zhang MatType mtype; 18339e1d080bSHong Zhang Vec vd_nz,vo_nz; 18349e1d080bSHong Zhang PetscInt *dnnz,*onnz; 18359e1d080bSHong Zhang PetscScalar *vdnz,*vonz; 18369e1d080bSHong Zhang 18379e1d080bSHong Zhang PetscFunctionBegin; 18389e1d080bSHong Zhang mtype = dm->mattype; 18399e1d080bSHong Zhang ierr = PetscStrcmp(mtype,MATNEST,&isNest);CHKERRQ(ierr); 18409e1d080bSHong Zhang if (isNest) { 18419e1d080bSHong Zhang ierr = DMCreateMatrix_Network_Nest(dm,J);CHKERRQ(ierr); 18429e1d080bSHong Zhang PetscFunctionReturn(0); 18439e1d080bSHong Zhang } 18449e1d080bSHong Zhang 18459e1d080bSHong Zhang if (!network->userEdgeJacobian && !network->userVertexJacobian) { 1846a4e85ca8SHong Zhang /* user does not provide Jacobian blocks */ 18479e1d080bSHong Zhang ierr = DMCreateMatrix_Plex(network->plex,J);CHKERRQ(ierr); 1848bfbc38dcSHong Zhang ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 18491ad426b7SHong Zhang PetscFunctionReturn(0); 18501ad426b7SHong Zhang } 18511ad426b7SHong Zhang 1852bfbc38dcSHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)dm),J);CHKERRQ(ierr); 1853e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§ionGlobal);CHKERRQ(ierr); 1854bfbc38dcSHong Zhang ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal,&localSize);CHKERRQ(ierr); 1855bfbc38dcSHong Zhang ierr = MatSetSizes(*J,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 18562a945128SHong Zhang 18572a945128SHong Zhang ierr = MatSetType(*J,MATAIJ);CHKERRQ(ierr); 18582a945128SHong Zhang ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 185989898e50SHong Zhang 186089898e50SHong Zhang /* (1) Set matrix preallocation */ 186189898e50SHong Zhang /*------------------------------*/ 1862840c2264SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 1863840c2264SHong Zhang ierr = VecCreate(comm,&vd_nz);CHKERRQ(ierr); 1864840c2264SHong Zhang ierr = VecSetSizes(vd_nz,localSize,PETSC_DECIDE);CHKERRQ(ierr); 1865840c2264SHong Zhang ierr = VecSetFromOptions(vd_nz);CHKERRQ(ierr); 1866840c2264SHong Zhang ierr = VecSet(vd_nz,0.0);CHKERRQ(ierr); 1867840c2264SHong Zhang ierr = VecDuplicate(vd_nz,&vo_nz);CHKERRQ(ierr); 1868840c2264SHong Zhang 186989898e50SHong Zhang /* Set preallocation for edges */ 187089898e50SHong Zhang /*-----------------------------*/ 1871840c2264SHong Zhang ierr = DMNetworkGetEdgeRange(dm,&eStart,&eEnd);CHKERRQ(ierr); 1872840c2264SHong Zhang 1873bdcb62a2SHong Zhang ierr = PetscMalloc1(localSize,&rows);CHKERRQ(ierr); 1874840c2264SHong Zhang for (e=eStart; e<eEnd; e++) { 1875840c2264SHong Zhang /* Get row indices */ 1876840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr); 1877840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr); 1878840c2264SHong Zhang if (nrows) { 1879840c2264SHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 1880840c2264SHong Zhang 18815cf7da58SHong Zhang /* Set preallocation for conntected vertices */ 1882d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 1883840c2264SHong Zhang for (v=0; v<2; v++) { 1884840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr); 1885840c2264SHong Zhang 18868675203cSHong Zhang if (network->Je) { 1887840c2264SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 18888675203cSHong Zhang } else Juser = NULL; 1889840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,cone[v],&ghost);CHKERRQ(ierr); 18905cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 1891840c2264SHong Zhang } 1892840c2264SHong Zhang 189389898e50SHong Zhang /* Set preallocation for edge self */ 1894840c2264SHong Zhang cstart = rstart; 18958675203cSHong Zhang if (network->Je) { 1896840c2264SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 18978675203cSHong Zhang } else Juser = NULL; 18985cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 1899840c2264SHong Zhang } 1900840c2264SHong Zhang } 1901840c2264SHong Zhang 190289898e50SHong Zhang /* Set preallocation for vertices */ 190389898e50SHong Zhang /*--------------------------------*/ 1904840c2264SHong Zhang ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 19058675203cSHong Zhang if (vEnd - vStart) vptr = network->Jvptr; 1906840c2264SHong Zhang 1907840c2264SHong Zhang for (v=vStart; v<vEnd; v++) { 1908840c2264SHong Zhang /* Get row indices */ 1909840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr); 1910840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr); 1911840c2264SHong Zhang if (!nrows) continue; 1912840c2264SHong Zhang 1913bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 1914bdcb62a2SHong Zhang if (ghost) { 1915bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 1916bdcb62a2SHong Zhang } else { 1917bdcb62a2SHong Zhang rows_v = rows; 1918bdcb62a2SHong Zhang } 1919bdcb62a2SHong Zhang 1920bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 1921840c2264SHong Zhang 1922840c2264SHong Zhang /* Get supporting edges and connected vertices */ 1923840c2264SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 1924840c2264SHong Zhang 1925840c2264SHong Zhang for (e=0; e<nedges; e++) { 1926840c2264SHong Zhang /* Supporting edges */ 1927840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr); 1928840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr); 1929840c2264SHong Zhang 19308675203cSHong Zhang if (network->Jv) { 1931840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 19328675203cSHong Zhang } else Juser = NULL; 1933bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 1934840c2264SHong Zhang 1935840c2264SHong Zhang /* Connected vertices */ 1936d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 1937840c2264SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 1938840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,vc,&ghost_vc);CHKERRQ(ierr); 1939840c2264SHong Zhang 1940840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr); 1941840c2264SHong Zhang 19428675203cSHong Zhang if (network->Jv) { 1943840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 19448675203cSHong Zhang } else Juser = NULL; 1945e102a522SHong Zhang if (ghost_vc||ghost) { 1946e102a522SHong Zhang ghost2 = PETSC_TRUE; 1947e102a522SHong Zhang } else { 1948e102a522SHong Zhang ghost2 = PETSC_FALSE; 1949e102a522SHong Zhang } 1950e102a522SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost2,vd_nz,vo_nz);CHKERRQ(ierr); 1951840c2264SHong Zhang } 1952840c2264SHong Zhang 195389898e50SHong Zhang /* Set preallocation for vertex self */ 1954840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 1955840c2264SHong Zhang if (!ghost) { 1956840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr); 19578675203cSHong Zhang if (network->Jv) { 1958840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 19598675203cSHong Zhang } else Juser = NULL; 1960bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 1961840c2264SHong Zhang } 1962bdcb62a2SHong Zhang if (ghost) { 1963bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 1964bdcb62a2SHong Zhang } 1965840c2264SHong Zhang } 1966840c2264SHong Zhang 1967840c2264SHong Zhang ierr = VecAssemblyBegin(vd_nz);CHKERRQ(ierr); 1968840c2264SHong Zhang ierr = VecAssemblyBegin(vo_nz);CHKERRQ(ierr); 19695cf7da58SHong Zhang 19705cf7da58SHong Zhang ierr = PetscMalloc2(localSize,&dnnz,localSize,&onnz);CHKERRQ(ierr); 19715cf7da58SHong Zhang 19725cf7da58SHong Zhang ierr = VecAssemblyEnd(vd_nz);CHKERRQ(ierr); 1973840c2264SHong Zhang ierr = VecAssemblyEnd(vo_nz);CHKERRQ(ierr); 1974840c2264SHong Zhang 1975840c2264SHong Zhang ierr = VecGetArray(vd_nz,&vdnz);CHKERRQ(ierr); 1976840c2264SHong Zhang ierr = VecGetArray(vo_nz,&vonz);CHKERRQ(ierr); 1977840c2264SHong Zhang for (j=0; j<localSize; j++) { 1978e102a522SHong Zhang dnnz[j] = (PetscInt)PetscRealPart(vdnz[j]); 1979e102a522SHong Zhang onnz[j] = (PetscInt)PetscRealPart(vonz[j]); 1980840c2264SHong Zhang } 1981840c2264SHong Zhang ierr = VecRestoreArray(vd_nz,&vdnz);CHKERRQ(ierr); 1982840c2264SHong Zhang ierr = VecRestoreArray(vo_nz,&vonz);CHKERRQ(ierr); 1983840c2264SHong Zhang ierr = VecDestroy(&vd_nz);CHKERRQ(ierr); 1984840c2264SHong Zhang ierr = VecDestroy(&vo_nz);CHKERRQ(ierr); 1985840c2264SHong Zhang 19865cf7da58SHong Zhang ierr = MatSeqAIJSetPreallocation(*J,0,dnnz);CHKERRQ(ierr); 19875cf7da58SHong Zhang ierr = MatMPIAIJSetPreallocation(*J,0,dnnz,0,onnz);CHKERRQ(ierr); 19885cf7da58SHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 19895cf7da58SHong Zhang 19905cf7da58SHong Zhang ierr = PetscFree2(dnnz,onnz);CHKERRQ(ierr); 19915cf7da58SHong Zhang 199289898e50SHong Zhang /* (2) Set matrix entries for edges */ 199389898e50SHong Zhang /*----------------------------------*/ 19941ad426b7SHong Zhang for (e=eStart; e<eEnd; e++) { 1995bfbc38dcSHong Zhang /* Get row indices */ 19961ad426b7SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr); 199717df6e9eSHong Zhang ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr); 19984b976069SHong Zhang if (nrows) { 199917df6e9eSHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 20001ad426b7SHong Zhang 2001bfbc38dcSHong Zhang /* Set matrix entries for conntected vertices */ 2002d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 2003bfbc38dcSHong Zhang for (v=0; v<2; v++) { 2004bfbc38dcSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,cone[v],&cstart);CHKERRQ(ierr); 2005883e35e8SHong Zhang ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr); 20063e97b6e8SHong Zhang 20078675203cSHong Zhang if (network->Je) { 2008a4e85ca8SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 20098675203cSHong Zhang } else Juser = NULL; 2010a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 2011bfbc38dcSHong Zhang } 201217df6e9eSHong Zhang 2013bfbc38dcSHong Zhang /* Set matrix entries for edge self */ 20143e97b6e8SHong Zhang cstart = rstart; 20158675203cSHong Zhang if (network->Je) { 2016a4e85ca8SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 20178675203cSHong Zhang } else Juser = NULL; 2018a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,nrows,cstart,J);CHKERRQ(ierr); 20191ad426b7SHong Zhang } 20204b976069SHong Zhang } 20211ad426b7SHong Zhang 2022bfbc38dcSHong Zhang /* Set matrix entries for vertices */ 202383b2e829SHong Zhang /*---------------------------------*/ 20241ad426b7SHong Zhang for (v=vStart; v<vEnd; v++) { 2025bfbc38dcSHong Zhang /* Get row indices */ 2026596e729fSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr); 2027596e729fSHong Zhang ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr); 20284b976069SHong Zhang if (!nrows) continue; 2029596e729fSHong Zhang 2030bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 2031bdcb62a2SHong Zhang if (ghost) { 2032bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 2033bdcb62a2SHong Zhang } else { 2034bdcb62a2SHong Zhang rows_v = rows; 2035bdcb62a2SHong Zhang } 2036bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 2037596e729fSHong Zhang 2038bfbc38dcSHong Zhang /* Get supporting edges and connected vertices */ 2039596e729fSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 2040596e729fSHong Zhang 2041596e729fSHong Zhang for (e=0; e<nedges; e++) { 2042bfbc38dcSHong Zhang /* Supporting edges */ 2043596e729fSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr); 2044596e729fSHong Zhang ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr); 2045596e729fSHong Zhang 20468675203cSHong Zhang if (network->Jv) { 2047a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 20488675203cSHong Zhang } else Juser = NULL; 2049bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 2050596e729fSHong Zhang 2051bfbc38dcSHong Zhang /* Connected vertices */ 2052d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 20532a945128SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 20542a945128SHong Zhang 205544aca652SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,vc,&cstart);CHKERRQ(ierr); 205644aca652SHong Zhang ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr); 2057a4e85ca8SHong Zhang 20588675203cSHong Zhang if (network->Jv) { 2059a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 20608675203cSHong Zhang } else Juser = NULL; 2061bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 2062596e729fSHong Zhang } 2063596e729fSHong Zhang 2064bfbc38dcSHong Zhang /* Set matrix entries for vertex self */ 20651ad426b7SHong Zhang if (!ghost) { 2066596e729fSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr); 20678675203cSHong Zhang if (network->Jv) { 2068a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 20698675203cSHong Zhang } else Juser = NULL; 2070bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,nrows,cstart,J);CHKERRQ(ierr); 2071bdcb62a2SHong Zhang } 2072bdcb62a2SHong Zhang if (ghost) { 2073bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 2074bdcb62a2SHong Zhang } 20751ad426b7SHong Zhang } 2076a4e85ca8SHong Zhang ierr = PetscFree(rows);CHKERRQ(ierr); 2077bdcb62a2SHong Zhang 20781ad426b7SHong Zhang ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20791ad426b7SHong Zhang ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2080dd6f46cdSHong Zhang 20815f2c45f1SShri Abhyankar ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 20825f2c45f1SShri Abhyankar PetscFunctionReturn(0); 20835f2c45f1SShri Abhyankar } 20845f2c45f1SShri Abhyankar 20855f2c45f1SShri Abhyankar PetscErrorCode DMDestroy_Network(DM dm) 20865f2c45f1SShri Abhyankar { 20875f2c45f1SShri Abhyankar PetscErrorCode ierr; 20885f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 20892727e31bSShri Abhyankar PetscInt j; 20905f2c45f1SShri Abhyankar 20915f2c45f1SShri Abhyankar PetscFunctionBegin; 20928415c774SShri Abhyankar if (--network->refct > 0) PetscFunctionReturn(0); 209383b2e829SHong Zhang if (network->Je) { 209483b2e829SHong Zhang ierr = PetscFree(network->Je);CHKERRQ(ierr); 209583b2e829SHong Zhang } 209683b2e829SHong Zhang if (network->Jv) { 2097883e35e8SHong Zhang ierr = PetscFree(network->Jvptr);CHKERRQ(ierr); 209883b2e829SHong Zhang ierr = PetscFree(network->Jv);CHKERRQ(ierr); 20991ad426b7SHong Zhang } 210013c2a604SAdrian Maldonado 210113c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->vertex.mapping);CHKERRQ(ierr); 210213c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.DofSection);CHKERRQ(ierr); 210313c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.GlobalDofSection);CHKERRQ(ierr); 2104f5427c60SHong Zhang if (network->vltog) { 2105f5427c60SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 2106f5427c60SHong Zhang } 210713c2a604SAdrian Maldonado if (network->vertex.sf) { 210813c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->vertex.sf);CHKERRQ(ierr); 210913c2a604SAdrian Maldonado } 211013c2a604SAdrian Maldonado /* edge */ 211113c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->edge.mapping);CHKERRQ(ierr); 211213c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.DofSection);CHKERRQ(ierr); 211313c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.GlobalDofSection);CHKERRQ(ierr); 211413c2a604SAdrian Maldonado if (network->edge.sf) { 211513c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->edge.sf);CHKERRQ(ierr); 211613c2a604SAdrian Maldonado } 21175f2c45f1SShri Abhyankar ierr = DMDestroy(&network->plex);CHKERRQ(ierr); 21185f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr); 21195f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr); 212083b2e829SHong Zhang 21212727e31bSShri Abhyankar for(j=0; j<network->nsubnet; j++) { 21222727e31bSShri Abhyankar ierr = PetscFree(network->subnet[j].edges);CHKERRQ(ierr); 21232727e31bSShri Abhyankar } 2124caf410d2SHong Zhang ierr = PetscFree(network->subnetvtx);CHKERRQ(ierr); 2125caf410d2SHong Zhang 2126e2aaf10cSShri Abhyankar ierr = PetscFree(network->subnet);CHKERRQ(ierr); 21275f2c45f1SShri Abhyankar ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr); 2128caf410d2SHong Zhang ierr = PetscFree2(network->header,network->cvalue);CHKERRQ(ierr); 21295f2c45f1SShri Abhyankar ierr = PetscFree(network);CHKERRQ(ierr); 21305f2c45f1SShri Abhyankar PetscFunctionReturn(0); 21315f2c45f1SShri Abhyankar } 21325f2c45f1SShri Abhyankar 21335f2c45f1SShri Abhyankar PetscErrorCode DMView_Network(DM dm,PetscViewer viewer) 21345f2c45f1SShri Abhyankar { 21355f2c45f1SShri Abhyankar PetscErrorCode ierr; 21365f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 2137caf410d2SHong Zhang PetscBool iascii; 2138caf410d2SHong Zhang PetscMPIInt rank; 2139caf410d2SHong Zhang PetscInt p,nsubnet; 21405f2c45f1SShri Abhyankar 21415f2c45f1SShri Abhyankar PetscFunctionBegin; 2142caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 2143caf410d2SHong Zhang ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 2144caf410d2SHong Zhang PetscValidHeaderSpecific(dm,DM_CLASSID, 1); 2145caf410d2SHong Zhang PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2146caf410d2SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 2147caf410d2SHong Zhang if (iascii) { 2148caf410d2SHong Zhang const PetscInt *cone,*vtx,*edges; 2149caf410d2SHong Zhang PetscInt vfrom,vto,i,j,nv,ne; 2150caf410d2SHong Zhang 2151caf410d2SHong Zhang nsubnet = network->nsubnet - network->ncsubnet; /* num of subnetworks */ 2152caf410d2SHong Zhang ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 2153caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " [%d] nsubnet: %D; nsubnetCouple: %D; nEdges: %D; nVertices: %D\n",rank,nsubnet,network->ncsubnet,network->nEdges,network->nVertices);CHKERRQ(ierr); 2154caf410d2SHong Zhang 2155caf410d2SHong Zhang for (i=0; i<nsubnet; i++) { 2156caf410d2SHong Zhang ierr = DMNetworkGetSubnetworkInfo(dm,i,&nv,&ne,&vtx,&edges);CHKERRQ(ierr); 2157caf410d2SHong Zhang if (ne) { 2158caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " Subnet %D: nEdges %D, nVertices %D\n",i,ne,nv);CHKERRQ(ierr); 2159caf410d2SHong Zhang for (j=0; j<ne; j++) { 2160caf410d2SHong Zhang p = edges[j]; 2161caf410d2SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,p,&cone);CHKERRQ(ierr); 2162caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[0],&vfrom);CHKERRQ(ierr); 2163caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[1],&vto);CHKERRQ(ierr); 2164caf410d2SHong Zhang ierr = DMNetworkGetGlobalEdgeIndex(dm,edges[j],&p);CHKERRQ(ierr); 2165caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " edge %D: %D----> %D\n",p,vfrom,vto);CHKERRQ(ierr); 2166caf410d2SHong Zhang } 2167caf410d2SHong Zhang } 2168caf410d2SHong Zhang } 2169caf410d2SHong Zhang /* Coupling subnets */ 2170caf410d2SHong Zhang nsubnet = network->nsubnet; 2171caf410d2SHong Zhang for (; i<nsubnet; i++) { 2172caf410d2SHong Zhang ierr = DMNetworkGetSubnetworkInfo(dm,i,&nv,&ne,&vtx,&edges);CHKERRQ(ierr); 2173caf410d2SHong Zhang if (ne) { 2174caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " Subnet %D (couple): nEdges %D, nVertices %D\n",i,ne,nv);CHKERRQ(ierr); 2175caf410d2SHong Zhang for (j=0; j<ne; j++) { 2176caf410d2SHong Zhang p = edges[j]; 2177caf410d2SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,p,&cone);CHKERRQ(ierr); 2178caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[0],&vfrom);CHKERRQ(ierr); 2179caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[1],&vto);CHKERRQ(ierr); 2180caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " edge %D: %D----> %D\n",p,vfrom,vto);CHKERRQ(ierr); 2181caf410d2SHong Zhang } 2182caf410d2SHong Zhang } 2183caf410d2SHong Zhang } 2184caf410d2SHong Zhang ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2185caf410d2SHong Zhang ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 2186caf410d2SHong Zhang } else SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMNetwork writing", ((PetscObject)viewer)->type_name); 21875f2c45f1SShri Abhyankar PetscFunctionReturn(0); 21885f2c45f1SShri Abhyankar } 21895f2c45f1SShri Abhyankar 21905f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l) 21915f2c45f1SShri Abhyankar { 21925f2c45f1SShri Abhyankar PetscErrorCode ierr; 21935f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 21945f2c45f1SShri Abhyankar 21955f2c45f1SShri Abhyankar PetscFunctionBegin; 21965f2c45f1SShri Abhyankar ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr); 21975f2c45f1SShri Abhyankar PetscFunctionReturn(0); 21985f2c45f1SShri Abhyankar } 21995f2c45f1SShri Abhyankar 22005f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l) 22015f2c45f1SShri Abhyankar { 22025f2c45f1SShri Abhyankar PetscErrorCode ierr; 22035f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 22045f2c45f1SShri Abhyankar 22055f2c45f1SShri Abhyankar PetscFunctionBegin; 22065f2c45f1SShri Abhyankar ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr); 22075f2c45f1SShri Abhyankar PetscFunctionReturn(0); 22085f2c45f1SShri Abhyankar } 22095f2c45f1SShri Abhyankar 22105f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g) 22115f2c45f1SShri Abhyankar { 22125f2c45f1SShri Abhyankar PetscErrorCode ierr; 22135f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 22145f2c45f1SShri Abhyankar 22155f2c45f1SShri Abhyankar PetscFunctionBegin; 22165f2c45f1SShri Abhyankar ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr); 22175f2c45f1SShri Abhyankar PetscFunctionReturn(0); 22185f2c45f1SShri Abhyankar } 22195f2c45f1SShri Abhyankar 22205f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g) 22215f2c45f1SShri Abhyankar { 22225f2c45f1SShri Abhyankar PetscErrorCode ierr; 22235f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 22245f2c45f1SShri Abhyankar 22255f2c45f1SShri Abhyankar PetscFunctionBegin; 22265f2c45f1SShri Abhyankar ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr); 22275f2c45f1SShri Abhyankar PetscFunctionReturn(0); 22285f2c45f1SShri Abhyankar } 222922bbedd7SHong Zhang 223022bbedd7SHong Zhang /*@ 2231b2aacc82SHong Zhang DMNetworkGetVertexLocalToGlobalOrdering - Get vertex globle index 223222bbedd7SHong Zhang 223322bbedd7SHong Zhang Not collective 223422bbedd7SHong Zhang 223522bbedd7SHong Zhang Input Parameters 223622bbedd7SHong Zhang + dm - the dm object 223722bbedd7SHong Zhang - vloc - local vertex ordering, start from 0 223822bbedd7SHong Zhang 223922bbedd7SHong Zhang Output Parameters 224022bbedd7SHong Zhang + vg - global vertex ordering, start from 0 224122bbedd7SHong Zhang 224222bbedd7SHong Zhang Level: Advanced 224322bbedd7SHong Zhang 224422bbedd7SHong Zhang .seealso: DMNetworkSetVertexLocalToGlobalOrdering() 224522bbedd7SHong Zhang @*/ 224622bbedd7SHong Zhang PetscErrorCode DMNetworkGetVertexLocalToGlobalOrdering(DM dm,PetscInt vloc,PetscInt *vg) 224722bbedd7SHong Zhang { 224822bbedd7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 224922bbedd7SHong Zhang PetscInt *vltog = network->vltog; 225022bbedd7SHong Zhang 225122bbedd7SHong Zhang PetscFunctionBegin; 225222bbedd7SHong Zhang if (!vltog) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkSetVertexLocalToGlobalOrdering() first"); 225322bbedd7SHong Zhang *vg = vltog[vloc]; 225422bbedd7SHong Zhang PetscFunctionReturn(0); 225522bbedd7SHong Zhang } 225622bbedd7SHong Zhang 225722bbedd7SHong Zhang /*@ 225822bbedd7SHong Zhang DMNetworkSetVertexLocalToGlobalOrdering - Create and setup vertex local to globle map 225922bbedd7SHong Zhang 226022bbedd7SHong Zhang Collective 226122bbedd7SHong Zhang 226222bbedd7SHong Zhang Input Parameters: 226322bbedd7SHong Zhang + dm - the dm object 226422bbedd7SHong Zhang 226522bbedd7SHong Zhang Level: Advanced 226622bbedd7SHong Zhang 226763029d29SHong Zhang .seealso: DMNetworkGetGlobalVertexIndex() 226822bbedd7SHong Zhang @*/ 226922bbedd7SHong Zhang PetscErrorCode DMNetworkSetVertexLocalToGlobalOrdering(DM dm) 227022bbedd7SHong Zhang { 227122bbedd7SHong Zhang PetscErrorCode ierr; 227222bbedd7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 227322bbedd7SHong Zhang MPI_Comm comm; 227463029d29SHong Zhang PetscMPIInt rank,size,*displs,*recvcounts,remoterank; 227522bbedd7SHong Zhang PetscBool ghost; 227663029d29SHong Zhang PetscInt *vltog,nroots,nleaves,i,*vrange,k,N,lidx; 227722bbedd7SHong Zhang const PetscSFNode *iremote; 227822bbedd7SHong Zhang PetscSF vsf; 227963029d29SHong Zhang Vec Vleaves,Vleaves_seq; 228063029d29SHong Zhang VecScatter ctx; 228163029d29SHong Zhang PetscScalar *varr,val; 228263029d29SHong Zhang const PetscScalar *varr_read; 228322bbedd7SHong Zhang 228422bbedd7SHong Zhang PetscFunctionBegin; 228522bbedd7SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 228622bbedd7SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 228763029d29SHong Zhang ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 228822bbedd7SHong Zhang 228922bbedd7SHong Zhang if (size == 1) { 229022bbedd7SHong Zhang nroots = network->vEnd - network->vStart; 229122bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 229222bbedd7SHong Zhang for (i=0; i<nroots; i++) vltog[i] = i; 229322bbedd7SHong Zhang network->vltog = vltog; 229422bbedd7SHong Zhang PetscFunctionReturn(0); 229522bbedd7SHong Zhang } 229622bbedd7SHong Zhang 229722bbedd7SHong Zhang if (!network->distributecalled) SETERRQ(comm, PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkDistribute() first"); 229822bbedd7SHong Zhang if (network->vltog) { 229922bbedd7SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 230022bbedd7SHong Zhang } 230122bbedd7SHong Zhang 230222bbedd7SHong Zhang ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 230322bbedd7SHong Zhang ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 230422bbedd7SHong Zhang vsf = network->vertex.sf; 230522bbedd7SHong Zhang 230622bbedd7SHong Zhang ierr = PetscMalloc3(size+1,&vrange,size+1,&displs,size,&recvcounts);CHKERRQ(ierr); 2307f5427c60SHong Zhang ierr = PetscSFGetGraph(vsf,&nroots,&nleaves,NULL,&iremote);CHKERRQ(ierr); 230822bbedd7SHong Zhang 230922bbedd7SHong Zhang for (i=0; i<size; i++) { displs[i] = i; recvcounts[i] = 1;} 231022bbedd7SHong Zhang 231122bbedd7SHong Zhang i = nroots - nleaves; /* local number of vertices, excluding ghosts */ 231222bbedd7SHong Zhang vrange[0] = 0; 231322bbedd7SHong Zhang ierr = MPI_Allgatherv(&i,1,MPIU_INT,vrange+1,recvcounts,displs,MPIU_INT,comm);CHKERRQ(ierr); 231467dd800bSHong Zhang for (i=2; i<size+1; i++) {vrange[i] += vrange[i-1];} 231522bbedd7SHong Zhang 231622bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 231722bbedd7SHong Zhang network->vltog = vltog; 231822bbedd7SHong Zhang 231963029d29SHong Zhang /* Set vltog for non-ghost vertices */ 232063029d29SHong Zhang k = 0; 232122bbedd7SHong Zhang for (i=0; i<nroots; i++) { 232222bbedd7SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 232363029d29SHong Zhang if (ghost) continue; 232463029d29SHong Zhang vltog[i] = vrange[rank] + k++; 232522bbedd7SHong Zhang } 2326f5427c60SHong Zhang ierr = PetscFree3(vrange,displs,recvcounts);CHKERRQ(ierr); 232763029d29SHong Zhang 232863029d29SHong Zhang /* Set vltog for ghost vertices */ 232963029d29SHong Zhang /* (a) create parallel Vleaves and sequential Vleaves_seq to convert local iremote[*].index to global index */ 233063029d29SHong Zhang ierr = VecCreate(comm,&Vleaves);CHKERRQ(ierr); 233163029d29SHong Zhang ierr = VecSetSizes(Vleaves,2*nleaves,PETSC_DETERMINE);CHKERRQ(ierr); 233263029d29SHong Zhang ierr = VecSetFromOptions(Vleaves);CHKERRQ(ierr); 233363029d29SHong Zhang ierr = VecGetArray(Vleaves,&varr);CHKERRQ(ierr); 233463029d29SHong Zhang for (i=0; i<nleaves; i++) { 233563029d29SHong Zhang varr[2*i] = (PetscScalar)(iremote[i].rank); /* rank of remote process */ 233663029d29SHong Zhang varr[2*i+1] = (PetscScalar)(iremote[i].index); /* local index in remote process */ 233763029d29SHong Zhang } 233863029d29SHong Zhang ierr = VecRestoreArray(Vleaves,&varr);CHKERRQ(ierr); 233963029d29SHong Zhang 234063029d29SHong Zhang /* (b) scatter local info to remote processes via VecScatter() */ 234163029d29SHong Zhang ierr = VecScatterCreateToAll(Vleaves,&ctx,&Vleaves_seq);CHKERRQ(ierr); 234263029d29SHong Zhang ierr = VecScatterBegin(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 234363029d29SHong Zhang ierr = VecScatterEnd(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 234463029d29SHong Zhang 234563029d29SHong Zhang /* (c) convert local indices to global indices in parallel vector Vleaves */ 234663029d29SHong Zhang ierr = VecGetSize(Vleaves_seq,&N);CHKERRQ(ierr); 234763029d29SHong Zhang ierr = VecGetArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 234863029d29SHong Zhang for (i=0; i<N; i+=2) { 23492e4cff2eSHong Zhang remoterank = (PetscMPIInt)PetscRealPart(varr_read[i]); 235063029d29SHong Zhang if (remoterank == rank) { 235163029d29SHong Zhang k = i+1; /* row number */ 23522e4cff2eSHong Zhang lidx = (PetscInt)PetscRealPart(varr_read[i+1]); 235363029d29SHong Zhang val = (PetscScalar)vltog[lidx]; /* global index for non-ghost vertex computed above */ 235463029d29SHong Zhang ierr = VecSetValues(Vleaves,1,&k,&val,INSERT_VALUES);CHKERRQ(ierr); 235563029d29SHong Zhang } 235663029d29SHong Zhang } 235763029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 235863029d29SHong Zhang ierr = VecAssemblyBegin(Vleaves);CHKERRQ(ierr); 235963029d29SHong Zhang ierr = VecAssemblyEnd(Vleaves);CHKERRQ(ierr); 236063029d29SHong Zhang 236163029d29SHong Zhang /* (d) Set vltog for ghost vertices by copying local values of Vleaves */ 236263029d29SHong Zhang ierr = VecGetArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 236363029d29SHong Zhang k = 0; 236463029d29SHong Zhang for (i=0; i<nroots; i++) { 236563029d29SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 236663029d29SHong Zhang if (!ghost) continue; 23672e4cff2eSHong Zhang vltog[i] = (PetscInt)PetscRealPart(varr_read[2*k+1]); k++; 236863029d29SHong Zhang } 236963029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 237063029d29SHong Zhang 237163029d29SHong Zhang ierr = VecDestroy(&Vleaves);CHKERRQ(ierr); 237263029d29SHong Zhang ierr = VecDestroy(&Vleaves_seq);CHKERRQ(ierr); 237363029d29SHong Zhang ierr = VecScatterDestroy(&ctx);CHKERRQ(ierr); 237422bbedd7SHong Zhang PetscFunctionReturn(0); 237522bbedd7SHong Zhang } 2376