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; 3349988b915SShri 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; 3759988b915SShri 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 507fd292e60Sprj- Output Parameters: 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 533fd292e60Sprj- Output Parameters: 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 560fd292e60Sprj- Output Parameters: 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 591fd292e60Sprj- Output Parameters: 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]; 7279988b915SShri 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 /*@ 7359988b915SShri Abhyankar DMNetworkSetComponentNumVariables - Sets the number of variables for a component 7369988b915SShri Abhyankar 7379988b915SShri Abhyankar Not Collective 7389988b915SShri Abhyankar 7399988b915SShri Abhyankar Input Parameters: 7409988b915SShri Abhyankar + dm - The DMNetwork object 7419988b915SShri Abhyankar . p - vertex/edge point 7429988b915SShri Abhyankar . compnum - component number (First component added = 0, second = 1, ...) 7439988b915SShri Abhyankar - nvar - number of variables for the component 7449988b915SShri Abhyankar 7459988b915SShri Abhyankar Level: intermediate 7469988b915SShri Abhyankar 7479dacc45bSShrirang Abhyankar .seealso: DMNetworkAddComponent(), DMNetworkGetNumComponents(),DMNetworkRegisterComponent() 7489988b915SShri Abhyankar @*/ 7499988b915SShri Abhyankar PetscErrorCode DMNetworkSetComponentNumVariables(DM dm, PetscInt p,PetscInt compnum,PetscInt nvar) 7509988b915SShri Abhyankar { 7519988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 7529988b915SShri Abhyankar DMNetworkComponentHeader header = &network->header[p]; 7539988b915SShri Abhyankar PetscErrorCode ierr; 7549988b915SShri Abhyankar 7559988b915SShri Abhyankar PetscFunctionBegin; 7569988b915SShri Abhyankar ierr = DMNetworkAddNumVariables(dm,p,nvar);CHKERRQ(ierr); 7579988b915SShri Abhyankar header->nvar[compnum] = nvar; 7589988b915SShri Abhyankar if (compnum != 0) header->offsetvarrel[compnum] = header->offsetvarrel[compnum-1] + header->nvar[compnum-1]; 7599988b915SShri Abhyankar PetscFunctionReturn(0); 7609988b915SShri Abhyankar } 7619988b915SShri Abhyankar 7629988b915SShri Abhyankar /*@ 7635f2c45f1SShri Abhyankar DMNetworkGetNumComponents - Get the number of components at a vertex/edge 7645f2c45f1SShri Abhyankar 7655f2c45f1SShri Abhyankar Not Collective 7665f2c45f1SShri Abhyankar 7675f2c45f1SShri Abhyankar Input Parameters: 7685f2c45f1SShri Abhyankar + dm - The DMNetwork object 769a2b725a8SWilliam Gropp - p - vertex/edge point 7705f2c45f1SShri Abhyankar 7715f2c45f1SShri Abhyankar Output Parameters: 7725f2c45f1SShri Abhyankar . numcomponents - Number of components at the vertex/edge 7735f2c45f1SShri Abhyankar 7745f2c45f1SShri Abhyankar Level: intermediate 7755f2c45f1SShri Abhyankar 7765f2c45f1SShri Abhyankar .seealso: DMNetworkRegisterComponent, DMNetworkAddComponent 7775f2c45f1SShri Abhyankar @*/ 7785f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetNumComponents(DM dm,PetscInt p,PetscInt *numcomponents) 7795f2c45f1SShri Abhyankar { 7805f2c45f1SShri Abhyankar PetscErrorCode ierr; 7815f2c45f1SShri Abhyankar PetscInt offset; 7825f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 7835f2c45f1SShri Abhyankar 7845f2c45f1SShri Abhyankar PetscFunctionBegin; 7855f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 7865f2c45f1SShri Abhyankar *numcomponents = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 7875f2c45f1SShri Abhyankar PetscFunctionReturn(0); 7885f2c45f1SShri Abhyankar } 7895f2c45f1SShri Abhyankar 7905f2c45f1SShri Abhyankar /*@ 7915f2c45f1SShri Abhyankar DMNetworkGetVariableOffset - Get the offset for accessing the variable associated with the given vertex/edge from the local vector. 7925f2c45f1SShri Abhyankar 7935f2c45f1SShri Abhyankar Not Collective 7945f2c45f1SShri Abhyankar 7955f2c45f1SShri Abhyankar Input Parameters: 7965f2c45f1SShri Abhyankar + dm - The DMNetwork object 7975f2c45f1SShri Abhyankar - p - the edge/vertex point 7985f2c45f1SShri Abhyankar 7995f2c45f1SShri Abhyankar Output Parameters: 8005f2c45f1SShri Abhyankar . offset - the offset 8015f2c45f1SShri Abhyankar 8025f2c45f1SShri Abhyankar Level: intermediate 8035f2c45f1SShri Abhyankar 8045f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 8055f2c45f1SShri Abhyankar @*/ 8065f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableOffset(DM dm,PetscInt p,PetscInt *offset) 8075f2c45f1SShri Abhyankar { 8085f2c45f1SShri Abhyankar PetscErrorCode ierr; 8095f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 8105f2c45f1SShri Abhyankar 8115f2c45f1SShri Abhyankar PetscFunctionBegin; 8121bb6d2a8SBarry Smith ierr = PetscSectionGetOffset(network->plex->localSection,p,offset);CHKERRQ(ierr); 8135f2c45f1SShri Abhyankar PetscFunctionReturn(0); 8145f2c45f1SShri Abhyankar } 8155f2c45f1SShri Abhyankar 8165f2c45f1SShri Abhyankar /*@ 8175f2c45f1SShri Abhyankar DMNetworkGetVariableGlobalOffset - Get the global offset for the variable associated with the given vertex/edge from the global vector. 8185f2c45f1SShri Abhyankar 8195f2c45f1SShri Abhyankar Not Collective 8205f2c45f1SShri Abhyankar 8215f2c45f1SShri Abhyankar Input Parameters: 8225f2c45f1SShri Abhyankar + dm - The DMNetwork object 8235f2c45f1SShri Abhyankar - p - the edge/vertex point 8245f2c45f1SShri Abhyankar 8255f2c45f1SShri Abhyankar Output Parameters: 8265f2c45f1SShri Abhyankar . offsetg - the offset 8275f2c45f1SShri Abhyankar 8285f2c45f1SShri Abhyankar Level: intermediate 8295f2c45f1SShri Abhyankar 8305f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableOffset, DMGetLocalVector 8315f2c45f1SShri Abhyankar @*/ 8325f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableGlobalOffset(DM dm,PetscInt p,PetscInt *offsetg) 8335f2c45f1SShri Abhyankar { 8345f2c45f1SShri Abhyankar PetscErrorCode ierr; 8355f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 8365f2c45f1SShri Abhyankar 8375f2c45f1SShri Abhyankar PetscFunctionBegin; 8381bb6d2a8SBarry Smith ierr = PetscSectionGetOffset(network->plex->globalSection,p,offsetg);CHKERRQ(ierr); 8396fefedf4SHong Zhang if (*offsetg < 0) *offsetg = -(*offsetg + 1); /* Convert to actual global offset for ghost vertex */ 8405f2c45f1SShri Abhyankar PetscFunctionReturn(0); 8415f2c45f1SShri Abhyankar } 8425f2c45f1SShri Abhyankar 84324121865SAdrian Maldonado /*@ 8449988b915SShri Abhyankar DMNetworkGetComponentVariableOffset - Get the offset for accessing the variable associated with a component for the given vertex/edge from the local vector. 8459988b915SShri Abhyankar 8469988b915SShri Abhyankar Not Collective 8479988b915SShri Abhyankar 8489988b915SShri Abhyankar Input Parameters: 8499988b915SShri Abhyankar + dm - The DMNetwork object 8509988b915SShri Abhyankar . compnum - component number 8519988b915SShri Abhyankar - p - the edge/vertex point 8529988b915SShri Abhyankar 8539988b915SShri Abhyankar Output Parameters: 8549988b915SShri Abhyankar . offset - the offset 8559988b915SShri Abhyankar 8569988b915SShri Abhyankar Level: intermediate 8579988b915SShri Abhyankar 8589dacc45bSShrirang Abhyankar .seealso: DMNetworkGetVariableGlobalOffset(), DMGetLocalVector(), DMNetworkSetComponentNumVariables() 8599988b915SShri Abhyankar @*/ 8609988b915SShri Abhyankar PetscErrorCode DMNetworkGetComponentVariableOffset(DM dm,PetscInt p,PetscInt compnum,PetscInt *offset) 8619988b915SShri Abhyankar { 8629988b915SShri Abhyankar PetscErrorCode ierr; 8639988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 8649988b915SShri Abhyankar PetscInt offsetp,offsetd; 8659988b915SShri Abhyankar DMNetworkComponentHeader header; 8669988b915SShri Abhyankar 8679988b915SShri Abhyankar PetscFunctionBegin; 8689988b915SShri Abhyankar ierr = DMNetworkGetVariableOffset(dm,p,&offsetp);CHKERRQ(ierr); 8699988b915SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetd);CHKERRQ(ierr); 8709988b915SShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetd); 8719988b915SShri Abhyankar *offset = offsetp + header->offsetvarrel[compnum]; 8729988b915SShri Abhyankar PetscFunctionReturn(0); 8739988b915SShri Abhyankar } 8749988b915SShri Abhyankar 8759988b915SShri Abhyankar /*@ 8769988b915SShri Abhyankar DMNetworkGetComponentVariableGlobalOffset - Get the global offset for accessing the variable associated with a component for the given vertex/edge from the local vector. 8779988b915SShri Abhyankar 8789988b915SShri Abhyankar Not Collective 8799988b915SShri Abhyankar 8809988b915SShri Abhyankar Input Parameters: 8819988b915SShri Abhyankar + dm - The DMNetwork object 8829988b915SShri Abhyankar . compnum - component number 8839988b915SShri Abhyankar - p - the edge/vertex point 8849988b915SShri Abhyankar 8859988b915SShri Abhyankar Output Parameters: 8869988b915SShri Abhyankar . offsetg - the global offset 8879988b915SShri Abhyankar 8889988b915SShri Abhyankar Level: intermediate 8899988b915SShri Abhyankar 8909dacc45bSShrirang Abhyankar .seealso: DMNetworkGetVariableGlobalOffset(), DMNetworkGetComponentVariableOffset(), DMGetLocalVector(), DMNetworkSetComponentNumVariables() 8919988b915SShri Abhyankar @*/ 8929988b915SShri Abhyankar PetscErrorCode DMNetworkGetComponentVariableGlobalOffset(DM dm,PetscInt p,PetscInt compnum,PetscInt *offsetg) 8939988b915SShri Abhyankar { 8949988b915SShri Abhyankar PetscErrorCode ierr; 8959988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 8969988b915SShri Abhyankar PetscInt offsetp,offsetd; 8979988b915SShri Abhyankar DMNetworkComponentHeader header; 8989988b915SShri Abhyankar 8999988b915SShri Abhyankar PetscFunctionBegin; 9009988b915SShri Abhyankar ierr = DMNetworkGetVariableGlobalOffset(dm,p,&offsetp);CHKERRQ(ierr); 9019988b915SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetd);CHKERRQ(ierr); 9029988b915SShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetd); 9039988b915SShri Abhyankar *offsetg = offsetp + header->offsetvarrel[compnum]; 9049988b915SShri Abhyankar PetscFunctionReturn(0); 9059988b915SShri Abhyankar } 9069988b915SShri Abhyankar 9079988b915SShri Abhyankar /*@ 90824121865SAdrian Maldonado DMNetworkGetEdgeOffset - Get the offset for accessing the variable associated with the given edge from the local subvector. 90924121865SAdrian Maldonado 91024121865SAdrian Maldonado Not Collective 91124121865SAdrian Maldonado 91224121865SAdrian Maldonado Input Parameters: 91324121865SAdrian Maldonado + dm - The DMNetwork object 91424121865SAdrian Maldonado - p - the edge point 91524121865SAdrian Maldonado 91624121865SAdrian Maldonado Output Parameters: 91724121865SAdrian Maldonado . offset - the offset 91824121865SAdrian Maldonado 91924121865SAdrian Maldonado Level: intermediate 92024121865SAdrian Maldonado 92124121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 92224121865SAdrian Maldonado @*/ 92324121865SAdrian Maldonado PetscErrorCode DMNetworkGetEdgeOffset(DM dm,PetscInt p,PetscInt *offset) 92424121865SAdrian Maldonado { 92524121865SAdrian Maldonado PetscErrorCode ierr; 92624121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 92724121865SAdrian Maldonado 92824121865SAdrian Maldonado PetscFunctionBegin; 92924121865SAdrian Maldonado 93024121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->edge.DofSection,p,offset);CHKERRQ(ierr); 93124121865SAdrian Maldonado PetscFunctionReturn(0); 93224121865SAdrian Maldonado } 93324121865SAdrian Maldonado 93424121865SAdrian Maldonado /*@ 93524121865SAdrian Maldonado DMNetworkGetVertexOffset - Get the offset for accessing the variable associated with the given vertex from the local subvector. 93624121865SAdrian Maldonado 93724121865SAdrian Maldonado Not Collective 93824121865SAdrian Maldonado 93924121865SAdrian Maldonado Input Parameters: 94024121865SAdrian Maldonado + dm - The DMNetwork object 94124121865SAdrian Maldonado - p - the vertex point 94224121865SAdrian Maldonado 94324121865SAdrian Maldonado Output Parameters: 94424121865SAdrian Maldonado . offset - the offset 94524121865SAdrian Maldonado 94624121865SAdrian Maldonado Level: intermediate 94724121865SAdrian Maldonado 94824121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 94924121865SAdrian Maldonado @*/ 95024121865SAdrian Maldonado PetscErrorCode DMNetworkGetVertexOffset(DM dm,PetscInt p,PetscInt *offset) 95124121865SAdrian Maldonado { 95224121865SAdrian Maldonado PetscErrorCode ierr; 95324121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 95424121865SAdrian Maldonado 95524121865SAdrian Maldonado PetscFunctionBegin; 95624121865SAdrian Maldonado 95724121865SAdrian Maldonado p -= network->vStart; 95824121865SAdrian Maldonado 95924121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->vertex.DofSection,p,offset);CHKERRQ(ierr); 96024121865SAdrian Maldonado PetscFunctionReturn(0); 96124121865SAdrian Maldonado } 9625f2c45f1SShri Abhyankar /*@ 9635f2c45f1SShri Abhyankar DMNetworkAddNumVariables - Add number of variables associated with a given point. 9645f2c45f1SShri Abhyankar 9655f2c45f1SShri Abhyankar Not Collective 9665f2c45f1SShri Abhyankar 9675f2c45f1SShri Abhyankar Input Parameters: 9685f2c45f1SShri Abhyankar + dm - The DMNetworkObject 9695f2c45f1SShri Abhyankar . p - the vertex/edge point 9705f2c45f1SShri Abhyankar - nvar - number of additional variables 9715f2c45f1SShri Abhyankar 9725f2c45f1SShri Abhyankar Level: intermediate 9735f2c45f1SShri Abhyankar 9745f2c45f1SShri Abhyankar .seealso: DMNetworkSetNumVariables 9755f2c45f1SShri Abhyankar @*/ 9765f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddNumVariables(DM dm,PetscInt p,PetscInt nvar) 9775f2c45f1SShri Abhyankar { 9785f2c45f1SShri Abhyankar PetscErrorCode ierr; 9795f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 9805f2c45f1SShri Abhyankar 9815f2c45f1SShri Abhyankar PetscFunctionBegin; 9825f2c45f1SShri Abhyankar ierr = PetscSectionAddDof(network->DofSection,p,nvar);CHKERRQ(ierr); 9835f2c45f1SShri Abhyankar PetscFunctionReturn(0); 9845f2c45f1SShri Abhyankar } 9855f2c45f1SShri Abhyankar 98627f51fceSHong Zhang /*@ 98727f51fceSHong Zhang DMNetworkGetNumVariables - Gets number of variables for a vertex/edge point. 98827f51fceSHong Zhang 98927f51fceSHong Zhang Not Collective 99027f51fceSHong Zhang 99127f51fceSHong Zhang Input Parameters: 99227f51fceSHong Zhang + dm - The DMNetworkObject 99327f51fceSHong Zhang - p - the vertex/edge point 99427f51fceSHong Zhang 99527f51fceSHong Zhang Output Parameters: 99627f51fceSHong Zhang . nvar - number of variables 99727f51fceSHong Zhang 99827f51fceSHong Zhang Level: intermediate 99927f51fceSHong Zhang 100027f51fceSHong Zhang .seealso: DMNetworkAddNumVariables, DMNetworkSddNumVariables 100127f51fceSHong Zhang @*/ 100227f51fceSHong Zhang PetscErrorCode DMNetworkGetNumVariables(DM dm,PetscInt p,PetscInt *nvar) 100327f51fceSHong Zhang { 100427f51fceSHong Zhang PetscErrorCode ierr; 100527f51fceSHong Zhang DM_Network *network = (DM_Network*)dm->data; 100627f51fceSHong Zhang 100727f51fceSHong Zhang PetscFunctionBegin; 100827f51fceSHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 100927f51fceSHong Zhang PetscFunctionReturn(0); 101027f51fceSHong Zhang } 101127f51fceSHong Zhang 10125f2c45f1SShri Abhyankar /*@ 10135f2c45f1SShri Abhyankar DMNetworkSetNumVariables - Sets number of variables for a vertex/edge point. 10145f2c45f1SShri Abhyankar 10155f2c45f1SShri Abhyankar Not Collective 10165f2c45f1SShri Abhyankar 10175f2c45f1SShri Abhyankar Input Parameters: 10185f2c45f1SShri Abhyankar + dm - The DMNetworkObject 10195f2c45f1SShri Abhyankar . p - the vertex/edge point 10205f2c45f1SShri Abhyankar - nvar - number of variables 10215f2c45f1SShri Abhyankar 10225f2c45f1SShri Abhyankar Level: intermediate 10235f2c45f1SShri Abhyankar 10245f2c45f1SShri Abhyankar .seealso: DMNetworkAddNumVariables 10255f2c45f1SShri Abhyankar @*/ 10265f2c45f1SShri Abhyankar PetscErrorCode DMNetworkSetNumVariables(DM dm,PetscInt p,PetscInt nvar) 10275f2c45f1SShri Abhyankar { 10285f2c45f1SShri Abhyankar PetscErrorCode ierr; 10295f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10305f2c45f1SShri Abhyankar 10315f2c45f1SShri Abhyankar PetscFunctionBegin; 10325f2c45f1SShri Abhyankar ierr = PetscSectionSetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 10335f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10345f2c45f1SShri Abhyankar } 10355f2c45f1SShri Abhyankar 10365f2c45f1SShri Abhyankar /* Sets up the array that holds the data for all components and its associated section. This 10375f2c45f1SShri Abhyankar function is called during DMSetUp() */ 10385f2c45f1SShri Abhyankar PetscErrorCode DMNetworkComponentSetUp(DM dm) 10395f2c45f1SShri Abhyankar { 10405f2c45f1SShri Abhyankar PetscErrorCode ierr; 10415f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 1042e53b5ba3SHong Zhang PetscInt arr_size,p,offset,offsetp,ncomp,i; 10435f2c45f1SShri Abhyankar DMNetworkComponentHeader header; 10445f2c45f1SShri Abhyankar DMNetworkComponentValue cvalue; 10455f2c45f1SShri Abhyankar DMNetworkComponentGenericDataType *componentdataarray; 10465f2c45f1SShri Abhyankar 10475f2c45f1SShri Abhyankar PetscFunctionBegin; 10485f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr); 10495f2c45f1SShri Abhyankar ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr); 105075b160a0SShri Abhyankar ierr = PetscMalloc1(arr_size,&network->componentdataarray);CHKERRQ(ierr); 10515f2c45f1SShri Abhyankar componentdataarray = network->componentdataarray; 10525f2c45f1SShri Abhyankar for (p = network->pStart; p < network->pEnd; p++) { 10535f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 10545f2c45f1SShri Abhyankar /* Copy header */ 10555f2c45f1SShri Abhyankar header = &network->header[p]; 1056302440fdSBarry Smith ierr = PetscMemcpy(componentdataarray+offsetp,header,network->dataheadersize*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 10575f2c45f1SShri Abhyankar /* Copy data */ 10585f2c45f1SShri Abhyankar cvalue = &network->cvalue[p]; 10595f2c45f1SShri Abhyankar ncomp = header->ndata; 10605f2c45f1SShri Abhyankar for (i = 0; i < ncomp; i++) { 10615f2c45f1SShri Abhyankar offset = offsetp + network->dataheadersize + header->offset[i]; 1062302440fdSBarry Smith ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 10635f2c45f1SShri Abhyankar } 10645f2c45f1SShri Abhyankar } 10655f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10665f2c45f1SShri Abhyankar } 10675f2c45f1SShri Abhyankar 10685f2c45f1SShri Abhyankar /* Sets up the section for dofs. This routine is called during DMSetUp() */ 10695f2c45f1SShri Abhyankar PetscErrorCode DMNetworkVariablesSetUp(DM dm) 10705f2c45f1SShri Abhyankar { 10715f2c45f1SShri Abhyankar PetscErrorCode ierr; 10725f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10735f2c45f1SShri Abhyankar 10745f2c45f1SShri Abhyankar PetscFunctionBegin; 10755f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr); 10765f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10775f2c45f1SShri Abhyankar } 10785f2c45f1SShri Abhyankar 10795f2c45f1SShri Abhyankar /*@C 10805f2c45f1SShri Abhyankar DMNetworkGetComponentDataArray - Returns the component data array 10815f2c45f1SShri Abhyankar 10825f2c45f1SShri Abhyankar Not Collective 10835f2c45f1SShri Abhyankar 10845f2c45f1SShri Abhyankar Input Parameters: 10855f2c45f1SShri Abhyankar . dm - The DMNetwork Object 10865f2c45f1SShri Abhyankar 10875f2c45f1SShri Abhyankar Output Parameters: 10885f2c45f1SShri Abhyankar . componentdataarray - array that holds data for all components 10895f2c45f1SShri Abhyankar 10905f2c45f1SShri Abhyankar Level: intermediate 10915f2c45f1SShri Abhyankar 1092a730d845SHong Zhang .seealso: DMNetworkGetComponentKeyOffset, DMNetworkGetNumComponents 10935f2c45f1SShri Abhyankar @*/ 10945f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetComponentDataArray(DM dm,DMNetworkComponentGenericDataType **componentdataarray) 10955f2c45f1SShri Abhyankar { 10965f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10975f2c45f1SShri Abhyankar 10985f2c45f1SShri Abhyankar PetscFunctionBegin; 10995f2c45f1SShri Abhyankar *componentdataarray = network->componentdataarray; 11005f2c45f1SShri Abhyankar PetscFunctionReturn(0); 11015f2c45f1SShri Abhyankar } 11025f2c45f1SShri Abhyankar 110324121865SAdrian Maldonado /* Get a subsection from a range of points */ 110424121865SAdrian Maldonado PetscErrorCode DMNetworkGetSubSection_private(PetscSection master, PetscInt pstart, PetscInt pend,PetscSection *subsection) 110524121865SAdrian Maldonado { 110624121865SAdrian Maldonado PetscErrorCode ierr; 110724121865SAdrian Maldonado PetscInt i, nvar; 110824121865SAdrian Maldonado 110924121865SAdrian Maldonado PetscFunctionBegin; 111024121865SAdrian Maldonado ierr = PetscSectionCreate(PetscObjectComm((PetscObject)master), subsection);CHKERRQ(ierr); 111124121865SAdrian Maldonado ierr = PetscSectionSetChart(*subsection, 0, pend - pstart);CHKERRQ(ierr); 111224121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 111324121865SAdrian Maldonado ierr = PetscSectionGetDof(master,i,&nvar);CHKERRQ(ierr); 111424121865SAdrian Maldonado ierr = PetscSectionSetDof(*subsection, i - pstart, nvar);CHKERRQ(ierr); 111524121865SAdrian Maldonado } 111624121865SAdrian Maldonado 111724121865SAdrian Maldonado ierr = PetscSectionSetUp(*subsection);CHKERRQ(ierr); 111824121865SAdrian Maldonado PetscFunctionReturn(0); 111924121865SAdrian Maldonado } 112024121865SAdrian Maldonado 112124121865SAdrian Maldonado /* Create a submap of points with a GlobalToLocal structure */ 112224121865SAdrian Maldonado PetscErrorCode DMNetworkSetSubMap_private(PetscInt pstart, PetscInt pend, ISLocalToGlobalMapping *map) 112324121865SAdrian Maldonado { 112424121865SAdrian Maldonado PetscErrorCode ierr; 112524121865SAdrian Maldonado PetscInt i, *subpoints; 112624121865SAdrian Maldonado 112724121865SAdrian Maldonado PetscFunctionBegin; 112824121865SAdrian Maldonado /* Create index sets to map from "points" to "subpoints" */ 112924121865SAdrian Maldonado ierr = PetscMalloc1(pend - pstart, &subpoints);CHKERRQ(ierr); 113024121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 113124121865SAdrian Maldonado subpoints[i - pstart] = i; 113224121865SAdrian Maldonado } 1133459726d8SSatish Balay ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,pend-pstart,subpoints,PETSC_COPY_VALUES,map);CHKERRQ(ierr); 113424121865SAdrian Maldonado ierr = PetscFree(subpoints);CHKERRQ(ierr); 113524121865SAdrian Maldonado PetscFunctionReturn(0); 113624121865SAdrian Maldonado } 113724121865SAdrian Maldonado 113824121865SAdrian Maldonado /*@ 113924121865SAdrian Maldonado DMNetworkAssembleGraphStructures - Assembles vertex and edge data structures. Must be called after DMNetworkDistribute. 114024121865SAdrian Maldonado 114124121865SAdrian Maldonado Collective 114224121865SAdrian Maldonado 114324121865SAdrian Maldonado Input Parameters: 114424121865SAdrian Maldonado . dm - The DMNetworkObject 114524121865SAdrian Maldonado 114624121865SAdrian Maldonado Note: the routine will create alternative orderings for the vertices and edges. Assume global network points are: 114724121865SAdrian Maldonado 114824121865SAdrian Maldonado points = [0 1 2 3 4 5 6] 114924121865SAdrian Maldonado 1150caf410d2SHong 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]). 115124121865SAdrian Maldonado 115224121865SAdrian Maldonado With this new ordering a local PetscSection, global PetscSection and PetscSF will be created specific to the subset. 115324121865SAdrian Maldonado 115424121865SAdrian Maldonado Level: intermediate 115524121865SAdrian Maldonado 115624121865SAdrian Maldonado @*/ 115724121865SAdrian Maldonado PetscErrorCode DMNetworkAssembleGraphStructures(DM dm) 115824121865SAdrian Maldonado { 115924121865SAdrian Maldonado PetscErrorCode ierr; 116024121865SAdrian Maldonado MPI_Comm comm; 11619852e123SBarry Smith PetscMPIInt rank, size; 116224121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 116324121865SAdrian Maldonado 1164eab1376dSHong Zhang PetscFunctionBegin; 116524121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 116624121865SAdrian Maldonado ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 11679852e123SBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 116824121865SAdrian Maldonado 116924121865SAdrian Maldonado /* Create maps for vertices and edges */ 117024121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 117124121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->eStart,network->eEnd,&network->edge.mapping);CHKERRQ(ierr); 117224121865SAdrian Maldonado 117324121865SAdrian Maldonado /* Create local sub-sections */ 117424121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->vStart,network->vEnd,&network->vertex.DofSection);CHKERRQ(ierr); 117524121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->eStart,network->eEnd,&network->edge.DofSection);CHKERRQ(ierr); 117624121865SAdrian Maldonado 11779852e123SBarry Smith if (size > 1) { 117824121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 117922bbedd7SHong Zhang 118024121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->vertex.DofSection, network->vertex.sf, PETSC_FALSE, PETSC_FALSE, &network->vertex.GlobalDofSection);CHKERRQ(ierr); 118124121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->edge.mapping, &network->edge.sf);CHKERRQ(ierr); 118224121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->edge.DofSection, network->edge.sf, PETSC_FALSE, PETSC_FALSE, &network->edge.GlobalDofSection);CHKERRQ(ierr); 118324121865SAdrian Maldonado } else { 118424121865SAdrian Maldonado /* create structures for vertex */ 118524121865SAdrian Maldonado ierr = PetscSectionClone(network->vertex.DofSection,&network->vertex.GlobalDofSection);CHKERRQ(ierr); 118624121865SAdrian Maldonado /* create structures for edge */ 118724121865SAdrian Maldonado ierr = PetscSectionClone(network->edge.DofSection,&network->edge.GlobalDofSection);CHKERRQ(ierr); 118824121865SAdrian Maldonado } 118924121865SAdrian Maldonado 119024121865SAdrian Maldonado /* Add viewers */ 119124121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->edge.GlobalDofSection,"Global edge dof section");CHKERRQ(ierr); 119224121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->vertex.GlobalDofSection,"Global vertex dof section");CHKERRQ(ierr); 119324121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->edge.GlobalDofSection, NULL, "-edge_global_section_view");CHKERRQ(ierr); 119424121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->vertex.GlobalDofSection, NULL, "-vertex_global_section_view");CHKERRQ(ierr); 119524121865SAdrian Maldonado PetscFunctionReturn(0); 119624121865SAdrian Maldonado } 11977b6afd5bSHong Zhang 11985f2c45f1SShri Abhyankar /*@ 11995f2c45f1SShri Abhyankar DMNetworkDistribute - Distributes the network and moves associated component data. 12005f2c45f1SShri Abhyankar 12015f2c45f1SShri Abhyankar Collective 12025f2c45f1SShri Abhyankar 12035f2c45f1SShri Abhyankar Input Parameter: 1204d3464fd4SAdrian Maldonado + DM - the DMNetwork object 12055f2c45f1SShri Abhyankar - overlap - The overlap of partitions, 0 is the default 12065f2c45f1SShri Abhyankar 12075f2c45f1SShri Abhyankar Notes: 12088b171c8eSHong Zhang Distributes the network with <overlap>-overlapping partitioning of the edges. 12095f2c45f1SShri Abhyankar 12105f2c45f1SShri Abhyankar Level: intermediate 12115f2c45f1SShri Abhyankar 12125f2c45f1SShri Abhyankar .seealso: DMNetworkCreate 12135f2c45f1SShri Abhyankar @*/ 1214d3464fd4SAdrian Maldonado PetscErrorCode DMNetworkDistribute(DM *dm,PetscInt overlap) 12155f2c45f1SShri Abhyankar { 1216d3464fd4SAdrian Maldonado MPI_Comm comm; 12175f2c45f1SShri Abhyankar PetscErrorCode ierr; 1218d3464fd4SAdrian Maldonado PetscMPIInt size; 1219d3464fd4SAdrian Maldonado DM_Network *oldDMnetwork = (DM_Network*)((*dm)->data); 1220d3464fd4SAdrian Maldonado DM_Network *newDMnetwork; 1221caf410d2SHong Zhang PetscSF pointsf=NULL; 12225f2c45f1SShri Abhyankar DM newDM; 1223caf410d2SHong Zhang PetscInt j,e,v,offset,*subnetvtx; 122451ac5effSHong Zhang PetscPartitioner part; 1225b9c6e19dSShri Abhyankar DMNetworkComponentHeader header; 12265f2c45f1SShri Abhyankar 12275f2c45f1SShri Abhyankar PetscFunctionBegin; 1228d3464fd4SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)*dm,&comm);CHKERRQ(ierr); 1229d3464fd4SAdrian Maldonado ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 1230d3464fd4SAdrian Maldonado if (size == 1) PetscFunctionReturn(0); 1231d3464fd4SAdrian Maldonado 1232d3464fd4SAdrian Maldonado ierr = DMNetworkCreate(PetscObjectComm((PetscObject)*dm),&newDM);CHKERRQ(ierr); 12335f2c45f1SShri Abhyankar newDMnetwork = (DM_Network*)newDM->data; 12345f2c45f1SShri Abhyankar newDMnetwork->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 123551ac5effSHong Zhang 123651ac5effSHong Zhang /* Enable runtime options for petscpartitioner */ 123751ac5effSHong Zhang ierr = DMPlexGetPartitioner(oldDMnetwork->plex,&part);CHKERRQ(ierr); 123851ac5effSHong Zhang ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); 123951ac5effSHong Zhang 12405f2c45f1SShri Abhyankar /* Distribute plex dm and dof section */ 124180cf41d5SMatthew G. Knepley ierr = DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr); 124251ac5effSHong Zhang 12435f2c45f1SShri Abhyankar /* Distribute dof section */ 1244d3464fd4SAdrian Maldonado ierr = PetscSectionCreate(PetscObjectComm((PetscObject)*dm),&newDMnetwork->DofSection);CHKERRQ(ierr); 12455f2c45f1SShri Abhyankar ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr); 1246d3464fd4SAdrian Maldonado ierr = PetscSectionCreate(PetscObjectComm((PetscObject)*dm),&newDMnetwork->DataSection);CHKERRQ(ierr); 124751ac5effSHong Zhang 12485f2c45f1SShri Abhyankar /* Distribute data and associated section */ 124931da1fc8SHong Zhang ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPIU_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr); 125024121865SAdrian Maldonado 12515f2c45f1SShri Abhyankar ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr); 12525f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr); 12535f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr); 12545f2c45f1SShri Abhyankar newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart; 12556fefedf4SHong Zhang newDMnetwork->nVertices = newDMnetwork->vEnd - newDMnetwork->vStart; 12566fefedf4SHong Zhang newDMnetwork->NVertices = oldDMnetwork->NVertices; 12575f2c45f1SShri Abhyankar newDMnetwork->NEdges = oldDMnetwork->NEdges; 125824121865SAdrian Maldonado 12591bb6d2a8SBarry Smith /* Set Dof section as the section for dm */ 126092fd8e1eSJed Brown ierr = DMSetLocalSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr); 1261e87a4003SBarry Smith ierr = DMGetGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr); 12625f2c45f1SShri Abhyankar 1263b9c6e19dSShri Abhyankar /* Set up subnetwork info in the newDM */ 1264b9c6e19dSShri Abhyankar newDMnetwork->nsubnet = oldDMnetwork->nsubnet; 1265caf410d2SHong Zhang newDMnetwork->ncsubnet = oldDMnetwork->ncsubnet; 1266b9c6e19dSShri Abhyankar ierr = PetscCalloc1(newDMnetwork->nsubnet,&newDMnetwork->subnet);CHKERRQ(ierr); 1267b9c6e19dSShri Abhyankar /* Copy over the global number of vertices and edges in each subnetwork. Note that these are already 1268b9c6e19dSShri Abhyankar calculated in DMNetworkLayoutSetUp() 1269b9c6e19dSShri Abhyankar */ 1270b9c6e19dSShri Abhyankar for(j=0; j < newDMnetwork->nsubnet; j++) { 1271b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nvtx = oldDMnetwork->subnet[j].Nvtx; 1272b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nedge = oldDMnetwork->subnet[j].Nedge; 1273b9c6e19dSShri Abhyankar } 1274b9c6e19dSShri Abhyankar 1275b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++ ) { 1276b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 1277b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1278b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nedge++; 1279b9c6e19dSShri Abhyankar } 1280b9c6e19dSShri Abhyankar 1281b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++ ) { 1282b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1283b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1284b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nvtx++; 1285b9c6e19dSShri Abhyankar } 1286b9c6e19dSShri Abhyankar 1287b9c6e19dSShri Abhyankar /* Now create the vertices and edge arrays for the subnetworks */ 1288caf410d2SHong Zhang ierr = PetscCalloc1(newDMnetwork->vEnd-newDMnetwork->vStart,&newDMnetwork->subnetvtx);CHKERRQ(ierr); 1289caf410d2SHong Zhang subnetvtx = newDMnetwork->subnetvtx; 1290caf410d2SHong Zhang 1291b9c6e19dSShri Abhyankar for (j=0; j<newDMnetwork->nsubnet; j++) { 1292b9c6e19dSShri Abhyankar ierr = PetscCalloc1(newDMnetwork->subnet[j].nedge,&newDMnetwork->subnet[j].edges);CHKERRQ(ierr); 1293caf410d2SHong Zhang newDMnetwork->subnet[j].vertices = subnetvtx; 1294caf410d2SHong Zhang subnetvtx += newDMnetwork->subnet[j].nvtx; 1295caf410d2SHong Zhang 1296b9c6e19dSShri Abhyankar /* Temporarily setting nvtx and nedge to 0 so we can use them as counters in the below for loop. 1297b9c6e19dSShri Abhyankar These get updated when the vertices and edges are added. */ 1298b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].nvtx = newDMnetwork->subnet[j].nedge = 0; 1299b9c6e19dSShri Abhyankar } 1300b9c6e19dSShri Abhyankar 1301b9c6e19dSShri Abhyankar /* Set the vertices and edges in each subnetwork */ 1302b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++ ) { 1303b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 1304b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1305b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].edges[newDMnetwork->subnet[header->subnetid].nedge++] = e; 1306b9c6e19dSShri Abhyankar } 1307b9c6e19dSShri Abhyankar 1308b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++ ) { 1309b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1310b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1311b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].vertices[newDMnetwork->subnet[header->subnetid].nvtx++] = v; 1312b9c6e19dSShri Abhyankar } 1313b9c6e19dSShri Abhyankar 1314caf410d2SHong Zhang newDM->setupcalled = (*dm)->setupcalled; 131522bbedd7SHong Zhang newDMnetwork->distributecalled = PETSC_TRUE; 1316caf410d2SHong Zhang 131724121865SAdrian Maldonado /* Destroy point SF */ 131824121865SAdrian Maldonado ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr); 131924121865SAdrian Maldonado 1320d3464fd4SAdrian Maldonado ierr = DMDestroy(dm);CHKERRQ(ierr); 1321d3464fd4SAdrian Maldonado *dm = newDM; 13225f2c45f1SShri Abhyankar PetscFunctionReturn(0); 13235f2c45f1SShri Abhyankar } 13245f2c45f1SShri Abhyankar 132524121865SAdrian Maldonado /*@C 132624121865SAdrian Maldonado PetscSFGetSubSF - Returns an SF for a specific subset of points. Leaves are re-numbered to reflect the new ordering. 132724121865SAdrian Maldonado 132824121865SAdrian Maldonado Input Parameters: 132924121865SAdrian Maldonado + masterSF - the original SF structure 133024121865SAdrian Maldonado - map - a ISLocalToGlobal mapping that contains the subset of points 133124121865SAdrian Maldonado 133224121865SAdrian Maldonado Output Parameters: 133324121865SAdrian Maldonado . subSF - a subset of the masterSF for the desired subset. 133424121865SAdrian Maldonado */ 133524121865SAdrian Maldonado 133624121865SAdrian Maldonado PetscErrorCode PetscSFGetSubSF(PetscSF mastersf, ISLocalToGlobalMapping map, PetscSF *subSF) { 133724121865SAdrian Maldonado 133824121865SAdrian Maldonado PetscErrorCode ierr; 133924121865SAdrian Maldonado PetscInt nroots, nleaves, *ilocal_sub; 134024121865SAdrian Maldonado PetscInt i, *ilocal_map, nroots_sub, nleaves_sub = 0; 134124121865SAdrian Maldonado PetscInt *local_points, *remote_points; 134224121865SAdrian Maldonado PetscSFNode *iremote_sub; 134324121865SAdrian Maldonado const PetscInt *ilocal; 134424121865SAdrian Maldonado const PetscSFNode *iremote; 134524121865SAdrian Maldonado 134624121865SAdrian Maldonado PetscFunctionBegin; 134724121865SAdrian Maldonado ierr = PetscSFGetGraph(mastersf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr); 134824121865SAdrian Maldonado 134924121865SAdrian Maldonado /* Look for leaves that pertain to the subset of points. Get the local ordering */ 135024121865SAdrian Maldonado ierr = PetscMalloc1(nleaves,&ilocal_map);CHKERRQ(ierr); 135124121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nleaves,ilocal,NULL,ilocal_map);CHKERRQ(ierr); 135224121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 135324121865SAdrian Maldonado if (ilocal_map[i] != -1) nleaves_sub += 1; 135424121865SAdrian Maldonado } 135524121865SAdrian Maldonado /* Re-number ilocal with subset numbering. Need information from roots */ 135624121865SAdrian Maldonado ierr = PetscMalloc2(nroots,&local_points,nroots,&remote_points);CHKERRQ(ierr); 135724121865SAdrian Maldonado for (i = 0; i < nroots; i++) local_points[i] = i; 135824121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nroots,local_points,NULL,local_points);CHKERRQ(ierr); 135924121865SAdrian Maldonado ierr = PetscSFBcastBegin(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr); 136024121865SAdrian Maldonado ierr = PetscSFBcastEnd(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr); 136124121865SAdrian Maldonado /* Fill up graph using local (that is, local to the subset) numbering. */ 13624b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&ilocal_sub);CHKERRQ(ierr); 13634b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&iremote_sub);CHKERRQ(ierr); 136424121865SAdrian Maldonado nleaves_sub = 0; 136524121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 136624121865SAdrian Maldonado if (ilocal_map[i] != -1) { 136724121865SAdrian Maldonado ilocal_sub[nleaves_sub] = ilocal_map[i]; 13684b70a8deSAdrian Maldonado iremote_sub[nleaves_sub].rank = iremote[i].rank; 136924121865SAdrian Maldonado iremote_sub[nleaves_sub].index = remote_points[ilocal[i]]; 137024121865SAdrian Maldonado nleaves_sub += 1; 137124121865SAdrian Maldonado } 137224121865SAdrian Maldonado } 137324121865SAdrian Maldonado ierr = PetscFree2(local_points,remote_points);CHKERRQ(ierr); 137424121865SAdrian Maldonado ierr = ISLocalToGlobalMappingGetSize(map,&nroots_sub);CHKERRQ(ierr); 137524121865SAdrian Maldonado 137624121865SAdrian Maldonado /* Create new subSF */ 137724121865SAdrian Maldonado ierr = PetscSFCreate(PETSC_COMM_WORLD,subSF);CHKERRQ(ierr); 137824121865SAdrian Maldonado ierr = PetscSFSetFromOptions(*subSF);CHKERRQ(ierr); 13794b70a8deSAdrian Maldonado ierr = PetscSFSetGraph(*subSF,nroots_sub,nleaves_sub,ilocal_sub,PETSC_OWN_POINTER,iremote_sub,PETSC_COPY_VALUES);CHKERRQ(ierr); 138024121865SAdrian Maldonado ierr = PetscFree(ilocal_map);CHKERRQ(ierr); 13814b70a8deSAdrian Maldonado ierr = PetscFree(iremote_sub);CHKERRQ(ierr); 138224121865SAdrian Maldonado PetscFunctionReturn(0); 138324121865SAdrian Maldonado } 138424121865SAdrian Maldonado 13855f2c45f1SShri Abhyankar /*@C 13865f2c45f1SShri Abhyankar DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point 13875f2c45f1SShri Abhyankar 13885f2c45f1SShri Abhyankar Not Collective 13895f2c45f1SShri Abhyankar 13905f2c45f1SShri Abhyankar Input Parameters: 13915f2c45f1SShri Abhyankar + dm - The DMNetwork object 13925f2c45f1SShri Abhyankar - p - the vertex point 13935f2c45f1SShri Abhyankar 1394fd292e60Sprj- Output Parameters: 13955f2c45f1SShri Abhyankar + nedges - number of edges connected to this vertex point 13965f2c45f1SShri Abhyankar - edges - List of edge points 13975f2c45f1SShri Abhyankar 13985f2c45f1SShri Abhyankar Level: intermediate 13995f2c45f1SShri Abhyankar 14005f2c45f1SShri Abhyankar Fortran Notes: 14015f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 14025f2c45f1SShri Abhyankar include petsc.h90 in your code. 14035f2c45f1SShri Abhyankar 1404d842c372SHong Zhang .seealso: DMNetworkCreate, DMNetworkGetConnectedVertices 14055f2c45f1SShri Abhyankar @*/ 14065f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[]) 14075f2c45f1SShri Abhyankar { 14085f2c45f1SShri Abhyankar PetscErrorCode ierr; 14095f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 14105f2c45f1SShri Abhyankar 14115f2c45f1SShri Abhyankar PetscFunctionBegin; 14125f2c45f1SShri Abhyankar ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr); 14135f2c45f1SShri Abhyankar ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr); 14145f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14155f2c45f1SShri Abhyankar } 14165f2c45f1SShri Abhyankar 14175f2c45f1SShri Abhyankar /*@C 1418d842c372SHong Zhang DMNetworkGetConnectedVertices - Return the connected vertices for this edge point 14195f2c45f1SShri Abhyankar 14205f2c45f1SShri Abhyankar Not Collective 14215f2c45f1SShri Abhyankar 14225f2c45f1SShri Abhyankar Input Parameters: 14235f2c45f1SShri Abhyankar + dm - The DMNetwork object 14245f2c45f1SShri Abhyankar - p - the edge point 14255f2c45f1SShri Abhyankar 1426fd292e60Sprj- Output Parameters: 14275f2c45f1SShri Abhyankar . vertices - vertices connected to this edge 14285f2c45f1SShri Abhyankar 14295f2c45f1SShri Abhyankar Level: intermediate 14305f2c45f1SShri Abhyankar 14315f2c45f1SShri Abhyankar Fortran Notes: 14325f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 14335f2c45f1SShri Abhyankar include petsc.h90 in your code. 14345f2c45f1SShri Abhyankar 14355f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkGetSupportingEdges 14365f2c45f1SShri Abhyankar @*/ 1437d842c372SHong Zhang PetscErrorCode DMNetworkGetConnectedVertices(DM dm,PetscInt edge,const PetscInt *vertices[]) 14385f2c45f1SShri Abhyankar { 14395f2c45f1SShri Abhyankar PetscErrorCode ierr; 14405f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 14415f2c45f1SShri Abhyankar 14425f2c45f1SShri Abhyankar PetscFunctionBegin; 14435f2c45f1SShri Abhyankar ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr); 14445f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14455f2c45f1SShri Abhyankar } 14465f2c45f1SShri Abhyankar 14475f2c45f1SShri Abhyankar /*@ 14485f2c45f1SShri Abhyankar DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex 14495f2c45f1SShri Abhyankar 14505f2c45f1SShri Abhyankar Not Collective 14515f2c45f1SShri Abhyankar 14525f2c45f1SShri Abhyankar Input Parameters: 14535f2c45f1SShri Abhyankar + dm - The DMNetwork object 1454a2b725a8SWilliam Gropp - p - the vertex point 14555f2c45f1SShri Abhyankar 14565f2c45f1SShri Abhyankar Output Parameter: 14575f2c45f1SShri Abhyankar . isghost - TRUE if the vertex is a ghost point 14585f2c45f1SShri Abhyankar 14595f2c45f1SShri Abhyankar Level: intermediate 14605f2c45f1SShri Abhyankar 1461d842c372SHong Zhang .seealso: DMNetworkCreate, DMNetworkGetConnectedVertices, DMNetworkGetVertexRange 14625f2c45f1SShri Abhyankar @*/ 14635f2c45f1SShri Abhyankar PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost) 14645f2c45f1SShri Abhyankar { 14655f2c45f1SShri Abhyankar PetscErrorCode ierr; 14665f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 14675f2c45f1SShri Abhyankar PetscInt offsetg; 14685f2c45f1SShri Abhyankar PetscSection sectiong; 14695f2c45f1SShri Abhyankar 14705f2c45f1SShri Abhyankar PetscFunctionBegin; 1471caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 14725f2c45f1SShri Abhyankar *isghost = PETSC_FALSE; 1473e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§iong);CHKERRQ(ierr); 14745f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr); 14755f2c45f1SShri Abhyankar if (offsetg < 0) *isghost = PETSC_TRUE; 14765f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14775f2c45f1SShri Abhyankar } 14785f2c45f1SShri Abhyankar 14795f2c45f1SShri Abhyankar PetscErrorCode DMSetUp_Network(DM dm) 14805f2c45f1SShri Abhyankar { 14815f2c45f1SShri Abhyankar PetscErrorCode ierr; 14825f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 14835f2c45f1SShri Abhyankar 14845f2c45f1SShri Abhyankar PetscFunctionBegin; 14855f2c45f1SShri Abhyankar ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr); 14865f2c45f1SShri Abhyankar ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr); 14875f2c45f1SShri Abhyankar 148892fd8e1eSJed Brown ierr = DMSetLocalSection(network->plex,network->DofSection);CHKERRQ(ierr); 1489e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr); 14909e1d080bSHong Zhang 14919e1d080bSHong Zhang dm->setupcalled = PETSC_TRUE; 14929e1d080bSHong Zhang ierr = DMViewFromOptions(dm,NULL,"-dm_view");CHKERRQ(ierr); 14935f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14945f2c45f1SShri Abhyankar } 14955f2c45f1SShri Abhyankar 14961ad426b7SHong Zhang /*@ 149717df6e9eSHong Zhang DMNetworkHasJacobian - Sets global flag for using user's sub Jacobian matrices 14981ad426b7SHong Zhang -- replaced by DMNetworkSetOption(network,userjacobian,PETSC_TURE)? 14991ad426b7SHong Zhang 15001ad426b7SHong Zhang Collective 15011ad426b7SHong Zhang 15021ad426b7SHong Zhang Input Parameters: 150383b2e829SHong Zhang + dm - The DMNetwork object 150483b2e829SHong Zhang . eflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for edges 150583b2e829SHong Zhang - vflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for vertices 15061ad426b7SHong Zhang 15071ad426b7SHong Zhang Level: intermediate 15081ad426b7SHong Zhang 15091ad426b7SHong Zhang @*/ 151083b2e829SHong Zhang PetscErrorCode DMNetworkHasJacobian(DM dm,PetscBool eflg,PetscBool vflg) 15111ad426b7SHong Zhang { 15121ad426b7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 15138675203cSHong Zhang PetscErrorCode ierr; 151466b4e0ffSHong Zhang PetscInt nVertices = network->nVertices; 15151ad426b7SHong Zhang 15161ad426b7SHong Zhang PetscFunctionBegin; 151783b2e829SHong Zhang network->userEdgeJacobian = eflg; 151883b2e829SHong Zhang network->userVertexJacobian = vflg; 15198675203cSHong Zhang 15208675203cSHong Zhang if (eflg && !network->Je) { 15218675203cSHong Zhang ierr = PetscCalloc1(3*network->nEdges,&network->Je);CHKERRQ(ierr); 15228675203cSHong Zhang } 15238675203cSHong Zhang 152466b4e0ffSHong Zhang if (vflg && !network->Jv && nVertices) { 15258675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 152666b4e0ffSHong Zhang PetscInt nedges_total; 15278675203cSHong Zhang const PetscInt *edges; 15288675203cSHong Zhang 15298675203cSHong Zhang /* count nvertex_total */ 15308675203cSHong Zhang nedges_total = 0; 15318675203cSHong Zhang ierr = PetscMalloc1(nVertices+1,&vptr);CHKERRQ(ierr); 15328675203cSHong Zhang 15338675203cSHong Zhang vptr[0] = 0; 15348675203cSHong Zhang for (i=0; i<nVertices; i++) { 15358675203cSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,i+vStart,&nedges,&edges);CHKERRQ(ierr); 15368675203cSHong Zhang nedges_total += nedges; 15378675203cSHong Zhang vptr[i+1] = vptr[i] + 2*nedges + 1; 15388675203cSHong Zhang } 15398675203cSHong Zhang 15408675203cSHong Zhang ierr = PetscCalloc1(2*nedges_total+nVertices,&network->Jv);CHKERRQ(ierr); 15418675203cSHong Zhang network->Jvptr = vptr; 15428675203cSHong Zhang } 15431ad426b7SHong Zhang PetscFunctionReturn(0); 15441ad426b7SHong Zhang } 15451ad426b7SHong Zhang 15461ad426b7SHong Zhang /*@ 154783b2e829SHong Zhang DMNetworkEdgeSetMatrix - Sets user-provided Jacobian matrices for this edge to the network 154883b2e829SHong Zhang 154983b2e829SHong Zhang Not Collective 155083b2e829SHong Zhang 155183b2e829SHong Zhang Input Parameters: 155283b2e829SHong Zhang + dm - The DMNetwork object 155383b2e829SHong Zhang . p - the edge point 15543e97b6e8SHong Zhang - J - array (size = 3) of Jacobian submatrices for this edge point: 15553e97b6e8SHong Zhang J[0]: this edge 1556d842c372SHong Zhang J[1] and J[2]: connected vertices, obtained by calling DMNetworkGetConnectedVertices() 155783b2e829SHong Zhang 155883b2e829SHong Zhang Level: intermediate 155983b2e829SHong Zhang 156083b2e829SHong Zhang .seealso: DMNetworkVertexSetMatrix 156183b2e829SHong Zhang @*/ 156283b2e829SHong Zhang PetscErrorCode DMNetworkEdgeSetMatrix(DM dm,PetscInt p,Mat J[]) 156383b2e829SHong Zhang { 156483b2e829SHong Zhang DM_Network *network=(DM_Network*)dm->data; 156583b2e829SHong Zhang 156683b2e829SHong Zhang PetscFunctionBegin; 15678675203cSHong Zhang if (!network->Je) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkEdgeSetMatrix"); 15688675203cSHong Zhang 15698675203cSHong Zhang if (J) { 1570883e35e8SHong Zhang network->Je[3*p] = J[0]; 1571883e35e8SHong Zhang network->Je[3*p+1] = J[1]; 1572883e35e8SHong Zhang network->Je[3*p+2] = J[2]; 15738675203cSHong Zhang } 157483b2e829SHong Zhang PetscFunctionReturn(0); 157583b2e829SHong Zhang } 157683b2e829SHong Zhang 157783b2e829SHong Zhang /*@ 157876ddfea5SHong Zhang DMNetworkVertexSetMatrix - Sets user-provided Jacobian matrix for this vertex to the network 15791ad426b7SHong Zhang 15801ad426b7SHong Zhang Not Collective 15811ad426b7SHong Zhang 15821ad426b7SHong Zhang Input Parameters: 15831ad426b7SHong Zhang + dm - The DMNetwork object 15841ad426b7SHong Zhang . p - the vertex point 15853e97b6e8SHong Zhang - J - array of Jacobian (size = 2*(num of supporting edges) + 1) submatrices for this vertex point: 15863e97b6e8SHong Zhang J[0]: this vertex 15873e97b6e8SHong Zhang J[1+2*i]: i-th supporting edge 15883e97b6e8SHong Zhang J[1+2*i+1]: i-th connected vertex 15891ad426b7SHong Zhang 15901ad426b7SHong Zhang Level: intermediate 15911ad426b7SHong Zhang 159283b2e829SHong Zhang .seealso: DMNetworkEdgeSetMatrix 15931ad426b7SHong Zhang @*/ 1594883e35e8SHong Zhang PetscErrorCode DMNetworkVertexSetMatrix(DM dm,PetscInt p,Mat J[]) 15955f2c45f1SShri Abhyankar { 15965f2c45f1SShri Abhyankar PetscErrorCode ierr; 15975f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 15988675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 1599883e35e8SHong Zhang const PetscInt *edges; 16005f2c45f1SShri Abhyankar 16015f2c45f1SShri Abhyankar PetscFunctionBegin; 16028675203cSHong Zhang if (!network->Jv) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkVertexSetMatrix"); 1603883e35e8SHong Zhang 16048675203cSHong Zhang if (J) { 1605883e35e8SHong Zhang vptr = network->Jvptr; 16063e97b6e8SHong Zhang network->Jv[vptr[p-vStart]] = J[0]; /* Set Jacobian for this vertex */ 16073e97b6e8SHong Zhang 16083e97b6e8SHong Zhang /* Set Jacobian for each supporting edge and connected vertex */ 1609883e35e8SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,p,&nedges,&edges);CHKERRQ(ierr); 1610883e35e8SHong Zhang for (i=1; i<=2*nedges; i++) network->Jv[vptr[p-vStart]+i] = J[i]; 16118675203cSHong Zhang } 1612883e35e8SHong Zhang PetscFunctionReturn(0); 1613883e35e8SHong Zhang } 1614883e35e8SHong Zhang 1615e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 16165cf7da58SHong Zhang { 16175cf7da58SHong Zhang PetscErrorCode ierr; 16185cf7da58SHong Zhang PetscInt j; 16195cf7da58SHong Zhang PetscScalar val=(PetscScalar)ncols; 16205cf7da58SHong Zhang 16215cf7da58SHong Zhang PetscFunctionBegin; 16225cf7da58SHong Zhang if (!ghost) { 16235cf7da58SHong Zhang for (j=0; j<nrows; j++) { 16245cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 16255cf7da58SHong Zhang } 16265cf7da58SHong Zhang } else { 16275cf7da58SHong Zhang for (j=0; j<nrows; j++) { 16285cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 16295cf7da58SHong Zhang } 16305cf7da58SHong Zhang } 16315cf7da58SHong Zhang PetscFunctionReturn(0); 16325cf7da58SHong Zhang } 16335cf7da58SHong Zhang 1634e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 16355cf7da58SHong Zhang { 16365cf7da58SHong Zhang PetscErrorCode ierr; 16375cf7da58SHong Zhang PetscInt j,ncols_u; 16385cf7da58SHong Zhang PetscScalar val; 16395cf7da58SHong Zhang 16405cf7da58SHong Zhang PetscFunctionBegin; 16415cf7da58SHong Zhang if (!ghost) { 16425cf7da58SHong Zhang for (j=0; j<nrows; j++) { 16435cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 16445cf7da58SHong Zhang val = (PetscScalar)ncols_u; 16455cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 16465cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 16475cf7da58SHong Zhang } 16485cf7da58SHong Zhang } else { 16495cf7da58SHong Zhang for (j=0; j<nrows; j++) { 16505cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 16515cf7da58SHong Zhang val = (PetscScalar)ncols_u; 16525cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 16535cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 16545cf7da58SHong Zhang } 16555cf7da58SHong Zhang } 16565cf7da58SHong Zhang PetscFunctionReturn(0); 16575cf7da58SHong Zhang } 16585cf7da58SHong Zhang 1659e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 16605cf7da58SHong Zhang { 16615cf7da58SHong Zhang PetscErrorCode ierr; 16625cf7da58SHong Zhang 16635cf7da58SHong Zhang PetscFunctionBegin; 16645cf7da58SHong Zhang if (Ju) { 16655cf7da58SHong Zhang ierr = MatSetPreallocationUserblock_private(Ju,nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 16665cf7da58SHong Zhang } else { 16675cf7da58SHong Zhang ierr = MatSetPreallocationDenseblock_private(nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 16685cf7da58SHong Zhang } 16695cf7da58SHong Zhang PetscFunctionReturn(0); 16705cf7da58SHong Zhang } 16715cf7da58SHong Zhang 1672e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 1673883e35e8SHong Zhang { 1674883e35e8SHong Zhang PetscErrorCode ierr; 1675883e35e8SHong Zhang PetscInt j,*cols; 1676883e35e8SHong Zhang PetscScalar *zeros; 1677883e35e8SHong Zhang 1678883e35e8SHong Zhang PetscFunctionBegin; 1679883e35e8SHong Zhang ierr = PetscCalloc2(ncols,&cols,nrows*ncols,&zeros);CHKERRQ(ierr); 1680883e35e8SHong Zhang for (j=0; j<ncols; j++) cols[j] = j+ cstart; 1681883e35e8SHong Zhang ierr = MatSetValues(*J,nrows,rows,ncols,cols,zeros,INSERT_VALUES);CHKERRQ(ierr); 1682883e35e8SHong Zhang ierr = PetscFree2(cols,zeros);CHKERRQ(ierr); 16831ad426b7SHong Zhang PetscFunctionReturn(0); 16841ad426b7SHong Zhang } 1685a4e85ca8SHong Zhang 1686e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 16873e97b6e8SHong Zhang { 16883e97b6e8SHong Zhang PetscErrorCode ierr; 16893e97b6e8SHong Zhang PetscInt j,M,N,row,col,ncols_u; 16903e97b6e8SHong Zhang const PetscInt *cols; 16913e97b6e8SHong Zhang PetscScalar zero=0.0; 16923e97b6e8SHong Zhang 16933e97b6e8SHong Zhang PetscFunctionBegin; 16943e97b6e8SHong Zhang ierr = MatGetSize(Ju,&M,&N);CHKERRQ(ierr); 16953e97b6e8SHong 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); 16963e97b6e8SHong Zhang 16973e97b6e8SHong Zhang for (row=0; row<nrows; row++) { 16983e97b6e8SHong Zhang ierr = MatGetRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 16993e97b6e8SHong Zhang for (j=0; j<ncols_u; j++) { 17003e97b6e8SHong Zhang col = cols[j] + cstart; 17013e97b6e8SHong Zhang ierr = MatSetValues(*J,1,&rows[row],1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr); 17023e97b6e8SHong Zhang } 17033e97b6e8SHong Zhang ierr = MatRestoreRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 17043e97b6e8SHong Zhang } 17053e97b6e8SHong Zhang PetscFunctionReturn(0); 17063e97b6e8SHong Zhang } 17071ad426b7SHong Zhang 1708e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 1709a4e85ca8SHong Zhang { 1710a4e85ca8SHong Zhang PetscErrorCode ierr; 1711f4431b8cSHong Zhang 1712a4e85ca8SHong Zhang PetscFunctionBegin; 1713a4e85ca8SHong Zhang if (Ju) { 1714a4e85ca8SHong Zhang ierr = MatSetUserblock_private(Ju,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 1715a4e85ca8SHong Zhang } else { 1716a4e85ca8SHong Zhang ierr = MatSetDenseblock_private(nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 1717a4e85ca8SHong Zhang } 1718a4e85ca8SHong Zhang PetscFunctionReturn(0); 1719a4e85ca8SHong Zhang } 1720a4e85ca8SHong Zhang 172124121865SAdrian 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. 172224121865SAdrian Maldonado */ 172324121865SAdrian Maldonado PetscErrorCode CreateSubGlobalToLocalMapping_private(PetscSection globalsec, PetscSection localsec, ISLocalToGlobalMapping *ltog) 172424121865SAdrian Maldonado { 172524121865SAdrian Maldonado PetscErrorCode ierr; 172624121865SAdrian Maldonado PetscInt i,size,dof; 172724121865SAdrian Maldonado PetscInt *glob2loc; 172824121865SAdrian Maldonado 172924121865SAdrian Maldonado PetscFunctionBegin; 173024121865SAdrian Maldonado ierr = PetscSectionGetStorageSize(localsec,&size);CHKERRQ(ierr); 173124121865SAdrian Maldonado ierr = PetscMalloc1(size,&glob2loc);CHKERRQ(ierr); 173224121865SAdrian Maldonado 173324121865SAdrian Maldonado for (i = 0; i < size; i++) { 173424121865SAdrian Maldonado ierr = PetscSectionGetOffset(globalsec,i,&dof);CHKERRQ(ierr); 173524121865SAdrian Maldonado dof = (dof >= 0) ? dof : -(dof + 1); 173624121865SAdrian Maldonado glob2loc[i] = dof; 173724121865SAdrian Maldonado } 173824121865SAdrian Maldonado 173924121865SAdrian Maldonado ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,size,glob2loc,PETSC_OWN_POINTER,ltog);CHKERRQ(ierr); 174024121865SAdrian Maldonado #if 0 174124121865SAdrian Maldonado ierr = PetscIntView(size,glob2loc,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 174224121865SAdrian Maldonado #endif 174324121865SAdrian Maldonado PetscFunctionReturn(0); 174424121865SAdrian Maldonado } 174524121865SAdrian Maldonado 174601ad2aeeSHong Zhang #include <petsc/private/matimpl.h> 17479e1d080bSHong Zhang 17489e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network_Nest(DM dm,Mat *J) 17491ad426b7SHong Zhang { 17501ad426b7SHong Zhang PetscErrorCode ierr; 17511ad426b7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 17529e1d080bSHong Zhang PetscMPIInt rank, size; 175324121865SAdrian Maldonado PetscInt eDof,vDof; 175424121865SAdrian Maldonado Mat j11,j12,j21,j22,bA[2][2]; 17559e1d080bSHong Zhang MPI_Comm comm; 175624121865SAdrian Maldonado ISLocalToGlobalMapping eISMap,vISMap; 175724121865SAdrian Maldonado 17589e1d080bSHong Zhang PetscFunctionBegin; 175924121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 176024121865SAdrian Maldonado ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 176124121865SAdrian Maldonado ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 176224121865SAdrian Maldonado 176324121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->edge.GlobalDofSection,&eDof);CHKERRQ(ierr); 176424121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->vertex.GlobalDofSection,&vDof);CHKERRQ(ierr); 176524121865SAdrian Maldonado 176601ad2aeeSHong Zhang ierr = MatCreate(comm, &j11);CHKERRQ(ierr); 176724121865SAdrian Maldonado ierr = MatSetSizes(j11, eDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 176824121865SAdrian Maldonado ierr = MatSetType(j11, MATMPIAIJ);CHKERRQ(ierr); 176924121865SAdrian Maldonado 177001ad2aeeSHong Zhang ierr = MatCreate(comm, &j12);CHKERRQ(ierr); 177124121865SAdrian Maldonado ierr = MatSetSizes(j12, eDof, vDof, PETSC_DETERMINE ,PETSC_DETERMINE);CHKERRQ(ierr); 177224121865SAdrian Maldonado ierr = MatSetType(j12, MATMPIAIJ);CHKERRQ(ierr); 177324121865SAdrian Maldonado 177401ad2aeeSHong Zhang ierr = MatCreate(comm, &j21);CHKERRQ(ierr); 177524121865SAdrian Maldonado ierr = MatSetSizes(j21, vDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 177624121865SAdrian Maldonado ierr = MatSetType(j21, MATMPIAIJ);CHKERRQ(ierr); 177724121865SAdrian Maldonado 177801ad2aeeSHong Zhang ierr = MatCreate(comm, &j22);CHKERRQ(ierr); 177924121865SAdrian Maldonado ierr = MatSetSizes(j22, vDof, vDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 178024121865SAdrian Maldonado ierr = MatSetType(j22, MATMPIAIJ);CHKERRQ(ierr); 178124121865SAdrian Maldonado 17823f6a6bdaSHong Zhang bA[0][0] = j11; 17833f6a6bdaSHong Zhang bA[0][1] = j12; 17843f6a6bdaSHong Zhang bA[1][0] = j21; 17853f6a6bdaSHong Zhang bA[1][1] = j22; 178624121865SAdrian Maldonado 178724121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->edge.GlobalDofSection,network->edge.DofSection,&eISMap);CHKERRQ(ierr); 178824121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->vertex.GlobalDofSection,network->vertex.DofSection,&vISMap);CHKERRQ(ierr); 178924121865SAdrian Maldonado 179024121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j11,eISMap,eISMap);CHKERRQ(ierr); 179124121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j12,eISMap,vISMap);CHKERRQ(ierr); 179224121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j21,vISMap,eISMap);CHKERRQ(ierr); 179324121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j22,vISMap,vISMap);CHKERRQ(ierr); 179424121865SAdrian Maldonado 179524121865SAdrian Maldonado ierr = MatSetUp(j11);CHKERRQ(ierr); 179624121865SAdrian Maldonado ierr = MatSetUp(j12);CHKERRQ(ierr); 179724121865SAdrian Maldonado ierr = MatSetUp(j21);CHKERRQ(ierr); 179824121865SAdrian Maldonado ierr = MatSetUp(j22);CHKERRQ(ierr); 179924121865SAdrian Maldonado 180001ad2aeeSHong Zhang ierr = MatCreateNest(comm,2,NULL,2,NULL,&bA[0][0],J);CHKERRQ(ierr); 180124121865SAdrian Maldonado ierr = MatSetUp(*J);CHKERRQ(ierr); 180224121865SAdrian Maldonado ierr = MatNestSetVecType(*J,VECNEST);CHKERRQ(ierr); 180324121865SAdrian Maldonado ierr = MatDestroy(&j11);CHKERRQ(ierr); 180424121865SAdrian Maldonado ierr = MatDestroy(&j12);CHKERRQ(ierr); 180524121865SAdrian Maldonado ierr = MatDestroy(&j21);CHKERRQ(ierr); 180624121865SAdrian Maldonado ierr = MatDestroy(&j22);CHKERRQ(ierr); 180724121865SAdrian Maldonado 180824121865SAdrian Maldonado ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 180924121865SAdrian Maldonado ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18109e1d080bSHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 181124121865SAdrian Maldonado 181224121865SAdrian Maldonado /* Free structures */ 181324121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&eISMap);CHKERRQ(ierr); 181424121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&vISMap);CHKERRQ(ierr); 181524121865SAdrian Maldonado PetscFunctionReturn(0); 18169e1d080bSHong Zhang } 18179e1d080bSHong Zhang 18189e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J) 18199e1d080bSHong Zhang { 18209e1d080bSHong Zhang PetscErrorCode ierr; 18219e1d080bSHong Zhang DM_Network *network = (DM_Network*)dm->data; 18229e1d080bSHong Zhang PetscInt eStart,eEnd,vStart,vEnd,rstart,nrows,*rows,localSize; 18239e1d080bSHong Zhang PetscInt cstart,ncols,j,e,v; 18249e1d080bSHong Zhang PetscBool ghost,ghost_vc,ghost2,isNest; 18259e1d080bSHong Zhang Mat Juser; 18269e1d080bSHong Zhang PetscSection sectionGlobal; 18279e1d080bSHong Zhang PetscInt nedges,*vptr=NULL,vc,*rows_v; /* suppress maybe-uninitialized warning */ 18289e1d080bSHong Zhang const PetscInt *edges,*cone; 18299e1d080bSHong Zhang MPI_Comm comm; 18309e1d080bSHong Zhang MatType mtype; 18319e1d080bSHong Zhang Vec vd_nz,vo_nz; 18329e1d080bSHong Zhang PetscInt *dnnz,*onnz; 18339e1d080bSHong Zhang PetscScalar *vdnz,*vonz; 18349e1d080bSHong Zhang 18359e1d080bSHong Zhang PetscFunctionBegin; 18369e1d080bSHong Zhang mtype = dm->mattype; 18379e1d080bSHong Zhang ierr = PetscStrcmp(mtype,MATNEST,&isNest);CHKERRQ(ierr); 18389e1d080bSHong Zhang if (isNest) { 18399e1d080bSHong Zhang ierr = DMCreateMatrix_Network_Nest(dm,J);CHKERRQ(ierr); 1840c6b011d8SStefano Zampini ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 18419e1d080bSHong Zhang PetscFunctionReturn(0); 18429e1d080bSHong Zhang } 18439e1d080bSHong Zhang 18449e1d080bSHong Zhang if (!network->userEdgeJacobian && !network->userVertexJacobian) { 1845a4e85ca8SHong Zhang /* user does not provide Jacobian blocks */ 18469e1d080bSHong Zhang ierr = DMCreateMatrix_Plex(network->plex,J);CHKERRQ(ierr); 1847bfbc38dcSHong Zhang ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 18481ad426b7SHong Zhang PetscFunctionReturn(0); 18491ad426b7SHong Zhang } 18501ad426b7SHong Zhang 1851bfbc38dcSHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)dm),J);CHKERRQ(ierr); 1852e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§ionGlobal);CHKERRQ(ierr); 1853bfbc38dcSHong Zhang ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal,&localSize);CHKERRQ(ierr); 1854bfbc38dcSHong Zhang ierr = MatSetSizes(*J,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 18552a945128SHong Zhang 18562a945128SHong Zhang ierr = MatSetType(*J,MATAIJ);CHKERRQ(ierr); 18572a945128SHong Zhang ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 185889898e50SHong Zhang 185989898e50SHong Zhang /* (1) Set matrix preallocation */ 186089898e50SHong Zhang /*------------------------------*/ 1861840c2264SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 1862840c2264SHong Zhang ierr = VecCreate(comm,&vd_nz);CHKERRQ(ierr); 1863840c2264SHong Zhang ierr = VecSetSizes(vd_nz,localSize,PETSC_DECIDE);CHKERRQ(ierr); 1864840c2264SHong Zhang ierr = VecSetFromOptions(vd_nz);CHKERRQ(ierr); 1865840c2264SHong Zhang ierr = VecSet(vd_nz,0.0);CHKERRQ(ierr); 1866840c2264SHong Zhang ierr = VecDuplicate(vd_nz,&vo_nz);CHKERRQ(ierr); 1867840c2264SHong Zhang 186889898e50SHong Zhang /* Set preallocation for edges */ 186989898e50SHong Zhang /*-----------------------------*/ 1870840c2264SHong Zhang ierr = DMNetworkGetEdgeRange(dm,&eStart,&eEnd);CHKERRQ(ierr); 1871840c2264SHong Zhang 1872bdcb62a2SHong Zhang ierr = PetscMalloc1(localSize,&rows);CHKERRQ(ierr); 1873840c2264SHong Zhang for (e=eStart; e<eEnd; e++) { 1874840c2264SHong Zhang /* Get row indices */ 1875840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr); 1876840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr); 1877840c2264SHong Zhang if (nrows) { 1878840c2264SHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 1879840c2264SHong Zhang 18805cf7da58SHong Zhang /* Set preallocation for conntected vertices */ 1881d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 1882840c2264SHong Zhang for (v=0; v<2; v++) { 1883840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr); 1884840c2264SHong Zhang 18858675203cSHong Zhang if (network->Je) { 1886840c2264SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 18878675203cSHong Zhang } else Juser = NULL; 1888840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,cone[v],&ghost);CHKERRQ(ierr); 18895cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 1890840c2264SHong Zhang } 1891840c2264SHong Zhang 189289898e50SHong Zhang /* Set preallocation for edge self */ 1893840c2264SHong Zhang cstart = rstart; 18948675203cSHong Zhang if (network->Je) { 1895840c2264SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 18968675203cSHong Zhang } else Juser = NULL; 18975cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 1898840c2264SHong Zhang } 1899840c2264SHong Zhang } 1900840c2264SHong Zhang 190189898e50SHong Zhang /* Set preallocation for vertices */ 190289898e50SHong Zhang /*--------------------------------*/ 1903840c2264SHong Zhang ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 19048675203cSHong Zhang if (vEnd - vStart) vptr = network->Jvptr; 1905840c2264SHong Zhang 1906840c2264SHong Zhang for (v=vStart; v<vEnd; v++) { 1907840c2264SHong Zhang /* Get row indices */ 1908840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr); 1909840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr); 1910840c2264SHong Zhang if (!nrows) continue; 1911840c2264SHong Zhang 1912bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 1913bdcb62a2SHong Zhang if (ghost) { 1914bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 1915bdcb62a2SHong Zhang } else { 1916bdcb62a2SHong Zhang rows_v = rows; 1917bdcb62a2SHong Zhang } 1918bdcb62a2SHong Zhang 1919bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 1920840c2264SHong Zhang 1921840c2264SHong Zhang /* Get supporting edges and connected vertices */ 1922840c2264SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 1923840c2264SHong Zhang 1924840c2264SHong Zhang for (e=0; e<nedges; e++) { 1925840c2264SHong Zhang /* Supporting edges */ 1926840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr); 1927840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr); 1928840c2264SHong Zhang 19298675203cSHong Zhang if (network->Jv) { 1930840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 19318675203cSHong Zhang } else Juser = NULL; 1932bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 1933840c2264SHong Zhang 1934840c2264SHong Zhang /* Connected vertices */ 1935d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 1936840c2264SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 1937840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,vc,&ghost_vc);CHKERRQ(ierr); 1938840c2264SHong Zhang 1939840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr); 1940840c2264SHong Zhang 19418675203cSHong Zhang if (network->Jv) { 1942840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 19438675203cSHong Zhang } else Juser = NULL; 1944e102a522SHong Zhang if (ghost_vc||ghost) { 1945e102a522SHong Zhang ghost2 = PETSC_TRUE; 1946e102a522SHong Zhang } else { 1947e102a522SHong Zhang ghost2 = PETSC_FALSE; 1948e102a522SHong Zhang } 1949e102a522SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost2,vd_nz,vo_nz);CHKERRQ(ierr); 1950840c2264SHong Zhang } 1951840c2264SHong Zhang 195289898e50SHong Zhang /* Set preallocation for vertex self */ 1953840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 1954840c2264SHong Zhang if (!ghost) { 1955840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr); 19568675203cSHong Zhang if (network->Jv) { 1957840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 19588675203cSHong Zhang } else Juser = NULL; 1959bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 1960840c2264SHong Zhang } 1961bdcb62a2SHong Zhang if (ghost) { 1962bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 1963bdcb62a2SHong Zhang } 1964840c2264SHong Zhang } 1965840c2264SHong Zhang 1966840c2264SHong Zhang ierr = VecAssemblyBegin(vd_nz);CHKERRQ(ierr); 1967840c2264SHong Zhang ierr = VecAssemblyBegin(vo_nz);CHKERRQ(ierr); 19685cf7da58SHong Zhang 19695cf7da58SHong Zhang ierr = PetscMalloc2(localSize,&dnnz,localSize,&onnz);CHKERRQ(ierr); 19705cf7da58SHong Zhang 19715cf7da58SHong Zhang ierr = VecAssemblyEnd(vd_nz);CHKERRQ(ierr); 1972840c2264SHong Zhang ierr = VecAssemblyEnd(vo_nz);CHKERRQ(ierr); 1973840c2264SHong Zhang 1974840c2264SHong Zhang ierr = VecGetArray(vd_nz,&vdnz);CHKERRQ(ierr); 1975840c2264SHong Zhang ierr = VecGetArray(vo_nz,&vonz);CHKERRQ(ierr); 1976840c2264SHong Zhang for (j=0; j<localSize; j++) { 1977e102a522SHong Zhang dnnz[j] = (PetscInt)PetscRealPart(vdnz[j]); 1978e102a522SHong Zhang onnz[j] = (PetscInt)PetscRealPart(vonz[j]); 1979840c2264SHong Zhang } 1980840c2264SHong Zhang ierr = VecRestoreArray(vd_nz,&vdnz);CHKERRQ(ierr); 1981840c2264SHong Zhang ierr = VecRestoreArray(vo_nz,&vonz);CHKERRQ(ierr); 1982840c2264SHong Zhang ierr = VecDestroy(&vd_nz);CHKERRQ(ierr); 1983840c2264SHong Zhang ierr = VecDestroy(&vo_nz);CHKERRQ(ierr); 1984840c2264SHong Zhang 19855cf7da58SHong Zhang ierr = MatSeqAIJSetPreallocation(*J,0,dnnz);CHKERRQ(ierr); 19865cf7da58SHong Zhang ierr = MatMPIAIJSetPreallocation(*J,0,dnnz,0,onnz);CHKERRQ(ierr); 19875cf7da58SHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 19885cf7da58SHong Zhang 19895cf7da58SHong Zhang ierr = PetscFree2(dnnz,onnz);CHKERRQ(ierr); 19905cf7da58SHong Zhang 199189898e50SHong Zhang /* (2) Set matrix entries for edges */ 199289898e50SHong Zhang /*----------------------------------*/ 19931ad426b7SHong Zhang for (e=eStart; e<eEnd; e++) { 1994bfbc38dcSHong Zhang /* Get row indices */ 19951ad426b7SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr); 199617df6e9eSHong Zhang ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr); 19974b976069SHong Zhang if (nrows) { 199817df6e9eSHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 19991ad426b7SHong Zhang 2000bfbc38dcSHong Zhang /* Set matrix entries for conntected vertices */ 2001d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 2002bfbc38dcSHong Zhang for (v=0; v<2; v++) { 2003bfbc38dcSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,cone[v],&cstart);CHKERRQ(ierr); 2004883e35e8SHong Zhang ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr); 20053e97b6e8SHong Zhang 20068675203cSHong Zhang if (network->Je) { 2007a4e85ca8SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 20088675203cSHong Zhang } else Juser = NULL; 2009a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 2010bfbc38dcSHong Zhang } 201117df6e9eSHong Zhang 2012bfbc38dcSHong Zhang /* Set matrix entries for edge self */ 20133e97b6e8SHong Zhang cstart = rstart; 20148675203cSHong Zhang if (network->Je) { 2015a4e85ca8SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 20168675203cSHong Zhang } else Juser = NULL; 2017a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,nrows,cstart,J);CHKERRQ(ierr); 20181ad426b7SHong Zhang } 20194b976069SHong Zhang } 20201ad426b7SHong Zhang 2021bfbc38dcSHong Zhang /* Set matrix entries for vertices */ 202283b2e829SHong Zhang /*---------------------------------*/ 20231ad426b7SHong Zhang for (v=vStart; v<vEnd; v++) { 2024bfbc38dcSHong Zhang /* Get row indices */ 2025596e729fSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr); 2026596e729fSHong Zhang ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr); 20274b976069SHong Zhang if (!nrows) continue; 2028596e729fSHong Zhang 2029bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 2030bdcb62a2SHong Zhang if (ghost) { 2031bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 2032bdcb62a2SHong Zhang } else { 2033bdcb62a2SHong Zhang rows_v = rows; 2034bdcb62a2SHong Zhang } 2035bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 2036596e729fSHong Zhang 2037bfbc38dcSHong Zhang /* Get supporting edges and connected vertices */ 2038596e729fSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 2039596e729fSHong Zhang 2040596e729fSHong Zhang for (e=0; e<nedges; e++) { 2041bfbc38dcSHong Zhang /* Supporting edges */ 2042596e729fSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr); 2043596e729fSHong Zhang ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr); 2044596e729fSHong Zhang 20458675203cSHong Zhang if (network->Jv) { 2046a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 20478675203cSHong Zhang } else Juser = NULL; 2048bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 2049596e729fSHong Zhang 2050bfbc38dcSHong Zhang /* Connected vertices */ 2051d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 20522a945128SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 20532a945128SHong Zhang 205444aca652SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,vc,&cstart);CHKERRQ(ierr); 205544aca652SHong Zhang ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr); 2056a4e85ca8SHong Zhang 20578675203cSHong Zhang if (network->Jv) { 2058a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 20598675203cSHong Zhang } else Juser = NULL; 2060bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 2061596e729fSHong Zhang } 2062596e729fSHong Zhang 2063bfbc38dcSHong Zhang /* Set matrix entries for vertex self */ 20641ad426b7SHong Zhang if (!ghost) { 2065596e729fSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr); 20668675203cSHong Zhang if (network->Jv) { 2067a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 20688675203cSHong Zhang } else Juser = NULL; 2069bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,nrows,cstart,J);CHKERRQ(ierr); 2070bdcb62a2SHong Zhang } 2071bdcb62a2SHong Zhang if (ghost) { 2072bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 2073bdcb62a2SHong Zhang } 20741ad426b7SHong Zhang } 2075a4e85ca8SHong Zhang ierr = PetscFree(rows);CHKERRQ(ierr); 2076bdcb62a2SHong Zhang 20771ad426b7SHong Zhang ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20781ad426b7SHong Zhang ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2079dd6f46cdSHong Zhang 20805f2c45f1SShri Abhyankar ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 20815f2c45f1SShri Abhyankar PetscFunctionReturn(0); 20825f2c45f1SShri Abhyankar } 20835f2c45f1SShri Abhyankar 20845f2c45f1SShri Abhyankar PetscErrorCode DMDestroy_Network(DM dm) 20855f2c45f1SShri Abhyankar { 20865f2c45f1SShri Abhyankar PetscErrorCode ierr; 20875f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 20882727e31bSShri Abhyankar PetscInt j; 20895f2c45f1SShri Abhyankar 20905f2c45f1SShri Abhyankar PetscFunctionBegin; 20918415c774SShri Abhyankar if (--network->refct > 0) PetscFunctionReturn(0); 209283b2e829SHong Zhang if (network->Je) { 209383b2e829SHong Zhang ierr = PetscFree(network->Je);CHKERRQ(ierr); 209483b2e829SHong Zhang } 209583b2e829SHong Zhang if (network->Jv) { 2096883e35e8SHong Zhang ierr = PetscFree(network->Jvptr);CHKERRQ(ierr); 209783b2e829SHong Zhang ierr = PetscFree(network->Jv);CHKERRQ(ierr); 20981ad426b7SHong Zhang } 209913c2a604SAdrian Maldonado 210013c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->vertex.mapping);CHKERRQ(ierr); 210113c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.DofSection);CHKERRQ(ierr); 210213c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.GlobalDofSection);CHKERRQ(ierr); 2103f5427c60SHong Zhang if (network->vltog) { 2104f5427c60SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 2105f5427c60SHong Zhang } 210613c2a604SAdrian Maldonado if (network->vertex.sf) { 210713c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->vertex.sf);CHKERRQ(ierr); 210813c2a604SAdrian Maldonado } 210913c2a604SAdrian Maldonado /* edge */ 211013c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->edge.mapping);CHKERRQ(ierr); 211113c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.DofSection);CHKERRQ(ierr); 211213c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.GlobalDofSection);CHKERRQ(ierr); 211313c2a604SAdrian Maldonado if (network->edge.sf) { 211413c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->edge.sf);CHKERRQ(ierr); 211513c2a604SAdrian Maldonado } 21165f2c45f1SShri Abhyankar ierr = DMDestroy(&network->plex);CHKERRQ(ierr); 21175f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr); 21185f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr); 211983b2e829SHong Zhang 21202727e31bSShri Abhyankar for(j=0; j<network->nsubnet; j++) { 21212727e31bSShri Abhyankar ierr = PetscFree(network->subnet[j].edges);CHKERRQ(ierr); 21222727e31bSShri Abhyankar } 2123caf410d2SHong Zhang ierr = PetscFree(network->subnetvtx);CHKERRQ(ierr); 2124caf410d2SHong Zhang 2125e2aaf10cSShri Abhyankar ierr = PetscFree(network->subnet);CHKERRQ(ierr); 21265f2c45f1SShri Abhyankar ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr); 2127caf410d2SHong Zhang ierr = PetscFree2(network->header,network->cvalue);CHKERRQ(ierr); 21285f2c45f1SShri Abhyankar ierr = PetscFree(network);CHKERRQ(ierr); 21295f2c45f1SShri Abhyankar PetscFunctionReturn(0); 21305f2c45f1SShri Abhyankar } 21315f2c45f1SShri Abhyankar 21325f2c45f1SShri Abhyankar PetscErrorCode DMView_Network(DM dm,PetscViewer viewer) 21335f2c45f1SShri Abhyankar { 21345f2c45f1SShri Abhyankar PetscErrorCode ierr; 21355f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 2136caf410d2SHong Zhang PetscBool iascii; 2137caf410d2SHong Zhang PetscMPIInt rank; 2138caf410d2SHong Zhang PetscInt p,nsubnet; 21395f2c45f1SShri Abhyankar 21405f2c45f1SShri Abhyankar PetscFunctionBegin; 2141caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 2142caf410d2SHong Zhang ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 2143caf410d2SHong Zhang PetscValidHeaderSpecific(dm,DM_CLASSID, 1); 2144caf410d2SHong Zhang PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2145caf410d2SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 2146caf410d2SHong Zhang if (iascii) { 2147caf410d2SHong Zhang const PetscInt *cone,*vtx,*edges; 2148caf410d2SHong Zhang PetscInt vfrom,vto,i,j,nv,ne; 2149caf410d2SHong Zhang 2150caf410d2SHong Zhang nsubnet = network->nsubnet - network->ncsubnet; /* num of subnetworks */ 2151caf410d2SHong Zhang ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 2152caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " [%d] nsubnet: %D; nsubnetCouple: %D; nEdges: %D; nVertices: %D\n",rank,nsubnet,network->ncsubnet,network->nEdges,network->nVertices);CHKERRQ(ierr); 2153caf410d2SHong Zhang 2154caf410d2SHong Zhang for (i=0; i<nsubnet; i++) { 2155caf410d2SHong Zhang ierr = DMNetworkGetSubnetworkInfo(dm,i,&nv,&ne,&vtx,&edges);CHKERRQ(ierr); 2156caf410d2SHong Zhang if (ne) { 2157caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " Subnet %D: nEdges %D, nVertices %D\n",i,ne,nv);CHKERRQ(ierr); 2158caf410d2SHong Zhang for (j=0; j<ne; j++) { 2159caf410d2SHong Zhang p = edges[j]; 2160caf410d2SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,p,&cone);CHKERRQ(ierr); 2161caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[0],&vfrom);CHKERRQ(ierr); 2162caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[1],&vto);CHKERRQ(ierr); 2163caf410d2SHong Zhang ierr = DMNetworkGetGlobalEdgeIndex(dm,edges[j],&p);CHKERRQ(ierr); 2164caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " edge %D: %D----> %D\n",p,vfrom,vto);CHKERRQ(ierr); 2165caf410d2SHong Zhang } 2166caf410d2SHong Zhang } 2167caf410d2SHong Zhang } 2168caf410d2SHong Zhang /* Coupling subnets */ 2169caf410d2SHong Zhang nsubnet = network->nsubnet; 2170caf410d2SHong Zhang for (; i<nsubnet; i++) { 2171caf410d2SHong Zhang ierr = DMNetworkGetSubnetworkInfo(dm,i,&nv,&ne,&vtx,&edges);CHKERRQ(ierr); 2172caf410d2SHong Zhang if (ne) { 2173caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " Subnet %D (couple): nEdges %D, nVertices %D\n",i,ne,nv);CHKERRQ(ierr); 2174caf410d2SHong Zhang for (j=0; j<ne; j++) { 2175caf410d2SHong Zhang p = edges[j]; 2176caf410d2SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,p,&cone);CHKERRQ(ierr); 2177caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[0],&vfrom);CHKERRQ(ierr); 2178caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[1],&vto);CHKERRQ(ierr); 2179caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " edge %D: %D----> %D\n",p,vfrom,vto);CHKERRQ(ierr); 2180caf410d2SHong Zhang } 2181caf410d2SHong Zhang } 2182caf410d2SHong Zhang } 2183caf410d2SHong Zhang ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2184caf410d2SHong Zhang ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 2185caf410d2SHong Zhang } else SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMNetwork writing", ((PetscObject)viewer)->type_name); 21865f2c45f1SShri Abhyankar PetscFunctionReturn(0); 21875f2c45f1SShri Abhyankar } 21885f2c45f1SShri Abhyankar 21895f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l) 21905f2c45f1SShri Abhyankar { 21915f2c45f1SShri Abhyankar PetscErrorCode ierr; 21925f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 21935f2c45f1SShri Abhyankar 21945f2c45f1SShri Abhyankar PetscFunctionBegin; 21955f2c45f1SShri Abhyankar ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr); 21965f2c45f1SShri Abhyankar PetscFunctionReturn(0); 21975f2c45f1SShri Abhyankar } 21985f2c45f1SShri Abhyankar 21995f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l) 22005f2c45f1SShri Abhyankar { 22015f2c45f1SShri Abhyankar PetscErrorCode ierr; 22025f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 22035f2c45f1SShri Abhyankar 22045f2c45f1SShri Abhyankar PetscFunctionBegin; 22055f2c45f1SShri Abhyankar ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr); 22065f2c45f1SShri Abhyankar PetscFunctionReturn(0); 22075f2c45f1SShri Abhyankar } 22085f2c45f1SShri Abhyankar 22095f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g) 22105f2c45f1SShri Abhyankar { 22115f2c45f1SShri Abhyankar PetscErrorCode ierr; 22125f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 22135f2c45f1SShri Abhyankar 22145f2c45f1SShri Abhyankar PetscFunctionBegin; 22155f2c45f1SShri Abhyankar ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr); 22165f2c45f1SShri Abhyankar PetscFunctionReturn(0); 22175f2c45f1SShri Abhyankar } 22185f2c45f1SShri Abhyankar 22195f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g) 22205f2c45f1SShri Abhyankar { 22215f2c45f1SShri Abhyankar PetscErrorCode ierr; 22225f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 22235f2c45f1SShri Abhyankar 22245f2c45f1SShri Abhyankar PetscFunctionBegin; 22255f2c45f1SShri Abhyankar ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr); 22265f2c45f1SShri Abhyankar PetscFunctionReturn(0); 22275f2c45f1SShri Abhyankar } 222822bbedd7SHong Zhang 222922bbedd7SHong Zhang /*@ 2230b2aacc82SHong Zhang DMNetworkGetVertexLocalToGlobalOrdering - Get vertex globle index 223122bbedd7SHong Zhang 223222bbedd7SHong Zhang Not collective 223322bbedd7SHong Zhang 223422bbedd7SHong Zhang Input Parameters 223522bbedd7SHong Zhang + dm - the dm object 223622bbedd7SHong Zhang - vloc - local vertex ordering, start from 0 223722bbedd7SHong Zhang 223822bbedd7SHong Zhang Output Parameters 2239*f0fc11ceSJed Brown . vg - global vertex ordering, start from 0 224022bbedd7SHong Zhang 224122bbedd7SHong Zhang Level: Advanced 224222bbedd7SHong Zhang 224322bbedd7SHong Zhang .seealso: DMNetworkSetVertexLocalToGlobalOrdering() 224422bbedd7SHong Zhang @*/ 224522bbedd7SHong Zhang PetscErrorCode DMNetworkGetVertexLocalToGlobalOrdering(DM dm,PetscInt vloc,PetscInt *vg) 224622bbedd7SHong Zhang { 224722bbedd7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 224822bbedd7SHong Zhang PetscInt *vltog = network->vltog; 224922bbedd7SHong Zhang 225022bbedd7SHong Zhang PetscFunctionBegin; 225122bbedd7SHong Zhang if (!vltog) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkSetVertexLocalToGlobalOrdering() first"); 225222bbedd7SHong Zhang *vg = vltog[vloc]; 225322bbedd7SHong Zhang PetscFunctionReturn(0); 225422bbedd7SHong Zhang } 225522bbedd7SHong Zhang 225622bbedd7SHong Zhang /*@ 225722bbedd7SHong Zhang DMNetworkSetVertexLocalToGlobalOrdering - Create and setup vertex local to globle map 225822bbedd7SHong Zhang 225922bbedd7SHong Zhang Collective 226022bbedd7SHong Zhang 226122bbedd7SHong Zhang Input Parameters: 2262*f0fc11ceSJed Brown . dm - the dm object 226322bbedd7SHong Zhang 226422bbedd7SHong Zhang Level: Advanced 226522bbedd7SHong Zhang 226663029d29SHong Zhang .seealso: DMNetworkGetGlobalVertexIndex() 226722bbedd7SHong Zhang @*/ 226822bbedd7SHong Zhang PetscErrorCode DMNetworkSetVertexLocalToGlobalOrdering(DM dm) 226922bbedd7SHong Zhang { 227022bbedd7SHong Zhang PetscErrorCode ierr; 227122bbedd7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 227222bbedd7SHong Zhang MPI_Comm comm; 227363029d29SHong Zhang PetscMPIInt rank,size,*displs,*recvcounts,remoterank; 227422bbedd7SHong Zhang PetscBool ghost; 227563029d29SHong Zhang PetscInt *vltog,nroots,nleaves,i,*vrange,k,N,lidx; 227622bbedd7SHong Zhang const PetscSFNode *iremote; 227722bbedd7SHong Zhang PetscSF vsf; 227863029d29SHong Zhang Vec Vleaves,Vleaves_seq; 227963029d29SHong Zhang VecScatter ctx; 228063029d29SHong Zhang PetscScalar *varr,val; 228163029d29SHong Zhang const PetscScalar *varr_read; 228222bbedd7SHong Zhang 228322bbedd7SHong Zhang PetscFunctionBegin; 228422bbedd7SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 228522bbedd7SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 228663029d29SHong Zhang ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 228722bbedd7SHong Zhang 228822bbedd7SHong Zhang if (size == 1) { 228922bbedd7SHong Zhang nroots = network->vEnd - network->vStart; 229022bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 229122bbedd7SHong Zhang for (i=0; i<nroots; i++) vltog[i] = i; 229222bbedd7SHong Zhang network->vltog = vltog; 229322bbedd7SHong Zhang PetscFunctionReturn(0); 229422bbedd7SHong Zhang } 229522bbedd7SHong Zhang 229622bbedd7SHong Zhang if (!network->distributecalled) SETERRQ(comm, PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkDistribute() first"); 229722bbedd7SHong Zhang if (network->vltog) { 229822bbedd7SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 229922bbedd7SHong Zhang } 230022bbedd7SHong Zhang 230122bbedd7SHong Zhang ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 230222bbedd7SHong Zhang ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 230322bbedd7SHong Zhang vsf = network->vertex.sf; 230422bbedd7SHong Zhang 230522bbedd7SHong Zhang ierr = PetscMalloc3(size+1,&vrange,size+1,&displs,size,&recvcounts);CHKERRQ(ierr); 2306f5427c60SHong Zhang ierr = PetscSFGetGraph(vsf,&nroots,&nleaves,NULL,&iremote);CHKERRQ(ierr); 230722bbedd7SHong Zhang 230822bbedd7SHong Zhang for (i=0; i<size; i++) { displs[i] = i; recvcounts[i] = 1;} 230922bbedd7SHong Zhang 231022bbedd7SHong Zhang i = nroots - nleaves; /* local number of vertices, excluding ghosts */ 231122bbedd7SHong Zhang vrange[0] = 0; 231222bbedd7SHong Zhang ierr = MPI_Allgatherv(&i,1,MPIU_INT,vrange+1,recvcounts,displs,MPIU_INT,comm);CHKERRQ(ierr); 231367dd800bSHong Zhang for (i=2; i<size+1; i++) {vrange[i] += vrange[i-1];} 231422bbedd7SHong Zhang 231522bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 231622bbedd7SHong Zhang network->vltog = vltog; 231722bbedd7SHong Zhang 231863029d29SHong Zhang /* Set vltog for non-ghost vertices */ 231963029d29SHong Zhang k = 0; 232022bbedd7SHong Zhang for (i=0; i<nroots; i++) { 232122bbedd7SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 232263029d29SHong Zhang if (ghost) continue; 232363029d29SHong Zhang vltog[i] = vrange[rank] + k++; 232422bbedd7SHong Zhang } 2325f5427c60SHong Zhang ierr = PetscFree3(vrange,displs,recvcounts);CHKERRQ(ierr); 232663029d29SHong Zhang 232763029d29SHong Zhang /* Set vltog for ghost vertices */ 232863029d29SHong Zhang /* (a) create parallel Vleaves and sequential Vleaves_seq to convert local iremote[*].index to global index */ 232963029d29SHong Zhang ierr = VecCreate(comm,&Vleaves);CHKERRQ(ierr); 233063029d29SHong Zhang ierr = VecSetSizes(Vleaves,2*nleaves,PETSC_DETERMINE);CHKERRQ(ierr); 233163029d29SHong Zhang ierr = VecSetFromOptions(Vleaves);CHKERRQ(ierr); 233263029d29SHong Zhang ierr = VecGetArray(Vleaves,&varr);CHKERRQ(ierr); 233363029d29SHong Zhang for (i=0; i<nleaves; i++) { 233463029d29SHong Zhang varr[2*i] = (PetscScalar)(iremote[i].rank); /* rank of remote process */ 233563029d29SHong Zhang varr[2*i+1] = (PetscScalar)(iremote[i].index); /* local index in remote process */ 233663029d29SHong Zhang } 233763029d29SHong Zhang ierr = VecRestoreArray(Vleaves,&varr);CHKERRQ(ierr); 233863029d29SHong Zhang 233963029d29SHong Zhang /* (b) scatter local info to remote processes via VecScatter() */ 234063029d29SHong Zhang ierr = VecScatterCreateToAll(Vleaves,&ctx,&Vleaves_seq);CHKERRQ(ierr); 234163029d29SHong Zhang ierr = VecScatterBegin(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 234263029d29SHong Zhang ierr = VecScatterEnd(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 234363029d29SHong Zhang 234463029d29SHong Zhang /* (c) convert local indices to global indices in parallel vector Vleaves */ 234563029d29SHong Zhang ierr = VecGetSize(Vleaves_seq,&N);CHKERRQ(ierr); 234663029d29SHong Zhang ierr = VecGetArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 234763029d29SHong Zhang for (i=0; i<N; i+=2) { 23482e4cff2eSHong Zhang remoterank = (PetscMPIInt)PetscRealPart(varr_read[i]); 234963029d29SHong Zhang if (remoterank == rank) { 235063029d29SHong Zhang k = i+1; /* row number */ 23512e4cff2eSHong Zhang lidx = (PetscInt)PetscRealPart(varr_read[i+1]); 235263029d29SHong Zhang val = (PetscScalar)vltog[lidx]; /* global index for non-ghost vertex computed above */ 235363029d29SHong Zhang ierr = VecSetValues(Vleaves,1,&k,&val,INSERT_VALUES);CHKERRQ(ierr); 235463029d29SHong Zhang } 235563029d29SHong Zhang } 235663029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 235763029d29SHong Zhang ierr = VecAssemblyBegin(Vleaves);CHKERRQ(ierr); 235863029d29SHong Zhang ierr = VecAssemblyEnd(Vleaves);CHKERRQ(ierr); 235963029d29SHong Zhang 236063029d29SHong Zhang /* (d) Set vltog for ghost vertices by copying local values of Vleaves */ 236163029d29SHong Zhang ierr = VecGetArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 236263029d29SHong Zhang k = 0; 236363029d29SHong Zhang for (i=0; i<nroots; i++) { 236463029d29SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 236563029d29SHong Zhang if (!ghost) continue; 23662e4cff2eSHong Zhang vltog[i] = (PetscInt)PetscRealPart(varr_read[2*k+1]); k++; 236763029d29SHong Zhang } 236863029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 236963029d29SHong Zhang 237063029d29SHong Zhang ierr = VecDestroy(&Vleaves);CHKERRQ(ierr); 237163029d29SHong Zhang ierr = VecDestroy(&Vleaves_seq);CHKERRQ(ierr); 237263029d29SHong Zhang ierr = VecScatterDestroy(&ctx);CHKERRQ(ierr); 237322bbedd7SHong Zhang PetscFunctionReturn(0); 237422bbedd7SHong Zhang } 2375