1af0996ceSBarry Smith #include <petsc/private/dmnetworkimpl.h> /*I "petscdmnetwork.h" I*/ 25f2c45f1SShri Abhyankar 3*54dfd506SHong Zhang /* 4*54dfd506SHong Zhang Creates the component header and value objects for a network point 5*54dfd506SHong Zhang */ 6*54dfd506SHong Zhang static PetscErrorCode SetUpNetworkHeaderComponentValue(DM dm,DMNetworkComponentHeader header,DMNetworkComponentValue cvalue) 7*54dfd506SHong Zhang { 8*54dfd506SHong Zhang PetscErrorCode ierr; 9*54dfd506SHong Zhang 10*54dfd506SHong Zhang PetscFunctionBegin; 11*54dfd506SHong Zhang /* Allocate arrays for component information */ 12*54dfd506SHong Zhang ierr = PetscCalloc5(header->maxcomps,&header->size,header->maxcomps,&header->key,header->maxcomps,&header->offset,header->maxcomps,&header->nvar,header->maxcomps,&header->offsetvarrel);CHKERRQ(ierr); 13*54dfd506SHong Zhang ierr = PetscCalloc1(header->maxcomps,&cvalue->data);CHKERRQ(ierr); 14*54dfd506SHong Zhang 15*54dfd506SHong Zhang /* The size of the header is the size of struct _p_DMNetworkComponentHeader. Since the struct contains PetscInt pointers we cannot use sizeof(struct). So, we need to explicitly calculate the size. 16*54dfd506SHong Zhang If the data header struct changes then this header size calculation needs to be updated. */ 17*54dfd506SHong Zhang header->hsize = sizeof(struct _p_DMNetworkComponentHeader) + 5*header->maxcomps*sizeof(PetscInt); 18*54dfd506SHong Zhang header->hsize /= sizeof(DMNetworkComponentGenericDataType); 19*54dfd506SHong Zhang PetscFunctionReturn(0); 20*54dfd506SHong Zhang } 21*54dfd506SHong Zhang 225f2c45f1SShri Abhyankar /*@ 23556ed216SShri Abhyankar DMNetworkGetPlex - Gets the Plex DM associated with this network DM 24556ed216SShri Abhyankar 25556ed216SShri Abhyankar Not collective 26556ed216SShri Abhyankar 27556ed216SShri Abhyankar Input Parameters: 282bf73ac6SHong Zhang . dm - the dm object 292bf73ac6SHong Zhang 302bf73ac6SHong Zhang Output Parameters: 312bf73ac6SHong Zhang . plexdm - the plex dm object 32556ed216SShri Abhyankar 33556ed216SShri Abhyankar Level: Advanced 34556ed216SShri Abhyankar 35556ed216SShri Abhyankar .seealso: DMNetworkCreate() 36556ed216SShri Abhyankar @*/ 372bf73ac6SHong Zhang PetscErrorCode DMNetworkGetPlex(DM dm,DM *plexdm) 38556ed216SShri Abhyankar { 392bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 40556ed216SShri Abhyankar 41556ed216SShri Abhyankar PetscFunctionBegin; 42556ed216SShri Abhyankar *plexdm = network->plex; 43556ed216SShri Abhyankar PetscFunctionReturn(0); 44556ed216SShri Abhyankar } 45556ed216SShri Abhyankar 46556ed216SShri Abhyankar /*@ 472bf73ac6SHong Zhang DMNetworkGetNumSubNetworks - Gets the the number of subnetworks 4872c3e9f7SHong Zhang 492bf73ac6SHong Zhang Not collective 5072c3e9f7SHong Zhang 5172c3e9f7SHong Zhang Input Parameters: 522bf73ac6SHong Zhang . dm - the dm object 532bf73ac6SHong Zhang 542bf73ac6SHong Zhang Output Parameters: 552bf73ac6SHong Zhang + nsubnet - local number of subnetworks 562bf73ac6SHong Zhang - Nsubnet - global number of subnetworks 5772c3e9f7SHong Zhang 5897bb938eSShri Abhyankar Level: beginner 5972c3e9f7SHong Zhang 602bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkSetNumSubNetworks() 6172c3e9f7SHong Zhang @*/ 622bf73ac6SHong Zhang PetscErrorCode DMNetworkGetNumSubNetworks(DM dm,PetscInt *nsubnet,PetscInt *Nsubnet) 6372c3e9f7SHong Zhang { 642bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 6572c3e9f7SHong Zhang 6672c3e9f7SHong Zhang PetscFunctionBegin; 672bf73ac6SHong Zhang if (nsubnet) *nsubnet = network->nsubnet; 682bf73ac6SHong Zhang if (Nsubnet) *Nsubnet = network->Nsubnet; 6972c3e9f7SHong Zhang PetscFunctionReturn(0); 7072c3e9f7SHong Zhang } 7172c3e9f7SHong Zhang 7272c3e9f7SHong Zhang /*@ 732bf73ac6SHong Zhang DMNetworkSetNumSubNetworks - Sets the number of subnetworks 745f2c45f1SShri Abhyankar 75d083f849SBarry Smith Collective on dm 765f2c45f1SShri Abhyankar 775f2c45f1SShri Abhyankar Input Parameters: 785f2c45f1SShri Abhyankar + dm - the dm object 792bf73ac6SHong Zhang . nsubnet - local number of subnetworks 802bf73ac6SHong Zhang - Nsubnet - global number of subnetworks 815f2c45f1SShri Abhyankar 8297bb938eSShri Abhyankar Level: beginner 831b266c99SBarry Smith 842bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkGetNumSubNetworks() 855f2c45f1SShri Abhyankar @*/ 862bf73ac6SHong Zhang PetscErrorCode DMNetworkSetNumSubNetworks(DM dm,PetscInt nsubnet,PetscInt Nsubnet) 875f2c45f1SShri Abhyankar { 885f2c45f1SShri Abhyankar PetscErrorCode ierr; 895f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 905f2c45f1SShri Abhyankar 915f2c45f1SShri Abhyankar PetscFunctionBegin; 922bf73ac6SHong Zhang if (network->Nsubnet != 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Network sizes alread set, cannot resize the network"); 932bf73ac6SHong Zhang 945f2c45f1SShri Abhyankar PetscValidHeaderSpecific(dm,DM_CLASSID,1); 952bf73ac6SHong Zhang PetscValidLogicalCollectiveInt(dm,nsubnet,2); 962bf73ac6SHong Zhang PetscValidLogicalCollectiveInt(dm,Nsubnet,3); 977765340cSHong Zhang 982bf73ac6SHong Zhang if (Nsubnet == PETSC_DECIDE) { 992bf73ac6SHong Zhang if (nsubnet < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of local subnetworks %D cannot be less than 0",nsubnet); 100820f2d46SBarry Smith ierr = MPIU_Allreduce(&nsubnet,&Nsubnet,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 101caf410d2SHong Zhang } 1022bf73ac6SHong Zhang if (Nsubnet < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Number of global subnetworks %D cannot be less than 1",Nsubnet); 103caf410d2SHong Zhang 1042bf73ac6SHong Zhang network->Nsubnet = Nsubnet; 1052bf73ac6SHong Zhang network->nsubnet = 0; /* initia value; will be determind by DMNetworkAddSubnetwork() */ 1062bf73ac6SHong Zhang ierr = PetscCalloc1(Nsubnet,&network->subnet);CHKERRQ(ierr); 107caf410d2SHong Zhang 1082bf73ac6SHong Zhang /* num of shared vertices */ 1092bf73ac6SHong Zhang network->nsvtx = 0; 1102bf73ac6SHong Zhang network->Nsvtx = 0; 1117765340cSHong Zhang PetscFunctionReturn(0); 1127765340cSHong Zhang } 1137765340cSHong Zhang 1145f2c45f1SShri Abhyankar /*@ 1152bf73ac6SHong Zhang DMNetworkAddSubnetwork - Add a subnetwork 1165f2c45f1SShri Abhyankar 1172bf73ac6SHong Zhang Collective on dm 1185f2c45f1SShri Abhyankar 1195f2c45f1SShri Abhyankar Input Parameters: 120e3e68989SHong Zhang + dm - the dm object 1212bf73ac6SHong Zhang . name - name of the subnetwork 1222bf73ac6SHong Zhang . nv - number of local vertices of this subnetwork 1232bf73ac6SHong Zhang . ne - number of local edges of this subnetwork 1242bf73ac6SHong Zhang - edgelist - list of edges for this subnetwork 1252bf73ac6SHong Zhang 1262bf73ac6SHong Zhang Output Parameters: 1272bf73ac6SHong Zhang . netnum - global index of the subnetwork 1285f2c45f1SShri Abhyankar 1295f2c45f1SShri Abhyankar Notes: 1305f2c45f1SShri Abhyankar There is no copy involved in this operation, only the pointer is referenced. The edgelist should 1312bf73ac6SHong Zhang not be destroyed before the call to DMNetworkLayoutSetUp() 1325f2c45f1SShri Abhyankar 13397bb938eSShri Abhyankar Level: beginner 1345f2c45f1SShri Abhyankar 135e3e68989SHong Zhang Example usage: 1362bf73ac6SHong Zhang Consider the following network: 137e3e68989SHong Zhang .vb 138e3e68989SHong Zhang network 1: v1 -> v2 -> v0 139e3e68989SHong Zhang .ve 140e3e68989SHong Zhang 141e3e68989SHong Zhang The resulting input 1422bf73ac6SHong Zhang edgelist = [1 2 | 2 0] 143e3e68989SHong Zhang 1442bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkSetNumSubnetworks() 1455f2c45f1SShri Abhyankar @*/ 1462bf73ac6SHong Zhang PetscErrorCode DMNetworkAddSubnetwork(DM dm,const char* name,PetscInt nv,PetscInt ne,PetscInt edgelist[],PetscInt *netnum) 1475f2c45f1SShri Abhyankar { 1482bf73ac6SHong Zhang PetscErrorCode ierr; 1495f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 1502bf73ac6SHong Zhang PetscInt i = network->nsubnet,a[2],b[2]; 1515f2c45f1SShri Abhyankar 1525f2c45f1SShri Abhyankar PetscFunctionBegin; 1532bf73ac6SHong Zhang if (name) { 1542bf73ac6SHong Zhang ierr = PetscStrcpy(network->subnet[i].name,name);CHKERRQ(ierr); 155e3e68989SHong Zhang } 1562bf73ac6SHong Zhang 1572bf73ac6SHong Zhang network->subnet[i].nvtx = nv; 1582bf73ac6SHong Zhang network->subnet[i].nedge = ne; 1592bf73ac6SHong Zhang network->subnet[i].edgelist = edgelist; 1602bf73ac6SHong Zhang 1612bf73ac6SHong Zhang /* Get global number of vertices and edges for subnet[i] */ 1622bf73ac6SHong Zhang a[0] = nv; a[1] = ne; 163820f2d46SBarry Smith ierr = MPIU_Allreduce(a,b,2,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 1642bf73ac6SHong Zhang network->subnet[i].Nvtx = b[0]; 1652bf73ac6SHong Zhang network->subnet[i].Nedge = b[1]; 1662bf73ac6SHong Zhang 1672bf73ac6SHong Zhang /* ---------------------------------------------------------- 1682bf73ac6SHong Zhang p=v or e; 1692bf73ac6SHong Zhang subnet[0].pStart = 0 1702bf73ac6SHong Zhang subnet[i+1].pStart = subnet[i].pEnd = subnet[i].pStart + (nE[i] or NV[i]) 1712bf73ac6SHong Zhang ----------------------------------------------------------------------- */ 1722bf73ac6SHong Zhang /* GLOBAL subnet[].vStart and vEnd, used by DMNetworkLayoutSetUp() */ 1732bf73ac6SHong Zhang network->subnet[i].vStart = network->NVertices; 1742bf73ac6SHong Zhang network->subnet[i].vEnd = network->subnet[i].vStart + network->subnet[i].Nvtx; /* global vEnd of subnet[i] */ 1752bf73ac6SHong Zhang 1762bf73ac6SHong Zhang network->nVertices += nv; 1772bf73ac6SHong Zhang network->NVertices += network->subnet[i].Nvtx; 1782bf73ac6SHong Zhang 1792bf73ac6SHong Zhang /* LOCAL subnet[].eStart and eEnd, used by DMNetworkLayoutSetUp() */ 1802bf73ac6SHong Zhang network->subnet[i].eStart = network->nEdges; 1812bf73ac6SHong Zhang network->subnet[i].eEnd = network->subnet[i].eStart + ne; 1822bf73ac6SHong Zhang network->nEdges += ne; 1832bf73ac6SHong Zhang network->NEdges += network->subnet[i].Nedge; 1842bf73ac6SHong Zhang 1852bf73ac6SHong Zhang ierr = PetscStrcpy(network->subnet[i].name,name);CHKERRQ(ierr); 1862bf73ac6SHong Zhang if (netnum) *netnum = network->nsubnet; 1872bf73ac6SHong Zhang network->nsubnet++; 1882bf73ac6SHong Zhang PetscFunctionReturn(0); 1892bf73ac6SHong Zhang } 1902bf73ac6SHong Zhang 1912bf73ac6SHong Zhang /* 1922bf73ac6SHong Zhang SetUp a single svtx struct. See SVtx defined in dmnetworkimpl.h 1932bf73ac6SHong Zhang Set gidx and type if input v=(net,idx) is a from_vertex; 1942bf73ac6SHong Zhang Get gid, type and index in the svtx array if input v=(net,idx) is a to_vertex. 1952bf73ac6SHong Zhang 1962bf73ac6SHong Zhang Input: Nsvtx, svtx, net, idx, gidx 1972bf73ac6SHong Zhang Output: gidx, svtype, svtx_idx 1982bf73ac6SHong Zhang */ 1992bf73ac6SHong Zhang static PetscErrorCode SVtxSetUp(PetscInt Nsvtx,SVtx *svtx,PetscInt net,PetscInt idx,PetscInt *gidx,SVtxType *svtype,PetscInt *svtx_idx) 2002bf73ac6SHong Zhang { 2012bf73ac6SHong Zhang PetscInt i,j,*svto; 2022bf73ac6SHong Zhang SVtxType vtype; 2032bf73ac6SHong Zhang 2042bf73ac6SHong Zhang PetscFunctionBegin; 2052bf73ac6SHong Zhang if (!Nsvtx) PetscFunctionReturn(0); 2062bf73ac6SHong Zhang 2072bf73ac6SHong Zhang vtype = SVNONE; 2082bf73ac6SHong Zhang for (i=0; i<Nsvtx; i++) { 2092bf73ac6SHong Zhang if (net == svtx[i].sv[0] && idx == svtx[i].sv[1]) { 2102bf73ac6SHong Zhang /* (1) input vertex net.idx is a shared from_vertex, set its global index and output its svtype */ 2112bf73ac6SHong Zhang svtx[i].gidx = *gidx; /* set gidx */ 2122bf73ac6SHong Zhang vtype = SVFROM; 2132bf73ac6SHong Zhang } else { /* loop over svtx[i].n */ 2142bf73ac6SHong Zhang for (j=1; j<svtx[i].n; j++) { 2152bf73ac6SHong Zhang svto = svtx[i].sv + 2*j; 2162bf73ac6SHong Zhang if (net == svto[0] && idx == svto[1]) { 2172bf73ac6SHong Zhang /* input vertex net.idx is a shared to_vertex, output its global index and its svtype */ 2182bf73ac6SHong Zhang *gidx = svtx[i].gidx; /* output gidx for to_vertex */ 2192bf73ac6SHong Zhang vtype = SVTO; 2202bf73ac6SHong Zhang } 2212bf73ac6SHong Zhang } 2222bf73ac6SHong Zhang } 2232bf73ac6SHong Zhang if (vtype != SVNONE) break; 2242bf73ac6SHong Zhang } 2252bf73ac6SHong Zhang if (svtype) *svtype = vtype; 2262bf73ac6SHong Zhang if (svtx_idx) *svtx_idx = i; 2272bf73ac6SHong Zhang PetscFunctionReturn(0); 2282bf73ac6SHong Zhang } 2292bf73ac6SHong Zhang 2302bf73ac6SHong Zhang /* 2312bf73ac6SHong Zhang Add a new shared vertex sv=(net,idx) to table svtas[ita] 2322bf73ac6SHong Zhang */ 2332bf73ac6SHong Zhang static PetscErrorCode TableAddSVtx(PetscTable *svtas,PetscInt ita,PetscInt* tdata,PetscInt *sv_wk,PetscInt *ii,PetscInt *sedgelist,PetscInt k,DM_Network *network,PetscInt **ta2sv) 2342bf73ac6SHong Zhang { 2352bf73ac6SHong Zhang PetscInt net,idx,gidx,i=*ii; 2362bf73ac6SHong Zhang PetscErrorCode ierr; 2372bf73ac6SHong Zhang 2382bf73ac6SHong Zhang PetscFunctionBegin; 2392bf73ac6SHong Zhang net = sv_wk[2*i] = sedgelist[k]; 2402bf73ac6SHong Zhang idx = sv_wk[2*i+1] = sedgelist[k+1]; 2412bf73ac6SHong Zhang gidx = network->subnet[net].vStart + idx; 2422bf73ac6SHong Zhang ierr = PetscTableAdd(svtas[ita],gidx+1,tdata[ita]+1,INSERT_VALUES);CHKERRQ(ierr); 2432bf73ac6SHong Zhang *(ta2sv[ita] + tdata[ita]) = i; /* maps tdata to index of sv_wk; sv_wk keeps (net,idx) info */ 2442bf73ac6SHong Zhang tdata[ita]++; (*ii)++; 2452bf73ac6SHong Zhang PetscFunctionReturn(0); 2462bf73ac6SHong Zhang } 2472bf73ac6SHong Zhang 2482bf73ac6SHong Zhang /* 2492bf73ac6SHong Zhang Create an array of shared vertices. See SVtx and SVtxType in dmnetworkimpl.h 2502bf73ac6SHong Zhang 2512bf73ac6SHong Zhang Input: dm, Nsedgelist, sedgelist 2522bf73ac6SHong Zhang Output: Nsvtx,svtx 2532bf73ac6SHong Zhang 2542bf73ac6SHong Zhang Note: Output svtx is organized as 2552bf73ac6SHong Zhang sv(net[0],idx[0]) --> sv(net[1],idx[1]) 2562bf73ac6SHong Zhang --> sv(net[1],idx[1]) 2572bf73ac6SHong Zhang ... 2582bf73ac6SHong Zhang --> sv(net[n-1],idx[n-1]) 2592bf73ac6SHong Zhang and net[0] < net[1] < ... < net[n-1] 2602bf73ac6SHong Zhang where sv[0] has SVFROM type, sv[i], i>0, has SVTO type. 2612bf73ac6SHong Zhang */ 2622bf73ac6SHong Zhang static PetscErrorCode SVtxCreate(DM dm,PetscInt Nsedgelist,PetscInt *sedgelist,PetscInt *Nsvtx,SVtx **svtx) 2632bf73ac6SHong Zhang { 2642bf73ac6SHong Zhang PetscErrorCode ierr; 2652bf73ac6SHong Zhang SVtx *sedges = NULL; 2662bf73ac6SHong Zhang PetscInt *sv,k,j,nsv,*tdata,**ta2sv; 2672bf73ac6SHong Zhang PetscTable *svtas; 2682bf73ac6SHong Zhang PetscInt gidx,net,idx,i,nta,ita,idx_from,idx_to,n,*sv_wk; 2692bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 2702bf73ac6SHong Zhang PetscTablePosition ppos; 2712bf73ac6SHong Zhang 2722bf73ac6SHong Zhang PetscFunctionBegin; 2732bf73ac6SHong Zhang /* (1) Crete ctables svtas */ 2742bf73ac6SHong Zhang ierr = PetscCalloc4(Nsedgelist,&svtas,Nsedgelist,&tdata,4*Nsedgelist,&sv_wk,2*Nsedgelist,&ta2sv);CHKERRQ(ierr); 2752bf73ac6SHong Zhang 2762bf73ac6SHong Zhang j = 0; /* sedgelist counter */ 2772bf73ac6SHong Zhang k = 0; /* sedgelist vertex counter j = 4*k */ 2782bf73ac6SHong Zhang i = 0; /* sv_wk (vertices added to the ctables) counter */ 2792bf73ac6SHong Zhang nta = 0; /* num of sv tables created */ 2802bf73ac6SHong Zhang 2812bf73ac6SHong Zhang /* for j=0 */ 2822bf73ac6SHong Zhang ierr = PetscTableCreate(2*Nsedgelist,network->NVertices+1,&svtas[nta]);CHKERRQ(ierr); 2832bf73ac6SHong Zhang ierr = PetscMalloc1(2*Nsedgelist,&ta2sv[nta]);CHKERRQ(ierr); 2842bf73ac6SHong Zhang 2852bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,nta,tdata,sv_wk,&i,sedgelist,k,network,ta2sv);CHKERRQ(ierr); 2862bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,nta,tdata,sv_wk,&i,sedgelist,k+2,network,ta2sv);CHKERRQ(ierr); 2872bf73ac6SHong Zhang nta++; k += 4; 2882bf73ac6SHong Zhang 2892bf73ac6SHong Zhang for (j = 1; j < Nsedgelist; j++) { 2902bf73ac6SHong Zhang for (ita = 0; ita < nta; ita++) { 2912bf73ac6SHong Zhang /* vfrom */ 2922bf73ac6SHong Zhang net = sedgelist[k]; idx = sedgelist[k+1]; 2932bf73ac6SHong Zhang gidx = network->subnet[net].vStart + idx; /* global index of the vertex net.idx before merging shared vertices */ 2942bf73ac6SHong Zhang ierr = PetscTableFind(svtas[ita],gidx+1,&idx_from);CHKERRQ(ierr); 2952bf73ac6SHong Zhang 2962bf73ac6SHong Zhang /* vto */ 2972bf73ac6SHong Zhang net = sedgelist[k+2]; idx = sedgelist[k+3]; 2982bf73ac6SHong Zhang gidx = network->subnet[net].vStart + idx; 2992bf73ac6SHong Zhang ierr = PetscTableFind(svtas[ita],gidx+1,&idx_to);CHKERRQ(ierr); 3002bf73ac6SHong Zhang 3012bf73ac6SHong Zhang if (idx_from || idx_to) { /* vfrom or vto is on table svtas[ita] */ 3022bf73ac6SHong Zhang idx_from--; idx_to--; 3032bf73ac6SHong Zhang if (idx_from < 0) { /* vto is on svtas[ita] */ 3042bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,ita,tdata,sv_wk,&i,sedgelist,k,network,ta2sv);CHKERRQ(ierr); 3052bf73ac6SHong Zhang break; 3062bf73ac6SHong Zhang } else if (idx_to < 0) { 3072bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,ita,tdata,sv_wk,&i,sedgelist,k+2,network,ta2sv);CHKERRQ(ierr); 3082bf73ac6SHong Zhang break; 3092bf73ac6SHong Zhang } 3102bf73ac6SHong Zhang } 3112bf73ac6SHong Zhang } 3122bf73ac6SHong Zhang 3132bf73ac6SHong Zhang if (ita == nta) { 3142bf73ac6SHong Zhang ierr = PetscTableCreate(2*Nsedgelist,network->NVertices+1,&svtas[nta]);CHKERRQ(ierr); 3152bf73ac6SHong Zhang ierr = PetscMalloc1(2*Nsedgelist, &ta2sv[nta]);CHKERRQ(ierr); 3162bf73ac6SHong Zhang 3172bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,nta,tdata,sv_wk,&i,sedgelist,k,network,ta2sv);CHKERRQ(ierr); 3182bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,nta,tdata,sv_wk,&i,sedgelist,k+2,network,ta2sv);CHKERRQ(ierr); 3192bf73ac6SHong Zhang nta++; 3202bf73ac6SHong Zhang } 3212bf73ac6SHong Zhang k += 4; 3222bf73ac6SHong Zhang } 3232bf73ac6SHong Zhang 3242bf73ac6SHong Zhang /* (2) Construct sedges from ctable 3252bf73ac6SHong Zhang sedges: edges connect vertex sv[0]=(net[0],idx[0]) to vertices sv[k], k=1,...,n-1; 3264f5c2772SJose E. Roman net[k], k=0, ...,n-1, are in ascending order */ 3272bf73ac6SHong Zhang ierr = PetscMalloc1(nta,&sedges);CHKERRQ(ierr); 3282bf73ac6SHong Zhang for (nsv = 0; nsv < nta; nsv++) { 3294f5c2772SJose E. Roman /* for a single svtx, put shared vertices in ascending order of gidx */ 3304f5c2772SJose E. Roman ierr = PetscTableGetCount(svtas[nsv],&n);CHKERRQ(ierr); 3312bf73ac6SHong Zhang ierr = PetscCalloc1(2*n,&sv);CHKERRQ(ierr); 3322bf73ac6SHong Zhang sedges[nsv].sv = sv; 3332bf73ac6SHong Zhang sedges[nsv].n = n; 3342bf73ac6SHong Zhang sedges[nsv].gidx = -1; /* initialization */ 3352bf73ac6SHong Zhang 3362bf73ac6SHong Zhang ierr = PetscTableGetHeadPosition(svtas[nsv],&ppos);CHKERRQ(ierr); 3374f5c2772SJose E. Roman for (k=0; k<n; k++) { /* gidx is sorted in ascending order */ 3382bf73ac6SHong Zhang ierr = PetscTableGetNext(svtas[nsv],&ppos,&gidx,&i);CHKERRQ(ierr); 3392bf73ac6SHong Zhang gidx--; i--; 3402bf73ac6SHong Zhang 3412bf73ac6SHong Zhang j = ta2sv[nsv][i]; /* maps i to index of sv_wk */ 3422bf73ac6SHong Zhang sv[2*k] = sv_wk[2*j]; 3432bf73ac6SHong Zhang sv[2*k+1] = sv_wk[2*j + 1]; 3442bf73ac6SHong Zhang } 3452bf73ac6SHong Zhang } 3462bf73ac6SHong Zhang 3472bf73ac6SHong Zhang for (j=0; j<nta; j++) { 3482bf73ac6SHong Zhang ierr = PetscTableDestroy(&svtas[j]);CHKERRQ(ierr); 3492bf73ac6SHong Zhang ierr = PetscFree(ta2sv[j]);CHKERRQ(ierr); 3502bf73ac6SHong Zhang } 3512bf73ac6SHong Zhang ierr = PetscFree4(svtas,tdata,sv_wk,ta2sv);CHKERRQ(ierr); 3522bf73ac6SHong Zhang 3532bf73ac6SHong Zhang *Nsvtx = nta; 3542bf73ac6SHong Zhang *svtx = sedges; 3552bf73ac6SHong Zhang PetscFunctionReturn(0); 3562bf73ac6SHong Zhang } 3572bf73ac6SHong Zhang 3582bf73ac6SHong Zhang static PetscErrorCode DMNetworkLayoutSetUp_Coupling(DM dm) 3592bf73ac6SHong Zhang { 3602bf73ac6SHong Zhang PetscErrorCode ierr; 3612bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 3622bf73ac6SHong Zhang PetscInt i,j,ctr,np,*edges,*subnetvtx,vStart; 3632bf73ac6SHong Zhang PetscInt k,*vidxlTog,Nsv=0,Nsubnet=network->Nsubnet; 3642bf73ac6SHong Zhang PetscInt *sedgelist=network->sedgelist; 3652bf73ac6SHong Zhang const PetscInt *cone; 3662bf73ac6SHong Zhang MPI_Comm comm; 3672bf73ac6SHong Zhang PetscMPIInt size,rank,*recvcounts=NULL,*displs=NULL; 3682bf73ac6SHong Zhang PetscInt net,idx,gidx,nmerged,e,v,vfrom,vto,*vrange,*eowners,gidx_from,net_from,sv_idx; 3692bf73ac6SHong Zhang SVtxType svtype = SVNONE; 3702bf73ac6SHong Zhang SVtx *svtx=NULL; 3712bf73ac6SHong Zhang PetscSection sectiong; 3722bf73ac6SHong Zhang 3732bf73ac6SHong Zhang PetscFunctionBegin; 3742bf73ac6SHong Zhang /* This implementation requires user input each subnet by a single processor, thus subnet[net].nvtx=subnet[net].Nvtx */ 3752bf73ac6SHong Zhang for (net=0; net<Nsubnet; net++) { 3762bf73ac6SHong 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); 3772bf73ac6SHong Zhang } 3782bf73ac6SHong Zhang 3792bf73ac6SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 38055b25c41SPierre Jolivet ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 38155b25c41SPierre Jolivet ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 3822bf73ac6SHong Zhang 3832bf73ac6SHong Zhang /* (1) Create svtx[] from sedgelist */ 3842bf73ac6SHong Zhang /* -------------------------------- */ 3852bf73ac6SHong Zhang /* Nsv: global number of SVtx; svtx: shared vertices, see SVtx in dmnetworkimpl.h */ 3862bf73ac6SHong Zhang ierr = SVtxCreate(dm,network->Nsvtx,sedgelist,&Nsv,&svtx);CHKERRQ(ierr); 3872bf73ac6SHong Zhang 3882bf73ac6SHong Zhang /* (2) Setup svtx; Shared vto vertices are merged to their vfrom vertex with same global vetex index (gidx) */ 3892bf73ac6SHong Zhang /* -------------------------------------------------------------------------------------------------------- */ 3902bf73ac6SHong Zhang /* (2.1) compute vrage[rank]: global index of 1st local vertex in proc[rank] */ 3912bf73ac6SHong Zhang ierr = PetscMalloc3(size+1,&vrange,size,&displs,size,&recvcounts);CHKERRQ(ierr); 3922bf73ac6SHong Zhang for (i=0; i<size; i++) {displs[i] = i; recvcounts[i] = 1;} 3932bf73ac6SHong Zhang 3942bf73ac6SHong Zhang vrange[0] = 0; 3952bf73ac6SHong Zhang ierr = MPI_Allgatherv(&network->nVertices,1,MPIU_INT,vrange+1,recvcounts,displs,MPIU_INT,comm);CHKERRMPI(ierr); 3962bf73ac6SHong Zhang for (i=2; i<size+1; i++) { 3972bf73ac6SHong Zhang vrange[i] += vrange[i-1]; 3982bf73ac6SHong Zhang } 3992bf73ac6SHong Zhang 4002bf73ac6SHong Zhang /* (2.2) Create vidxlTog: maps UN-MERGED local vertex index i to global index gidx (plex, excluding ghost vertices) */ 4012bf73ac6SHong Zhang ierr = PetscMalloc1(network->nVertices,&vidxlTog);CHKERRQ(ierr); 4022bf73ac6SHong Zhang i = 0; gidx = 0; 4032bf73ac6SHong Zhang nmerged = 0; /* local num of merged vertices */ 4042bf73ac6SHong Zhang network->nsvtx = 0; 4052bf73ac6SHong Zhang for (net=0; net<Nsubnet; net++) { 4062bf73ac6SHong Zhang for (idx=0; idx<network->subnet[net].Nvtx; idx++) { 4072bf73ac6SHong Zhang gidx_from = gidx; 4082bf73ac6SHong Zhang sv_idx = -1; 4092bf73ac6SHong Zhang 4102bf73ac6SHong Zhang ierr = SVtxSetUp(Nsv,svtx,net,idx,&gidx_from,&svtype,&sv_idx);CHKERRQ(ierr); 4112bf73ac6SHong Zhang if (svtype == SVTO) { 4122bf73ac6SHong Zhang if (network->subnet[net].nvtx) {/* this proc owns sv_to */ 4132bf73ac6SHong Zhang net_from = svtx[sv_idx].sv[0]; /* subnet num of its shared vertex */ 4142bf73ac6SHong Zhang if (network->subnet[net_from].nvtx == 0) { 4152bf73ac6SHong Zhang /* this proc does not own v_from, thus a new local coupling vertex */ 4162bf73ac6SHong Zhang network->nsvtx++; 4172bf73ac6SHong Zhang } 4182bf73ac6SHong Zhang vidxlTog[i++] = gidx_from; 4192bf73ac6SHong Zhang nmerged++; /* a coupling vertex -- merged */ 4202bf73ac6SHong Zhang } 4212bf73ac6SHong Zhang } else { 4222bf73ac6SHong Zhang if (svtype == SVFROM) { 4232bf73ac6SHong Zhang if (network->subnet[net].nvtx) { 4242bf73ac6SHong Zhang /* this proc owns this v_from, a new local coupling vertex */ 4252bf73ac6SHong Zhang network->nsvtx++; 4262bf73ac6SHong Zhang } 4272bf73ac6SHong Zhang } 4282bf73ac6SHong Zhang if (network->subnet[net].nvtx) vidxlTog[i++] = gidx; 4292bf73ac6SHong Zhang gidx++; 4302bf73ac6SHong Zhang } 4312bf73ac6SHong Zhang } 4322bf73ac6SHong Zhang } 4332bf73ac6SHong Zhang #if defined(PETSC_USE_DEBUG) 4342bf73ac6SHong Zhang if (i != network->nVertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"%D != %D nVertices",i,network->nVertices); 4352bf73ac6SHong Zhang #endif 4362bf73ac6SHong Zhang 4372bf73ac6SHong Zhang /* (2.3) Setup svtable for querry shared vertices */ 4382bf73ac6SHong Zhang for (v=0; v<Nsv; v++) { 4392bf73ac6SHong Zhang gidx = svtx[v].gidx; 4402bf73ac6SHong Zhang ierr = PetscTableAdd(network->svtable,gidx+1,v+1,INSERT_VALUES);CHKERRQ(ierr); 4412bf73ac6SHong Zhang } 4422bf73ac6SHong Zhang 4432bf73ac6SHong Zhang /* (2.4) Shared vertices in the subnetworks are merged, update global NVertices: np = sum(local nmerged) */ 4442bf73ac6SHong Zhang ierr = MPI_Allreduce(&nmerged,&np,1,MPIU_INT,MPI_SUM,comm);CHKERRMPI(ierr); 4452bf73ac6SHong Zhang network->NVertices -= np; 4462bf73ac6SHong Zhang 4472bf73ac6SHong Zhang ierr = PetscCalloc1(2*network->nEdges,&edges);CHKERRQ(ierr); 4482bf73ac6SHong Zhang ierr = PetscCalloc1(network->nVertices+network->nsvtx,&network->subnetvtx);CHKERRQ(ierr); 4492bf73ac6SHong Zhang 4502bf73ac6SHong Zhang ctr = 0; 4512bf73ac6SHong Zhang for (net=0; net<Nsubnet; net++) { 4522bf73ac6SHong Zhang for (j = 0; j < network->subnet[net].nedge; j++) { 4532bf73ac6SHong Zhang /* vfrom: */ 4542bf73ac6SHong Zhang i = network->subnet[net].edgelist[2*j] + (network->subnet[net].vStart - vrange[rank]); 4552bf73ac6SHong Zhang edges[2*ctr] = vidxlTog[i]; 4562bf73ac6SHong Zhang 4572bf73ac6SHong Zhang /* vto */ 4582bf73ac6SHong Zhang i = network->subnet[net].edgelist[2*j+1] + (network->subnet[net].vStart - vrange[rank]); 4592bf73ac6SHong Zhang edges[2*ctr+1] = vidxlTog[i]; 4602bf73ac6SHong Zhang ctr++; 4612bf73ac6SHong Zhang } 4622bf73ac6SHong Zhang } 4632bf73ac6SHong Zhang ierr = PetscFree3(vrange,displs,recvcounts);CHKERRQ(ierr); 4642bf73ac6SHong Zhang ierr = PetscFree(vidxlTog);CHKERRQ(ierr); 4652bf73ac6SHong Zhang 4662bf73ac6SHong Zhang /* (3) Create network->plex */ 4672bf73ac6SHong Zhang ierr = DMCreate(comm,&network->plex);CHKERRQ(ierr); 4682bf73ac6SHong Zhang ierr = DMSetType(network->plex,DMPLEX);CHKERRQ(ierr); 4692bf73ac6SHong Zhang ierr = DMSetDimension(network->plex,1);CHKERRQ(ierr); 4702bf73ac6SHong Zhang if (size == 1) { 4712bf73ac6SHong Zhang ierr = DMPlexBuildFromCellList(network->plex,network->nEdges,network->nVertices-nmerged,2,edges);CHKERRQ(ierr); 4722bf73ac6SHong Zhang } else { 4732bf73ac6SHong Zhang ierr = DMPlexBuildFromCellListParallel(network->plex,network->nEdges,network->nVertices-nmerged,PETSC_DECIDE,2,edges,NULL);CHKERRQ(ierr); 4742bf73ac6SHong Zhang } 4752bf73ac6SHong Zhang 4762bf73ac6SHong Zhang ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr); 4772bf73ac6SHong Zhang ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr); 4782bf73ac6SHong Zhang ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr); 4792bf73ac6SHong Zhang vStart = network->vStart; 4802bf73ac6SHong Zhang 4812bf73ac6SHong Zhang ierr = PetscSectionCreate(comm,&network->DataSection);CHKERRQ(ierr); 4822bf73ac6SHong Zhang ierr = PetscSectionCreate(comm,&network->DofSection);CHKERRQ(ierr); 4832bf73ac6SHong Zhang ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr); 4842bf73ac6SHong Zhang ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr); 4852bf73ac6SHong Zhang 4862bf73ac6SHong Zhang np = network->pEnd - network->pStart; 4872bf73ac6SHong Zhang ierr = PetscCalloc2(np,&network->header,np,&network->cvalue);CHKERRQ(ierr); 488*54dfd506SHong Zhang for (i=0; i<np; i++) { 489*54dfd506SHong Zhang network->header[i].maxcomps = 1; 490*54dfd506SHong Zhang ierr = SetUpNetworkHeaderComponentValue(dm,&network->header[i],&network->cvalue[i]);CHKERRQ(ierr); 491*54dfd506SHong Zhang } 4922bf73ac6SHong Zhang 4932bf73ac6SHong Zhang /* (4) Create vidxlTog: maps MERGED plex local vertex index (including ghosts) to User's global vertex index (without merging shared vertices) */ 4942bf73ac6SHong Zhang np = network->vEnd - vStart; /* include ghost vertices */ 4952bf73ac6SHong Zhang ierr = PetscMalloc2(np,&vidxlTog,size+1,&eowners);CHKERRQ(ierr); 4962bf73ac6SHong Zhang 4972bf73ac6SHong Zhang ctr = 0; 4982bf73ac6SHong Zhang for (e=network->eStart; e<network->eEnd; e++) { 4992bf73ac6SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 5002bf73ac6SHong Zhang vidxlTog[cone[0] - vStart] = edges[2*ctr]; 5012bf73ac6SHong Zhang vidxlTog[cone[1] - vStart] = edges[2*ctr+1]; 5022bf73ac6SHong Zhang ctr++; 5032bf73ac6SHong Zhang } 5042bf73ac6SHong Zhang ierr = PetscFree(edges);CHKERRQ(ierr); 5052bf73ac6SHong Zhang 5062bf73ac6SHong Zhang /* (5) Create vertices and edges array for the subnetworks */ 5072bf73ac6SHong Zhang subnetvtx = network->subnetvtx; 5082bf73ac6SHong Zhang for (j=0; j < Nsubnet; j++) { 5092bf73ac6SHong Zhang ierr = PetscCalloc1(network->subnet[j].nedge,&network->subnet[j].edges);CHKERRQ(ierr); 5102bf73ac6SHong Zhang network->subnet[j].vertices = subnetvtx; 5112bf73ac6SHong Zhang subnetvtx += network->subnet[j].nvtx; 5122bf73ac6SHong Zhang } 5132bf73ac6SHong Zhang network->svertices = subnetvtx; 5142bf73ac6SHong Zhang 5152bf73ac6SHong Zhang /* Get edge ownership */ 5162bf73ac6SHong Zhang np = network->eEnd - network->eStart; /* num of local edges */ 5172bf73ac6SHong Zhang ierr = MPI_Allgather(&np,1,MPIU_INT,eowners+1,1,MPIU_INT,comm);CHKERRMPI(ierr); 5182bf73ac6SHong Zhang eowners[0] = 0; 5192bf73ac6SHong Zhang for (i=2; i<=size; i++) eowners[i] += eowners[i-1]; 5202bf73ac6SHong Zhang 5212bf73ac6SHong Zhang e = 0; 5222bf73ac6SHong Zhang for (i=0; i < Nsubnet; i++) { 5232bf73ac6SHong Zhang v = 0; 5242bf73ac6SHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 5252bf73ac6SHong Zhang 5262bf73ac6SHong Zhang /* edge e */ 5272bf73ac6SHong Zhang network->header[e].index = e + eowners[rank]; /* Global edge index */ 5282bf73ac6SHong Zhang network->header[e].subnetid = i; /* Subnetwork id */ 5292bf73ac6SHong Zhang network->subnet[i].edges[j] = e; 5302bf73ac6SHong Zhang network->header[e].ndata = 0; 5312bf73ac6SHong Zhang network->header[e].offset[0] = 0; 5322bf73ac6SHong Zhang network->header[e].offsetvarrel[0] = 0; 533*54dfd506SHong Zhang ierr = PetscSectionAddDof(network->DataSection,e,network->header[e].hsize);CHKERRQ(ierr); 5342bf73ac6SHong Zhang 5352bf73ac6SHong Zhang /* connected vertices */ 5362bf73ac6SHong Zhang ierr = DMPlexGetCone(network->plex,e,&cone);CHKERRQ(ierr); 5372bf73ac6SHong Zhang 5382bf73ac6SHong Zhang /* vertex cone[0] */ 5392bf73ac6SHong Zhang vfrom = network->subnet[i].edgelist[2*v]; 5402bf73ac6SHong Zhang network->header[cone[0]].index = vidxlTog[cone[0]-vStart]; /* Global vertex index */ 5412bf73ac6SHong Zhang network->header[cone[0]].subnetid = i; /* Subnetwork id */ 5422bf73ac6SHong Zhang network->subnet[i].vertices[vfrom] = cone[0]; /* user's subnet[].dix = petsc's v */ 5432bf73ac6SHong Zhang 5442bf73ac6SHong Zhang /* vertex cone[1] */ 5452bf73ac6SHong Zhang vto = network->subnet[i].edgelist[2*v+1]; 5462bf73ac6SHong Zhang network->header[cone[1]].index = vidxlTog[cone[1]-vStart]; /* Global vertex index */ 5472bf73ac6SHong Zhang network->header[cone[1]].subnetid = i; 5482bf73ac6SHong Zhang network->subnet[i].vertices[vto]= cone[1]; 5492bf73ac6SHong Zhang 5502bf73ac6SHong Zhang e++; v++; 5512bf73ac6SHong Zhang } 5522bf73ac6SHong Zhang } 5532bf73ac6SHong Zhang 5542bf73ac6SHong Zhang /* Set vertex array for the subnetworks */ 5552bf73ac6SHong Zhang k = 0; 5562bf73ac6SHong Zhang for (v=vStart; v<network->vEnd; v++) { /* local vertices, including ghosts */ 5572bf73ac6SHong Zhang network->header[v].ndata = 0; 5582bf73ac6SHong Zhang network->header[v].offset[0] = 0; 5592bf73ac6SHong Zhang network->header[v].offsetvarrel[0] = 0; 560*54dfd506SHong Zhang ierr = PetscSectionAddDof(network->DataSection,v,network->header[v].hsize);CHKERRQ(ierr); 5612bf73ac6SHong Zhang 5622bf73ac6SHong Zhang /* shared vertex */ 5632bf73ac6SHong Zhang ierr = PetscTableFind(network->svtable,vidxlTog[v-vStart]+1,&i);CHKERRQ(ierr); 5642bf73ac6SHong Zhang if (i) network->svertices[k++] = v; 5652bf73ac6SHong Zhang } 5662bf73ac6SHong Zhang #if defined(PETSC_USE_DEBUG) 5672bf73ac6SHong Zhang if (k != network->nsvtx) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"k %D != %D nsvtx",k,network->nsvtx); 5682bf73ac6SHong Zhang #endif 5692bf73ac6SHong Zhang 5702bf73ac6SHong Zhang ierr = PetscFree2(vidxlTog,eowners);CHKERRQ(ierr); 5712bf73ac6SHong Zhang 5722bf73ac6SHong Zhang network->svtx = svtx; 5732bf73ac6SHong Zhang network->Nsvtx = Nsv; 5742bf73ac6SHong Zhang ierr = PetscFree(sedgelist);CHKERRQ(ierr); 5752bf73ac6SHong Zhang 5762bf73ac6SHong Zhang /* Create a global section to be used by DMNetworkIsGhostVertex() which is a non-collective routine */ 5772bf73ac6SHong Zhang ierr = DMGetGlobalSection(network->plex,§iong);CHKERRQ(ierr); 5785f2c45f1SShri Abhyankar PetscFunctionReturn(0); 5795f2c45f1SShri Abhyankar } 5805f2c45f1SShri Abhyankar 5815f2c45f1SShri Abhyankar /*@ 5825f2c45f1SShri Abhyankar DMNetworkLayoutSetUp - Sets up the bare layout (graph) for the network 5835f2c45f1SShri Abhyankar 584d083f849SBarry Smith Collective on dm 5855f2c45f1SShri Abhyankar 5867a7aea1fSJed Brown Input Parameters: 5875f2c45f1SShri Abhyankar . DM - the dmnetwork object 5885f2c45f1SShri Abhyankar 5895f2c45f1SShri Abhyankar Notes: 5905f2c45f1SShri Abhyankar This routine should be called after the network sizes and edgelists have been provided. It creates 5915f2c45f1SShri Abhyankar the bare layout of the network and sets up the network to begin insertion of components. 5925f2c45f1SShri Abhyankar 5935f2c45f1SShri Abhyankar All the components should be registered before calling this routine. 5945f2c45f1SShri Abhyankar 59597bb938eSShri Abhyankar Level: beginner 5965f2c45f1SShri Abhyankar 5972bf73ac6SHong Zhang .seealso: DMNetworkSetNumSubNetworks(), DMNetworkAddSubnetwork() 5985f2c45f1SShri Abhyankar @*/ 5995f2c45f1SShri Abhyankar PetscErrorCode DMNetworkLayoutSetUp(DM dm) 6005f2c45f1SShri Abhyankar { 6015f2c45f1SShri Abhyankar PetscErrorCode ierr; 6025f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 6032bf73ac6SHong Zhang PetscInt i,j,ctr,Nsubnet=network->Nsubnet,*eowners,np,*edges,*subnetvtx; 6042bf73ac6SHong Zhang PetscInt e,v,vfrom,vto; 605caf410d2SHong Zhang const PetscInt *cone; 606caf410d2SHong Zhang MPI_Comm comm; 607caf410d2SHong Zhang PetscMPIInt size,rank; 6086500d4abSHong Zhang 6096500d4abSHong Zhang PetscFunctionBegin; 6102bf73ac6SHong Zhang if (network->nsubnet != network->Nsubnet) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Must call DMNetworkAddSubnetwork() %D times",network->Nsubnet); 6112bf73ac6SHong Zhang 6122bf73ac6SHong Zhang /* Create svtable for querry shared vertices */ 6132bf73ac6SHong Zhang ierr = PetscTableCreate(network->Nsvtx,network->NVertices+1,&network->svtable);CHKERRQ(ierr); 6142bf73ac6SHong Zhang 6152bf73ac6SHong Zhang if (network->Nsvtx) { 6162bf73ac6SHong Zhang ierr = DMNetworkLayoutSetUp_Coupling(dm);CHKERRQ(ierr); 6172bf73ac6SHong Zhang PetscFunctionReturn(0); 6182bf73ac6SHong Zhang } 6192bf73ac6SHong Zhang 620caf410d2SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 621ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 622ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 6236500d4abSHong Zhang 6242bf73ac6SHong Zhang /* Create LOCAL edgelist for the network by concatenating local input edgelists of the subnetworks */ 6258e71b177SVaclav Hapla ierr = PetscCalloc1(2*network->nEdges,&edges);CHKERRQ(ierr); 626caf410d2SHong Zhang ctr = 0; 6272bf73ac6SHong Zhang for (i=0; i < Nsubnet; i++) { 6286500d4abSHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 629ba38b151SHong Zhang edges[2*ctr] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j]; 630ba38b151SHong Zhang edges[2*ctr+1] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j+1]; 6316500d4abSHong Zhang ctr++; 6326500d4abSHong Zhang } 6336500d4abSHong Zhang } 6347765340cSHong Zhang 6352bf73ac6SHong Zhang /* Create network->plex; One dimensional network, numCorners=2 */ 6368e71b177SVaclav Hapla ierr = DMCreate(comm,&network->plex);CHKERRQ(ierr); 6378e71b177SVaclav Hapla ierr = DMSetType(network->plex,DMPLEX);CHKERRQ(ierr); 6382bf73ac6SHong Zhang ierr = DMSetDimension(network->plex,1);CHKERRQ(ierr); 639caf410d2SHong Zhang if (size == 1) { 6402bf73ac6SHong Zhang ierr = DMPlexBuildFromCellList(network->plex,network->nEdges,network->nVertices,2,edges);CHKERRQ(ierr); 641caf410d2SHong Zhang } else { 6422bf73ac6SHong Zhang ierr = DMPlexBuildFromCellListParallel(network->plex,network->nEdges,network->nVertices,PETSC_DECIDE,2,edges,NULL);CHKERRQ(ierr); 643acdb140fSBarry Smith } 6442bf73ac6SHong Zhang ierr = PetscFree(edges);CHKERRQ(ierr); /* local edge list with global idx used by DMPlexBuildFromCellList() */ 6456500d4abSHong Zhang 6466500d4abSHong Zhang ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr); 6476500d4abSHong Zhang ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr); 6486500d4abSHong Zhang ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr); 6496500d4abSHong Zhang 650caf410d2SHong Zhang ierr = PetscSectionCreate(comm,&network->DataSection);CHKERRQ(ierr); 651caf410d2SHong Zhang ierr = PetscSectionCreate(comm,&network->DofSection);CHKERRQ(ierr); 6526500d4abSHong Zhang ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr); 6536500d4abSHong Zhang ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr); 6546500d4abSHong Zhang 655caf410d2SHong Zhang np = network->pEnd - network->pStart; 656caf410d2SHong Zhang ierr = PetscCalloc2(np,&network->header,np,&network->cvalue);CHKERRQ(ierr); 657*54dfd506SHong Zhang for (i=0; i < np; i++) { 658*54dfd506SHong Zhang network->header[i].maxcomps = 1; 659*54dfd506SHong Zhang ierr = SetUpNetworkHeaderComponentValue(dm,&network->header[i],&network->cvalue[i]);CHKERRQ(ierr); 660*54dfd506SHong Zhang } 661caf410d2SHong Zhang 6622bf73ac6SHong Zhang /* Create edge and vertex arrays for the subnetworks */ 6632bf73ac6SHong Zhang for (j=0; j < network->Nsubnet; j++) { 6646500d4abSHong Zhang ierr = PetscCalloc1(network->subnet[j].nedge,&network->subnet[j].edges);CHKERRQ(ierr); 6656500d4abSHong Zhang } 666caf410d2SHong Zhang 667caf410d2SHong Zhang /* Get edge ownership */ 6682bf73ac6SHong Zhang ierr = PetscMalloc1(size+1,&eowners);CHKERRQ(ierr); 669caf410d2SHong Zhang np = network->eEnd - network->eStart; 670ffc4695bSBarry Smith ierr = MPI_Allgather(&np,1,MPIU_INT,eowners+1,1,MPIU_INT,comm);CHKERRMPI(ierr); 671caf410d2SHong Zhang eowners[0] = 0; 672caf410d2SHong Zhang for (i=2; i<=size; i++) eowners[i] += eowners[i-1]; 673caf410d2SHong Zhang 674caf410d2SHong Zhang /* Set network->subnet[*].vertices on array network->subnetvtx */ 6752bf73ac6SHong Zhang np = 0; 6762bf73ac6SHong Zhang for (j=0; j<network->Nsubnet; j++) { 6772bf73ac6SHong Zhang /* sum up subnet[j].Nvtx instead of subnet[j].nvtx, because a subnet might be owned by more than one processor; 6782bf73ac6SHong Zhang below, subnet[i].vertices[vfrom/vto] requires vfrom/vto =0, ...,Nvtx-1 6792bf73ac6SHong Zhang */ 6802bf73ac6SHong Zhang if (network->subnet[j].nvtx) np += network->subnet[j].Nvtx; 6812bf73ac6SHong Zhang } 6822bf73ac6SHong Zhang 6832bf73ac6SHong Zhang ierr = PetscCalloc1(np,&network->subnetvtx);CHKERRQ(ierr); /* Maps local vertex to local subnetwork's vertex */ 684caf410d2SHong Zhang subnetvtx = network->subnetvtx; 6852bf73ac6SHong Zhang for (j=0; j<network->Nsubnet; j++) { 686caf410d2SHong Zhang network->subnet[j].vertices = subnetvtx; 6872bf73ac6SHong Zhang if (network->subnet[j].nvtx) subnetvtx += network->subnet[j].Nvtx; 688caf410d2SHong Zhang } 689caf410d2SHong Zhang 6902bf73ac6SHong Zhang /* Setup edge and vertex arrays for subnetworks */ 6912bf73ac6SHong Zhang e = 0; 6922bf73ac6SHong Zhang for (i=0; i < Nsubnet; i++) { 6932bf73ac6SHong Zhang v = 0; 6942bf73ac6SHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 6952bf73ac6SHong Zhang /* edge e */ 6962bf73ac6SHong Zhang network->header[e].index = e + eowners[rank]; /* Global edge index */ 6972bf73ac6SHong Zhang network->header[e].subnetid = i; 6982bf73ac6SHong Zhang network->subnet[i].edges[j] = e; 699caf410d2SHong Zhang 7002bf73ac6SHong Zhang network->header[e].ndata = 0; 7012bf73ac6SHong Zhang network->header[e].offset[0] = 0; 7022bf73ac6SHong Zhang network->header[e].offsetvarrel[0] = 0; 703*54dfd506SHong Zhang ierr = PetscSectionAddDof(network->DataSection,e,network->header[e].hsize);CHKERRQ(ierr); 7042bf73ac6SHong Zhang 7052bf73ac6SHong Zhang /* connected vertices */ 7062bf73ac6SHong Zhang ierr = DMPlexGetCone(network->plex,e,&cone);CHKERRQ(ierr); 7072bf73ac6SHong Zhang 7082bf73ac6SHong Zhang /* vertex cone[0] */ 7092bf73ac6SHong Zhang vfrom = network->subnet[i].edgelist[2*v]; /* =subnet[i].idx, Global index! */ 7102bf73ac6SHong Zhang network->header[cone[0]].index = vfrom + network->subnet[i].vStart; /* Global vertex index */ 7112bf73ac6SHong Zhang network->header[cone[0]].subnetid = i; /* Subnetwork id */ 7122bf73ac6SHong Zhang network->subnet[i].vertices[vfrom] = cone[0]; /* user's subnet[].dix = petsc's v */ 7132bf73ac6SHong Zhang 7142bf73ac6SHong Zhang /* vertex cone[1] */ 7152bf73ac6SHong Zhang vto = network->subnet[i].edgelist[2*v+1]; /* =subnet[i].idx, Global index! */ 7162bf73ac6SHong Zhang network->header[cone[1]].index = vto + network->subnet[i].vStart; /* Global vertex index */ 7172bf73ac6SHong Zhang network->header[cone[1]].subnetid = i; 7182bf73ac6SHong Zhang network->subnet[i].vertices[vto] = cone[1]; /* user's subnet[].dix = petsc's v */ 7192bf73ac6SHong Zhang 7202bf73ac6SHong Zhang e++; v++; 7216500d4abSHong Zhang } 7226500d4abSHong Zhang } 7232bf73ac6SHong Zhang ierr = PetscFree(eowners);CHKERRQ(ierr); 724caf410d2SHong Zhang 7252bf73ac6SHong Zhang for (v = network->vStart; v < network->vEnd; v++) { 7262bf73ac6SHong Zhang network->header[v].ndata = 0; 7272bf73ac6SHong Zhang network->header[v].offset[0] = 0; 7282bf73ac6SHong Zhang network->header[v].offsetvarrel[0] = 0; 729*54dfd506SHong Zhang ierr = PetscSectionAddDof(network->DataSection,v,network->header[e].hsize);CHKERRQ(ierr); 7306500d4abSHong Zhang } 7315f2c45f1SShri Abhyankar PetscFunctionReturn(0); 7325f2c45f1SShri Abhyankar } 7335f2c45f1SShri Abhyankar 73494ef8ddeSSatish Balay /*@C 7352bf73ac6SHong Zhang DMNetworkGetSubnetwork - Returns the information about a requested subnetwork 7362bf73ac6SHong Zhang 7372bf73ac6SHong Zhang Not collective 7382727e31bSShri Abhyankar 7397a7aea1fSJed Brown Input Parameters: 740caf410d2SHong Zhang + dm - the DM object 7412bf73ac6SHong Zhang - netnum - the global index of the subnetwork 7422727e31bSShri Abhyankar 7437a7aea1fSJed Brown Output Parameters: 7442727e31bSShri Abhyankar + nv - number of vertices (local) 7452727e31bSShri Abhyankar . ne - number of edges (local) 7462bf73ac6SHong Zhang . vtx - local vertices of the subnetwork 7472bf73ac6SHong Zhang - edge - local edges of the subnetwork 7482727e31bSShri Abhyankar 7492727e31bSShri Abhyankar Notes: 7502727e31bSShri Abhyankar Cannot call this routine before DMNetworkLayoutSetup() 7512727e31bSShri Abhyankar 75206dd6b0eSSatish Balay Level: intermediate 75306dd6b0eSSatish Balay 7542bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkAddSubnetwork(), DMNetworkLayoutSetUp() 7552727e31bSShri Abhyankar @*/ 7562bf73ac6SHong Zhang PetscErrorCode DMNetworkGetSubnetwork(DM dm,PetscInt netnum,PetscInt *nv,PetscInt *ne,const PetscInt **vtx,const PetscInt **edge) 7572727e31bSShri Abhyankar { 758caf410d2SHong Zhang DM_Network *network = (DM_Network*)dm->data; 7592727e31bSShri Abhyankar 7602727e31bSShri Abhyankar PetscFunctionBegin; 7612bf73ac6SHong 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); 7622bf73ac6SHong Zhang if (nv) *nv = network->subnet[netnum].nvtx; 7632bf73ac6SHong Zhang if (ne) *ne = network->subnet[netnum].nedge; 7642bf73ac6SHong Zhang if (vtx) *vtx = network->subnet[netnum].vertices; 7652bf73ac6SHong Zhang if (edge) *edge = network->subnet[netnum].edges; 7662bf73ac6SHong Zhang PetscFunctionReturn(0); 7672bf73ac6SHong Zhang } 7682bf73ac6SHong Zhang 7692bf73ac6SHong Zhang /*@ 7702bf73ac6SHong Zhang DMNetworkAddSharedVertices - Add shared vertices that connect two given subnetworks 7712bf73ac6SHong Zhang 7722bf73ac6SHong Zhang Collective on dm 7732bf73ac6SHong Zhang 7742bf73ac6SHong Zhang Input Parameters: 7752bf73ac6SHong Zhang + dm - the dm object 7762bf73ac6SHong Zhang . anetnum - first subnetwork global numbering returned by DMNetworkAddSubnetwork() 7772bf73ac6SHong Zhang . bnetnum - second subnetwork global numbering returned by DMNetworkAddSubnetwork() 7782bf73ac6SHong Zhang . nsvtx - number of vertices that are shared by the two subnetworks 7792bf73ac6SHong Zhang . asvtx - vertex index in the first subnetwork 7802bf73ac6SHong Zhang - bsvtx - vertex index in the second subnetwork 7812bf73ac6SHong Zhang 7822bf73ac6SHong Zhang Level: beginner 7832bf73ac6SHong Zhang 7842bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkAddSubnetwork(), DMNetworkGetSharedVertices() 7852bf73ac6SHong Zhang @*/ 7862bf73ac6SHong Zhang PetscErrorCode DMNetworkAddSharedVertices(DM dm,PetscInt anetnum,PetscInt bnetnum,PetscInt nsvtx,PetscInt asvtx[],PetscInt bsvtx[]) 7872bf73ac6SHong Zhang { 7882bf73ac6SHong Zhang PetscErrorCode ierr; 7892bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 7902bf73ac6SHong Zhang PetscInt i,nsubnet = network->Nsubnet,*sedgelist,Nsvtx=network->Nsvtx; 7912bf73ac6SHong Zhang 7922bf73ac6SHong Zhang PetscFunctionBegin; 7932bf73ac6SHong Zhang if (anetnum == bnetnum) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Subnetworks must have different netnum"); 7942bf73ac6SHong Zhang if (anetnum < 0 || bnetnum < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"netnum cannot be negative"); 7952bf73ac6SHong Zhang if (!Nsvtx) { 7962bf73ac6SHong Zhang /* allocate network->sedgelist to hold at most 2*nsubnet pairs of shared vertices */ 7972bf73ac6SHong Zhang ierr = PetscMalloc1(2*4*nsubnet,&network->sedgelist);CHKERRQ(ierr); 7982bf73ac6SHong Zhang } 7992bf73ac6SHong Zhang 8002bf73ac6SHong Zhang sedgelist = network->sedgelist; 8012bf73ac6SHong Zhang for (i=0; i<nsvtx; i++) { 8022bf73ac6SHong Zhang sedgelist[4*Nsvtx] = anetnum; sedgelist[4*Nsvtx+1] = asvtx[i]; 8032bf73ac6SHong Zhang sedgelist[4*Nsvtx+2] = bnetnum; sedgelist[4*Nsvtx+3] = bsvtx[i]; 8042bf73ac6SHong Zhang Nsvtx++; 8052bf73ac6SHong Zhang } 8062bf73ac6SHong Zhang if (Nsvtx > 2*nsubnet) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"allocate more space for coupling edgelist"); 8072bf73ac6SHong Zhang network->Nsvtx = Nsvtx; 8082727e31bSShri Abhyankar PetscFunctionReturn(0); 8092727e31bSShri Abhyankar } 8102727e31bSShri Abhyankar 8112727e31bSShri Abhyankar /*@C 8122bf73ac6SHong Zhang DMNetworkGetSharedVertices - Returns the info for the shared vertices 8132bf73ac6SHong Zhang 8142bf73ac6SHong Zhang Not collective 815caf410d2SHong Zhang 8167a7aea1fSJed Brown Input Parameters: 8172bf73ac6SHong Zhang . dm - the DM object 818caf410d2SHong Zhang 8197a7aea1fSJed Brown Output Parameters: 8202bf73ac6SHong Zhang + nsv - number of local shared vertices 8212bf73ac6SHong Zhang - svtx - local shared vertices 822caf410d2SHong Zhang 823caf410d2SHong Zhang Notes: 824caf410d2SHong Zhang Cannot call this routine before DMNetworkLayoutSetup() 825caf410d2SHong Zhang 826caf410d2SHong Zhang Level: intermediate 827caf410d2SHong Zhang 8282bf73ac6SHong Zhang .seealso: DMNetworkGetSubnetwork(), DMNetworkLayoutSetUp(), DMNetworkAddSharedVertices() 829caf410d2SHong Zhang @*/ 8302bf73ac6SHong Zhang PetscErrorCode DMNetworkGetSharedVertices(DM dm,PetscInt *nsv,const PetscInt **svtx) 831caf410d2SHong Zhang { 832caf410d2SHong Zhang DM_Network *net = (DM_Network*)dm->data; 833caf410d2SHong Zhang 834caf410d2SHong Zhang PetscFunctionBegin; 8352bf73ac6SHong Zhang if (net->Nsvtx) { 8362bf73ac6SHong Zhang *nsv = net->nsvtx; 8372bf73ac6SHong Zhang *svtx = net->svertices; 83872c3e9f7SHong Zhang } else { 8392bf73ac6SHong Zhang *nsv = 0; 8402bf73ac6SHong Zhang *svtx = NULL; 84172c3e9f7SHong Zhang } 842caf410d2SHong Zhang PetscFunctionReturn(0); 843caf410d2SHong Zhang } 844caf410d2SHong Zhang 845caf410d2SHong Zhang /*@C 8465f2c45f1SShri Abhyankar DMNetworkRegisterComponent - Registers the network component 8475f2c45f1SShri Abhyankar 848d083f849SBarry Smith Logically collective on dm 8495f2c45f1SShri Abhyankar 8507a7aea1fSJed Brown Input Parameters: 8515f2c45f1SShri Abhyankar + dm - the network object 8525f2c45f1SShri Abhyankar . name - the component name 8535f2c45f1SShri Abhyankar - size - the storage size in bytes for this component data 8545f2c45f1SShri Abhyankar 8557a7aea1fSJed Brown Output Parameters: 8565f2c45f1SShri Abhyankar . key - an integer key that defines the component 8575f2c45f1SShri Abhyankar 8585f2c45f1SShri Abhyankar Notes 8595f2c45f1SShri Abhyankar This routine should be called by all processors before calling DMNetworkLayoutSetup(). 8605f2c45f1SShri Abhyankar 86197bb938eSShri Abhyankar Level: beginner 8625f2c45f1SShri Abhyankar 8632bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkLayoutSetUp() 8645f2c45f1SShri Abhyankar @*/ 865caf410d2SHong Zhang PetscErrorCode DMNetworkRegisterComponent(DM dm,const char *name,size_t size,PetscInt *key) 8665f2c45f1SShri Abhyankar { 8675f2c45f1SShri Abhyankar PetscErrorCode ierr; 8685f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 869*54dfd506SHong Zhang DMNetworkComponent *component=NULL,*newcomponent=NULL; 8705f2c45f1SShri Abhyankar PetscBool flg=PETSC_FALSE; 8715f2c45f1SShri Abhyankar PetscInt i; 8725f2c45f1SShri Abhyankar 8735f2c45f1SShri Abhyankar PetscFunctionBegin; 874*54dfd506SHong Zhang if (!network->component) { 875*54dfd506SHong Zhang ierr = PetscCalloc1(network->max_comps_registered,&network->component);CHKERRQ(ierr); 876*54dfd506SHong Zhang } 877*54dfd506SHong Zhang 8785f2c45f1SShri Abhyankar for (i=0; i < network->ncomponent; i++) { 879*54dfd506SHong Zhang ierr = PetscStrcmp(network->component[i].name,name,&flg);CHKERRQ(ierr); 8805f2c45f1SShri Abhyankar if (flg) { 8815f2c45f1SShri Abhyankar *key = i; 8825f2c45f1SShri Abhyankar PetscFunctionReturn(0); 8835f2c45f1SShri Abhyankar } 8846d64e262SShri Abhyankar } 885*54dfd506SHong Zhang 886*54dfd506SHong Zhang if (network->ncomponent == network->max_comps_registered) { 887*54dfd506SHong Zhang /* Reached max allowed so resize component */ 888*54dfd506SHong Zhang network->max_comps_registered += 2; 889*54dfd506SHong Zhang ierr = PetscCalloc1(network->max_comps_registered,&newcomponent);CHKERRQ(ierr); 890*54dfd506SHong Zhang /* Copy over the previous component info */ 891*54dfd506SHong Zhang for (i=0; i < network->ncomponent; i++) { 892*54dfd506SHong Zhang ierr = PetscStrcpy(newcomponent[i].name,network->component[i].name);CHKERRQ(ierr); 893*54dfd506SHong Zhang newcomponent[i].size = network->component[i].size; 8945f2c45f1SShri Abhyankar } 895*54dfd506SHong Zhang /* Free old one */ 896*54dfd506SHong Zhang ierr = PetscFree(network->component);CHKERRQ(ierr); 897*54dfd506SHong Zhang /* Update pointer */ 898*54dfd506SHong Zhang network->component = newcomponent; 899*54dfd506SHong Zhang } 900*54dfd506SHong Zhang 901*54dfd506SHong Zhang component = &network->component[network->ncomponent]; 9025f2c45f1SShri Abhyankar 9035f2c45f1SShri Abhyankar ierr = PetscStrcpy(component->name,name);CHKERRQ(ierr); 9045f2c45f1SShri Abhyankar component->size = size/sizeof(DMNetworkComponentGenericDataType); 9055f2c45f1SShri Abhyankar *key = network->ncomponent; 9065f2c45f1SShri Abhyankar network->ncomponent++; 9075f2c45f1SShri Abhyankar PetscFunctionReturn(0); 9085f2c45f1SShri Abhyankar } 9095f2c45f1SShri Abhyankar 9105f2c45f1SShri Abhyankar /*@ 9112bf73ac6SHong Zhang DMNetworkGetVertexRange - Get the bounds [start, end) for the local vertices 9125f2c45f1SShri Abhyankar 9135f2c45f1SShri Abhyankar Not Collective 9145f2c45f1SShri Abhyankar 9155f2c45f1SShri Abhyankar Input Parameters: 9162bf73ac6SHong Zhang . dm - the DMNetwork object 9175f2c45f1SShri Abhyankar 918fd292e60Sprj- Output Parameters: 9192bf73ac6SHong Zhang + vStart - the first vertex point 9202bf73ac6SHong Zhang - vEnd - one beyond the last vertex point 9215f2c45f1SShri Abhyankar 92297bb938eSShri Abhyankar Level: beginner 9235f2c45f1SShri Abhyankar 9242bf73ac6SHong Zhang .seealso: DMNetworkGetEdgeRange() 9255f2c45f1SShri Abhyankar @*/ 9265f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVertexRange(DM dm,PetscInt *vStart,PetscInt *vEnd) 9275f2c45f1SShri Abhyankar { 9285f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 9295f2c45f1SShri Abhyankar 9305f2c45f1SShri Abhyankar PetscFunctionBegin; 9315f2c45f1SShri Abhyankar if (vStart) *vStart = network->vStart; 9325f2c45f1SShri Abhyankar if (vEnd) *vEnd = network->vEnd; 9335f2c45f1SShri Abhyankar PetscFunctionReturn(0); 9345f2c45f1SShri Abhyankar } 9355f2c45f1SShri Abhyankar 9365f2c45f1SShri Abhyankar /*@ 9372bf73ac6SHong Zhang DMNetworkGetEdgeRange - Get the bounds [start, end) for the local edges 9385f2c45f1SShri Abhyankar 9395f2c45f1SShri Abhyankar Not Collective 9405f2c45f1SShri Abhyankar 9415f2c45f1SShri Abhyankar Input Parameters: 9422bf73ac6SHong Zhang . dm - the DMNetwork object 9435f2c45f1SShri Abhyankar 944fd292e60Sprj- Output Parameters: 9455f2c45f1SShri Abhyankar + eStart - The first edge point 9465f2c45f1SShri Abhyankar - eEnd - One beyond the last edge point 9475f2c45f1SShri Abhyankar 94897bb938eSShri Abhyankar Level: beginner 9495f2c45f1SShri Abhyankar 9502bf73ac6SHong Zhang .seealso: DMNetworkGetVertexRange() 9515f2c45f1SShri Abhyankar @*/ 9525f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetEdgeRange(DM dm,PetscInt *eStart,PetscInt *eEnd) 9535f2c45f1SShri Abhyankar { 9545f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 9555f2c45f1SShri Abhyankar 9565f2c45f1SShri Abhyankar PetscFunctionBegin; 9575f2c45f1SShri Abhyankar if (eStart) *eStart = network->eStart; 9585f2c45f1SShri Abhyankar if (eEnd) *eEnd = network->eEnd; 9595f2c45f1SShri Abhyankar PetscFunctionReturn(0); 9605f2c45f1SShri Abhyankar } 9615f2c45f1SShri Abhyankar 9622bf73ac6SHong Zhang static PetscErrorCode DMNetworkGetIndex(DM dm,PetscInt p,PetscInt *index) 9632bf73ac6SHong Zhang { 9642bf73ac6SHong Zhang PetscErrorCode ierr; 9652bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 9662bf73ac6SHong Zhang PetscInt offsetp; 9672bf73ac6SHong Zhang DMNetworkComponentHeader header; 9682bf73ac6SHong Zhang 9692bf73ac6SHong Zhang PetscFunctionBegin; 9702bf73ac6SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 9712bf73ac6SHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 9722bf73ac6SHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 9732bf73ac6SHong Zhang *index = header->index; 9742bf73ac6SHong Zhang PetscFunctionReturn(0); 9752bf73ac6SHong Zhang } 9762bf73ac6SHong Zhang 9777b6afd5bSHong Zhang /*@ 9782bf73ac6SHong Zhang DMNetworkGetGlobalEdgeIndex - Get the global numbering for the edge on the network 9797b6afd5bSHong Zhang 9807b6afd5bSHong Zhang Not Collective 9817b6afd5bSHong Zhang 9827b6afd5bSHong Zhang Input Parameters: 9837b6afd5bSHong Zhang + dm - DMNetwork object 984e85e6aecSHong Zhang - p - edge point 9857b6afd5bSHong Zhang 986fd292e60Sprj- Output Parameters: 9872bf73ac6SHong Zhang . index - the global numbering for the edge 9887b6afd5bSHong Zhang 9897b6afd5bSHong Zhang Level: intermediate 9907b6afd5bSHong Zhang 9912bf73ac6SHong Zhang .seealso: DMNetworkGetGlobalVertexIndex() 9927b6afd5bSHong Zhang @*/ 993e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalEdgeIndex(DM dm,PetscInt p,PetscInt *index) 9947b6afd5bSHong Zhang { 9957b6afd5bSHong Zhang PetscErrorCode ierr; 9967b6afd5bSHong Zhang 9977b6afd5bSHong Zhang PetscFunctionBegin; 9982bf73ac6SHong Zhang ierr = DMNetworkGetIndex(dm,p,index);CHKERRQ(ierr); 9997b6afd5bSHong Zhang PetscFunctionReturn(0); 10007b6afd5bSHong Zhang } 10017b6afd5bSHong Zhang 10025f2c45f1SShri Abhyankar /*@ 10032bf73ac6SHong Zhang DMNetworkGetGlobalVertexIndex - Get the global numbering for the vertex on the network 1004e85e6aecSHong Zhang 1005e85e6aecSHong Zhang Not Collective 1006e85e6aecSHong Zhang 1007e85e6aecSHong Zhang Input Parameters: 1008e85e6aecSHong Zhang + dm - DMNetwork object 1009e85e6aecSHong Zhang - p - vertex point 1010e85e6aecSHong Zhang 1011fd292e60Sprj- Output Parameters: 10122bf73ac6SHong Zhang . index - the global numbering for the vertex 1013e85e6aecSHong Zhang 1014e85e6aecSHong Zhang Level: intermediate 1015e85e6aecSHong Zhang 10162bf73ac6SHong Zhang .seealso: DMNetworkGetGlobalEdgeIndex() 1017e85e6aecSHong Zhang @*/ 1018e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalVertexIndex(DM dm,PetscInt p,PetscInt *index) 1019e85e6aecSHong Zhang { 1020e85e6aecSHong Zhang PetscErrorCode ierr; 1021e85e6aecSHong Zhang 1022e85e6aecSHong Zhang PetscFunctionBegin; 10232bf73ac6SHong Zhang ierr = DMNetworkGetIndex(dm,p,index);CHKERRQ(ierr); 10249988b915SShri Abhyankar PetscFunctionReturn(0); 10259988b915SShri Abhyankar } 10269988b915SShri Abhyankar 10279988b915SShri Abhyankar /*@ 10285f2c45f1SShri Abhyankar DMNetworkGetNumComponents - Get the number of components at a vertex/edge 10295f2c45f1SShri Abhyankar 10305f2c45f1SShri Abhyankar Not Collective 10315f2c45f1SShri Abhyankar 10325f2c45f1SShri Abhyankar Input Parameters: 10332bf73ac6SHong Zhang + dm - the DMNetwork object 1034a2b725a8SWilliam Gropp - p - vertex/edge point 10355f2c45f1SShri Abhyankar 10365f2c45f1SShri Abhyankar Output Parameters: 10375f2c45f1SShri Abhyankar . numcomponents - Number of components at the vertex/edge 10385f2c45f1SShri Abhyankar 103997bb938eSShri Abhyankar Level: beginner 10405f2c45f1SShri Abhyankar 10412bf73ac6SHong Zhang .seealso: DMNetworkRegisterComponent(), DMNetworkAddComponent() 10425f2c45f1SShri Abhyankar @*/ 10435f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetNumComponents(DM dm,PetscInt p,PetscInt *numcomponents) 10445f2c45f1SShri Abhyankar { 10455f2c45f1SShri Abhyankar PetscErrorCode ierr; 10465f2c45f1SShri Abhyankar PetscInt offset; 10475f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10485f2c45f1SShri Abhyankar 10495f2c45f1SShri Abhyankar PetscFunctionBegin; 10505f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 10515f2c45f1SShri Abhyankar *numcomponents = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 10525f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10535f2c45f1SShri Abhyankar } 10545f2c45f1SShri Abhyankar 10555f2c45f1SShri Abhyankar /*@ 10562bf73ac6SHong Zhang DMNetworkGetLocalVecOffset - Get the offset for accessing the variables associated with a component at the given vertex/edge from the local vector 10575f2c45f1SShri Abhyankar 10585f2c45f1SShri Abhyankar Not Collective 10595f2c45f1SShri Abhyankar 10605f2c45f1SShri Abhyankar Input Parameters: 10612bf73ac6SHong Zhang + dm - the DMNetwork object 10627d928bffSSatish Balay . p - the edge/vertex point 10632bf73ac6SHong Zhang - compnum - component number; use ALL_COMPONENTS if no specific component is requested 10649988b915SShri Abhyankar 10659988b915SShri Abhyankar Output Parameters: 10662bf73ac6SHong Zhang . offset - the local offset 10679988b915SShri Abhyankar 10689988b915SShri Abhyankar Level: intermediate 10699988b915SShri Abhyankar 10702bf73ac6SHong Zhang .seealso: DMGetLocalVector(), DMNetworkGetComponent(), DMNetworkGetGlobalVecOffset() 10719988b915SShri Abhyankar @*/ 10722bf73ac6SHong Zhang PetscErrorCode DMNetworkGetLocalVecOffset(DM dm,PetscInt p,PetscInt compnum,PetscInt *offset) 10739988b915SShri Abhyankar { 10749988b915SShri Abhyankar PetscErrorCode ierr; 10759988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10769988b915SShri Abhyankar PetscInt offsetp,offsetd; 10779988b915SShri Abhyankar DMNetworkComponentHeader header; 10789988b915SShri Abhyankar 10799988b915SShri Abhyankar PetscFunctionBegin; 10802bf73ac6SHong Zhang ierr = PetscSectionGetOffset(network->plex->localSection,p,&offsetp);CHKERRQ(ierr); 10812bf73ac6SHong Zhang if (compnum == ALL_COMPONENTS) { 10822bf73ac6SHong Zhang *offset = offsetp; 10832bf73ac6SHong Zhang PetscFunctionReturn(0); 10842bf73ac6SHong Zhang } 10852bf73ac6SHong Zhang 10869988b915SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetd);CHKERRQ(ierr); 10879988b915SShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetd); 10889988b915SShri Abhyankar *offset = offsetp + header->offsetvarrel[compnum]; 10899988b915SShri Abhyankar PetscFunctionReturn(0); 10909988b915SShri Abhyankar } 10919988b915SShri Abhyankar 10929988b915SShri Abhyankar /*@ 10932bf73ac6SHong Zhang DMNetworkGetGlobalVecOffset - Get the global offset for accessing the variables associated with a component for the given vertex/edge from the global vector 10949988b915SShri Abhyankar 10959988b915SShri Abhyankar Not Collective 10969988b915SShri Abhyankar 10979988b915SShri Abhyankar Input Parameters: 10982bf73ac6SHong Zhang + dm - the DMNetwork object 10997d928bffSSatish Balay . p - the edge/vertex point 11002bf73ac6SHong Zhang - compnum - component number; use ALL_COMPONENTS if no specific component is requested 11019988b915SShri Abhyankar 11029988b915SShri Abhyankar Output Parameters: 11039988b915SShri Abhyankar . offsetg - the global offset 11049988b915SShri Abhyankar 11059988b915SShri Abhyankar Level: intermediate 11069988b915SShri Abhyankar 11072bf73ac6SHong Zhang .seealso: DMNetworkGetLocalVecOffset(), DMGetGlobalVector(), DMNetworkGetComponent() 11089988b915SShri Abhyankar @*/ 11092bf73ac6SHong Zhang PetscErrorCode DMNetworkGetGlobalVecOffset(DM dm,PetscInt p,PetscInt compnum,PetscInt *offsetg) 11109988b915SShri Abhyankar { 11119988b915SShri Abhyankar PetscErrorCode ierr; 11129988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 11139988b915SShri Abhyankar PetscInt offsetp,offsetd; 11149988b915SShri Abhyankar DMNetworkComponentHeader header; 11159988b915SShri Abhyankar 11169988b915SShri Abhyankar PetscFunctionBegin; 11172bf73ac6SHong Zhang ierr = PetscSectionGetOffset(network->plex->globalSection,p,&offsetp);CHKERRQ(ierr); 11182bf73ac6SHong Zhang if (offsetp < 0) offsetp = -(offsetp + 1); /* Convert to actual global offset for ghost vertex */ 11192bf73ac6SHong Zhang 11202bf73ac6SHong Zhang if (compnum == ALL_COMPONENTS) { 11212bf73ac6SHong Zhang *offsetg = offsetp; 11222bf73ac6SHong Zhang PetscFunctionReturn(0); 11232bf73ac6SHong Zhang } 11249988b915SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetd);CHKERRQ(ierr); 11259988b915SShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetd); 11269988b915SShri Abhyankar *offsetg = offsetp + header->offsetvarrel[compnum]; 11279988b915SShri Abhyankar PetscFunctionReturn(0); 11289988b915SShri Abhyankar } 11299988b915SShri Abhyankar 11309988b915SShri Abhyankar /*@ 11312bf73ac6SHong Zhang DMNetworkGetEdgeOffset - Get the offset for accessing the variables associated with the given edge from the local subvector 113224121865SAdrian Maldonado 113324121865SAdrian Maldonado Not Collective 113424121865SAdrian Maldonado 113524121865SAdrian Maldonado Input Parameters: 11362bf73ac6SHong Zhang + dm - the DMNetwork object 113724121865SAdrian Maldonado - p - the edge point 113824121865SAdrian Maldonado 113924121865SAdrian Maldonado Output Parameters: 114024121865SAdrian Maldonado . offset - the offset 114124121865SAdrian Maldonado 114224121865SAdrian Maldonado Level: intermediate 114324121865SAdrian Maldonado 11442bf73ac6SHong Zhang .seealso: DMNetworkGetLocalVecOffset(), DMGetLocalVector() 114524121865SAdrian Maldonado @*/ 114624121865SAdrian Maldonado PetscErrorCode DMNetworkGetEdgeOffset(DM dm,PetscInt p,PetscInt *offset) 114724121865SAdrian Maldonado { 114824121865SAdrian Maldonado PetscErrorCode ierr; 114924121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 115024121865SAdrian Maldonado 115124121865SAdrian Maldonado PetscFunctionBegin; 115224121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->edge.DofSection,p,offset);CHKERRQ(ierr); 115324121865SAdrian Maldonado PetscFunctionReturn(0); 115424121865SAdrian Maldonado } 115524121865SAdrian Maldonado 115624121865SAdrian Maldonado /*@ 11572bf73ac6SHong Zhang DMNetworkGetVertexOffset - Get the offset for accessing the variables associated with the given vertex from the local subvector 115824121865SAdrian Maldonado 115924121865SAdrian Maldonado Not Collective 116024121865SAdrian Maldonado 116124121865SAdrian Maldonado Input Parameters: 11622bf73ac6SHong Zhang + dm - the DMNetwork object 116324121865SAdrian Maldonado - p - the vertex point 116424121865SAdrian Maldonado 116524121865SAdrian Maldonado Output Parameters: 116624121865SAdrian Maldonado . offset - the offset 116724121865SAdrian Maldonado 116824121865SAdrian Maldonado Level: intermediate 116924121865SAdrian Maldonado 11702bf73ac6SHong Zhang .seealso: DMNetworkGetEdgeOffset(), DMGetLocalVector() 117124121865SAdrian Maldonado @*/ 117224121865SAdrian Maldonado PetscErrorCode DMNetworkGetVertexOffset(DM dm,PetscInt p,PetscInt *offset) 117324121865SAdrian Maldonado { 117424121865SAdrian Maldonado PetscErrorCode ierr; 117524121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 117624121865SAdrian Maldonado 117724121865SAdrian Maldonado PetscFunctionBegin; 117824121865SAdrian Maldonado p -= network->vStart; 117924121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->vertex.DofSection,p,offset);CHKERRQ(ierr); 118024121865SAdrian Maldonado PetscFunctionReturn(0); 118124121865SAdrian Maldonado } 11822bf73ac6SHong Zhang 11835f2c45f1SShri Abhyankar /*@ 11842bf73ac6SHong Zhang DMNetworkAddComponent - Adds a network component and number of variables at the given point (vertex/edge) 11855f2c45f1SShri Abhyankar 11865f2c45f1SShri Abhyankar Not Collective 11875f2c45f1SShri Abhyankar 11885f2c45f1SShri Abhyankar Input Parameters: 11894dc646bcSBarry Smith + dm - the DMNetwork 11905f2c45f1SShri Abhyankar . p - the vertex/edge point 11912bf73ac6SHong Zhang . componentkey - component key returned while registering the component; ignored if compvalue=NULL 11922bf73ac6SHong Zhang . compvalue - pointer to the data structure for the component, or NULL if not required. 11932bf73ac6SHong Zhang - nvar - number of variables for the component at the vertex/edge point 11945f2c45f1SShri Abhyankar 119597bb938eSShri Abhyankar Level: beginner 11965f2c45f1SShri Abhyankar 11972bf73ac6SHong Zhang .seealso: DMNetworkGetComponent() 11985f2c45f1SShri Abhyankar @*/ 11992bf73ac6SHong Zhang PetscErrorCode DMNetworkAddComponent(DM dm,PetscInt p,PetscInt componentkey,void* compvalue,PetscInt nvar) 12005f2c45f1SShri Abhyankar { 12015f2c45f1SShri Abhyankar PetscErrorCode ierr; 12025f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 12032bf73ac6SHong Zhang DMNetworkComponent *component = &network->component[componentkey]; 1204*54dfd506SHong Zhang DMNetworkComponentHeader header; 1205*54dfd506SHong Zhang DMNetworkComponentValue cvalue; 12062bf73ac6SHong Zhang PetscBool sharedv=PETSC_FALSE; 1207*54dfd506SHong Zhang PetscInt compnum; 1208*54dfd506SHong Zhang PetscInt *compsize,*compkey,*compoffset,*compnvar,*compoffsetvarrel; 1209*54dfd506SHong Zhang void* *compdata; 12105f2c45f1SShri Abhyankar 12115f2c45f1SShri Abhyankar PetscFunctionBegin; 12125f2c45f1SShri Abhyankar ierr = PetscSectionAddDof(network->DofSection,p,nvar);CHKERRQ(ierr); 12132bf73ac6SHong Zhang if (!compvalue) PetscFunctionReturn(0); 12142bf73ac6SHong Zhang 12152bf73ac6SHong Zhang ierr = DMNetworkIsSharedVertex(dm,p,&sharedv);CHKERRQ(ierr); 12162bf73ac6SHong Zhang if (sharedv) { 12172bf73ac6SHong Zhang PetscBool ghost; 12182bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 12192bf73ac6SHong Zhang if (ghost) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Adding a component at a leaf(ghost) shared vertex is not supported"); 12202bf73ac6SHong Zhang } 12212bf73ac6SHong Zhang 1222*54dfd506SHong Zhang header = &network->header[p]; 1223*54dfd506SHong Zhang cvalue = &network->cvalue[p]; 1224*54dfd506SHong Zhang if (header->ndata == header->maxcomps) { 1225*54dfd506SHong Zhang /* Reached limit so resize header component arrays */ 1226*54dfd506SHong Zhang header->maxcomps += 2; 1227*54dfd506SHong Zhang 1228*54dfd506SHong Zhang /* Allocate arrays for component information and value */ 1229*54dfd506SHong Zhang ierr = PetscCalloc5(header->maxcomps,&compsize,header->maxcomps,&compkey,header->maxcomps,&compoffset,header->maxcomps,&compnvar,header->maxcomps,&compoffsetvarrel);CHKERRQ(ierr); 1230*54dfd506SHong Zhang ierr = PetscMalloc1(header->maxcomps,&compdata);CHKERRQ(ierr); 1231*54dfd506SHong Zhang 1232*54dfd506SHong Zhang /* Recalculate header size */ 1233*54dfd506SHong Zhang header->hsize = sizeof(struct _p_DMNetworkComponentHeader) + 5*header->maxcomps*sizeof(PetscInt); 1234*54dfd506SHong Zhang 1235*54dfd506SHong Zhang header->hsize /= sizeof(DMNetworkComponentGenericDataType); 1236*54dfd506SHong Zhang 1237*54dfd506SHong Zhang /* Copy over component info */ 1238*54dfd506SHong Zhang ierr = PetscMemcpy(compsize,header->size,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 1239*54dfd506SHong Zhang ierr = PetscMemcpy(compkey,header->key,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 1240*54dfd506SHong Zhang ierr = PetscMemcpy(compoffset,header->offset,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 1241*54dfd506SHong Zhang ierr = PetscMemcpy(compnvar,header->nvar,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 1242*54dfd506SHong Zhang ierr = PetscMemcpy(compoffsetvarrel,header->offsetvarrel,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 1243*54dfd506SHong Zhang 1244*54dfd506SHong Zhang /* Copy over component data pointers */ 1245*54dfd506SHong Zhang ierr = PetscMemcpy(compdata,cvalue->data,header->ndata*sizeof(void*));CHKERRQ(ierr); 1246*54dfd506SHong Zhang 1247*54dfd506SHong Zhang /* Free old arrays */ 1248*54dfd506SHong Zhang ierr = PetscFree5(header->size,header->key,header->offset,header->nvar,header->offsetvarrel);CHKERRQ(ierr); 1249*54dfd506SHong Zhang ierr = PetscFree(cvalue->data);CHKERRQ(ierr); 1250*54dfd506SHong Zhang 1251*54dfd506SHong Zhang /* Update pointers */ 1252*54dfd506SHong Zhang header->size = compsize; 1253*54dfd506SHong Zhang header->key = compkey; 1254*54dfd506SHong Zhang header->offset = compoffset; 1255*54dfd506SHong Zhang header->nvar = compnvar; 1256*54dfd506SHong Zhang header->offsetvarrel = compoffsetvarrel; 1257*54dfd506SHong Zhang 1258*54dfd506SHong Zhang cvalue->data = compdata; 1259*54dfd506SHong Zhang 1260*54dfd506SHong Zhang /* Update DataSection Dofs */ 1261*54dfd506SHong Zhang /* The dofs for datasection point p equals sizeof the header (i.e. header->hsize) + sizes of the components added at point p. With the resizing of the header, we need to update the dofs for point p. Hence, we add the extra size added for the header */ 1262*54dfd506SHong Zhang PetscInt additional_size = (5*(header->maxcomps - header->ndata)*sizeof(PetscInt))/sizeof(DMNetworkComponentGenericDataType); 1263*54dfd506SHong Zhang ierr = PetscSectionAddDof(network->DataSection,p,additional_size);CHKERRQ(ierr); 1264*54dfd506SHong Zhang } 1265*54dfd506SHong Zhang header = &network->header[p]; 1266*54dfd506SHong Zhang cvalue = &network->cvalue[p]; 1267*54dfd506SHong Zhang 1268*54dfd506SHong Zhang compnum = header->ndata; 12692bf73ac6SHong Zhang 12702bf73ac6SHong Zhang header->size[compnum] = component->size; 12712bf73ac6SHong Zhang ierr = PetscSectionAddDof(network->DataSection,p,component->size);CHKERRQ(ierr); 12722bf73ac6SHong Zhang header->key[compnum] = componentkey; 12732bf73ac6SHong Zhang if (compnum != 0) header->offset[compnum] = header->offset[compnum-1] + header->size[compnum-1]; 12742bf73ac6SHong Zhang cvalue->data[compnum] = (void*)compvalue; 12752bf73ac6SHong Zhang 12762bf73ac6SHong Zhang /* variables */ 12772bf73ac6SHong Zhang header->nvar[compnum] += nvar; 12782bf73ac6SHong Zhang if (compnum != 0) header->offsetvarrel[compnum] = header->offsetvarrel[compnum-1] + header->nvar[compnum-1]; 12792bf73ac6SHong Zhang 12802bf73ac6SHong Zhang header->ndata++; 12815f2c45f1SShri Abhyankar PetscFunctionReturn(0); 12825f2c45f1SShri Abhyankar } 12835f2c45f1SShri Abhyankar 128427f51fceSHong Zhang /*@ 12852bf73ac6SHong Zhang DMNetworkGetComponent - Gets the component key, the component data, and the number of variables at a given network point 128627f51fceSHong Zhang 128727f51fceSHong Zhang Not Collective 128827f51fceSHong Zhang 128927f51fceSHong Zhang Input Parameters: 12902bf73ac6SHong Zhang + dm - the DMNetwork object 12912bf73ac6SHong Zhang . p - vertex/edge point 129299c90e12SSatish Balay - compnum - component number; use ALL_COMPONENTS if sum up all the components 129327f51fceSHong Zhang 129427f51fceSHong Zhang Output Parameters: 12952bf73ac6SHong Zhang + compkey - the key obtained when registering the component (use NULL if not required) 12962bf73ac6SHong Zhang . component - the component data (use NULL if not required) 12972bf73ac6SHong Zhang - nvar - number of variables (use NULL if not required) 129827f51fceSHong Zhang 129997bb938eSShri Abhyankar Level: beginner 130027f51fceSHong Zhang 13012bf73ac6SHong Zhang .seealso: DMNetworkAddComponent(), DMNetworkGetNumComponents() 130227f51fceSHong Zhang @*/ 13032bf73ac6SHong Zhang PetscErrorCode DMNetworkGetComponent(DM dm,PetscInt p,PetscInt compnum,PetscInt *compkey,void **component,PetscInt *nvar) 130427f51fceSHong Zhang { 130527f51fceSHong Zhang PetscErrorCode ierr; 130627f51fceSHong Zhang DM_Network *network = (DM_Network*)dm->data; 13072bf73ac6SHong Zhang PetscInt offset = 0; 13082bf73ac6SHong Zhang DMNetworkComponentHeader header; 130927f51fceSHong Zhang 131027f51fceSHong Zhang PetscFunctionBegin; 13112bf73ac6SHong Zhang if (compnum == ALL_COMPONENTS) { 131227f51fceSHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 131327f51fceSHong Zhang PetscFunctionReturn(0); 131427f51fceSHong Zhang } 131527f51fceSHong Zhang 13162bf73ac6SHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 13172bf73ac6SHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offset);CHKERRQ(ierr); 13185f2c45f1SShri Abhyankar 13192bf73ac6SHong Zhang if (compnum >= 0) { 13202bf73ac6SHong Zhang if (compkey) *compkey = header->key[compnum]; 13212bf73ac6SHong Zhang if (component) { 1322*54dfd506SHong Zhang offset += header->hsize+header->offset[compnum]; 13232bf73ac6SHong Zhang *component = network->componentdataarray+offset; 13242bf73ac6SHong Zhang } 13252bf73ac6SHong Zhang } 13265f2c45f1SShri Abhyankar 13272bf73ac6SHong Zhang if (nvar) *nvar = header->nvar[compnum]; 1328*54dfd506SHong Zhang 13295f2c45f1SShri Abhyankar PetscFunctionReturn(0); 13305f2c45f1SShri Abhyankar } 13315f2c45f1SShri Abhyankar 13322bf73ac6SHong Zhang /* 13332bf73ac6SHong Zhang Sets up the array that holds the data for all components and its associated section. 13342bf73ac6SHong 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. 13352bf73ac6SHong Zhang */ 13365f2c45f1SShri Abhyankar PetscErrorCode DMNetworkComponentSetUp(DM dm) 13375f2c45f1SShri Abhyankar { 13385f2c45f1SShri Abhyankar PetscErrorCode ierr; 13395f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 1340e53b5ba3SHong Zhang PetscInt arr_size,p,offset,offsetp,ncomp,i; 13412bf73ac6SHong Zhang MPI_Comm comm; 13422bf73ac6SHong Zhang PetscMPIInt size,rank; 13435f2c45f1SShri Abhyankar DMNetworkComponentHeader header; 13445f2c45f1SShri Abhyankar DMNetworkComponentValue cvalue; 13455f2c45f1SShri Abhyankar DMNetworkComponentGenericDataType *componentdataarray; 13465f2c45f1SShri Abhyankar 13475f2c45f1SShri Abhyankar PetscFunctionBegin; 13482bf73ac6SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 13492bf73ac6SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 13502bf73ac6SHong Zhang ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 13512bf73ac6SHong Zhang #if 0 13522bf73ac6SHong Zhang //------------- new 13532bf73ac6SHong Zhang if (size > 1) { /* Sync nvar at shared vertices for all processes */ 13542bf73ac6SHong Zhang PetscSF sf = network->plex->sf; 13552bf73ac6SHong Zhang const PetscInt *degree; 13562bf73ac6SHong Zhang PetscInt i,nleaves_total,*indata,*outdata,nroots,nleaves,nsv,p,ncomp; 13572bf73ac6SHong Zhang const PetscInt *svtx; 13582bf73ac6SHong Zhang PetscBool ghost; 13592bf73ac6SHong Zhang 13602bf73ac6SHong Zhang ierr = PetscSFGetGraph(sf,&nroots,&nleaves,NULL,NULL);CHKERRQ(ierr); 13612bf73ac6SHong Zhang ierr = PetscSFComputeDegreeBegin(sf,°ree);CHKERRQ(ierr); 13622bf73ac6SHong Zhang ierr = PetscSFComputeDegreeEnd(sf,°ree);CHKERRQ(ierr); 13632bf73ac6SHong Zhang nleaves_total=0; 13642bf73ac6SHong Zhang for (i=0; i<nroots; i++) nleaves_total += degree[i]; 13652bf73ac6SHong Zhang printf("[%d] nleaves_total %d\n",rank,nleaves_total); 13662bf73ac6SHong Zhang MPI_Barrier(comm); 13672bf73ac6SHong Zhang 13682bf73ac6SHong Zhang ierr = PetscCalloc2(nleaves_total,&indata,nleaves,&outdata);CHKERRQ(ierr); 13692bf73ac6SHong Zhang 13702bf73ac6SHong Zhang /* Leaves copy user's ncomp to outdata */ 13712bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&nsv,&svtx);CHKERRQ(ierr); 13722bf73ac6SHong Zhang for (i=0; i<nsv; i++) { 13732bf73ac6SHong Zhang p = svtx[i]; 13742bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 13752bf73ac6SHong Zhang if (!ghost) continue; 13762bf73ac6SHong Zhang 13772bf73ac6SHong Zhang header = &network->header[p]; 13782bf73ac6SHong Zhang ncomp = header->ndata; 13792bf73ac6SHong Zhang printf("[%d] leaf has ncomp %d\n",rank,ncomp); 13802bf73ac6SHong Zhang outdata[p] = ncomp; 13812bf73ac6SHong Zhang } 13822bf73ac6SHong Zhang 13832bf73ac6SHong Zhang /* Roots gather ncomp from leaves */ 13842bf73ac6SHong Zhang ierr = PetscSFGatherBegin(sf,MPIU_INT,outdata,indata);CHKERRQ(ierr); 13852bf73ac6SHong Zhang ierr = PetscSFGatherEnd(sf,MPIU_INT,outdata,indata);CHKERRQ(ierr); 13862bf73ac6SHong Zhang ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD,"## Gathered data at multi-roots from leaves\n");CHKERRQ(ierr); 13872bf73ac6SHong Zhang ierr = PetscIntView(nleaves_total,indata,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 13882bf73ac6SHong Zhang 13892bf73ac6SHong Zhang ierr = PetscFree2(indata,outdata);CHKERRQ(ierr); 13902bf73ac6SHong Zhang } 13912bf73ac6SHong Zhang //---------------------- 13922bf73ac6SHong Zhang #endif 13932bf73ac6SHong Zhang 13945f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr); 13955f2c45f1SShri Abhyankar ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr); 1396*54dfd506SHong Zhang ierr = PetscCalloc1(arr_size,&network->componentdataarray);CHKERRQ(ierr); 13975f2c45f1SShri Abhyankar componentdataarray = network->componentdataarray; 13985f2c45f1SShri Abhyankar for (p = network->pStart; p < network->pEnd; p++) { 13995f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 14005f2c45f1SShri Abhyankar /* Copy header */ 14015f2c45f1SShri Abhyankar header = &network->header[p]; 1402*54dfd506SHong Zhang DMNetworkComponentHeader headerinfo=(DMNetworkComponentHeader)(componentdataarray+offsetp); 1403*54dfd506SHong Zhang ierr = PetscMemcpy(headerinfo,header,sizeof(struct _p_DMNetworkComponentHeader));CHKERRQ(ierr); 1404*54dfd506SHong Zhang PetscInt *headerarr = (PetscInt*)(headerinfo+1); 1405*54dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->size,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 1406*54dfd506SHong Zhang headerarr += header->maxcomps; 1407*54dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->key,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 1408*54dfd506SHong Zhang headerarr += header->maxcomps; 1409*54dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->offset,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 1410*54dfd506SHong Zhang headerarr += header->maxcomps; 1411*54dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->nvar,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 1412*54dfd506SHong Zhang headerarr += header->maxcomps; 1413*54dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->offsetvarrel,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 1414*54dfd506SHong Zhang 14155f2c45f1SShri Abhyankar /* Copy data */ 14165f2c45f1SShri Abhyankar cvalue = &network->cvalue[p]; 14175f2c45f1SShri Abhyankar ncomp = header->ndata; 14182bf73ac6SHong Zhang 14195f2c45f1SShri Abhyankar for (i = 0; i < ncomp; i++) { 1420*54dfd506SHong Zhang offset = offsetp + header->hsize + header->offset[i]; 1421302440fdSBarry Smith ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 14225f2c45f1SShri Abhyankar } 14235f2c45f1SShri Abhyankar } 14245f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14255f2c45f1SShri Abhyankar } 14265f2c45f1SShri Abhyankar 14275f2c45f1SShri Abhyankar /* Sets up the section for dofs. This routine is called during DMSetUp() */ 14282bf73ac6SHong Zhang static PetscErrorCode DMNetworkVariablesSetUp(DM dm) 14295f2c45f1SShri Abhyankar { 14305f2c45f1SShri Abhyankar PetscErrorCode ierr; 14315f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 14322bf73ac6SHong Zhang MPI_Comm comm; 14332bf73ac6SHong Zhang PetscMPIInt size; 14345f2c45f1SShri Abhyankar 14355f2c45f1SShri Abhyankar PetscFunctionBegin; 14362bf73ac6SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 14372bf73ac6SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 14382bf73ac6SHong Zhang 14392bf73ac6SHong Zhang if (size > 1) { /* Sync nvar at shared vertices for all processes */ 14402bf73ac6SHong Zhang PetscSF sf = network->plex->sf; 14412bf73ac6SHong Zhang PetscInt *local_nvar, *remote_nvar,nroots,nleaves,p=-1,i,nsv; 14422bf73ac6SHong Zhang const PetscInt *svtx; 14432bf73ac6SHong Zhang PetscBool ghost; 14442bf73ac6SHong Zhang /* 14452bf73ac6SHong Zhang PetscMPIInt rank; 14462bf73ac6SHong Zhang const PetscInt *ilocal; 14472bf73ac6SHong Zhang const PetscSFNode *iremote; 14482bf73ac6SHong Zhang ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 14492bf73ac6SHong Zhang ierr = PetscSFGetGraph(sf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr); 14502bf73ac6SHong Zhang */ 14512bf73ac6SHong Zhang ierr = PetscSFGetGraph(sf,&nroots,&nleaves,NULL,NULL);CHKERRQ(ierr); 14522bf73ac6SHong Zhang ierr = PetscCalloc2(nroots,&local_nvar,nroots,&remote_nvar);CHKERRQ(ierr); 14532bf73ac6SHong Zhang 14542bf73ac6SHong Zhang /* Leaves copy user's nvar to local_nvar */ 14552bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&nsv,&svtx);CHKERRQ(ierr); 14562bf73ac6SHong Zhang for (i=0; i<nsv; i++) { 14572bf73ac6SHong Zhang p = svtx[i]; 14582bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 14592bf73ac6SHong Zhang if (!ghost) continue; 14602bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,&local_nvar[p]);CHKERRQ(ierr); 14612bf73ac6SHong Zhang /* printf("[%d] Before SFReduce: leaf local_nvar[%d] = %d\n",rank,p,local_nvar[p]); */ 14622bf73ac6SHong Zhang } 14632bf73ac6SHong Zhang 14642bf73ac6SHong Zhang /* Leaves add local_nvar to root remote_nvar */ 14652bf73ac6SHong Zhang ierr = PetscSFReduceBegin(sf, MPIU_INT, local_nvar, remote_nvar, MPI_SUM);CHKERRQ(ierr); 14662bf73ac6SHong Zhang ierr = PetscSFReduceEnd(sf, MPIU_INT, local_nvar, remote_nvar, MPI_SUM);CHKERRQ(ierr); 14672bf73ac6SHong Zhang /* printf("[%d] remote_nvar[%d] = %d\n",rank,p,remote_nvar[p]); */ 14682bf73ac6SHong Zhang 14692bf73ac6SHong Zhang /* Update roots' local_nvar */ 14702bf73ac6SHong Zhang for (i=0; i<nsv; i++) { 14712bf73ac6SHong Zhang p = svtx[i]; 14722bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 14732bf73ac6SHong Zhang if (ghost) continue; 14742bf73ac6SHong Zhang 14752bf73ac6SHong Zhang ierr = PetscSectionAddDof(network->DofSection,p,remote_nvar[p]);CHKERRQ(ierr); 14762bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,&local_nvar[p]);CHKERRQ(ierr); 14772bf73ac6SHong Zhang /* printf("[%d] After SFReduce: root local_nvar[%d] = %d\n",rank,p,local_nvar[p]); */ 14782bf73ac6SHong Zhang } 14792bf73ac6SHong Zhang 14802bf73ac6SHong Zhang /* Roots Bcast nvar to leaves */ 1481ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sf, MPIU_INT, local_nvar, remote_nvar,MPI_REPLACE);CHKERRQ(ierr); 1482ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sf, MPIU_INT, local_nvar, remote_nvar,MPI_REPLACE);CHKERRQ(ierr); 14832bf73ac6SHong Zhang 14842bf73ac6SHong Zhang /* Leaves reset receved/remote nvar to dm */ 14852bf73ac6SHong Zhang for (i=0; i<nsv; i++) { 14862bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 14872bf73ac6SHong Zhang if (!ghost) continue; 14882bf73ac6SHong Zhang p = svtx[i]; 14892bf73ac6SHong Zhang /* printf("[%d] leaf reset nvar %d at p= %d \n",rank,remote_nvar[p],p); */ 14902bf73ac6SHong Zhang /* DMNetworkSetNumVariables(dm,p,remote_nvar[p]) */ 14912bf73ac6SHong Zhang ierr = PetscSectionSetDof(network->DofSection,p,remote_nvar[p]);CHKERRQ(ierr); 14922bf73ac6SHong Zhang } 14932bf73ac6SHong Zhang 14942bf73ac6SHong Zhang ierr = PetscFree2(local_nvar,remote_nvar);CHKERRQ(ierr); 14952bf73ac6SHong Zhang } 14962bf73ac6SHong Zhang 14975f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr); 14985f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14995f2c45f1SShri Abhyankar } 15005f2c45f1SShri Abhyankar 150124121865SAdrian Maldonado /* Get a subsection from a range of points */ 15029dddd249SSatish Balay static PetscErrorCode DMNetworkGetSubSection_private(PetscSection main,PetscInt pstart,PetscInt pend,PetscSection *subsection) 150324121865SAdrian Maldonado { 150424121865SAdrian Maldonado PetscErrorCode ierr; 150524121865SAdrian Maldonado PetscInt i, nvar; 150624121865SAdrian Maldonado 150724121865SAdrian Maldonado PetscFunctionBegin; 15089dddd249SSatish Balay ierr = PetscSectionCreate(PetscObjectComm((PetscObject)main), subsection);CHKERRQ(ierr); 150924121865SAdrian Maldonado ierr = PetscSectionSetChart(*subsection, 0, pend - pstart);CHKERRQ(ierr); 151024121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 15119dddd249SSatish Balay ierr = PetscSectionGetDof(main,i,&nvar);CHKERRQ(ierr); 151224121865SAdrian Maldonado ierr = PetscSectionSetDof(*subsection, i - pstart, nvar);CHKERRQ(ierr); 151324121865SAdrian Maldonado } 151424121865SAdrian Maldonado 151524121865SAdrian Maldonado ierr = PetscSectionSetUp(*subsection);CHKERRQ(ierr); 151624121865SAdrian Maldonado PetscFunctionReturn(0); 151724121865SAdrian Maldonado } 151824121865SAdrian Maldonado 151924121865SAdrian Maldonado /* Create a submap of points with a GlobalToLocal structure */ 15202bf73ac6SHong Zhang static PetscErrorCode DMNetworkSetSubMap_private(PetscInt pstart, PetscInt pend, ISLocalToGlobalMapping *map) 152124121865SAdrian Maldonado { 152224121865SAdrian Maldonado PetscErrorCode ierr; 152324121865SAdrian Maldonado PetscInt i, *subpoints; 152424121865SAdrian Maldonado 152524121865SAdrian Maldonado PetscFunctionBegin; 152624121865SAdrian Maldonado /* Create index sets to map from "points" to "subpoints" */ 152724121865SAdrian Maldonado ierr = PetscMalloc1(pend - pstart, &subpoints);CHKERRQ(ierr); 152824121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 152924121865SAdrian Maldonado subpoints[i - pstart] = i; 153024121865SAdrian Maldonado } 1531459726d8SSatish Balay ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,pend-pstart,subpoints,PETSC_COPY_VALUES,map);CHKERRQ(ierr); 153224121865SAdrian Maldonado ierr = PetscFree(subpoints);CHKERRQ(ierr); 153324121865SAdrian Maldonado PetscFunctionReturn(0); 153424121865SAdrian Maldonado } 153524121865SAdrian Maldonado 153624121865SAdrian Maldonado /*@ 15372bf73ac6SHong Zhang DMNetworkAssembleGraphStructures - Assembles vertex and edge data structures. Must be called after DMNetworkDistribute 153824121865SAdrian Maldonado 15392bf73ac6SHong Zhang Collective on dm 154024121865SAdrian Maldonado 154124121865SAdrian Maldonado Input Parameters: 15422bf73ac6SHong Zhang . dm - the DMNetworkObject 154324121865SAdrian Maldonado 154424121865SAdrian Maldonado Note: the routine will create alternative orderings for the vertices and edges. Assume global network points are: 154524121865SAdrian Maldonado 154624121865SAdrian Maldonado points = [0 1 2 3 4 5 6] 154724121865SAdrian Maldonado 1548caf410d2SHong 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]). 154924121865SAdrian Maldonado 155024121865SAdrian Maldonado With this new ordering a local PetscSection, global PetscSection and PetscSF will be created specific to the subset. 155124121865SAdrian Maldonado 155224121865SAdrian Maldonado Level: intermediate 155324121865SAdrian Maldonado 155424121865SAdrian Maldonado @*/ 155524121865SAdrian Maldonado PetscErrorCode DMNetworkAssembleGraphStructures(DM dm) 155624121865SAdrian Maldonado { 155724121865SAdrian Maldonado PetscErrorCode ierr; 155824121865SAdrian Maldonado MPI_Comm comm; 15599852e123SBarry Smith PetscMPIInt rank, size; 156024121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 156124121865SAdrian Maldonado 1562eab1376dSHong Zhang PetscFunctionBegin; 156324121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 1564ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 1565ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 156624121865SAdrian Maldonado 156724121865SAdrian Maldonado /* Create maps for vertices and edges */ 156824121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 156924121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->eStart,network->eEnd,&network->edge.mapping);CHKERRQ(ierr); 157024121865SAdrian Maldonado 157124121865SAdrian Maldonado /* Create local sub-sections */ 157224121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->vStart,network->vEnd,&network->vertex.DofSection);CHKERRQ(ierr); 157324121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->eStart,network->eEnd,&network->edge.DofSection);CHKERRQ(ierr); 157424121865SAdrian Maldonado 15759852e123SBarry Smith if (size > 1) { 157624121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 157722bbedd7SHong Zhang 157824121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->vertex.DofSection, network->vertex.sf, PETSC_FALSE, PETSC_FALSE, &network->vertex.GlobalDofSection);CHKERRQ(ierr); 157924121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->edge.mapping, &network->edge.sf);CHKERRQ(ierr); 158024121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->edge.DofSection, network->edge.sf, PETSC_FALSE, PETSC_FALSE, &network->edge.GlobalDofSection);CHKERRQ(ierr); 158124121865SAdrian Maldonado } else { 158224121865SAdrian Maldonado /* create structures for vertex */ 158324121865SAdrian Maldonado ierr = PetscSectionClone(network->vertex.DofSection,&network->vertex.GlobalDofSection);CHKERRQ(ierr); 158424121865SAdrian Maldonado /* create structures for edge */ 158524121865SAdrian Maldonado ierr = PetscSectionClone(network->edge.DofSection,&network->edge.GlobalDofSection);CHKERRQ(ierr); 158624121865SAdrian Maldonado } 158724121865SAdrian Maldonado 158824121865SAdrian Maldonado /* Add viewers */ 158924121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->edge.GlobalDofSection,"Global edge dof section");CHKERRQ(ierr); 159024121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->vertex.GlobalDofSection,"Global vertex dof section");CHKERRQ(ierr); 159124121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->edge.GlobalDofSection, NULL, "-edge_global_section_view");CHKERRQ(ierr); 159224121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->vertex.GlobalDofSection, NULL, "-vertex_global_section_view");CHKERRQ(ierr); 159324121865SAdrian Maldonado PetscFunctionReturn(0); 159424121865SAdrian Maldonado } 15957b6afd5bSHong Zhang 15965f2c45f1SShri Abhyankar /*@ 15972bf73ac6SHong Zhang DMNetworkDistribute - Distributes the network and moves associated component data 15985f2c45f1SShri Abhyankar 15995f2c45f1SShri Abhyankar Collective 16005f2c45f1SShri Abhyankar 16015f2c45f1SShri Abhyankar Input Parameter: 1602d3464fd4SAdrian Maldonado + DM - the DMNetwork object 16032bf73ac6SHong Zhang - overlap - the overlap of partitions, 0 is the default 16045f2c45f1SShri Abhyankar 16055f2c45f1SShri Abhyankar Notes: 16068b171c8eSHong Zhang Distributes the network with <overlap>-overlapping partitioning of the edges. 16075f2c45f1SShri Abhyankar 16085f2c45f1SShri Abhyankar Level: intermediate 16095f2c45f1SShri Abhyankar 16102bf73ac6SHong Zhang .seealso: DMNetworkCreate() 16115f2c45f1SShri Abhyankar @*/ 1612d3464fd4SAdrian Maldonado PetscErrorCode DMNetworkDistribute(DM *dm,PetscInt overlap) 16135f2c45f1SShri Abhyankar { 1614d3464fd4SAdrian Maldonado MPI_Comm comm; 16155f2c45f1SShri Abhyankar PetscErrorCode ierr; 1616d3464fd4SAdrian Maldonado PetscMPIInt size; 1617d3464fd4SAdrian Maldonado DM_Network *oldDMnetwork = (DM_Network*)((*dm)->data); 1618d3464fd4SAdrian Maldonado DM_Network *newDMnetwork; 1619caf410d2SHong Zhang PetscSF pointsf=NULL; 16205f2c45f1SShri Abhyankar DM newDM; 16212bf73ac6SHong Zhang PetscInt j,e,v,offset,*subnetvtx,nsubnet,gidx,svtx_idx,nv; 16222bf73ac6SHong Zhang PetscInt to_net,from_net,*svto; 162351ac5effSHong Zhang PetscPartitioner part; 1624b9c6e19dSShri Abhyankar DMNetworkComponentHeader header; 16255f2c45f1SShri Abhyankar 16265f2c45f1SShri Abhyankar PetscFunctionBegin; 1627d3464fd4SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)*dm,&comm);CHKERRQ(ierr); 1628ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 1629d3464fd4SAdrian Maldonado if (size == 1) PetscFunctionReturn(0); 1630d3464fd4SAdrian Maldonado 16312bf73ac6SHong 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. */ 1632d3464fd4SAdrian Maldonado ierr = DMNetworkCreate(PetscObjectComm((PetscObject)*dm),&newDM);CHKERRQ(ierr); 16335f2c45f1SShri Abhyankar newDMnetwork = (DM_Network*)newDM->data; 1634*54dfd506SHong Zhang newDMnetwork->max_comps_registered = oldDMnetwork->max_comps_registered; 1635*54dfd506SHong Zhang ierr = PetscMalloc1(newDMnetwork->max_comps_registered,&newDMnetwork->component);CHKERRQ(ierr); 163651ac5effSHong Zhang 163751ac5effSHong Zhang /* Enable runtime options for petscpartitioner */ 163851ac5effSHong Zhang ierr = DMPlexGetPartitioner(oldDMnetwork->plex,&part);CHKERRQ(ierr); 163951ac5effSHong Zhang ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); 164051ac5effSHong Zhang 16412bf73ac6SHong Zhang /* Distribute plex dm */ 164280cf41d5SMatthew G. Knepley ierr = DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr); 164351ac5effSHong Zhang 16445f2c45f1SShri Abhyankar /* Distribute dof section */ 16452bf73ac6SHong Zhang ierr = PetscSectionCreate(comm,&newDMnetwork->DofSection);CHKERRQ(ierr); 16465f2c45f1SShri Abhyankar ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr); 164751ac5effSHong Zhang 16485f2c45f1SShri Abhyankar /* Distribute data and associated section */ 16492bf73ac6SHong Zhang ierr = PetscSectionCreate(comm,&newDMnetwork->DataSection);CHKERRQ(ierr); 165031da1fc8SHong Zhang ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPIU_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr); 165124121865SAdrian Maldonado 16525f2c45f1SShri Abhyankar ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr); 16535f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr); 16545f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr); 16555f2c45f1SShri Abhyankar newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart; 16566fefedf4SHong Zhang newDMnetwork->nVertices = newDMnetwork->vEnd - newDMnetwork->vStart; 16576fefedf4SHong Zhang newDMnetwork->NVertices = oldDMnetwork->NVertices; 16585f2c45f1SShri Abhyankar newDMnetwork->NEdges = oldDMnetwork->NEdges; 16592bf73ac6SHong Zhang newDMnetwork->svtable = oldDMnetwork->svtable; 16602bf73ac6SHong Zhang oldDMnetwork->svtable = NULL; 166124121865SAdrian Maldonado 16621bb6d2a8SBarry Smith /* Set Dof section as the section for dm */ 166392fd8e1eSJed Brown ierr = DMSetLocalSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr); 1664e87a4003SBarry Smith ierr = DMGetGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr); 16655f2c45f1SShri Abhyankar 1666b9c6e19dSShri Abhyankar /* Set up subnetwork info in the newDM */ 16672bf73ac6SHong Zhang newDMnetwork->Nsubnet = oldDMnetwork->Nsubnet; 16682bf73ac6SHong Zhang newDMnetwork->Nsvtx = oldDMnetwork->Nsvtx; 16692bf73ac6SHong Zhang oldDMnetwork->Nsvtx = 0; 16702bf73ac6SHong Zhang newDMnetwork->svtx = oldDMnetwork->svtx; /* global vertices! */ 16712bf73ac6SHong Zhang oldDMnetwork->svtx = NULL; 16722bf73ac6SHong Zhang ierr = PetscCalloc1(newDMnetwork->Nsubnet,&newDMnetwork->subnet);CHKERRQ(ierr); 16732bf73ac6SHong Zhang 16742bf73ac6SHong Zhang /* Copy over the global number of vertices and edges in each subnetwork. 16752bf73ac6SHong Zhang Note: these are calculated in DMNetworkLayoutSetUp() 1676b9c6e19dSShri Abhyankar */ 16772bf73ac6SHong Zhang nsubnet = newDMnetwork->Nsubnet; 16782bf73ac6SHong Zhang for (j = 0; j < nsubnet; j++) { 1679b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nvtx = oldDMnetwork->subnet[j].Nvtx; 1680b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nedge = oldDMnetwork->subnet[j].Nedge; 1681b9c6e19dSShri Abhyankar } 1682b9c6e19dSShri Abhyankar 1683*54dfd506SHong Zhang PetscMPIInt rank; 1684*54dfd506SHong Zhang ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 1685*54dfd506SHong Zhang 16862bf73ac6SHong Zhang /* Get local nedges and nvtx for subnetworks */ 1687b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++) { 1688b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 1689*54dfd506SHong Zhang header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset); 1690*54dfd506SHong Zhang /* Update pointers */ 1691*54dfd506SHong Zhang header->size = (PetscInt*)(header + 1); 1692*54dfd506SHong Zhang header->key = header->size + header->maxcomps; 1693*54dfd506SHong Zhang header->offset = header->key + header->maxcomps; 1694*54dfd506SHong Zhang header->nvar = header->offset + header->maxcomps; 1695*54dfd506SHong Zhang header->offsetvarrel = header->nvar + header->maxcomps; 1696*54dfd506SHong Zhang 1697b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nedge++; 1698b9c6e19dSShri Abhyankar } 1699b9c6e19dSShri Abhyankar 1700b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++) { 1701b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1702b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 17032bf73ac6SHong Zhang 1704*54dfd506SHong Zhang /* Update pointers */ 1705*54dfd506SHong Zhang header->size = (PetscInt*)(header + 1); 1706*54dfd506SHong Zhang header->key = header->size + header->maxcomps; 1707*54dfd506SHong Zhang header->offset = header->key + header->maxcomps; 1708*54dfd506SHong Zhang header->nvar = header->offset + header->maxcomps; 1709*54dfd506SHong Zhang header->offsetvarrel = header->nvar + header->maxcomps; 1710*54dfd506SHong Zhang 17112bf73ac6SHong Zhang /* shared vertices: use gidx = header->index to check if v is a shared vertex */ 17122bf73ac6SHong Zhang gidx = header->index; 17132bf73ac6SHong Zhang ierr = PetscTableFind(newDMnetwork->svtable,gidx+1,&svtx_idx);CHKERRQ(ierr); 17142bf73ac6SHong Zhang svtx_idx--; 17152bf73ac6SHong Zhang 17162bf73ac6SHong Zhang if (svtx_idx < 0) { /* not a shared vertex */ 1717b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nvtx++; 17182bf73ac6SHong Zhang } else { /* a shared vertex belongs to more than one subnetworks, it is being counted by multiple subnets */ 17192bf73ac6SHong Zhang from_net = newDMnetwork->svtx[svtx_idx].sv[0]; 17202bf73ac6SHong Zhang newDMnetwork->subnet[from_net].nvtx++; 17212bf73ac6SHong Zhang for (j=1; j<newDMnetwork->svtx[svtx_idx].n; j++) { 17222bf73ac6SHong Zhang svto = newDMnetwork->svtx[svtx_idx].sv + 2*j; 17232bf73ac6SHong Zhang to_net = svto[0]; 17242bf73ac6SHong Zhang newDMnetwork->subnet[to_net].nvtx++; 17252bf73ac6SHong Zhang } 17262bf73ac6SHong Zhang } 1727b9c6e19dSShri Abhyankar } 1728b9c6e19dSShri Abhyankar 17292bf73ac6SHong Zhang /* Get total local nvtx for subnetworks */ 17302bf73ac6SHong Zhang nv = 0; 17312bf73ac6SHong Zhang for (j=0; j<nsubnet; j++) nv += newDMnetwork->subnet[j].nvtx; 17322bf73ac6SHong Zhang nv += newDMnetwork->Nsvtx; 1733caf410d2SHong Zhang 17342bf73ac6SHong Zhang /* Now create the vertices and edge arrays for the subnetworks */ 17352bf73ac6SHong Zhang ierr = PetscCalloc1(nv,&subnetvtx);CHKERRQ(ierr); 17362bf73ac6SHong Zhang newDMnetwork->subnetvtx = subnetvtx; 17372bf73ac6SHong Zhang 17382bf73ac6SHong Zhang for (j=0; j<nsubnet; j++) { 1739b9c6e19dSShri Abhyankar ierr = PetscCalloc1(newDMnetwork->subnet[j].nedge,&newDMnetwork->subnet[j].edges);CHKERRQ(ierr); 1740caf410d2SHong Zhang newDMnetwork->subnet[j].vertices = subnetvtx; 1741caf410d2SHong Zhang subnetvtx += newDMnetwork->subnet[j].nvtx; 1742caf410d2SHong Zhang 17432bf73ac6SHong 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. */ 1744b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].nvtx = newDMnetwork->subnet[j].nedge = 0; 1745b9c6e19dSShri Abhyankar } 17462bf73ac6SHong Zhang newDMnetwork->svertices = subnetvtx; 1747b9c6e19dSShri Abhyankar 17482bf73ac6SHong Zhang /* Set the edges and vertices in each subnetwork */ 1749b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++) { 1750b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 1751b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1752b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].edges[newDMnetwork->subnet[header->subnetid].nedge++] = e; 1753b9c6e19dSShri Abhyankar } 1754b9c6e19dSShri Abhyankar 17552bf73ac6SHong Zhang nv = 0; 1756b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++) { 1757b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1758b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 17592bf73ac6SHong Zhang 17602bf73ac6SHong Zhang /* coupling vertices: use gidx = header->index to check if v is a coupling vertex */ 17612bf73ac6SHong Zhang ierr = PetscTableFind(newDMnetwork->svtable,header->index+1,&svtx_idx);CHKERRQ(ierr); 17622bf73ac6SHong Zhang svtx_idx--; 17632bf73ac6SHong Zhang if (svtx_idx < 0) { 1764b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].vertices[newDMnetwork->subnet[header->subnetid].nvtx++] = v; 17652bf73ac6SHong Zhang } else { /* a shared vertex */ 17662bf73ac6SHong Zhang newDMnetwork->svertices[nv++] = v; 17672bf73ac6SHong Zhang 17682bf73ac6SHong Zhang from_net = newDMnetwork->svtx[svtx_idx].sv[0]; 17692bf73ac6SHong Zhang newDMnetwork->subnet[from_net].vertices[newDMnetwork->subnet[from_net].nvtx++] = v; 17702bf73ac6SHong Zhang 17712bf73ac6SHong Zhang for (j=1; j<newDMnetwork->svtx[svtx_idx].n; j++) { 17722bf73ac6SHong Zhang svto = newDMnetwork->svtx[svtx_idx].sv + 2*j; 17732bf73ac6SHong Zhang to_net = svto[0]; 17742bf73ac6SHong Zhang newDMnetwork->subnet[to_net].vertices[newDMnetwork->subnet[to_net].nvtx++] = v; 1775b9c6e19dSShri Abhyankar } 17762bf73ac6SHong Zhang } 17772bf73ac6SHong Zhang } 17782bf73ac6SHong Zhang newDMnetwork->nsvtx = nv; /* num of local shared vertices */ 1779b9c6e19dSShri Abhyankar 1780caf410d2SHong Zhang newDM->setupcalled = (*dm)->setupcalled; 178122bbedd7SHong Zhang newDMnetwork->distributecalled = PETSC_TRUE; 1782caf410d2SHong Zhang 17832bf73ac6SHong Zhang /* Free spaces */ 178424121865SAdrian Maldonado ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr); 1785d3464fd4SAdrian Maldonado ierr = DMDestroy(dm);CHKERRQ(ierr); 17862bf73ac6SHong Zhang 1787d3464fd4SAdrian Maldonado *dm = newDM; 17885f2c45f1SShri Abhyankar PetscFunctionReturn(0); 17895f2c45f1SShri Abhyankar } 17905f2c45f1SShri Abhyankar 179124121865SAdrian Maldonado /*@C 17922bf73ac6SHong Zhang PetscSFGetSubSF - Returns an SF for a specific subset of points. Leaves are re-numbered to reflect the new ordering 17932bf73ac6SHong Zhang 17942bf73ac6SHong Zhang Collective 179524121865SAdrian Maldonado 179624121865SAdrian Maldonado Input Parameters: 17979dddd249SSatish Balay + mainSF - the original SF structure 179824121865SAdrian Maldonado - map - a ISLocalToGlobal mapping that contains the subset of points 179924121865SAdrian Maldonado 180024121865SAdrian Maldonado Output Parameters: 18019dddd249SSatish Balay . subSF - a subset of the mainSF for the desired subset. 1802ee300463SSatish Balay 1803ee300463SSatish Balay Level: intermediate 18047d928bffSSatish Balay @*/ 18059dddd249SSatish Balay PetscErrorCode PetscSFGetSubSF(PetscSF mainsf,ISLocalToGlobalMapping map,PetscSF *subSF) 18062bf73ac6SHong Zhang { 180724121865SAdrian Maldonado PetscErrorCode ierr; 180824121865SAdrian Maldonado PetscInt nroots, nleaves, *ilocal_sub; 180924121865SAdrian Maldonado PetscInt i, *ilocal_map, nroots_sub, nleaves_sub = 0; 181024121865SAdrian Maldonado PetscInt *local_points, *remote_points; 181124121865SAdrian Maldonado PetscSFNode *iremote_sub; 181224121865SAdrian Maldonado const PetscInt *ilocal; 181324121865SAdrian Maldonado const PetscSFNode *iremote; 181424121865SAdrian Maldonado 181524121865SAdrian Maldonado PetscFunctionBegin; 18169dddd249SSatish Balay ierr = PetscSFGetGraph(mainsf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr); 181724121865SAdrian Maldonado 181824121865SAdrian Maldonado /* Look for leaves that pertain to the subset of points. Get the local ordering */ 181924121865SAdrian Maldonado ierr = PetscMalloc1(nleaves,&ilocal_map);CHKERRQ(ierr); 182024121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nleaves,ilocal,NULL,ilocal_map);CHKERRQ(ierr); 182124121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 182224121865SAdrian Maldonado if (ilocal_map[i] != -1) nleaves_sub += 1; 182324121865SAdrian Maldonado } 182424121865SAdrian Maldonado /* Re-number ilocal with subset numbering. Need information from roots */ 182524121865SAdrian Maldonado ierr = PetscMalloc2(nroots,&local_points,nroots,&remote_points);CHKERRQ(ierr); 182624121865SAdrian Maldonado for (i = 0; i < nroots; i++) local_points[i] = i; 182724121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nroots,local_points,NULL,local_points);CHKERRQ(ierr); 1828ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(mainsf, MPIU_INT, local_points, remote_points,MPI_REPLACE);CHKERRQ(ierr); 1829ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(mainsf, MPIU_INT, local_points, remote_points,MPI_REPLACE);CHKERRQ(ierr); 183024121865SAdrian Maldonado /* Fill up graph using local (that is, local to the subset) numbering. */ 18314b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&ilocal_sub);CHKERRQ(ierr); 18324b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&iremote_sub);CHKERRQ(ierr); 183324121865SAdrian Maldonado nleaves_sub = 0; 183424121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 183524121865SAdrian Maldonado if (ilocal_map[i] != -1) { 183624121865SAdrian Maldonado ilocal_sub[nleaves_sub] = ilocal_map[i]; 18374b70a8deSAdrian Maldonado iremote_sub[nleaves_sub].rank = iremote[i].rank; 183824121865SAdrian Maldonado iremote_sub[nleaves_sub].index = remote_points[ilocal[i]]; 183924121865SAdrian Maldonado nleaves_sub += 1; 184024121865SAdrian Maldonado } 184124121865SAdrian Maldonado } 184224121865SAdrian Maldonado ierr = PetscFree2(local_points,remote_points);CHKERRQ(ierr); 184324121865SAdrian Maldonado ierr = ISLocalToGlobalMappingGetSize(map,&nroots_sub);CHKERRQ(ierr); 184424121865SAdrian Maldonado 184524121865SAdrian Maldonado /* Create new subSF */ 184624121865SAdrian Maldonado ierr = PetscSFCreate(PETSC_COMM_WORLD,subSF);CHKERRQ(ierr); 184724121865SAdrian Maldonado ierr = PetscSFSetFromOptions(*subSF);CHKERRQ(ierr); 18484b70a8deSAdrian Maldonado ierr = PetscSFSetGraph(*subSF,nroots_sub,nleaves_sub,ilocal_sub,PETSC_OWN_POINTER,iremote_sub,PETSC_COPY_VALUES);CHKERRQ(ierr); 184924121865SAdrian Maldonado ierr = PetscFree(ilocal_map);CHKERRQ(ierr); 18504b70a8deSAdrian Maldonado ierr = PetscFree(iremote_sub);CHKERRQ(ierr); 185124121865SAdrian Maldonado PetscFunctionReturn(0); 185224121865SAdrian Maldonado } 185324121865SAdrian Maldonado 18545f2c45f1SShri Abhyankar /*@C 18555f2c45f1SShri Abhyankar DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point 18565f2c45f1SShri Abhyankar 18575f2c45f1SShri Abhyankar Not Collective 18585f2c45f1SShri Abhyankar 18595f2c45f1SShri Abhyankar Input Parameters: 18602bf73ac6SHong Zhang + dm - the DMNetwork object 18615f2c45f1SShri Abhyankar - p - the vertex point 18625f2c45f1SShri Abhyankar 1863fd292e60Sprj- Output Parameters: 18645f2c45f1SShri Abhyankar + nedges - number of edges connected to this vertex point 18652bf73ac6SHong Zhang - edges - list of edge points 18665f2c45f1SShri Abhyankar 186797bb938eSShri Abhyankar Level: beginner 18685f2c45f1SShri Abhyankar 18695f2c45f1SShri Abhyankar Fortran Notes: 18705f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 18715f2c45f1SShri Abhyankar include petsc.h90 in your code. 18725f2c45f1SShri Abhyankar 18732bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkGetConnectedVertices() 18745f2c45f1SShri Abhyankar @*/ 18755f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[]) 18765f2c45f1SShri Abhyankar { 18775f2c45f1SShri Abhyankar PetscErrorCode ierr; 18785f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 18795f2c45f1SShri Abhyankar 18805f2c45f1SShri Abhyankar PetscFunctionBegin; 18815f2c45f1SShri Abhyankar ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr); 1882a9b4a83eSHong Zhang if (edges) {ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr);} 18835f2c45f1SShri Abhyankar PetscFunctionReturn(0); 18845f2c45f1SShri Abhyankar } 18855f2c45f1SShri Abhyankar 18865f2c45f1SShri Abhyankar /*@C 1887d842c372SHong Zhang DMNetworkGetConnectedVertices - Return the connected vertices for this edge point 18885f2c45f1SShri Abhyankar 18895f2c45f1SShri Abhyankar Not Collective 18905f2c45f1SShri Abhyankar 18915f2c45f1SShri Abhyankar Input Parameters: 18922bf73ac6SHong Zhang + dm - the DMNetwork object 18935f2c45f1SShri Abhyankar - p - the edge point 18945f2c45f1SShri Abhyankar 1895fd292e60Sprj- Output Parameters: 18965f2c45f1SShri Abhyankar . vertices - vertices connected to this edge 18975f2c45f1SShri Abhyankar 189897bb938eSShri Abhyankar Level: beginner 18995f2c45f1SShri Abhyankar 19005f2c45f1SShri Abhyankar Fortran Notes: 19015f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 19025f2c45f1SShri Abhyankar include petsc.h90 in your code. 19035f2c45f1SShri Abhyankar 19042bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkGetSupportingEdges() 19055f2c45f1SShri Abhyankar @*/ 1906d842c372SHong Zhang PetscErrorCode DMNetworkGetConnectedVertices(DM dm,PetscInt edge,const PetscInt *vertices[]) 19075f2c45f1SShri Abhyankar { 19085f2c45f1SShri Abhyankar PetscErrorCode ierr; 19095f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 19105f2c45f1SShri Abhyankar 19115f2c45f1SShri Abhyankar PetscFunctionBegin; 19125f2c45f1SShri Abhyankar ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr); 19135f2c45f1SShri Abhyankar PetscFunctionReturn(0); 19145f2c45f1SShri Abhyankar } 19155f2c45f1SShri Abhyankar 19165f2c45f1SShri Abhyankar /*@ 19172bf73ac6SHong Zhang DMNetworkIsSharedVertex - Returns TRUE if the vertex is shared by subnetworks 19182bf73ac6SHong Zhang 19192bf73ac6SHong Zhang Not Collective 19202bf73ac6SHong Zhang 19212bf73ac6SHong Zhang Input Parameters: 19222bf73ac6SHong Zhang + dm - the DMNetwork object 19232bf73ac6SHong Zhang - p - the vertex point 19242bf73ac6SHong Zhang 19252bf73ac6SHong Zhang Output Parameter: 19262bf73ac6SHong Zhang . flag - TRUE if the vertex is shared by subnetworks 19272bf73ac6SHong Zhang 19282bf73ac6SHong Zhang Level: beginner 19292bf73ac6SHong Zhang 19302bf73ac6SHong Zhang .seealso: DMNetworkAddSharedVertices(), DMNetworkIsGhostVertex() 19312bf73ac6SHong Zhang @*/ 19322bf73ac6SHong Zhang PetscErrorCode DMNetworkIsSharedVertex(DM dm,PetscInt p,PetscBool *flag) 19332bf73ac6SHong Zhang { 19342bf73ac6SHong Zhang PetscErrorCode ierr; 19352bf73ac6SHong Zhang PetscInt i; 19362bf73ac6SHong Zhang 19372bf73ac6SHong Zhang PetscFunctionBegin; 19382bf73ac6SHong Zhang *flag = PETSC_FALSE; 19392bf73ac6SHong Zhang 19402bf73ac6SHong Zhang if (dm->setupcalled) { /* DMNetworkGetGlobalVertexIndex() requires DMSetUp() be called */ 19412bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 19422bf73ac6SHong Zhang PetscInt gidx; 19432bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,p,&gidx);CHKERRQ(ierr); 19442bf73ac6SHong Zhang ierr = PetscTableFind(network->svtable,gidx+1,&i);CHKERRQ(ierr); 19452bf73ac6SHong Zhang if (i) *flag = PETSC_TRUE; 19462bf73ac6SHong Zhang } else { /* would be removed? */ 19472bf73ac6SHong Zhang PetscInt nv; 19482bf73ac6SHong Zhang const PetscInt *vtx; 19492bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&nv,&vtx);CHKERRQ(ierr); 19502bf73ac6SHong Zhang for (i=0; i<nv; i++) { 19512bf73ac6SHong Zhang if (p == vtx[i]) { 19522bf73ac6SHong Zhang *flag = PETSC_TRUE; 19532bf73ac6SHong Zhang break; 19542bf73ac6SHong Zhang } 19552bf73ac6SHong Zhang } 19562bf73ac6SHong Zhang } 19572bf73ac6SHong Zhang PetscFunctionReturn(0); 19582bf73ac6SHong Zhang } 19592bf73ac6SHong Zhang 19602bf73ac6SHong Zhang /*@ 19615f2c45f1SShri Abhyankar DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex 19625f2c45f1SShri Abhyankar 19635f2c45f1SShri Abhyankar Not Collective 19645f2c45f1SShri Abhyankar 19655f2c45f1SShri Abhyankar Input Parameters: 19662bf73ac6SHong Zhang + dm - the DMNetwork object 1967a2b725a8SWilliam Gropp - p - the vertex point 19685f2c45f1SShri Abhyankar 19695f2c45f1SShri Abhyankar Output Parameter: 19705f2c45f1SShri Abhyankar . isghost - TRUE if the vertex is a ghost point 19715f2c45f1SShri Abhyankar 197297bb938eSShri Abhyankar Level: beginner 19735f2c45f1SShri Abhyankar 19742bf73ac6SHong Zhang .seealso: DMNetworkGetConnectedVertices(), DMNetworkGetVertexRange(), DMNetworkIsSharedVertex() 19755f2c45f1SShri Abhyankar @*/ 19765f2c45f1SShri Abhyankar PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost) 19775f2c45f1SShri Abhyankar { 19785f2c45f1SShri Abhyankar PetscErrorCode ierr; 19795f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 19805f2c45f1SShri Abhyankar PetscInt offsetg; 19815f2c45f1SShri Abhyankar PetscSection sectiong; 19825f2c45f1SShri Abhyankar 19835f2c45f1SShri Abhyankar PetscFunctionBegin; 19845f2c45f1SShri Abhyankar *isghost = PETSC_FALSE; 1985e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§iong);CHKERRQ(ierr); 19865f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr); 19875f2c45f1SShri Abhyankar if (offsetg < 0) *isghost = PETSC_TRUE; 19885f2c45f1SShri Abhyankar PetscFunctionReturn(0); 19895f2c45f1SShri Abhyankar } 19905f2c45f1SShri Abhyankar 19915f2c45f1SShri Abhyankar PetscErrorCode DMSetUp_Network(DM dm) 19925f2c45f1SShri Abhyankar { 19935f2c45f1SShri Abhyankar PetscErrorCode ierr; 19945f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 19955f2c45f1SShri Abhyankar 19965f2c45f1SShri Abhyankar PetscFunctionBegin; 19975f2c45f1SShri Abhyankar ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr); 19985f2c45f1SShri Abhyankar ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr); 19995f2c45f1SShri Abhyankar 200092fd8e1eSJed Brown ierr = DMSetLocalSection(network->plex,network->DofSection);CHKERRQ(ierr); 2001e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr); 20029e1d080bSHong Zhang 20039e1d080bSHong Zhang dm->setupcalled = PETSC_TRUE; 20049e1d080bSHong Zhang ierr = DMViewFromOptions(dm,NULL,"-dm_view");CHKERRQ(ierr); 20055f2c45f1SShri Abhyankar PetscFunctionReturn(0); 20065f2c45f1SShri Abhyankar } 20075f2c45f1SShri Abhyankar 20081ad426b7SHong Zhang /*@ 200917df6e9eSHong Zhang DMNetworkHasJacobian - Sets global flag for using user's sub Jacobian matrices 20101ad426b7SHong Zhang -- replaced by DMNetworkSetOption(network,userjacobian,PETSC_TURE)? 20111ad426b7SHong Zhang 20121ad426b7SHong Zhang Collective 20131ad426b7SHong Zhang 20141ad426b7SHong Zhang Input Parameters: 20152bf73ac6SHong Zhang + dm - the DMNetwork object 201683b2e829SHong Zhang . eflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for edges 201783b2e829SHong Zhang - vflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for vertices 20181ad426b7SHong Zhang 20191ad426b7SHong Zhang Level: intermediate 20201ad426b7SHong Zhang 20211ad426b7SHong Zhang @*/ 202283b2e829SHong Zhang PetscErrorCode DMNetworkHasJacobian(DM dm,PetscBool eflg,PetscBool vflg) 20231ad426b7SHong Zhang { 20241ad426b7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 20258675203cSHong Zhang PetscErrorCode ierr; 202666b4e0ffSHong Zhang PetscInt nVertices = network->nVertices; 20271ad426b7SHong Zhang 20281ad426b7SHong Zhang PetscFunctionBegin; 202983b2e829SHong Zhang network->userEdgeJacobian = eflg; 203083b2e829SHong Zhang network->userVertexJacobian = vflg; 20318675203cSHong Zhang 20328675203cSHong Zhang if (eflg && !network->Je) { 20338675203cSHong Zhang ierr = PetscCalloc1(3*network->nEdges,&network->Je);CHKERRQ(ierr); 20348675203cSHong Zhang } 20358675203cSHong Zhang 203666b4e0ffSHong Zhang if (vflg && !network->Jv && nVertices) { 20378675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 203866b4e0ffSHong Zhang PetscInt nedges_total; 20398675203cSHong Zhang const PetscInt *edges; 20408675203cSHong Zhang 20418675203cSHong Zhang /* count nvertex_total */ 20428675203cSHong Zhang nedges_total = 0; 20438675203cSHong Zhang ierr = PetscMalloc1(nVertices+1,&vptr);CHKERRQ(ierr); 20448675203cSHong Zhang 20458675203cSHong Zhang vptr[0] = 0; 20468675203cSHong Zhang for (i=0; i<nVertices; i++) { 20478675203cSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,i+vStart,&nedges,&edges);CHKERRQ(ierr); 20488675203cSHong Zhang nedges_total += nedges; 20498675203cSHong Zhang vptr[i+1] = vptr[i] + 2*nedges + 1; 20508675203cSHong Zhang } 20518675203cSHong Zhang 20528675203cSHong Zhang ierr = PetscCalloc1(2*nedges_total+nVertices,&network->Jv);CHKERRQ(ierr); 20538675203cSHong Zhang network->Jvptr = vptr; 20548675203cSHong Zhang } 20551ad426b7SHong Zhang PetscFunctionReturn(0); 20561ad426b7SHong Zhang } 20571ad426b7SHong Zhang 20581ad426b7SHong Zhang /*@ 205983b2e829SHong Zhang DMNetworkEdgeSetMatrix - Sets user-provided Jacobian matrices for this edge to the network 206083b2e829SHong Zhang 206183b2e829SHong Zhang Not Collective 206283b2e829SHong Zhang 206383b2e829SHong Zhang Input Parameters: 20642bf73ac6SHong Zhang + dm - the DMNetwork object 206583b2e829SHong Zhang . p - the edge point 20663e97b6e8SHong Zhang - J - array (size = 3) of Jacobian submatrices for this edge point: 20673e97b6e8SHong Zhang J[0]: this edge 2068d842c372SHong Zhang J[1] and J[2]: connected vertices, obtained by calling DMNetworkGetConnectedVertices() 206983b2e829SHong Zhang 207097bb938eSShri Abhyankar Level: advanced 207183b2e829SHong Zhang 20722bf73ac6SHong Zhang .seealso: DMNetworkVertexSetMatrix() 207383b2e829SHong Zhang @*/ 207483b2e829SHong Zhang PetscErrorCode DMNetworkEdgeSetMatrix(DM dm,PetscInt p,Mat J[]) 207583b2e829SHong Zhang { 207683b2e829SHong Zhang DM_Network *network=(DM_Network*)dm->data; 207783b2e829SHong Zhang 207883b2e829SHong Zhang PetscFunctionBegin; 20798675203cSHong Zhang if (!network->Je) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkEdgeSetMatrix"); 20808675203cSHong Zhang 20818675203cSHong Zhang if (J) { 2082883e35e8SHong Zhang network->Je[3*p] = J[0]; 2083883e35e8SHong Zhang network->Je[3*p+1] = J[1]; 2084883e35e8SHong Zhang network->Je[3*p+2] = J[2]; 20858675203cSHong Zhang } 208683b2e829SHong Zhang PetscFunctionReturn(0); 208783b2e829SHong Zhang } 208883b2e829SHong Zhang 208983b2e829SHong Zhang /*@ 209076ddfea5SHong Zhang DMNetworkVertexSetMatrix - Sets user-provided Jacobian matrix for this vertex to the network 20911ad426b7SHong Zhang 20921ad426b7SHong Zhang Not Collective 20931ad426b7SHong Zhang 20941ad426b7SHong Zhang Input Parameters: 20951ad426b7SHong Zhang + dm - The DMNetwork object 20961ad426b7SHong Zhang . p - the vertex point 20973e97b6e8SHong Zhang - J - array of Jacobian (size = 2*(num of supporting edges) + 1) submatrices for this vertex point: 20983e97b6e8SHong Zhang J[0]: this vertex 20993e97b6e8SHong Zhang J[1+2*i]: i-th supporting edge 21003e97b6e8SHong Zhang J[1+2*i+1]: i-th connected vertex 21011ad426b7SHong Zhang 210297bb938eSShri Abhyankar Level: advanced 21031ad426b7SHong Zhang 21042bf73ac6SHong Zhang .seealso: DMNetworkEdgeSetMatrix() 21051ad426b7SHong Zhang @*/ 2106883e35e8SHong Zhang PetscErrorCode DMNetworkVertexSetMatrix(DM dm,PetscInt p,Mat J[]) 21075f2c45f1SShri Abhyankar { 21085f2c45f1SShri Abhyankar PetscErrorCode ierr; 21095f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 21108675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 2111883e35e8SHong Zhang const PetscInt *edges; 21125f2c45f1SShri Abhyankar 21135f2c45f1SShri Abhyankar PetscFunctionBegin; 21148675203cSHong Zhang if (!network->Jv) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkVertexSetMatrix"); 2115883e35e8SHong Zhang 21168675203cSHong Zhang if (J) { 2117883e35e8SHong Zhang vptr = network->Jvptr; 21183e97b6e8SHong Zhang network->Jv[vptr[p-vStart]] = J[0]; /* Set Jacobian for this vertex */ 21193e97b6e8SHong Zhang 21203e97b6e8SHong Zhang /* Set Jacobian for each supporting edge and connected vertex */ 2121883e35e8SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,p,&nedges,&edges);CHKERRQ(ierr); 2122883e35e8SHong Zhang for (i=1; i<=2*nedges; i++) network->Jv[vptr[p-vStart]+i] = J[i]; 21238675203cSHong Zhang } 2124883e35e8SHong Zhang PetscFunctionReturn(0); 2125883e35e8SHong Zhang } 2126883e35e8SHong Zhang 2127e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 21285cf7da58SHong Zhang { 21295cf7da58SHong Zhang PetscErrorCode ierr; 21305cf7da58SHong Zhang PetscInt j; 21315cf7da58SHong Zhang PetscScalar val=(PetscScalar)ncols; 21325cf7da58SHong Zhang 21335cf7da58SHong Zhang PetscFunctionBegin; 21345cf7da58SHong Zhang if (!ghost) { 21355cf7da58SHong Zhang for (j=0; j<nrows; j++) { 21365cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 21375cf7da58SHong Zhang } 21385cf7da58SHong Zhang } else { 21395cf7da58SHong Zhang for (j=0; j<nrows; j++) { 21405cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 21415cf7da58SHong Zhang } 21425cf7da58SHong Zhang } 21435cf7da58SHong Zhang PetscFunctionReturn(0); 21445cf7da58SHong Zhang } 21455cf7da58SHong Zhang 2146e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 21475cf7da58SHong Zhang { 21485cf7da58SHong Zhang PetscErrorCode ierr; 21495cf7da58SHong Zhang PetscInt j,ncols_u; 21505cf7da58SHong Zhang PetscScalar val; 21515cf7da58SHong Zhang 21525cf7da58SHong Zhang PetscFunctionBegin; 21535cf7da58SHong Zhang if (!ghost) { 21545cf7da58SHong Zhang for (j=0; j<nrows; j++) { 21555cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 21565cf7da58SHong Zhang val = (PetscScalar)ncols_u; 21575cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 21585cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 21595cf7da58SHong Zhang } 21605cf7da58SHong Zhang } else { 21615cf7da58SHong Zhang for (j=0; j<nrows; j++) { 21625cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 21635cf7da58SHong Zhang val = (PetscScalar)ncols_u; 21645cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 21655cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 21665cf7da58SHong Zhang } 21675cf7da58SHong Zhang } 21685cf7da58SHong Zhang PetscFunctionReturn(0); 21695cf7da58SHong Zhang } 21705cf7da58SHong Zhang 2171e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 21725cf7da58SHong Zhang { 21735cf7da58SHong Zhang PetscErrorCode ierr; 21745cf7da58SHong Zhang 21755cf7da58SHong Zhang PetscFunctionBegin; 21765cf7da58SHong Zhang if (Ju) { 21775cf7da58SHong Zhang ierr = MatSetPreallocationUserblock_private(Ju,nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 21785cf7da58SHong Zhang } else { 21795cf7da58SHong Zhang ierr = MatSetPreallocationDenseblock_private(nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 21805cf7da58SHong Zhang } 21815cf7da58SHong Zhang PetscFunctionReturn(0); 21825cf7da58SHong Zhang } 21835cf7da58SHong Zhang 2184e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 2185883e35e8SHong Zhang { 2186883e35e8SHong Zhang PetscErrorCode ierr; 2187883e35e8SHong Zhang PetscInt j,*cols; 2188883e35e8SHong Zhang PetscScalar *zeros; 2189883e35e8SHong Zhang 2190883e35e8SHong Zhang PetscFunctionBegin; 2191883e35e8SHong Zhang ierr = PetscCalloc2(ncols,&cols,nrows*ncols,&zeros);CHKERRQ(ierr); 2192883e35e8SHong Zhang for (j=0; j<ncols; j++) cols[j] = j+ cstart; 2193883e35e8SHong Zhang ierr = MatSetValues(*J,nrows,rows,ncols,cols,zeros,INSERT_VALUES);CHKERRQ(ierr); 2194883e35e8SHong Zhang ierr = PetscFree2(cols,zeros);CHKERRQ(ierr); 21951ad426b7SHong Zhang PetscFunctionReturn(0); 21961ad426b7SHong Zhang } 2197a4e85ca8SHong Zhang 2198e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 21993e97b6e8SHong Zhang { 22003e97b6e8SHong Zhang PetscErrorCode ierr; 22013e97b6e8SHong Zhang PetscInt j,M,N,row,col,ncols_u; 22023e97b6e8SHong Zhang const PetscInt *cols; 22033e97b6e8SHong Zhang PetscScalar zero=0.0; 22043e97b6e8SHong Zhang 22053e97b6e8SHong Zhang PetscFunctionBegin; 22063e97b6e8SHong Zhang ierr = MatGetSize(Ju,&M,&N);CHKERRQ(ierr); 22073e97b6e8SHong 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); 22083e97b6e8SHong Zhang 22093e97b6e8SHong Zhang for (row=0; row<nrows; row++) { 22103e97b6e8SHong Zhang ierr = MatGetRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 22113e97b6e8SHong Zhang for (j=0; j<ncols_u; j++) { 22123e97b6e8SHong Zhang col = cols[j] + cstart; 22133e97b6e8SHong Zhang ierr = MatSetValues(*J,1,&rows[row],1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr); 22143e97b6e8SHong Zhang } 22153e97b6e8SHong Zhang ierr = MatRestoreRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 22163e97b6e8SHong Zhang } 22173e97b6e8SHong Zhang PetscFunctionReturn(0); 22183e97b6e8SHong Zhang } 22191ad426b7SHong Zhang 2220e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 2221a4e85ca8SHong Zhang { 2222a4e85ca8SHong Zhang PetscErrorCode ierr; 2223f4431b8cSHong Zhang 2224a4e85ca8SHong Zhang PetscFunctionBegin; 2225a4e85ca8SHong Zhang if (Ju) { 2226a4e85ca8SHong Zhang ierr = MatSetUserblock_private(Ju,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 2227a4e85ca8SHong Zhang } else { 2228a4e85ca8SHong Zhang ierr = MatSetDenseblock_private(nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 2229a4e85ca8SHong Zhang } 2230a4e85ca8SHong Zhang PetscFunctionReturn(0); 2231a4e85ca8SHong Zhang } 2232a4e85ca8SHong Zhang 223324121865SAdrian 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. 223424121865SAdrian Maldonado */ 223524121865SAdrian Maldonado PetscErrorCode CreateSubGlobalToLocalMapping_private(PetscSection globalsec, PetscSection localsec, ISLocalToGlobalMapping *ltog) 223624121865SAdrian Maldonado { 223724121865SAdrian Maldonado PetscErrorCode ierr; 223824121865SAdrian Maldonado PetscInt i,size,dof; 223924121865SAdrian Maldonado PetscInt *glob2loc; 224024121865SAdrian Maldonado 224124121865SAdrian Maldonado PetscFunctionBegin; 224224121865SAdrian Maldonado ierr = PetscSectionGetStorageSize(localsec,&size);CHKERRQ(ierr); 224324121865SAdrian Maldonado ierr = PetscMalloc1(size,&glob2loc);CHKERRQ(ierr); 224424121865SAdrian Maldonado 224524121865SAdrian Maldonado for (i = 0; i < size; i++) { 224624121865SAdrian Maldonado ierr = PetscSectionGetOffset(globalsec,i,&dof);CHKERRQ(ierr); 224724121865SAdrian Maldonado dof = (dof >= 0) ? dof : -(dof + 1); 224824121865SAdrian Maldonado glob2loc[i] = dof; 224924121865SAdrian Maldonado } 225024121865SAdrian Maldonado 225124121865SAdrian Maldonado ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,size,glob2loc,PETSC_OWN_POINTER,ltog);CHKERRQ(ierr); 225224121865SAdrian Maldonado #if 0 225324121865SAdrian Maldonado ierr = PetscIntView(size,glob2loc,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 225424121865SAdrian Maldonado #endif 225524121865SAdrian Maldonado PetscFunctionReturn(0); 225624121865SAdrian Maldonado } 225724121865SAdrian Maldonado 225801ad2aeeSHong Zhang #include <petsc/private/matimpl.h> 22599e1d080bSHong Zhang 22609e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network_Nest(DM dm,Mat *J) 22611ad426b7SHong Zhang { 22621ad426b7SHong Zhang PetscErrorCode ierr; 22631ad426b7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 22649e1d080bSHong Zhang PetscMPIInt rank, size; 226524121865SAdrian Maldonado PetscInt eDof,vDof; 226624121865SAdrian Maldonado Mat j11,j12,j21,j22,bA[2][2]; 22679e1d080bSHong Zhang MPI_Comm comm; 226824121865SAdrian Maldonado ISLocalToGlobalMapping eISMap,vISMap; 226924121865SAdrian Maldonado 22709e1d080bSHong Zhang PetscFunctionBegin; 227124121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 2272ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 2273ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 227424121865SAdrian Maldonado 227524121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->edge.GlobalDofSection,&eDof);CHKERRQ(ierr); 227624121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->vertex.GlobalDofSection,&vDof);CHKERRQ(ierr); 227724121865SAdrian Maldonado 227801ad2aeeSHong Zhang ierr = MatCreate(comm, &j11);CHKERRQ(ierr); 227924121865SAdrian Maldonado ierr = MatSetSizes(j11, eDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 228024121865SAdrian Maldonado ierr = MatSetType(j11, MATMPIAIJ);CHKERRQ(ierr); 228124121865SAdrian Maldonado 228201ad2aeeSHong Zhang ierr = MatCreate(comm, &j12);CHKERRQ(ierr); 228324121865SAdrian Maldonado ierr = MatSetSizes(j12, eDof, vDof, PETSC_DETERMINE ,PETSC_DETERMINE);CHKERRQ(ierr); 228424121865SAdrian Maldonado ierr = MatSetType(j12, MATMPIAIJ);CHKERRQ(ierr); 228524121865SAdrian Maldonado 228601ad2aeeSHong Zhang ierr = MatCreate(comm, &j21);CHKERRQ(ierr); 228724121865SAdrian Maldonado ierr = MatSetSizes(j21, vDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 228824121865SAdrian Maldonado ierr = MatSetType(j21, MATMPIAIJ);CHKERRQ(ierr); 228924121865SAdrian Maldonado 229001ad2aeeSHong Zhang ierr = MatCreate(comm, &j22);CHKERRQ(ierr); 229124121865SAdrian Maldonado ierr = MatSetSizes(j22, vDof, vDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 229224121865SAdrian Maldonado ierr = MatSetType(j22, MATMPIAIJ);CHKERRQ(ierr); 229324121865SAdrian Maldonado 22943f6a6bdaSHong Zhang bA[0][0] = j11; 22953f6a6bdaSHong Zhang bA[0][1] = j12; 22963f6a6bdaSHong Zhang bA[1][0] = j21; 22973f6a6bdaSHong Zhang bA[1][1] = j22; 229824121865SAdrian Maldonado 229924121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->edge.GlobalDofSection,network->edge.DofSection,&eISMap);CHKERRQ(ierr); 230024121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->vertex.GlobalDofSection,network->vertex.DofSection,&vISMap);CHKERRQ(ierr); 230124121865SAdrian Maldonado 230224121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j11,eISMap,eISMap);CHKERRQ(ierr); 230324121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j12,eISMap,vISMap);CHKERRQ(ierr); 230424121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j21,vISMap,eISMap);CHKERRQ(ierr); 230524121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j22,vISMap,vISMap);CHKERRQ(ierr); 230624121865SAdrian Maldonado 230724121865SAdrian Maldonado ierr = MatSetUp(j11);CHKERRQ(ierr); 230824121865SAdrian Maldonado ierr = MatSetUp(j12);CHKERRQ(ierr); 230924121865SAdrian Maldonado ierr = MatSetUp(j21);CHKERRQ(ierr); 231024121865SAdrian Maldonado ierr = MatSetUp(j22);CHKERRQ(ierr); 231124121865SAdrian Maldonado 231201ad2aeeSHong Zhang ierr = MatCreateNest(comm,2,NULL,2,NULL,&bA[0][0],J);CHKERRQ(ierr); 231324121865SAdrian Maldonado ierr = MatSetUp(*J);CHKERRQ(ierr); 231424121865SAdrian Maldonado ierr = MatNestSetVecType(*J,VECNEST);CHKERRQ(ierr); 231524121865SAdrian Maldonado ierr = MatDestroy(&j11);CHKERRQ(ierr); 231624121865SAdrian Maldonado ierr = MatDestroy(&j12);CHKERRQ(ierr); 231724121865SAdrian Maldonado ierr = MatDestroy(&j21);CHKERRQ(ierr); 231824121865SAdrian Maldonado ierr = MatDestroy(&j22);CHKERRQ(ierr); 231924121865SAdrian Maldonado 232024121865SAdrian Maldonado ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 232124121865SAdrian Maldonado ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 23229e1d080bSHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 232324121865SAdrian Maldonado 232424121865SAdrian Maldonado /* Free structures */ 232524121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&eISMap);CHKERRQ(ierr); 232624121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&vISMap);CHKERRQ(ierr); 232724121865SAdrian Maldonado PetscFunctionReturn(0); 23289e1d080bSHong Zhang } 23299e1d080bSHong Zhang 23309e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J) 23319e1d080bSHong Zhang { 23329e1d080bSHong Zhang PetscErrorCode ierr; 23339e1d080bSHong Zhang DM_Network *network = (DM_Network*)dm->data; 23349e1d080bSHong Zhang PetscInt eStart,eEnd,vStart,vEnd,rstart,nrows,*rows,localSize; 23359e1d080bSHong Zhang PetscInt cstart,ncols,j,e,v; 23369e1d080bSHong Zhang PetscBool ghost,ghost_vc,ghost2,isNest; 23379e1d080bSHong Zhang Mat Juser; 23389e1d080bSHong Zhang PetscSection sectionGlobal; 23399e1d080bSHong Zhang PetscInt nedges,*vptr=NULL,vc,*rows_v; /* suppress maybe-uninitialized warning */ 23409e1d080bSHong Zhang const PetscInt *edges,*cone; 23419e1d080bSHong Zhang MPI_Comm comm; 23429e1d080bSHong Zhang MatType mtype; 23439e1d080bSHong Zhang Vec vd_nz,vo_nz; 23449e1d080bSHong Zhang PetscInt *dnnz,*onnz; 23459e1d080bSHong Zhang PetscScalar *vdnz,*vonz; 23469e1d080bSHong Zhang 23479e1d080bSHong Zhang PetscFunctionBegin; 23489e1d080bSHong Zhang mtype = dm->mattype; 23499e1d080bSHong Zhang ierr = PetscStrcmp(mtype,MATNEST,&isNest);CHKERRQ(ierr); 23509e1d080bSHong Zhang if (isNest) { 23519e1d080bSHong Zhang ierr = DMCreateMatrix_Network_Nest(dm,J);CHKERRQ(ierr); 2352c6b011d8SStefano Zampini ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 23539e1d080bSHong Zhang PetscFunctionReturn(0); 23549e1d080bSHong Zhang } 23559e1d080bSHong Zhang 23569e1d080bSHong Zhang if (!network->userEdgeJacobian && !network->userVertexJacobian) { 2357a4e85ca8SHong Zhang /* user does not provide Jacobian blocks */ 23589e1d080bSHong Zhang ierr = DMCreateMatrix_Plex(network->plex,J);CHKERRQ(ierr); 2359bfbc38dcSHong Zhang ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 23601ad426b7SHong Zhang PetscFunctionReturn(0); 23611ad426b7SHong Zhang } 23621ad426b7SHong Zhang 2363bfbc38dcSHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)dm),J);CHKERRQ(ierr); 2364e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§ionGlobal);CHKERRQ(ierr); 2365bfbc38dcSHong Zhang ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal,&localSize);CHKERRQ(ierr); 2366bfbc38dcSHong Zhang ierr = MatSetSizes(*J,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 23672a945128SHong Zhang 23682a945128SHong Zhang ierr = MatSetType(*J,MATAIJ);CHKERRQ(ierr); 23692a945128SHong Zhang ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 237089898e50SHong Zhang 237189898e50SHong Zhang /* (1) Set matrix preallocation */ 237289898e50SHong Zhang /*------------------------------*/ 2373840c2264SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 2374840c2264SHong Zhang ierr = VecCreate(comm,&vd_nz);CHKERRQ(ierr); 2375840c2264SHong Zhang ierr = VecSetSizes(vd_nz,localSize,PETSC_DECIDE);CHKERRQ(ierr); 2376840c2264SHong Zhang ierr = VecSetFromOptions(vd_nz);CHKERRQ(ierr); 2377840c2264SHong Zhang ierr = VecSet(vd_nz,0.0);CHKERRQ(ierr); 2378840c2264SHong Zhang ierr = VecDuplicate(vd_nz,&vo_nz);CHKERRQ(ierr); 2379840c2264SHong Zhang 238089898e50SHong Zhang /* Set preallocation for edges */ 238189898e50SHong Zhang /*-----------------------------*/ 2382840c2264SHong Zhang ierr = DMNetworkGetEdgeRange(dm,&eStart,&eEnd);CHKERRQ(ierr); 2383840c2264SHong Zhang 2384bdcb62a2SHong Zhang ierr = PetscMalloc1(localSize,&rows);CHKERRQ(ierr); 2385840c2264SHong Zhang for (e=eStart; e<eEnd; e++) { 2386840c2264SHong Zhang /* Get row indices */ 23872bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,e,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 23882bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,e,&nrows);CHKERRQ(ierr); 2389840c2264SHong Zhang if (nrows) { 2390840c2264SHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 2391840c2264SHong Zhang 23925cf7da58SHong Zhang /* Set preallocation for conntected vertices */ 2393d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 2394840c2264SHong Zhang for (v=0; v<2; v++) { 23952bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,cone[v],&ncols);CHKERRQ(ierr); 2396840c2264SHong Zhang 23978675203cSHong Zhang if (network->Je) { 2398840c2264SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 23998675203cSHong Zhang } else Juser = NULL; 2400840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,cone[v],&ghost);CHKERRQ(ierr); 24015cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 2402840c2264SHong Zhang } 2403840c2264SHong Zhang 240489898e50SHong Zhang /* Set preallocation for edge self */ 2405840c2264SHong Zhang cstart = rstart; 24068675203cSHong Zhang if (network->Je) { 2407840c2264SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 24088675203cSHong Zhang } else Juser = NULL; 24095cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 2410840c2264SHong Zhang } 2411840c2264SHong Zhang } 2412840c2264SHong Zhang 241389898e50SHong Zhang /* Set preallocation for vertices */ 241489898e50SHong Zhang /*--------------------------------*/ 2415840c2264SHong Zhang ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 24168675203cSHong Zhang if (vEnd - vStart) vptr = network->Jvptr; 2417840c2264SHong Zhang 2418840c2264SHong Zhang for (v=vStart; v<vEnd; v++) { 2419840c2264SHong Zhang /* Get row indices */ 24202bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 24212bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,v,&nrows);CHKERRQ(ierr); 2422840c2264SHong Zhang if (!nrows) continue; 2423840c2264SHong Zhang 2424bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 2425bdcb62a2SHong Zhang if (ghost) { 2426bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 2427bdcb62a2SHong Zhang } else { 2428bdcb62a2SHong Zhang rows_v = rows; 2429bdcb62a2SHong Zhang } 2430bdcb62a2SHong Zhang 2431bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 2432840c2264SHong Zhang 2433840c2264SHong Zhang /* Get supporting edges and connected vertices */ 2434840c2264SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 2435840c2264SHong Zhang 2436840c2264SHong Zhang for (e=0; e<nedges; e++) { 2437840c2264SHong Zhang /* Supporting edges */ 24382bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,edges[e],ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 24392bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,edges[e],&ncols);CHKERRQ(ierr); 2440840c2264SHong Zhang 24418675203cSHong Zhang if (network->Jv) { 2442840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 24438675203cSHong Zhang } else Juser = NULL; 2444bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 2445840c2264SHong Zhang 2446840c2264SHong Zhang /* Connected vertices */ 2447d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 2448840c2264SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 2449840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,vc,&ghost_vc);CHKERRQ(ierr); 2450840c2264SHong Zhang 24512bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,vc,&ncols);CHKERRQ(ierr); 2452840c2264SHong Zhang 24538675203cSHong Zhang if (network->Jv) { 2454840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 24558675203cSHong Zhang } else Juser = NULL; 2456e102a522SHong Zhang if (ghost_vc||ghost) { 2457e102a522SHong Zhang ghost2 = PETSC_TRUE; 2458e102a522SHong Zhang } else { 2459e102a522SHong Zhang ghost2 = PETSC_FALSE; 2460e102a522SHong Zhang } 2461e102a522SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost2,vd_nz,vo_nz);CHKERRQ(ierr); 2462840c2264SHong Zhang } 2463840c2264SHong Zhang 246489898e50SHong Zhang /* Set preallocation for vertex self */ 2465840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 2466840c2264SHong Zhang if (!ghost) { 24672bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 24688675203cSHong Zhang if (network->Jv) { 2469840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 24708675203cSHong Zhang } else Juser = NULL; 2471bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 2472840c2264SHong Zhang } 2473bdcb62a2SHong Zhang if (ghost) { 2474bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 2475bdcb62a2SHong Zhang } 2476840c2264SHong Zhang } 2477840c2264SHong Zhang 2478840c2264SHong Zhang ierr = VecAssemblyBegin(vd_nz);CHKERRQ(ierr); 2479840c2264SHong Zhang ierr = VecAssemblyBegin(vo_nz);CHKERRQ(ierr); 24805cf7da58SHong Zhang 24815cf7da58SHong Zhang ierr = PetscMalloc2(localSize,&dnnz,localSize,&onnz);CHKERRQ(ierr); 24825cf7da58SHong Zhang 24835cf7da58SHong Zhang ierr = VecAssemblyEnd(vd_nz);CHKERRQ(ierr); 2484840c2264SHong Zhang ierr = VecAssemblyEnd(vo_nz);CHKERRQ(ierr); 2485840c2264SHong Zhang 2486840c2264SHong Zhang ierr = VecGetArray(vd_nz,&vdnz);CHKERRQ(ierr); 2487840c2264SHong Zhang ierr = VecGetArray(vo_nz,&vonz);CHKERRQ(ierr); 2488840c2264SHong Zhang for (j=0; j<localSize; j++) { 2489e102a522SHong Zhang dnnz[j] = (PetscInt)PetscRealPart(vdnz[j]); 2490e102a522SHong Zhang onnz[j] = (PetscInt)PetscRealPart(vonz[j]); 2491840c2264SHong Zhang } 2492840c2264SHong Zhang ierr = VecRestoreArray(vd_nz,&vdnz);CHKERRQ(ierr); 2493840c2264SHong Zhang ierr = VecRestoreArray(vo_nz,&vonz);CHKERRQ(ierr); 2494840c2264SHong Zhang ierr = VecDestroy(&vd_nz);CHKERRQ(ierr); 2495840c2264SHong Zhang ierr = VecDestroy(&vo_nz);CHKERRQ(ierr); 2496840c2264SHong Zhang 24975cf7da58SHong Zhang ierr = MatSeqAIJSetPreallocation(*J,0,dnnz);CHKERRQ(ierr); 24985cf7da58SHong Zhang ierr = MatMPIAIJSetPreallocation(*J,0,dnnz,0,onnz);CHKERRQ(ierr); 24995cf7da58SHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 25005cf7da58SHong Zhang 25015cf7da58SHong Zhang ierr = PetscFree2(dnnz,onnz);CHKERRQ(ierr); 25025cf7da58SHong Zhang 250389898e50SHong Zhang /* (2) Set matrix entries for edges */ 250489898e50SHong Zhang /*----------------------------------*/ 25051ad426b7SHong Zhang for (e=eStart; e<eEnd; e++) { 2506bfbc38dcSHong Zhang /* Get row indices */ 25072bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,e,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 25082bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,e,&nrows);CHKERRQ(ierr); 25094b976069SHong Zhang if (nrows) { 251017df6e9eSHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 25111ad426b7SHong Zhang 2512bfbc38dcSHong Zhang /* Set matrix entries for conntected vertices */ 2513d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 2514bfbc38dcSHong Zhang for (v=0; v<2; v++) { 25152bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,cone[v],ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 25162bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,cone[v],&ncols);CHKERRQ(ierr); 25173e97b6e8SHong Zhang 25188675203cSHong Zhang if (network->Je) { 2519a4e85ca8SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 25208675203cSHong Zhang } else Juser = NULL; 2521a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 2522bfbc38dcSHong Zhang } 252317df6e9eSHong Zhang 2524bfbc38dcSHong Zhang /* Set matrix entries for edge self */ 25253e97b6e8SHong Zhang cstart = rstart; 25268675203cSHong Zhang if (network->Je) { 2527a4e85ca8SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 25288675203cSHong Zhang } else Juser = NULL; 2529a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,nrows,cstart,J);CHKERRQ(ierr); 25301ad426b7SHong Zhang } 25314b976069SHong Zhang } 25321ad426b7SHong Zhang 2533bfbc38dcSHong Zhang /* Set matrix entries for vertices */ 253483b2e829SHong Zhang /*---------------------------------*/ 25351ad426b7SHong Zhang for (v=vStart; v<vEnd; v++) { 2536bfbc38dcSHong Zhang /* Get row indices */ 25372bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 25382bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,v,&nrows);CHKERRQ(ierr); 25394b976069SHong Zhang if (!nrows) continue; 2540596e729fSHong Zhang 2541bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 2542bdcb62a2SHong Zhang if (ghost) { 2543bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 2544bdcb62a2SHong Zhang } else { 2545bdcb62a2SHong Zhang rows_v = rows; 2546bdcb62a2SHong Zhang } 2547bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 2548596e729fSHong Zhang 2549bfbc38dcSHong Zhang /* Get supporting edges and connected vertices */ 2550596e729fSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 2551596e729fSHong Zhang 2552596e729fSHong Zhang for (e=0; e<nedges; e++) { 2553bfbc38dcSHong Zhang /* Supporting edges */ 25542bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,edges[e],ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 25552bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,edges[e],&ncols);CHKERRQ(ierr); 2556596e729fSHong Zhang 25578675203cSHong Zhang if (network->Jv) { 2558a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 25598675203cSHong Zhang } else Juser = NULL; 2560bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 2561596e729fSHong Zhang 2562bfbc38dcSHong Zhang /* Connected vertices */ 2563d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 25642a945128SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 25652a945128SHong Zhang 25662bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,vc,ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 25672bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,vc,&ncols);CHKERRQ(ierr); 2568a4e85ca8SHong Zhang 25698675203cSHong Zhang if (network->Jv) { 2570a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 25718675203cSHong Zhang } else Juser = NULL; 2572bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 2573596e729fSHong Zhang } 2574596e729fSHong Zhang 2575bfbc38dcSHong Zhang /* Set matrix entries for vertex self */ 25761ad426b7SHong Zhang if (!ghost) { 25772bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 25788675203cSHong Zhang if (network->Jv) { 2579a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 25808675203cSHong Zhang } else Juser = NULL; 2581bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,nrows,cstart,J);CHKERRQ(ierr); 2582bdcb62a2SHong Zhang } 2583bdcb62a2SHong Zhang if (ghost) { 2584bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 2585bdcb62a2SHong Zhang } 25861ad426b7SHong Zhang } 2587a4e85ca8SHong Zhang ierr = PetscFree(rows);CHKERRQ(ierr); 2588bdcb62a2SHong Zhang 25891ad426b7SHong Zhang ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 25901ad426b7SHong Zhang ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2591dd6f46cdSHong Zhang 25925f2c45f1SShri Abhyankar ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 25935f2c45f1SShri Abhyankar PetscFunctionReturn(0); 25945f2c45f1SShri Abhyankar } 25955f2c45f1SShri Abhyankar 25965f2c45f1SShri Abhyankar PetscErrorCode DMDestroy_Network(DM dm) 25975f2c45f1SShri Abhyankar { 25985f2c45f1SShri Abhyankar PetscErrorCode ierr; 25995f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 2600*54dfd506SHong Zhang PetscInt j,np; 26015f2c45f1SShri Abhyankar 26025f2c45f1SShri Abhyankar PetscFunctionBegin; 26038415c774SShri Abhyankar if (--network->refct > 0) PetscFunctionReturn(0); 260483b2e829SHong Zhang if (network->Je) { 260583b2e829SHong Zhang ierr = PetscFree(network->Je);CHKERRQ(ierr); 260683b2e829SHong Zhang } 260783b2e829SHong Zhang if (network->Jv) { 2608883e35e8SHong Zhang ierr = PetscFree(network->Jvptr);CHKERRQ(ierr); 260983b2e829SHong Zhang ierr = PetscFree(network->Jv);CHKERRQ(ierr); 26101ad426b7SHong Zhang } 261113c2a604SAdrian Maldonado 261213c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->vertex.mapping);CHKERRQ(ierr); 261313c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.DofSection);CHKERRQ(ierr); 261413c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.GlobalDofSection);CHKERRQ(ierr); 2615f5427c60SHong Zhang if (network->vltog) { 2616f5427c60SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 2617f5427c60SHong Zhang } 261813c2a604SAdrian Maldonado if (network->vertex.sf) { 261913c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->vertex.sf);CHKERRQ(ierr); 262013c2a604SAdrian Maldonado } 262113c2a604SAdrian Maldonado /* edge */ 262213c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->edge.mapping);CHKERRQ(ierr); 262313c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.DofSection);CHKERRQ(ierr); 262413c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.GlobalDofSection);CHKERRQ(ierr); 262513c2a604SAdrian Maldonado if (network->edge.sf) { 262613c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->edge.sf);CHKERRQ(ierr); 262713c2a604SAdrian Maldonado } 26285f2c45f1SShri Abhyankar ierr = DMDestroy(&network->plex);CHKERRQ(ierr); 26295f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr); 26305f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr); 263183b2e829SHong Zhang 26322bf73ac6SHong Zhang for (j=0; j<network->Nsvtx; j++) { 26332bf73ac6SHong Zhang ierr = PetscFree(network->svtx[j].sv);CHKERRQ(ierr); 26342bf73ac6SHong Zhang } 26352bf73ac6SHong Zhang if (network->svtx) {ierr = PetscFree(network->svtx);CHKERRQ(ierr);} 26362bf73ac6SHong Zhang 26372bf73ac6SHong Zhang for (j=0; j<network->Nsubnet; j++) { 26382727e31bSShri Abhyankar ierr = PetscFree(network->subnet[j].edges);CHKERRQ(ierr); 26392727e31bSShri Abhyankar } 26402bf73ac6SHong Zhang if (network->subnetvtx) {ierr = PetscFree(network->subnetvtx);CHKERRQ(ierr);} 2641caf410d2SHong Zhang 26422bf73ac6SHong Zhang ierr = PetscTableDestroy(&network->svtable);CHKERRQ(ierr); 2643e2aaf10cSShri Abhyankar ierr = PetscFree(network->subnet);CHKERRQ(ierr); 2644*54dfd506SHong Zhang ierr = PetscFree(network->component);CHKERRQ(ierr); 26455f2c45f1SShri Abhyankar ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr); 2646*54dfd506SHong Zhang 2647*54dfd506SHong Zhang if (network->header) { 2648*54dfd506SHong Zhang np = network->pEnd - network->pStart; 2649*54dfd506SHong Zhang for (j=0; j < np; j++) { 2650*54dfd506SHong Zhang ierr = PetscFree5(network->header[j].size,network->header[j].key,network->header[j].offset,network->header[j].nvar,network->header[j].offsetvarrel);CHKERRQ(ierr); 2651*54dfd506SHong Zhang ierr = PetscFree(network->cvalue[j].data);CHKERRQ(ierr); 2652*54dfd506SHong Zhang } 2653caf410d2SHong Zhang ierr = PetscFree2(network->header,network->cvalue);CHKERRQ(ierr); 2654*54dfd506SHong Zhang } 26555f2c45f1SShri Abhyankar ierr = PetscFree(network);CHKERRQ(ierr); 26565f2c45f1SShri Abhyankar PetscFunctionReturn(0); 26575f2c45f1SShri Abhyankar } 26585f2c45f1SShri Abhyankar 26595f2c45f1SShri Abhyankar PetscErrorCode DMView_Network(DM dm,PetscViewer viewer) 26605f2c45f1SShri Abhyankar { 26615f2c45f1SShri Abhyankar PetscErrorCode ierr; 2662caf410d2SHong Zhang PetscBool iascii; 2663caf410d2SHong Zhang PetscMPIInt rank; 26645f2c45f1SShri Abhyankar 26655f2c45f1SShri Abhyankar PetscFunctionBegin; 2666caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 2667ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRMPI(ierr); 2668caf410d2SHong Zhang PetscValidHeaderSpecific(dm,DM_CLASSID, 1); 2669caf410d2SHong Zhang PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2670caf410d2SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 2671caf410d2SHong Zhang if (iascii) { 2672caf410d2SHong Zhang const PetscInt *cone,*vtx,*edges; 26732bf73ac6SHong Zhang PetscInt vfrom,vto,i,j,nv,ne,ncv,p,nsubnet; 26742bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 2675caf410d2SHong Zhang 26762bf73ac6SHong Zhang nsubnet = network->Nsubnet; /* num of subnetworks */ 26772bf73ac6SHong Zhang if (!rank) { 26782bf73ac6SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF," NSubnets: %D; NEdges: %D; NVertices: %D; NSharedVertices: %D.\n",nsubnet,network->NEdges,network->NVertices,network->Nsvtx);CHKERRQ(ierr); 26792bf73ac6SHong Zhang } 26802bf73ac6SHong Zhang 26812bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&ncv,&vtx);CHKERRQ(ierr); 2682caf410d2SHong Zhang ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 26832bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " [%d] nEdges: %D; nVertices: %D; nSharedVertices: %D\n",rank,network->nEdges,network->nVertices,ncv);CHKERRQ(ierr); 2684caf410d2SHong Zhang 2685caf410d2SHong Zhang for (i=0; i<nsubnet; i++) { 26862bf73ac6SHong Zhang ierr = DMNetworkGetSubnetwork(dm,i,&nv,&ne,&vtx,&edges);CHKERRQ(ierr); 2687caf410d2SHong Zhang if (ne) { 26882bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " Subnet %D: nEdges %D, nVertices(include shared vertices) %D\n",i,ne,nv);CHKERRQ(ierr); 2689caf410d2SHong Zhang for (j=0; j<ne; j++) { 2690caf410d2SHong Zhang p = edges[j]; 2691caf410d2SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,p,&cone);CHKERRQ(ierr); 2692caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[0],&vfrom);CHKERRQ(ierr); 2693caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[1],&vto);CHKERRQ(ierr); 2694caf410d2SHong Zhang ierr = DMNetworkGetGlobalEdgeIndex(dm,edges[j],&p);CHKERRQ(ierr); 2695caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " edge %D: %D ----> %D\n",p,vfrom,vto);CHKERRQ(ierr); 2696caf410d2SHong Zhang } 2697caf410d2SHong Zhang } 2698caf410d2SHong Zhang } 26992bf73ac6SHong Zhang 27002bf73ac6SHong Zhang /* Shared vertices */ 27012bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&ncv,&vtx);CHKERRQ(ierr); 27022bf73ac6SHong Zhang if (ncv) { 27032bf73ac6SHong Zhang SVtx *svtx = network->svtx; 27042bf73ac6SHong Zhang PetscInt gidx,svtx_idx,nvto,vfrom_net,vfrom_idx,*svto; 27052bf73ac6SHong Zhang PetscBool ghost; 27062bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " SharedVertices:\n");CHKERRQ(ierr); 27072bf73ac6SHong Zhang for (i=0; i<ncv; i++) { 27082bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,vtx[i],&ghost);CHKERRQ(ierr); 27092bf73ac6SHong Zhang if (ghost) continue; 27102bf73ac6SHong Zhang 27112bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,vtx[i],&gidx);CHKERRQ(ierr); 27122bf73ac6SHong Zhang ierr = PetscTableFind(network->svtable,gidx+1,&svtx_idx);CHKERRQ(ierr); 27132bf73ac6SHong Zhang svtx_idx--; 27142bf73ac6SHong Zhang nvto = svtx[svtx_idx].n; 27152bf73ac6SHong Zhang 27162bf73ac6SHong Zhang vfrom_net = svtx[svtx_idx].sv[0]; 27172bf73ac6SHong Zhang vfrom_idx = svtx[svtx_idx].sv[1]; 27182bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " svtx %D: global index %D, subnet[%D].%D ---->\n",i,gidx,vfrom_net,vfrom_idx);CHKERRQ(ierr); 27192bf73ac6SHong Zhang for (j=1; j<nvto; j++) { 27202bf73ac6SHong Zhang svto = svtx[svtx_idx].sv + 2*j; 27212bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " ----> subnet[%D].%D\n",svto[0],svto[1]);CHKERRQ(ierr); 2722caf410d2SHong Zhang } 2723caf410d2SHong Zhang } 2724caf410d2SHong Zhang } 2725caf410d2SHong Zhang ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2726caf410d2SHong Zhang ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 2727caf410d2SHong Zhang } else SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMNetwork writing", ((PetscObject)viewer)->type_name); 27285f2c45f1SShri Abhyankar PetscFunctionReturn(0); 27295f2c45f1SShri Abhyankar } 27305f2c45f1SShri Abhyankar 27315f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l) 27325f2c45f1SShri Abhyankar { 27335f2c45f1SShri Abhyankar PetscErrorCode ierr; 27345f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 27355f2c45f1SShri Abhyankar 27365f2c45f1SShri Abhyankar PetscFunctionBegin; 27375f2c45f1SShri Abhyankar ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr); 27385f2c45f1SShri Abhyankar PetscFunctionReturn(0); 27395f2c45f1SShri Abhyankar } 27405f2c45f1SShri Abhyankar 27415f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l) 27425f2c45f1SShri Abhyankar { 27435f2c45f1SShri Abhyankar PetscErrorCode ierr; 27445f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 27455f2c45f1SShri Abhyankar 27465f2c45f1SShri Abhyankar PetscFunctionBegin; 27475f2c45f1SShri Abhyankar ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr); 27485f2c45f1SShri Abhyankar PetscFunctionReturn(0); 27495f2c45f1SShri Abhyankar } 27505f2c45f1SShri Abhyankar 27515f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g) 27525f2c45f1SShri Abhyankar { 27535f2c45f1SShri Abhyankar PetscErrorCode ierr; 27545f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 27555f2c45f1SShri Abhyankar 27565f2c45f1SShri Abhyankar PetscFunctionBegin; 27575f2c45f1SShri Abhyankar ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr); 27585f2c45f1SShri Abhyankar PetscFunctionReturn(0); 27595f2c45f1SShri Abhyankar } 27605f2c45f1SShri Abhyankar 27615f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g) 27625f2c45f1SShri Abhyankar { 27635f2c45f1SShri Abhyankar PetscErrorCode ierr; 27645f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 27655f2c45f1SShri Abhyankar 27665f2c45f1SShri Abhyankar PetscFunctionBegin; 27675f2c45f1SShri Abhyankar ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr); 27685f2c45f1SShri Abhyankar PetscFunctionReturn(0); 27695f2c45f1SShri Abhyankar } 277022bbedd7SHong Zhang 277122bbedd7SHong Zhang /*@ 277264238763SRodolfo Oliveira DMNetworkGetVertexLocalToGlobalOrdering - Get vertex global index 277322bbedd7SHong Zhang 277422bbedd7SHong Zhang Not collective 277522bbedd7SHong Zhang 27767a7aea1fSJed Brown Input Parameters: 277722bbedd7SHong Zhang + dm - the dm object 277822bbedd7SHong Zhang - vloc - local vertex ordering, start from 0 277922bbedd7SHong Zhang 27807a7aea1fSJed Brown Output Parameters: 2781f0fc11ceSJed Brown . vg - global vertex ordering, start from 0 278222bbedd7SHong Zhang 278397bb938eSShri Abhyankar Level: advanced 278422bbedd7SHong Zhang 278522bbedd7SHong Zhang .seealso: DMNetworkSetVertexLocalToGlobalOrdering() 278622bbedd7SHong Zhang @*/ 278722bbedd7SHong Zhang PetscErrorCode DMNetworkGetVertexLocalToGlobalOrdering(DM dm,PetscInt vloc,PetscInt *vg) 278822bbedd7SHong Zhang { 278922bbedd7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 279022bbedd7SHong Zhang PetscInt *vltog = network->vltog; 279122bbedd7SHong Zhang 279222bbedd7SHong Zhang PetscFunctionBegin; 279322bbedd7SHong Zhang if (!vltog) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkSetVertexLocalToGlobalOrdering() first"); 279422bbedd7SHong Zhang *vg = vltog[vloc]; 279522bbedd7SHong Zhang PetscFunctionReturn(0); 279622bbedd7SHong Zhang } 279722bbedd7SHong Zhang 279822bbedd7SHong Zhang /*@ 279964238763SRodolfo Oliveira DMNetworkSetVertexLocalToGlobalOrdering - Create and setup vertex local to global map 280022bbedd7SHong Zhang 280122bbedd7SHong Zhang Collective 280222bbedd7SHong Zhang 280322bbedd7SHong Zhang Input Parameters: 2804f0fc11ceSJed Brown . dm - the dm object 280522bbedd7SHong Zhang 280697bb938eSShri Abhyankar Level: advanced 280722bbedd7SHong Zhang 280863029d29SHong Zhang .seealso: DMNetworkGetGlobalVertexIndex() 280922bbedd7SHong Zhang @*/ 281022bbedd7SHong Zhang PetscErrorCode DMNetworkSetVertexLocalToGlobalOrdering(DM dm) 281122bbedd7SHong Zhang { 281222bbedd7SHong Zhang PetscErrorCode ierr; 281322bbedd7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 281422bbedd7SHong Zhang MPI_Comm comm; 28152bf73ac6SHong Zhang PetscMPIInt rank,size,*displs=NULL,*recvcounts=NULL,remoterank; 281622bbedd7SHong Zhang PetscBool ghost; 281763029d29SHong Zhang PetscInt *vltog,nroots,nleaves,i,*vrange,k,N,lidx; 281822bbedd7SHong Zhang const PetscSFNode *iremote; 281922bbedd7SHong Zhang PetscSF vsf; 282063029d29SHong Zhang Vec Vleaves,Vleaves_seq; 282163029d29SHong Zhang VecScatter ctx; 282263029d29SHong Zhang PetscScalar *varr,val; 282363029d29SHong Zhang const PetscScalar *varr_read; 282422bbedd7SHong Zhang 282522bbedd7SHong Zhang PetscFunctionBegin; 282622bbedd7SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 2827ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 2828ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 282922bbedd7SHong Zhang 283022bbedd7SHong Zhang if (size == 1) { 283122bbedd7SHong Zhang nroots = network->vEnd - network->vStart; 283222bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 283322bbedd7SHong Zhang for (i=0; i<nroots; i++) vltog[i] = i; 283422bbedd7SHong Zhang network->vltog = vltog; 283522bbedd7SHong Zhang PetscFunctionReturn(0); 283622bbedd7SHong Zhang } 283722bbedd7SHong Zhang 283822bbedd7SHong Zhang if (!network->distributecalled) SETERRQ(comm, PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkDistribute() first"); 283922bbedd7SHong Zhang if (network->vltog) { 284022bbedd7SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 284122bbedd7SHong Zhang } 284222bbedd7SHong Zhang 284322bbedd7SHong Zhang ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 284422bbedd7SHong Zhang ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 284522bbedd7SHong Zhang vsf = network->vertex.sf; 284622bbedd7SHong Zhang 28472bf73ac6SHong Zhang ierr = PetscMalloc3(size+1,&vrange,size,&displs,size,&recvcounts);CHKERRQ(ierr); 2848f5427c60SHong Zhang ierr = PetscSFGetGraph(vsf,&nroots,&nleaves,NULL,&iremote);CHKERRQ(ierr); 284922bbedd7SHong Zhang 285022bbedd7SHong Zhang for (i=0; i<size; i++) { displs[i] = i; recvcounts[i] = 1;} 285122bbedd7SHong Zhang 285222bbedd7SHong Zhang i = nroots - nleaves; /* local number of vertices, excluding ghosts */ 285322bbedd7SHong Zhang vrange[0] = 0; 2854ffc4695bSBarry Smith ierr = MPI_Allgatherv(&i,1,MPIU_INT,vrange+1,recvcounts,displs,MPIU_INT,comm);CHKERRMPI(ierr); 285567dd800bSHong Zhang for (i=2; i<size+1; i++) {vrange[i] += vrange[i-1];} 285622bbedd7SHong Zhang 285722bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 285822bbedd7SHong Zhang network->vltog = vltog; 285922bbedd7SHong Zhang 286063029d29SHong Zhang /* Set vltog for non-ghost vertices */ 286163029d29SHong Zhang k = 0; 286222bbedd7SHong Zhang for (i=0; i<nroots; i++) { 286322bbedd7SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 286463029d29SHong Zhang if (ghost) continue; 286563029d29SHong Zhang vltog[i] = vrange[rank] + k++; 286622bbedd7SHong Zhang } 2867f5427c60SHong Zhang ierr = PetscFree3(vrange,displs,recvcounts);CHKERRQ(ierr); 286863029d29SHong Zhang 286963029d29SHong Zhang /* Set vltog for ghost vertices */ 287063029d29SHong Zhang /* (a) create parallel Vleaves and sequential Vleaves_seq to convert local iremote[*].index to global index */ 287163029d29SHong Zhang ierr = VecCreate(comm,&Vleaves);CHKERRQ(ierr); 287263029d29SHong Zhang ierr = VecSetSizes(Vleaves,2*nleaves,PETSC_DETERMINE);CHKERRQ(ierr); 287363029d29SHong Zhang ierr = VecSetFromOptions(Vleaves);CHKERRQ(ierr); 287463029d29SHong Zhang ierr = VecGetArray(Vleaves,&varr);CHKERRQ(ierr); 287563029d29SHong Zhang for (i=0; i<nleaves; i++) { 287663029d29SHong Zhang varr[2*i] = (PetscScalar)(iremote[i].rank); /* rank of remote process */ 287763029d29SHong Zhang varr[2*i+1] = (PetscScalar)(iremote[i].index); /* local index in remote process */ 287863029d29SHong Zhang } 287963029d29SHong Zhang ierr = VecRestoreArray(Vleaves,&varr);CHKERRQ(ierr); 288063029d29SHong Zhang 288163029d29SHong Zhang /* (b) scatter local info to remote processes via VecScatter() */ 288263029d29SHong Zhang ierr = VecScatterCreateToAll(Vleaves,&ctx,&Vleaves_seq);CHKERRQ(ierr); 288363029d29SHong Zhang ierr = VecScatterBegin(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 288463029d29SHong Zhang ierr = VecScatterEnd(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 288563029d29SHong Zhang 288663029d29SHong Zhang /* (c) convert local indices to global indices in parallel vector Vleaves */ 288763029d29SHong Zhang ierr = VecGetSize(Vleaves_seq,&N);CHKERRQ(ierr); 288863029d29SHong Zhang ierr = VecGetArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 288963029d29SHong Zhang for (i=0; i<N; i+=2) { 28902e4cff2eSHong Zhang remoterank = (PetscMPIInt)PetscRealPart(varr_read[i]); 289163029d29SHong Zhang if (remoterank == rank) { 289263029d29SHong Zhang k = i+1; /* row number */ 28932e4cff2eSHong Zhang lidx = (PetscInt)PetscRealPart(varr_read[i+1]); 289463029d29SHong Zhang val = (PetscScalar)vltog[lidx]; /* global index for non-ghost vertex computed above */ 289563029d29SHong Zhang ierr = VecSetValues(Vleaves,1,&k,&val,INSERT_VALUES);CHKERRQ(ierr); 289663029d29SHong Zhang } 289763029d29SHong Zhang } 289863029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 289963029d29SHong Zhang ierr = VecAssemblyBegin(Vleaves);CHKERRQ(ierr); 290063029d29SHong Zhang ierr = VecAssemblyEnd(Vleaves);CHKERRQ(ierr); 290163029d29SHong Zhang 290263029d29SHong Zhang /* (d) Set vltog for ghost vertices by copying local values of Vleaves */ 290363029d29SHong Zhang ierr = VecGetArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 290463029d29SHong Zhang k = 0; 290563029d29SHong Zhang for (i=0; i<nroots; i++) { 290663029d29SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 290763029d29SHong Zhang if (!ghost) continue; 29082e4cff2eSHong Zhang vltog[i] = (PetscInt)PetscRealPart(varr_read[2*k+1]); k++; 290963029d29SHong Zhang } 291063029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 291163029d29SHong Zhang 291263029d29SHong Zhang ierr = VecDestroy(&Vleaves);CHKERRQ(ierr); 291363029d29SHong Zhang ierr = VecDestroy(&Vleaves_seq);CHKERRQ(ierr); 291463029d29SHong Zhang ierr = VecScatterDestroy(&ctx);CHKERRQ(ierr); 291522bbedd7SHong Zhang PetscFunctionReturn(0); 291622bbedd7SHong Zhang } 2917