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: 92bf73ac6SHong Zhang . dm - the dm object 102bf73ac6SHong Zhang 112bf73ac6SHong Zhang Output Parameters: 122bf73ac6SHong Zhang . plexdm - the plex dm object 13556ed216SShri Abhyankar 14556ed216SShri Abhyankar Level: Advanced 15556ed216SShri Abhyankar 16556ed216SShri Abhyankar .seealso: DMNetworkCreate() 17556ed216SShri Abhyankar @*/ 182bf73ac6SHong Zhang PetscErrorCode DMNetworkGetPlex(DM dm,DM *plexdm) 19556ed216SShri Abhyankar { 202bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 21556ed216SShri Abhyankar 22556ed216SShri Abhyankar PetscFunctionBegin; 23556ed216SShri Abhyankar *plexdm = network->plex; 24556ed216SShri Abhyankar PetscFunctionReturn(0); 25556ed216SShri Abhyankar } 26556ed216SShri Abhyankar 27556ed216SShri Abhyankar /*@ 282bf73ac6SHong Zhang DMNetworkGetNumSubNetworks - Gets the the number of subnetworks 2972c3e9f7SHong Zhang 302bf73ac6SHong Zhang Not collective 3172c3e9f7SHong Zhang 3272c3e9f7SHong Zhang Input Parameters: 332bf73ac6SHong Zhang . dm - the dm object 342bf73ac6SHong Zhang 352bf73ac6SHong Zhang Output Parameters: 362bf73ac6SHong Zhang + nsubnet - local number of subnetworks 372bf73ac6SHong Zhang - Nsubnet - global number of subnetworks 3872c3e9f7SHong Zhang 3997bb938eSShri Abhyankar Level: beginner 4072c3e9f7SHong Zhang 412bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkSetNumSubNetworks() 4272c3e9f7SHong Zhang @*/ 432bf73ac6SHong Zhang PetscErrorCode DMNetworkGetNumSubNetworks(DM dm,PetscInt *nsubnet,PetscInt *Nsubnet) 4472c3e9f7SHong Zhang { 452bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 4672c3e9f7SHong Zhang 4772c3e9f7SHong Zhang PetscFunctionBegin; 482bf73ac6SHong Zhang if (nsubnet) *nsubnet = network->nsubnet; 492bf73ac6SHong Zhang if (Nsubnet) *Nsubnet = network->Nsubnet; 5072c3e9f7SHong Zhang PetscFunctionReturn(0); 5172c3e9f7SHong Zhang } 5272c3e9f7SHong Zhang 5372c3e9f7SHong Zhang /*@ 542bf73ac6SHong Zhang DMNetworkSetNumSubNetworks - Sets the number of subnetworks 555f2c45f1SShri Abhyankar 56d083f849SBarry Smith Collective on dm 575f2c45f1SShri Abhyankar 585f2c45f1SShri Abhyankar Input Parameters: 595f2c45f1SShri Abhyankar + dm - the dm object 602bf73ac6SHong Zhang . nsubnet - local number of subnetworks 612bf73ac6SHong Zhang - Nsubnet - global number of subnetworks 625f2c45f1SShri Abhyankar 6397bb938eSShri Abhyankar Level: beginner 641b266c99SBarry Smith 652bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkGetNumSubNetworks() 665f2c45f1SShri Abhyankar @*/ 672bf73ac6SHong Zhang PetscErrorCode DMNetworkSetNumSubNetworks(DM dm,PetscInt nsubnet,PetscInt Nsubnet) 685f2c45f1SShri Abhyankar { 695f2c45f1SShri Abhyankar PetscErrorCode ierr; 705f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 715f2c45f1SShri Abhyankar 725f2c45f1SShri Abhyankar PetscFunctionBegin; 732bf73ac6SHong Zhang if (network->Nsubnet != 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Network sizes alread set, cannot resize the network"); 742bf73ac6SHong Zhang 755f2c45f1SShri Abhyankar PetscValidHeaderSpecific(dm,DM_CLASSID,1); 762bf73ac6SHong Zhang PetscValidLogicalCollectiveInt(dm,nsubnet,2); 772bf73ac6SHong Zhang PetscValidLogicalCollectiveInt(dm,Nsubnet,3); 787765340cSHong Zhang 792bf73ac6SHong Zhang if (Nsubnet == PETSC_DECIDE) { 802bf73ac6SHong Zhang if (nsubnet < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of local subnetworks %D cannot be less than 0",nsubnet); 8155b25c41SPierre Jolivet ierr = MPIU_Allreduce(&nsubnet,&Nsubnet,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 82caf410d2SHong Zhang } 832bf73ac6SHong Zhang if (Nsubnet < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Number of global subnetworks %D cannot be less than 1",Nsubnet); 84caf410d2SHong Zhang 852bf73ac6SHong Zhang network->Nsubnet = Nsubnet; 862bf73ac6SHong Zhang network->nsubnet = 0; /* initia value; will be determind by DMNetworkAddSubnetwork() */ 872bf73ac6SHong Zhang ierr = PetscCalloc1(Nsubnet,&network->subnet);CHKERRQ(ierr); 88caf410d2SHong Zhang 892bf73ac6SHong Zhang /* num of shared vertices */ 902bf73ac6SHong Zhang network->nsvtx = 0; 912bf73ac6SHong Zhang network->Nsvtx = 0; 927765340cSHong Zhang PetscFunctionReturn(0); 937765340cSHong Zhang } 947765340cSHong Zhang 955f2c45f1SShri Abhyankar /*@ 962bf73ac6SHong Zhang DMNetworkAddSubnetwork - Add a subnetwork 975f2c45f1SShri Abhyankar 982bf73ac6SHong Zhang Collective on dm 995f2c45f1SShri Abhyankar 1005f2c45f1SShri Abhyankar Input Parameters: 101e3e68989SHong Zhang + dm - the dm object 1022bf73ac6SHong Zhang . name - name of the subnetwork 1032bf73ac6SHong Zhang . nv - number of local vertices of this subnetwork 1042bf73ac6SHong Zhang . ne - number of local edges of this subnetwork 1052bf73ac6SHong Zhang - edgelist - list of edges for this subnetwork 1062bf73ac6SHong Zhang 1072bf73ac6SHong Zhang Output Parameters: 1082bf73ac6SHong Zhang . netnum - global index of the subnetwork 1095f2c45f1SShri Abhyankar 1105f2c45f1SShri Abhyankar Notes: 1115f2c45f1SShri Abhyankar There is no copy involved in this operation, only the pointer is referenced. The edgelist should 1122bf73ac6SHong Zhang not be destroyed before the call to DMNetworkLayoutSetUp() 1135f2c45f1SShri Abhyankar 11497bb938eSShri Abhyankar Level: beginner 1155f2c45f1SShri Abhyankar 116e3e68989SHong Zhang Example usage: 1172bf73ac6SHong Zhang Consider the following network: 118e3e68989SHong Zhang .vb 119e3e68989SHong Zhang network 1: v1 -> v2 -> v0 120e3e68989SHong Zhang .ve 121e3e68989SHong Zhang 122e3e68989SHong Zhang The resulting input 1232bf73ac6SHong Zhang edgelist = [1 2 | 2 0] 124e3e68989SHong Zhang 1252bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkSetNumSubnetworks() 1265f2c45f1SShri Abhyankar @*/ 1272bf73ac6SHong Zhang PetscErrorCode DMNetworkAddSubnetwork(DM dm,const char* name,PetscInt nv,PetscInt ne,PetscInt edgelist[],PetscInt *netnum) 1285f2c45f1SShri Abhyankar { 1292bf73ac6SHong Zhang PetscErrorCode ierr; 1305f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 1312bf73ac6SHong Zhang PetscInt i = network->nsubnet,a[2],b[2]; 1325f2c45f1SShri Abhyankar 1335f2c45f1SShri Abhyankar PetscFunctionBegin; 1342bf73ac6SHong Zhang if (name) { 1352bf73ac6SHong Zhang ierr = PetscStrcpy(network->subnet[i].name,name);CHKERRQ(ierr); 136e3e68989SHong Zhang } 1372bf73ac6SHong Zhang 1382bf73ac6SHong Zhang network->subnet[i].nvtx = nv; 1392bf73ac6SHong Zhang network->subnet[i].nedge = ne; 1402bf73ac6SHong Zhang network->subnet[i].edgelist = edgelist; 1412bf73ac6SHong Zhang 1422bf73ac6SHong Zhang /* Get global number of vertices and edges for subnet[i] */ 1432bf73ac6SHong Zhang a[0] = nv; a[1] = ne; 14455b25c41SPierre Jolivet ierr = MPIU_Allreduce(a,b,2,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 1452bf73ac6SHong Zhang network->subnet[i].Nvtx = b[0]; 1462bf73ac6SHong Zhang network->subnet[i].Nedge = b[1]; 1472bf73ac6SHong Zhang 1482bf73ac6SHong Zhang /* ---------------------------------------------------------- 1492bf73ac6SHong Zhang p=v or e; 1502bf73ac6SHong Zhang subnet[0].pStart = 0 1512bf73ac6SHong Zhang subnet[i+1].pStart = subnet[i].pEnd = subnet[i].pStart + (nE[i] or NV[i]) 1522bf73ac6SHong Zhang ----------------------------------------------------------------------- */ 1532bf73ac6SHong Zhang /* GLOBAL subnet[].vStart and vEnd, used by DMNetworkLayoutSetUp() */ 1542bf73ac6SHong Zhang network->subnet[i].vStart = network->NVertices; 1552bf73ac6SHong Zhang network->subnet[i].vEnd = network->subnet[i].vStart + network->subnet[i].Nvtx; /* global vEnd of subnet[i] */ 1562bf73ac6SHong Zhang 1572bf73ac6SHong Zhang network->nVertices += nv; 1582bf73ac6SHong Zhang network->NVertices += network->subnet[i].Nvtx; 1592bf73ac6SHong Zhang 1602bf73ac6SHong Zhang /* LOCAL subnet[].eStart and eEnd, used by DMNetworkLayoutSetUp() */ 1612bf73ac6SHong Zhang network->subnet[i].eStart = network->nEdges; 1622bf73ac6SHong Zhang network->subnet[i].eEnd = network->subnet[i].eStart + ne; 1632bf73ac6SHong Zhang network->nEdges += ne; 1642bf73ac6SHong Zhang network->NEdges += network->subnet[i].Nedge; 1652bf73ac6SHong Zhang 1662bf73ac6SHong Zhang ierr = PetscStrcpy(network->subnet[i].name,name);CHKERRQ(ierr); 1672bf73ac6SHong Zhang if (netnum) *netnum = network->nsubnet; 1682bf73ac6SHong Zhang network->nsubnet++; 1692bf73ac6SHong Zhang PetscFunctionReturn(0); 1702bf73ac6SHong Zhang } 1712bf73ac6SHong Zhang 1722bf73ac6SHong Zhang /* 1732bf73ac6SHong Zhang SetUp a single svtx struct. See SVtx defined in dmnetworkimpl.h 1742bf73ac6SHong Zhang Set gidx and type if input v=(net,idx) is a from_vertex; 1752bf73ac6SHong Zhang Get gid, type and index in the svtx array if input v=(net,idx) is a to_vertex. 1762bf73ac6SHong Zhang 1772bf73ac6SHong Zhang Input: Nsvtx, svtx, net, idx, gidx 1782bf73ac6SHong Zhang Output: gidx, svtype, svtx_idx 1792bf73ac6SHong Zhang */ 1802bf73ac6SHong Zhang static PetscErrorCode SVtxSetUp(PetscInt Nsvtx,SVtx *svtx,PetscInt net,PetscInt idx,PetscInt *gidx,SVtxType *svtype,PetscInt *svtx_idx) 1812bf73ac6SHong Zhang { 1822bf73ac6SHong Zhang PetscInt i,j,*svto; 1832bf73ac6SHong Zhang SVtxType vtype; 1842bf73ac6SHong Zhang 1852bf73ac6SHong Zhang PetscFunctionBegin; 1862bf73ac6SHong Zhang if (!Nsvtx) PetscFunctionReturn(0); 1872bf73ac6SHong Zhang 1882bf73ac6SHong Zhang vtype = SVNONE; 1892bf73ac6SHong Zhang for (i=0; i<Nsvtx; i++) { 1902bf73ac6SHong Zhang if (net == svtx[i].sv[0] && idx == svtx[i].sv[1]) { 1912bf73ac6SHong Zhang /* (1) input vertex net.idx is a shared from_vertex, set its global index and output its svtype */ 1922bf73ac6SHong Zhang svtx[i].gidx = *gidx; /* set gidx */ 1932bf73ac6SHong Zhang vtype = SVFROM; 1942bf73ac6SHong Zhang } else { /* loop over svtx[i].n */ 1952bf73ac6SHong Zhang for (j=1; j<svtx[i].n; j++) { 1962bf73ac6SHong Zhang svto = svtx[i].sv + 2*j; 1972bf73ac6SHong Zhang if (net == svto[0] && idx == svto[1]) { 1982bf73ac6SHong Zhang /* input vertex net.idx is a shared to_vertex, output its global index and its svtype */ 1992bf73ac6SHong Zhang *gidx = svtx[i].gidx; /* output gidx for to_vertex */ 2002bf73ac6SHong Zhang vtype = SVTO; 2012bf73ac6SHong Zhang } 2022bf73ac6SHong Zhang } 2032bf73ac6SHong Zhang } 2042bf73ac6SHong Zhang if (vtype != SVNONE) break; 2052bf73ac6SHong Zhang } 2062bf73ac6SHong Zhang if (svtype) *svtype = vtype; 2072bf73ac6SHong Zhang if (svtx_idx) *svtx_idx = i; 2082bf73ac6SHong Zhang PetscFunctionReturn(0); 2092bf73ac6SHong Zhang } 2102bf73ac6SHong Zhang 2112bf73ac6SHong Zhang /* 2122bf73ac6SHong Zhang Add a new shared vertex sv=(net,idx) to table svtas[ita] 2132bf73ac6SHong Zhang */ 2142bf73ac6SHong Zhang static PetscErrorCode TableAddSVtx(PetscTable *svtas,PetscInt ita,PetscInt* tdata,PetscInt *sv_wk,PetscInt *ii,PetscInt *sedgelist,PetscInt k,DM_Network *network,PetscInt **ta2sv) 2152bf73ac6SHong Zhang { 2162bf73ac6SHong Zhang PetscInt net,idx,gidx,i=*ii; 2172bf73ac6SHong Zhang PetscErrorCode ierr; 2182bf73ac6SHong Zhang 2192bf73ac6SHong Zhang PetscFunctionBegin; 2202bf73ac6SHong Zhang net = sv_wk[2*i] = sedgelist[k]; 2212bf73ac6SHong Zhang idx = sv_wk[2*i+1] = sedgelist[k+1]; 2222bf73ac6SHong Zhang gidx = network->subnet[net].vStart + idx; 2232bf73ac6SHong Zhang ierr = PetscTableAdd(svtas[ita],gidx+1,tdata[ita]+1,INSERT_VALUES);CHKERRQ(ierr); 2242bf73ac6SHong Zhang *(ta2sv[ita] + tdata[ita]) = i; /* maps tdata to index of sv_wk; sv_wk keeps (net,idx) info */ 2252bf73ac6SHong Zhang tdata[ita]++; (*ii)++; 2262bf73ac6SHong Zhang PetscFunctionReturn(0); 2272bf73ac6SHong Zhang } 2282bf73ac6SHong Zhang 2292bf73ac6SHong Zhang /* 2302bf73ac6SHong Zhang Create an array of shared vertices. See SVtx and SVtxType in dmnetworkimpl.h 2312bf73ac6SHong Zhang 2322bf73ac6SHong Zhang Input: dm, Nsedgelist, sedgelist 2332bf73ac6SHong Zhang Output: Nsvtx,svtx 2342bf73ac6SHong Zhang 2352bf73ac6SHong Zhang Note: Output svtx is organized as 2362bf73ac6SHong Zhang sv(net[0],idx[0]) --> sv(net[1],idx[1]) 2372bf73ac6SHong Zhang --> sv(net[1],idx[1]) 2382bf73ac6SHong Zhang ... 2392bf73ac6SHong Zhang --> sv(net[n-1],idx[n-1]) 2402bf73ac6SHong Zhang and net[0] < net[1] < ... < net[n-1] 2412bf73ac6SHong Zhang where sv[0] has SVFROM type, sv[i], i>0, has SVTO type. 2422bf73ac6SHong Zhang */ 2432bf73ac6SHong Zhang static PetscErrorCode SVtxCreate(DM dm,PetscInt Nsedgelist,PetscInt *sedgelist,PetscInt *Nsvtx,SVtx **svtx) 2442bf73ac6SHong Zhang { 2452bf73ac6SHong Zhang PetscErrorCode ierr; 2462bf73ac6SHong Zhang SVtx *sedges = NULL; 2472bf73ac6SHong Zhang PetscInt *sv,k,j,nsv,*tdata,**ta2sv; 2482bf73ac6SHong Zhang PetscTable *svtas; 2492bf73ac6SHong Zhang PetscInt gidx,net,idx,i,nta,ita,idx_from,idx_to,n,*sv_wk; 2502bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 2512bf73ac6SHong Zhang PetscTablePosition ppos; 2522bf73ac6SHong Zhang 2532bf73ac6SHong Zhang PetscFunctionBegin; 2542bf73ac6SHong Zhang /* (1) Crete ctables svtas */ 2552bf73ac6SHong Zhang ierr = PetscCalloc4(Nsedgelist,&svtas,Nsedgelist,&tdata,4*Nsedgelist,&sv_wk,2*Nsedgelist,&ta2sv);CHKERRQ(ierr); 2562bf73ac6SHong Zhang 2572bf73ac6SHong Zhang j = 0; /* sedgelist counter */ 2582bf73ac6SHong Zhang k = 0; /* sedgelist vertex counter j = 4*k */ 2592bf73ac6SHong Zhang i = 0; /* sv_wk (vertices added to the ctables) counter */ 2602bf73ac6SHong Zhang nta = 0; /* num of sv tables created */ 2612bf73ac6SHong Zhang 2622bf73ac6SHong Zhang /* for j=0 */ 2632bf73ac6SHong Zhang ierr = PetscTableCreate(2*Nsedgelist,network->NVertices+1,&svtas[nta]);CHKERRQ(ierr); 2642bf73ac6SHong Zhang ierr = PetscMalloc1(2*Nsedgelist,&ta2sv[nta]);CHKERRQ(ierr); 2652bf73ac6SHong Zhang 2662bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,nta,tdata,sv_wk,&i,sedgelist,k,network,ta2sv);CHKERRQ(ierr); 2672bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,nta,tdata,sv_wk,&i,sedgelist,k+2,network,ta2sv);CHKERRQ(ierr); 2682bf73ac6SHong Zhang nta++; k += 4; 2692bf73ac6SHong Zhang 2702bf73ac6SHong Zhang for (j = 1; j < Nsedgelist; j++) { 2712bf73ac6SHong Zhang for (ita = 0; ita < nta; ita++) { 2722bf73ac6SHong Zhang /* vfrom */ 2732bf73ac6SHong Zhang net = sedgelist[k]; idx = sedgelist[k+1]; 2742bf73ac6SHong Zhang gidx = network->subnet[net].vStart + idx; /* global index of the vertex net.idx before merging shared vertices */ 2752bf73ac6SHong Zhang ierr = PetscTableFind(svtas[ita],gidx+1,&idx_from);CHKERRQ(ierr); 2762bf73ac6SHong Zhang 2772bf73ac6SHong Zhang /* vto */ 2782bf73ac6SHong Zhang net = sedgelist[k+2]; idx = sedgelist[k+3]; 2792bf73ac6SHong Zhang gidx = network->subnet[net].vStart + idx; 2802bf73ac6SHong Zhang ierr = PetscTableFind(svtas[ita],gidx+1,&idx_to);CHKERRQ(ierr); 2812bf73ac6SHong Zhang 2822bf73ac6SHong Zhang if (idx_from || idx_to) { /* vfrom or vto is on table svtas[ita] */ 2832bf73ac6SHong Zhang idx_from--; idx_to--; 2842bf73ac6SHong Zhang if (idx_from < 0) { /* vto is on svtas[ita] */ 2852bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,ita,tdata,sv_wk,&i,sedgelist,k,network,ta2sv);CHKERRQ(ierr); 2862bf73ac6SHong Zhang break; 2872bf73ac6SHong Zhang } else if (idx_to < 0) { 2882bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,ita,tdata,sv_wk,&i,sedgelist,k+2,network,ta2sv);CHKERRQ(ierr); 2892bf73ac6SHong Zhang break; 2902bf73ac6SHong Zhang } 2912bf73ac6SHong Zhang } 2922bf73ac6SHong Zhang } 2932bf73ac6SHong Zhang 2942bf73ac6SHong Zhang if (ita == nta) { 2952bf73ac6SHong Zhang ierr = PetscTableCreate(2*Nsedgelist,network->NVertices+1,&svtas[nta]);CHKERRQ(ierr); 2962bf73ac6SHong Zhang ierr = PetscMalloc1(2*Nsedgelist, &ta2sv[nta]);CHKERRQ(ierr); 2972bf73ac6SHong Zhang 2982bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,nta,tdata,sv_wk,&i,sedgelist,k,network,ta2sv);CHKERRQ(ierr); 2992bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,nta,tdata,sv_wk,&i,sedgelist,k+2,network,ta2sv);CHKERRQ(ierr); 3002bf73ac6SHong Zhang nta++; 3012bf73ac6SHong Zhang } 3022bf73ac6SHong Zhang k += 4; 3032bf73ac6SHong Zhang } 3042bf73ac6SHong Zhang 3052bf73ac6SHong Zhang /* (2) Construct sedges from ctable 3062bf73ac6SHong Zhang sedges: edges connect vertex sv[0]=(net[0],idx[0]) to vertices sv[k], k=1,...,n-1; 3074f5c2772SJose E. Roman net[k], k=0, ...,n-1, are in ascending order */ 3082bf73ac6SHong Zhang ierr = PetscMalloc1(nta,&sedges);CHKERRQ(ierr); 3092bf73ac6SHong Zhang for (nsv = 0; nsv < nta; nsv++) { 3104f5c2772SJose E. Roman /* for a single svtx, put shared vertices in ascending order of gidx */ 3114f5c2772SJose E. Roman ierr = PetscTableGetCount(svtas[nsv],&n);CHKERRQ(ierr); 3122bf73ac6SHong Zhang ierr = PetscCalloc1(2*n,&sv);CHKERRQ(ierr); 3132bf73ac6SHong Zhang sedges[nsv].sv = sv; 3142bf73ac6SHong Zhang sedges[nsv].n = n; 3152bf73ac6SHong Zhang sedges[nsv].gidx = -1; /* initialization */ 3162bf73ac6SHong Zhang 3172bf73ac6SHong Zhang ierr = PetscTableGetHeadPosition(svtas[nsv],&ppos);CHKERRQ(ierr); 3184f5c2772SJose E. Roman for (k=0; k<n; k++) { /* gidx is sorted in ascending order */ 3192bf73ac6SHong Zhang ierr = PetscTableGetNext(svtas[nsv],&ppos,&gidx,&i);CHKERRQ(ierr); 3202bf73ac6SHong Zhang gidx--; i--; 3212bf73ac6SHong Zhang 3222bf73ac6SHong Zhang j = ta2sv[nsv][i]; /* maps i to index of sv_wk */ 3232bf73ac6SHong Zhang sv[2*k] = sv_wk[2*j]; 3242bf73ac6SHong Zhang sv[2*k+1] = sv_wk[2*j + 1]; 3252bf73ac6SHong Zhang } 3262bf73ac6SHong Zhang } 3272bf73ac6SHong Zhang 3282bf73ac6SHong Zhang for (j=0; j<nta; j++) { 3292bf73ac6SHong Zhang ierr = PetscTableDestroy(&svtas[j]);CHKERRQ(ierr); 3302bf73ac6SHong Zhang ierr = PetscFree(ta2sv[j]);CHKERRQ(ierr); 3312bf73ac6SHong Zhang } 3322bf73ac6SHong Zhang ierr = PetscFree4(svtas,tdata,sv_wk,ta2sv);CHKERRQ(ierr); 3332bf73ac6SHong Zhang 3342bf73ac6SHong Zhang *Nsvtx = nta; 3352bf73ac6SHong Zhang *svtx = sedges; 3362bf73ac6SHong Zhang PetscFunctionReturn(0); 3372bf73ac6SHong Zhang } 3382bf73ac6SHong Zhang 3392bf73ac6SHong Zhang static PetscErrorCode DMNetworkLayoutSetUp_Coupling(DM dm) 3402bf73ac6SHong Zhang { 3412bf73ac6SHong Zhang PetscErrorCode ierr; 3422bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 3432bf73ac6SHong Zhang PetscInt i,j,ctr,np,*edges,*subnetvtx,vStart; 3442bf73ac6SHong Zhang PetscInt k,*vidxlTog,Nsv=0,Nsubnet=network->Nsubnet; 3452bf73ac6SHong Zhang PetscInt *sedgelist=network->sedgelist; 3462bf73ac6SHong Zhang const PetscInt *cone; 3472bf73ac6SHong Zhang MPI_Comm comm; 3482bf73ac6SHong Zhang PetscMPIInt size,rank,*recvcounts=NULL,*displs=NULL; 3492bf73ac6SHong Zhang PetscInt net,idx,gidx,nmerged,e,v,vfrom,vto,*vrange,*eowners,gidx_from,net_from,sv_idx; 3502bf73ac6SHong Zhang SVtxType svtype = SVNONE; 3512bf73ac6SHong Zhang SVtx *svtx=NULL; 3522bf73ac6SHong Zhang PetscSection sectiong; 3532bf73ac6SHong Zhang 3542bf73ac6SHong Zhang PetscFunctionBegin; 3552bf73ac6SHong Zhang /* This implementation requires user input each subnet by a single processor, thus subnet[net].nvtx=subnet[net].Nvtx */ 3562bf73ac6SHong Zhang for (net=0; net<Nsubnet; net++) { 3572bf73ac6SHong Zhang if (network->subnet[net].nvtx && network->subnet[net].nvtx != network->subnet[net].Nvtx) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_SUP,"subnetwork %D local num of vertices %D != %D global num",net,network->subnet[net].nvtx,network->subnet[net].Nvtx); 3582bf73ac6SHong Zhang } 3592bf73ac6SHong Zhang 3602bf73ac6SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 36155b25c41SPierre Jolivet ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 36255b25c41SPierre Jolivet ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 3632bf73ac6SHong Zhang 3642bf73ac6SHong Zhang /* (1) Create svtx[] from sedgelist */ 3652bf73ac6SHong Zhang /* -------------------------------- */ 3662bf73ac6SHong Zhang /* Nsv: global number of SVtx; svtx: shared vertices, see SVtx in dmnetworkimpl.h */ 3672bf73ac6SHong Zhang ierr = SVtxCreate(dm,network->Nsvtx,sedgelist,&Nsv,&svtx);CHKERRQ(ierr); 3682bf73ac6SHong Zhang 3692bf73ac6SHong Zhang /* (2) Setup svtx; Shared vto vertices are merged to their vfrom vertex with same global vetex index (gidx) */ 3702bf73ac6SHong Zhang /* -------------------------------------------------------------------------------------------------------- */ 3712bf73ac6SHong Zhang /* (2.1) compute vrage[rank]: global index of 1st local vertex in proc[rank] */ 3722bf73ac6SHong Zhang ierr = PetscMalloc3(size+1,&vrange,size,&displs,size,&recvcounts);CHKERRQ(ierr); 3732bf73ac6SHong Zhang for (i=0; i<size; i++) {displs[i] = i; recvcounts[i] = 1;} 3742bf73ac6SHong Zhang 3752bf73ac6SHong Zhang vrange[0] = 0; 3762bf73ac6SHong Zhang ierr = MPI_Allgatherv(&network->nVertices,1,MPIU_INT,vrange+1,recvcounts,displs,MPIU_INT,comm);CHKERRMPI(ierr); 3772bf73ac6SHong Zhang for (i=2; i<size+1; i++) { 3782bf73ac6SHong Zhang vrange[i] += vrange[i-1]; 3792bf73ac6SHong Zhang } 3802bf73ac6SHong Zhang 3812bf73ac6SHong Zhang /* (2.2) Create vidxlTog: maps UN-MERGED local vertex index i to global index gidx (plex, excluding ghost vertices) */ 3822bf73ac6SHong Zhang ierr = PetscMalloc1(network->nVertices,&vidxlTog);CHKERRQ(ierr); 3832bf73ac6SHong Zhang i = 0; gidx = 0; 3842bf73ac6SHong Zhang nmerged = 0; /* local num of merged vertices */ 3852bf73ac6SHong Zhang network->nsvtx = 0; 3862bf73ac6SHong Zhang for (net=0; net<Nsubnet; net++) { 3872bf73ac6SHong Zhang for (idx=0; idx<network->subnet[net].Nvtx; idx++) { 3882bf73ac6SHong Zhang gidx_from = gidx; 3892bf73ac6SHong Zhang sv_idx = -1; 3902bf73ac6SHong Zhang 3912bf73ac6SHong Zhang ierr = SVtxSetUp(Nsv,svtx,net,idx,&gidx_from,&svtype,&sv_idx);CHKERRQ(ierr); 3922bf73ac6SHong Zhang if (svtype == SVTO) { 3932bf73ac6SHong Zhang if (network->subnet[net].nvtx) {/* this proc owns sv_to */ 3942bf73ac6SHong Zhang net_from = svtx[sv_idx].sv[0]; /* subnet num of its shared vertex */ 3952bf73ac6SHong Zhang if (network->subnet[net_from].nvtx == 0) { 3962bf73ac6SHong Zhang /* this proc does not own v_from, thus a new local coupling vertex */ 3972bf73ac6SHong Zhang network->nsvtx++; 3982bf73ac6SHong Zhang } 3992bf73ac6SHong Zhang vidxlTog[i++] = gidx_from; 4002bf73ac6SHong Zhang nmerged++; /* a coupling vertex -- merged */ 4012bf73ac6SHong Zhang } 4022bf73ac6SHong Zhang } else { 4032bf73ac6SHong Zhang if (svtype == SVFROM) { 4042bf73ac6SHong Zhang if (network->subnet[net].nvtx) { 4052bf73ac6SHong Zhang /* this proc owns this v_from, a new local coupling vertex */ 4062bf73ac6SHong Zhang network->nsvtx++; 4072bf73ac6SHong Zhang } 4082bf73ac6SHong Zhang } 4092bf73ac6SHong Zhang if (network->subnet[net].nvtx) vidxlTog[i++] = gidx; 4102bf73ac6SHong Zhang gidx++; 4112bf73ac6SHong Zhang } 4122bf73ac6SHong Zhang } 4132bf73ac6SHong Zhang } 4142bf73ac6SHong Zhang #if defined(PETSC_USE_DEBUG) 4152bf73ac6SHong Zhang if (i != network->nVertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"%D != %D nVertices",i,network->nVertices); 4162bf73ac6SHong Zhang #endif 4172bf73ac6SHong Zhang 4182bf73ac6SHong Zhang /* (2.3) Setup svtable for querry shared vertices */ 4192bf73ac6SHong Zhang for (v=0; v<Nsv; v++) { 4202bf73ac6SHong Zhang gidx = svtx[v].gidx; 4212bf73ac6SHong Zhang ierr = PetscTableAdd(network->svtable,gidx+1,v+1,INSERT_VALUES);CHKERRQ(ierr); 4222bf73ac6SHong Zhang } 4232bf73ac6SHong Zhang 4242bf73ac6SHong Zhang /* (2.4) Shared vertices in the subnetworks are merged, update global NVertices: np = sum(local nmerged) */ 4252bf73ac6SHong Zhang ierr = MPI_Allreduce(&nmerged,&np,1,MPIU_INT,MPI_SUM,comm);CHKERRMPI(ierr); 4262bf73ac6SHong Zhang network->NVertices -= np; 4272bf73ac6SHong Zhang 4282bf73ac6SHong Zhang ierr = PetscCalloc1(2*network->nEdges,&edges);CHKERRQ(ierr); 4292bf73ac6SHong Zhang ierr = PetscCalloc1(network->nVertices+network->nsvtx,&network->subnetvtx);CHKERRQ(ierr); 4302bf73ac6SHong Zhang 4312bf73ac6SHong Zhang ctr = 0; 4322bf73ac6SHong Zhang for (net=0; net<Nsubnet; net++) { 4332bf73ac6SHong Zhang for (j = 0; j < network->subnet[net].nedge; j++) { 4342bf73ac6SHong Zhang /* vfrom: */ 4352bf73ac6SHong Zhang i = network->subnet[net].edgelist[2*j] + (network->subnet[net].vStart - vrange[rank]); 4362bf73ac6SHong Zhang edges[2*ctr] = vidxlTog[i]; 4372bf73ac6SHong Zhang 4382bf73ac6SHong Zhang /* vto */ 4392bf73ac6SHong Zhang i = network->subnet[net].edgelist[2*j+1] + (network->subnet[net].vStart - vrange[rank]); 4402bf73ac6SHong Zhang edges[2*ctr+1] = vidxlTog[i]; 4412bf73ac6SHong Zhang ctr++; 4422bf73ac6SHong Zhang } 4432bf73ac6SHong Zhang } 4442bf73ac6SHong Zhang ierr = PetscFree3(vrange,displs,recvcounts);CHKERRQ(ierr); 4452bf73ac6SHong Zhang ierr = PetscFree(vidxlTog);CHKERRQ(ierr); 4462bf73ac6SHong Zhang 4472bf73ac6SHong Zhang /* (3) Create network->plex */ 4482bf73ac6SHong Zhang ierr = DMCreate(comm,&network->plex);CHKERRQ(ierr); 4492bf73ac6SHong Zhang ierr = DMSetType(network->plex,DMPLEX);CHKERRQ(ierr); 4502bf73ac6SHong Zhang ierr = DMSetDimension(network->plex,1);CHKERRQ(ierr); 4512bf73ac6SHong Zhang if (size == 1) { 4522bf73ac6SHong Zhang ierr = DMPlexBuildFromCellList(network->plex,network->nEdges,network->nVertices-nmerged,2,edges);CHKERRQ(ierr); 4532bf73ac6SHong Zhang } else { 4542bf73ac6SHong Zhang ierr = DMPlexBuildFromCellListParallel(network->plex,network->nEdges,network->nVertices-nmerged,PETSC_DECIDE,2,edges,NULL);CHKERRQ(ierr); 4552bf73ac6SHong Zhang } 4562bf73ac6SHong Zhang 4572bf73ac6SHong Zhang ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr); 4582bf73ac6SHong Zhang ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr); 4592bf73ac6SHong Zhang ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr); 4602bf73ac6SHong Zhang vStart = network->vStart; 4612bf73ac6SHong Zhang 4622bf73ac6SHong Zhang ierr = PetscSectionCreate(comm,&network->DataSection);CHKERRQ(ierr); 4632bf73ac6SHong Zhang ierr = PetscSectionCreate(comm,&network->DofSection);CHKERRQ(ierr); 4642bf73ac6SHong Zhang ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr); 4652bf73ac6SHong Zhang ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr); 4662bf73ac6SHong Zhang 4672bf73ac6SHong Zhang network->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 4682bf73ac6SHong Zhang np = network->pEnd - network->pStart; 4692bf73ac6SHong Zhang ierr = PetscCalloc2(np,&network->header,np,&network->cvalue);CHKERRQ(ierr); 4702bf73ac6SHong Zhang 4712bf73ac6SHong Zhang /* (4) Create vidxlTog: maps MERGED plex local vertex index (including ghosts) to User's global vertex index (without merging shared vertices) */ 4722bf73ac6SHong Zhang np = network->vEnd - vStart; /* include ghost vertices */ 4732bf73ac6SHong Zhang ierr = PetscMalloc2(np,&vidxlTog,size+1,&eowners);CHKERRQ(ierr); 4742bf73ac6SHong Zhang 4752bf73ac6SHong Zhang ctr = 0; 4762bf73ac6SHong Zhang for (e=network->eStart; e<network->eEnd; e++) { 4772bf73ac6SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 4782bf73ac6SHong Zhang vidxlTog[cone[0] - vStart] = edges[2*ctr]; 4792bf73ac6SHong Zhang vidxlTog[cone[1] - vStart] = edges[2*ctr+1]; 4802bf73ac6SHong Zhang ctr++; 4812bf73ac6SHong Zhang } 4822bf73ac6SHong Zhang ierr = PetscFree(edges);CHKERRQ(ierr); 4832bf73ac6SHong Zhang 4842bf73ac6SHong Zhang /* (5) Create vertices and edges array for the subnetworks */ 4852bf73ac6SHong Zhang subnetvtx = network->subnetvtx; 4862bf73ac6SHong Zhang for (j=0; j < Nsubnet; j++) { 4872bf73ac6SHong Zhang ierr = PetscCalloc1(network->subnet[j].nedge,&network->subnet[j].edges);CHKERRQ(ierr); 4882bf73ac6SHong Zhang network->subnet[j].vertices = subnetvtx; 4892bf73ac6SHong Zhang subnetvtx += network->subnet[j].nvtx; 4902bf73ac6SHong Zhang } 4912bf73ac6SHong Zhang network->svertices = subnetvtx; 4922bf73ac6SHong Zhang 4932bf73ac6SHong Zhang /* Get edge ownership */ 4942bf73ac6SHong Zhang np = network->eEnd - network->eStart; /* num of local edges */ 4952bf73ac6SHong Zhang ierr = MPI_Allgather(&np,1,MPIU_INT,eowners+1,1,MPIU_INT,comm);CHKERRMPI(ierr); 4962bf73ac6SHong Zhang eowners[0] = 0; 4972bf73ac6SHong Zhang for (i=2; i<=size; i++) eowners[i] += eowners[i-1]; 4982bf73ac6SHong Zhang 4992bf73ac6SHong Zhang e = 0; 5002bf73ac6SHong Zhang for (i=0; i < Nsubnet; i++) { 5012bf73ac6SHong Zhang v = 0; 5022bf73ac6SHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 5032bf73ac6SHong Zhang 5042bf73ac6SHong Zhang /* edge e */ 5052bf73ac6SHong Zhang network->header[e].index = e + eowners[rank]; /* Global edge index */ 5062bf73ac6SHong Zhang network->header[e].subnetid = i; /* Subnetwork id */ 5072bf73ac6SHong Zhang network->subnet[i].edges[j] = e; 5082bf73ac6SHong Zhang network->header[e].ndata = 0; 5092bf73ac6SHong Zhang network->header[e].offset[0] = 0; 5102bf73ac6SHong Zhang network->header[e].offsetvarrel[0] = 0; 5112bf73ac6SHong Zhang ierr = PetscSectionAddDof(network->DataSection,e,network->dataheadersize);CHKERRQ(ierr); 5122bf73ac6SHong Zhang 5132bf73ac6SHong Zhang /* connected vertices */ 5142bf73ac6SHong Zhang ierr = DMPlexGetCone(network->plex,e,&cone);CHKERRQ(ierr); 5152bf73ac6SHong Zhang 5162bf73ac6SHong Zhang /* vertex cone[0] */ 5172bf73ac6SHong Zhang vfrom = network->subnet[i].edgelist[2*v]; 5182bf73ac6SHong Zhang network->header[cone[0]].index = vidxlTog[cone[0]-vStart]; /* Global vertex index */ 5192bf73ac6SHong Zhang network->header[cone[0]].subnetid = i; /* Subnetwork id */ 5202bf73ac6SHong Zhang network->subnet[i].vertices[vfrom] = cone[0]; /* user's subnet[].dix = petsc's v */ 5212bf73ac6SHong Zhang 5222bf73ac6SHong Zhang /* vertex cone[1] */ 5232bf73ac6SHong Zhang vto = network->subnet[i].edgelist[2*v+1]; 5242bf73ac6SHong Zhang network->header[cone[1]].index = vidxlTog[cone[1]-vStart]; /* Global vertex index */ 5252bf73ac6SHong Zhang network->header[cone[1]].subnetid = i; 5262bf73ac6SHong Zhang network->subnet[i].vertices[vto]= cone[1]; 5272bf73ac6SHong Zhang 5282bf73ac6SHong Zhang e++; v++; 5292bf73ac6SHong Zhang } 5302bf73ac6SHong Zhang } 5312bf73ac6SHong Zhang 5322bf73ac6SHong Zhang /* Set vertex array for the subnetworks */ 5332bf73ac6SHong Zhang k = 0; 5342bf73ac6SHong Zhang for (v=vStart; v<network->vEnd; v++) { /* local vertices, including ghosts */ 5352bf73ac6SHong Zhang network->header[v].ndata = 0; 5362bf73ac6SHong Zhang network->header[v].offset[0] = 0; 5372bf73ac6SHong Zhang network->header[v].offsetvarrel[0] = 0; 5382bf73ac6SHong Zhang ierr = PetscSectionAddDof(network->DataSection,v,network->dataheadersize);CHKERRQ(ierr); 5392bf73ac6SHong Zhang 5402bf73ac6SHong Zhang /* shared vertex */ 5412bf73ac6SHong Zhang ierr = PetscTableFind(network->svtable,vidxlTog[v-vStart]+1,&i);CHKERRQ(ierr); 5422bf73ac6SHong Zhang if (i) network->svertices[k++] = v; 5432bf73ac6SHong Zhang } 5442bf73ac6SHong Zhang #if defined(PETSC_USE_DEBUG) 5452bf73ac6SHong Zhang if (k != network->nsvtx) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"k %D != %D nsvtx",k,network->nsvtx); 5462bf73ac6SHong Zhang #endif 5472bf73ac6SHong Zhang 5482bf73ac6SHong Zhang ierr = PetscFree2(vidxlTog,eowners);CHKERRQ(ierr); 5492bf73ac6SHong Zhang 5502bf73ac6SHong Zhang network->svtx = svtx; 5512bf73ac6SHong Zhang network->Nsvtx = Nsv; 5522bf73ac6SHong Zhang ierr = PetscFree(sedgelist);CHKERRQ(ierr); 5532bf73ac6SHong Zhang 5542bf73ac6SHong Zhang /* Create a global section to be used by DMNetworkIsGhostVertex() which is a non-collective routine */ 5552bf73ac6SHong Zhang ierr = DMGetGlobalSection(network->plex,§iong);CHKERRQ(ierr); 5565f2c45f1SShri Abhyankar PetscFunctionReturn(0); 5575f2c45f1SShri Abhyankar } 5585f2c45f1SShri Abhyankar 5595f2c45f1SShri Abhyankar /*@ 5605f2c45f1SShri Abhyankar DMNetworkLayoutSetUp - Sets up the bare layout (graph) for the network 5615f2c45f1SShri Abhyankar 562d083f849SBarry Smith Collective on dm 5635f2c45f1SShri Abhyankar 5647a7aea1fSJed Brown Input Parameters: 5655f2c45f1SShri Abhyankar . DM - the dmnetwork object 5665f2c45f1SShri Abhyankar 5675f2c45f1SShri Abhyankar Notes: 5685f2c45f1SShri Abhyankar This routine should be called after the network sizes and edgelists have been provided. It creates 5695f2c45f1SShri Abhyankar the bare layout of the network and sets up the network to begin insertion of components. 5705f2c45f1SShri Abhyankar 5715f2c45f1SShri Abhyankar All the components should be registered before calling this routine. 5725f2c45f1SShri Abhyankar 57397bb938eSShri Abhyankar Level: beginner 5745f2c45f1SShri Abhyankar 5752bf73ac6SHong Zhang .seealso: DMNetworkSetNumSubNetworks(), DMNetworkAddSubnetwork() 5765f2c45f1SShri Abhyankar @*/ 5775f2c45f1SShri Abhyankar PetscErrorCode DMNetworkLayoutSetUp(DM dm) 5785f2c45f1SShri Abhyankar { 5795f2c45f1SShri Abhyankar PetscErrorCode ierr; 5805f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 5812bf73ac6SHong Zhang PetscInt i,j,ctr,Nsubnet=network->Nsubnet,*eowners,np,*edges,*subnetvtx; 5822bf73ac6SHong Zhang PetscInt e,v,vfrom,vto; 583caf410d2SHong Zhang const PetscInt *cone; 584caf410d2SHong Zhang MPI_Comm comm; 585caf410d2SHong Zhang PetscMPIInt size,rank; 5866500d4abSHong Zhang 5876500d4abSHong Zhang PetscFunctionBegin; 5882bf73ac6SHong Zhang if (network->nsubnet != network->Nsubnet) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Must call DMNetworkAddSubnetwork() %D times",network->Nsubnet); 5892bf73ac6SHong Zhang 5902bf73ac6SHong Zhang /* Create svtable for querry shared vertices */ 5912bf73ac6SHong Zhang ierr = PetscTableCreate(network->Nsvtx,network->NVertices+1,&network->svtable);CHKERRQ(ierr); 5922bf73ac6SHong Zhang 5932bf73ac6SHong Zhang if (network->Nsvtx) { 5942bf73ac6SHong Zhang ierr = DMNetworkLayoutSetUp_Coupling(dm);CHKERRQ(ierr); 5952bf73ac6SHong Zhang PetscFunctionReturn(0); 5962bf73ac6SHong Zhang } 5972bf73ac6SHong Zhang 598caf410d2SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 599ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 600ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 6016500d4abSHong Zhang 6022bf73ac6SHong Zhang /* Create LOCAL edgelist for the network by concatenating local input edgelists of the subnetworks */ 6038e71b177SVaclav Hapla ierr = PetscCalloc1(2*network->nEdges,&edges);CHKERRQ(ierr); 604caf410d2SHong Zhang ctr = 0; 6052bf73ac6SHong Zhang for (i=0; i < Nsubnet; i++) { 6066500d4abSHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 607ba38b151SHong Zhang edges[2*ctr] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j]; 608ba38b151SHong Zhang edges[2*ctr+1] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j+1]; 6096500d4abSHong Zhang ctr++; 6106500d4abSHong Zhang } 6116500d4abSHong Zhang } 6127765340cSHong Zhang 6132bf73ac6SHong Zhang /* Create network->plex; One dimensional network, numCorners=2 */ 6148e71b177SVaclav Hapla ierr = DMCreate(comm,&network->plex);CHKERRQ(ierr); 6158e71b177SVaclav Hapla ierr = DMSetType(network->plex,DMPLEX);CHKERRQ(ierr); 6162bf73ac6SHong Zhang ierr = DMSetDimension(network->plex,1);CHKERRQ(ierr); 617caf410d2SHong Zhang if (size == 1) { 6182bf73ac6SHong Zhang ierr = DMPlexBuildFromCellList(network->plex,network->nEdges,network->nVertices,2,edges);CHKERRQ(ierr); 619caf410d2SHong Zhang } else { 6202bf73ac6SHong Zhang ierr = DMPlexBuildFromCellListParallel(network->plex,network->nEdges,network->nVertices,PETSC_DECIDE,2,edges,NULL);CHKERRQ(ierr); 621acdb140fSBarry Smith } 6222bf73ac6SHong Zhang ierr = PetscFree(edges);CHKERRQ(ierr); /* local edge list with global idx used by DMPlexBuildFromCellList() */ 6236500d4abSHong Zhang 6246500d4abSHong Zhang ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr); 6256500d4abSHong Zhang ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr); 6266500d4abSHong Zhang ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr); 6276500d4abSHong Zhang 628caf410d2SHong Zhang ierr = PetscSectionCreate(comm,&network->DataSection);CHKERRQ(ierr); 629caf410d2SHong Zhang ierr = PetscSectionCreate(comm,&network->DofSection);CHKERRQ(ierr); 6306500d4abSHong Zhang ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr); 6316500d4abSHong Zhang ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr); 6326500d4abSHong Zhang 633caf410d2SHong Zhang network->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 634caf410d2SHong Zhang np = network->pEnd - network->pStart; 635caf410d2SHong Zhang ierr = PetscCalloc2(np,&network->header,np,&network->cvalue);CHKERRQ(ierr); 636caf410d2SHong Zhang 6372bf73ac6SHong Zhang /* Create edge and vertex arrays for the subnetworks */ 6382bf73ac6SHong Zhang for (j=0; j < network->Nsubnet; j++) { 6396500d4abSHong Zhang ierr = PetscCalloc1(network->subnet[j].nedge,&network->subnet[j].edges);CHKERRQ(ierr); 6406500d4abSHong Zhang } 641caf410d2SHong Zhang 642caf410d2SHong Zhang /* Get edge ownership */ 6432bf73ac6SHong Zhang ierr = PetscMalloc1(size+1,&eowners);CHKERRQ(ierr); 644caf410d2SHong Zhang np = network->eEnd - network->eStart; 645ffc4695bSBarry Smith ierr = MPI_Allgather(&np,1,MPIU_INT,eowners+1,1,MPIU_INT,comm);CHKERRMPI(ierr); 646caf410d2SHong Zhang eowners[0] = 0; 647caf410d2SHong Zhang for (i=2; i<=size; i++) eowners[i] += eowners[i-1]; 648caf410d2SHong Zhang 649caf410d2SHong Zhang /* Set network->subnet[*].vertices on array network->subnetvtx */ 6502bf73ac6SHong Zhang np = 0; 6512bf73ac6SHong Zhang for (j=0; j<network->Nsubnet; j++) { 6522bf73ac6SHong Zhang /* sum up subnet[j].Nvtx instead of subnet[j].nvtx, because a subnet might be owned by more than one processor; 6532bf73ac6SHong Zhang below, subnet[i].vertices[vfrom/vto] requires vfrom/vto =0, ...,Nvtx-1 6542bf73ac6SHong Zhang */ 6552bf73ac6SHong Zhang if (network->subnet[j].nvtx) np += network->subnet[j].Nvtx; 6562bf73ac6SHong Zhang } 6572bf73ac6SHong Zhang 6582bf73ac6SHong Zhang ierr = PetscCalloc1(np,&network->subnetvtx);CHKERRQ(ierr); /* Maps local vertex to local subnetwork's vertex */ 659caf410d2SHong Zhang subnetvtx = network->subnetvtx; 6602bf73ac6SHong Zhang for (j=0; j<network->Nsubnet; j++) { 661caf410d2SHong Zhang network->subnet[j].vertices = subnetvtx; 6622bf73ac6SHong Zhang if (network->subnet[j].nvtx) subnetvtx += network->subnet[j].Nvtx; 663caf410d2SHong Zhang } 664caf410d2SHong Zhang 6652bf73ac6SHong Zhang /* Setup edge and vertex arrays for subnetworks */ 6662bf73ac6SHong Zhang e = 0; 6672bf73ac6SHong Zhang for (i=0; i < Nsubnet; i++) { 6682bf73ac6SHong Zhang v = 0; 6692bf73ac6SHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 6702bf73ac6SHong Zhang /* edge e */ 6712bf73ac6SHong Zhang network->header[e].index = e + eowners[rank]; /* Global edge index */ 6722bf73ac6SHong Zhang network->header[e].subnetid = i; 6732bf73ac6SHong Zhang network->subnet[i].edges[j] = e; 674caf410d2SHong Zhang 6752bf73ac6SHong Zhang network->header[e].ndata = 0; 6762bf73ac6SHong Zhang network->header[e].offset[0] = 0; 6772bf73ac6SHong Zhang network->header[e].offsetvarrel[0] = 0; 6782bf73ac6SHong Zhang ierr = PetscSectionAddDof(network->DataSection,e,network->dataheadersize);CHKERRQ(ierr); 6792bf73ac6SHong Zhang 6802bf73ac6SHong Zhang /* connected vertices */ 6812bf73ac6SHong Zhang ierr = DMPlexGetCone(network->plex,e,&cone);CHKERRQ(ierr); 6822bf73ac6SHong Zhang 6832bf73ac6SHong Zhang /* vertex cone[0] */ 6842bf73ac6SHong Zhang vfrom = network->subnet[i].edgelist[2*v]; /* =subnet[i].idx, Global index! */ 6852bf73ac6SHong Zhang network->header[cone[0]].index = vfrom + network->subnet[i].vStart; /* Global vertex index */ 6862bf73ac6SHong Zhang network->header[cone[0]].subnetid = i; /* Subnetwork id */ 6872bf73ac6SHong Zhang network->subnet[i].vertices[vfrom] = cone[0]; /* user's subnet[].dix = petsc's v */ 6882bf73ac6SHong Zhang 6892bf73ac6SHong Zhang /* vertex cone[1] */ 6902bf73ac6SHong Zhang vto = network->subnet[i].edgelist[2*v+1]; /* =subnet[i].idx, Global index! */ 6912bf73ac6SHong Zhang network->header[cone[1]].index = vto + network->subnet[i].vStart; /* Global vertex index */ 6922bf73ac6SHong Zhang network->header[cone[1]].subnetid = i; 6932bf73ac6SHong Zhang network->subnet[i].vertices[vto] = cone[1]; /* user's subnet[].dix = petsc's v */ 6942bf73ac6SHong Zhang 6952bf73ac6SHong Zhang e++; v++; 6966500d4abSHong Zhang } 6976500d4abSHong Zhang } 6982bf73ac6SHong Zhang ierr = PetscFree(eowners);CHKERRQ(ierr); 699caf410d2SHong Zhang 7002bf73ac6SHong Zhang for (v = network->vStart; v < network->vEnd; v++) { 7012bf73ac6SHong Zhang network->header[v].ndata = 0; 7022bf73ac6SHong Zhang network->header[v].offset[0] = 0; 7032bf73ac6SHong Zhang network->header[v].offsetvarrel[0] = 0; 7042bf73ac6SHong Zhang ierr = PetscSectionAddDof(network->DataSection,v,network->dataheadersize);CHKERRQ(ierr); 7056500d4abSHong Zhang } 7065f2c45f1SShri Abhyankar PetscFunctionReturn(0); 7075f2c45f1SShri Abhyankar } 7085f2c45f1SShri Abhyankar 70994ef8ddeSSatish Balay /*@C 7102bf73ac6SHong Zhang DMNetworkGetSubnetwork - Returns the information about a requested subnetwork 7112bf73ac6SHong Zhang 7122bf73ac6SHong Zhang Not collective 7132727e31bSShri Abhyankar 7147a7aea1fSJed Brown Input Parameters: 715caf410d2SHong Zhang + dm - the DM object 7162bf73ac6SHong Zhang - netnum - the global index of the subnetwork 7172727e31bSShri Abhyankar 7187a7aea1fSJed Brown Output Parameters: 7192727e31bSShri Abhyankar + nv - number of vertices (local) 7202727e31bSShri Abhyankar . ne - number of edges (local) 7212bf73ac6SHong Zhang . vtx - local vertices of the subnetwork 7222bf73ac6SHong Zhang - edge - local edges of the subnetwork 7232727e31bSShri Abhyankar 7242727e31bSShri Abhyankar Notes: 7252727e31bSShri Abhyankar Cannot call this routine before DMNetworkLayoutSetup() 7262727e31bSShri Abhyankar 72706dd6b0eSSatish Balay Level: intermediate 72806dd6b0eSSatish Balay 7292bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkAddSubnetwork(), DMNetworkLayoutSetUp() 7302727e31bSShri Abhyankar @*/ 7312bf73ac6SHong Zhang PetscErrorCode DMNetworkGetSubnetwork(DM dm,PetscInt netnum,PetscInt *nv,PetscInt *ne,const PetscInt **vtx,const PetscInt **edge) 7322727e31bSShri Abhyankar { 733caf410d2SHong Zhang DM_Network *network = (DM_Network*)dm->data; 7342727e31bSShri Abhyankar 7352727e31bSShri Abhyankar PetscFunctionBegin; 7362bf73ac6SHong Zhang if (netnum >= network->Nsubnet) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Subnet index %D exceeds the num of subnets %D",netnum,network->Nsubnet); 7372bf73ac6SHong Zhang if (nv) *nv = network->subnet[netnum].nvtx; 7382bf73ac6SHong Zhang if (ne) *ne = network->subnet[netnum].nedge; 7392bf73ac6SHong Zhang if (vtx) *vtx = network->subnet[netnum].vertices; 7402bf73ac6SHong Zhang if (edge) *edge = network->subnet[netnum].edges; 7412bf73ac6SHong Zhang PetscFunctionReturn(0); 7422bf73ac6SHong Zhang } 7432bf73ac6SHong Zhang 7442bf73ac6SHong Zhang /*@ 7452bf73ac6SHong Zhang DMNetworkAddSharedVertices - Add shared vertices that connect two given subnetworks 7462bf73ac6SHong Zhang 7472bf73ac6SHong Zhang Collective on dm 7482bf73ac6SHong Zhang 7492bf73ac6SHong Zhang Input Parameters: 7502bf73ac6SHong Zhang + dm - the dm object 7512bf73ac6SHong Zhang . anetnum - first subnetwork global numbering returned by DMNetworkAddSubnetwork() 7522bf73ac6SHong Zhang . bnetnum - second subnetwork global numbering returned by DMNetworkAddSubnetwork() 7532bf73ac6SHong Zhang . nsvtx - number of vertices that are shared by the two subnetworks 7542bf73ac6SHong Zhang . asvtx - vertex index in the first subnetwork 7552bf73ac6SHong Zhang - bsvtx - vertex index in the second subnetwork 7562bf73ac6SHong Zhang 7572bf73ac6SHong Zhang Level: beginner 7582bf73ac6SHong Zhang 7592bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkAddSubnetwork(), DMNetworkGetSharedVertices() 7602bf73ac6SHong Zhang @*/ 7612bf73ac6SHong Zhang PetscErrorCode DMNetworkAddSharedVertices(DM dm,PetscInt anetnum,PetscInt bnetnum,PetscInt nsvtx,PetscInt asvtx[],PetscInt bsvtx[]) 7622bf73ac6SHong Zhang { 7632bf73ac6SHong Zhang PetscErrorCode ierr; 7642bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 7652bf73ac6SHong Zhang PetscInt i,nsubnet = network->Nsubnet,*sedgelist,Nsvtx=network->Nsvtx; 7662bf73ac6SHong Zhang 7672bf73ac6SHong Zhang PetscFunctionBegin; 7682bf73ac6SHong Zhang if (anetnum == bnetnum) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Subnetworks must have different netnum"); 7692bf73ac6SHong Zhang if (anetnum < 0 || bnetnum < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"netnum cannot be negative"); 7702bf73ac6SHong Zhang if (!Nsvtx) { 7712bf73ac6SHong Zhang /* allocate network->sedgelist to hold at most 2*nsubnet pairs of shared vertices */ 7722bf73ac6SHong Zhang ierr = PetscMalloc1(2*4*nsubnet,&network->sedgelist);CHKERRQ(ierr); 7732bf73ac6SHong Zhang } 7742bf73ac6SHong Zhang 7752bf73ac6SHong Zhang sedgelist = network->sedgelist; 7762bf73ac6SHong Zhang for (i=0; i<nsvtx; i++) { 7772bf73ac6SHong Zhang sedgelist[4*Nsvtx] = anetnum; sedgelist[4*Nsvtx+1] = asvtx[i]; 7782bf73ac6SHong Zhang sedgelist[4*Nsvtx+2] = bnetnum; sedgelist[4*Nsvtx+3] = bsvtx[i]; 7792bf73ac6SHong Zhang Nsvtx++; 7802bf73ac6SHong Zhang } 7812bf73ac6SHong Zhang if (Nsvtx > 2*nsubnet) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"allocate more space for coupling edgelist"); 7822bf73ac6SHong Zhang network->Nsvtx = Nsvtx; 7832727e31bSShri Abhyankar PetscFunctionReturn(0); 7842727e31bSShri Abhyankar } 7852727e31bSShri Abhyankar 7862727e31bSShri Abhyankar /*@C 7872bf73ac6SHong Zhang DMNetworkGetSharedVertices - Returns the info for the shared vertices 7882bf73ac6SHong Zhang 7892bf73ac6SHong Zhang Not collective 790caf410d2SHong Zhang 7917a7aea1fSJed Brown Input Parameters: 7922bf73ac6SHong Zhang . dm - the DM object 793caf410d2SHong Zhang 7947a7aea1fSJed Brown Output Parameters: 7952bf73ac6SHong Zhang + nsv - number of local shared vertices 7962bf73ac6SHong Zhang - svtx - local shared vertices 797caf410d2SHong Zhang 798caf410d2SHong Zhang Notes: 799caf410d2SHong Zhang Cannot call this routine before DMNetworkLayoutSetup() 800caf410d2SHong Zhang 801caf410d2SHong Zhang Level: intermediate 802caf410d2SHong Zhang 8032bf73ac6SHong Zhang .seealso: DMNetworkGetSubnetwork(), DMNetworkLayoutSetUp(), DMNetworkAddSharedVertices() 804caf410d2SHong Zhang @*/ 8052bf73ac6SHong Zhang PetscErrorCode DMNetworkGetSharedVertices(DM dm,PetscInt *nsv,const PetscInt **svtx) 806caf410d2SHong Zhang { 807caf410d2SHong Zhang DM_Network *net = (DM_Network*)dm->data; 808caf410d2SHong Zhang 809caf410d2SHong Zhang PetscFunctionBegin; 8102bf73ac6SHong Zhang if (net->Nsvtx) { 8112bf73ac6SHong Zhang *nsv = net->nsvtx; 8122bf73ac6SHong Zhang *svtx = net->svertices; 81372c3e9f7SHong Zhang } else { 8142bf73ac6SHong Zhang *nsv = 0; 8152bf73ac6SHong Zhang *svtx = NULL; 81672c3e9f7SHong Zhang } 817caf410d2SHong Zhang PetscFunctionReturn(0); 818caf410d2SHong Zhang } 819caf410d2SHong Zhang 820caf410d2SHong Zhang /*@C 8215f2c45f1SShri Abhyankar DMNetworkRegisterComponent - Registers the network component 8225f2c45f1SShri Abhyankar 823d083f849SBarry Smith Logically collective on dm 8245f2c45f1SShri Abhyankar 8257a7aea1fSJed Brown Input Parameters: 8265f2c45f1SShri Abhyankar + dm - the network object 8275f2c45f1SShri Abhyankar . name - the component name 8285f2c45f1SShri Abhyankar - size - the storage size in bytes for this component data 8295f2c45f1SShri Abhyankar 8307a7aea1fSJed Brown Output Parameters: 8315f2c45f1SShri Abhyankar . key - an integer key that defines the component 8325f2c45f1SShri Abhyankar 8335f2c45f1SShri Abhyankar Notes 8345f2c45f1SShri Abhyankar This routine should be called by all processors before calling DMNetworkLayoutSetup(). 8355f2c45f1SShri Abhyankar 83697bb938eSShri Abhyankar Level: beginner 8375f2c45f1SShri Abhyankar 8382bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkLayoutSetUp() 8395f2c45f1SShri Abhyankar @*/ 840caf410d2SHong Zhang PetscErrorCode DMNetworkRegisterComponent(DM dm,const char *name,size_t size,PetscInt *key) 8415f2c45f1SShri Abhyankar { 8425f2c45f1SShri Abhyankar PetscErrorCode ierr; 8435f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 8445f2c45f1SShri Abhyankar DMNetworkComponent *component=&network->component[network->ncomponent]; 8455f2c45f1SShri Abhyankar PetscBool flg=PETSC_FALSE; 8465f2c45f1SShri Abhyankar PetscInt i; 8475f2c45f1SShri Abhyankar 8485f2c45f1SShri Abhyankar PetscFunctionBegin; 8495f2c45f1SShri Abhyankar for (i=0; i < network->ncomponent; i++) { 8505f2c45f1SShri Abhyankar ierr = PetscStrcmp(component->name,name,&flg);CHKERRQ(ierr); 8515f2c45f1SShri Abhyankar if (flg) { 8525f2c45f1SShri Abhyankar *key = i; 8535f2c45f1SShri Abhyankar PetscFunctionReturn(0); 8545f2c45f1SShri Abhyankar } 8556d64e262SShri Abhyankar } 856a9b4a83eSHong Zhang if (network->ncomponent == MAX_NETCOMPONENTS) { 857a9b4a83eSHong Zhang SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Number of components registered exceeds the max %D",MAX_NETCOMPONENTS); 8585f2c45f1SShri Abhyankar } 8595f2c45f1SShri Abhyankar 8605f2c45f1SShri Abhyankar ierr = PetscStrcpy(component->name,name);CHKERRQ(ierr); 8615f2c45f1SShri Abhyankar component->size = size/sizeof(DMNetworkComponentGenericDataType); 8625f2c45f1SShri Abhyankar *key = network->ncomponent; 8635f2c45f1SShri Abhyankar network->ncomponent++; 8645f2c45f1SShri Abhyankar PetscFunctionReturn(0); 8655f2c45f1SShri Abhyankar } 8665f2c45f1SShri Abhyankar 8675f2c45f1SShri Abhyankar /*@ 8682bf73ac6SHong Zhang DMNetworkGetVertexRange - Get the bounds [start, end) for the local vertices 8695f2c45f1SShri Abhyankar 8705f2c45f1SShri Abhyankar Not Collective 8715f2c45f1SShri Abhyankar 8725f2c45f1SShri Abhyankar Input Parameters: 8732bf73ac6SHong Zhang . dm - the DMNetwork object 8745f2c45f1SShri Abhyankar 875fd292e60Sprj- Output Parameters: 8762bf73ac6SHong Zhang + vStart - the first vertex point 8772bf73ac6SHong Zhang - vEnd - one beyond the last vertex point 8785f2c45f1SShri Abhyankar 87997bb938eSShri Abhyankar Level: beginner 8805f2c45f1SShri Abhyankar 8812bf73ac6SHong Zhang .seealso: DMNetworkGetEdgeRange() 8825f2c45f1SShri Abhyankar @*/ 8835f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVertexRange(DM dm,PetscInt *vStart,PetscInt *vEnd) 8845f2c45f1SShri Abhyankar { 8855f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 8865f2c45f1SShri Abhyankar 8875f2c45f1SShri Abhyankar PetscFunctionBegin; 8885f2c45f1SShri Abhyankar if (vStart) *vStart = network->vStart; 8895f2c45f1SShri Abhyankar if (vEnd) *vEnd = network->vEnd; 8905f2c45f1SShri Abhyankar PetscFunctionReturn(0); 8915f2c45f1SShri Abhyankar } 8925f2c45f1SShri Abhyankar 8935f2c45f1SShri Abhyankar /*@ 8942bf73ac6SHong Zhang DMNetworkGetEdgeRange - Get the bounds [start, end) for the local edges 8955f2c45f1SShri Abhyankar 8965f2c45f1SShri Abhyankar Not Collective 8975f2c45f1SShri Abhyankar 8985f2c45f1SShri Abhyankar Input Parameters: 8992bf73ac6SHong Zhang . dm - the DMNetwork object 9005f2c45f1SShri Abhyankar 901fd292e60Sprj- Output Parameters: 9025f2c45f1SShri Abhyankar + eStart - The first edge point 9035f2c45f1SShri Abhyankar - eEnd - One beyond the last edge point 9045f2c45f1SShri Abhyankar 90597bb938eSShri Abhyankar Level: beginner 9065f2c45f1SShri Abhyankar 9072bf73ac6SHong Zhang .seealso: DMNetworkGetVertexRange() 9085f2c45f1SShri Abhyankar @*/ 9095f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetEdgeRange(DM dm,PetscInt *eStart,PetscInt *eEnd) 9105f2c45f1SShri Abhyankar { 9115f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 9125f2c45f1SShri Abhyankar 9135f2c45f1SShri Abhyankar PetscFunctionBegin; 9145f2c45f1SShri Abhyankar if (eStart) *eStart = network->eStart; 9155f2c45f1SShri Abhyankar if (eEnd) *eEnd = network->eEnd; 9165f2c45f1SShri Abhyankar PetscFunctionReturn(0); 9175f2c45f1SShri Abhyankar } 9185f2c45f1SShri Abhyankar 9192bf73ac6SHong Zhang static PetscErrorCode DMNetworkGetIndex(DM dm,PetscInt p,PetscInt *index) 9202bf73ac6SHong Zhang { 9212bf73ac6SHong Zhang PetscErrorCode ierr; 9222bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 9232bf73ac6SHong Zhang PetscInt offsetp; 9242bf73ac6SHong Zhang DMNetworkComponentHeader header; 9252bf73ac6SHong Zhang 9262bf73ac6SHong Zhang PetscFunctionBegin; 9272bf73ac6SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 9282bf73ac6SHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 9292bf73ac6SHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 9302bf73ac6SHong Zhang *index = header->index; 9312bf73ac6SHong Zhang PetscFunctionReturn(0); 9322bf73ac6SHong Zhang } 9332bf73ac6SHong Zhang 9347b6afd5bSHong Zhang /*@ 9352bf73ac6SHong Zhang DMNetworkGetGlobalEdgeIndex - Get the global numbering for the edge on the network 9367b6afd5bSHong Zhang 9377b6afd5bSHong Zhang Not Collective 9387b6afd5bSHong Zhang 9397b6afd5bSHong Zhang Input Parameters: 9407b6afd5bSHong Zhang + dm - DMNetwork object 941e85e6aecSHong Zhang - p - edge point 9427b6afd5bSHong Zhang 943fd292e60Sprj- Output Parameters: 9442bf73ac6SHong Zhang . index - the global numbering for the edge 9457b6afd5bSHong Zhang 9467b6afd5bSHong Zhang Level: intermediate 9477b6afd5bSHong Zhang 9482bf73ac6SHong Zhang .seealso: DMNetworkGetGlobalVertexIndex() 9497b6afd5bSHong Zhang @*/ 950e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalEdgeIndex(DM dm,PetscInt p,PetscInt *index) 9517b6afd5bSHong Zhang { 9527b6afd5bSHong Zhang PetscErrorCode ierr; 9537b6afd5bSHong Zhang 9547b6afd5bSHong Zhang PetscFunctionBegin; 9552bf73ac6SHong Zhang ierr = DMNetworkGetIndex(dm,p,index);CHKERRQ(ierr); 9567b6afd5bSHong Zhang PetscFunctionReturn(0); 9577b6afd5bSHong Zhang } 9587b6afd5bSHong Zhang 9595f2c45f1SShri Abhyankar /*@ 9602bf73ac6SHong Zhang DMNetworkGetGlobalVertexIndex - Get the global numbering for the vertex on the network 961e85e6aecSHong Zhang 962e85e6aecSHong Zhang Not Collective 963e85e6aecSHong Zhang 964e85e6aecSHong Zhang Input Parameters: 965e85e6aecSHong Zhang + dm - DMNetwork object 966e85e6aecSHong Zhang - p - vertex point 967e85e6aecSHong Zhang 968fd292e60Sprj- Output Parameters: 9692bf73ac6SHong Zhang . index - the global numbering for the vertex 970e85e6aecSHong Zhang 971e85e6aecSHong Zhang Level: intermediate 972e85e6aecSHong Zhang 9732bf73ac6SHong Zhang .seealso: DMNetworkGetGlobalEdgeIndex() 974e85e6aecSHong Zhang @*/ 975e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalVertexIndex(DM dm,PetscInt p,PetscInt *index) 976e85e6aecSHong Zhang { 977e85e6aecSHong Zhang PetscErrorCode ierr; 978e85e6aecSHong Zhang 979e85e6aecSHong Zhang PetscFunctionBegin; 9802bf73ac6SHong Zhang ierr = DMNetworkGetIndex(dm,p,index);CHKERRQ(ierr); 9819988b915SShri Abhyankar PetscFunctionReturn(0); 9829988b915SShri Abhyankar } 9839988b915SShri Abhyankar 9849988b915SShri Abhyankar /*@ 9855f2c45f1SShri Abhyankar DMNetworkGetNumComponents - Get the number of components at a vertex/edge 9865f2c45f1SShri Abhyankar 9875f2c45f1SShri Abhyankar Not Collective 9885f2c45f1SShri Abhyankar 9895f2c45f1SShri Abhyankar Input Parameters: 9902bf73ac6SHong Zhang + dm - the DMNetwork object 991a2b725a8SWilliam Gropp - p - vertex/edge point 9925f2c45f1SShri Abhyankar 9935f2c45f1SShri Abhyankar Output Parameters: 9945f2c45f1SShri Abhyankar . numcomponents - Number of components at the vertex/edge 9955f2c45f1SShri Abhyankar 99697bb938eSShri Abhyankar Level: beginner 9975f2c45f1SShri Abhyankar 9982bf73ac6SHong Zhang .seealso: DMNetworkRegisterComponent(), DMNetworkAddComponent() 9995f2c45f1SShri Abhyankar @*/ 10005f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetNumComponents(DM dm,PetscInt p,PetscInt *numcomponents) 10015f2c45f1SShri Abhyankar { 10025f2c45f1SShri Abhyankar PetscErrorCode ierr; 10035f2c45f1SShri Abhyankar PetscInt offset; 10045f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10055f2c45f1SShri Abhyankar 10065f2c45f1SShri Abhyankar PetscFunctionBegin; 10075f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 10085f2c45f1SShri Abhyankar *numcomponents = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 10095f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10105f2c45f1SShri Abhyankar } 10115f2c45f1SShri Abhyankar 10125f2c45f1SShri Abhyankar /*@ 10132bf73ac6SHong Zhang DMNetworkGetLocalVecOffset - Get the offset for accessing the variables associated with a component at the given vertex/edge from the local vector 10145f2c45f1SShri Abhyankar 10155f2c45f1SShri Abhyankar Not Collective 10165f2c45f1SShri Abhyankar 10175f2c45f1SShri Abhyankar Input Parameters: 10182bf73ac6SHong Zhang + dm - the DMNetwork object 10197d928bffSSatish Balay . p - the edge/vertex point 10202bf73ac6SHong Zhang - compnum - component number; use ALL_COMPONENTS if no specific component is requested 10219988b915SShri Abhyankar 10229988b915SShri Abhyankar Output Parameters: 10232bf73ac6SHong Zhang . offset - the local offset 10249988b915SShri Abhyankar 10259988b915SShri Abhyankar Level: intermediate 10269988b915SShri Abhyankar 10272bf73ac6SHong Zhang .seealso: DMGetLocalVector(), DMNetworkGetComponent(), DMNetworkGetGlobalVecOffset() 10289988b915SShri Abhyankar @*/ 10292bf73ac6SHong Zhang PetscErrorCode DMNetworkGetLocalVecOffset(DM dm,PetscInt p,PetscInt compnum,PetscInt *offset) 10309988b915SShri Abhyankar { 10319988b915SShri Abhyankar PetscErrorCode ierr; 10329988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10339988b915SShri Abhyankar PetscInt offsetp,offsetd; 10349988b915SShri Abhyankar DMNetworkComponentHeader header; 10359988b915SShri Abhyankar 10369988b915SShri Abhyankar PetscFunctionBegin; 10372bf73ac6SHong Zhang ierr = PetscSectionGetOffset(network->plex->localSection,p,&offsetp);CHKERRQ(ierr); 10382bf73ac6SHong Zhang if (compnum == ALL_COMPONENTS) { 10392bf73ac6SHong Zhang *offset = offsetp; 10402bf73ac6SHong Zhang PetscFunctionReturn(0); 10412bf73ac6SHong Zhang } 10422bf73ac6SHong Zhang 10439988b915SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetd);CHKERRQ(ierr); 10449988b915SShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetd); 10459988b915SShri Abhyankar *offset = offsetp + header->offsetvarrel[compnum]; 10469988b915SShri Abhyankar PetscFunctionReturn(0); 10479988b915SShri Abhyankar } 10489988b915SShri Abhyankar 10499988b915SShri Abhyankar /*@ 10502bf73ac6SHong Zhang DMNetworkGetGlobalVecOffset - Get the global offset for accessing the variables associated with a component for the given vertex/edge from the global vector 10519988b915SShri Abhyankar 10529988b915SShri Abhyankar Not Collective 10539988b915SShri Abhyankar 10549988b915SShri Abhyankar Input Parameters: 10552bf73ac6SHong Zhang + dm - the DMNetwork object 10567d928bffSSatish Balay . p - the edge/vertex point 10572bf73ac6SHong Zhang - compnum - component number; use ALL_COMPONENTS if no specific component is requested 10589988b915SShri Abhyankar 10599988b915SShri Abhyankar Output Parameters: 10609988b915SShri Abhyankar . offsetg - the global offset 10619988b915SShri Abhyankar 10629988b915SShri Abhyankar Level: intermediate 10639988b915SShri Abhyankar 10642bf73ac6SHong Zhang .seealso: DMNetworkGetLocalVecOffset(), DMGetGlobalVector(), DMNetworkGetComponent() 10659988b915SShri Abhyankar @*/ 10662bf73ac6SHong Zhang PetscErrorCode DMNetworkGetGlobalVecOffset(DM dm,PetscInt p,PetscInt compnum,PetscInt *offsetg) 10679988b915SShri Abhyankar { 10689988b915SShri Abhyankar PetscErrorCode ierr; 10699988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10709988b915SShri Abhyankar PetscInt offsetp,offsetd; 10719988b915SShri Abhyankar DMNetworkComponentHeader header; 10729988b915SShri Abhyankar 10739988b915SShri Abhyankar PetscFunctionBegin; 10742bf73ac6SHong Zhang ierr = PetscSectionGetOffset(network->plex->globalSection,p,&offsetp);CHKERRQ(ierr); 10752bf73ac6SHong Zhang if (offsetp < 0) offsetp = -(offsetp + 1); /* Convert to actual global offset for ghost vertex */ 10762bf73ac6SHong Zhang 10772bf73ac6SHong Zhang if (compnum == ALL_COMPONENTS) { 10782bf73ac6SHong Zhang *offsetg = offsetp; 10792bf73ac6SHong Zhang PetscFunctionReturn(0); 10802bf73ac6SHong Zhang } 10819988b915SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetd);CHKERRQ(ierr); 10829988b915SShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetd); 10839988b915SShri Abhyankar *offsetg = offsetp + header->offsetvarrel[compnum]; 10849988b915SShri Abhyankar PetscFunctionReturn(0); 10859988b915SShri Abhyankar } 10869988b915SShri Abhyankar 10879988b915SShri Abhyankar /*@ 10882bf73ac6SHong Zhang DMNetworkGetEdgeOffset - Get the offset for accessing the variables associated with the given edge from the local subvector 108924121865SAdrian Maldonado 109024121865SAdrian Maldonado Not Collective 109124121865SAdrian Maldonado 109224121865SAdrian Maldonado Input Parameters: 10932bf73ac6SHong Zhang + dm - the DMNetwork object 109424121865SAdrian Maldonado - p - the edge point 109524121865SAdrian Maldonado 109624121865SAdrian Maldonado Output Parameters: 109724121865SAdrian Maldonado . offset - the offset 109824121865SAdrian Maldonado 109924121865SAdrian Maldonado Level: intermediate 110024121865SAdrian Maldonado 11012bf73ac6SHong Zhang .seealso: DMNetworkGetLocalVecOffset(), DMGetLocalVector() 110224121865SAdrian Maldonado @*/ 110324121865SAdrian Maldonado PetscErrorCode DMNetworkGetEdgeOffset(DM dm,PetscInt p,PetscInt *offset) 110424121865SAdrian Maldonado { 110524121865SAdrian Maldonado PetscErrorCode ierr; 110624121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 110724121865SAdrian Maldonado 110824121865SAdrian Maldonado PetscFunctionBegin; 110924121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->edge.DofSection,p,offset);CHKERRQ(ierr); 111024121865SAdrian Maldonado PetscFunctionReturn(0); 111124121865SAdrian Maldonado } 111224121865SAdrian Maldonado 111324121865SAdrian Maldonado /*@ 11142bf73ac6SHong Zhang DMNetworkGetVertexOffset - Get the offset for accessing the variables associated with the given vertex from the local subvector 111524121865SAdrian Maldonado 111624121865SAdrian Maldonado Not Collective 111724121865SAdrian Maldonado 111824121865SAdrian Maldonado Input Parameters: 11192bf73ac6SHong Zhang + dm - the DMNetwork object 112024121865SAdrian Maldonado - p - the vertex point 112124121865SAdrian Maldonado 112224121865SAdrian Maldonado Output Parameters: 112324121865SAdrian Maldonado . offset - the offset 112424121865SAdrian Maldonado 112524121865SAdrian Maldonado Level: intermediate 112624121865SAdrian Maldonado 11272bf73ac6SHong Zhang .seealso: DMNetworkGetEdgeOffset(), DMGetLocalVector() 112824121865SAdrian Maldonado @*/ 112924121865SAdrian Maldonado PetscErrorCode DMNetworkGetVertexOffset(DM dm,PetscInt p,PetscInt *offset) 113024121865SAdrian Maldonado { 113124121865SAdrian Maldonado PetscErrorCode ierr; 113224121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 113324121865SAdrian Maldonado 113424121865SAdrian Maldonado PetscFunctionBegin; 113524121865SAdrian Maldonado p -= network->vStart; 113624121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->vertex.DofSection,p,offset);CHKERRQ(ierr); 113724121865SAdrian Maldonado PetscFunctionReturn(0); 113824121865SAdrian Maldonado } 11392bf73ac6SHong Zhang 11405f2c45f1SShri Abhyankar /*@ 11412bf73ac6SHong Zhang DMNetworkAddComponent - Adds a network component and number of variables at the given point (vertex/edge) 11425f2c45f1SShri Abhyankar 11435f2c45f1SShri Abhyankar Not Collective 11445f2c45f1SShri Abhyankar 11455f2c45f1SShri Abhyankar Input Parameters: 11462bf73ac6SHong Zhang + dm - the DMNetworkObject 11475f2c45f1SShri Abhyankar . p - the vertex/edge point 11482bf73ac6SHong Zhang . componentkey - component key returned while registering the component; ignored if compvalue=NULL 11492bf73ac6SHong Zhang . compvalue - pointer to the data structure for the component, or NULL if not required. 11502bf73ac6SHong Zhang - nvar - number of variables for the component at the vertex/edge point 11515f2c45f1SShri Abhyankar 115297bb938eSShri Abhyankar Level: beginner 11535f2c45f1SShri Abhyankar 11542bf73ac6SHong Zhang .seealso: DMNetworkGetComponent() 11555f2c45f1SShri Abhyankar @*/ 11562bf73ac6SHong Zhang PetscErrorCode DMNetworkAddComponent(DM dm,PetscInt p,PetscInt componentkey,void* compvalue,PetscInt nvar) 11575f2c45f1SShri Abhyankar { 11585f2c45f1SShri Abhyankar PetscErrorCode ierr; 11595f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 11602bf73ac6SHong Zhang DMNetworkComponent *component = &network->component[componentkey]; 11612bf73ac6SHong Zhang DMNetworkComponentHeader header = &network->header[p]; 11622bf73ac6SHong Zhang DMNetworkComponentValue cvalue = &network->cvalue[p]; 11632bf73ac6SHong Zhang PetscBool sharedv=PETSC_FALSE; 11642bf73ac6SHong Zhang PetscInt compnum=header->ndata; 11655f2c45f1SShri Abhyankar 11665f2c45f1SShri Abhyankar PetscFunctionBegin; 11675f2c45f1SShri Abhyankar ierr = PetscSectionAddDof(network->DofSection,p,nvar);CHKERRQ(ierr); 11682bf73ac6SHong Zhang if (!compvalue) PetscFunctionReturn(0); 11692bf73ac6SHong Zhang 11702bf73ac6SHong Zhang ierr = DMNetworkIsSharedVertex(dm,p,&sharedv);CHKERRQ(ierr); 11712bf73ac6SHong Zhang if (sharedv) { 11722bf73ac6SHong Zhang PetscBool ghost; 11732bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 11742bf73ac6SHong Zhang if (ghost) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Adding a component at a leaf(ghost) shared vertex is not supported"); 11752bf73ac6SHong Zhang } 11762bf73ac6SHong Zhang 1177a9b4a83eSHong Zhang if (compnum == MAX_NETCOMPONENTS) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Number of components at a point exceeds the max %D",MAX_NETCOMPONENTS); 11782bf73ac6SHong Zhang 11792bf73ac6SHong Zhang header->size[compnum] = component->size; 11802bf73ac6SHong Zhang ierr = PetscSectionAddDof(network->DataSection,p,component->size);CHKERRQ(ierr); 11812bf73ac6SHong Zhang header->key[compnum] = componentkey; 11822bf73ac6SHong Zhang if (compnum != 0) header->offset[compnum] = header->offset[compnum-1] + header->size[compnum-1]; 11832bf73ac6SHong Zhang cvalue->data[compnum] = (void*)compvalue; 11842bf73ac6SHong Zhang 11852bf73ac6SHong Zhang /* variables */ 11862bf73ac6SHong Zhang header->nvar[compnum] += nvar; 11872bf73ac6SHong Zhang if (compnum != 0) header->offsetvarrel[compnum] = header->offsetvarrel[compnum-1] + header->nvar[compnum-1]; 11882bf73ac6SHong Zhang 11892bf73ac6SHong Zhang header->ndata++; 11905f2c45f1SShri Abhyankar PetscFunctionReturn(0); 11915f2c45f1SShri Abhyankar } 11925f2c45f1SShri Abhyankar 119327f51fceSHong Zhang /*@ 11942bf73ac6SHong Zhang DMNetworkGetComponent - Gets the component key, the component data, and the number of variables at a given network point 119527f51fceSHong Zhang 119627f51fceSHong Zhang Not Collective 119727f51fceSHong Zhang 119827f51fceSHong Zhang Input Parameters: 11992bf73ac6SHong Zhang + dm - the DMNetwork object 12002bf73ac6SHong Zhang . p - vertex/edge point 1201*99c90e12SSatish Balay - compnum - component number; use ALL_COMPONENTS if sum up all the components 120227f51fceSHong Zhang 120327f51fceSHong Zhang Output Parameters: 12042bf73ac6SHong Zhang + compkey - the key obtained when registering the component (use NULL if not required) 12052bf73ac6SHong Zhang . component - the component data (use NULL if not required) 12062bf73ac6SHong Zhang - nvar - number of variables (use NULL if not required) 120727f51fceSHong Zhang 120897bb938eSShri Abhyankar Level: beginner 120927f51fceSHong Zhang 12102bf73ac6SHong Zhang .seealso: DMNetworkAddComponent(), DMNetworkGetNumComponents() 121127f51fceSHong Zhang @*/ 12122bf73ac6SHong Zhang PetscErrorCode DMNetworkGetComponent(DM dm,PetscInt p,PetscInt compnum,PetscInt *compkey,void **component,PetscInt *nvar) 121327f51fceSHong Zhang { 121427f51fceSHong Zhang PetscErrorCode ierr; 121527f51fceSHong Zhang DM_Network *network = (DM_Network*)dm->data; 12162bf73ac6SHong Zhang PetscInt offset = 0; 12172bf73ac6SHong Zhang DMNetworkComponentHeader header; 121827f51fceSHong Zhang 121927f51fceSHong Zhang PetscFunctionBegin; 12202bf73ac6SHong Zhang if (compnum == ALL_COMPONENTS) { 122127f51fceSHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 122227f51fceSHong Zhang PetscFunctionReturn(0); 122327f51fceSHong Zhang } 122427f51fceSHong Zhang 12252bf73ac6SHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 12262bf73ac6SHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offset);CHKERRQ(ierr); 12275f2c45f1SShri Abhyankar 12282bf73ac6SHong Zhang if (compnum >= 0) { 12292bf73ac6SHong Zhang if (compkey) *compkey = header->key[compnum]; 12302bf73ac6SHong Zhang if (component) { 12312bf73ac6SHong Zhang offset += network->dataheadersize+header->offset[compnum]; 12322bf73ac6SHong Zhang *component = network->componentdataarray+offset; 12332bf73ac6SHong Zhang } 12342bf73ac6SHong Zhang } 12355f2c45f1SShri Abhyankar 12362bf73ac6SHong Zhang if (nvar) *nvar = header->nvar[compnum]; 12375f2c45f1SShri Abhyankar PetscFunctionReturn(0); 12385f2c45f1SShri Abhyankar } 12395f2c45f1SShri Abhyankar 12402bf73ac6SHong Zhang /* 12412bf73ac6SHong Zhang Sets up the array that holds the data for all components and its associated section. 12422bf73ac6SHong Zhang It copies the data for all components in a contiguous array called componentdataarray. The component data is stored pointwise with an additional header (metadata) stored for each point. The header has metadata information such as number of components at each point, number of variables for each component, offsets for the components data, etc. 12432bf73ac6SHong Zhang */ 12445f2c45f1SShri Abhyankar PetscErrorCode DMNetworkComponentSetUp(DM dm) 12455f2c45f1SShri Abhyankar { 12465f2c45f1SShri Abhyankar PetscErrorCode ierr; 12475f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 1248e53b5ba3SHong Zhang PetscInt arr_size,p,offset,offsetp,ncomp,i; 12492bf73ac6SHong Zhang MPI_Comm comm; 12502bf73ac6SHong Zhang PetscMPIInt size,rank; 12515f2c45f1SShri Abhyankar DMNetworkComponentHeader header; 12525f2c45f1SShri Abhyankar DMNetworkComponentValue cvalue; 12535f2c45f1SShri Abhyankar DMNetworkComponentGenericDataType *componentdataarray; 12545f2c45f1SShri Abhyankar 12555f2c45f1SShri Abhyankar PetscFunctionBegin; 12562bf73ac6SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 12572bf73ac6SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 12582bf73ac6SHong Zhang ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 12592bf73ac6SHong Zhang #if 0 12602bf73ac6SHong Zhang //------------- new 12612bf73ac6SHong Zhang if (size > 1) { /* Sync nvar at shared vertices for all processes */ 12622bf73ac6SHong Zhang PetscSF sf = network->plex->sf; 12632bf73ac6SHong Zhang const PetscInt *degree; 12642bf73ac6SHong Zhang PetscInt i,nleaves_total,*indata,*outdata,nroots,nleaves,nsv,p,ncomp; 12652bf73ac6SHong Zhang const PetscInt *svtx; 12662bf73ac6SHong Zhang PetscBool ghost; 12672bf73ac6SHong Zhang 12682bf73ac6SHong Zhang ierr = PetscSFGetGraph(sf,&nroots,&nleaves,NULL,NULL);CHKERRQ(ierr); 12692bf73ac6SHong Zhang ierr = PetscSFComputeDegreeBegin(sf,°ree);CHKERRQ(ierr); 12702bf73ac6SHong Zhang ierr = PetscSFComputeDegreeEnd(sf,°ree);CHKERRQ(ierr); 12712bf73ac6SHong Zhang nleaves_total=0; 12722bf73ac6SHong Zhang for (i=0; i<nroots; i++) nleaves_total += degree[i]; 12732bf73ac6SHong Zhang printf("[%d] nleaves_total %d\n",rank,nleaves_total); 12742bf73ac6SHong Zhang MPI_Barrier(comm); 12752bf73ac6SHong Zhang 12762bf73ac6SHong Zhang ierr = PetscCalloc2(nleaves_total,&indata,nleaves,&outdata);CHKERRQ(ierr); 12772bf73ac6SHong Zhang 12782bf73ac6SHong Zhang /* Leaves copy user's ncomp to outdata */ 12792bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&nsv,&svtx);CHKERRQ(ierr); 12802bf73ac6SHong Zhang for (i=0; i<nsv; i++) { 12812bf73ac6SHong Zhang p = svtx[i]; 12822bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 12832bf73ac6SHong Zhang if (!ghost) continue; 12842bf73ac6SHong Zhang 12852bf73ac6SHong Zhang header = &network->header[p]; 12862bf73ac6SHong Zhang ncomp = header->ndata; 12872bf73ac6SHong Zhang printf("[%d] leaf has ncomp %d\n",rank,ncomp); 12882bf73ac6SHong Zhang outdata[p] = ncomp; 12892bf73ac6SHong Zhang } 12902bf73ac6SHong Zhang 12912bf73ac6SHong Zhang /* Roots gather ncomp from leaves */ 12922bf73ac6SHong Zhang ierr = PetscSFGatherBegin(sf,MPIU_INT,outdata,indata);CHKERRQ(ierr); 12932bf73ac6SHong Zhang ierr = PetscSFGatherEnd(sf,MPIU_INT,outdata,indata);CHKERRQ(ierr); 12942bf73ac6SHong Zhang ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD,"## Gathered data at multi-roots from leaves\n");CHKERRQ(ierr); 12952bf73ac6SHong Zhang ierr = PetscIntView(nleaves_total,indata,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 12962bf73ac6SHong Zhang 12972bf73ac6SHong Zhang ierr = PetscFree2(indata,outdata);CHKERRQ(ierr); 12982bf73ac6SHong Zhang } 12992bf73ac6SHong Zhang //---------------------- 13002bf73ac6SHong Zhang #endif 13012bf73ac6SHong Zhang 13025f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr); 13035f2c45f1SShri Abhyankar ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr); 130475b160a0SShri Abhyankar ierr = PetscMalloc1(arr_size,&network->componentdataarray);CHKERRQ(ierr); 13055f2c45f1SShri Abhyankar componentdataarray = network->componentdataarray; 13065f2c45f1SShri Abhyankar for (p = network->pStart; p < network->pEnd; p++) { 13075f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 13085f2c45f1SShri Abhyankar /* Copy header */ 13095f2c45f1SShri Abhyankar header = &network->header[p]; 1310302440fdSBarry Smith ierr = PetscMemcpy(componentdataarray+offsetp,header,network->dataheadersize*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 13115f2c45f1SShri Abhyankar /* Copy data */ 13125f2c45f1SShri Abhyankar cvalue = &network->cvalue[p]; 13135f2c45f1SShri Abhyankar ncomp = header->ndata; 13142bf73ac6SHong Zhang 13155f2c45f1SShri Abhyankar for (i = 0; i < ncomp; i++) { 13165f2c45f1SShri Abhyankar offset = offsetp + network->dataheadersize + header->offset[i]; 1317302440fdSBarry Smith ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 13185f2c45f1SShri Abhyankar } 13195f2c45f1SShri Abhyankar } 13205f2c45f1SShri Abhyankar PetscFunctionReturn(0); 13215f2c45f1SShri Abhyankar } 13225f2c45f1SShri Abhyankar 13235f2c45f1SShri Abhyankar /* Sets up the section for dofs. This routine is called during DMSetUp() */ 13242bf73ac6SHong Zhang static PetscErrorCode DMNetworkVariablesSetUp(DM dm) 13255f2c45f1SShri Abhyankar { 13265f2c45f1SShri Abhyankar PetscErrorCode ierr; 13275f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 13282bf73ac6SHong Zhang MPI_Comm comm; 13292bf73ac6SHong Zhang PetscMPIInt size; 13305f2c45f1SShri Abhyankar 13315f2c45f1SShri Abhyankar PetscFunctionBegin; 13322bf73ac6SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 13332bf73ac6SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 13342bf73ac6SHong Zhang 13352bf73ac6SHong Zhang if (size > 1) { /* Sync nvar at shared vertices for all processes */ 13362bf73ac6SHong Zhang PetscSF sf = network->plex->sf; 13372bf73ac6SHong Zhang PetscInt *local_nvar, *remote_nvar,nroots,nleaves,p=-1,i,nsv; 13382bf73ac6SHong Zhang const PetscInt *svtx; 13392bf73ac6SHong Zhang PetscBool ghost; 13402bf73ac6SHong Zhang /* 13412bf73ac6SHong Zhang PetscMPIInt rank; 13422bf73ac6SHong Zhang const PetscInt *ilocal; 13432bf73ac6SHong Zhang const PetscSFNode *iremote; 13442bf73ac6SHong Zhang ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 13452bf73ac6SHong Zhang ierr = PetscSFGetGraph(sf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr); 13462bf73ac6SHong Zhang */ 13472bf73ac6SHong Zhang ierr = PetscSFGetGraph(sf,&nroots,&nleaves,NULL,NULL);CHKERRQ(ierr); 13482bf73ac6SHong Zhang ierr = PetscCalloc2(nroots,&local_nvar,nroots,&remote_nvar);CHKERRQ(ierr); 13492bf73ac6SHong Zhang 13502bf73ac6SHong Zhang /* Leaves copy user's nvar to local_nvar */ 13512bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&nsv,&svtx);CHKERRQ(ierr); 13522bf73ac6SHong Zhang for (i=0; i<nsv; i++) { 13532bf73ac6SHong Zhang p = svtx[i]; 13542bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 13552bf73ac6SHong Zhang if (!ghost) continue; 13562bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,&local_nvar[p]);CHKERRQ(ierr); 13572bf73ac6SHong Zhang /* printf("[%d] Before SFReduce: leaf local_nvar[%d] = %d\n",rank,p,local_nvar[p]); */ 13582bf73ac6SHong Zhang } 13592bf73ac6SHong Zhang 13602bf73ac6SHong Zhang /* Leaves add local_nvar to root remote_nvar */ 13612bf73ac6SHong Zhang ierr = PetscSFReduceBegin(sf, MPIU_INT, local_nvar, remote_nvar, MPI_SUM);CHKERRQ(ierr); 13622bf73ac6SHong Zhang ierr = PetscSFReduceEnd(sf, MPIU_INT, local_nvar, remote_nvar, MPI_SUM);CHKERRQ(ierr); 13632bf73ac6SHong Zhang /* printf("[%d] remote_nvar[%d] = %d\n",rank,p,remote_nvar[p]); */ 13642bf73ac6SHong Zhang 13652bf73ac6SHong Zhang /* Update roots' local_nvar */ 13662bf73ac6SHong Zhang for (i=0; i<nsv; i++) { 13672bf73ac6SHong Zhang p = svtx[i]; 13682bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 13692bf73ac6SHong Zhang if (ghost) continue; 13702bf73ac6SHong Zhang 13712bf73ac6SHong Zhang ierr = PetscSectionAddDof(network->DofSection,p,remote_nvar[p]);CHKERRQ(ierr); 13722bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,&local_nvar[p]);CHKERRQ(ierr); 13732bf73ac6SHong Zhang /* printf("[%d] After SFReduce: root local_nvar[%d] = %d\n",rank,p,local_nvar[p]); */ 13742bf73ac6SHong Zhang } 13752bf73ac6SHong Zhang 13762bf73ac6SHong Zhang /* Roots Bcast nvar to leaves */ 1377ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sf, MPIU_INT, local_nvar, remote_nvar,MPI_REPLACE);CHKERRQ(ierr); 1378ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sf, MPIU_INT, local_nvar, remote_nvar,MPI_REPLACE);CHKERRQ(ierr); 13792bf73ac6SHong Zhang 13802bf73ac6SHong Zhang /* Leaves reset receved/remote nvar to dm */ 13812bf73ac6SHong Zhang for (i=0; i<nsv; i++) { 13822bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 13832bf73ac6SHong Zhang if (!ghost) continue; 13842bf73ac6SHong Zhang p = svtx[i]; 13852bf73ac6SHong Zhang /* printf("[%d] leaf reset nvar %d at p= %d \n",rank,remote_nvar[p],p); */ 13862bf73ac6SHong Zhang /* DMNetworkSetNumVariables(dm,p,remote_nvar[p]) */ 13872bf73ac6SHong Zhang ierr = PetscSectionSetDof(network->DofSection,p,remote_nvar[p]);CHKERRQ(ierr); 13882bf73ac6SHong Zhang } 13892bf73ac6SHong Zhang 13902bf73ac6SHong Zhang ierr = PetscFree2(local_nvar,remote_nvar);CHKERRQ(ierr); 13912bf73ac6SHong Zhang } 13922bf73ac6SHong Zhang 13935f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr); 13945f2c45f1SShri Abhyankar PetscFunctionReturn(0); 13955f2c45f1SShri Abhyankar } 13965f2c45f1SShri Abhyankar 139724121865SAdrian Maldonado /* Get a subsection from a range of points */ 13989dddd249SSatish Balay static PetscErrorCode DMNetworkGetSubSection_private(PetscSection main,PetscInt pstart,PetscInt pend,PetscSection *subsection) 139924121865SAdrian Maldonado { 140024121865SAdrian Maldonado PetscErrorCode ierr; 140124121865SAdrian Maldonado PetscInt i, nvar; 140224121865SAdrian Maldonado 140324121865SAdrian Maldonado PetscFunctionBegin; 14049dddd249SSatish Balay ierr = PetscSectionCreate(PetscObjectComm((PetscObject)main), subsection);CHKERRQ(ierr); 140524121865SAdrian Maldonado ierr = PetscSectionSetChart(*subsection, 0, pend - pstart);CHKERRQ(ierr); 140624121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 14079dddd249SSatish Balay ierr = PetscSectionGetDof(main,i,&nvar);CHKERRQ(ierr); 140824121865SAdrian Maldonado ierr = PetscSectionSetDof(*subsection, i - pstart, nvar);CHKERRQ(ierr); 140924121865SAdrian Maldonado } 141024121865SAdrian Maldonado 141124121865SAdrian Maldonado ierr = PetscSectionSetUp(*subsection);CHKERRQ(ierr); 141224121865SAdrian Maldonado PetscFunctionReturn(0); 141324121865SAdrian Maldonado } 141424121865SAdrian Maldonado 141524121865SAdrian Maldonado /* Create a submap of points with a GlobalToLocal structure */ 14162bf73ac6SHong Zhang static PetscErrorCode DMNetworkSetSubMap_private(PetscInt pstart, PetscInt pend, ISLocalToGlobalMapping *map) 141724121865SAdrian Maldonado { 141824121865SAdrian Maldonado PetscErrorCode ierr; 141924121865SAdrian Maldonado PetscInt i, *subpoints; 142024121865SAdrian Maldonado 142124121865SAdrian Maldonado PetscFunctionBegin; 142224121865SAdrian Maldonado /* Create index sets to map from "points" to "subpoints" */ 142324121865SAdrian Maldonado ierr = PetscMalloc1(pend - pstart, &subpoints);CHKERRQ(ierr); 142424121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 142524121865SAdrian Maldonado subpoints[i - pstart] = i; 142624121865SAdrian Maldonado } 1427459726d8SSatish Balay ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,pend-pstart,subpoints,PETSC_COPY_VALUES,map);CHKERRQ(ierr); 142824121865SAdrian Maldonado ierr = PetscFree(subpoints);CHKERRQ(ierr); 142924121865SAdrian Maldonado PetscFunctionReturn(0); 143024121865SAdrian Maldonado } 143124121865SAdrian Maldonado 143224121865SAdrian Maldonado /*@ 14332bf73ac6SHong Zhang DMNetworkAssembleGraphStructures - Assembles vertex and edge data structures. Must be called after DMNetworkDistribute 143424121865SAdrian Maldonado 14352bf73ac6SHong Zhang Collective on dm 143624121865SAdrian Maldonado 143724121865SAdrian Maldonado Input Parameters: 14382bf73ac6SHong Zhang . dm - the DMNetworkObject 143924121865SAdrian Maldonado 144024121865SAdrian Maldonado Note: the routine will create alternative orderings for the vertices and edges. Assume global network points are: 144124121865SAdrian Maldonado 144224121865SAdrian Maldonado points = [0 1 2 3 4 5 6] 144324121865SAdrian Maldonado 1444caf410d2SHong 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]). 144524121865SAdrian Maldonado 144624121865SAdrian Maldonado With this new ordering a local PetscSection, global PetscSection and PetscSF will be created specific to the subset. 144724121865SAdrian Maldonado 144824121865SAdrian Maldonado Level: intermediate 144924121865SAdrian Maldonado 145024121865SAdrian Maldonado @*/ 145124121865SAdrian Maldonado PetscErrorCode DMNetworkAssembleGraphStructures(DM dm) 145224121865SAdrian Maldonado { 145324121865SAdrian Maldonado PetscErrorCode ierr; 145424121865SAdrian Maldonado MPI_Comm comm; 14559852e123SBarry Smith PetscMPIInt rank, size; 145624121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 145724121865SAdrian Maldonado 1458eab1376dSHong Zhang PetscFunctionBegin; 145924121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 1460ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 1461ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 146224121865SAdrian Maldonado 146324121865SAdrian Maldonado /* Create maps for vertices and edges */ 146424121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 146524121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->eStart,network->eEnd,&network->edge.mapping);CHKERRQ(ierr); 146624121865SAdrian Maldonado 146724121865SAdrian Maldonado /* Create local sub-sections */ 146824121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->vStart,network->vEnd,&network->vertex.DofSection);CHKERRQ(ierr); 146924121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->eStart,network->eEnd,&network->edge.DofSection);CHKERRQ(ierr); 147024121865SAdrian Maldonado 14719852e123SBarry Smith if (size > 1) { 147224121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 147322bbedd7SHong Zhang 147424121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->vertex.DofSection, network->vertex.sf, PETSC_FALSE, PETSC_FALSE, &network->vertex.GlobalDofSection);CHKERRQ(ierr); 147524121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->edge.mapping, &network->edge.sf);CHKERRQ(ierr); 147624121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->edge.DofSection, network->edge.sf, PETSC_FALSE, PETSC_FALSE, &network->edge.GlobalDofSection);CHKERRQ(ierr); 147724121865SAdrian Maldonado } else { 147824121865SAdrian Maldonado /* create structures for vertex */ 147924121865SAdrian Maldonado ierr = PetscSectionClone(network->vertex.DofSection,&network->vertex.GlobalDofSection);CHKERRQ(ierr); 148024121865SAdrian Maldonado /* create structures for edge */ 148124121865SAdrian Maldonado ierr = PetscSectionClone(network->edge.DofSection,&network->edge.GlobalDofSection);CHKERRQ(ierr); 148224121865SAdrian Maldonado } 148324121865SAdrian Maldonado 148424121865SAdrian Maldonado /* Add viewers */ 148524121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->edge.GlobalDofSection,"Global edge dof section");CHKERRQ(ierr); 148624121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->vertex.GlobalDofSection,"Global vertex dof section");CHKERRQ(ierr); 148724121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->edge.GlobalDofSection, NULL, "-edge_global_section_view");CHKERRQ(ierr); 148824121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->vertex.GlobalDofSection, NULL, "-vertex_global_section_view");CHKERRQ(ierr); 148924121865SAdrian Maldonado PetscFunctionReturn(0); 149024121865SAdrian Maldonado } 14917b6afd5bSHong Zhang 14925f2c45f1SShri Abhyankar /*@ 14932bf73ac6SHong Zhang DMNetworkDistribute - Distributes the network and moves associated component data 14945f2c45f1SShri Abhyankar 14955f2c45f1SShri Abhyankar Collective 14965f2c45f1SShri Abhyankar 14975f2c45f1SShri Abhyankar Input Parameter: 1498d3464fd4SAdrian Maldonado + DM - the DMNetwork object 14992bf73ac6SHong Zhang - overlap - the overlap of partitions, 0 is the default 15005f2c45f1SShri Abhyankar 15015f2c45f1SShri Abhyankar Notes: 15028b171c8eSHong Zhang Distributes the network with <overlap>-overlapping partitioning of the edges. 15035f2c45f1SShri Abhyankar 15045f2c45f1SShri Abhyankar Level: intermediate 15055f2c45f1SShri Abhyankar 15062bf73ac6SHong Zhang .seealso: DMNetworkCreate() 15075f2c45f1SShri Abhyankar @*/ 1508d3464fd4SAdrian Maldonado PetscErrorCode DMNetworkDistribute(DM *dm,PetscInt overlap) 15095f2c45f1SShri Abhyankar { 1510d3464fd4SAdrian Maldonado MPI_Comm comm; 15115f2c45f1SShri Abhyankar PetscErrorCode ierr; 1512d3464fd4SAdrian Maldonado PetscMPIInt size; 1513d3464fd4SAdrian Maldonado DM_Network *oldDMnetwork = (DM_Network*)((*dm)->data); 1514d3464fd4SAdrian Maldonado DM_Network *newDMnetwork; 1515caf410d2SHong Zhang PetscSF pointsf=NULL; 15165f2c45f1SShri Abhyankar DM newDM; 15172bf73ac6SHong Zhang PetscInt j,e,v,offset,*subnetvtx,nsubnet,gidx,svtx_idx,nv; 15182bf73ac6SHong Zhang PetscInt to_net,from_net,*svto; 151951ac5effSHong Zhang PetscPartitioner part; 1520b9c6e19dSShri Abhyankar DMNetworkComponentHeader header; 15215f2c45f1SShri Abhyankar 15225f2c45f1SShri Abhyankar PetscFunctionBegin; 1523d3464fd4SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)*dm,&comm);CHKERRQ(ierr); 1524ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 1525d3464fd4SAdrian Maldonado if (size == 1) PetscFunctionReturn(0); 1526d3464fd4SAdrian Maldonado 15272bf73ac6SHong Zhang /* This routine moves the component data to the appropriate processors. It makes use of the DataSection and the componentdataarray to move the component data to appropriate processors and returns a new DataSection and new componentdataarray. */ 1528d3464fd4SAdrian Maldonado ierr = DMNetworkCreate(PetscObjectComm((PetscObject)*dm),&newDM);CHKERRQ(ierr); 15295f2c45f1SShri Abhyankar newDMnetwork = (DM_Network*)newDM->data; 15305f2c45f1SShri Abhyankar newDMnetwork->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 153151ac5effSHong Zhang 153251ac5effSHong Zhang /* Enable runtime options for petscpartitioner */ 153351ac5effSHong Zhang ierr = DMPlexGetPartitioner(oldDMnetwork->plex,&part);CHKERRQ(ierr); 153451ac5effSHong Zhang ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); 153551ac5effSHong Zhang 15362bf73ac6SHong Zhang /* Distribute plex dm */ 153780cf41d5SMatthew G. Knepley ierr = DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr); 153851ac5effSHong Zhang 15395f2c45f1SShri Abhyankar /* Distribute dof section */ 15402bf73ac6SHong Zhang ierr = PetscSectionCreate(comm,&newDMnetwork->DofSection);CHKERRQ(ierr); 15415f2c45f1SShri Abhyankar ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr); 154251ac5effSHong Zhang 15435f2c45f1SShri Abhyankar /* Distribute data and associated section */ 15442bf73ac6SHong Zhang ierr = PetscSectionCreate(comm,&newDMnetwork->DataSection);CHKERRQ(ierr); 154531da1fc8SHong Zhang ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPIU_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr); 154624121865SAdrian Maldonado 15475f2c45f1SShri Abhyankar ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr); 15485f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr); 15495f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr); 15505f2c45f1SShri Abhyankar newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart; 15516fefedf4SHong Zhang newDMnetwork->nVertices = newDMnetwork->vEnd - newDMnetwork->vStart; 15526fefedf4SHong Zhang newDMnetwork->NVertices = oldDMnetwork->NVertices; 15535f2c45f1SShri Abhyankar newDMnetwork->NEdges = oldDMnetwork->NEdges; 15542bf73ac6SHong Zhang newDMnetwork->svtable = oldDMnetwork->svtable; 15552bf73ac6SHong Zhang oldDMnetwork->svtable = NULL; 155624121865SAdrian Maldonado 15571bb6d2a8SBarry Smith /* Set Dof section as the section for dm */ 155892fd8e1eSJed Brown ierr = DMSetLocalSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr); 1559e87a4003SBarry Smith ierr = DMGetGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr); 15605f2c45f1SShri Abhyankar 1561b9c6e19dSShri Abhyankar /* Set up subnetwork info in the newDM */ 15622bf73ac6SHong Zhang newDMnetwork->Nsubnet = oldDMnetwork->Nsubnet; 15632bf73ac6SHong Zhang newDMnetwork->Nsvtx = oldDMnetwork->Nsvtx; 15642bf73ac6SHong Zhang oldDMnetwork->Nsvtx = 0; 15652bf73ac6SHong Zhang newDMnetwork->svtx = oldDMnetwork->svtx; /* global vertices! */ 15662bf73ac6SHong Zhang oldDMnetwork->svtx = NULL; 15672bf73ac6SHong Zhang ierr = PetscCalloc1(newDMnetwork->Nsubnet,&newDMnetwork->subnet);CHKERRQ(ierr); 15682bf73ac6SHong Zhang 15692bf73ac6SHong Zhang /* Copy over the global number of vertices and edges in each subnetwork. 15702bf73ac6SHong Zhang Note: these are calculated in DMNetworkLayoutSetUp() 1571b9c6e19dSShri Abhyankar */ 15722bf73ac6SHong Zhang nsubnet = newDMnetwork->Nsubnet; 15732bf73ac6SHong Zhang for (j = 0; j < nsubnet; j++) { 1574b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nvtx = oldDMnetwork->subnet[j].Nvtx; 1575b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nedge = oldDMnetwork->subnet[j].Nedge; 1576b9c6e19dSShri Abhyankar } 1577b9c6e19dSShri Abhyankar 15782bf73ac6SHong Zhang /* Get local nedges and nvtx for subnetworks */ 1579b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++) { 1580b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 1581b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1582b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nedge++; 1583b9c6e19dSShri Abhyankar } 1584b9c6e19dSShri Abhyankar 1585b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++) { 1586b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1587b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 15882bf73ac6SHong Zhang 15892bf73ac6SHong Zhang /* shared vertices: use gidx = header->index to check if v is a shared vertex */ 15902bf73ac6SHong Zhang gidx = header->index; 15912bf73ac6SHong Zhang ierr = PetscTableFind(newDMnetwork->svtable,gidx+1,&svtx_idx);CHKERRQ(ierr); 15922bf73ac6SHong Zhang svtx_idx--; 15932bf73ac6SHong Zhang 15942bf73ac6SHong Zhang if (svtx_idx < 0) { /* not a shared vertex */ 1595b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nvtx++; 15962bf73ac6SHong Zhang } else { /* a shared vertex belongs to more than one subnetworks, it is being counted by multiple subnets */ 15972bf73ac6SHong Zhang from_net = newDMnetwork->svtx[svtx_idx].sv[0]; 15982bf73ac6SHong Zhang newDMnetwork->subnet[from_net].nvtx++; 15992bf73ac6SHong Zhang for (j=1; j<newDMnetwork->svtx[svtx_idx].n; j++) { 16002bf73ac6SHong Zhang svto = newDMnetwork->svtx[svtx_idx].sv + 2*j; 16012bf73ac6SHong Zhang to_net = svto[0]; 16022bf73ac6SHong Zhang newDMnetwork->subnet[to_net].nvtx++; 16032bf73ac6SHong Zhang } 16042bf73ac6SHong Zhang } 1605b9c6e19dSShri Abhyankar } 1606b9c6e19dSShri Abhyankar 16072bf73ac6SHong Zhang /* Get total local nvtx for subnetworks */ 16082bf73ac6SHong Zhang nv = 0; 16092bf73ac6SHong Zhang for (j=0; j<nsubnet; j++) nv += newDMnetwork->subnet[j].nvtx; 16102bf73ac6SHong Zhang nv += newDMnetwork->Nsvtx; 1611caf410d2SHong Zhang 16122bf73ac6SHong Zhang /* Now create the vertices and edge arrays for the subnetworks */ 16132bf73ac6SHong Zhang ierr = PetscCalloc1(nv,&subnetvtx);CHKERRQ(ierr); 16142bf73ac6SHong Zhang newDMnetwork->subnetvtx = subnetvtx; 16152bf73ac6SHong Zhang 16162bf73ac6SHong Zhang for (j=0; j<nsubnet; j++) { 1617b9c6e19dSShri Abhyankar ierr = PetscCalloc1(newDMnetwork->subnet[j].nedge,&newDMnetwork->subnet[j].edges);CHKERRQ(ierr); 1618caf410d2SHong Zhang newDMnetwork->subnet[j].vertices = subnetvtx; 1619caf410d2SHong Zhang subnetvtx += newDMnetwork->subnet[j].nvtx; 1620caf410d2SHong Zhang 16212bf73ac6SHong Zhang /* Temporarily setting nvtx and nedge to 0 so we can use them as counters in the below for loop. These get updated when the vertices and edges are added. */ 1622b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].nvtx = newDMnetwork->subnet[j].nedge = 0; 1623b9c6e19dSShri Abhyankar } 16242bf73ac6SHong Zhang newDMnetwork->svertices = subnetvtx; 1625b9c6e19dSShri Abhyankar 16262bf73ac6SHong Zhang /* Set the edges and vertices in each subnetwork */ 1627b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++) { 1628b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 1629b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1630b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].edges[newDMnetwork->subnet[header->subnetid].nedge++] = e; 1631b9c6e19dSShri Abhyankar } 1632b9c6e19dSShri Abhyankar 16332bf73ac6SHong Zhang nv = 0; 1634b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++) { 1635b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1636b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 16372bf73ac6SHong Zhang 16382bf73ac6SHong Zhang /* coupling vertices: use gidx = header->index to check if v is a coupling vertex */ 16392bf73ac6SHong Zhang ierr = PetscTableFind(newDMnetwork->svtable,header->index+1,&svtx_idx);CHKERRQ(ierr); 16402bf73ac6SHong Zhang svtx_idx--; 16412bf73ac6SHong Zhang if (svtx_idx < 0) { 1642b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].vertices[newDMnetwork->subnet[header->subnetid].nvtx++] = v; 16432bf73ac6SHong Zhang } else { /* a shared vertex */ 16442bf73ac6SHong Zhang newDMnetwork->svertices[nv++] = v; 16452bf73ac6SHong Zhang 16462bf73ac6SHong Zhang from_net = newDMnetwork->svtx[svtx_idx].sv[0]; 16472bf73ac6SHong Zhang newDMnetwork->subnet[from_net].vertices[newDMnetwork->subnet[from_net].nvtx++] = v; 16482bf73ac6SHong Zhang 16492bf73ac6SHong Zhang for (j=1; j<newDMnetwork->svtx[svtx_idx].n; j++) { 16502bf73ac6SHong Zhang svto = newDMnetwork->svtx[svtx_idx].sv + 2*j; 16512bf73ac6SHong Zhang to_net = svto[0]; 16522bf73ac6SHong Zhang newDMnetwork->subnet[to_net].vertices[newDMnetwork->subnet[to_net].nvtx++] = v; 1653b9c6e19dSShri Abhyankar } 16542bf73ac6SHong Zhang } 16552bf73ac6SHong Zhang } 16562bf73ac6SHong Zhang newDMnetwork->nsvtx = nv; /* num of local shared vertices */ 1657b9c6e19dSShri Abhyankar 1658caf410d2SHong Zhang newDM->setupcalled = (*dm)->setupcalled; 165922bbedd7SHong Zhang newDMnetwork->distributecalled = PETSC_TRUE; 1660caf410d2SHong Zhang 16612bf73ac6SHong Zhang /* Free spaces */ 166224121865SAdrian Maldonado ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr); 1663d3464fd4SAdrian Maldonado ierr = DMDestroy(dm);CHKERRQ(ierr); 16642bf73ac6SHong Zhang 1665d3464fd4SAdrian Maldonado *dm = newDM; 16665f2c45f1SShri Abhyankar PetscFunctionReturn(0); 16675f2c45f1SShri Abhyankar } 16685f2c45f1SShri Abhyankar 166924121865SAdrian Maldonado /*@C 16702bf73ac6SHong Zhang PetscSFGetSubSF - Returns an SF for a specific subset of points. Leaves are re-numbered to reflect the new ordering 16712bf73ac6SHong Zhang 16722bf73ac6SHong Zhang Collective 167324121865SAdrian Maldonado 167424121865SAdrian Maldonado Input Parameters: 16759dddd249SSatish Balay + mainSF - the original SF structure 167624121865SAdrian Maldonado - map - a ISLocalToGlobal mapping that contains the subset of points 167724121865SAdrian Maldonado 167824121865SAdrian Maldonado Output Parameters: 16799dddd249SSatish Balay . subSF - a subset of the mainSF for the desired subset. 1680ee300463SSatish Balay 1681ee300463SSatish Balay Level: intermediate 16827d928bffSSatish Balay @*/ 16839dddd249SSatish Balay PetscErrorCode PetscSFGetSubSF(PetscSF mainsf,ISLocalToGlobalMapping map,PetscSF *subSF) 16842bf73ac6SHong Zhang { 168524121865SAdrian Maldonado PetscErrorCode ierr; 168624121865SAdrian Maldonado PetscInt nroots, nleaves, *ilocal_sub; 168724121865SAdrian Maldonado PetscInt i, *ilocal_map, nroots_sub, nleaves_sub = 0; 168824121865SAdrian Maldonado PetscInt *local_points, *remote_points; 168924121865SAdrian Maldonado PetscSFNode *iremote_sub; 169024121865SAdrian Maldonado const PetscInt *ilocal; 169124121865SAdrian Maldonado const PetscSFNode *iremote; 169224121865SAdrian Maldonado 169324121865SAdrian Maldonado PetscFunctionBegin; 16949dddd249SSatish Balay ierr = PetscSFGetGraph(mainsf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr); 169524121865SAdrian Maldonado 169624121865SAdrian Maldonado /* Look for leaves that pertain to the subset of points. Get the local ordering */ 169724121865SAdrian Maldonado ierr = PetscMalloc1(nleaves,&ilocal_map);CHKERRQ(ierr); 169824121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nleaves,ilocal,NULL,ilocal_map);CHKERRQ(ierr); 169924121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 170024121865SAdrian Maldonado if (ilocal_map[i] != -1) nleaves_sub += 1; 170124121865SAdrian Maldonado } 170224121865SAdrian Maldonado /* Re-number ilocal with subset numbering. Need information from roots */ 170324121865SAdrian Maldonado ierr = PetscMalloc2(nroots,&local_points,nroots,&remote_points);CHKERRQ(ierr); 170424121865SAdrian Maldonado for (i = 0; i < nroots; i++) local_points[i] = i; 170524121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nroots,local_points,NULL,local_points);CHKERRQ(ierr); 1706ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(mainsf, MPIU_INT, local_points, remote_points,MPI_REPLACE);CHKERRQ(ierr); 1707ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(mainsf, MPIU_INT, local_points, remote_points,MPI_REPLACE);CHKERRQ(ierr); 170824121865SAdrian Maldonado /* Fill up graph using local (that is, local to the subset) numbering. */ 17094b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&ilocal_sub);CHKERRQ(ierr); 17104b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&iremote_sub);CHKERRQ(ierr); 171124121865SAdrian Maldonado nleaves_sub = 0; 171224121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 171324121865SAdrian Maldonado if (ilocal_map[i] != -1) { 171424121865SAdrian Maldonado ilocal_sub[nleaves_sub] = ilocal_map[i]; 17154b70a8deSAdrian Maldonado iremote_sub[nleaves_sub].rank = iremote[i].rank; 171624121865SAdrian Maldonado iremote_sub[nleaves_sub].index = remote_points[ilocal[i]]; 171724121865SAdrian Maldonado nleaves_sub += 1; 171824121865SAdrian Maldonado } 171924121865SAdrian Maldonado } 172024121865SAdrian Maldonado ierr = PetscFree2(local_points,remote_points);CHKERRQ(ierr); 172124121865SAdrian Maldonado ierr = ISLocalToGlobalMappingGetSize(map,&nroots_sub);CHKERRQ(ierr); 172224121865SAdrian Maldonado 172324121865SAdrian Maldonado /* Create new subSF */ 172424121865SAdrian Maldonado ierr = PetscSFCreate(PETSC_COMM_WORLD,subSF);CHKERRQ(ierr); 172524121865SAdrian Maldonado ierr = PetscSFSetFromOptions(*subSF);CHKERRQ(ierr); 17264b70a8deSAdrian Maldonado ierr = PetscSFSetGraph(*subSF,nroots_sub,nleaves_sub,ilocal_sub,PETSC_OWN_POINTER,iremote_sub,PETSC_COPY_VALUES);CHKERRQ(ierr); 172724121865SAdrian Maldonado ierr = PetscFree(ilocal_map);CHKERRQ(ierr); 17284b70a8deSAdrian Maldonado ierr = PetscFree(iremote_sub);CHKERRQ(ierr); 172924121865SAdrian Maldonado PetscFunctionReturn(0); 173024121865SAdrian Maldonado } 173124121865SAdrian Maldonado 17325f2c45f1SShri Abhyankar /*@C 17335f2c45f1SShri Abhyankar DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point 17345f2c45f1SShri Abhyankar 17355f2c45f1SShri Abhyankar Not Collective 17365f2c45f1SShri Abhyankar 17375f2c45f1SShri Abhyankar Input Parameters: 17382bf73ac6SHong Zhang + dm - the DMNetwork object 17395f2c45f1SShri Abhyankar - p - the vertex point 17405f2c45f1SShri Abhyankar 1741fd292e60Sprj- Output Parameters: 17425f2c45f1SShri Abhyankar + nedges - number of edges connected to this vertex point 17432bf73ac6SHong Zhang - edges - list of edge points 17445f2c45f1SShri Abhyankar 174597bb938eSShri Abhyankar Level: beginner 17465f2c45f1SShri Abhyankar 17475f2c45f1SShri Abhyankar Fortran Notes: 17485f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 17495f2c45f1SShri Abhyankar include petsc.h90 in your code. 17505f2c45f1SShri Abhyankar 17512bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkGetConnectedVertices() 17525f2c45f1SShri Abhyankar @*/ 17535f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[]) 17545f2c45f1SShri Abhyankar { 17555f2c45f1SShri Abhyankar PetscErrorCode ierr; 17565f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 17575f2c45f1SShri Abhyankar 17585f2c45f1SShri Abhyankar PetscFunctionBegin; 17595f2c45f1SShri Abhyankar ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr); 1760a9b4a83eSHong Zhang if (edges) {ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr);} 17615f2c45f1SShri Abhyankar PetscFunctionReturn(0); 17625f2c45f1SShri Abhyankar } 17635f2c45f1SShri Abhyankar 17645f2c45f1SShri Abhyankar /*@C 1765d842c372SHong Zhang DMNetworkGetConnectedVertices - Return the connected vertices for this edge point 17665f2c45f1SShri Abhyankar 17675f2c45f1SShri Abhyankar Not Collective 17685f2c45f1SShri Abhyankar 17695f2c45f1SShri Abhyankar Input Parameters: 17702bf73ac6SHong Zhang + dm - the DMNetwork object 17715f2c45f1SShri Abhyankar - p - the edge point 17725f2c45f1SShri Abhyankar 1773fd292e60Sprj- Output Parameters: 17745f2c45f1SShri Abhyankar . vertices - vertices connected to this edge 17755f2c45f1SShri Abhyankar 177697bb938eSShri Abhyankar Level: beginner 17775f2c45f1SShri Abhyankar 17785f2c45f1SShri Abhyankar Fortran Notes: 17795f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 17805f2c45f1SShri Abhyankar include petsc.h90 in your code. 17815f2c45f1SShri Abhyankar 17822bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkGetSupportingEdges() 17835f2c45f1SShri Abhyankar @*/ 1784d842c372SHong Zhang PetscErrorCode DMNetworkGetConnectedVertices(DM dm,PetscInt edge,const PetscInt *vertices[]) 17855f2c45f1SShri Abhyankar { 17865f2c45f1SShri Abhyankar PetscErrorCode ierr; 17875f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 17885f2c45f1SShri Abhyankar 17895f2c45f1SShri Abhyankar PetscFunctionBegin; 17905f2c45f1SShri Abhyankar ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr); 17915f2c45f1SShri Abhyankar PetscFunctionReturn(0); 17925f2c45f1SShri Abhyankar } 17935f2c45f1SShri Abhyankar 17945f2c45f1SShri Abhyankar /*@ 17952bf73ac6SHong Zhang DMNetworkIsSharedVertex - Returns TRUE if the vertex is shared by subnetworks 17962bf73ac6SHong Zhang 17972bf73ac6SHong Zhang Not Collective 17982bf73ac6SHong Zhang 17992bf73ac6SHong Zhang Input Parameters: 18002bf73ac6SHong Zhang + dm - the DMNetwork object 18012bf73ac6SHong Zhang - p - the vertex point 18022bf73ac6SHong Zhang 18032bf73ac6SHong Zhang Output Parameter: 18042bf73ac6SHong Zhang . flag - TRUE if the vertex is shared by subnetworks 18052bf73ac6SHong Zhang 18062bf73ac6SHong Zhang Level: beginner 18072bf73ac6SHong Zhang 18082bf73ac6SHong Zhang .seealso: DMNetworkAddSharedVertices(), DMNetworkIsGhostVertex() 18092bf73ac6SHong Zhang @*/ 18102bf73ac6SHong Zhang PetscErrorCode DMNetworkIsSharedVertex(DM dm,PetscInt p,PetscBool *flag) 18112bf73ac6SHong Zhang { 18122bf73ac6SHong Zhang PetscErrorCode ierr; 18132bf73ac6SHong Zhang PetscInt i; 18142bf73ac6SHong Zhang 18152bf73ac6SHong Zhang PetscFunctionBegin; 18162bf73ac6SHong Zhang *flag = PETSC_FALSE; 18172bf73ac6SHong Zhang 18182bf73ac6SHong Zhang if (dm->setupcalled) { /* DMNetworkGetGlobalVertexIndex() requires DMSetUp() be called */ 18192bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 18202bf73ac6SHong Zhang PetscInt gidx; 18212bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,p,&gidx);CHKERRQ(ierr); 18222bf73ac6SHong Zhang ierr = PetscTableFind(network->svtable,gidx+1,&i);CHKERRQ(ierr); 18232bf73ac6SHong Zhang if (i) *flag = PETSC_TRUE; 18242bf73ac6SHong Zhang } else { /* would be removed? */ 18252bf73ac6SHong Zhang PetscInt nv; 18262bf73ac6SHong Zhang const PetscInt *vtx; 18272bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&nv,&vtx);CHKERRQ(ierr); 18282bf73ac6SHong Zhang for (i=0; i<nv; i++) { 18292bf73ac6SHong Zhang if (p == vtx[i]) { 18302bf73ac6SHong Zhang *flag = PETSC_TRUE; 18312bf73ac6SHong Zhang break; 18322bf73ac6SHong Zhang } 18332bf73ac6SHong Zhang } 18342bf73ac6SHong Zhang } 18352bf73ac6SHong Zhang PetscFunctionReturn(0); 18362bf73ac6SHong Zhang } 18372bf73ac6SHong Zhang 18382bf73ac6SHong Zhang /*@ 18395f2c45f1SShri Abhyankar DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex 18405f2c45f1SShri Abhyankar 18415f2c45f1SShri Abhyankar Not Collective 18425f2c45f1SShri Abhyankar 18435f2c45f1SShri Abhyankar Input Parameters: 18442bf73ac6SHong Zhang + dm - the DMNetwork object 1845a2b725a8SWilliam Gropp - p - the vertex point 18465f2c45f1SShri Abhyankar 18475f2c45f1SShri Abhyankar Output Parameter: 18485f2c45f1SShri Abhyankar . isghost - TRUE if the vertex is a ghost point 18495f2c45f1SShri Abhyankar 185097bb938eSShri Abhyankar Level: beginner 18515f2c45f1SShri Abhyankar 18522bf73ac6SHong Zhang .seealso: DMNetworkGetConnectedVertices(), DMNetworkGetVertexRange(), DMNetworkIsSharedVertex() 18535f2c45f1SShri Abhyankar @*/ 18545f2c45f1SShri Abhyankar PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost) 18555f2c45f1SShri Abhyankar { 18565f2c45f1SShri Abhyankar PetscErrorCode ierr; 18575f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 18585f2c45f1SShri Abhyankar PetscInt offsetg; 18595f2c45f1SShri Abhyankar PetscSection sectiong; 18605f2c45f1SShri Abhyankar 18615f2c45f1SShri Abhyankar PetscFunctionBegin; 18625f2c45f1SShri Abhyankar *isghost = PETSC_FALSE; 1863e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§iong);CHKERRQ(ierr); 18645f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr); 18655f2c45f1SShri Abhyankar if (offsetg < 0) *isghost = PETSC_TRUE; 18665f2c45f1SShri Abhyankar PetscFunctionReturn(0); 18675f2c45f1SShri Abhyankar } 18685f2c45f1SShri Abhyankar 18695f2c45f1SShri Abhyankar PetscErrorCode DMSetUp_Network(DM dm) 18705f2c45f1SShri Abhyankar { 18715f2c45f1SShri Abhyankar PetscErrorCode ierr; 18725f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 18735f2c45f1SShri Abhyankar 18745f2c45f1SShri Abhyankar PetscFunctionBegin; 18755f2c45f1SShri Abhyankar ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr); 18765f2c45f1SShri Abhyankar ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr); 18775f2c45f1SShri Abhyankar 187892fd8e1eSJed Brown ierr = DMSetLocalSection(network->plex,network->DofSection);CHKERRQ(ierr); 1879e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr); 18809e1d080bSHong Zhang 18819e1d080bSHong Zhang dm->setupcalled = PETSC_TRUE; 18829e1d080bSHong Zhang ierr = DMViewFromOptions(dm,NULL,"-dm_view");CHKERRQ(ierr); 18835f2c45f1SShri Abhyankar PetscFunctionReturn(0); 18845f2c45f1SShri Abhyankar } 18855f2c45f1SShri Abhyankar 18861ad426b7SHong Zhang /*@ 188717df6e9eSHong Zhang DMNetworkHasJacobian - Sets global flag for using user's sub Jacobian matrices 18881ad426b7SHong Zhang -- replaced by DMNetworkSetOption(network,userjacobian,PETSC_TURE)? 18891ad426b7SHong Zhang 18901ad426b7SHong Zhang Collective 18911ad426b7SHong Zhang 18921ad426b7SHong Zhang Input Parameters: 18932bf73ac6SHong Zhang + dm - the DMNetwork object 189483b2e829SHong Zhang . eflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for edges 189583b2e829SHong Zhang - vflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for vertices 18961ad426b7SHong Zhang 18971ad426b7SHong Zhang Level: intermediate 18981ad426b7SHong Zhang 18991ad426b7SHong Zhang @*/ 190083b2e829SHong Zhang PetscErrorCode DMNetworkHasJacobian(DM dm,PetscBool eflg,PetscBool vflg) 19011ad426b7SHong Zhang { 19021ad426b7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 19038675203cSHong Zhang PetscErrorCode ierr; 190466b4e0ffSHong Zhang PetscInt nVertices = network->nVertices; 19051ad426b7SHong Zhang 19061ad426b7SHong Zhang PetscFunctionBegin; 190783b2e829SHong Zhang network->userEdgeJacobian = eflg; 190883b2e829SHong Zhang network->userVertexJacobian = vflg; 19098675203cSHong Zhang 19108675203cSHong Zhang if (eflg && !network->Je) { 19118675203cSHong Zhang ierr = PetscCalloc1(3*network->nEdges,&network->Je);CHKERRQ(ierr); 19128675203cSHong Zhang } 19138675203cSHong Zhang 191466b4e0ffSHong Zhang if (vflg && !network->Jv && nVertices) { 19158675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 191666b4e0ffSHong Zhang PetscInt nedges_total; 19178675203cSHong Zhang const PetscInt *edges; 19188675203cSHong Zhang 19198675203cSHong Zhang /* count nvertex_total */ 19208675203cSHong Zhang nedges_total = 0; 19218675203cSHong Zhang ierr = PetscMalloc1(nVertices+1,&vptr);CHKERRQ(ierr); 19228675203cSHong Zhang 19238675203cSHong Zhang vptr[0] = 0; 19248675203cSHong Zhang for (i=0; i<nVertices; i++) { 19258675203cSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,i+vStart,&nedges,&edges);CHKERRQ(ierr); 19268675203cSHong Zhang nedges_total += nedges; 19278675203cSHong Zhang vptr[i+1] = vptr[i] + 2*nedges + 1; 19288675203cSHong Zhang } 19298675203cSHong Zhang 19308675203cSHong Zhang ierr = PetscCalloc1(2*nedges_total+nVertices,&network->Jv);CHKERRQ(ierr); 19318675203cSHong Zhang network->Jvptr = vptr; 19328675203cSHong Zhang } 19331ad426b7SHong Zhang PetscFunctionReturn(0); 19341ad426b7SHong Zhang } 19351ad426b7SHong Zhang 19361ad426b7SHong Zhang /*@ 193783b2e829SHong Zhang DMNetworkEdgeSetMatrix - Sets user-provided Jacobian matrices for this edge to the network 193883b2e829SHong Zhang 193983b2e829SHong Zhang Not Collective 194083b2e829SHong Zhang 194183b2e829SHong Zhang Input Parameters: 19422bf73ac6SHong Zhang + dm - the DMNetwork object 194383b2e829SHong Zhang . p - the edge point 19443e97b6e8SHong Zhang - J - array (size = 3) of Jacobian submatrices for this edge point: 19453e97b6e8SHong Zhang J[0]: this edge 1946d842c372SHong Zhang J[1] and J[2]: connected vertices, obtained by calling DMNetworkGetConnectedVertices() 194783b2e829SHong Zhang 194897bb938eSShri Abhyankar Level: advanced 194983b2e829SHong Zhang 19502bf73ac6SHong Zhang .seealso: DMNetworkVertexSetMatrix() 195183b2e829SHong Zhang @*/ 195283b2e829SHong Zhang PetscErrorCode DMNetworkEdgeSetMatrix(DM dm,PetscInt p,Mat J[]) 195383b2e829SHong Zhang { 195483b2e829SHong Zhang DM_Network *network=(DM_Network*)dm->data; 195583b2e829SHong Zhang 195683b2e829SHong Zhang PetscFunctionBegin; 19578675203cSHong Zhang if (!network->Je) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkEdgeSetMatrix"); 19588675203cSHong Zhang 19598675203cSHong Zhang if (J) { 1960883e35e8SHong Zhang network->Je[3*p] = J[0]; 1961883e35e8SHong Zhang network->Je[3*p+1] = J[1]; 1962883e35e8SHong Zhang network->Je[3*p+2] = J[2]; 19638675203cSHong Zhang } 196483b2e829SHong Zhang PetscFunctionReturn(0); 196583b2e829SHong Zhang } 196683b2e829SHong Zhang 196783b2e829SHong Zhang /*@ 196876ddfea5SHong Zhang DMNetworkVertexSetMatrix - Sets user-provided Jacobian matrix for this vertex to the network 19691ad426b7SHong Zhang 19701ad426b7SHong Zhang Not Collective 19711ad426b7SHong Zhang 19721ad426b7SHong Zhang Input Parameters: 19731ad426b7SHong Zhang + dm - The DMNetwork object 19741ad426b7SHong Zhang . p - the vertex point 19753e97b6e8SHong Zhang - J - array of Jacobian (size = 2*(num of supporting edges) + 1) submatrices for this vertex point: 19763e97b6e8SHong Zhang J[0]: this vertex 19773e97b6e8SHong Zhang J[1+2*i]: i-th supporting edge 19783e97b6e8SHong Zhang J[1+2*i+1]: i-th connected vertex 19791ad426b7SHong Zhang 198097bb938eSShri Abhyankar Level: advanced 19811ad426b7SHong Zhang 19822bf73ac6SHong Zhang .seealso: DMNetworkEdgeSetMatrix() 19831ad426b7SHong Zhang @*/ 1984883e35e8SHong Zhang PetscErrorCode DMNetworkVertexSetMatrix(DM dm,PetscInt p,Mat J[]) 19855f2c45f1SShri Abhyankar { 19865f2c45f1SShri Abhyankar PetscErrorCode ierr; 19875f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 19888675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 1989883e35e8SHong Zhang const PetscInt *edges; 19905f2c45f1SShri Abhyankar 19915f2c45f1SShri Abhyankar PetscFunctionBegin; 19928675203cSHong Zhang if (!network->Jv) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkVertexSetMatrix"); 1993883e35e8SHong Zhang 19948675203cSHong Zhang if (J) { 1995883e35e8SHong Zhang vptr = network->Jvptr; 19963e97b6e8SHong Zhang network->Jv[vptr[p-vStart]] = J[0]; /* Set Jacobian for this vertex */ 19973e97b6e8SHong Zhang 19983e97b6e8SHong Zhang /* Set Jacobian for each supporting edge and connected vertex */ 1999883e35e8SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,p,&nedges,&edges);CHKERRQ(ierr); 2000883e35e8SHong Zhang for (i=1; i<=2*nedges; i++) network->Jv[vptr[p-vStart]+i] = J[i]; 20018675203cSHong Zhang } 2002883e35e8SHong Zhang PetscFunctionReturn(0); 2003883e35e8SHong Zhang } 2004883e35e8SHong Zhang 2005e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 20065cf7da58SHong Zhang { 20075cf7da58SHong Zhang PetscErrorCode ierr; 20085cf7da58SHong Zhang PetscInt j; 20095cf7da58SHong Zhang PetscScalar val=(PetscScalar)ncols; 20105cf7da58SHong Zhang 20115cf7da58SHong Zhang PetscFunctionBegin; 20125cf7da58SHong Zhang if (!ghost) { 20135cf7da58SHong Zhang for (j=0; j<nrows; j++) { 20145cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 20155cf7da58SHong Zhang } 20165cf7da58SHong Zhang } else { 20175cf7da58SHong Zhang for (j=0; j<nrows; j++) { 20185cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 20195cf7da58SHong Zhang } 20205cf7da58SHong Zhang } 20215cf7da58SHong Zhang PetscFunctionReturn(0); 20225cf7da58SHong Zhang } 20235cf7da58SHong Zhang 2024e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 20255cf7da58SHong Zhang { 20265cf7da58SHong Zhang PetscErrorCode ierr; 20275cf7da58SHong Zhang PetscInt j,ncols_u; 20285cf7da58SHong Zhang PetscScalar val; 20295cf7da58SHong Zhang 20305cf7da58SHong Zhang PetscFunctionBegin; 20315cf7da58SHong Zhang if (!ghost) { 20325cf7da58SHong Zhang for (j=0; j<nrows; j++) { 20335cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 20345cf7da58SHong Zhang val = (PetscScalar)ncols_u; 20355cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 20365cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 20375cf7da58SHong Zhang } 20385cf7da58SHong Zhang } else { 20395cf7da58SHong Zhang for (j=0; j<nrows; j++) { 20405cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 20415cf7da58SHong Zhang val = (PetscScalar)ncols_u; 20425cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 20435cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 20445cf7da58SHong Zhang } 20455cf7da58SHong Zhang } 20465cf7da58SHong Zhang PetscFunctionReturn(0); 20475cf7da58SHong Zhang } 20485cf7da58SHong Zhang 2049e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 20505cf7da58SHong Zhang { 20515cf7da58SHong Zhang PetscErrorCode ierr; 20525cf7da58SHong Zhang 20535cf7da58SHong Zhang PetscFunctionBegin; 20545cf7da58SHong Zhang if (Ju) { 20555cf7da58SHong Zhang ierr = MatSetPreallocationUserblock_private(Ju,nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 20565cf7da58SHong Zhang } else { 20575cf7da58SHong Zhang ierr = MatSetPreallocationDenseblock_private(nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 20585cf7da58SHong Zhang } 20595cf7da58SHong Zhang PetscFunctionReturn(0); 20605cf7da58SHong Zhang } 20615cf7da58SHong Zhang 2062e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 2063883e35e8SHong Zhang { 2064883e35e8SHong Zhang PetscErrorCode ierr; 2065883e35e8SHong Zhang PetscInt j,*cols; 2066883e35e8SHong Zhang PetscScalar *zeros; 2067883e35e8SHong Zhang 2068883e35e8SHong Zhang PetscFunctionBegin; 2069883e35e8SHong Zhang ierr = PetscCalloc2(ncols,&cols,nrows*ncols,&zeros);CHKERRQ(ierr); 2070883e35e8SHong Zhang for (j=0; j<ncols; j++) cols[j] = j+ cstart; 2071883e35e8SHong Zhang ierr = MatSetValues(*J,nrows,rows,ncols,cols,zeros,INSERT_VALUES);CHKERRQ(ierr); 2072883e35e8SHong Zhang ierr = PetscFree2(cols,zeros);CHKERRQ(ierr); 20731ad426b7SHong Zhang PetscFunctionReturn(0); 20741ad426b7SHong Zhang } 2075a4e85ca8SHong Zhang 2076e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 20773e97b6e8SHong Zhang { 20783e97b6e8SHong Zhang PetscErrorCode ierr; 20793e97b6e8SHong Zhang PetscInt j,M,N,row,col,ncols_u; 20803e97b6e8SHong Zhang const PetscInt *cols; 20813e97b6e8SHong Zhang PetscScalar zero=0.0; 20823e97b6e8SHong Zhang 20833e97b6e8SHong Zhang PetscFunctionBegin; 20843e97b6e8SHong Zhang ierr = MatGetSize(Ju,&M,&N);CHKERRQ(ierr); 20853e97b6e8SHong 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); 20863e97b6e8SHong Zhang 20873e97b6e8SHong Zhang for (row=0; row<nrows; row++) { 20883e97b6e8SHong Zhang ierr = MatGetRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 20893e97b6e8SHong Zhang for (j=0; j<ncols_u; j++) { 20903e97b6e8SHong Zhang col = cols[j] + cstart; 20913e97b6e8SHong Zhang ierr = MatSetValues(*J,1,&rows[row],1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr); 20923e97b6e8SHong Zhang } 20933e97b6e8SHong Zhang ierr = MatRestoreRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 20943e97b6e8SHong Zhang } 20953e97b6e8SHong Zhang PetscFunctionReturn(0); 20963e97b6e8SHong Zhang } 20971ad426b7SHong Zhang 2098e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 2099a4e85ca8SHong Zhang { 2100a4e85ca8SHong Zhang PetscErrorCode ierr; 2101f4431b8cSHong Zhang 2102a4e85ca8SHong Zhang PetscFunctionBegin; 2103a4e85ca8SHong Zhang if (Ju) { 2104a4e85ca8SHong Zhang ierr = MatSetUserblock_private(Ju,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 2105a4e85ca8SHong Zhang } else { 2106a4e85ca8SHong Zhang ierr = MatSetDenseblock_private(nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 2107a4e85ca8SHong Zhang } 2108a4e85ca8SHong Zhang PetscFunctionReturn(0); 2109a4e85ca8SHong Zhang } 2110a4e85ca8SHong Zhang 211124121865SAdrian 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. 211224121865SAdrian Maldonado */ 211324121865SAdrian Maldonado PetscErrorCode CreateSubGlobalToLocalMapping_private(PetscSection globalsec, PetscSection localsec, ISLocalToGlobalMapping *ltog) 211424121865SAdrian Maldonado { 211524121865SAdrian Maldonado PetscErrorCode ierr; 211624121865SAdrian Maldonado PetscInt i,size,dof; 211724121865SAdrian Maldonado PetscInt *glob2loc; 211824121865SAdrian Maldonado 211924121865SAdrian Maldonado PetscFunctionBegin; 212024121865SAdrian Maldonado ierr = PetscSectionGetStorageSize(localsec,&size);CHKERRQ(ierr); 212124121865SAdrian Maldonado ierr = PetscMalloc1(size,&glob2loc);CHKERRQ(ierr); 212224121865SAdrian Maldonado 212324121865SAdrian Maldonado for (i = 0; i < size; i++) { 212424121865SAdrian Maldonado ierr = PetscSectionGetOffset(globalsec,i,&dof);CHKERRQ(ierr); 212524121865SAdrian Maldonado dof = (dof >= 0) ? dof : -(dof + 1); 212624121865SAdrian Maldonado glob2loc[i] = dof; 212724121865SAdrian Maldonado } 212824121865SAdrian Maldonado 212924121865SAdrian Maldonado ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,size,glob2loc,PETSC_OWN_POINTER,ltog);CHKERRQ(ierr); 213024121865SAdrian Maldonado #if 0 213124121865SAdrian Maldonado ierr = PetscIntView(size,glob2loc,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 213224121865SAdrian Maldonado #endif 213324121865SAdrian Maldonado PetscFunctionReturn(0); 213424121865SAdrian Maldonado } 213524121865SAdrian Maldonado 213601ad2aeeSHong Zhang #include <petsc/private/matimpl.h> 21379e1d080bSHong Zhang 21389e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network_Nest(DM dm,Mat *J) 21391ad426b7SHong Zhang { 21401ad426b7SHong Zhang PetscErrorCode ierr; 21411ad426b7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 21429e1d080bSHong Zhang PetscMPIInt rank, size; 214324121865SAdrian Maldonado PetscInt eDof,vDof; 214424121865SAdrian Maldonado Mat j11,j12,j21,j22,bA[2][2]; 21459e1d080bSHong Zhang MPI_Comm comm; 214624121865SAdrian Maldonado ISLocalToGlobalMapping eISMap,vISMap; 214724121865SAdrian Maldonado 21489e1d080bSHong Zhang PetscFunctionBegin; 214924121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 2150ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 2151ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 215224121865SAdrian Maldonado 215324121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->edge.GlobalDofSection,&eDof);CHKERRQ(ierr); 215424121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->vertex.GlobalDofSection,&vDof);CHKERRQ(ierr); 215524121865SAdrian Maldonado 215601ad2aeeSHong Zhang ierr = MatCreate(comm, &j11);CHKERRQ(ierr); 215724121865SAdrian Maldonado ierr = MatSetSizes(j11, eDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 215824121865SAdrian Maldonado ierr = MatSetType(j11, MATMPIAIJ);CHKERRQ(ierr); 215924121865SAdrian Maldonado 216001ad2aeeSHong Zhang ierr = MatCreate(comm, &j12);CHKERRQ(ierr); 216124121865SAdrian Maldonado ierr = MatSetSizes(j12, eDof, vDof, PETSC_DETERMINE ,PETSC_DETERMINE);CHKERRQ(ierr); 216224121865SAdrian Maldonado ierr = MatSetType(j12, MATMPIAIJ);CHKERRQ(ierr); 216324121865SAdrian Maldonado 216401ad2aeeSHong Zhang ierr = MatCreate(comm, &j21);CHKERRQ(ierr); 216524121865SAdrian Maldonado ierr = MatSetSizes(j21, vDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 216624121865SAdrian Maldonado ierr = MatSetType(j21, MATMPIAIJ);CHKERRQ(ierr); 216724121865SAdrian Maldonado 216801ad2aeeSHong Zhang ierr = MatCreate(comm, &j22);CHKERRQ(ierr); 216924121865SAdrian Maldonado ierr = MatSetSizes(j22, vDof, vDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 217024121865SAdrian Maldonado ierr = MatSetType(j22, MATMPIAIJ);CHKERRQ(ierr); 217124121865SAdrian Maldonado 21723f6a6bdaSHong Zhang bA[0][0] = j11; 21733f6a6bdaSHong Zhang bA[0][1] = j12; 21743f6a6bdaSHong Zhang bA[1][0] = j21; 21753f6a6bdaSHong Zhang bA[1][1] = j22; 217624121865SAdrian Maldonado 217724121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->edge.GlobalDofSection,network->edge.DofSection,&eISMap);CHKERRQ(ierr); 217824121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->vertex.GlobalDofSection,network->vertex.DofSection,&vISMap);CHKERRQ(ierr); 217924121865SAdrian Maldonado 218024121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j11,eISMap,eISMap);CHKERRQ(ierr); 218124121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j12,eISMap,vISMap);CHKERRQ(ierr); 218224121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j21,vISMap,eISMap);CHKERRQ(ierr); 218324121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j22,vISMap,vISMap);CHKERRQ(ierr); 218424121865SAdrian Maldonado 218524121865SAdrian Maldonado ierr = MatSetUp(j11);CHKERRQ(ierr); 218624121865SAdrian Maldonado ierr = MatSetUp(j12);CHKERRQ(ierr); 218724121865SAdrian Maldonado ierr = MatSetUp(j21);CHKERRQ(ierr); 218824121865SAdrian Maldonado ierr = MatSetUp(j22);CHKERRQ(ierr); 218924121865SAdrian Maldonado 219001ad2aeeSHong Zhang ierr = MatCreateNest(comm,2,NULL,2,NULL,&bA[0][0],J);CHKERRQ(ierr); 219124121865SAdrian Maldonado ierr = MatSetUp(*J);CHKERRQ(ierr); 219224121865SAdrian Maldonado ierr = MatNestSetVecType(*J,VECNEST);CHKERRQ(ierr); 219324121865SAdrian Maldonado ierr = MatDestroy(&j11);CHKERRQ(ierr); 219424121865SAdrian Maldonado ierr = MatDestroy(&j12);CHKERRQ(ierr); 219524121865SAdrian Maldonado ierr = MatDestroy(&j21);CHKERRQ(ierr); 219624121865SAdrian Maldonado ierr = MatDestroy(&j22);CHKERRQ(ierr); 219724121865SAdrian Maldonado 219824121865SAdrian Maldonado ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 219924121865SAdrian Maldonado ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 22009e1d080bSHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 220124121865SAdrian Maldonado 220224121865SAdrian Maldonado /* Free structures */ 220324121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&eISMap);CHKERRQ(ierr); 220424121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&vISMap);CHKERRQ(ierr); 220524121865SAdrian Maldonado PetscFunctionReturn(0); 22069e1d080bSHong Zhang } 22079e1d080bSHong Zhang 22089e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J) 22099e1d080bSHong Zhang { 22109e1d080bSHong Zhang PetscErrorCode ierr; 22119e1d080bSHong Zhang DM_Network *network = (DM_Network*)dm->data; 22129e1d080bSHong Zhang PetscInt eStart,eEnd,vStart,vEnd,rstart,nrows,*rows,localSize; 22139e1d080bSHong Zhang PetscInt cstart,ncols,j,e,v; 22149e1d080bSHong Zhang PetscBool ghost,ghost_vc,ghost2,isNest; 22159e1d080bSHong Zhang Mat Juser; 22169e1d080bSHong Zhang PetscSection sectionGlobal; 22179e1d080bSHong Zhang PetscInt nedges,*vptr=NULL,vc,*rows_v; /* suppress maybe-uninitialized warning */ 22189e1d080bSHong Zhang const PetscInt *edges,*cone; 22199e1d080bSHong Zhang MPI_Comm comm; 22209e1d080bSHong Zhang MatType mtype; 22219e1d080bSHong Zhang Vec vd_nz,vo_nz; 22229e1d080bSHong Zhang PetscInt *dnnz,*onnz; 22239e1d080bSHong Zhang PetscScalar *vdnz,*vonz; 22249e1d080bSHong Zhang 22259e1d080bSHong Zhang PetscFunctionBegin; 22269e1d080bSHong Zhang mtype = dm->mattype; 22279e1d080bSHong Zhang ierr = PetscStrcmp(mtype,MATNEST,&isNest);CHKERRQ(ierr); 22289e1d080bSHong Zhang if (isNest) { 22299e1d080bSHong Zhang ierr = DMCreateMatrix_Network_Nest(dm,J);CHKERRQ(ierr); 2230c6b011d8SStefano Zampini ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 22319e1d080bSHong Zhang PetscFunctionReturn(0); 22329e1d080bSHong Zhang } 22339e1d080bSHong Zhang 22349e1d080bSHong Zhang if (!network->userEdgeJacobian && !network->userVertexJacobian) { 2235a4e85ca8SHong Zhang /* user does not provide Jacobian blocks */ 22369e1d080bSHong Zhang ierr = DMCreateMatrix_Plex(network->plex,J);CHKERRQ(ierr); 2237bfbc38dcSHong Zhang ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 22381ad426b7SHong Zhang PetscFunctionReturn(0); 22391ad426b7SHong Zhang } 22401ad426b7SHong Zhang 2241bfbc38dcSHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)dm),J);CHKERRQ(ierr); 2242e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§ionGlobal);CHKERRQ(ierr); 2243bfbc38dcSHong Zhang ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal,&localSize);CHKERRQ(ierr); 2244bfbc38dcSHong Zhang ierr = MatSetSizes(*J,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 22452a945128SHong Zhang 22462a945128SHong Zhang ierr = MatSetType(*J,MATAIJ);CHKERRQ(ierr); 22472a945128SHong Zhang ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 224889898e50SHong Zhang 224989898e50SHong Zhang /* (1) Set matrix preallocation */ 225089898e50SHong Zhang /*------------------------------*/ 2251840c2264SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 2252840c2264SHong Zhang ierr = VecCreate(comm,&vd_nz);CHKERRQ(ierr); 2253840c2264SHong Zhang ierr = VecSetSizes(vd_nz,localSize,PETSC_DECIDE);CHKERRQ(ierr); 2254840c2264SHong Zhang ierr = VecSetFromOptions(vd_nz);CHKERRQ(ierr); 2255840c2264SHong Zhang ierr = VecSet(vd_nz,0.0);CHKERRQ(ierr); 2256840c2264SHong Zhang ierr = VecDuplicate(vd_nz,&vo_nz);CHKERRQ(ierr); 2257840c2264SHong Zhang 225889898e50SHong Zhang /* Set preallocation for edges */ 225989898e50SHong Zhang /*-----------------------------*/ 2260840c2264SHong Zhang ierr = DMNetworkGetEdgeRange(dm,&eStart,&eEnd);CHKERRQ(ierr); 2261840c2264SHong Zhang 2262bdcb62a2SHong Zhang ierr = PetscMalloc1(localSize,&rows);CHKERRQ(ierr); 2263840c2264SHong Zhang for (e=eStart; e<eEnd; e++) { 2264840c2264SHong Zhang /* Get row indices */ 22652bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,e,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 22662bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,e,&nrows);CHKERRQ(ierr); 2267840c2264SHong Zhang if (nrows) { 2268840c2264SHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 2269840c2264SHong Zhang 22705cf7da58SHong Zhang /* Set preallocation for conntected vertices */ 2271d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 2272840c2264SHong Zhang for (v=0; v<2; v++) { 22732bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,cone[v],&ncols);CHKERRQ(ierr); 2274840c2264SHong Zhang 22758675203cSHong Zhang if (network->Je) { 2276840c2264SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 22778675203cSHong Zhang } else Juser = NULL; 2278840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,cone[v],&ghost);CHKERRQ(ierr); 22795cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 2280840c2264SHong Zhang } 2281840c2264SHong Zhang 228289898e50SHong Zhang /* Set preallocation for edge self */ 2283840c2264SHong Zhang cstart = rstart; 22848675203cSHong Zhang if (network->Je) { 2285840c2264SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 22868675203cSHong Zhang } else Juser = NULL; 22875cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 2288840c2264SHong Zhang } 2289840c2264SHong Zhang } 2290840c2264SHong Zhang 229189898e50SHong Zhang /* Set preallocation for vertices */ 229289898e50SHong Zhang /*--------------------------------*/ 2293840c2264SHong Zhang ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 22948675203cSHong Zhang if (vEnd - vStart) vptr = network->Jvptr; 2295840c2264SHong Zhang 2296840c2264SHong Zhang for (v=vStart; v<vEnd; v++) { 2297840c2264SHong Zhang /* Get row indices */ 22982bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 22992bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,v,&nrows);CHKERRQ(ierr); 2300840c2264SHong Zhang if (!nrows) continue; 2301840c2264SHong Zhang 2302bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 2303bdcb62a2SHong Zhang if (ghost) { 2304bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 2305bdcb62a2SHong Zhang } else { 2306bdcb62a2SHong Zhang rows_v = rows; 2307bdcb62a2SHong Zhang } 2308bdcb62a2SHong Zhang 2309bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 2310840c2264SHong Zhang 2311840c2264SHong Zhang /* Get supporting edges and connected vertices */ 2312840c2264SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 2313840c2264SHong Zhang 2314840c2264SHong Zhang for (e=0; e<nedges; e++) { 2315840c2264SHong Zhang /* Supporting edges */ 23162bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,edges[e],ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 23172bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,edges[e],&ncols);CHKERRQ(ierr); 2318840c2264SHong Zhang 23198675203cSHong Zhang if (network->Jv) { 2320840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 23218675203cSHong Zhang } else Juser = NULL; 2322bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 2323840c2264SHong Zhang 2324840c2264SHong Zhang /* Connected vertices */ 2325d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 2326840c2264SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 2327840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,vc,&ghost_vc);CHKERRQ(ierr); 2328840c2264SHong Zhang 23292bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,vc,&ncols);CHKERRQ(ierr); 2330840c2264SHong Zhang 23318675203cSHong Zhang if (network->Jv) { 2332840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 23338675203cSHong Zhang } else Juser = NULL; 2334e102a522SHong Zhang if (ghost_vc||ghost) { 2335e102a522SHong Zhang ghost2 = PETSC_TRUE; 2336e102a522SHong Zhang } else { 2337e102a522SHong Zhang ghost2 = PETSC_FALSE; 2338e102a522SHong Zhang } 2339e102a522SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost2,vd_nz,vo_nz);CHKERRQ(ierr); 2340840c2264SHong Zhang } 2341840c2264SHong Zhang 234289898e50SHong Zhang /* Set preallocation for vertex self */ 2343840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 2344840c2264SHong Zhang if (!ghost) { 23452bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 23468675203cSHong Zhang if (network->Jv) { 2347840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 23488675203cSHong Zhang } else Juser = NULL; 2349bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 2350840c2264SHong Zhang } 2351bdcb62a2SHong Zhang if (ghost) { 2352bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 2353bdcb62a2SHong Zhang } 2354840c2264SHong Zhang } 2355840c2264SHong Zhang 2356840c2264SHong Zhang ierr = VecAssemblyBegin(vd_nz);CHKERRQ(ierr); 2357840c2264SHong Zhang ierr = VecAssemblyBegin(vo_nz);CHKERRQ(ierr); 23585cf7da58SHong Zhang 23595cf7da58SHong Zhang ierr = PetscMalloc2(localSize,&dnnz,localSize,&onnz);CHKERRQ(ierr); 23605cf7da58SHong Zhang 23615cf7da58SHong Zhang ierr = VecAssemblyEnd(vd_nz);CHKERRQ(ierr); 2362840c2264SHong Zhang ierr = VecAssemblyEnd(vo_nz);CHKERRQ(ierr); 2363840c2264SHong Zhang 2364840c2264SHong Zhang ierr = VecGetArray(vd_nz,&vdnz);CHKERRQ(ierr); 2365840c2264SHong Zhang ierr = VecGetArray(vo_nz,&vonz);CHKERRQ(ierr); 2366840c2264SHong Zhang for (j=0; j<localSize; j++) { 2367e102a522SHong Zhang dnnz[j] = (PetscInt)PetscRealPart(vdnz[j]); 2368e102a522SHong Zhang onnz[j] = (PetscInt)PetscRealPart(vonz[j]); 2369840c2264SHong Zhang } 2370840c2264SHong Zhang ierr = VecRestoreArray(vd_nz,&vdnz);CHKERRQ(ierr); 2371840c2264SHong Zhang ierr = VecRestoreArray(vo_nz,&vonz);CHKERRQ(ierr); 2372840c2264SHong Zhang ierr = VecDestroy(&vd_nz);CHKERRQ(ierr); 2373840c2264SHong Zhang ierr = VecDestroy(&vo_nz);CHKERRQ(ierr); 2374840c2264SHong Zhang 23755cf7da58SHong Zhang ierr = MatSeqAIJSetPreallocation(*J,0,dnnz);CHKERRQ(ierr); 23765cf7da58SHong Zhang ierr = MatMPIAIJSetPreallocation(*J,0,dnnz,0,onnz);CHKERRQ(ierr); 23775cf7da58SHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 23785cf7da58SHong Zhang 23795cf7da58SHong Zhang ierr = PetscFree2(dnnz,onnz);CHKERRQ(ierr); 23805cf7da58SHong Zhang 238189898e50SHong Zhang /* (2) Set matrix entries for edges */ 238289898e50SHong Zhang /*----------------------------------*/ 23831ad426b7SHong Zhang for (e=eStart; e<eEnd; e++) { 2384bfbc38dcSHong Zhang /* Get row indices */ 23852bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,e,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 23862bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,e,&nrows);CHKERRQ(ierr); 23874b976069SHong Zhang if (nrows) { 238817df6e9eSHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 23891ad426b7SHong Zhang 2390bfbc38dcSHong Zhang /* Set matrix entries for conntected vertices */ 2391d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 2392bfbc38dcSHong Zhang for (v=0; v<2; v++) { 23932bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,cone[v],ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 23942bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,cone[v],&ncols);CHKERRQ(ierr); 23953e97b6e8SHong Zhang 23968675203cSHong Zhang if (network->Je) { 2397a4e85ca8SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 23988675203cSHong Zhang } else Juser = NULL; 2399a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 2400bfbc38dcSHong Zhang } 240117df6e9eSHong Zhang 2402bfbc38dcSHong Zhang /* Set matrix entries for edge self */ 24033e97b6e8SHong Zhang cstart = rstart; 24048675203cSHong Zhang if (network->Je) { 2405a4e85ca8SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 24068675203cSHong Zhang } else Juser = NULL; 2407a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,nrows,cstart,J);CHKERRQ(ierr); 24081ad426b7SHong Zhang } 24094b976069SHong Zhang } 24101ad426b7SHong Zhang 2411bfbc38dcSHong Zhang /* Set matrix entries for vertices */ 241283b2e829SHong Zhang /*---------------------------------*/ 24131ad426b7SHong Zhang for (v=vStart; v<vEnd; v++) { 2414bfbc38dcSHong Zhang /* Get row indices */ 24152bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 24162bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,v,&nrows);CHKERRQ(ierr); 24174b976069SHong Zhang if (!nrows) continue; 2418596e729fSHong Zhang 2419bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 2420bdcb62a2SHong Zhang if (ghost) { 2421bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 2422bdcb62a2SHong Zhang } else { 2423bdcb62a2SHong Zhang rows_v = rows; 2424bdcb62a2SHong Zhang } 2425bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 2426596e729fSHong Zhang 2427bfbc38dcSHong Zhang /* Get supporting edges and connected vertices */ 2428596e729fSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 2429596e729fSHong Zhang 2430596e729fSHong Zhang for (e=0; e<nedges; e++) { 2431bfbc38dcSHong Zhang /* Supporting edges */ 24322bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,edges[e],ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 24332bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,edges[e],&ncols);CHKERRQ(ierr); 2434596e729fSHong Zhang 24358675203cSHong Zhang if (network->Jv) { 2436a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 24378675203cSHong Zhang } else Juser = NULL; 2438bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 2439596e729fSHong Zhang 2440bfbc38dcSHong Zhang /* Connected vertices */ 2441d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 24422a945128SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 24432a945128SHong Zhang 24442bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,vc,ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 24452bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,vc,&ncols);CHKERRQ(ierr); 2446a4e85ca8SHong Zhang 24478675203cSHong Zhang if (network->Jv) { 2448a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 24498675203cSHong Zhang } else Juser = NULL; 2450bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 2451596e729fSHong Zhang } 2452596e729fSHong Zhang 2453bfbc38dcSHong Zhang /* Set matrix entries for vertex self */ 24541ad426b7SHong Zhang if (!ghost) { 24552bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 24568675203cSHong Zhang if (network->Jv) { 2457a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 24588675203cSHong Zhang } else Juser = NULL; 2459bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,nrows,cstart,J);CHKERRQ(ierr); 2460bdcb62a2SHong Zhang } 2461bdcb62a2SHong Zhang if (ghost) { 2462bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 2463bdcb62a2SHong Zhang } 24641ad426b7SHong Zhang } 2465a4e85ca8SHong Zhang ierr = PetscFree(rows);CHKERRQ(ierr); 2466bdcb62a2SHong Zhang 24671ad426b7SHong Zhang ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24681ad426b7SHong Zhang ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2469dd6f46cdSHong Zhang 24705f2c45f1SShri Abhyankar ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 24715f2c45f1SShri Abhyankar PetscFunctionReturn(0); 24725f2c45f1SShri Abhyankar } 24735f2c45f1SShri Abhyankar 24745f2c45f1SShri Abhyankar PetscErrorCode DMDestroy_Network(DM dm) 24755f2c45f1SShri Abhyankar { 24765f2c45f1SShri Abhyankar PetscErrorCode ierr; 24775f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 24782727e31bSShri Abhyankar PetscInt j; 24795f2c45f1SShri Abhyankar 24805f2c45f1SShri Abhyankar PetscFunctionBegin; 24818415c774SShri Abhyankar if (--network->refct > 0) PetscFunctionReturn(0); 248283b2e829SHong Zhang if (network->Je) { 248383b2e829SHong Zhang ierr = PetscFree(network->Je);CHKERRQ(ierr); 248483b2e829SHong Zhang } 248583b2e829SHong Zhang if (network->Jv) { 2486883e35e8SHong Zhang ierr = PetscFree(network->Jvptr);CHKERRQ(ierr); 248783b2e829SHong Zhang ierr = PetscFree(network->Jv);CHKERRQ(ierr); 24881ad426b7SHong Zhang } 248913c2a604SAdrian Maldonado 249013c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->vertex.mapping);CHKERRQ(ierr); 249113c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.DofSection);CHKERRQ(ierr); 249213c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.GlobalDofSection);CHKERRQ(ierr); 2493f5427c60SHong Zhang if (network->vltog) { 2494f5427c60SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 2495f5427c60SHong Zhang } 249613c2a604SAdrian Maldonado if (network->vertex.sf) { 249713c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->vertex.sf);CHKERRQ(ierr); 249813c2a604SAdrian Maldonado } 249913c2a604SAdrian Maldonado /* edge */ 250013c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->edge.mapping);CHKERRQ(ierr); 250113c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.DofSection);CHKERRQ(ierr); 250213c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.GlobalDofSection);CHKERRQ(ierr); 250313c2a604SAdrian Maldonado if (network->edge.sf) { 250413c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->edge.sf);CHKERRQ(ierr); 250513c2a604SAdrian Maldonado } 25065f2c45f1SShri Abhyankar ierr = DMDestroy(&network->plex);CHKERRQ(ierr); 25075f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr); 25085f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr); 250983b2e829SHong Zhang 25102bf73ac6SHong Zhang for (j=0; j<network->Nsvtx; j++) { 25112bf73ac6SHong Zhang ierr = PetscFree(network->svtx[j].sv);CHKERRQ(ierr); 25122bf73ac6SHong Zhang } 25132bf73ac6SHong Zhang if (network->svtx) {ierr = PetscFree(network->svtx);CHKERRQ(ierr);} 25142bf73ac6SHong Zhang 25152bf73ac6SHong Zhang for (j=0; j<network->Nsubnet; j++) { 25162727e31bSShri Abhyankar ierr = PetscFree(network->subnet[j].edges);CHKERRQ(ierr); 25172727e31bSShri Abhyankar } 25182bf73ac6SHong Zhang if (network->subnetvtx) {ierr = PetscFree(network->subnetvtx);CHKERRQ(ierr);} 2519caf410d2SHong Zhang 25202bf73ac6SHong Zhang ierr = PetscTableDestroy(&network->svtable);CHKERRQ(ierr); 2521e2aaf10cSShri Abhyankar ierr = PetscFree(network->subnet);CHKERRQ(ierr); 25225f2c45f1SShri Abhyankar ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr); 2523caf410d2SHong Zhang ierr = PetscFree2(network->header,network->cvalue);CHKERRQ(ierr); 25245f2c45f1SShri Abhyankar ierr = PetscFree(network);CHKERRQ(ierr); 25255f2c45f1SShri Abhyankar PetscFunctionReturn(0); 25265f2c45f1SShri Abhyankar } 25275f2c45f1SShri Abhyankar 25285f2c45f1SShri Abhyankar PetscErrorCode DMView_Network(DM dm,PetscViewer viewer) 25295f2c45f1SShri Abhyankar { 25305f2c45f1SShri Abhyankar PetscErrorCode ierr; 2531caf410d2SHong Zhang PetscBool iascii; 2532caf410d2SHong Zhang PetscMPIInt rank; 25335f2c45f1SShri Abhyankar 25345f2c45f1SShri Abhyankar PetscFunctionBegin; 2535caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 2536ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRMPI(ierr); 2537caf410d2SHong Zhang PetscValidHeaderSpecific(dm,DM_CLASSID, 1); 2538caf410d2SHong Zhang PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2539caf410d2SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 2540caf410d2SHong Zhang if (iascii) { 2541caf410d2SHong Zhang const PetscInt *cone,*vtx,*edges; 25422bf73ac6SHong Zhang PetscInt vfrom,vto,i,j,nv,ne,ncv,p,nsubnet; 25432bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 2544caf410d2SHong Zhang 25452bf73ac6SHong Zhang nsubnet = network->Nsubnet; /* num of subnetworks */ 25462bf73ac6SHong Zhang if (!rank) { 25472bf73ac6SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF," NSubnets: %D; NEdges: %D; NVertices: %D; NSharedVertices: %D.\n",nsubnet,network->NEdges,network->NVertices,network->Nsvtx);CHKERRQ(ierr); 25482bf73ac6SHong Zhang } 25492bf73ac6SHong Zhang 25502bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&ncv,&vtx);CHKERRQ(ierr); 2551caf410d2SHong Zhang ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 25522bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " [%d] nEdges: %D; nVertices: %D; nSharedVertices: %D\n",rank,network->nEdges,network->nVertices,ncv);CHKERRQ(ierr); 2553caf410d2SHong Zhang 2554caf410d2SHong Zhang for (i=0; i<nsubnet; i++) { 25552bf73ac6SHong Zhang ierr = DMNetworkGetSubnetwork(dm,i,&nv,&ne,&vtx,&edges);CHKERRQ(ierr); 2556caf410d2SHong Zhang if (ne) { 25572bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " Subnet %D: nEdges %D, nVertices(include shared vertices) %D\n",i,ne,nv);CHKERRQ(ierr); 2558caf410d2SHong Zhang for (j=0; j<ne; j++) { 2559caf410d2SHong Zhang p = edges[j]; 2560caf410d2SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,p,&cone);CHKERRQ(ierr); 2561caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[0],&vfrom);CHKERRQ(ierr); 2562caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[1],&vto);CHKERRQ(ierr); 2563caf410d2SHong Zhang ierr = DMNetworkGetGlobalEdgeIndex(dm,edges[j],&p);CHKERRQ(ierr); 2564caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " edge %D: %D ----> %D\n",p,vfrom,vto);CHKERRQ(ierr); 2565caf410d2SHong Zhang } 2566caf410d2SHong Zhang } 2567caf410d2SHong Zhang } 25682bf73ac6SHong Zhang 25692bf73ac6SHong Zhang /* Shared vertices */ 25702bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&ncv,&vtx);CHKERRQ(ierr); 25712bf73ac6SHong Zhang if (ncv) { 25722bf73ac6SHong Zhang SVtx *svtx = network->svtx; 25732bf73ac6SHong Zhang PetscInt gidx,svtx_idx,nvto,vfrom_net,vfrom_idx,*svto; 25742bf73ac6SHong Zhang PetscBool ghost; 25752bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " SharedVertices:\n");CHKERRQ(ierr); 25762bf73ac6SHong Zhang for (i=0; i<ncv; i++) { 25772bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,vtx[i],&ghost);CHKERRQ(ierr); 25782bf73ac6SHong Zhang if (ghost) continue; 25792bf73ac6SHong Zhang 25802bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,vtx[i],&gidx);CHKERRQ(ierr); 25812bf73ac6SHong Zhang ierr = PetscTableFind(network->svtable,gidx+1,&svtx_idx);CHKERRQ(ierr); 25822bf73ac6SHong Zhang svtx_idx--; 25832bf73ac6SHong Zhang nvto = svtx[svtx_idx].n; 25842bf73ac6SHong Zhang 25852bf73ac6SHong Zhang vfrom_net = svtx[svtx_idx].sv[0]; 25862bf73ac6SHong Zhang vfrom_idx = svtx[svtx_idx].sv[1]; 25872bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " svtx %D: global index %D, subnet[%D].%D ---->\n",i,gidx,vfrom_net,vfrom_idx);CHKERRQ(ierr); 25882bf73ac6SHong Zhang for (j=1; j<nvto; j++) { 25892bf73ac6SHong Zhang svto = svtx[svtx_idx].sv + 2*j; 25902bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " ----> subnet[%D].%D\n",svto[0],svto[1]);CHKERRQ(ierr); 2591caf410d2SHong Zhang } 2592caf410d2SHong Zhang } 2593caf410d2SHong Zhang } 2594caf410d2SHong Zhang ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2595caf410d2SHong Zhang ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 2596caf410d2SHong Zhang } else SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMNetwork writing", ((PetscObject)viewer)->type_name); 25975f2c45f1SShri Abhyankar PetscFunctionReturn(0); 25985f2c45f1SShri Abhyankar } 25995f2c45f1SShri Abhyankar 26005f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l) 26015f2c45f1SShri Abhyankar { 26025f2c45f1SShri Abhyankar PetscErrorCode ierr; 26035f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 26045f2c45f1SShri Abhyankar 26055f2c45f1SShri Abhyankar PetscFunctionBegin; 26065f2c45f1SShri Abhyankar ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr); 26075f2c45f1SShri Abhyankar PetscFunctionReturn(0); 26085f2c45f1SShri Abhyankar } 26095f2c45f1SShri Abhyankar 26105f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l) 26115f2c45f1SShri Abhyankar { 26125f2c45f1SShri Abhyankar PetscErrorCode ierr; 26135f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 26145f2c45f1SShri Abhyankar 26155f2c45f1SShri Abhyankar PetscFunctionBegin; 26165f2c45f1SShri Abhyankar ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr); 26175f2c45f1SShri Abhyankar PetscFunctionReturn(0); 26185f2c45f1SShri Abhyankar } 26195f2c45f1SShri Abhyankar 26205f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g) 26215f2c45f1SShri Abhyankar { 26225f2c45f1SShri Abhyankar PetscErrorCode ierr; 26235f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 26245f2c45f1SShri Abhyankar 26255f2c45f1SShri Abhyankar PetscFunctionBegin; 26265f2c45f1SShri Abhyankar ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr); 26275f2c45f1SShri Abhyankar PetscFunctionReturn(0); 26285f2c45f1SShri Abhyankar } 26295f2c45f1SShri Abhyankar 26305f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g) 26315f2c45f1SShri Abhyankar { 26325f2c45f1SShri Abhyankar PetscErrorCode ierr; 26335f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 26345f2c45f1SShri Abhyankar 26355f2c45f1SShri Abhyankar PetscFunctionBegin; 26365f2c45f1SShri Abhyankar ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr); 26375f2c45f1SShri Abhyankar PetscFunctionReturn(0); 26385f2c45f1SShri Abhyankar } 263922bbedd7SHong Zhang 264022bbedd7SHong Zhang /*@ 264164238763SRodolfo Oliveira DMNetworkGetVertexLocalToGlobalOrdering - Get vertex global index 264222bbedd7SHong Zhang 264322bbedd7SHong Zhang Not collective 264422bbedd7SHong Zhang 26457a7aea1fSJed Brown Input Parameters: 264622bbedd7SHong Zhang + dm - the dm object 264722bbedd7SHong Zhang - vloc - local vertex ordering, start from 0 264822bbedd7SHong Zhang 26497a7aea1fSJed Brown Output Parameters: 2650f0fc11ceSJed Brown . vg - global vertex ordering, start from 0 265122bbedd7SHong Zhang 265297bb938eSShri Abhyankar Level: advanced 265322bbedd7SHong Zhang 265422bbedd7SHong Zhang .seealso: DMNetworkSetVertexLocalToGlobalOrdering() 265522bbedd7SHong Zhang @*/ 265622bbedd7SHong Zhang PetscErrorCode DMNetworkGetVertexLocalToGlobalOrdering(DM dm,PetscInt vloc,PetscInt *vg) 265722bbedd7SHong Zhang { 265822bbedd7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 265922bbedd7SHong Zhang PetscInt *vltog = network->vltog; 266022bbedd7SHong Zhang 266122bbedd7SHong Zhang PetscFunctionBegin; 266222bbedd7SHong Zhang if (!vltog) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkSetVertexLocalToGlobalOrdering() first"); 266322bbedd7SHong Zhang *vg = vltog[vloc]; 266422bbedd7SHong Zhang PetscFunctionReturn(0); 266522bbedd7SHong Zhang } 266622bbedd7SHong Zhang 266722bbedd7SHong Zhang /*@ 266864238763SRodolfo Oliveira DMNetworkSetVertexLocalToGlobalOrdering - Create and setup vertex local to global map 266922bbedd7SHong Zhang 267022bbedd7SHong Zhang Collective 267122bbedd7SHong Zhang 267222bbedd7SHong Zhang Input Parameters: 2673f0fc11ceSJed Brown . dm - the dm object 267422bbedd7SHong Zhang 267597bb938eSShri Abhyankar Level: advanced 267622bbedd7SHong Zhang 267763029d29SHong Zhang .seealso: DMNetworkGetGlobalVertexIndex() 267822bbedd7SHong Zhang @*/ 267922bbedd7SHong Zhang PetscErrorCode DMNetworkSetVertexLocalToGlobalOrdering(DM dm) 268022bbedd7SHong Zhang { 268122bbedd7SHong Zhang PetscErrorCode ierr; 268222bbedd7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 268322bbedd7SHong Zhang MPI_Comm comm; 26842bf73ac6SHong Zhang PetscMPIInt rank,size,*displs=NULL,*recvcounts=NULL,remoterank; 268522bbedd7SHong Zhang PetscBool ghost; 268663029d29SHong Zhang PetscInt *vltog,nroots,nleaves,i,*vrange,k,N,lidx; 268722bbedd7SHong Zhang const PetscSFNode *iremote; 268822bbedd7SHong Zhang PetscSF vsf; 268963029d29SHong Zhang Vec Vleaves,Vleaves_seq; 269063029d29SHong Zhang VecScatter ctx; 269163029d29SHong Zhang PetscScalar *varr,val; 269263029d29SHong Zhang const PetscScalar *varr_read; 269322bbedd7SHong Zhang 269422bbedd7SHong Zhang PetscFunctionBegin; 269522bbedd7SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 2696ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 2697ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 269822bbedd7SHong Zhang 269922bbedd7SHong Zhang if (size == 1) { 270022bbedd7SHong Zhang nroots = network->vEnd - network->vStart; 270122bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 270222bbedd7SHong Zhang for (i=0; i<nroots; i++) vltog[i] = i; 270322bbedd7SHong Zhang network->vltog = vltog; 270422bbedd7SHong Zhang PetscFunctionReturn(0); 270522bbedd7SHong Zhang } 270622bbedd7SHong Zhang 270722bbedd7SHong Zhang if (!network->distributecalled) SETERRQ(comm, PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkDistribute() first"); 270822bbedd7SHong Zhang if (network->vltog) { 270922bbedd7SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 271022bbedd7SHong Zhang } 271122bbedd7SHong Zhang 271222bbedd7SHong Zhang ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 271322bbedd7SHong Zhang ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 271422bbedd7SHong Zhang vsf = network->vertex.sf; 271522bbedd7SHong Zhang 27162bf73ac6SHong Zhang ierr = PetscMalloc3(size+1,&vrange,size,&displs,size,&recvcounts);CHKERRQ(ierr); 2717f5427c60SHong Zhang ierr = PetscSFGetGraph(vsf,&nroots,&nleaves,NULL,&iremote);CHKERRQ(ierr); 271822bbedd7SHong Zhang 271922bbedd7SHong Zhang for (i=0; i<size; i++) { displs[i] = i; recvcounts[i] = 1;} 272022bbedd7SHong Zhang 272122bbedd7SHong Zhang i = nroots - nleaves; /* local number of vertices, excluding ghosts */ 272222bbedd7SHong Zhang vrange[0] = 0; 2723ffc4695bSBarry Smith ierr = MPI_Allgatherv(&i,1,MPIU_INT,vrange+1,recvcounts,displs,MPIU_INT,comm);CHKERRMPI(ierr); 272467dd800bSHong Zhang for (i=2; i<size+1; i++) {vrange[i] += vrange[i-1];} 272522bbedd7SHong Zhang 272622bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 272722bbedd7SHong Zhang network->vltog = vltog; 272822bbedd7SHong Zhang 272963029d29SHong Zhang /* Set vltog for non-ghost vertices */ 273063029d29SHong Zhang k = 0; 273122bbedd7SHong Zhang for (i=0; i<nroots; i++) { 273222bbedd7SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 273363029d29SHong Zhang if (ghost) continue; 273463029d29SHong Zhang vltog[i] = vrange[rank] + k++; 273522bbedd7SHong Zhang } 2736f5427c60SHong Zhang ierr = PetscFree3(vrange,displs,recvcounts);CHKERRQ(ierr); 273763029d29SHong Zhang 273863029d29SHong Zhang /* Set vltog for ghost vertices */ 273963029d29SHong Zhang /* (a) create parallel Vleaves and sequential Vleaves_seq to convert local iremote[*].index to global index */ 274063029d29SHong Zhang ierr = VecCreate(comm,&Vleaves);CHKERRQ(ierr); 274163029d29SHong Zhang ierr = VecSetSizes(Vleaves,2*nleaves,PETSC_DETERMINE);CHKERRQ(ierr); 274263029d29SHong Zhang ierr = VecSetFromOptions(Vleaves);CHKERRQ(ierr); 274363029d29SHong Zhang ierr = VecGetArray(Vleaves,&varr);CHKERRQ(ierr); 274463029d29SHong Zhang for (i=0; i<nleaves; i++) { 274563029d29SHong Zhang varr[2*i] = (PetscScalar)(iremote[i].rank); /* rank of remote process */ 274663029d29SHong Zhang varr[2*i+1] = (PetscScalar)(iremote[i].index); /* local index in remote process */ 274763029d29SHong Zhang } 274863029d29SHong Zhang ierr = VecRestoreArray(Vleaves,&varr);CHKERRQ(ierr); 274963029d29SHong Zhang 275063029d29SHong Zhang /* (b) scatter local info to remote processes via VecScatter() */ 275163029d29SHong Zhang ierr = VecScatterCreateToAll(Vleaves,&ctx,&Vleaves_seq);CHKERRQ(ierr); 275263029d29SHong Zhang ierr = VecScatterBegin(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 275363029d29SHong Zhang ierr = VecScatterEnd(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 275463029d29SHong Zhang 275563029d29SHong Zhang /* (c) convert local indices to global indices in parallel vector Vleaves */ 275663029d29SHong Zhang ierr = VecGetSize(Vleaves_seq,&N);CHKERRQ(ierr); 275763029d29SHong Zhang ierr = VecGetArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 275863029d29SHong Zhang for (i=0; i<N; i+=2) { 27592e4cff2eSHong Zhang remoterank = (PetscMPIInt)PetscRealPart(varr_read[i]); 276063029d29SHong Zhang if (remoterank == rank) { 276163029d29SHong Zhang k = i+1; /* row number */ 27622e4cff2eSHong Zhang lidx = (PetscInt)PetscRealPart(varr_read[i+1]); 276363029d29SHong Zhang val = (PetscScalar)vltog[lidx]; /* global index for non-ghost vertex computed above */ 276463029d29SHong Zhang ierr = VecSetValues(Vleaves,1,&k,&val,INSERT_VALUES);CHKERRQ(ierr); 276563029d29SHong Zhang } 276663029d29SHong Zhang } 276763029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 276863029d29SHong Zhang ierr = VecAssemblyBegin(Vleaves);CHKERRQ(ierr); 276963029d29SHong Zhang ierr = VecAssemblyEnd(Vleaves);CHKERRQ(ierr); 277063029d29SHong Zhang 277163029d29SHong Zhang /* (d) Set vltog for ghost vertices by copying local values of Vleaves */ 277263029d29SHong Zhang ierr = VecGetArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 277363029d29SHong Zhang k = 0; 277463029d29SHong Zhang for (i=0; i<nroots; i++) { 277563029d29SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 277663029d29SHong Zhang if (!ghost) continue; 27772e4cff2eSHong Zhang vltog[i] = (PetscInt)PetscRealPart(varr_read[2*k+1]); k++; 277863029d29SHong Zhang } 277963029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 278063029d29SHong Zhang 278163029d29SHong Zhang ierr = VecDestroy(&Vleaves);CHKERRQ(ierr); 278263029d29SHong Zhang ierr = VecDestroy(&Vleaves_seq);CHKERRQ(ierr); 278363029d29SHong Zhang ierr = VecScatterDestroy(&ctx);CHKERRQ(ierr); 278422bbedd7SHong Zhang PetscFunctionReturn(0); 278522bbedd7SHong Zhang } 2786