1af0996ceSBarry Smith #include <petsc/private/dmnetworkimpl.h> /*I "petscdmnetwork.h" I*/ 25f2c45f1SShri Abhyankar 354dfd506SHong Zhang /* 454dfd506SHong Zhang Creates the component header and value objects for a network point 554dfd506SHong Zhang */ 654dfd506SHong Zhang static PetscErrorCode SetUpNetworkHeaderComponentValue(DM dm,DMNetworkComponentHeader header,DMNetworkComponentValue cvalue) 754dfd506SHong Zhang { 854dfd506SHong Zhang PetscErrorCode ierr; 954dfd506SHong Zhang 1054dfd506SHong Zhang PetscFunctionBegin; 1154dfd506SHong Zhang /* Allocate arrays for component information */ 1254dfd506SHong 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); 1354dfd506SHong Zhang ierr = PetscCalloc1(header->maxcomps,&cvalue->data);CHKERRQ(ierr); 1454dfd506SHong Zhang 1554dfd506SHong 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. 1654dfd506SHong Zhang If the data header struct changes then this header size calculation needs to be updated. */ 1754dfd506SHong Zhang header->hsize = sizeof(struct _p_DMNetworkComponentHeader) + 5*header->maxcomps*sizeof(PetscInt); 1854dfd506SHong Zhang header->hsize /= sizeof(DMNetworkComponentGenericDataType); 1954dfd506SHong Zhang PetscFunctionReturn(0); 2054dfd506SHong Zhang } 2154dfd506SHong 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 . ne - number of local edges of this subnetwork 1232bf73ac6SHong Zhang - edgelist - list of edges for this subnetwork 1242bf73ac6SHong Zhang 1252bf73ac6SHong Zhang Output Parameters: 1262bf73ac6SHong Zhang . netnum - global index of the subnetwork 1275f2c45f1SShri Abhyankar 1285f2c45f1SShri Abhyankar Notes: 1295f2c45f1SShri Abhyankar There is no copy involved in this operation, only the pointer is referenced. The edgelist should 1302bf73ac6SHong Zhang not be destroyed before the call to DMNetworkLayoutSetUp() 1315f2c45f1SShri Abhyankar 132f11a936eSBarry Smith A network can comprise of a single subnetwork OR multiple subnetworks. For a single subnetwork, the subnetwork can be read either in serial or parallel. For a multiple subnetworks, each subnetwork topology needs to be set on a unique rank and the communicator size needs to be at least equal to the number of subnetworks. 133f11a936eSBarry Smith 13497bb938eSShri Abhyankar Level: beginner 1355f2c45f1SShri Abhyankar 136e3e68989SHong Zhang Example usage: 137f11a936eSBarry Smith Consider the following networks: 138f11a936eSBarry Smith 1) A sigle subnetwork: 139e3e68989SHong Zhang .vb 140f11a936eSBarry Smith network 0: 141f11a936eSBarry Smith rank[0]: 142f11a936eSBarry Smith v0 --> v2; v1 --> v2 143f11a936eSBarry Smith rank[1]: 144f11a936eSBarry Smith v3 --> v5; v4 --> v5 145e3e68989SHong Zhang .ve 146e3e68989SHong Zhang 147e3e68989SHong Zhang The resulting input 148f11a936eSBarry Smith network 0: 149f11a936eSBarry Smith rank[0]: 150f11a936eSBarry Smith ne = 2 151f11a936eSBarry Smith edgelist = [0 2 | 1 2] 152f11a936eSBarry Smith rank[1]: 153f11a936eSBarry Smith ne = 2 154f11a936eSBarry Smith edgelist = [3 5 | 4 5] 155f11a936eSBarry Smith 156f11a936eSBarry Smith 2) Two subnetworks: 157f11a936eSBarry Smith .vb 158f11a936eSBarry Smith subnetwork 0: 159f11a936eSBarry Smith rank[0]: 160f11a936eSBarry Smith v0 --> v2; v2 --> v1; v1 --> v3; 161f11a936eSBarry Smith subnetwork 1: 162f11a936eSBarry Smith rank[1]: 163f11a936eSBarry Smith v0 --> v3; v3 --> v2; v2 --> v1; 164f11a936eSBarry Smith .ve 165f11a936eSBarry Smith 166f11a936eSBarry Smith The resulting input 167f11a936eSBarry Smith subnetwork 0: 168f11a936eSBarry Smith rank[0]: 169f11a936eSBarry Smith ne = 3 170f11a936eSBarry Smith edgelist = [0 2 | 2 1 | 1 3] 171f11a936eSBarry Smith rank[1]: 172f11a936eSBarry Smith ne = 0 173f11a936eSBarry Smith edgelist = NULL 174f11a936eSBarry Smith 175f11a936eSBarry Smith subnetwork 1: 176f11a936eSBarry Smith rank[0]: 177f11a936eSBarry Smith ne = 0 178f11a936eSBarry Smith edgelist = NULL 179f11a936eSBarry Smith rank[1]: 180f11a936eSBarry Smith edgelist = [0 3 | 3 2 | 2 1] 181e3e68989SHong Zhang 1822bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkSetNumSubnetworks() 1835f2c45f1SShri Abhyankar @*/ 184f11a936eSBarry Smith PetscErrorCode DMNetworkAddSubnetwork(DM dm,const char* name,PetscInt ne,PetscInt edgelist[],PetscInt *netnum) 1855f2c45f1SShri Abhyankar { 1862bf73ac6SHong Zhang PetscErrorCode ierr; 1875f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 188f11a936eSBarry Smith PetscInt i,Nedge,j,Nvtx,nvtx; 189f11a936eSBarry Smith PetscBT table; 1905f2c45f1SShri Abhyankar 1915f2c45f1SShri Abhyankar PetscFunctionBegin; 192f11a936eSBarry Smith /* Get global total Nvtx = max(edgelist[])+1 for this subnet */ 193f11a936eSBarry Smith nvtx = -1; i = 0; 194f11a936eSBarry Smith for (j=0; j<ne; j++) { 195f11a936eSBarry Smith nvtx = PetscMax(nvtx, edgelist[i]); i++; 196f11a936eSBarry Smith nvtx = PetscMax(nvtx, edgelist[i]); i++; 197f11a936eSBarry Smith } 198f11a936eSBarry Smith nvtx++; 199f11a936eSBarry Smith ierr = MPIU_Allreduce(&nvtx,&Nvtx,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 200f11a936eSBarry Smith 201f11a936eSBarry Smith /* Get local nvtx for this subnet */ 202f11a936eSBarry Smith ierr = PetscBTCreate(Nvtx,&table);CHKERRQ(ierr); 203f11a936eSBarry Smith ierr = PetscBTMemzero(Nvtx,table);CHKERRQ(ierr); 204f11a936eSBarry Smith i = 0; 205f11a936eSBarry Smith for (j=0; j<ne; j++) { 206f11a936eSBarry Smith ierr = PetscBTSet(table,edgelist[i]);CHKERRQ(ierr); 207f11a936eSBarry Smith i++; 208f11a936eSBarry Smith ierr = PetscBTSet(table,edgelist[i]);CHKERRQ(ierr); 209f11a936eSBarry Smith i++; 210f11a936eSBarry Smith } 211f11a936eSBarry Smith nvtx = 0; 212f11a936eSBarry Smith for (j=0; j<Nvtx; j++) { 213f11a936eSBarry Smith if (PetscBTLookup(table,j)) nvtx++; 214f11a936eSBarry Smith } 215f11a936eSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 216f11a936eSBarry Smith 217f11a936eSBarry Smith /* Get global total Nedge for this subnet */ 218f11a936eSBarry Smith ierr = MPIU_Allreduce(&ne,&Nedge,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 219f11a936eSBarry Smith 220f11a936eSBarry Smith i = network->nsubnet; 2212bf73ac6SHong Zhang if (name) { 2222bf73ac6SHong Zhang ierr = PetscStrcpy(network->subnet[i].name,name);CHKERRQ(ierr); 223e3e68989SHong Zhang } 224f11a936eSBarry Smith network->subnet[i].nvtx = nvtx; /* include ghost vertices */ 2252bf73ac6SHong Zhang network->subnet[i].nedge = ne; 2262bf73ac6SHong Zhang network->subnet[i].edgelist = edgelist; 227f11a936eSBarry Smith network->subnet[i].Nvtx = Nvtx; 228f11a936eSBarry Smith network->subnet[i].Nedge = Nedge; 2292bf73ac6SHong Zhang 2302bf73ac6SHong Zhang /* ---------------------------------------------------------- 2312bf73ac6SHong Zhang p=v or e; 2322bf73ac6SHong Zhang subnet[0].pStart = 0 2332bf73ac6SHong Zhang subnet[i+1].pStart = subnet[i].pEnd = subnet[i].pStart + (nE[i] or NV[i]) 2342bf73ac6SHong Zhang ----------------------------------------------------------------------- */ 2352bf73ac6SHong Zhang /* GLOBAL subnet[].vStart and vEnd, used by DMNetworkLayoutSetUp() */ 2362bf73ac6SHong Zhang network->subnet[i].vStart = network->NVertices; 2372bf73ac6SHong Zhang network->subnet[i].vEnd = network->subnet[i].vStart + network->subnet[i].Nvtx; /* global vEnd of subnet[i] */ 2382bf73ac6SHong Zhang 239f11a936eSBarry Smith network->nVertices += nvtx; /* include ghost vertices */ 2402bf73ac6SHong Zhang network->NVertices += network->subnet[i].Nvtx; 2412bf73ac6SHong Zhang 2422bf73ac6SHong Zhang /* LOCAL subnet[].eStart and eEnd, used by DMNetworkLayoutSetUp() */ 2432bf73ac6SHong Zhang network->subnet[i].eStart = network->nEdges; 2442bf73ac6SHong Zhang network->subnet[i].eEnd = network->subnet[i].eStart + ne; 2452bf73ac6SHong Zhang network->nEdges += ne; 2462bf73ac6SHong Zhang network->NEdges += network->subnet[i].Nedge; 2472bf73ac6SHong Zhang 2482bf73ac6SHong Zhang ierr = PetscStrcpy(network->subnet[i].name,name);CHKERRQ(ierr); 2492bf73ac6SHong Zhang if (netnum) *netnum = network->nsubnet; 2502bf73ac6SHong Zhang network->nsubnet++; 2512bf73ac6SHong Zhang PetscFunctionReturn(0); 2522bf73ac6SHong Zhang } 2532bf73ac6SHong Zhang 2542bf73ac6SHong Zhang /* 2552bf73ac6SHong Zhang SetUp a single svtx struct. See SVtx defined in dmnetworkimpl.h 2562bf73ac6SHong Zhang Set gidx and type if input v=(net,idx) is a from_vertex; 2572bf73ac6SHong Zhang Get gid, type and index in the svtx array if input v=(net,idx) is a to_vertex. 2582bf73ac6SHong Zhang 2592bf73ac6SHong Zhang Input: Nsvtx, svtx, net, idx, gidx 2602bf73ac6SHong Zhang Output: gidx, svtype, svtx_idx 2612bf73ac6SHong Zhang */ 2622bf73ac6SHong Zhang static PetscErrorCode SVtxSetUp(PetscInt Nsvtx,SVtx *svtx,PetscInt net,PetscInt idx,PetscInt *gidx,SVtxType *svtype,PetscInt *svtx_idx) 2632bf73ac6SHong Zhang { 2642bf73ac6SHong Zhang PetscInt i,j,*svto; 2652bf73ac6SHong Zhang SVtxType vtype; 2662bf73ac6SHong Zhang 2672bf73ac6SHong Zhang PetscFunctionBegin; 2682bf73ac6SHong Zhang if (!Nsvtx) PetscFunctionReturn(0); 2692bf73ac6SHong Zhang 2702bf73ac6SHong Zhang vtype = SVNONE; 2712bf73ac6SHong Zhang for (i=0; i<Nsvtx; i++) { 2722bf73ac6SHong Zhang if (net == svtx[i].sv[0] && idx == svtx[i].sv[1]) { 2732bf73ac6SHong Zhang /* (1) input vertex net.idx is a shared from_vertex, set its global index and output its svtype */ 2742bf73ac6SHong Zhang svtx[i].gidx = *gidx; /* set gidx */ 2752bf73ac6SHong Zhang vtype = SVFROM; 2762bf73ac6SHong Zhang } else { /* loop over svtx[i].n */ 2772bf73ac6SHong Zhang for (j=1; j<svtx[i].n; j++) { 2782bf73ac6SHong Zhang svto = svtx[i].sv + 2*j; 2792bf73ac6SHong Zhang if (net == svto[0] && idx == svto[1]) { 2802bf73ac6SHong Zhang /* input vertex net.idx is a shared to_vertex, output its global index and its svtype */ 2812bf73ac6SHong Zhang *gidx = svtx[i].gidx; /* output gidx for to_vertex */ 2822bf73ac6SHong Zhang vtype = SVTO; 2832bf73ac6SHong Zhang } 2842bf73ac6SHong Zhang } 2852bf73ac6SHong Zhang } 2862bf73ac6SHong Zhang if (vtype != SVNONE) break; 2872bf73ac6SHong Zhang } 2882bf73ac6SHong Zhang if (svtype) *svtype = vtype; 2892bf73ac6SHong Zhang if (svtx_idx) *svtx_idx = i; 2902bf73ac6SHong Zhang PetscFunctionReturn(0); 2912bf73ac6SHong Zhang } 2922bf73ac6SHong Zhang 2932bf73ac6SHong Zhang /* 2942bf73ac6SHong Zhang Add a new shared vertex sv=(net,idx) to table svtas[ita] 2952bf73ac6SHong Zhang */ 2962bf73ac6SHong Zhang static PetscErrorCode TableAddSVtx(PetscTable *svtas,PetscInt ita,PetscInt* tdata,PetscInt *sv_wk,PetscInt *ii,PetscInt *sedgelist,PetscInt k,DM_Network *network,PetscInt **ta2sv) 2972bf73ac6SHong Zhang { 2982bf73ac6SHong Zhang PetscInt net,idx,gidx,i=*ii; 2992bf73ac6SHong Zhang PetscErrorCode ierr; 3002bf73ac6SHong Zhang 3012bf73ac6SHong Zhang PetscFunctionBegin; 3022bf73ac6SHong Zhang net = sv_wk[2*i] = sedgelist[k]; 3032bf73ac6SHong Zhang idx = sv_wk[2*i+1] = sedgelist[k+1]; 3042bf73ac6SHong Zhang gidx = network->subnet[net].vStart + idx; 3052bf73ac6SHong Zhang ierr = PetscTableAdd(svtas[ita],gidx+1,tdata[ita]+1,INSERT_VALUES);CHKERRQ(ierr); 3062bf73ac6SHong Zhang *(ta2sv[ita] + tdata[ita]) = i; /* maps tdata to index of sv_wk; sv_wk keeps (net,idx) info */ 3072bf73ac6SHong Zhang tdata[ita]++; (*ii)++; 3082bf73ac6SHong Zhang PetscFunctionReturn(0); 3092bf73ac6SHong Zhang } 3102bf73ac6SHong Zhang 3112bf73ac6SHong Zhang /* 3122bf73ac6SHong Zhang Create an array of shared vertices. See SVtx and SVtxType in dmnetworkimpl.h 3132bf73ac6SHong Zhang 3142bf73ac6SHong Zhang Input: dm, Nsedgelist, sedgelist 3152bf73ac6SHong Zhang Output: Nsvtx,svtx 3162bf73ac6SHong Zhang 3172bf73ac6SHong Zhang Note: Output svtx is organized as 3182bf73ac6SHong Zhang sv(net[0],idx[0]) --> sv(net[1],idx[1]) 3192bf73ac6SHong Zhang --> sv(net[1],idx[1]) 3202bf73ac6SHong Zhang ... 3212bf73ac6SHong Zhang --> sv(net[n-1],idx[n-1]) 3222bf73ac6SHong Zhang and net[0] < net[1] < ... < net[n-1] 3232bf73ac6SHong Zhang where sv[0] has SVFROM type, sv[i], i>0, has SVTO type. 3242bf73ac6SHong Zhang */ 3252bf73ac6SHong Zhang static PetscErrorCode SVtxCreate(DM dm,PetscInt Nsedgelist,PetscInt *sedgelist,PetscInt *Nsvtx,SVtx **svtx) 3262bf73ac6SHong Zhang { 3272bf73ac6SHong Zhang PetscErrorCode ierr; 3282bf73ac6SHong Zhang SVtx *sedges = NULL; 3292bf73ac6SHong Zhang PetscInt *sv,k,j,nsv,*tdata,**ta2sv; 3302bf73ac6SHong Zhang PetscTable *svtas; 3312bf73ac6SHong Zhang PetscInt gidx,net,idx,i,nta,ita,idx_from,idx_to,n,*sv_wk; 3322bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 3332bf73ac6SHong Zhang PetscTablePosition ppos; 3342bf73ac6SHong Zhang 3352bf73ac6SHong Zhang PetscFunctionBegin; 3362bf73ac6SHong Zhang /* (1) Crete ctables svtas */ 3372bf73ac6SHong Zhang ierr = PetscCalloc4(Nsedgelist,&svtas,Nsedgelist,&tdata,4*Nsedgelist,&sv_wk,2*Nsedgelist,&ta2sv);CHKERRQ(ierr); 3382bf73ac6SHong Zhang 3392bf73ac6SHong Zhang j = 0; /* sedgelist counter */ 3402bf73ac6SHong Zhang k = 0; /* sedgelist vertex counter j = 4*k */ 3412bf73ac6SHong Zhang i = 0; /* sv_wk (vertices added to the ctables) counter */ 3422bf73ac6SHong Zhang nta = 0; /* num of sv tables created */ 3432bf73ac6SHong Zhang 3442bf73ac6SHong Zhang /* for j=0 */ 3452bf73ac6SHong Zhang ierr = PetscTableCreate(2*Nsedgelist,network->NVertices+1,&svtas[nta]);CHKERRQ(ierr); 3462bf73ac6SHong Zhang ierr = PetscMalloc1(2*Nsedgelist,&ta2sv[nta]);CHKERRQ(ierr); 3472bf73ac6SHong Zhang 3482bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,nta,tdata,sv_wk,&i,sedgelist,k,network,ta2sv);CHKERRQ(ierr); 3492bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,nta,tdata,sv_wk,&i,sedgelist,k+2,network,ta2sv);CHKERRQ(ierr); 3502bf73ac6SHong Zhang nta++; k += 4; 3512bf73ac6SHong Zhang 3522bf73ac6SHong Zhang for (j = 1; j < Nsedgelist; j++) { 3532bf73ac6SHong Zhang for (ita = 0; ita < nta; ita++) { 3542bf73ac6SHong Zhang /* vfrom */ 3552bf73ac6SHong Zhang net = sedgelist[k]; idx = sedgelist[k+1]; 3562bf73ac6SHong Zhang gidx = network->subnet[net].vStart + idx; /* global index of the vertex net.idx before merging shared vertices */ 3572bf73ac6SHong Zhang ierr = PetscTableFind(svtas[ita],gidx+1,&idx_from);CHKERRQ(ierr); 3582bf73ac6SHong Zhang 3592bf73ac6SHong Zhang /* vto */ 3602bf73ac6SHong Zhang net = sedgelist[k+2]; idx = sedgelist[k+3]; 3612bf73ac6SHong Zhang gidx = network->subnet[net].vStart + idx; 3622bf73ac6SHong Zhang ierr = PetscTableFind(svtas[ita],gidx+1,&idx_to);CHKERRQ(ierr); 3632bf73ac6SHong Zhang 3642bf73ac6SHong Zhang if (idx_from || idx_to) { /* vfrom or vto is on table svtas[ita] */ 3652bf73ac6SHong Zhang idx_from--; idx_to--; 3662bf73ac6SHong Zhang if (idx_from < 0) { /* vto is on svtas[ita] */ 3672bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,ita,tdata,sv_wk,&i,sedgelist,k,network,ta2sv);CHKERRQ(ierr); 3682bf73ac6SHong Zhang break; 3692bf73ac6SHong Zhang } else if (idx_to < 0) { 3702bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,ita,tdata,sv_wk,&i,sedgelist,k+2,network,ta2sv);CHKERRQ(ierr); 3712bf73ac6SHong Zhang break; 3722bf73ac6SHong Zhang } 3732bf73ac6SHong Zhang } 3742bf73ac6SHong Zhang } 3752bf73ac6SHong Zhang 3762bf73ac6SHong Zhang if (ita == nta) { 3772bf73ac6SHong Zhang ierr = PetscTableCreate(2*Nsedgelist,network->NVertices+1,&svtas[nta]);CHKERRQ(ierr); 3782bf73ac6SHong Zhang ierr = PetscMalloc1(2*Nsedgelist, &ta2sv[nta]);CHKERRQ(ierr); 3792bf73ac6SHong Zhang 3802bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,nta,tdata,sv_wk,&i,sedgelist,k,network,ta2sv);CHKERRQ(ierr); 3812bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,nta,tdata,sv_wk,&i,sedgelist,k+2,network,ta2sv);CHKERRQ(ierr); 3822bf73ac6SHong Zhang nta++; 3832bf73ac6SHong Zhang } 3842bf73ac6SHong Zhang k += 4; 3852bf73ac6SHong Zhang } 3862bf73ac6SHong Zhang 3872bf73ac6SHong Zhang /* (2) Construct sedges from ctable 3882bf73ac6SHong Zhang sedges: edges connect vertex sv[0]=(net[0],idx[0]) to vertices sv[k], k=1,...,n-1; 3894f5c2772SJose E. Roman net[k], k=0, ...,n-1, are in ascending order */ 3902bf73ac6SHong Zhang ierr = PetscMalloc1(nta,&sedges);CHKERRQ(ierr); 3912bf73ac6SHong Zhang for (nsv = 0; nsv < nta; nsv++) { 3924f5c2772SJose E. Roman /* for a single svtx, put shared vertices in ascending order of gidx */ 3934f5c2772SJose E. Roman ierr = PetscTableGetCount(svtas[nsv],&n);CHKERRQ(ierr); 3942bf73ac6SHong Zhang ierr = PetscCalloc1(2*n,&sv);CHKERRQ(ierr); 3952bf73ac6SHong Zhang sedges[nsv].sv = sv; 3962bf73ac6SHong Zhang sedges[nsv].n = n; 3972bf73ac6SHong Zhang sedges[nsv].gidx = -1; /* initialization */ 3982bf73ac6SHong Zhang 3992bf73ac6SHong Zhang ierr = PetscTableGetHeadPosition(svtas[nsv],&ppos);CHKERRQ(ierr); 4004f5c2772SJose E. Roman for (k=0; k<n; k++) { /* gidx is sorted in ascending order */ 4012bf73ac6SHong Zhang ierr = PetscTableGetNext(svtas[nsv],&ppos,&gidx,&i);CHKERRQ(ierr); 4022bf73ac6SHong Zhang gidx--; i--; 4032bf73ac6SHong Zhang 4042bf73ac6SHong Zhang j = ta2sv[nsv][i]; /* maps i to index of sv_wk */ 4052bf73ac6SHong Zhang sv[2*k] = sv_wk[2*j]; 4062bf73ac6SHong Zhang sv[2*k+1] = sv_wk[2*j + 1]; 4072bf73ac6SHong Zhang } 4082bf73ac6SHong Zhang } 4092bf73ac6SHong Zhang 4102bf73ac6SHong Zhang for (j=0; j<nta; j++) { 4112bf73ac6SHong Zhang ierr = PetscTableDestroy(&svtas[j]);CHKERRQ(ierr); 4122bf73ac6SHong Zhang ierr = PetscFree(ta2sv[j]);CHKERRQ(ierr); 4132bf73ac6SHong Zhang } 4142bf73ac6SHong Zhang ierr = PetscFree4(svtas,tdata,sv_wk,ta2sv);CHKERRQ(ierr); 4152bf73ac6SHong Zhang 4162bf73ac6SHong Zhang *Nsvtx = nta; 4172bf73ac6SHong Zhang *svtx = sedges; 4182bf73ac6SHong Zhang PetscFunctionReturn(0); 4192bf73ac6SHong Zhang } 4202bf73ac6SHong Zhang 4212bf73ac6SHong Zhang static PetscErrorCode DMNetworkLayoutSetUp_Coupling(DM dm) 4222bf73ac6SHong Zhang { 4232bf73ac6SHong Zhang PetscErrorCode ierr; 4242bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 425f11a936eSBarry Smith PetscInt i,j,ctr,np,*edges,*subnetvtx,*subnetedge,vStart; 4262bf73ac6SHong Zhang PetscInt k,*vidxlTog,Nsv=0,Nsubnet=network->Nsubnet; 4272bf73ac6SHong Zhang PetscInt *sedgelist=network->sedgelist; 4282bf73ac6SHong Zhang const PetscInt *cone; 4292bf73ac6SHong Zhang MPI_Comm comm; 4302bf73ac6SHong Zhang PetscMPIInt size,rank,*recvcounts=NULL,*displs=NULL; 4312bf73ac6SHong Zhang PetscInt net,idx,gidx,nmerged,e,v,vfrom,vto,*vrange,*eowners,gidx_from,net_from,sv_idx; 4322bf73ac6SHong Zhang SVtxType svtype = SVNONE; 4332bf73ac6SHong Zhang SVtx *svtx=NULL; 4342bf73ac6SHong Zhang PetscSection sectiong; 4352bf73ac6SHong Zhang 4362bf73ac6SHong Zhang PetscFunctionBegin; 4372bf73ac6SHong Zhang /* This implementation requires user input each subnet by a single processor, thus subnet[net].nvtx=subnet[net].Nvtx */ 4382bf73ac6SHong Zhang for (net=0; net<Nsubnet; net++) { 4392bf73ac6SHong 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); 4402bf73ac6SHong Zhang } 4412bf73ac6SHong Zhang 4422bf73ac6SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 44355b25c41SPierre Jolivet ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 44455b25c41SPierre Jolivet ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 4452bf73ac6SHong Zhang 4462bf73ac6SHong Zhang /* (1) Create svtx[] from sedgelist */ 4472bf73ac6SHong Zhang /* -------------------------------- */ 4482bf73ac6SHong Zhang /* Nsv: global number of SVtx; svtx: shared vertices, see SVtx in dmnetworkimpl.h */ 4492bf73ac6SHong Zhang ierr = SVtxCreate(dm,network->Nsvtx,sedgelist,&Nsv,&svtx);CHKERRQ(ierr); 4502bf73ac6SHong Zhang 4512bf73ac6SHong Zhang /* (2) Setup svtx; Shared vto vertices are merged to their vfrom vertex with same global vetex index (gidx) */ 4522bf73ac6SHong Zhang /* -------------------------------------------------------------------------------------------------------- */ 4532bf73ac6SHong Zhang /* (2.1) compute vrage[rank]: global index of 1st local vertex in proc[rank] */ 4542bf73ac6SHong Zhang ierr = PetscMalloc3(size+1,&vrange,size,&displs,size,&recvcounts);CHKERRQ(ierr); 4552bf73ac6SHong Zhang for (i=0; i<size; i++) {displs[i] = i; recvcounts[i] = 1;} 4562bf73ac6SHong Zhang 4572bf73ac6SHong Zhang vrange[0] = 0; 4582bf73ac6SHong Zhang ierr = MPI_Allgatherv(&network->nVertices,1,MPIU_INT,vrange+1,recvcounts,displs,MPIU_INT,comm);CHKERRMPI(ierr); 4592bf73ac6SHong Zhang for (i=2; i<size+1; i++) { 4602bf73ac6SHong Zhang vrange[i] += vrange[i-1]; 4612bf73ac6SHong Zhang } 4622bf73ac6SHong Zhang 4632bf73ac6SHong Zhang /* (2.2) Create vidxlTog: maps UN-MERGED local vertex index i to global index gidx (plex, excluding ghost vertices) */ 4642bf73ac6SHong Zhang ierr = PetscMalloc1(network->nVertices,&vidxlTog);CHKERRQ(ierr); 4652bf73ac6SHong Zhang i = 0; gidx = 0; 4662bf73ac6SHong Zhang nmerged = 0; /* local num of merged vertices */ 4672bf73ac6SHong Zhang network->nsvtx = 0; 4682bf73ac6SHong Zhang for (net=0; net<Nsubnet; net++) { 4692bf73ac6SHong Zhang for (idx=0; idx<network->subnet[net].Nvtx; idx++) { 4702bf73ac6SHong Zhang gidx_from = gidx; 4712bf73ac6SHong Zhang sv_idx = -1; 4722bf73ac6SHong Zhang 4732bf73ac6SHong Zhang ierr = SVtxSetUp(Nsv,svtx,net,idx,&gidx_from,&svtype,&sv_idx);CHKERRQ(ierr); 4742bf73ac6SHong Zhang if (svtype == SVTO) { 4752bf73ac6SHong Zhang if (network->subnet[net].nvtx) {/* this proc owns sv_to */ 4762bf73ac6SHong Zhang net_from = svtx[sv_idx].sv[0]; /* subnet num of its shared vertex */ 4772bf73ac6SHong Zhang if (network->subnet[net_from].nvtx == 0) { 4782bf73ac6SHong Zhang /* this proc does not own v_from, thus a new local coupling vertex */ 4792bf73ac6SHong Zhang network->nsvtx++; 4802bf73ac6SHong Zhang } 4812bf73ac6SHong Zhang vidxlTog[i++] = gidx_from; 4822bf73ac6SHong Zhang nmerged++; /* a coupling vertex -- merged */ 4832bf73ac6SHong Zhang } 4842bf73ac6SHong Zhang } else { 4852bf73ac6SHong Zhang if (svtype == SVFROM) { 4862bf73ac6SHong Zhang if (network->subnet[net].nvtx) { 4872bf73ac6SHong Zhang /* this proc owns this v_from, a new local coupling vertex */ 4882bf73ac6SHong Zhang network->nsvtx++; 4892bf73ac6SHong Zhang } 4902bf73ac6SHong Zhang } 4912bf73ac6SHong Zhang if (network->subnet[net].nvtx) vidxlTog[i++] = gidx; 4922bf73ac6SHong Zhang gidx++; 4932bf73ac6SHong Zhang } 4942bf73ac6SHong Zhang } 4952bf73ac6SHong Zhang } 4962bf73ac6SHong Zhang #if defined(PETSC_USE_DEBUG) 4972bf73ac6SHong Zhang if (i != network->nVertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"%D != %D nVertices",i,network->nVertices); 4982bf73ac6SHong Zhang #endif 4992bf73ac6SHong Zhang 5002bf73ac6SHong Zhang /* (2.3) Setup svtable for querry shared vertices */ 5012bf73ac6SHong Zhang for (v=0; v<Nsv; v++) { 5022bf73ac6SHong Zhang gidx = svtx[v].gidx; 5032bf73ac6SHong Zhang ierr = PetscTableAdd(network->svtable,gidx+1,v+1,INSERT_VALUES);CHKERRQ(ierr); 5042bf73ac6SHong Zhang } 5052bf73ac6SHong Zhang 5062bf73ac6SHong Zhang /* (2.4) Shared vertices in the subnetworks are merged, update global NVertices: np = sum(local nmerged) */ 5072bf73ac6SHong Zhang ierr = MPI_Allreduce(&nmerged,&np,1,MPIU_INT,MPI_SUM,comm);CHKERRMPI(ierr); 5082bf73ac6SHong Zhang network->NVertices -= np; 5092bf73ac6SHong Zhang 5102bf73ac6SHong Zhang ierr = PetscCalloc1(2*network->nEdges,&edges);CHKERRQ(ierr); 5112bf73ac6SHong Zhang 5122bf73ac6SHong Zhang ctr = 0; 5132bf73ac6SHong Zhang for (net=0; net<Nsubnet; net++) { 5142bf73ac6SHong Zhang for (j = 0; j < network->subnet[net].nedge; j++) { 5152bf73ac6SHong Zhang /* vfrom: */ 5162bf73ac6SHong Zhang i = network->subnet[net].edgelist[2*j] + (network->subnet[net].vStart - vrange[rank]); 5172bf73ac6SHong Zhang edges[2*ctr] = vidxlTog[i]; 5182bf73ac6SHong Zhang 5192bf73ac6SHong Zhang /* vto */ 5202bf73ac6SHong Zhang i = network->subnet[net].edgelist[2*j+1] + (network->subnet[net].vStart - vrange[rank]); 5212bf73ac6SHong Zhang edges[2*ctr+1] = vidxlTog[i]; 5222bf73ac6SHong Zhang ctr++; 5232bf73ac6SHong Zhang } 5242bf73ac6SHong Zhang } 5252bf73ac6SHong Zhang ierr = PetscFree3(vrange,displs,recvcounts);CHKERRQ(ierr); 5262bf73ac6SHong Zhang ierr = PetscFree(vidxlTog);CHKERRQ(ierr); 5272bf73ac6SHong Zhang 5282bf73ac6SHong Zhang /* (3) Create network->plex */ 5292bf73ac6SHong Zhang ierr = DMCreate(comm,&network->plex);CHKERRQ(ierr); 5302bf73ac6SHong Zhang ierr = DMSetType(network->plex,DMPLEX);CHKERRQ(ierr); 5312bf73ac6SHong Zhang ierr = DMSetDimension(network->plex,1);CHKERRQ(ierr); 5322bf73ac6SHong Zhang if (size == 1) { 5332bf73ac6SHong Zhang ierr = DMPlexBuildFromCellList(network->plex,network->nEdges,network->nVertices-nmerged,2,edges);CHKERRQ(ierr); 5342bf73ac6SHong Zhang } else { 5352bf73ac6SHong Zhang ierr = DMPlexBuildFromCellListParallel(network->plex,network->nEdges,network->nVertices-nmerged,PETSC_DECIDE,2,edges,NULL);CHKERRQ(ierr); 5362bf73ac6SHong Zhang } 5372bf73ac6SHong Zhang 5382bf73ac6SHong Zhang ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr); 5392bf73ac6SHong Zhang ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr); 5402bf73ac6SHong Zhang ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr); 5412bf73ac6SHong Zhang vStart = network->vStart; 5422bf73ac6SHong Zhang 5432bf73ac6SHong Zhang ierr = PetscSectionCreate(comm,&network->DataSection);CHKERRQ(ierr); 5442bf73ac6SHong Zhang ierr = PetscSectionCreate(comm,&network->DofSection);CHKERRQ(ierr); 5452bf73ac6SHong Zhang ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr); 5462bf73ac6SHong Zhang ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr); 5472bf73ac6SHong Zhang 5482bf73ac6SHong Zhang np = network->pEnd - network->pStart; 5492bf73ac6SHong Zhang ierr = PetscCalloc2(np,&network->header,np,&network->cvalue);CHKERRQ(ierr); 55054dfd506SHong Zhang for (i=0; i<np; i++) { 55154dfd506SHong Zhang network->header[i].maxcomps = 1; 55254dfd506SHong Zhang ierr = SetUpNetworkHeaderComponentValue(dm,&network->header[i],&network->cvalue[i]);CHKERRQ(ierr); 55354dfd506SHong Zhang } 5542bf73ac6SHong Zhang 555f11a936eSBarry Smith /* (4) Create edge and vertex arrays for the subnetworks */ 556f11a936eSBarry Smith ierr = PetscCalloc2(network->nEdges,&subnetedge,network->nVertices+network->nsvtx,&subnetvtx);CHKERRQ(ierr); /* Maps local edge/vertex to local subnetwork's edge/vertex */ 557f11a936eSBarry Smith network->subnetedge = subnetedge; 558f11a936eSBarry Smith network->subnetvtx = subnetvtx; 5592bf73ac6SHong Zhang for (j=0; j < Nsubnet; j++) { 560f11a936eSBarry Smith network->subnet[j].edges = subnetedge; 561f11a936eSBarry Smith subnetedge += network->subnet[j].nedge; 562f11a936eSBarry Smith 5632bf73ac6SHong Zhang network->subnet[j].vertices = subnetvtx; 5642bf73ac6SHong Zhang subnetvtx += network->subnet[j].nvtx; 5652bf73ac6SHong Zhang } 5662bf73ac6SHong Zhang network->svertices = subnetvtx; 5672bf73ac6SHong Zhang 5682bf73ac6SHong Zhang /* Get edge ownership */ 569f11a936eSBarry Smith ierr = PetscMalloc1(size+1,&eowners);CHKERRQ(ierr); 5702bf73ac6SHong Zhang np = network->eEnd - network->eStart; /* num of local edges */ 5712bf73ac6SHong Zhang ierr = MPI_Allgather(&np,1,MPIU_INT,eowners+1,1,MPIU_INT,comm);CHKERRMPI(ierr); 5722bf73ac6SHong Zhang eowners[0] = 0; 5732bf73ac6SHong Zhang for (i=2; i<=size; i++) eowners[i] += eowners[i-1]; 5742bf73ac6SHong Zhang 575f11a936eSBarry Smith /* Setup edge and vertex arrays for subnetworks */ 5762bf73ac6SHong Zhang e = 0; 5772bf73ac6SHong Zhang for (i=0; i < Nsubnet; i++) { 578f11a936eSBarry Smith ctr = 0; 5792bf73ac6SHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 5802bf73ac6SHong Zhang /* edge e */ 5812bf73ac6SHong Zhang network->header[e].index = e + eowners[rank]; /* Global edge index */ 5822bf73ac6SHong Zhang network->header[e].subnetid = i; /* Subnetwork id */ 5832bf73ac6SHong Zhang network->subnet[i].edges[j] = e; 5842bf73ac6SHong Zhang network->header[e].ndata = 0; 5852bf73ac6SHong Zhang network->header[e].offset[0] = 0; 5862bf73ac6SHong Zhang network->header[e].offsetvarrel[0] = 0; 58754dfd506SHong Zhang ierr = PetscSectionAddDof(network->DataSection,e,network->header[e].hsize);CHKERRQ(ierr); 5882bf73ac6SHong Zhang 5892bf73ac6SHong Zhang /* connected vertices */ 5902bf73ac6SHong Zhang ierr = DMPlexGetCone(network->plex,e,&cone);CHKERRQ(ierr); 5912bf73ac6SHong Zhang 5922bf73ac6SHong Zhang /* vertex cone[0] */ 593f11a936eSBarry Smith v = cone[0]; 594f11a936eSBarry Smith network->header[v].index = edges[2*e]; /* Global vertex index */ 595f11a936eSBarry Smith network->header[v].subnetid = i; /* Subnetwork id */ 596f11a936eSBarry Smith vfrom = network->subnet[i].edgelist[2*ctr]; 597f11a936eSBarry Smith network->subnet[i].vertices[vfrom] = v; /* user's subnet[].dix = petsc's v */ 5982bf73ac6SHong Zhang 5992bf73ac6SHong Zhang /* vertex cone[1] */ 600f11a936eSBarry Smith v = cone[1]; 601f11a936eSBarry Smith network->header[v].index = edges[2*e+1]; /* Global vertex index */ 602f11a936eSBarry Smith network->header[v].subnetid = i; 603f11a936eSBarry Smith vto = network->subnet[i].edgelist[2*ctr+1]; 604f11a936eSBarry Smith network->subnet[i].vertices[vto]= v; 6052bf73ac6SHong Zhang 606f11a936eSBarry Smith e++; ctr++; 6072bf73ac6SHong Zhang } 6082bf73ac6SHong Zhang } 609f11a936eSBarry Smith ierr = PetscFree(eowners);CHKERRQ(ierr); 610f11a936eSBarry Smith ierr = PetscFree(edges);CHKERRQ(ierr); 6112bf73ac6SHong Zhang 6122bf73ac6SHong Zhang /* Set vertex array for the subnetworks */ 6132bf73ac6SHong Zhang k = 0; 6142bf73ac6SHong Zhang for (v=vStart; v<network->vEnd; v++) { /* local vertices, including ghosts */ 6152bf73ac6SHong Zhang network->header[v].ndata = 0; 6162bf73ac6SHong Zhang network->header[v].offset[0] = 0; 6172bf73ac6SHong Zhang network->header[v].offsetvarrel[0] = 0; 61854dfd506SHong Zhang ierr = PetscSectionAddDof(network->DataSection,v,network->header[v].hsize);CHKERRQ(ierr); 6192bf73ac6SHong Zhang 6202bf73ac6SHong Zhang /* shared vertex */ 621f11a936eSBarry Smith ierr = PetscTableFind(network->svtable,network->header[v].index+1,&i);CHKERRQ(ierr); 6222bf73ac6SHong Zhang if (i) network->svertices[k++] = v; 6232bf73ac6SHong Zhang } 6242bf73ac6SHong Zhang #if defined(PETSC_USE_DEBUG) 6252bf73ac6SHong Zhang if (k != network->nsvtx) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"k %D != %D nsvtx",k,network->nsvtx); 6262bf73ac6SHong Zhang #endif 6272bf73ac6SHong Zhang 6282bf73ac6SHong Zhang network->svtx = svtx; 6292bf73ac6SHong Zhang network->Nsvtx = Nsv; 6302bf73ac6SHong Zhang ierr = PetscFree(sedgelist);CHKERRQ(ierr); 6312bf73ac6SHong Zhang 6322bf73ac6SHong Zhang /* Create a global section to be used by DMNetworkIsGhostVertex() which is a non-collective routine */ 633f11a936eSBarry Smith /* see snes_tutorials_network-ex1_4 */ 6342bf73ac6SHong Zhang ierr = DMGetGlobalSection(network->plex,§iong);CHKERRQ(ierr); 6355f2c45f1SShri Abhyankar PetscFunctionReturn(0); 6365f2c45f1SShri Abhyankar } 6375f2c45f1SShri Abhyankar 6385f2c45f1SShri Abhyankar /*@ 6395f2c45f1SShri Abhyankar DMNetworkLayoutSetUp - Sets up the bare layout (graph) for the network 6405f2c45f1SShri Abhyankar 641d083f849SBarry Smith Collective on dm 6425f2c45f1SShri Abhyankar 6437a7aea1fSJed Brown Input Parameters: 644f11a936eSBarry Smith . dm - the dmnetwork object 6455f2c45f1SShri Abhyankar 6465f2c45f1SShri Abhyankar Notes: 6475f2c45f1SShri Abhyankar This routine should be called after the network sizes and edgelists have been provided. It creates 6485f2c45f1SShri Abhyankar the bare layout of the network and sets up the network to begin insertion of components. 6495f2c45f1SShri Abhyankar 6505f2c45f1SShri Abhyankar All the components should be registered before calling this routine. 6515f2c45f1SShri Abhyankar 65297bb938eSShri Abhyankar Level: beginner 6535f2c45f1SShri Abhyankar 6542bf73ac6SHong Zhang .seealso: DMNetworkSetNumSubNetworks(), DMNetworkAddSubnetwork() 6555f2c45f1SShri Abhyankar @*/ 6565f2c45f1SShri Abhyankar PetscErrorCode DMNetworkLayoutSetUp(DM dm) 6575f2c45f1SShri Abhyankar { 6585f2c45f1SShri Abhyankar PetscErrorCode ierr; 6595f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 660f11a936eSBarry Smith PetscInt i,j,ctr,Nsubnet=network->Nsubnet,*eowners,np,*edges,*subnetvtx,*subnetedge,e,v,vfrom,vto; 661caf410d2SHong Zhang const PetscInt *cone; 662caf410d2SHong Zhang MPI_Comm comm; 663caf410d2SHong Zhang PetscMPIInt size,rank; 6646500d4abSHong Zhang 6656500d4abSHong Zhang PetscFunctionBegin; 6662bf73ac6SHong Zhang if (network->nsubnet != network->Nsubnet) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Must call DMNetworkAddSubnetwork() %D times",network->Nsubnet); 6672bf73ac6SHong Zhang 6682bf73ac6SHong Zhang /* Create svtable for querry shared vertices */ 6692bf73ac6SHong Zhang ierr = PetscTableCreate(network->Nsvtx,network->NVertices+1,&network->svtable);CHKERRQ(ierr); 6702bf73ac6SHong Zhang 6712bf73ac6SHong Zhang if (network->Nsvtx) { 6722bf73ac6SHong Zhang ierr = DMNetworkLayoutSetUp_Coupling(dm);CHKERRQ(ierr); 6732bf73ac6SHong Zhang PetscFunctionReturn(0); 6742bf73ac6SHong Zhang } 6752bf73ac6SHong Zhang 676caf410d2SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 677ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 678ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 6796500d4abSHong Zhang 680f11a936eSBarry Smith /* Create LOCAL edgelist in global vertex ordering for the network by concatenating local input edgelists of the subnetworks */ 6818e71b177SVaclav Hapla ierr = PetscCalloc1(2*network->nEdges,&edges);CHKERRQ(ierr); 682caf410d2SHong Zhang ctr = 0; 6832bf73ac6SHong Zhang for (i=0; i < Nsubnet; i++) { 6846500d4abSHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 685ba38b151SHong Zhang edges[2*ctr] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j]; 686ba38b151SHong Zhang edges[2*ctr+1] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j+1]; 6876500d4abSHong Zhang ctr++; 6886500d4abSHong Zhang } 6896500d4abSHong Zhang } 6907765340cSHong Zhang 6912bf73ac6SHong Zhang /* Create network->plex; One dimensional network, numCorners=2 */ 6928e71b177SVaclav Hapla ierr = DMCreate(comm,&network->plex);CHKERRQ(ierr); 6938e71b177SVaclav Hapla ierr = DMSetType(network->plex,DMPLEX);CHKERRQ(ierr); 6942bf73ac6SHong Zhang ierr = DMSetDimension(network->plex,1);CHKERRQ(ierr); 695caf410d2SHong Zhang if (size == 1) { 6962bf73ac6SHong Zhang ierr = DMPlexBuildFromCellList(network->plex,network->nEdges,network->nVertices,2,edges);CHKERRQ(ierr); 697caf410d2SHong Zhang } else { 6982bf73ac6SHong Zhang ierr = DMPlexBuildFromCellListParallel(network->plex,network->nEdges,network->nVertices,PETSC_DECIDE,2,edges,NULL);CHKERRQ(ierr); 699acdb140fSBarry Smith } 7006500d4abSHong Zhang 7016500d4abSHong Zhang ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr); 7026500d4abSHong Zhang ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr); 7036500d4abSHong Zhang ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr); 7046500d4abSHong Zhang 705caf410d2SHong Zhang ierr = PetscSectionCreate(comm,&network->DataSection);CHKERRQ(ierr); 706caf410d2SHong Zhang ierr = PetscSectionCreate(comm,&network->DofSection);CHKERRQ(ierr); 7076500d4abSHong Zhang ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr); 7086500d4abSHong Zhang ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr); 7096500d4abSHong Zhang 710caf410d2SHong Zhang np = network->pEnd - network->pStart; 711caf410d2SHong Zhang ierr = PetscCalloc2(np,&network->header,np,&network->cvalue);CHKERRQ(ierr); 71254dfd506SHong Zhang for (i=0; i < np; i++) { 71354dfd506SHong Zhang network->header[i].maxcomps = 1; 71454dfd506SHong Zhang ierr = SetUpNetworkHeaderComponentValue(dm,&network->header[i],&network->cvalue[i]);CHKERRQ(ierr); 71554dfd506SHong Zhang } 716caf410d2SHong Zhang 717f11a936eSBarry Smith /* Create edge and vertex arrays for the subnetworks 718f11a936eSBarry Smith This implementation assumes that DMNetwork reads 719f11a936eSBarry Smith (1) a single subnetwork in parallel; or 720f11a936eSBarry Smith (2) n subnetworks using n processors, one subnetwork/processor. 721f11a936eSBarry Smith */ 722f11a936eSBarry Smith ierr = PetscCalloc2(network->nEdges,&subnetedge,network->nVertices,&subnetvtx);CHKERRQ(ierr); /* Maps local edge/vertex to local subnetwork's edge/vertex */ 723f11a936eSBarry Smith 724f11a936eSBarry Smith network->subnetedge = subnetedge; 725f11a936eSBarry Smith network->subnetvtx = subnetvtx; 7262bf73ac6SHong Zhang for (j=0; j < network->Nsubnet; j++) { 727f11a936eSBarry Smith network->subnet[j].edges = subnetedge; 728f11a936eSBarry Smith subnetedge += network->subnet[j].nedge; 729f11a936eSBarry Smith 730f11a936eSBarry Smith network->subnet[j].vertices = subnetvtx; 731f11a936eSBarry Smith subnetvtx += network->subnet[j].nvtx; 7326500d4abSHong Zhang } 733caf410d2SHong Zhang 734caf410d2SHong Zhang /* Get edge ownership */ 7352bf73ac6SHong Zhang ierr = PetscMalloc1(size+1,&eowners);CHKERRQ(ierr); 736caf410d2SHong Zhang np = network->eEnd - network->eStart; 737ffc4695bSBarry Smith ierr = MPI_Allgather(&np,1,MPIU_INT,eowners+1,1,MPIU_INT,comm);CHKERRMPI(ierr); 738caf410d2SHong Zhang eowners[0] = 0; 739caf410d2SHong Zhang for (i=2; i<=size; i++) eowners[i] += eowners[i-1]; 740caf410d2SHong Zhang 7412bf73ac6SHong Zhang /* Setup edge and vertex arrays for subnetworks */ 7422bf73ac6SHong Zhang e = 0; 7432bf73ac6SHong Zhang for (i=0; i < Nsubnet; i++) { 744f11a936eSBarry Smith ctr = 0; 7452bf73ac6SHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 7462bf73ac6SHong Zhang /* edge e */ 7472bf73ac6SHong Zhang network->header[e].index = e + eowners[rank]; /* Global edge index */ 7482bf73ac6SHong Zhang network->header[e].subnetid = i; 7492bf73ac6SHong Zhang network->subnet[i].edges[j] = e; 750caf410d2SHong Zhang 7512bf73ac6SHong Zhang network->header[e].ndata = 0; 7522bf73ac6SHong Zhang network->header[e].offset[0] = 0; 7532bf73ac6SHong Zhang network->header[e].offsetvarrel[0] = 0; 75454dfd506SHong Zhang ierr = PetscSectionAddDof(network->DataSection,e,network->header[e].hsize);CHKERRQ(ierr); 7552bf73ac6SHong Zhang 7562bf73ac6SHong Zhang /* connected vertices */ 7572bf73ac6SHong Zhang ierr = DMPlexGetCone(network->plex,e,&cone);CHKERRQ(ierr); 7582bf73ac6SHong Zhang 7592bf73ac6SHong Zhang /* vertex cone[0] */ 760f11a936eSBarry Smith v = cone[0]; 761f11a936eSBarry Smith network->header[v].index = edges[2*e]; /* Global vertex index */ 762f11a936eSBarry Smith network->header[v].subnetid = i; /* Subnetwork id */ 763f11a936eSBarry Smith if (Nsubnet == 1) { 764f11a936eSBarry Smith network->subnet[i].vertices[v - network->vStart] = v; /* user's subnet[].idx = petsc's v */ 765f11a936eSBarry Smith } else { 766f11a936eSBarry Smith vfrom = network->subnet[i].edgelist[2*ctr]; /* =subnet[i].idx, Global index! */ 767f11a936eSBarry Smith network->subnet[i].vertices[vfrom] = v; /* user's subnet[].dix = petsc's v */ 768f11a936eSBarry Smith } 7692bf73ac6SHong Zhang 7702bf73ac6SHong Zhang /* vertex cone[1] */ 771f11a936eSBarry Smith v = cone[1]; 772f11a936eSBarry Smith network->header[v].index = edges[2*e+1]; /* Global vertex index */ 773f11a936eSBarry Smith network->header[v].subnetid = i; /* Subnetwork id */ 774f11a936eSBarry Smith if (Nsubnet == 1) { 775f11a936eSBarry Smith network->subnet[i].vertices[v - network->vStart] = v; /* user's subnet[].idx = petsc's v */ 776f11a936eSBarry Smith } else { 777f11a936eSBarry Smith vto = network->subnet[i].edgelist[2*ctr+1]; /* =subnet[i].idx, Global index! */ 778f11a936eSBarry Smith network->subnet[i].vertices[vto] = v; /* user's subnet[].dix = petsc's v */ 779f11a936eSBarry Smith } 7802bf73ac6SHong Zhang 781f11a936eSBarry Smith e++; ctr++; 7826500d4abSHong Zhang } 7836500d4abSHong Zhang } 7842bf73ac6SHong Zhang ierr = PetscFree(eowners);CHKERRQ(ierr); 785f11a936eSBarry Smith ierr = PetscFree(edges);CHKERRQ(ierr); /* local edge list with global idx used by DMPlexBuildFromCellList() */ 786caf410d2SHong Zhang 7872bf73ac6SHong Zhang for (v = network->vStart; v < network->vEnd; v++) { 7882bf73ac6SHong Zhang network->header[v].ndata = 0; 7892bf73ac6SHong Zhang network->header[v].offset[0] = 0; 7902bf73ac6SHong Zhang network->header[v].offsetvarrel[0] = 0; 79154dfd506SHong Zhang ierr = PetscSectionAddDof(network->DataSection,v,network->header[e].hsize);CHKERRQ(ierr); 7926500d4abSHong Zhang } 7935f2c45f1SShri Abhyankar PetscFunctionReturn(0); 7945f2c45f1SShri Abhyankar } 7955f2c45f1SShri Abhyankar 79694ef8ddeSSatish Balay /*@C 7972bf73ac6SHong Zhang DMNetworkGetSubnetwork - Returns the information about a requested subnetwork 7982bf73ac6SHong Zhang 7992bf73ac6SHong Zhang Not collective 8002727e31bSShri Abhyankar 8017a7aea1fSJed Brown Input Parameters: 802caf410d2SHong Zhang + dm - the DM object 8032bf73ac6SHong Zhang - netnum - the global index of the subnetwork 8042727e31bSShri Abhyankar 8057a7aea1fSJed Brown Output Parameters: 8062727e31bSShri Abhyankar + nv - number of vertices (local) 8072727e31bSShri Abhyankar . ne - number of edges (local) 8082bf73ac6SHong Zhang . vtx - local vertices of the subnetwork 8092bf73ac6SHong Zhang - edge - local edges of the subnetwork 8102727e31bSShri Abhyankar 8112727e31bSShri Abhyankar Notes: 8122727e31bSShri Abhyankar Cannot call this routine before DMNetworkLayoutSetup() 8132727e31bSShri Abhyankar 81406dd6b0eSSatish Balay Level: intermediate 81506dd6b0eSSatish Balay 8162bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkAddSubnetwork(), DMNetworkLayoutSetUp() 8172727e31bSShri Abhyankar @*/ 8182bf73ac6SHong Zhang PetscErrorCode DMNetworkGetSubnetwork(DM dm,PetscInt netnum,PetscInt *nv,PetscInt *ne,const PetscInt **vtx,const PetscInt **edge) 8192727e31bSShri Abhyankar { 820caf410d2SHong Zhang DM_Network *network = (DM_Network*)dm->data; 8212727e31bSShri Abhyankar 8222727e31bSShri Abhyankar PetscFunctionBegin; 8232bf73ac6SHong 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); 8242bf73ac6SHong Zhang if (nv) *nv = network->subnet[netnum].nvtx; 8252bf73ac6SHong Zhang if (ne) *ne = network->subnet[netnum].nedge; 8262bf73ac6SHong Zhang if (vtx) *vtx = network->subnet[netnum].vertices; 8272bf73ac6SHong Zhang if (edge) *edge = network->subnet[netnum].edges; 8282bf73ac6SHong Zhang PetscFunctionReturn(0); 8292bf73ac6SHong Zhang } 8302bf73ac6SHong Zhang 8312bf73ac6SHong Zhang /*@ 8322bf73ac6SHong Zhang DMNetworkAddSharedVertices - Add shared vertices that connect two given subnetworks 8332bf73ac6SHong Zhang 8342bf73ac6SHong Zhang Collective on dm 8352bf73ac6SHong Zhang 8362bf73ac6SHong Zhang Input Parameters: 8372bf73ac6SHong Zhang + dm - the dm object 8382bf73ac6SHong Zhang . anetnum - first subnetwork global numbering returned by DMNetworkAddSubnetwork() 8392bf73ac6SHong Zhang . bnetnum - second subnetwork global numbering returned by DMNetworkAddSubnetwork() 8402bf73ac6SHong Zhang . nsvtx - number of vertices that are shared by the two subnetworks 8412bf73ac6SHong Zhang . asvtx - vertex index in the first subnetwork 8422bf73ac6SHong Zhang - bsvtx - vertex index in the second subnetwork 8432bf73ac6SHong Zhang 8442bf73ac6SHong Zhang Level: beginner 8452bf73ac6SHong Zhang 8462bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkAddSubnetwork(), DMNetworkGetSharedVertices() 8472bf73ac6SHong Zhang @*/ 8482bf73ac6SHong Zhang PetscErrorCode DMNetworkAddSharedVertices(DM dm,PetscInt anetnum,PetscInt bnetnum,PetscInt nsvtx,PetscInt asvtx[],PetscInt bsvtx[]) 8492bf73ac6SHong Zhang { 8502bf73ac6SHong Zhang PetscErrorCode ierr; 8512bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 8522bf73ac6SHong Zhang PetscInt i,nsubnet = network->Nsubnet,*sedgelist,Nsvtx=network->Nsvtx; 8532bf73ac6SHong Zhang 8542bf73ac6SHong Zhang PetscFunctionBegin; 8552bf73ac6SHong Zhang if (anetnum == bnetnum) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Subnetworks must have different netnum"); 8562bf73ac6SHong Zhang if (anetnum < 0 || bnetnum < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"netnum cannot be negative"); 8572bf73ac6SHong Zhang if (!Nsvtx) { 8582bf73ac6SHong Zhang /* allocate network->sedgelist to hold at most 2*nsubnet pairs of shared vertices */ 8592bf73ac6SHong Zhang ierr = PetscMalloc1(2*4*nsubnet,&network->sedgelist);CHKERRQ(ierr); 8602bf73ac6SHong Zhang } 8612bf73ac6SHong Zhang 8622bf73ac6SHong Zhang sedgelist = network->sedgelist; 8632bf73ac6SHong Zhang for (i=0; i<nsvtx; i++) { 8642bf73ac6SHong Zhang sedgelist[4*Nsvtx] = anetnum; sedgelist[4*Nsvtx+1] = asvtx[i]; 8652bf73ac6SHong Zhang sedgelist[4*Nsvtx+2] = bnetnum; sedgelist[4*Nsvtx+3] = bsvtx[i]; 8662bf73ac6SHong Zhang Nsvtx++; 8672bf73ac6SHong Zhang } 8682bf73ac6SHong Zhang if (Nsvtx > 2*nsubnet) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"allocate more space for coupling edgelist"); 8692bf73ac6SHong Zhang network->Nsvtx = Nsvtx; 8702727e31bSShri Abhyankar PetscFunctionReturn(0); 8712727e31bSShri Abhyankar } 8722727e31bSShri Abhyankar 8732727e31bSShri Abhyankar /*@C 8742bf73ac6SHong Zhang DMNetworkGetSharedVertices - Returns the info for the shared vertices 8752bf73ac6SHong Zhang 8762bf73ac6SHong Zhang Not collective 877caf410d2SHong Zhang 8787a7aea1fSJed Brown Input Parameters: 8792bf73ac6SHong Zhang . dm - the DM object 880caf410d2SHong Zhang 8817a7aea1fSJed Brown Output Parameters: 8822bf73ac6SHong Zhang + nsv - number of local shared vertices 8832bf73ac6SHong Zhang - svtx - local shared vertices 884caf410d2SHong Zhang 885caf410d2SHong Zhang Notes: 886caf410d2SHong Zhang Cannot call this routine before DMNetworkLayoutSetup() 887caf410d2SHong Zhang 888caf410d2SHong Zhang Level: intermediate 889caf410d2SHong Zhang 8902bf73ac6SHong Zhang .seealso: DMNetworkGetSubnetwork(), DMNetworkLayoutSetUp(), DMNetworkAddSharedVertices() 891caf410d2SHong Zhang @*/ 8922bf73ac6SHong Zhang PetscErrorCode DMNetworkGetSharedVertices(DM dm,PetscInt *nsv,const PetscInt **svtx) 893caf410d2SHong Zhang { 894caf410d2SHong Zhang DM_Network *net = (DM_Network*)dm->data; 895caf410d2SHong Zhang 896caf410d2SHong Zhang PetscFunctionBegin; 8972bf73ac6SHong Zhang if (net->Nsvtx) { 8982bf73ac6SHong Zhang *nsv = net->nsvtx; 8992bf73ac6SHong Zhang *svtx = net->svertices; 90072c3e9f7SHong Zhang } else { 9012bf73ac6SHong Zhang *nsv = 0; 9022bf73ac6SHong Zhang *svtx = NULL; 90372c3e9f7SHong Zhang } 904caf410d2SHong Zhang PetscFunctionReturn(0); 905caf410d2SHong Zhang } 906caf410d2SHong Zhang 907caf410d2SHong Zhang /*@C 9085f2c45f1SShri Abhyankar DMNetworkRegisterComponent - Registers the network component 9095f2c45f1SShri Abhyankar 910d083f849SBarry Smith Logically collective on dm 9115f2c45f1SShri Abhyankar 9127a7aea1fSJed Brown Input Parameters: 9135f2c45f1SShri Abhyankar + dm - the network object 9145f2c45f1SShri Abhyankar . name - the component name 9155f2c45f1SShri Abhyankar - size - the storage size in bytes for this component data 9165f2c45f1SShri Abhyankar 9177a7aea1fSJed Brown Output Parameters: 9185f2c45f1SShri Abhyankar . key - an integer key that defines the component 9195f2c45f1SShri Abhyankar 9205f2c45f1SShri Abhyankar Notes 9215f2c45f1SShri Abhyankar This routine should be called by all processors before calling DMNetworkLayoutSetup(). 9225f2c45f1SShri Abhyankar 92397bb938eSShri Abhyankar Level: beginner 9245f2c45f1SShri Abhyankar 9252bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkLayoutSetUp() 9265f2c45f1SShri Abhyankar @*/ 927caf410d2SHong Zhang PetscErrorCode DMNetworkRegisterComponent(DM dm,const char *name,size_t size,PetscInt *key) 9285f2c45f1SShri Abhyankar { 9295f2c45f1SShri Abhyankar PetscErrorCode ierr; 9305f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 93154dfd506SHong Zhang DMNetworkComponent *component=NULL,*newcomponent=NULL; 9325f2c45f1SShri Abhyankar PetscBool flg=PETSC_FALSE; 9335f2c45f1SShri Abhyankar PetscInt i; 9345f2c45f1SShri Abhyankar 9355f2c45f1SShri Abhyankar PetscFunctionBegin; 93654dfd506SHong Zhang if (!network->component) { 93754dfd506SHong Zhang ierr = PetscCalloc1(network->max_comps_registered,&network->component);CHKERRQ(ierr); 93854dfd506SHong Zhang } 93954dfd506SHong Zhang 9405f2c45f1SShri Abhyankar for (i=0; i < network->ncomponent; i++) { 94154dfd506SHong Zhang ierr = PetscStrcmp(network->component[i].name,name,&flg);CHKERRQ(ierr); 9425f2c45f1SShri Abhyankar if (flg) { 9435f2c45f1SShri Abhyankar *key = i; 9445f2c45f1SShri Abhyankar PetscFunctionReturn(0); 9455f2c45f1SShri Abhyankar } 9466d64e262SShri Abhyankar } 94754dfd506SHong Zhang 94854dfd506SHong Zhang if (network->ncomponent == network->max_comps_registered) { 94954dfd506SHong Zhang /* Reached max allowed so resize component */ 95054dfd506SHong Zhang network->max_comps_registered += 2; 95154dfd506SHong Zhang ierr = PetscCalloc1(network->max_comps_registered,&newcomponent);CHKERRQ(ierr); 95254dfd506SHong Zhang /* Copy over the previous component info */ 95354dfd506SHong Zhang for (i=0; i < network->ncomponent; i++) { 95454dfd506SHong Zhang ierr = PetscStrcpy(newcomponent[i].name,network->component[i].name);CHKERRQ(ierr); 95554dfd506SHong Zhang newcomponent[i].size = network->component[i].size; 9565f2c45f1SShri Abhyankar } 95754dfd506SHong Zhang /* Free old one */ 95854dfd506SHong Zhang ierr = PetscFree(network->component);CHKERRQ(ierr); 95954dfd506SHong Zhang /* Update pointer */ 96054dfd506SHong Zhang network->component = newcomponent; 96154dfd506SHong Zhang } 96254dfd506SHong Zhang 96354dfd506SHong Zhang component = &network->component[network->ncomponent]; 9645f2c45f1SShri Abhyankar 9655f2c45f1SShri Abhyankar ierr = PetscStrcpy(component->name,name);CHKERRQ(ierr); 9665f2c45f1SShri Abhyankar component->size = size/sizeof(DMNetworkComponentGenericDataType); 9675f2c45f1SShri Abhyankar *key = network->ncomponent; 9685f2c45f1SShri Abhyankar network->ncomponent++; 9695f2c45f1SShri Abhyankar PetscFunctionReturn(0); 9705f2c45f1SShri Abhyankar } 9715f2c45f1SShri Abhyankar 9725f2c45f1SShri Abhyankar /*@ 9732bf73ac6SHong Zhang DMNetworkGetVertexRange - Get the bounds [start, end) for the local vertices 9745f2c45f1SShri Abhyankar 9755f2c45f1SShri Abhyankar Not Collective 9765f2c45f1SShri Abhyankar 9775f2c45f1SShri Abhyankar Input Parameters: 9782bf73ac6SHong Zhang . dm - the DMNetwork object 9795f2c45f1SShri Abhyankar 980fd292e60Sprj- Output Parameters: 9812bf73ac6SHong Zhang + vStart - the first vertex point 9822bf73ac6SHong Zhang - vEnd - one beyond the last vertex point 9835f2c45f1SShri Abhyankar 98497bb938eSShri Abhyankar Level: beginner 9855f2c45f1SShri Abhyankar 9862bf73ac6SHong Zhang .seealso: DMNetworkGetEdgeRange() 9875f2c45f1SShri Abhyankar @*/ 9885f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVertexRange(DM dm,PetscInt *vStart,PetscInt *vEnd) 9895f2c45f1SShri Abhyankar { 9905f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 9915f2c45f1SShri Abhyankar 9925f2c45f1SShri Abhyankar PetscFunctionBegin; 9935f2c45f1SShri Abhyankar if (vStart) *vStart = network->vStart; 9945f2c45f1SShri Abhyankar if (vEnd) *vEnd = network->vEnd; 9955f2c45f1SShri Abhyankar PetscFunctionReturn(0); 9965f2c45f1SShri Abhyankar } 9975f2c45f1SShri Abhyankar 9985f2c45f1SShri Abhyankar /*@ 9992bf73ac6SHong Zhang DMNetworkGetEdgeRange - Get the bounds [start, end) for the local edges 10005f2c45f1SShri Abhyankar 10015f2c45f1SShri Abhyankar Not Collective 10025f2c45f1SShri Abhyankar 10035f2c45f1SShri Abhyankar Input Parameters: 10042bf73ac6SHong Zhang . dm - the DMNetwork object 10055f2c45f1SShri Abhyankar 1006fd292e60Sprj- Output Parameters: 10075f2c45f1SShri Abhyankar + eStart - The first edge point 10085f2c45f1SShri Abhyankar - eEnd - One beyond the last edge point 10095f2c45f1SShri Abhyankar 101097bb938eSShri Abhyankar Level: beginner 10115f2c45f1SShri Abhyankar 10122bf73ac6SHong Zhang .seealso: DMNetworkGetVertexRange() 10135f2c45f1SShri Abhyankar @*/ 10145f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetEdgeRange(DM dm,PetscInt *eStart,PetscInt *eEnd) 10155f2c45f1SShri Abhyankar { 10165f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10175f2c45f1SShri Abhyankar 10185f2c45f1SShri Abhyankar PetscFunctionBegin; 10195f2c45f1SShri Abhyankar if (eStart) *eStart = network->eStart; 10205f2c45f1SShri Abhyankar if (eEnd) *eEnd = network->eEnd; 10215f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10225f2c45f1SShri Abhyankar } 10235f2c45f1SShri Abhyankar 10242bf73ac6SHong Zhang static PetscErrorCode DMNetworkGetIndex(DM dm,PetscInt p,PetscInt *index) 10252bf73ac6SHong Zhang { 10262bf73ac6SHong Zhang PetscErrorCode ierr; 10272bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 10282bf73ac6SHong Zhang PetscInt offsetp; 10292bf73ac6SHong Zhang DMNetworkComponentHeader header; 10302bf73ac6SHong Zhang 10312bf73ac6SHong Zhang PetscFunctionBegin; 10322bf73ac6SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 10332bf73ac6SHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 10342bf73ac6SHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 10352bf73ac6SHong Zhang *index = header->index; 10362bf73ac6SHong Zhang PetscFunctionReturn(0); 10372bf73ac6SHong Zhang } 10382bf73ac6SHong Zhang 10397b6afd5bSHong Zhang /*@ 10402bf73ac6SHong Zhang DMNetworkGetGlobalEdgeIndex - Get the global numbering for the edge on the network 10417b6afd5bSHong Zhang 10427b6afd5bSHong Zhang Not Collective 10437b6afd5bSHong Zhang 10447b6afd5bSHong Zhang Input Parameters: 10457b6afd5bSHong Zhang + dm - DMNetwork object 1046e85e6aecSHong Zhang - p - edge point 10477b6afd5bSHong Zhang 1048fd292e60Sprj- Output Parameters: 10492bf73ac6SHong Zhang . index - the global numbering for the edge 10507b6afd5bSHong Zhang 10517b6afd5bSHong Zhang Level: intermediate 10527b6afd5bSHong Zhang 10532bf73ac6SHong Zhang .seealso: DMNetworkGetGlobalVertexIndex() 10547b6afd5bSHong Zhang @*/ 1055e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalEdgeIndex(DM dm,PetscInt p,PetscInt *index) 10567b6afd5bSHong Zhang { 10577b6afd5bSHong Zhang PetscErrorCode ierr; 10587b6afd5bSHong Zhang 10597b6afd5bSHong Zhang PetscFunctionBegin; 10602bf73ac6SHong Zhang ierr = DMNetworkGetIndex(dm,p,index);CHKERRQ(ierr); 10617b6afd5bSHong Zhang PetscFunctionReturn(0); 10627b6afd5bSHong Zhang } 10637b6afd5bSHong Zhang 10645f2c45f1SShri Abhyankar /*@ 10652bf73ac6SHong Zhang DMNetworkGetGlobalVertexIndex - Get the global numbering for the vertex on the network 1066e85e6aecSHong Zhang 1067e85e6aecSHong Zhang Not Collective 1068e85e6aecSHong Zhang 1069e85e6aecSHong Zhang Input Parameters: 1070e85e6aecSHong Zhang + dm - DMNetwork object 1071e85e6aecSHong Zhang - p - vertex point 1072e85e6aecSHong Zhang 1073fd292e60Sprj- Output Parameters: 10742bf73ac6SHong Zhang . index - the global numbering for the vertex 1075e85e6aecSHong Zhang 1076e85e6aecSHong Zhang Level: intermediate 1077e85e6aecSHong Zhang 10782bf73ac6SHong Zhang .seealso: DMNetworkGetGlobalEdgeIndex() 1079e85e6aecSHong Zhang @*/ 1080e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalVertexIndex(DM dm,PetscInt p,PetscInt *index) 1081e85e6aecSHong Zhang { 1082e85e6aecSHong Zhang PetscErrorCode ierr; 1083e85e6aecSHong Zhang 1084e85e6aecSHong Zhang PetscFunctionBegin; 10852bf73ac6SHong Zhang ierr = DMNetworkGetIndex(dm,p,index);CHKERRQ(ierr); 10869988b915SShri Abhyankar PetscFunctionReturn(0); 10879988b915SShri Abhyankar } 10889988b915SShri Abhyankar 10899988b915SShri Abhyankar /*@ 10905f2c45f1SShri Abhyankar DMNetworkGetNumComponents - Get the number of components at a vertex/edge 10915f2c45f1SShri Abhyankar 10925f2c45f1SShri Abhyankar Not Collective 10935f2c45f1SShri Abhyankar 10945f2c45f1SShri Abhyankar Input Parameters: 10952bf73ac6SHong Zhang + dm - the DMNetwork object 1096a2b725a8SWilliam Gropp - p - vertex/edge point 10975f2c45f1SShri Abhyankar 10985f2c45f1SShri Abhyankar Output Parameters: 10995f2c45f1SShri Abhyankar . numcomponents - Number of components at the vertex/edge 11005f2c45f1SShri Abhyankar 110197bb938eSShri Abhyankar Level: beginner 11025f2c45f1SShri Abhyankar 11032bf73ac6SHong Zhang .seealso: DMNetworkRegisterComponent(), DMNetworkAddComponent() 11045f2c45f1SShri Abhyankar @*/ 11055f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetNumComponents(DM dm,PetscInt p,PetscInt *numcomponents) 11065f2c45f1SShri Abhyankar { 11075f2c45f1SShri Abhyankar PetscErrorCode ierr; 11085f2c45f1SShri Abhyankar PetscInt offset; 11095f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 11105f2c45f1SShri Abhyankar 11115f2c45f1SShri Abhyankar PetscFunctionBegin; 11125f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 11135f2c45f1SShri Abhyankar *numcomponents = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 11145f2c45f1SShri Abhyankar PetscFunctionReturn(0); 11155f2c45f1SShri Abhyankar } 11165f2c45f1SShri Abhyankar 11175f2c45f1SShri Abhyankar /*@ 11182bf73ac6SHong Zhang DMNetworkGetLocalVecOffset - Get the offset for accessing the variables associated with a component at the given vertex/edge from the local vector 11195f2c45f1SShri Abhyankar 11205f2c45f1SShri Abhyankar Not Collective 11215f2c45f1SShri Abhyankar 11225f2c45f1SShri Abhyankar Input Parameters: 11232bf73ac6SHong Zhang + dm - the DMNetwork object 11247d928bffSSatish Balay . p - the edge/vertex point 11252bf73ac6SHong Zhang - compnum - component number; use ALL_COMPONENTS if no specific component is requested 11269988b915SShri Abhyankar 11279988b915SShri Abhyankar Output Parameters: 11282bf73ac6SHong Zhang . offset - the local offset 11299988b915SShri Abhyankar 11309988b915SShri Abhyankar Level: intermediate 11319988b915SShri Abhyankar 11322bf73ac6SHong Zhang .seealso: DMGetLocalVector(), DMNetworkGetComponent(), DMNetworkGetGlobalVecOffset() 11339988b915SShri Abhyankar @*/ 11342bf73ac6SHong Zhang PetscErrorCode DMNetworkGetLocalVecOffset(DM dm,PetscInt p,PetscInt compnum,PetscInt *offset) 11359988b915SShri Abhyankar { 11369988b915SShri Abhyankar PetscErrorCode ierr; 11379988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 11389988b915SShri Abhyankar PetscInt offsetp,offsetd; 11399988b915SShri Abhyankar DMNetworkComponentHeader header; 11409988b915SShri Abhyankar 11419988b915SShri Abhyankar PetscFunctionBegin; 11422bf73ac6SHong Zhang ierr = PetscSectionGetOffset(network->plex->localSection,p,&offsetp);CHKERRQ(ierr); 11432bf73ac6SHong Zhang if (compnum == ALL_COMPONENTS) { 11442bf73ac6SHong Zhang *offset = offsetp; 11452bf73ac6SHong Zhang PetscFunctionReturn(0); 11462bf73ac6SHong Zhang } 11472bf73ac6SHong Zhang 11489988b915SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetd);CHKERRQ(ierr); 11499988b915SShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetd); 11509988b915SShri Abhyankar *offset = offsetp + header->offsetvarrel[compnum]; 11519988b915SShri Abhyankar PetscFunctionReturn(0); 11529988b915SShri Abhyankar } 11539988b915SShri Abhyankar 11549988b915SShri Abhyankar /*@ 11552bf73ac6SHong Zhang DMNetworkGetGlobalVecOffset - Get the global offset for accessing the variables associated with a component for the given vertex/edge from the global vector 11569988b915SShri Abhyankar 11579988b915SShri Abhyankar Not Collective 11589988b915SShri Abhyankar 11599988b915SShri Abhyankar Input Parameters: 11602bf73ac6SHong Zhang + dm - the DMNetwork object 11617d928bffSSatish Balay . p - the edge/vertex point 11622bf73ac6SHong Zhang - compnum - component number; use ALL_COMPONENTS if no specific component is requested 11639988b915SShri Abhyankar 11649988b915SShri Abhyankar Output Parameters: 11659988b915SShri Abhyankar . offsetg - the global offset 11669988b915SShri Abhyankar 11679988b915SShri Abhyankar Level: intermediate 11689988b915SShri Abhyankar 11692bf73ac6SHong Zhang .seealso: DMNetworkGetLocalVecOffset(), DMGetGlobalVector(), DMNetworkGetComponent() 11709988b915SShri Abhyankar @*/ 11712bf73ac6SHong Zhang PetscErrorCode DMNetworkGetGlobalVecOffset(DM dm,PetscInt p,PetscInt compnum,PetscInt *offsetg) 11729988b915SShri Abhyankar { 11739988b915SShri Abhyankar PetscErrorCode ierr; 11749988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 11759988b915SShri Abhyankar PetscInt offsetp,offsetd; 11769988b915SShri Abhyankar DMNetworkComponentHeader header; 11779988b915SShri Abhyankar 11789988b915SShri Abhyankar PetscFunctionBegin; 11792bf73ac6SHong Zhang ierr = PetscSectionGetOffset(network->plex->globalSection,p,&offsetp);CHKERRQ(ierr); 11802bf73ac6SHong Zhang if (offsetp < 0) offsetp = -(offsetp + 1); /* Convert to actual global offset for ghost vertex */ 11812bf73ac6SHong Zhang 11822bf73ac6SHong Zhang if (compnum == ALL_COMPONENTS) { 11832bf73ac6SHong Zhang *offsetg = offsetp; 11842bf73ac6SHong Zhang PetscFunctionReturn(0); 11852bf73ac6SHong Zhang } 11869988b915SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetd);CHKERRQ(ierr); 11879988b915SShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetd); 11889988b915SShri Abhyankar *offsetg = offsetp + header->offsetvarrel[compnum]; 11899988b915SShri Abhyankar PetscFunctionReturn(0); 11909988b915SShri Abhyankar } 11919988b915SShri Abhyankar 11929988b915SShri Abhyankar /*@ 11932bf73ac6SHong Zhang DMNetworkGetEdgeOffset - Get the offset for accessing the variables associated with the given edge from the local subvector 119424121865SAdrian Maldonado 119524121865SAdrian Maldonado Not Collective 119624121865SAdrian Maldonado 119724121865SAdrian Maldonado Input Parameters: 11982bf73ac6SHong Zhang + dm - the DMNetwork object 119924121865SAdrian Maldonado - p - the edge point 120024121865SAdrian Maldonado 120124121865SAdrian Maldonado Output Parameters: 120224121865SAdrian Maldonado . offset - the offset 120324121865SAdrian Maldonado 120424121865SAdrian Maldonado Level: intermediate 120524121865SAdrian Maldonado 12062bf73ac6SHong Zhang .seealso: DMNetworkGetLocalVecOffset(), DMGetLocalVector() 120724121865SAdrian Maldonado @*/ 120824121865SAdrian Maldonado PetscErrorCode DMNetworkGetEdgeOffset(DM dm,PetscInt p,PetscInt *offset) 120924121865SAdrian Maldonado { 121024121865SAdrian Maldonado PetscErrorCode ierr; 121124121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 121224121865SAdrian Maldonado 121324121865SAdrian Maldonado PetscFunctionBegin; 121424121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->edge.DofSection,p,offset);CHKERRQ(ierr); 121524121865SAdrian Maldonado PetscFunctionReturn(0); 121624121865SAdrian Maldonado } 121724121865SAdrian Maldonado 121824121865SAdrian Maldonado /*@ 12192bf73ac6SHong Zhang DMNetworkGetVertexOffset - Get the offset for accessing the variables associated with the given vertex from the local subvector 122024121865SAdrian Maldonado 122124121865SAdrian Maldonado Not Collective 122224121865SAdrian Maldonado 122324121865SAdrian Maldonado Input Parameters: 12242bf73ac6SHong Zhang + dm - the DMNetwork object 122524121865SAdrian Maldonado - p - the vertex point 122624121865SAdrian Maldonado 122724121865SAdrian Maldonado Output Parameters: 122824121865SAdrian Maldonado . offset - the offset 122924121865SAdrian Maldonado 123024121865SAdrian Maldonado Level: intermediate 123124121865SAdrian Maldonado 12322bf73ac6SHong Zhang .seealso: DMNetworkGetEdgeOffset(), DMGetLocalVector() 123324121865SAdrian Maldonado @*/ 123424121865SAdrian Maldonado PetscErrorCode DMNetworkGetVertexOffset(DM dm,PetscInt p,PetscInt *offset) 123524121865SAdrian Maldonado { 123624121865SAdrian Maldonado PetscErrorCode ierr; 123724121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 123824121865SAdrian Maldonado 123924121865SAdrian Maldonado PetscFunctionBegin; 124024121865SAdrian Maldonado p -= network->vStart; 124124121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->vertex.DofSection,p,offset);CHKERRQ(ierr); 124224121865SAdrian Maldonado PetscFunctionReturn(0); 124324121865SAdrian Maldonado } 12442bf73ac6SHong Zhang 12455f2c45f1SShri Abhyankar /*@ 12462bf73ac6SHong Zhang DMNetworkAddComponent - Adds a network component and number of variables at the given point (vertex/edge) 12475f2c45f1SShri Abhyankar 12485f2c45f1SShri Abhyankar Not Collective 12495f2c45f1SShri Abhyankar 12505f2c45f1SShri Abhyankar Input Parameters: 12514dc646bcSBarry Smith + dm - the DMNetwork 12525f2c45f1SShri Abhyankar . p - the vertex/edge point 12532bf73ac6SHong Zhang . componentkey - component key returned while registering the component; ignored if compvalue=NULL 12542bf73ac6SHong Zhang . compvalue - pointer to the data structure for the component, or NULL if not required. 12552bf73ac6SHong Zhang - nvar - number of variables for the component at the vertex/edge point 12565f2c45f1SShri Abhyankar 125797bb938eSShri Abhyankar Level: beginner 12585f2c45f1SShri Abhyankar 12592bf73ac6SHong Zhang .seealso: DMNetworkGetComponent() 12605f2c45f1SShri Abhyankar @*/ 12612bf73ac6SHong Zhang PetscErrorCode DMNetworkAddComponent(DM dm,PetscInt p,PetscInt componentkey,void* compvalue,PetscInt nvar) 12625f2c45f1SShri Abhyankar { 12635f2c45f1SShri Abhyankar PetscErrorCode ierr; 12645f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 12652bf73ac6SHong Zhang DMNetworkComponent *component = &network->component[componentkey]; 126654dfd506SHong Zhang DMNetworkComponentHeader header; 126754dfd506SHong Zhang DMNetworkComponentValue cvalue; 12682bf73ac6SHong Zhang PetscBool sharedv=PETSC_FALSE; 126954dfd506SHong Zhang PetscInt compnum; 127054dfd506SHong Zhang PetscInt *compsize,*compkey,*compoffset,*compnvar,*compoffsetvarrel; 127154dfd506SHong Zhang void* *compdata; 12725f2c45f1SShri Abhyankar 12735f2c45f1SShri Abhyankar PetscFunctionBegin; 12745f2c45f1SShri Abhyankar ierr = PetscSectionAddDof(network->DofSection,p,nvar);CHKERRQ(ierr); 12752bf73ac6SHong Zhang if (!compvalue) PetscFunctionReturn(0); 12762bf73ac6SHong Zhang 12772bf73ac6SHong Zhang ierr = DMNetworkIsSharedVertex(dm,p,&sharedv);CHKERRQ(ierr); 12782bf73ac6SHong Zhang if (sharedv) { 12792bf73ac6SHong Zhang PetscBool ghost; 12802bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 12812bf73ac6SHong Zhang if (ghost) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Adding a component at a leaf(ghost) shared vertex is not supported"); 12822bf73ac6SHong Zhang } 12832bf73ac6SHong Zhang 128454dfd506SHong Zhang header = &network->header[p]; 128554dfd506SHong Zhang cvalue = &network->cvalue[p]; 128654dfd506SHong Zhang if (header->ndata == header->maxcomps) { 1287f11a936eSBarry Smith PetscInt additional_size; 1288f11a936eSBarry Smith 128954dfd506SHong Zhang /* Reached limit so resize header component arrays */ 129054dfd506SHong Zhang header->maxcomps += 2; 129154dfd506SHong Zhang 129254dfd506SHong Zhang /* Allocate arrays for component information and value */ 129354dfd506SHong Zhang ierr = PetscCalloc5(header->maxcomps,&compsize,header->maxcomps,&compkey,header->maxcomps,&compoffset,header->maxcomps,&compnvar,header->maxcomps,&compoffsetvarrel);CHKERRQ(ierr); 129454dfd506SHong Zhang ierr = PetscMalloc1(header->maxcomps,&compdata);CHKERRQ(ierr); 129554dfd506SHong Zhang 129654dfd506SHong Zhang /* Recalculate header size */ 129754dfd506SHong Zhang header->hsize = sizeof(struct _p_DMNetworkComponentHeader) + 5*header->maxcomps*sizeof(PetscInt); 129854dfd506SHong Zhang 129954dfd506SHong Zhang header->hsize /= sizeof(DMNetworkComponentGenericDataType); 130054dfd506SHong Zhang 130154dfd506SHong Zhang /* Copy over component info */ 130254dfd506SHong Zhang ierr = PetscMemcpy(compsize,header->size,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 130354dfd506SHong Zhang ierr = PetscMemcpy(compkey,header->key,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 130454dfd506SHong Zhang ierr = PetscMemcpy(compoffset,header->offset,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 130554dfd506SHong Zhang ierr = PetscMemcpy(compnvar,header->nvar,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 130654dfd506SHong Zhang ierr = PetscMemcpy(compoffsetvarrel,header->offsetvarrel,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 130754dfd506SHong Zhang 130854dfd506SHong Zhang /* Copy over component data pointers */ 130954dfd506SHong Zhang ierr = PetscMemcpy(compdata,cvalue->data,header->ndata*sizeof(void*));CHKERRQ(ierr); 131054dfd506SHong Zhang 131154dfd506SHong Zhang /* Free old arrays */ 131254dfd506SHong Zhang ierr = PetscFree5(header->size,header->key,header->offset,header->nvar,header->offsetvarrel);CHKERRQ(ierr); 131354dfd506SHong Zhang ierr = PetscFree(cvalue->data);CHKERRQ(ierr); 131454dfd506SHong Zhang 131554dfd506SHong Zhang /* Update pointers */ 131654dfd506SHong Zhang header->size = compsize; 131754dfd506SHong Zhang header->key = compkey; 131854dfd506SHong Zhang header->offset = compoffset; 131954dfd506SHong Zhang header->nvar = compnvar; 132054dfd506SHong Zhang header->offsetvarrel = compoffsetvarrel; 132154dfd506SHong Zhang 132254dfd506SHong Zhang cvalue->data = compdata; 132354dfd506SHong Zhang 132454dfd506SHong Zhang /* Update DataSection Dofs */ 132554dfd506SHong 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 */ 1326f11a936eSBarry Smith additional_size = (5*(header->maxcomps - header->ndata)*sizeof(PetscInt))/sizeof(DMNetworkComponentGenericDataType); 132754dfd506SHong Zhang ierr = PetscSectionAddDof(network->DataSection,p,additional_size);CHKERRQ(ierr); 132854dfd506SHong Zhang } 132954dfd506SHong Zhang header = &network->header[p]; 133054dfd506SHong Zhang cvalue = &network->cvalue[p]; 133154dfd506SHong Zhang 133254dfd506SHong Zhang compnum = header->ndata; 13332bf73ac6SHong Zhang 13342bf73ac6SHong Zhang header->size[compnum] = component->size; 13352bf73ac6SHong Zhang ierr = PetscSectionAddDof(network->DataSection,p,component->size);CHKERRQ(ierr); 13362bf73ac6SHong Zhang header->key[compnum] = componentkey; 13372bf73ac6SHong Zhang if (compnum != 0) header->offset[compnum] = header->offset[compnum-1] + header->size[compnum-1]; 13382bf73ac6SHong Zhang cvalue->data[compnum] = (void*)compvalue; 13392bf73ac6SHong Zhang 13402bf73ac6SHong Zhang /* variables */ 13412bf73ac6SHong Zhang header->nvar[compnum] += nvar; 13422bf73ac6SHong Zhang if (compnum != 0) header->offsetvarrel[compnum] = header->offsetvarrel[compnum-1] + header->nvar[compnum-1]; 13432bf73ac6SHong Zhang 13442bf73ac6SHong Zhang header->ndata++; 13455f2c45f1SShri Abhyankar PetscFunctionReturn(0); 13465f2c45f1SShri Abhyankar } 13475f2c45f1SShri Abhyankar 134827f51fceSHong Zhang /*@ 13492bf73ac6SHong Zhang DMNetworkGetComponent - Gets the component key, the component data, and the number of variables at a given network point 135027f51fceSHong Zhang 135127f51fceSHong Zhang Not Collective 135227f51fceSHong Zhang 135327f51fceSHong Zhang Input Parameters: 13542bf73ac6SHong Zhang + dm - the DMNetwork object 13552bf73ac6SHong Zhang . p - vertex/edge point 135699c90e12SSatish Balay - compnum - component number; use ALL_COMPONENTS if sum up all the components 135727f51fceSHong Zhang 135827f51fceSHong Zhang Output Parameters: 13592bf73ac6SHong Zhang + compkey - the key obtained when registering the component (use NULL if not required) 13602bf73ac6SHong Zhang . component - the component data (use NULL if not required) 13612bf73ac6SHong Zhang - nvar - number of variables (use NULL if not required) 136227f51fceSHong Zhang 136397bb938eSShri Abhyankar Level: beginner 136427f51fceSHong Zhang 13652bf73ac6SHong Zhang .seealso: DMNetworkAddComponent(), DMNetworkGetNumComponents() 136627f51fceSHong Zhang @*/ 13672bf73ac6SHong Zhang PetscErrorCode DMNetworkGetComponent(DM dm,PetscInt p,PetscInt compnum,PetscInt *compkey,void **component,PetscInt *nvar) 136827f51fceSHong Zhang { 136927f51fceSHong Zhang PetscErrorCode ierr; 137027f51fceSHong Zhang DM_Network *network = (DM_Network*)dm->data; 13712bf73ac6SHong Zhang PetscInt offset = 0; 13722bf73ac6SHong Zhang DMNetworkComponentHeader header; 137327f51fceSHong Zhang 137427f51fceSHong Zhang PetscFunctionBegin; 13752bf73ac6SHong Zhang if (compnum == ALL_COMPONENTS) { 137627f51fceSHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 137727f51fceSHong Zhang PetscFunctionReturn(0); 137827f51fceSHong Zhang } 137927f51fceSHong Zhang 13802bf73ac6SHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 138142dc13f1SHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offset); 13825f2c45f1SShri Abhyankar 13832bf73ac6SHong Zhang if (compnum >= 0) { 13842bf73ac6SHong Zhang if (compkey) *compkey = header->key[compnum]; 13852bf73ac6SHong Zhang if (component) { 138654dfd506SHong Zhang offset += header->hsize+header->offset[compnum]; 13872bf73ac6SHong Zhang *component = network->componentdataarray+offset; 13882bf73ac6SHong Zhang } 13892bf73ac6SHong Zhang } 13905f2c45f1SShri Abhyankar 13912bf73ac6SHong Zhang if (nvar) *nvar = header->nvar[compnum]; 139254dfd506SHong Zhang 13935f2c45f1SShri Abhyankar PetscFunctionReturn(0); 13945f2c45f1SShri Abhyankar } 13955f2c45f1SShri Abhyankar 13962bf73ac6SHong Zhang /* 13972bf73ac6SHong Zhang Sets up the array that holds the data for all components and its associated section. 13982bf73ac6SHong 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. 13992bf73ac6SHong Zhang */ 14005f2c45f1SShri Abhyankar PetscErrorCode DMNetworkComponentSetUp(DM dm) 14015f2c45f1SShri Abhyankar { 14025f2c45f1SShri Abhyankar PetscErrorCode ierr; 14035f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 1404f11a936eSBarry Smith PetscInt arr_size,p,offset,offsetp,ncomp,i,*headerarr; 14055f2c45f1SShri Abhyankar DMNetworkComponentHeader header; 14065f2c45f1SShri Abhyankar DMNetworkComponentValue cvalue; 1407f11a936eSBarry Smith DMNetworkComponentHeader headerinfo; 14085f2c45f1SShri Abhyankar DMNetworkComponentGenericDataType *componentdataarray; 14095f2c45f1SShri Abhyankar 14105f2c45f1SShri Abhyankar PetscFunctionBegin; 14115f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr); 14125f2c45f1SShri Abhyankar ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr); 1413f11a936eSBarry Smith /* arr_size+1 fixes pipeline test of opensolaris-misc for src/dm/tests/ex10.c -- Do not know why */ 1414f11a936eSBarry Smith ierr = PetscCalloc1(arr_size+1,&network->componentdataarray);CHKERRQ(ierr); 14155f2c45f1SShri Abhyankar componentdataarray = network->componentdataarray; 14165f2c45f1SShri Abhyankar for (p = network->pStart; p < network->pEnd; p++) { 14175f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 14185f2c45f1SShri Abhyankar /* Copy header */ 14195f2c45f1SShri Abhyankar header = &network->header[p]; 1420f11a936eSBarry Smith headerinfo = (DMNetworkComponentHeader)(componentdataarray+offsetp); 142154dfd506SHong Zhang ierr = PetscMemcpy(headerinfo,header,sizeof(struct _p_DMNetworkComponentHeader));CHKERRQ(ierr); 1422f11a936eSBarry Smith headerarr = (PetscInt*)(headerinfo+1); 142354dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->size,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 142454dfd506SHong Zhang headerarr += header->maxcomps; 142554dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->key,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 142654dfd506SHong Zhang headerarr += header->maxcomps; 142754dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->offset,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 142854dfd506SHong Zhang headerarr += header->maxcomps; 142954dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->nvar,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 143054dfd506SHong Zhang headerarr += header->maxcomps; 143154dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->offsetvarrel,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 143254dfd506SHong Zhang 14335f2c45f1SShri Abhyankar /* Copy data */ 14345f2c45f1SShri Abhyankar cvalue = &network->cvalue[p]; 14355f2c45f1SShri Abhyankar ncomp = header->ndata; 14362bf73ac6SHong Zhang 14375f2c45f1SShri Abhyankar for (i = 0; i < ncomp; i++) { 143854dfd506SHong Zhang offset = offsetp + header->hsize + header->offset[i]; 1439302440fdSBarry Smith ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 14405f2c45f1SShri Abhyankar } 14415f2c45f1SShri Abhyankar } 14425f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14435f2c45f1SShri Abhyankar } 14445f2c45f1SShri Abhyankar 14455f2c45f1SShri Abhyankar /* Sets up the section for dofs. This routine is called during DMSetUp() */ 14462bf73ac6SHong Zhang static PetscErrorCode DMNetworkVariablesSetUp(DM dm) 14475f2c45f1SShri Abhyankar { 14485f2c45f1SShri Abhyankar PetscErrorCode ierr; 14495f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 14502bf73ac6SHong Zhang MPI_Comm comm; 14512bf73ac6SHong Zhang PetscMPIInt size; 14525f2c45f1SShri Abhyankar 14535f2c45f1SShri Abhyankar PetscFunctionBegin; 14542bf73ac6SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 14552bf73ac6SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 14562bf73ac6SHong Zhang 14572bf73ac6SHong Zhang if (size > 1) { /* Sync nvar at shared vertices for all processes */ 14582bf73ac6SHong Zhang PetscSF sf = network->plex->sf; 14592bf73ac6SHong Zhang PetscInt *local_nvar, *remote_nvar,nroots,nleaves,p=-1,i,nsv; 14602bf73ac6SHong Zhang const PetscInt *svtx; 14612bf73ac6SHong Zhang PetscBool ghost; 14622bf73ac6SHong Zhang /* 14632bf73ac6SHong Zhang PetscMPIInt rank; 14642bf73ac6SHong Zhang const PetscInt *ilocal; 14652bf73ac6SHong Zhang const PetscSFNode *iremote; 14662bf73ac6SHong Zhang ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 14672bf73ac6SHong Zhang ierr = PetscSFGetGraph(sf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr); 14682bf73ac6SHong Zhang */ 14692bf73ac6SHong Zhang ierr = PetscSFGetGraph(sf,&nroots,&nleaves,NULL,NULL);CHKERRQ(ierr); 14702bf73ac6SHong Zhang ierr = PetscCalloc2(nroots,&local_nvar,nroots,&remote_nvar);CHKERRQ(ierr); 14712bf73ac6SHong Zhang 14722bf73ac6SHong Zhang /* Leaves copy user's nvar to local_nvar */ 14732bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&nsv,&svtx);CHKERRQ(ierr); 14742bf73ac6SHong Zhang for (i=0; i<nsv; i++) { 14752bf73ac6SHong Zhang p = svtx[i]; 14762bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 14772bf73ac6SHong Zhang if (!ghost) continue; 14782bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,&local_nvar[p]);CHKERRQ(ierr); 14792bf73ac6SHong Zhang /* printf("[%d] Before SFReduce: leaf local_nvar[%d] = %d\n",rank,p,local_nvar[p]); */ 14802bf73ac6SHong Zhang } 14812bf73ac6SHong Zhang 14822bf73ac6SHong Zhang /* Leaves add local_nvar to root remote_nvar */ 14832bf73ac6SHong Zhang ierr = PetscSFReduceBegin(sf, MPIU_INT, local_nvar, remote_nvar, MPI_SUM);CHKERRQ(ierr); 14842bf73ac6SHong Zhang ierr = PetscSFReduceEnd(sf, MPIU_INT, local_nvar, remote_nvar, MPI_SUM);CHKERRQ(ierr); 14852bf73ac6SHong Zhang /* printf("[%d] remote_nvar[%d] = %d\n",rank,p,remote_nvar[p]); */ 14862bf73ac6SHong Zhang 14872bf73ac6SHong Zhang /* Update roots' local_nvar */ 14882bf73ac6SHong Zhang for (i=0; i<nsv; i++) { 14892bf73ac6SHong Zhang p = svtx[i]; 14902bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 14912bf73ac6SHong Zhang if (ghost) continue; 14922bf73ac6SHong Zhang 14932bf73ac6SHong Zhang ierr = PetscSectionAddDof(network->DofSection,p,remote_nvar[p]);CHKERRQ(ierr); 14942bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,&local_nvar[p]);CHKERRQ(ierr); 14952bf73ac6SHong Zhang /* printf("[%d] After SFReduce: root local_nvar[%d] = %d\n",rank,p,local_nvar[p]); */ 14962bf73ac6SHong Zhang } 14972bf73ac6SHong Zhang 14982bf73ac6SHong Zhang /* Roots Bcast nvar to leaves */ 1499ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sf, MPIU_INT, local_nvar, remote_nvar,MPI_REPLACE);CHKERRQ(ierr); 1500ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sf, MPIU_INT, local_nvar, remote_nvar,MPI_REPLACE);CHKERRQ(ierr); 15012bf73ac6SHong Zhang 15022bf73ac6SHong Zhang /* Leaves reset receved/remote nvar to dm */ 15032bf73ac6SHong Zhang for (i=0; i<nsv; i++) { 15042bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 15052bf73ac6SHong Zhang if (!ghost) continue; 15062bf73ac6SHong Zhang p = svtx[i]; 15072bf73ac6SHong Zhang /* printf("[%d] leaf reset nvar %d at p= %d \n",rank,remote_nvar[p],p); */ 15082bf73ac6SHong Zhang /* DMNetworkSetNumVariables(dm,p,remote_nvar[p]) */ 15092bf73ac6SHong Zhang ierr = PetscSectionSetDof(network->DofSection,p,remote_nvar[p]);CHKERRQ(ierr); 15102bf73ac6SHong Zhang } 15112bf73ac6SHong Zhang 15122bf73ac6SHong Zhang ierr = PetscFree2(local_nvar,remote_nvar);CHKERRQ(ierr); 15132bf73ac6SHong Zhang } 15142bf73ac6SHong Zhang 15155f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr); 15165f2c45f1SShri Abhyankar PetscFunctionReturn(0); 15175f2c45f1SShri Abhyankar } 15185f2c45f1SShri Abhyankar 151924121865SAdrian Maldonado /* Get a subsection from a range of points */ 15209dddd249SSatish Balay static PetscErrorCode DMNetworkGetSubSection_private(PetscSection main,PetscInt pstart,PetscInt pend,PetscSection *subsection) 152124121865SAdrian Maldonado { 152224121865SAdrian Maldonado PetscErrorCode ierr; 152324121865SAdrian Maldonado PetscInt i, nvar; 152424121865SAdrian Maldonado 152524121865SAdrian Maldonado PetscFunctionBegin; 15269dddd249SSatish Balay ierr = PetscSectionCreate(PetscObjectComm((PetscObject)main), subsection);CHKERRQ(ierr); 152724121865SAdrian Maldonado ierr = PetscSectionSetChart(*subsection, 0, pend - pstart);CHKERRQ(ierr); 152824121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 15299dddd249SSatish Balay ierr = PetscSectionGetDof(main,i,&nvar);CHKERRQ(ierr); 153024121865SAdrian Maldonado ierr = PetscSectionSetDof(*subsection, i - pstart, nvar);CHKERRQ(ierr); 153124121865SAdrian Maldonado } 153224121865SAdrian Maldonado 153324121865SAdrian Maldonado ierr = PetscSectionSetUp(*subsection);CHKERRQ(ierr); 153424121865SAdrian Maldonado PetscFunctionReturn(0); 153524121865SAdrian Maldonado } 153624121865SAdrian Maldonado 153724121865SAdrian Maldonado /* Create a submap of points with a GlobalToLocal structure */ 15382bf73ac6SHong Zhang static PetscErrorCode DMNetworkSetSubMap_private(PetscInt pstart, PetscInt pend, ISLocalToGlobalMapping *map) 153924121865SAdrian Maldonado { 154024121865SAdrian Maldonado PetscErrorCode ierr; 154124121865SAdrian Maldonado PetscInt i, *subpoints; 154224121865SAdrian Maldonado 154324121865SAdrian Maldonado PetscFunctionBegin; 154424121865SAdrian Maldonado /* Create index sets to map from "points" to "subpoints" */ 154524121865SAdrian Maldonado ierr = PetscMalloc1(pend - pstart, &subpoints);CHKERRQ(ierr); 154624121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 154724121865SAdrian Maldonado subpoints[i - pstart] = i; 154824121865SAdrian Maldonado } 1549459726d8SSatish Balay ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,pend-pstart,subpoints,PETSC_COPY_VALUES,map);CHKERRQ(ierr); 155024121865SAdrian Maldonado ierr = PetscFree(subpoints);CHKERRQ(ierr); 155124121865SAdrian Maldonado PetscFunctionReturn(0); 155224121865SAdrian Maldonado } 155324121865SAdrian Maldonado 155424121865SAdrian Maldonado /*@ 15552bf73ac6SHong Zhang DMNetworkAssembleGraphStructures - Assembles vertex and edge data structures. Must be called after DMNetworkDistribute 155624121865SAdrian Maldonado 15572bf73ac6SHong Zhang Collective on dm 155824121865SAdrian Maldonado 155924121865SAdrian Maldonado Input Parameters: 15602bf73ac6SHong Zhang . dm - the DMNetworkObject 156124121865SAdrian Maldonado 156224121865SAdrian Maldonado Note: the routine will create alternative orderings for the vertices and edges. Assume global network points are: 156324121865SAdrian Maldonado 156424121865SAdrian Maldonado points = [0 1 2 3 4 5 6] 156524121865SAdrian Maldonado 1566caf410d2SHong 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]). 156724121865SAdrian Maldonado 156824121865SAdrian Maldonado With this new ordering a local PetscSection, global PetscSection and PetscSF will be created specific to the subset. 156924121865SAdrian Maldonado 157024121865SAdrian Maldonado Level: intermediate 157124121865SAdrian Maldonado 157224121865SAdrian Maldonado @*/ 157324121865SAdrian Maldonado PetscErrorCode DMNetworkAssembleGraphStructures(DM dm) 157424121865SAdrian Maldonado { 157524121865SAdrian Maldonado PetscErrorCode ierr; 157624121865SAdrian Maldonado MPI_Comm comm; 1577f11a936eSBarry Smith PetscMPIInt size; 157824121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 157924121865SAdrian Maldonado 1580eab1376dSHong Zhang PetscFunctionBegin; 158124121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 1582ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 158324121865SAdrian Maldonado 158424121865SAdrian Maldonado /* Create maps for vertices and edges */ 158524121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 158624121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->eStart,network->eEnd,&network->edge.mapping);CHKERRQ(ierr); 158724121865SAdrian Maldonado 158824121865SAdrian Maldonado /* Create local sub-sections */ 158924121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->vStart,network->vEnd,&network->vertex.DofSection);CHKERRQ(ierr); 159024121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->eStart,network->eEnd,&network->edge.DofSection);CHKERRQ(ierr); 159124121865SAdrian Maldonado 15929852e123SBarry Smith if (size > 1) { 159324121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 159422bbedd7SHong Zhang 159524121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->vertex.DofSection, network->vertex.sf, PETSC_FALSE, PETSC_FALSE, &network->vertex.GlobalDofSection);CHKERRQ(ierr); 159624121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->edge.mapping, &network->edge.sf);CHKERRQ(ierr); 159724121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->edge.DofSection, network->edge.sf, PETSC_FALSE, PETSC_FALSE, &network->edge.GlobalDofSection);CHKERRQ(ierr); 159824121865SAdrian Maldonado } else { 159924121865SAdrian Maldonado /* create structures for vertex */ 160024121865SAdrian Maldonado ierr = PetscSectionClone(network->vertex.DofSection,&network->vertex.GlobalDofSection);CHKERRQ(ierr); 160124121865SAdrian Maldonado /* create structures for edge */ 160224121865SAdrian Maldonado ierr = PetscSectionClone(network->edge.DofSection,&network->edge.GlobalDofSection);CHKERRQ(ierr); 160324121865SAdrian Maldonado } 160424121865SAdrian Maldonado 160524121865SAdrian Maldonado /* Add viewers */ 160624121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->edge.GlobalDofSection,"Global edge dof section");CHKERRQ(ierr); 160724121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->vertex.GlobalDofSection,"Global vertex dof section");CHKERRQ(ierr); 160824121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->edge.GlobalDofSection, NULL, "-edge_global_section_view");CHKERRQ(ierr); 160924121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->vertex.GlobalDofSection, NULL, "-vertex_global_section_view");CHKERRQ(ierr); 161024121865SAdrian Maldonado PetscFunctionReturn(0); 161124121865SAdrian Maldonado } 16127b6afd5bSHong Zhang 1613f11a936eSBarry Smith /* 1614f11a936eSBarry Smith Add all subnetid for the input vertex v in this process to the btable 1615f11a936eSBarry Smith vertex_subnetid = supportingedge_subnetid 1616f11a936eSBarry Smith */ 1617f11a936eSBarry Smith PETSC_STATIC_INLINE PetscErrorCode SetSubnetIdLookupBT(DM dm,PetscInt v,PetscInt Nsubnet,PetscBT btable) 1618f11a936eSBarry Smith { 1619f11a936eSBarry Smith PetscErrorCode ierr; 1620f11a936eSBarry Smith PetscInt e,nedges,offset; 1621f11a936eSBarry Smith const PetscInt *edges; 1622f11a936eSBarry Smith DM_Network *newDMnetwork = (DM_Network*)dm->data; 1623f11a936eSBarry Smith DMNetworkComponentHeader header; 1624f11a936eSBarry Smith 1625f11a936eSBarry Smith PetscFunctionBegin; 1626f11a936eSBarry Smith ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 1627f11a936eSBarry Smith ierr = PetscBTMemzero(Nsubnet,btable);CHKERRQ(ierr); 1628f11a936eSBarry Smith for (e=0; e<nedges; e++) { 1629f11a936eSBarry Smith ierr = PetscSectionGetOffset(newDMnetwork->DataSection,edges[e],&offset);CHKERRQ(ierr); 1630f11a936eSBarry Smith header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset); 1631f11a936eSBarry Smith ierr = PetscBTSet(btable,header->subnetid);CHKERRQ(ierr); 1632f11a936eSBarry Smith } 1633f11a936eSBarry Smith PetscFunctionReturn(0); 1634f11a936eSBarry Smith } 1635f11a936eSBarry Smith 16365f2c45f1SShri Abhyankar /*@ 16372bf73ac6SHong Zhang DMNetworkDistribute - Distributes the network and moves associated component data 16385f2c45f1SShri Abhyankar 16395f2c45f1SShri Abhyankar Collective 16405f2c45f1SShri Abhyankar 1641*d8d19677SJose E. Roman Input Parameters: 1642d3464fd4SAdrian Maldonado + DM - the DMNetwork object 16432bf73ac6SHong Zhang - overlap - the overlap of partitions, 0 is the default 16445f2c45f1SShri Abhyankar 16455b3f975aSHong Zhang Options Database Key: 16465b3f975aSHong Zhang + -dmnetwork_view - Calls DMView() at the conclusion of DMSetUp() 16475b3f975aSHong Zhang - -dmnetwork_view_distributed - Calls DMView() at the conclusion of DMNetworkDistribute() 16485b3f975aSHong Zhang 16495f2c45f1SShri Abhyankar Notes: 16508b171c8eSHong Zhang Distributes the network with <overlap>-overlapping partitioning of the edges. 16515f2c45f1SShri Abhyankar 16525f2c45f1SShri Abhyankar Level: intermediate 16535f2c45f1SShri Abhyankar 16542bf73ac6SHong Zhang .seealso: DMNetworkCreate() 16555f2c45f1SShri Abhyankar @*/ 1656d3464fd4SAdrian Maldonado PetscErrorCode DMNetworkDistribute(DM *dm,PetscInt overlap) 16575f2c45f1SShri Abhyankar { 1658d3464fd4SAdrian Maldonado MPI_Comm comm; 16595f2c45f1SShri Abhyankar PetscErrorCode ierr; 1660d3464fd4SAdrian Maldonado PetscMPIInt size; 1661d3464fd4SAdrian Maldonado DM_Network *oldDMnetwork = (DM_Network*)((*dm)->data); 1662d3464fd4SAdrian Maldonado DM_Network *newDMnetwork; 1663caf410d2SHong Zhang PetscSF pointsf=NULL; 16645f2c45f1SShri Abhyankar DM newDM; 1665f11a936eSBarry Smith PetscInt j,e,v,offset,*subnetvtx,*subnetedge,Nsubnet,gidx,svtx_idx,nv; 16662bf73ac6SHong Zhang PetscInt to_net,from_net,*svto; 1667f11a936eSBarry Smith PetscBT btable; 166851ac5effSHong Zhang PetscPartitioner part; 1669b9c6e19dSShri Abhyankar DMNetworkComponentHeader header; 16705f2c45f1SShri Abhyankar 16715f2c45f1SShri Abhyankar PetscFunctionBegin; 1672d3464fd4SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)*dm,&comm);CHKERRQ(ierr); 1673ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 1674d3464fd4SAdrian Maldonado if (size == 1) PetscFunctionReturn(0); 1675d3464fd4SAdrian Maldonado 16765b3f975aSHong Zhang if (overlap) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"overlap %D != 0 is not supported yet",overlap); 16775b3f975aSHong Zhang 16782bf73ac6SHong 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. */ 1679d3464fd4SAdrian Maldonado ierr = DMNetworkCreate(PetscObjectComm((PetscObject)*dm),&newDM);CHKERRQ(ierr); 16805f2c45f1SShri Abhyankar newDMnetwork = (DM_Network*)newDM->data; 168154dfd506SHong Zhang newDMnetwork->max_comps_registered = oldDMnetwork->max_comps_registered; 168254dfd506SHong Zhang ierr = PetscMalloc1(newDMnetwork->max_comps_registered,&newDMnetwork->component);CHKERRQ(ierr); 168351ac5effSHong Zhang 168451ac5effSHong Zhang /* Enable runtime options for petscpartitioner */ 168551ac5effSHong Zhang ierr = DMPlexGetPartitioner(oldDMnetwork->plex,&part);CHKERRQ(ierr); 168651ac5effSHong Zhang ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); 168751ac5effSHong Zhang 16882bf73ac6SHong Zhang /* Distribute plex dm */ 168980cf41d5SMatthew G. Knepley ierr = DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr); 169051ac5effSHong Zhang 16915f2c45f1SShri Abhyankar /* Distribute dof section */ 16922bf73ac6SHong Zhang ierr = PetscSectionCreate(comm,&newDMnetwork->DofSection);CHKERRQ(ierr); 16935f2c45f1SShri Abhyankar ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr); 169451ac5effSHong Zhang 16955f2c45f1SShri Abhyankar /* Distribute data and associated section */ 16962bf73ac6SHong Zhang ierr = PetscSectionCreate(comm,&newDMnetwork->DataSection);CHKERRQ(ierr); 169731da1fc8SHong Zhang ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPIU_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr); 169824121865SAdrian Maldonado 16995f2c45f1SShri Abhyankar ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr); 17005f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr); 17015f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr); 17025f2c45f1SShri Abhyankar newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart; 17036fefedf4SHong Zhang newDMnetwork->nVertices = newDMnetwork->vEnd - newDMnetwork->vStart; 17046fefedf4SHong Zhang newDMnetwork->NVertices = oldDMnetwork->NVertices; 17055f2c45f1SShri Abhyankar newDMnetwork->NEdges = oldDMnetwork->NEdges; 1706f11a936eSBarry Smith newDMnetwork->svtable = oldDMnetwork->svtable; /* global table! */ 17072bf73ac6SHong Zhang oldDMnetwork->svtable = NULL; 170824121865SAdrian Maldonado 17091bb6d2a8SBarry Smith /* Set Dof section as the section for dm */ 171092fd8e1eSJed Brown ierr = DMSetLocalSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr); 1711e87a4003SBarry Smith ierr = DMGetGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr); 17125f2c45f1SShri Abhyankar 1713b9c6e19dSShri Abhyankar /* Setup subnetwork info in the newDM */ 17142bf73ac6SHong Zhang newDMnetwork->Nsubnet = oldDMnetwork->Nsubnet; 17152bf73ac6SHong Zhang newDMnetwork->Nsvtx = oldDMnetwork->Nsvtx; 17162bf73ac6SHong Zhang oldDMnetwork->Nsvtx = 0; 17172bf73ac6SHong Zhang newDMnetwork->svtx = oldDMnetwork->svtx; /* global vertices! */ 17182bf73ac6SHong Zhang oldDMnetwork->svtx = NULL; 17192bf73ac6SHong Zhang ierr = PetscCalloc1(newDMnetwork->Nsubnet,&newDMnetwork->subnet);CHKERRQ(ierr); 17202bf73ac6SHong Zhang 17212bf73ac6SHong Zhang /* Copy over the global number of vertices and edges in each subnetwork. 17222bf73ac6SHong Zhang Note: these are calculated in DMNetworkLayoutSetUp() 1723b9c6e19dSShri Abhyankar */ 1724f11a936eSBarry Smith Nsubnet = newDMnetwork->Nsubnet; 1725f11a936eSBarry Smith for (j = 0; j < Nsubnet; j++) { 1726b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nvtx = oldDMnetwork->subnet[j].Nvtx; 1727b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nedge = oldDMnetwork->subnet[j].Nedge; 1728b9c6e19dSShri Abhyankar } 1729b9c6e19dSShri Abhyankar 1730f11a936eSBarry Smith /* Count local nedges for subnetworks */ 1731b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++) { 1732b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 173354dfd506SHong Zhang header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset); 173454dfd506SHong Zhang /* Update pointers */ 173554dfd506SHong Zhang header->size = (PetscInt*)(header + 1); 173654dfd506SHong Zhang header->key = header->size + header->maxcomps; 173754dfd506SHong Zhang header->offset = header->key + header->maxcomps; 173854dfd506SHong Zhang header->nvar = header->offset + header->maxcomps; 173954dfd506SHong Zhang header->offsetvarrel = header->nvar + header->maxcomps; 174054dfd506SHong Zhang 1741b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nedge++; 1742b9c6e19dSShri Abhyankar } 1743b9c6e19dSShri Abhyankar 1744f11a936eSBarry Smith /* Count local nvtx for subnetworks */ 1745f11a936eSBarry Smith ierr = PetscBTCreate(Nsubnet,&btable);CHKERRQ(ierr); 1746b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++) { 1747b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1748b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 174954dfd506SHong Zhang /* Update pointers */ 175054dfd506SHong Zhang header->size = (PetscInt*)(header + 1); 175154dfd506SHong Zhang header->key = header->size + header->maxcomps; 175254dfd506SHong Zhang header->offset = header->key + header->maxcomps; 175354dfd506SHong Zhang header->nvar = header->offset + header->maxcomps; 175454dfd506SHong Zhang header->offsetvarrel = header->nvar + header->maxcomps; 175554dfd506SHong Zhang 17562bf73ac6SHong Zhang /* shared vertices: use gidx=header->index to check if v is a shared vertex */ 17572bf73ac6SHong Zhang gidx = header->index; 17582bf73ac6SHong Zhang ierr = PetscTableFind(newDMnetwork->svtable,gidx+1,&svtx_idx);CHKERRQ(ierr); 17592bf73ac6SHong Zhang svtx_idx--; 17602bf73ac6SHong Zhang 17612bf73ac6SHong Zhang if (svtx_idx < 0) { /* not a shared vertex */ 1762b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nvtx++; 17632bf73ac6SHong Zhang } else { /* a shared vertex belongs to more than one subnetworks, it is being counted by multiple subnets */ 1764f11a936eSBarry Smith ierr = SetSubnetIdLookupBT(newDM,v,Nsubnet,btable);CHKERRQ(ierr); 1765f11a936eSBarry Smith 17662bf73ac6SHong Zhang from_net = newDMnetwork->svtx[svtx_idx].sv[0]; 1767f11a936eSBarry Smith if (PetscBTLookup(btable,from_net)) newDMnetwork->subnet[from_net].nvtx++; /* sv is on from_net */ 1768f11a936eSBarry Smith 17692bf73ac6SHong Zhang for (j=1; j<newDMnetwork->svtx[svtx_idx].n; j++) { 17702bf73ac6SHong Zhang svto = newDMnetwork->svtx[svtx_idx].sv + 2*j; 17712bf73ac6SHong Zhang to_net = svto[0]; 1772f11a936eSBarry Smith if (PetscBTLookup(btable,to_net)) newDMnetwork->subnet[to_net].nvtx++; /* sv is on to_net */ 17732bf73ac6SHong Zhang } 17742bf73ac6SHong Zhang } 1775b9c6e19dSShri Abhyankar } 1776b9c6e19dSShri Abhyankar 17772bf73ac6SHong Zhang /* Get total local nvtx for subnetworks */ 17782bf73ac6SHong Zhang nv = 0; 1779f11a936eSBarry Smith for (j=0; j<Nsubnet; j++) nv += newDMnetwork->subnet[j].nvtx; 17802bf73ac6SHong Zhang nv += newDMnetwork->Nsvtx; 1781caf410d2SHong Zhang 17822bf73ac6SHong Zhang /* Now create the vertices and edge arrays for the subnetworks */ 1783f11a936eSBarry Smith ierr = PetscCalloc2(newDMnetwork->nEdges,&subnetedge,nv,&subnetvtx);CHKERRQ(ierr); /* Maps local vertex to local subnetwork's vertex */ 1784f11a936eSBarry Smith newDMnetwork->subnetedge = subnetedge; 17852bf73ac6SHong Zhang newDMnetwork->subnetvtx = subnetvtx; 1786f11a936eSBarry Smith for (j=0; j < newDMnetwork->Nsubnet; j++) { 1787f11a936eSBarry Smith newDMnetwork->subnet[j].edges = subnetedge; 1788f11a936eSBarry Smith subnetedge += newDMnetwork->subnet[j].nedge; 17892bf73ac6SHong Zhang 1790caf410d2SHong Zhang newDMnetwork->subnet[j].vertices = subnetvtx; 1791caf410d2SHong Zhang subnetvtx += newDMnetwork->subnet[j].nvtx; 1792caf410d2SHong Zhang 17932bf73ac6SHong 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. */ 1794b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].nvtx = newDMnetwork->subnet[j].nedge = 0; 1795b9c6e19dSShri Abhyankar } 17962bf73ac6SHong Zhang newDMnetwork->svertices = subnetvtx; 1797b9c6e19dSShri Abhyankar 17982bf73ac6SHong Zhang /* Set the edges and vertices in each subnetwork */ 1799b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++) { 1800b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 1801b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1802b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].edges[newDMnetwork->subnet[header->subnetid].nedge++] = e; 1803b9c6e19dSShri Abhyankar } 1804b9c6e19dSShri Abhyankar 18052bf73ac6SHong Zhang nv = 0; 1806b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++) { 1807b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1808b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 18092bf73ac6SHong Zhang 18102bf73ac6SHong Zhang /* coupling vertices: use gidx = header->index to check if v is a coupling vertex */ 18112bf73ac6SHong Zhang ierr = PetscTableFind(newDMnetwork->svtable,header->index+1,&svtx_idx);CHKERRQ(ierr); 18122bf73ac6SHong Zhang svtx_idx--; 18132bf73ac6SHong Zhang if (svtx_idx < 0) { 1814b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].vertices[newDMnetwork->subnet[header->subnetid].nvtx++] = v; 18152bf73ac6SHong Zhang } else { /* a shared vertex */ 18162bf73ac6SHong Zhang newDMnetwork->svertices[nv++] = v; 18172bf73ac6SHong Zhang 1818f11a936eSBarry Smith /* add all subnetid for this shared vertex in this process to btable */ 1819f11a936eSBarry Smith ierr = SetSubnetIdLookupBT(newDM,v,Nsubnet,btable);CHKERRQ(ierr); 1820f11a936eSBarry Smith 18212bf73ac6SHong Zhang from_net = newDMnetwork->svtx[svtx_idx].sv[0]; 1822f11a936eSBarry Smith if (PetscBTLookup(btable,from_net)) 18232bf73ac6SHong Zhang newDMnetwork->subnet[from_net].vertices[newDMnetwork->subnet[from_net].nvtx++] = v; 18242bf73ac6SHong Zhang 18252bf73ac6SHong Zhang for (j=1; j<newDMnetwork->svtx[svtx_idx].n; j++) { 18262bf73ac6SHong Zhang svto = newDMnetwork->svtx[svtx_idx].sv + 2*j; 18272bf73ac6SHong Zhang to_net = svto[0]; 1828f11a936eSBarry Smith if (PetscBTLookup(btable,to_net)) 18292bf73ac6SHong Zhang newDMnetwork->subnet[to_net].vertices[newDMnetwork->subnet[to_net].nvtx++] = v; 1830b9c6e19dSShri Abhyankar } 18312bf73ac6SHong Zhang } 18322bf73ac6SHong Zhang } 18332bf73ac6SHong Zhang newDMnetwork->nsvtx = nv; /* num of local shared vertices */ 1834b9c6e19dSShri Abhyankar 1835caf410d2SHong Zhang newDM->setupcalled = (*dm)->setupcalled; 183622bbedd7SHong Zhang newDMnetwork->distributecalled = PETSC_TRUE; 1837caf410d2SHong Zhang 18382bf73ac6SHong Zhang /* Free spaces */ 183924121865SAdrian Maldonado ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr); 1840d3464fd4SAdrian Maldonado ierr = DMDestroy(dm);CHKERRQ(ierr); 1841f11a936eSBarry Smith ierr = PetscBTDestroy(&btable);CHKERRQ(ierr); 18422bf73ac6SHong Zhang 18435b3f975aSHong Zhang /* View distributed dmnetwork */ 18445b3f975aSHong Zhang ierr = DMViewFromOptions(newDM,NULL,"-dmnetwork_view_distributed");CHKERRQ(ierr); 18455b3f975aSHong Zhang 1846d3464fd4SAdrian Maldonado *dm = newDM; 18475f2c45f1SShri Abhyankar PetscFunctionReturn(0); 18485f2c45f1SShri Abhyankar } 18495f2c45f1SShri Abhyankar 185024121865SAdrian Maldonado /*@C 18512bf73ac6SHong Zhang PetscSFGetSubSF - Returns an SF for a specific subset of points. Leaves are re-numbered to reflect the new ordering 18522bf73ac6SHong Zhang 18532bf73ac6SHong Zhang Collective 185424121865SAdrian Maldonado 185524121865SAdrian Maldonado Input Parameters: 18569dddd249SSatish Balay + mainSF - the original SF structure 185724121865SAdrian Maldonado - map - a ISLocalToGlobal mapping that contains the subset of points 185824121865SAdrian Maldonado 185924121865SAdrian Maldonado Output Parameters: 18609dddd249SSatish Balay . subSF - a subset of the mainSF for the desired subset. 1861ee300463SSatish Balay 1862ee300463SSatish Balay Level: intermediate 18637d928bffSSatish Balay @*/ 18649dddd249SSatish Balay PetscErrorCode PetscSFGetSubSF(PetscSF mainsf,ISLocalToGlobalMapping map,PetscSF *subSF) 18652bf73ac6SHong Zhang { 186624121865SAdrian Maldonado PetscErrorCode ierr; 186724121865SAdrian Maldonado PetscInt nroots, nleaves, *ilocal_sub; 186824121865SAdrian Maldonado PetscInt i, *ilocal_map, nroots_sub, nleaves_sub = 0; 186924121865SAdrian Maldonado PetscInt *local_points, *remote_points; 187024121865SAdrian Maldonado PetscSFNode *iremote_sub; 187124121865SAdrian Maldonado const PetscInt *ilocal; 187224121865SAdrian Maldonado const PetscSFNode *iremote; 187324121865SAdrian Maldonado 187424121865SAdrian Maldonado PetscFunctionBegin; 18759dddd249SSatish Balay ierr = PetscSFGetGraph(mainsf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr); 187624121865SAdrian Maldonado 187724121865SAdrian Maldonado /* Look for leaves that pertain to the subset of points. Get the local ordering */ 187824121865SAdrian Maldonado ierr = PetscMalloc1(nleaves,&ilocal_map);CHKERRQ(ierr); 187924121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nleaves,ilocal,NULL,ilocal_map);CHKERRQ(ierr); 188024121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 188124121865SAdrian Maldonado if (ilocal_map[i] != -1) nleaves_sub += 1; 188224121865SAdrian Maldonado } 188324121865SAdrian Maldonado /* Re-number ilocal with subset numbering. Need information from roots */ 188424121865SAdrian Maldonado ierr = PetscMalloc2(nroots,&local_points,nroots,&remote_points);CHKERRQ(ierr); 188524121865SAdrian Maldonado for (i = 0; i < nroots; i++) local_points[i] = i; 188624121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nroots,local_points,NULL,local_points);CHKERRQ(ierr); 1887ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(mainsf, MPIU_INT, local_points, remote_points,MPI_REPLACE);CHKERRQ(ierr); 1888ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(mainsf, MPIU_INT, local_points, remote_points,MPI_REPLACE);CHKERRQ(ierr); 188924121865SAdrian Maldonado /* Fill up graph using local (that is, local to the subset) numbering. */ 18904b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&ilocal_sub);CHKERRQ(ierr); 18914b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&iremote_sub);CHKERRQ(ierr); 189224121865SAdrian Maldonado nleaves_sub = 0; 189324121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 189424121865SAdrian Maldonado if (ilocal_map[i] != -1) { 189524121865SAdrian Maldonado ilocal_sub[nleaves_sub] = ilocal_map[i]; 18964b70a8deSAdrian Maldonado iremote_sub[nleaves_sub].rank = iremote[i].rank; 189724121865SAdrian Maldonado iremote_sub[nleaves_sub].index = remote_points[ilocal[i]]; 189824121865SAdrian Maldonado nleaves_sub += 1; 189924121865SAdrian Maldonado } 190024121865SAdrian Maldonado } 190124121865SAdrian Maldonado ierr = PetscFree2(local_points,remote_points);CHKERRQ(ierr); 190224121865SAdrian Maldonado ierr = ISLocalToGlobalMappingGetSize(map,&nroots_sub);CHKERRQ(ierr); 190324121865SAdrian Maldonado 190424121865SAdrian Maldonado /* Create new subSF */ 190524121865SAdrian Maldonado ierr = PetscSFCreate(PETSC_COMM_WORLD,subSF);CHKERRQ(ierr); 190624121865SAdrian Maldonado ierr = PetscSFSetFromOptions(*subSF);CHKERRQ(ierr); 19074b70a8deSAdrian Maldonado ierr = PetscSFSetGraph(*subSF,nroots_sub,nleaves_sub,ilocal_sub,PETSC_OWN_POINTER,iremote_sub,PETSC_COPY_VALUES);CHKERRQ(ierr); 190824121865SAdrian Maldonado ierr = PetscFree(ilocal_map);CHKERRQ(ierr); 19094b70a8deSAdrian Maldonado ierr = PetscFree(iremote_sub);CHKERRQ(ierr); 191024121865SAdrian Maldonado PetscFunctionReturn(0); 191124121865SAdrian Maldonado } 191224121865SAdrian Maldonado 19135f2c45f1SShri Abhyankar /*@C 19145f2c45f1SShri Abhyankar DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point 19155f2c45f1SShri Abhyankar 19165f2c45f1SShri Abhyankar Not Collective 19175f2c45f1SShri Abhyankar 19185f2c45f1SShri Abhyankar Input Parameters: 19192bf73ac6SHong Zhang + dm - the DMNetwork object 19205f2c45f1SShri Abhyankar - p - the vertex point 19215f2c45f1SShri Abhyankar 1922fd292e60Sprj- Output Parameters: 19235f2c45f1SShri Abhyankar + nedges - number of edges connected to this vertex point 19242bf73ac6SHong Zhang - edges - list of edge points 19255f2c45f1SShri Abhyankar 192697bb938eSShri Abhyankar Level: beginner 19275f2c45f1SShri Abhyankar 19285f2c45f1SShri Abhyankar Fortran Notes: 19295f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 19305f2c45f1SShri Abhyankar include petsc.h90 in your code. 19315f2c45f1SShri Abhyankar 19322bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkGetConnectedVertices() 19335f2c45f1SShri Abhyankar @*/ 19345f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[]) 19355f2c45f1SShri Abhyankar { 19365f2c45f1SShri Abhyankar PetscErrorCode ierr; 19375f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 19385f2c45f1SShri Abhyankar 19395f2c45f1SShri Abhyankar PetscFunctionBegin; 19405f2c45f1SShri Abhyankar ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr); 1941a9b4a83eSHong Zhang if (edges) {ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr);} 19425f2c45f1SShri Abhyankar PetscFunctionReturn(0); 19435f2c45f1SShri Abhyankar } 19445f2c45f1SShri Abhyankar 19455f2c45f1SShri Abhyankar /*@C 1946d842c372SHong Zhang DMNetworkGetConnectedVertices - Return the connected vertices for this edge point 19475f2c45f1SShri Abhyankar 19485f2c45f1SShri Abhyankar Not Collective 19495f2c45f1SShri Abhyankar 19505f2c45f1SShri Abhyankar Input Parameters: 19512bf73ac6SHong Zhang + dm - the DMNetwork object 19525f2c45f1SShri Abhyankar - p - the edge point 19535f2c45f1SShri Abhyankar 1954fd292e60Sprj- Output Parameters: 19555f2c45f1SShri Abhyankar . vertices - vertices connected to this edge 19565f2c45f1SShri Abhyankar 195797bb938eSShri Abhyankar Level: beginner 19585f2c45f1SShri Abhyankar 19595f2c45f1SShri Abhyankar Fortran Notes: 19605f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 19615f2c45f1SShri Abhyankar include petsc.h90 in your code. 19625f2c45f1SShri Abhyankar 19632bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkGetSupportingEdges() 19645f2c45f1SShri Abhyankar @*/ 1965d842c372SHong Zhang PetscErrorCode DMNetworkGetConnectedVertices(DM dm,PetscInt edge,const PetscInt *vertices[]) 19665f2c45f1SShri Abhyankar { 19675f2c45f1SShri Abhyankar PetscErrorCode ierr; 19685f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 19695f2c45f1SShri Abhyankar 19705f2c45f1SShri Abhyankar PetscFunctionBegin; 19715f2c45f1SShri Abhyankar ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr); 19725f2c45f1SShri Abhyankar PetscFunctionReturn(0); 19735f2c45f1SShri Abhyankar } 19745f2c45f1SShri Abhyankar 19755f2c45f1SShri Abhyankar /*@ 19762bf73ac6SHong Zhang DMNetworkIsSharedVertex - Returns TRUE if the vertex is shared by subnetworks 19772bf73ac6SHong Zhang 19782bf73ac6SHong Zhang Not Collective 19792bf73ac6SHong Zhang 19802bf73ac6SHong Zhang Input Parameters: 19812bf73ac6SHong Zhang + dm - the DMNetwork object 19822bf73ac6SHong Zhang - p - the vertex point 19832bf73ac6SHong Zhang 19842bf73ac6SHong Zhang Output Parameter: 19852bf73ac6SHong Zhang . flag - TRUE if the vertex is shared by subnetworks 19862bf73ac6SHong Zhang 19872bf73ac6SHong Zhang Level: beginner 19882bf73ac6SHong Zhang 19892bf73ac6SHong Zhang .seealso: DMNetworkAddSharedVertices(), DMNetworkIsGhostVertex() 19902bf73ac6SHong Zhang @*/ 19912bf73ac6SHong Zhang PetscErrorCode DMNetworkIsSharedVertex(DM dm,PetscInt p,PetscBool *flag) 19922bf73ac6SHong Zhang { 19932bf73ac6SHong Zhang PetscErrorCode ierr; 19942bf73ac6SHong Zhang PetscInt i; 19952bf73ac6SHong Zhang 19962bf73ac6SHong Zhang PetscFunctionBegin; 19972bf73ac6SHong Zhang *flag = PETSC_FALSE; 19982bf73ac6SHong Zhang 19992bf73ac6SHong Zhang if (dm->setupcalled) { /* DMNetworkGetGlobalVertexIndex() requires DMSetUp() be called */ 20002bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 20012bf73ac6SHong Zhang PetscInt gidx; 20022bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,p,&gidx);CHKERRQ(ierr); 20032bf73ac6SHong Zhang ierr = PetscTableFind(network->svtable,gidx+1,&i);CHKERRQ(ierr); 20042bf73ac6SHong Zhang if (i) *flag = PETSC_TRUE; 20052bf73ac6SHong Zhang } else { /* would be removed? */ 20062bf73ac6SHong Zhang PetscInt nv; 20072bf73ac6SHong Zhang const PetscInt *vtx; 20082bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&nv,&vtx);CHKERRQ(ierr); 20092bf73ac6SHong Zhang for (i=0; i<nv; i++) { 20102bf73ac6SHong Zhang if (p == vtx[i]) { 20112bf73ac6SHong Zhang *flag = PETSC_TRUE; 20122bf73ac6SHong Zhang break; 20132bf73ac6SHong Zhang } 20142bf73ac6SHong Zhang } 20152bf73ac6SHong Zhang } 20162bf73ac6SHong Zhang PetscFunctionReturn(0); 20172bf73ac6SHong Zhang } 20182bf73ac6SHong Zhang 20192bf73ac6SHong Zhang /*@ 20205f2c45f1SShri Abhyankar DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex 20215f2c45f1SShri Abhyankar 20225f2c45f1SShri Abhyankar Not Collective 20235f2c45f1SShri Abhyankar 20245f2c45f1SShri Abhyankar Input Parameters: 20252bf73ac6SHong Zhang + dm - the DMNetwork object 2026a2b725a8SWilliam Gropp - p - the vertex point 20275f2c45f1SShri Abhyankar 20285f2c45f1SShri Abhyankar Output Parameter: 20295f2c45f1SShri Abhyankar . isghost - TRUE if the vertex is a ghost point 20305f2c45f1SShri Abhyankar 203197bb938eSShri Abhyankar Level: beginner 20325f2c45f1SShri Abhyankar 20332bf73ac6SHong Zhang .seealso: DMNetworkGetConnectedVertices(), DMNetworkGetVertexRange(), DMNetworkIsSharedVertex() 20345f2c45f1SShri Abhyankar @*/ 20355f2c45f1SShri Abhyankar PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost) 20365f2c45f1SShri Abhyankar { 20375f2c45f1SShri Abhyankar PetscErrorCode ierr; 20385f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 20395f2c45f1SShri Abhyankar PetscInt offsetg; 20405f2c45f1SShri Abhyankar PetscSection sectiong; 20415f2c45f1SShri Abhyankar 20425f2c45f1SShri Abhyankar PetscFunctionBegin; 20435f2c45f1SShri Abhyankar *isghost = PETSC_FALSE; 2044e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§iong);CHKERRQ(ierr); 20455f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr); 20465f2c45f1SShri Abhyankar if (offsetg < 0) *isghost = PETSC_TRUE; 20475f2c45f1SShri Abhyankar PetscFunctionReturn(0); 20485f2c45f1SShri Abhyankar } 20495f2c45f1SShri Abhyankar 20505f2c45f1SShri Abhyankar PetscErrorCode DMSetUp_Network(DM dm) 20515f2c45f1SShri Abhyankar { 20525f2c45f1SShri Abhyankar PetscErrorCode ierr; 20535f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 20545f2c45f1SShri Abhyankar 20555f2c45f1SShri Abhyankar PetscFunctionBegin; 20565f2c45f1SShri Abhyankar ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr); 20575f2c45f1SShri Abhyankar ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr); 20585f2c45f1SShri Abhyankar 205992fd8e1eSJed Brown ierr = DMSetLocalSection(network->plex,network->DofSection);CHKERRQ(ierr); 2060e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr); 20619e1d080bSHong Zhang 20629e1d080bSHong Zhang dm->setupcalled = PETSC_TRUE; 20635b3f975aSHong Zhang 20645b3f975aSHong Zhang /* View dmnetwork */ 20655b3f975aSHong Zhang ierr = DMViewFromOptions(dm,NULL,"-dmnetwork_view");CHKERRQ(ierr); 20665f2c45f1SShri Abhyankar PetscFunctionReturn(0); 20675f2c45f1SShri Abhyankar } 20685f2c45f1SShri Abhyankar 20691ad426b7SHong Zhang /*@ 207017df6e9eSHong Zhang DMNetworkHasJacobian - Sets global flag for using user's sub Jacobian matrices 20711ad426b7SHong Zhang -- replaced by DMNetworkSetOption(network,userjacobian,PETSC_TURE)? 20721ad426b7SHong Zhang 20731ad426b7SHong Zhang Collective 20741ad426b7SHong Zhang 20751ad426b7SHong Zhang Input Parameters: 20762bf73ac6SHong Zhang + dm - the DMNetwork object 207783b2e829SHong Zhang . eflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for edges 207883b2e829SHong Zhang - vflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for vertices 20791ad426b7SHong Zhang 20801ad426b7SHong Zhang Level: intermediate 20811ad426b7SHong Zhang 20821ad426b7SHong Zhang @*/ 208383b2e829SHong Zhang PetscErrorCode DMNetworkHasJacobian(DM dm,PetscBool eflg,PetscBool vflg) 20841ad426b7SHong Zhang { 20851ad426b7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 20868675203cSHong Zhang PetscErrorCode ierr; 208766b4e0ffSHong Zhang PetscInt nVertices = network->nVertices; 20881ad426b7SHong Zhang 20891ad426b7SHong Zhang PetscFunctionBegin; 209083b2e829SHong Zhang network->userEdgeJacobian = eflg; 209183b2e829SHong Zhang network->userVertexJacobian = vflg; 20928675203cSHong Zhang 20938675203cSHong Zhang if (eflg && !network->Je) { 20948675203cSHong Zhang ierr = PetscCalloc1(3*network->nEdges,&network->Je);CHKERRQ(ierr); 20958675203cSHong Zhang } 20968675203cSHong Zhang 209766b4e0ffSHong Zhang if (vflg && !network->Jv && nVertices) { 20988675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 209966b4e0ffSHong Zhang PetscInt nedges_total; 21008675203cSHong Zhang const PetscInt *edges; 21018675203cSHong Zhang 21028675203cSHong Zhang /* count nvertex_total */ 21038675203cSHong Zhang nedges_total = 0; 21048675203cSHong Zhang ierr = PetscMalloc1(nVertices+1,&vptr);CHKERRQ(ierr); 21058675203cSHong Zhang 21068675203cSHong Zhang vptr[0] = 0; 21078675203cSHong Zhang for (i=0; i<nVertices; i++) { 21088675203cSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,i+vStart,&nedges,&edges);CHKERRQ(ierr); 21098675203cSHong Zhang nedges_total += nedges; 21108675203cSHong Zhang vptr[i+1] = vptr[i] + 2*nedges + 1; 21118675203cSHong Zhang } 21128675203cSHong Zhang 21138675203cSHong Zhang ierr = PetscCalloc1(2*nedges_total+nVertices,&network->Jv);CHKERRQ(ierr); 21148675203cSHong Zhang network->Jvptr = vptr; 21158675203cSHong Zhang } 21161ad426b7SHong Zhang PetscFunctionReturn(0); 21171ad426b7SHong Zhang } 21181ad426b7SHong Zhang 21191ad426b7SHong Zhang /*@ 212083b2e829SHong Zhang DMNetworkEdgeSetMatrix - Sets user-provided Jacobian matrices for this edge to the network 212183b2e829SHong Zhang 212283b2e829SHong Zhang Not Collective 212383b2e829SHong Zhang 212483b2e829SHong Zhang Input Parameters: 21252bf73ac6SHong Zhang + dm - the DMNetwork object 212683b2e829SHong Zhang . p - the edge point 21273e97b6e8SHong Zhang - J - array (size = 3) of Jacobian submatrices for this edge point: 21283e97b6e8SHong Zhang J[0]: this edge 2129d842c372SHong Zhang J[1] and J[2]: connected vertices, obtained by calling DMNetworkGetConnectedVertices() 213083b2e829SHong Zhang 213197bb938eSShri Abhyankar Level: advanced 213283b2e829SHong Zhang 21332bf73ac6SHong Zhang .seealso: DMNetworkVertexSetMatrix() 213483b2e829SHong Zhang @*/ 213583b2e829SHong Zhang PetscErrorCode DMNetworkEdgeSetMatrix(DM dm,PetscInt p,Mat J[]) 213683b2e829SHong Zhang { 213783b2e829SHong Zhang DM_Network *network=(DM_Network*)dm->data; 213883b2e829SHong Zhang 213983b2e829SHong Zhang PetscFunctionBegin; 21408675203cSHong Zhang if (!network->Je) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkEdgeSetMatrix"); 21418675203cSHong Zhang 21428675203cSHong Zhang if (J) { 2143883e35e8SHong Zhang network->Je[3*p] = J[0]; 2144883e35e8SHong Zhang network->Je[3*p+1] = J[1]; 2145883e35e8SHong Zhang network->Je[3*p+2] = J[2]; 21468675203cSHong Zhang } 214783b2e829SHong Zhang PetscFunctionReturn(0); 214883b2e829SHong Zhang } 214983b2e829SHong Zhang 215083b2e829SHong Zhang /*@ 215176ddfea5SHong Zhang DMNetworkVertexSetMatrix - Sets user-provided Jacobian matrix for this vertex to the network 21521ad426b7SHong Zhang 21531ad426b7SHong Zhang Not Collective 21541ad426b7SHong Zhang 21551ad426b7SHong Zhang Input Parameters: 21561ad426b7SHong Zhang + dm - The DMNetwork object 21571ad426b7SHong Zhang . p - the vertex point 21583e97b6e8SHong Zhang - J - array of Jacobian (size = 2*(num of supporting edges) + 1) submatrices for this vertex point: 21593e97b6e8SHong Zhang J[0]: this vertex 21603e97b6e8SHong Zhang J[1+2*i]: i-th supporting edge 21613e97b6e8SHong Zhang J[1+2*i+1]: i-th connected vertex 21621ad426b7SHong Zhang 216397bb938eSShri Abhyankar Level: advanced 21641ad426b7SHong Zhang 21652bf73ac6SHong Zhang .seealso: DMNetworkEdgeSetMatrix() 21661ad426b7SHong Zhang @*/ 2167883e35e8SHong Zhang PetscErrorCode DMNetworkVertexSetMatrix(DM dm,PetscInt p,Mat J[]) 21685f2c45f1SShri Abhyankar { 21695f2c45f1SShri Abhyankar PetscErrorCode ierr; 21705f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 21718675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 2172883e35e8SHong Zhang const PetscInt *edges; 21735f2c45f1SShri Abhyankar 21745f2c45f1SShri Abhyankar PetscFunctionBegin; 21758675203cSHong Zhang if (!network->Jv) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkVertexSetMatrix"); 2176883e35e8SHong Zhang 21778675203cSHong Zhang if (J) { 2178883e35e8SHong Zhang vptr = network->Jvptr; 21793e97b6e8SHong Zhang network->Jv[vptr[p-vStart]] = J[0]; /* Set Jacobian for this vertex */ 21803e97b6e8SHong Zhang 21813e97b6e8SHong Zhang /* Set Jacobian for each supporting edge and connected vertex */ 2182883e35e8SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,p,&nedges,&edges);CHKERRQ(ierr); 2183883e35e8SHong Zhang for (i=1; i<=2*nedges; i++) network->Jv[vptr[p-vStart]+i] = J[i]; 21848675203cSHong Zhang } 2185883e35e8SHong Zhang PetscFunctionReturn(0); 2186883e35e8SHong Zhang } 2187883e35e8SHong Zhang 2188e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 21895cf7da58SHong Zhang { 21905cf7da58SHong Zhang PetscErrorCode ierr; 21915cf7da58SHong Zhang PetscInt j; 21925cf7da58SHong Zhang PetscScalar val=(PetscScalar)ncols; 21935cf7da58SHong Zhang 21945cf7da58SHong Zhang PetscFunctionBegin; 21955cf7da58SHong Zhang if (!ghost) { 21965cf7da58SHong Zhang for (j=0; j<nrows; j++) { 21975cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 21985cf7da58SHong Zhang } 21995cf7da58SHong Zhang } else { 22005cf7da58SHong Zhang for (j=0; j<nrows; j++) { 22015cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 22025cf7da58SHong Zhang } 22035cf7da58SHong Zhang } 22045cf7da58SHong Zhang PetscFunctionReturn(0); 22055cf7da58SHong Zhang } 22065cf7da58SHong Zhang 2207e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 22085cf7da58SHong Zhang { 22095cf7da58SHong Zhang PetscErrorCode ierr; 22105cf7da58SHong Zhang PetscInt j,ncols_u; 22115cf7da58SHong Zhang PetscScalar val; 22125cf7da58SHong Zhang 22135cf7da58SHong Zhang PetscFunctionBegin; 22145cf7da58SHong Zhang if (!ghost) { 22155cf7da58SHong Zhang for (j=0; j<nrows; j++) { 22165cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 22175cf7da58SHong Zhang val = (PetscScalar)ncols_u; 22185cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 22195cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 22205cf7da58SHong Zhang } 22215cf7da58SHong Zhang } else { 22225cf7da58SHong Zhang for (j=0; j<nrows; j++) { 22235cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 22245cf7da58SHong Zhang val = (PetscScalar)ncols_u; 22255cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 22265cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 22275cf7da58SHong Zhang } 22285cf7da58SHong Zhang } 22295cf7da58SHong Zhang PetscFunctionReturn(0); 22305cf7da58SHong Zhang } 22315cf7da58SHong Zhang 2232e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 22335cf7da58SHong Zhang { 22345cf7da58SHong Zhang PetscErrorCode ierr; 22355cf7da58SHong Zhang 22365cf7da58SHong Zhang PetscFunctionBegin; 22375cf7da58SHong Zhang if (Ju) { 22385cf7da58SHong Zhang ierr = MatSetPreallocationUserblock_private(Ju,nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 22395cf7da58SHong Zhang } else { 22405cf7da58SHong Zhang ierr = MatSetPreallocationDenseblock_private(nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 22415cf7da58SHong Zhang } 22425cf7da58SHong Zhang PetscFunctionReturn(0); 22435cf7da58SHong Zhang } 22445cf7da58SHong Zhang 2245e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 2246883e35e8SHong Zhang { 2247883e35e8SHong Zhang PetscErrorCode ierr; 2248883e35e8SHong Zhang PetscInt j,*cols; 2249883e35e8SHong Zhang PetscScalar *zeros; 2250883e35e8SHong Zhang 2251883e35e8SHong Zhang PetscFunctionBegin; 2252883e35e8SHong Zhang ierr = PetscCalloc2(ncols,&cols,nrows*ncols,&zeros);CHKERRQ(ierr); 2253883e35e8SHong Zhang for (j=0; j<ncols; j++) cols[j] = j+ cstart; 2254883e35e8SHong Zhang ierr = MatSetValues(*J,nrows,rows,ncols,cols,zeros,INSERT_VALUES);CHKERRQ(ierr); 2255883e35e8SHong Zhang ierr = PetscFree2(cols,zeros);CHKERRQ(ierr); 22561ad426b7SHong Zhang PetscFunctionReturn(0); 22571ad426b7SHong Zhang } 2258a4e85ca8SHong Zhang 2259e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 22603e97b6e8SHong Zhang { 22613e97b6e8SHong Zhang PetscErrorCode ierr; 22623e97b6e8SHong Zhang PetscInt j,M,N,row,col,ncols_u; 22633e97b6e8SHong Zhang const PetscInt *cols; 22643e97b6e8SHong Zhang PetscScalar zero=0.0; 22653e97b6e8SHong Zhang 22663e97b6e8SHong Zhang PetscFunctionBegin; 22673e97b6e8SHong Zhang ierr = MatGetSize(Ju,&M,&N);CHKERRQ(ierr); 22683e97b6e8SHong 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); 22693e97b6e8SHong Zhang 22703e97b6e8SHong Zhang for (row=0; row<nrows; row++) { 22713e97b6e8SHong Zhang ierr = MatGetRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 22723e97b6e8SHong Zhang for (j=0; j<ncols_u; j++) { 22733e97b6e8SHong Zhang col = cols[j] + cstart; 22743e97b6e8SHong Zhang ierr = MatSetValues(*J,1,&rows[row],1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr); 22753e97b6e8SHong Zhang } 22763e97b6e8SHong Zhang ierr = MatRestoreRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 22773e97b6e8SHong Zhang } 22783e97b6e8SHong Zhang PetscFunctionReturn(0); 22793e97b6e8SHong Zhang } 22801ad426b7SHong Zhang 2281e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 2282a4e85ca8SHong Zhang { 2283a4e85ca8SHong Zhang PetscErrorCode ierr; 2284f4431b8cSHong Zhang 2285a4e85ca8SHong Zhang PetscFunctionBegin; 2286a4e85ca8SHong Zhang if (Ju) { 2287a4e85ca8SHong Zhang ierr = MatSetUserblock_private(Ju,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 2288a4e85ca8SHong Zhang } else { 2289a4e85ca8SHong Zhang ierr = MatSetDenseblock_private(nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 2290a4e85ca8SHong Zhang } 2291a4e85ca8SHong Zhang PetscFunctionReturn(0); 2292a4e85ca8SHong Zhang } 2293a4e85ca8SHong Zhang 229424121865SAdrian 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. 229524121865SAdrian Maldonado */ 229624121865SAdrian Maldonado PetscErrorCode CreateSubGlobalToLocalMapping_private(PetscSection globalsec, PetscSection localsec, ISLocalToGlobalMapping *ltog) 229724121865SAdrian Maldonado { 229824121865SAdrian Maldonado PetscErrorCode ierr; 229924121865SAdrian Maldonado PetscInt i,size,dof; 230024121865SAdrian Maldonado PetscInt *glob2loc; 230124121865SAdrian Maldonado 230224121865SAdrian Maldonado PetscFunctionBegin; 230324121865SAdrian Maldonado ierr = PetscSectionGetStorageSize(localsec,&size);CHKERRQ(ierr); 230424121865SAdrian Maldonado ierr = PetscMalloc1(size,&glob2loc);CHKERRQ(ierr); 230524121865SAdrian Maldonado 230624121865SAdrian Maldonado for (i = 0; i < size; i++) { 230724121865SAdrian Maldonado ierr = PetscSectionGetOffset(globalsec,i,&dof);CHKERRQ(ierr); 230824121865SAdrian Maldonado dof = (dof >= 0) ? dof : -(dof + 1); 230924121865SAdrian Maldonado glob2loc[i] = dof; 231024121865SAdrian Maldonado } 231124121865SAdrian Maldonado 231224121865SAdrian Maldonado ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,size,glob2loc,PETSC_OWN_POINTER,ltog);CHKERRQ(ierr); 231324121865SAdrian Maldonado #if 0 231424121865SAdrian Maldonado ierr = PetscIntView(size,glob2loc,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 231524121865SAdrian Maldonado #endif 231624121865SAdrian Maldonado PetscFunctionReturn(0); 231724121865SAdrian Maldonado } 231824121865SAdrian Maldonado 231901ad2aeeSHong Zhang #include <petsc/private/matimpl.h> 23209e1d080bSHong Zhang 23219e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network_Nest(DM dm,Mat *J) 23221ad426b7SHong Zhang { 23231ad426b7SHong Zhang PetscErrorCode ierr; 23241ad426b7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 232524121865SAdrian Maldonado PetscInt eDof,vDof; 232624121865SAdrian Maldonado Mat j11,j12,j21,j22,bA[2][2]; 23279e1d080bSHong Zhang MPI_Comm comm; 232824121865SAdrian Maldonado ISLocalToGlobalMapping eISMap,vISMap; 232924121865SAdrian Maldonado 23309e1d080bSHong Zhang PetscFunctionBegin; 233124121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 233224121865SAdrian Maldonado 233324121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->edge.GlobalDofSection,&eDof);CHKERRQ(ierr); 233424121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->vertex.GlobalDofSection,&vDof);CHKERRQ(ierr); 233524121865SAdrian Maldonado 233601ad2aeeSHong Zhang ierr = MatCreate(comm, &j11);CHKERRQ(ierr); 233724121865SAdrian Maldonado ierr = MatSetSizes(j11, eDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 233824121865SAdrian Maldonado ierr = MatSetType(j11, MATMPIAIJ);CHKERRQ(ierr); 233924121865SAdrian Maldonado 234001ad2aeeSHong Zhang ierr = MatCreate(comm, &j12);CHKERRQ(ierr); 234124121865SAdrian Maldonado ierr = MatSetSizes(j12, eDof, vDof, PETSC_DETERMINE ,PETSC_DETERMINE);CHKERRQ(ierr); 234224121865SAdrian Maldonado ierr = MatSetType(j12, MATMPIAIJ);CHKERRQ(ierr); 234324121865SAdrian Maldonado 234401ad2aeeSHong Zhang ierr = MatCreate(comm, &j21);CHKERRQ(ierr); 234524121865SAdrian Maldonado ierr = MatSetSizes(j21, vDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 234624121865SAdrian Maldonado ierr = MatSetType(j21, MATMPIAIJ);CHKERRQ(ierr); 234724121865SAdrian Maldonado 234801ad2aeeSHong Zhang ierr = MatCreate(comm, &j22);CHKERRQ(ierr); 234924121865SAdrian Maldonado ierr = MatSetSizes(j22, vDof, vDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 235024121865SAdrian Maldonado ierr = MatSetType(j22, MATMPIAIJ);CHKERRQ(ierr); 235124121865SAdrian Maldonado 23523f6a6bdaSHong Zhang bA[0][0] = j11; 23533f6a6bdaSHong Zhang bA[0][1] = j12; 23543f6a6bdaSHong Zhang bA[1][0] = j21; 23553f6a6bdaSHong Zhang bA[1][1] = j22; 235624121865SAdrian Maldonado 235724121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->edge.GlobalDofSection,network->edge.DofSection,&eISMap);CHKERRQ(ierr); 235824121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->vertex.GlobalDofSection,network->vertex.DofSection,&vISMap);CHKERRQ(ierr); 235924121865SAdrian Maldonado 236024121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j11,eISMap,eISMap);CHKERRQ(ierr); 236124121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j12,eISMap,vISMap);CHKERRQ(ierr); 236224121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j21,vISMap,eISMap);CHKERRQ(ierr); 236324121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j22,vISMap,vISMap);CHKERRQ(ierr); 236424121865SAdrian Maldonado 236524121865SAdrian Maldonado ierr = MatSetUp(j11);CHKERRQ(ierr); 236624121865SAdrian Maldonado ierr = MatSetUp(j12);CHKERRQ(ierr); 236724121865SAdrian Maldonado ierr = MatSetUp(j21);CHKERRQ(ierr); 236824121865SAdrian Maldonado ierr = MatSetUp(j22);CHKERRQ(ierr); 236924121865SAdrian Maldonado 237001ad2aeeSHong Zhang ierr = MatCreateNest(comm,2,NULL,2,NULL,&bA[0][0],J);CHKERRQ(ierr); 237124121865SAdrian Maldonado ierr = MatSetUp(*J);CHKERRQ(ierr); 237224121865SAdrian Maldonado ierr = MatNestSetVecType(*J,VECNEST);CHKERRQ(ierr); 237324121865SAdrian Maldonado ierr = MatDestroy(&j11);CHKERRQ(ierr); 237424121865SAdrian Maldonado ierr = MatDestroy(&j12);CHKERRQ(ierr); 237524121865SAdrian Maldonado ierr = MatDestroy(&j21);CHKERRQ(ierr); 237624121865SAdrian Maldonado ierr = MatDestroy(&j22);CHKERRQ(ierr); 237724121865SAdrian Maldonado 237824121865SAdrian Maldonado ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 237924121865SAdrian Maldonado ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 23809e1d080bSHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 238124121865SAdrian Maldonado 238224121865SAdrian Maldonado /* Free structures */ 238324121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&eISMap);CHKERRQ(ierr); 238424121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&vISMap);CHKERRQ(ierr); 238524121865SAdrian Maldonado PetscFunctionReturn(0); 23869e1d080bSHong Zhang } 23879e1d080bSHong Zhang 23889e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J) 23899e1d080bSHong Zhang { 23909e1d080bSHong Zhang PetscErrorCode ierr; 23919e1d080bSHong Zhang DM_Network *network = (DM_Network*)dm->data; 23929e1d080bSHong Zhang PetscInt eStart,eEnd,vStart,vEnd,rstart,nrows,*rows,localSize; 23939e1d080bSHong Zhang PetscInt cstart,ncols,j,e,v; 23949e1d080bSHong Zhang PetscBool ghost,ghost_vc,ghost2,isNest; 23959e1d080bSHong Zhang Mat Juser; 23969e1d080bSHong Zhang PetscSection sectionGlobal; 23979e1d080bSHong Zhang PetscInt nedges,*vptr=NULL,vc,*rows_v; /* suppress maybe-uninitialized warning */ 23989e1d080bSHong Zhang const PetscInt *edges,*cone; 23999e1d080bSHong Zhang MPI_Comm comm; 24009e1d080bSHong Zhang MatType mtype; 24019e1d080bSHong Zhang Vec vd_nz,vo_nz; 24029e1d080bSHong Zhang PetscInt *dnnz,*onnz; 24039e1d080bSHong Zhang PetscScalar *vdnz,*vonz; 24049e1d080bSHong Zhang 24059e1d080bSHong Zhang PetscFunctionBegin; 24069e1d080bSHong Zhang mtype = dm->mattype; 24079e1d080bSHong Zhang ierr = PetscStrcmp(mtype,MATNEST,&isNest);CHKERRQ(ierr); 24089e1d080bSHong Zhang if (isNest) { 24099e1d080bSHong Zhang ierr = DMCreateMatrix_Network_Nest(dm,J);CHKERRQ(ierr); 2410c6b011d8SStefano Zampini ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 24119e1d080bSHong Zhang PetscFunctionReturn(0); 24129e1d080bSHong Zhang } 24139e1d080bSHong Zhang 24149e1d080bSHong Zhang if (!network->userEdgeJacobian && !network->userVertexJacobian) { 2415a4e85ca8SHong Zhang /* user does not provide Jacobian blocks */ 24169e1d080bSHong Zhang ierr = DMCreateMatrix_Plex(network->plex,J);CHKERRQ(ierr); 2417bfbc38dcSHong Zhang ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 24181ad426b7SHong Zhang PetscFunctionReturn(0); 24191ad426b7SHong Zhang } 24201ad426b7SHong Zhang 2421bfbc38dcSHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)dm),J);CHKERRQ(ierr); 2422e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§ionGlobal);CHKERRQ(ierr); 2423bfbc38dcSHong Zhang ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal,&localSize);CHKERRQ(ierr); 2424bfbc38dcSHong Zhang ierr = MatSetSizes(*J,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 24252a945128SHong Zhang 24262a945128SHong Zhang ierr = MatSetType(*J,MATAIJ);CHKERRQ(ierr); 24272a945128SHong Zhang ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 242889898e50SHong Zhang 242989898e50SHong Zhang /* (1) Set matrix preallocation */ 243089898e50SHong Zhang /*------------------------------*/ 2431840c2264SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 2432840c2264SHong Zhang ierr = VecCreate(comm,&vd_nz);CHKERRQ(ierr); 2433840c2264SHong Zhang ierr = VecSetSizes(vd_nz,localSize,PETSC_DECIDE);CHKERRQ(ierr); 2434840c2264SHong Zhang ierr = VecSetFromOptions(vd_nz);CHKERRQ(ierr); 2435840c2264SHong Zhang ierr = VecSet(vd_nz,0.0);CHKERRQ(ierr); 2436840c2264SHong Zhang ierr = VecDuplicate(vd_nz,&vo_nz);CHKERRQ(ierr); 2437840c2264SHong Zhang 243889898e50SHong Zhang /* Set preallocation for edges */ 243989898e50SHong Zhang /*-----------------------------*/ 2440840c2264SHong Zhang ierr = DMNetworkGetEdgeRange(dm,&eStart,&eEnd);CHKERRQ(ierr); 2441840c2264SHong Zhang 2442bdcb62a2SHong Zhang ierr = PetscMalloc1(localSize,&rows);CHKERRQ(ierr); 2443840c2264SHong Zhang for (e=eStart; e<eEnd; e++) { 2444840c2264SHong Zhang /* Get row indices */ 24452bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,e,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 24462bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,e,&nrows);CHKERRQ(ierr); 2447840c2264SHong Zhang if (nrows) { 2448840c2264SHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 2449840c2264SHong Zhang 2450a5b23f4aSJose E. Roman /* Set preallocation for connected vertices */ 2451d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 2452840c2264SHong Zhang for (v=0; v<2; v++) { 24532bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,cone[v],&ncols);CHKERRQ(ierr); 2454840c2264SHong Zhang 24558675203cSHong Zhang if (network->Je) { 2456840c2264SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 24578675203cSHong Zhang } else Juser = NULL; 2458840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,cone[v],&ghost);CHKERRQ(ierr); 24595cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 2460840c2264SHong Zhang } 2461840c2264SHong Zhang 246289898e50SHong Zhang /* Set preallocation for edge self */ 2463840c2264SHong Zhang cstart = rstart; 24648675203cSHong Zhang if (network->Je) { 2465840c2264SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 24668675203cSHong Zhang } else Juser = NULL; 24675cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 2468840c2264SHong Zhang } 2469840c2264SHong Zhang } 2470840c2264SHong Zhang 247189898e50SHong Zhang /* Set preallocation for vertices */ 247289898e50SHong Zhang /*--------------------------------*/ 2473840c2264SHong Zhang ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 24748675203cSHong Zhang if (vEnd - vStart) vptr = network->Jvptr; 2475840c2264SHong Zhang 2476840c2264SHong Zhang for (v=vStart; v<vEnd; v++) { 2477840c2264SHong Zhang /* Get row indices */ 24782bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 24792bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,v,&nrows);CHKERRQ(ierr); 2480840c2264SHong Zhang if (!nrows) continue; 2481840c2264SHong Zhang 2482bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 2483bdcb62a2SHong Zhang if (ghost) { 2484bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 2485bdcb62a2SHong Zhang } else { 2486bdcb62a2SHong Zhang rows_v = rows; 2487bdcb62a2SHong Zhang } 2488bdcb62a2SHong Zhang 2489bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 2490840c2264SHong Zhang 2491840c2264SHong Zhang /* Get supporting edges and connected vertices */ 2492840c2264SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 2493840c2264SHong Zhang 2494840c2264SHong Zhang for (e=0; e<nedges; e++) { 2495840c2264SHong Zhang /* Supporting edges */ 24962bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,edges[e],ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 24972bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,edges[e],&ncols);CHKERRQ(ierr); 2498840c2264SHong Zhang 24998675203cSHong Zhang if (network->Jv) { 2500840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 25018675203cSHong Zhang } else Juser = NULL; 2502bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 2503840c2264SHong Zhang 2504840c2264SHong Zhang /* Connected vertices */ 2505d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 2506840c2264SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 2507840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,vc,&ghost_vc);CHKERRQ(ierr); 2508840c2264SHong Zhang 25092bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,vc,&ncols);CHKERRQ(ierr); 2510840c2264SHong Zhang 25118675203cSHong Zhang if (network->Jv) { 2512840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 25138675203cSHong Zhang } else Juser = NULL; 2514e102a522SHong Zhang if (ghost_vc||ghost) { 2515e102a522SHong Zhang ghost2 = PETSC_TRUE; 2516e102a522SHong Zhang } else { 2517e102a522SHong Zhang ghost2 = PETSC_FALSE; 2518e102a522SHong Zhang } 2519e102a522SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost2,vd_nz,vo_nz);CHKERRQ(ierr); 2520840c2264SHong Zhang } 2521840c2264SHong Zhang 252289898e50SHong Zhang /* Set preallocation for vertex self */ 2523840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 2524840c2264SHong Zhang if (!ghost) { 25252bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 25268675203cSHong Zhang if (network->Jv) { 2527840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 25288675203cSHong Zhang } else Juser = NULL; 2529bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 2530840c2264SHong Zhang } 2531bdcb62a2SHong Zhang if (ghost) { 2532bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 2533bdcb62a2SHong Zhang } 2534840c2264SHong Zhang } 2535840c2264SHong Zhang 2536840c2264SHong Zhang ierr = VecAssemblyBegin(vd_nz);CHKERRQ(ierr); 2537840c2264SHong Zhang ierr = VecAssemblyBegin(vo_nz);CHKERRQ(ierr); 25385cf7da58SHong Zhang 25395cf7da58SHong Zhang ierr = PetscMalloc2(localSize,&dnnz,localSize,&onnz);CHKERRQ(ierr); 25405cf7da58SHong Zhang 25415cf7da58SHong Zhang ierr = VecAssemblyEnd(vd_nz);CHKERRQ(ierr); 2542840c2264SHong Zhang ierr = VecAssemblyEnd(vo_nz);CHKERRQ(ierr); 2543840c2264SHong Zhang 2544840c2264SHong Zhang ierr = VecGetArray(vd_nz,&vdnz);CHKERRQ(ierr); 2545840c2264SHong Zhang ierr = VecGetArray(vo_nz,&vonz);CHKERRQ(ierr); 2546840c2264SHong Zhang for (j=0; j<localSize; j++) { 2547e102a522SHong Zhang dnnz[j] = (PetscInt)PetscRealPart(vdnz[j]); 2548e102a522SHong Zhang onnz[j] = (PetscInt)PetscRealPart(vonz[j]); 2549840c2264SHong Zhang } 2550840c2264SHong Zhang ierr = VecRestoreArray(vd_nz,&vdnz);CHKERRQ(ierr); 2551840c2264SHong Zhang ierr = VecRestoreArray(vo_nz,&vonz);CHKERRQ(ierr); 2552840c2264SHong Zhang ierr = VecDestroy(&vd_nz);CHKERRQ(ierr); 2553840c2264SHong Zhang ierr = VecDestroy(&vo_nz);CHKERRQ(ierr); 2554840c2264SHong Zhang 25555cf7da58SHong Zhang ierr = MatSeqAIJSetPreallocation(*J,0,dnnz);CHKERRQ(ierr); 25565cf7da58SHong Zhang ierr = MatMPIAIJSetPreallocation(*J,0,dnnz,0,onnz);CHKERRQ(ierr); 25575cf7da58SHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 25585cf7da58SHong Zhang 25595cf7da58SHong Zhang ierr = PetscFree2(dnnz,onnz);CHKERRQ(ierr); 25605cf7da58SHong Zhang 256189898e50SHong Zhang /* (2) Set matrix entries for edges */ 256289898e50SHong Zhang /*----------------------------------*/ 25631ad426b7SHong Zhang for (e=eStart; e<eEnd; e++) { 2564bfbc38dcSHong Zhang /* Get row indices */ 25652bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,e,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 25662bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,e,&nrows);CHKERRQ(ierr); 25674b976069SHong Zhang if (nrows) { 256817df6e9eSHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 25691ad426b7SHong Zhang 2570a5b23f4aSJose E. Roman /* Set matrix entries for connected vertices */ 2571d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 2572bfbc38dcSHong Zhang for (v=0; v<2; v++) { 25732bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,cone[v],ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 25742bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,cone[v],&ncols);CHKERRQ(ierr); 25753e97b6e8SHong Zhang 25768675203cSHong Zhang if (network->Je) { 2577a4e85ca8SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 25788675203cSHong Zhang } else Juser = NULL; 2579a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 2580bfbc38dcSHong Zhang } 258117df6e9eSHong Zhang 2582bfbc38dcSHong Zhang /* Set matrix entries for edge self */ 25833e97b6e8SHong Zhang cstart = rstart; 25848675203cSHong Zhang if (network->Je) { 2585a4e85ca8SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 25868675203cSHong Zhang } else Juser = NULL; 2587a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,nrows,cstart,J);CHKERRQ(ierr); 25881ad426b7SHong Zhang } 25894b976069SHong Zhang } 25901ad426b7SHong Zhang 2591bfbc38dcSHong Zhang /* Set matrix entries for vertices */ 259283b2e829SHong Zhang /*---------------------------------*/ 25931ad426b7SHong Zhang for (v=vStart; v<vEnd; v++) { 2594bfbc38dcSHong Zhang /* Get row indices */ 25952bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 25962bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,v,&nrows);CHKERRQ(ierr); 25974b976069SHong Zhang if (!nrows) continue; 2598596e729fSHong Zhang 2599bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 2600bdcb62a2SHong Zhang if (ghost) { 2601bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 2602bdcb62a2SHong Zhang } else { 2603bdcb62a2SHong Zhang rows_v = rows; 2604bdcb62a2SHong Zhang } 2605bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 2606596e729fSHong Zhang 2607bfbc38dcSHong Zhang /* Get supporting edges and connected vertices */ 2608596e729fSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 2609596e729fSHong Zhang 2610596e729fSHong Zhang for (e=0; e<nedges; e++) { 2611bfbc38dcSHong Zhang /* Supporting edges */ 26122bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,edges[e],ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 26132bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,edges[e],&ncols);CHKERRQ(ierr); 2614596e729fSHong Zhang 26158675203cSHong Zhang if (network->Jv) { 2616a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 26178675203cSHong Zhang } else Juser = NULL; 2618bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 2619596e729fSHong Zhang 2620bfbc38dcSHong Zhang /* Connected vertices */ 2621d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 26222a945128SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 26232a945128SHong Zhang 26242bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,vc,ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 26252bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,vc,&ncols);CHKERRQ(ierr); 2626a4e85ca8SHong Zhang 26278675203cSHong Zhang if (network->Jv) { 2628a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 26298675203cSHong Zhang } else Juser = NULL; 2630bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 2631596e729fSHong Zhang } 2632596e729fSHong Zhang 2633bfbc38dcSHong Zhang /* Set matrix entries for vertex self */ 26341ad426b7SHong Zhang if (!ghost) { 26352bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 26368675203cSHong Zhang if (network->Jv) { 2637a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 26388675203cSHong Zhang } else Juser = NULL; 2639bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,nrows,cstart,J);CHKERRQ(ierr); 2640bdcb62a2SHong Zhang } 2641bdcb62a2SHong Zhang if (ghost) { 2642bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 2643bdcb62a2SHong Zhang } 26441ad426b7SHong Zhang } 2645a4e85ca8SHong Zhang ierr = PetscFree(rows);CHKERRQ(ierr); 2646bdcb62a2SHong Zhang 26471ad426b7SHong Zhang ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 26481ad426b7SHong Zhang ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2649dd6f46cdSHong Zhang 26505f2c45f1SShri Abhyankar ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 26515f2c45f1SShri Abhyankar PetscFunctionReturn(0); 26525f2c45f1SShri Abhyankar } 26535f2c45f1SShri Abhyankar 26545f2c45f1SShri Abhyankar PetscErrorCode DMDestroy_Network(DM dm) 26555f2c45f1SShri Abhyankar { 26565f2c45f1SShri Abhyankar PetscErrorCode ierr; 26575f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 265854dfd506SHong Zhang PetscInt j,np; 26595f2c45f1SShri Abhyankar 26605f2c45f1SShri Abhyankar PetscFunctionBegin; 26618415c774SShri Abhyankar if (--network->refct > 0) PetscFunctionReturn(0); 266283b2e829SHong Zhang if (network->Je) { 266383b2e829SHong Zhang ierr = PetscFree(network->Je);CHKERRQ(ierr); 266483b2e829SHong Zhang } 266583b2e829SHong Zhang if (network->Jv) { 2666883e35e8SHong Zhang ierr = PetscFree(network->Jvptr);CHKERRQ(ierr); 266783b2e829SHong Zhang ierr = PetscFree(network->Jv);CHKERRQ(ierr); 26681ad426b7SHong Zhang } 266913c2a604SAdrian Maldonado 267013c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->vertex.mapping);CHKERRQ(ierr); 267113c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.DofSection);CHKERRQ(ierr); 267213c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.GlobalDofSection);CHKERRQ(ierr); 2673f5427c60SHong Zhang if (network->vltog) { 2674f5427c60SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 2675f5427c60SHong Zhang } 267613c2a604SAdrian Maldonado if (network->vertex.sf) { 267713c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->vertex.sf);CHKERRQ(ierr); 267813c2a604SAdrian Maldonado } 267913c2a604SAdrian Maldonado /* edge */ 268013c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->edge.mapping);CHKERRQ(ierr); 268113c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.DofSection);CHKERRQ(ierr); 268213c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.GlobalDofSection);CHKERRQ(ierr); 268313c2a604SAdrian Maldonado if (network->edge.sf) { 268413c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->edge.sf);CHKERRQ(ierr); 268513c2a604SAdrian Maldonado } 26865f2c45f1SShri Abhyankar ierr = DMDestroy(&network->plex);CHKERRQ(ierr); 26875f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr); 26885f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr); 268983b2e829SHong Zhang 26902bf73ac6SHong Zhang for (j=0; j<network->Nsvtx; j++) { 26912bf73ac6SHong Zhang ierr = PetscFree(network->svtx[j].sv);CHKERRQ(ierr); 26922bf73ac6SHong Zhang } 26932bf73ac6SHong Zhang if (network->svtx) {ierr = PetscFree(network->svtx);CHKERRQ(ierr);} 2694f11a936eSBarry Smith ierr = PetscFree2(network->subnetedge,network->subnetvtx);CHKERRQ(ierr); 2695caf410d2SHong Zhang 26962bf73ac6SHong Zhang ierr = PetscTableDestroy(&network->svtable);CHKERRQ(ierr); 2697e2aaf10cSShri Abhyankar ierr = PetscFree(network->subnet);CHKERRQ(ierr); 269854dfd506SHong Zhang ierr = PetscFree(network->component);CHKERRQ(ierr); 26995f2c45f1SShri Abhyankar ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr); 270054dfd506SHong Zhang 270154dfd506SHong Zhang if (network->header) { 270254dfd506SHong Zhang np = network->pEnd - network->pStart; 270354dfd506SHong Zhang for (j=0; j < np; j++) { 270454dfd506SHong 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); 270554dfd506SHong Zhang ierr = PetscFree(network->cvalue[j].data);CHKERRQ(ierr); 270654dfd506SHong Zhang } 2707caf410d2SHong Zhang ierr = PetscFree2(network->header,network->cvalue);CHKERRQ(ierr); 270854dfd506SHong Zhang } 27095f2c45f1SShri Abhyankar ierr = PetscFree(network);CHKERRQ(ierr); 27105f2c45f1SShri Abhyankar PetscFunctionReturn(0); 27115f2c45f1SShri Abhyankar } 27125f2c45f1SShri Abhyankar 27135f2c45f1SShri Abhyankar PetscErrorCode DMView_Network(DM dm,PetscViewer viewer) 27145f2c45f1SShri Abhyankar { 27155f2c45f1SShri Abhyankar PetscErrorCode ierr; 2716caf410d2SHong Zhang PetscBool iascii; 2717caf410d2SHong Zhang PetscMPIInt rank; 27185f2c45f1SShri Abhyankar 27195f2c45f1SShri Abhyankar PetscFunctionBegin; 2720caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 2721ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRMPI(ierr); 2722caf410d2SHong Zhang PetscValidHeaderSpecific(dm,DM_CLASSID, 1); 2723caf410d2SHong Zhang PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2724caf410d2SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 2725caf410d2SHong Zhang if (iascii) { 2726caf410d2SHong Zhang const PetscInt *cone,*vtx,*edges; 27272bf73ac6SHong Zhang PetscInt vfrom,vto,i,j,nv,ne,ncv,p,nsubnet; 27282bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 2729caf410d2SHong Zhang 27302bf73ac6SHong Zhang nsubnet = network->Nsubnet; /* num of subnetworks */ 27312bf73ac6SHong Zhang if (!rank) { 27322bf73ac6SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF," NSubnets: %D; NEdges: %D; NVertices: %D; NSharedVertices: %D.\n",nsubnet,network->NEdges,network->NVertices,network->Nsvtx);CHKERRQ(ierr); 27332bf73ac6SHong Zhang } 27342bf73ac6SHong Zhang 27352bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&ncv,&vtx);CHKERRQ(ierr); 2736caf410d2SHong Zhang ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 27372bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " [%d] nEdges: %D; nVertices: %D; nSharedVertices: %D\n",rank,network->nEdges,network->nVertices,ncv);CHKERRQ(ierr); 2738caf410d2SHong Zhang 2739caf410d2SHong Zhang for (i=0; i<nsubnet; i++) { 27402bf73ac6SHong Zhang ierr = DMNetworkGetSubnetwork(dm,i,&nv,&ne,&vtx,&edges);CHKERRQ(ierr); 2741caf410d2SHong Zhang if (ne) { 27422bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " Subnet %D: nEdges %D, nVertices(include shared vertices) %D\n",i,ne,nv);CHKERRQ(ierr); 2743caf410d2SHong Zhang for (j=0; j<ne; j++) { 2744caf410d2SHong Zhang p = edges[j]; 2745caf410d2SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,p,&cone);CHKERRQ(ierr); 2746caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[0],&vfrom);CHKERRQ(ierr); 2747caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[1],&vto);CHKERRQ(ierr); 2748caf410d2SHong Zhang ierr = DMNetworkGetGlobalEdgeIndex(dm,edges[j],&p);CHKERRQ(ierr); 2749caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " edge %D: %D ----> %D\n",p,vfrom,vto);CHKERRQ(ierr); 2750caf410d2SHong Zhang } 2751caf410d2SHong Zhang } 2752caf410d2SHong Zhang } 27532bf73ac6SHong Zhang 27542bf73ac6SHong Zhang /* Shared vertices */ 27552bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&ncv,&vtx);CHKERRQ(ierr); 27562bf73ac6SHong Zhang if (ncv) { 27572bf73ac6SHong Zhang SVtx *svtx = network->svtx; 27582bf73ac6SHong Zhang PetscInt gidx,svtx_idx,nvto,vfrom_net,vfrom_idx,*svto; 27592bf73ac6SHong Zhang PetscBool ghost; 27602bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " SharedVertices:\n");CHKERRQ(ierr); 27612bf73ac6SHong Zhang for (i=0; i<ncv; i++) { 27622bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,vtx[i],&ghost);CHKERRQ(ierr); 27632bf73ac6SHong Zhang if (ghost) continue; 27642bf73ac6SHong Zhang 27652bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,vtx[i],&gidx);CHKERRQ(ierr); 27662bf73ac6SHong Zhang ierr = PetscTableFind(network->svtable,gidx+1,&svtx_idx);CHKERRQ(ierr); 27672bf73ac6SHong Zhang svtx_idx--; 27682bf73ac6SHong Zhang nvto = svtx[svtx_idx].n; 27692bf73ac6SHong Zhang 27702bf73ac6SHong Zhang vfrom_net = svtx[svtx_idx].sv[0]; 27712bf73ac6SHong Zhang vfrom_idx = svtx[svtx_idx].sv[1]; 27722bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " svtx %D: global index %D, subnet[%D].%D ---->\n",i,gidx,vfrom_net,vfrom_idx);CHKERRQ(ierr); 27732bf73ac6SHong Zhang for (j=1; j<nvto; j++) { 27742bf73ac6SHong Zhang svto = svtx[svtx_idx].sv + 2*j; 27752bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " ----> subnet[%D].%D\n",svto[0],svto[1]);CHKERRQ(ierr); 2776caf410d2SHong Zhang } 2777caf410d2SHong Zhang } 2778caf410d2SHong Zhang } 2779caf410d2SHong Zhang ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2780caf410d2SHong Zhang ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 2781caf410d2SHong Zhang } else SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMNetwork writing", ((PetscObject)viewer)->type_name); 27825f2c45f1SShri Abhyankar PetscFunctionReturn(0); 27835f2c45f1SShri Abhyankar } 27845f2c45f1SShri Abhyankar 27855f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l) 27865f2c45f1SShri Abhyankar { 27875f2c45f1SShri Abhyankar PetscErrorCode ierr; 27885f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 27895f2c45f1SShri Abhyankar 27905f2c45f1SShri Abhyankar PetscFunctionBegin; 27915f2c45f1SShri Abhyankar ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr); 27925f2c45f1SShri Abhyankar PetscFunctionReturn(0); 27935f2c45f1SShri Abhyankar } 27945f2c45f1SShri Abhyankar 27955f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l) 27965f2c45f1SShri Abhyankar { 27975f2c45f1SShri Abhyankar PetscErrorCode ierr; 27985f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 27995f2c45f1SShri Abhyankar 28005f2c45f1SShri Abhyankar PetscFunctionBegin; 28015f2c45f1SShri Abhyankar ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr); 28025f2c45f1SShri Abhyankar PetscFunctionReturn(0); 28035f2c45f1SShri Abhyankar } 28045f2c45f1SShri Abhyankar 28055f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g) 28065f2c45f1SShri Abhyankar { 28075f2c45f1SShri Abhyankar PetscErrorCode ierr; 28085f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 28095f2c45f1SShri Abhyankar 28105f2c45f1SShri Abhyankar PetscFunctionBegin; 28115f2c45f1SShri Abhyankar ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr); 28125f2c45f1SShri Abhyankar PetscFunctionReturn(0); 28135f2c45f1SShri Abhyankar } 28145f2c45f1SShri Abhyankar 28155f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g) 28165f2c45f1SShri Abhyankar { 28175f2c45f1SShri Abhyankar PetscErrorCode ierr; 28185f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 28195f2c45f1SShri Abhyankar 28205f2c45f1SShri Abhyankar PetscFunctionBegin; 28215f2c45f1SShri Abhyankar ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr); 28225f2c45f1SShri Abhyankar PetscFunctionReturn(0); 28235f2c45f1SShri Abhyankar } 282422bbedd7SHong Zhang 282522bbedd7SHong Zhang /*@ 282664238763SRodolfo Oliveira DMNetworkGetVertexLocalToGlobalOrdering - Get vertex global index 282722bbedd7SHong Zhang 282822bbedd7SHong Zhang Not collective 282922bbedd7SHong Zhang 28307a7aea1fSJed Brown Input Parameters: 283122bbedd7SHong Zhang + dm - the dm object 283222bbedd7SHong Zhang - vloc - local vertex ordering, start from 0 283322bbedd7SHong Zhang 28347a7aea1fSJed Brown Output Parameters: 2835f0fc11ceSJed Brown . vg - global vertex ordering, start from 0 283622bbedd7SHong Zhang 283797bb938eSShri Abhyankar Level: advanced 283822bbedd7SHong Zhang 283922bbedd7SHong Zhang .seealso: DMNetworkSetVertexLocalToGlobalOrdering() 284022bbedd7SHong Zhang @*/ 284122bbedd7SHong Zhang PetscErrorCode DMNetworkGetVertexLocalToGlobalOrdering(DM dm,PetscInt vloc,PetscInt *vg) 284222bbedd7SHong Zhang { 284322bbedd7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 284422bbedd7SHong Zhang PetscInt *vltog = network->vltog; 284522bbedd7SHong Zhang 284622bbedd7SHong Zhang PetscFunctionBegin; 284722bbedd7SHong Zhang if (!vltog) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkSetVertexLocalToGlobalOrdering() first"); 284822bbedd7SHong Zhang *vg = vltog[vloc]; 284922bbedd7SHong Zhang PetscFunctionReturn(0); 285022bbedd7SHong Zhang } 285122bbedd7SHong Zhang 285222bbedd7SHong Zhang /*@ 285364238763SRodolfo Oliveira DMNetworkSetVertexLocalToGlobalOrdering - Create and setup vertex local to global map 285422bbedd7SHong Zhang 285522bbedd7SHong Zhang Collective 285622bbedd7SHong Zhang 285722bbedd7SHong Zhang Input Parameters: 2858f0fc11ceSJed Brown . dm - the dm object 285922bbedd7SHong Zhang 286097bb938eSShri Abhyankar Level: advanced 286122bbedd7SHong Zhang 286263029d29SHong Zhang .seealso: DMNetworkGetGlobalVertexIndex() 286322bbedd7SHong Zhang @*/ 286422bbedd7SHong Zhang PetscErrorCode DMNetworkSetVertexLocalToGlobalOrdering(DM dm) 286522bbedd7SHong Zhang { 286622bbedd7SHong Zhang PetscErrorCode ierr; 286722bbedd7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 286822bbedd7SHong Zhang MPI_Comm comm; 28692bf73ac6SHong Zhang PetscMPIInt rank,size,*displs=NULL,*recvcounts=NULL,remoterank; 287022bbedd7SHong Zhang PetscBool ghost; 287163029d29SHong Zhang PetscInt *vltog,nroots,nleaves,i,*vrange,k,N,lidx; 287222bbedd7SHong Zhang const PetscSFNode *iremote; 287322bbedd7SHong Zhang PetscSF vsf; 287463029d29SHong Zhang Vec Vleaves,Vleaves_seq; 287563029d29SHong Zhang VecScatter ctx; 287663029d29SHong Zhang PetscScalar *varr,val; 287763029d29SHong Zhang const PetscScalar *varr_read; 287822bbedd7SHong Zhang 287922bbedd7SHong Zhang PetscFunctionBegin; 288022bbedd7SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 2881ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 2882ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 288322bbedd7SHong Zhang 288422bbedd7SHong Zhang if (size == 1) { 288522bbedd7SHong Zhang nroots = network->vEnd - network->vStart; 288622bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 288722bbedd7SHong Zhang for (i=0; i<nroots; i++) vltog[i] = i; 288822bbedd7SHong Zhang network->vltog = vltog; 288922bbedd7SHong Zhang PetscFunctionReturn(0); 289022bbedd7SHong Zhang } 289122bbedd7SHong Zhang 289222bbedd7SHong Zhang if (!network->distributecalled) SETERRQ(comm, PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkDistribute() first"); 289322bbedd7SHong Zhang if (network->vltog) { 289422bbedd7SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 289522bbedd7SHong Zhang } 289622bbedd7SHong Zhang 289722bbedd7SHong Zhang ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 289822bbedd7SHong Zhang ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 289922bbedd7SHong Zhang vsf = network->vertex.sf; 290022bbedd7SHong Zhang 29012bf73ac6SHong Zhang ierr = PetscMalloc3(size+1,&vrange,size,&displs,size,&recvcounts);CHKERRQ(ierr); 2902f5427c60SHong Zhang ierr = PetscSFGetGraph(vsf,&nroots,&nleaves,NULL,&iremote);CHKERRQ(ierr); 290322bbedd7SHong Zhang 290422bbedd7SHong Zhang for (i=0; i<size; i++) { displs[i] = i; recvcounts[i] = 1;} 290522bbedd7SHong Zhang 290622bbedd7SHong Zhang i = nroots - nleaves; /* local number of vertices, excluding ghosts */ 290722bbedd7SHong Zhang vrange[0] = 0; 2908ffc4695bSBarry Smith ierr = MPI_Allgatherv(&i,1,MPIU_INT,vrange+1,recvcounts,displs,MPIU_INT,comm);CHKERRMPI(ierr); 290967dd800bSHong Zhang for (i=2; i<size+1; i++) {vrange[i] += vrange[i-1];} 291022bbedd7SHong Zhang 291122bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 291222bbedd7SHong Zhang network->vltog = vltog; 291322bbedd7SHong Zhang 291463029d29SHong Zhang /* Set vltog for non-ghost vertices */ 291563029d29SHong Zhang k = 0; 291622bbedd7SHong Zhang for (i=0; i<nroots; i++) { 291722bbedd7SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 291863029d29SHong Zhang if (ghost) continue; 291963029d29SHong Zhang vltog[i] = vrange[rank] + k++; 292022bbedd7SHong Zhang } 2921f5427c60SHong Zhang ierr = PetscFree3(vrange,displs,recvcounts);CHKERRQ(ierr); 292263029d29SHong Zhang 292363029d29SHong Zhang /* Set vltog for ghost vertices */ 292463029d29SHong Zhang /* (a) create parallel Vleaves and sequential Vleaves_seq to convert local iremote[*].index to global index */ 292563029d29SHong Zhang ierr = VecCreate(comm,&Vleaves);CHKERRQ(ierr); 292663029d29SHong Zhang ierr = VecSetSizes(Vleaves,2*nleaves,PETSC_DETERMINE);CHKERRQ(ierr); 292763029d29SHong Zhang ierr = VecSetFromOptions(Vleaves);CHKERRQ(ierr); 292863029d29SHong Zhang ierr = VecGetArray(Vleaves,&varr);CHKERRQ(ierr); 292963029d29SHong Zhang for (i=0; i<nleaves; i++) { 293063029d29SHong Zhang varr[2*i] = (PetscScalar)(iremote[i].rank); /* rank of remote process */ 293163029d29SHong Zhang varr[2*i+1] = (PetscScalar)(iremote[i].index); /* local index in remote process */ 293263029d29SHong Zhang } 293363029d29SHong Zhang ierr = VecRestoreArray(Vleaves,&varr);CHKERRQ(ierr); 293463029d29SHong Zhang 293563029d29SHong Zhang /* (b) scatter local info to remote processes via VecScatter() */ 293663029d29SHong Zhang ierr = VecScatterCreateToAll(Vleaves,&ctx,&Vleaves_seq);CHKERRQ(ierr); 293763029d29SHong Zhang ierr = VecScatterBegin(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 293863029d29SHong Zhang ierr = VecScatterEnd(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 293963029d29SHong Zhang 294063029d29SHong Zhang /* (c) convert local indices to global indices in parallel vector Vleaves */ 294163029d29SHong Zhang ierr = VecGetSize(Vleaves_seq,&N);CHKERRQ(ierr); 294263029d29SHong Zhang ierr = VecGetArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 294363029d29SHong Zhang for (i=0; i<N; i+=2) { 29442e4cff2eSHong Zhang remoterank = (PetscMPIInt)PetscRealPart(varr_read[i]); 294563029d29SHong Zhang if (remoterank == rank) { 294663029d29SHong Zhang k = i+1; /* row number */ 29472e4cff2eSHong Zhang lidx = (PetscInt)PetscRealPart(varr_read[i+1]); 294863029d29SHong Zhang val = (PetscScalar)vltog[lidx]; /* global index for non-ghost vertex computed above */ 294963029d29SHong Zhang ierr = VecSetValues(Vleaves,1,&k,&val,INSERT_VALUES);CHKERRQ(ierr); 295063029d29SHong Zhang } 295163029d29SHong Zhang } 295263029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 295363029d29SHong Zhang ierr = VecAssemblyBegin(Vleaves);CHKERRQ(ierr); 295463029d29SHong Zhang ierr = VecAssemblyEnd(Vleaves);CHKERRQ(ierr); 295563029d29SHong Zhang 295663029d29SHong Zhang /* (d) Set vltog for ghost vertices by copying local values of Vleaves */ 295763029d29SHong Zhang ierr = VecGetArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 295863029d29SHong Zhang k = 0; 295963029d29SHong Zhang for (i=0; i<nroots; i++) { 296063029d29SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 296163029d29SHong Zhang if (!ghost) continue; 29622e4cff2eSHong Zhang vltog[i] = (PetscInt)PetscRealPart(varr_read[2*k+1]); k++; 296363029d29SHong Zhang } 296463029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 296563029d29SHong Zhang 296663029d29SHong Zhang ierr = VecDestroy(&Vleaves);CHKERRQ(ierr); 296763029d29SHong Zhang ierr = VecDestroy(&Vleaves_seq);CHKERRQ(ierr); 296863029d29SHong Zhang ierr = VecScatterDestroy(&ctx);CHKERRQ(ierr); 296922bbedd7SHong Zhang PetscFunctionReturn(0); 297022bbedd7SHong Zhang } 297142dc13f1SHong Zhang 297242dc13f1SHong Zhang PETSC_STATIC_INLINE PetscErrorCode DMISAddSize_private(DM_Network *network,PetscInt p,PetscInt numkeys,PetscInt keys[],PetscInt blocksize[],PetscInt nselectedvar[],PetscInt *nidx) 297342dc13f1SHong Zhang { 297442dc13f1SHong Zhang PetscErrorCode ierr; 297542dc13f1SHong Zhang PetscInt i,j,ncomps,nvar,key,offset=0; 297642dc13f1SHong Zhang DMNetworkComponentHeader header; 297742dc13f1SHong Zhang 297842dc13f1SHong Zhang PetscFunctionBegin; 297942dc13f1SHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 298042dc13f1SHong Zhang ncomps = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 298142dc13f1SHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offset); 298242dc13f1SHong Zhang 298342dc13f1SHong Zhang for (i=0; i<ncomps; i++) { 298442dc13f1SHong Zhang key = header->key[i]; 298542dc13f1SHong Zhang nvar = header->nvar[i]; 298642dc13f1SHong Zhang for (j=0; j<numkeys; j++) { 298742dc13f1SHong Zhang if (key == keys[j]) { 298842dc13f1SHong Zhang if (!blocksize || blocksize[j] == -1) { 298942dc13f1SHong Zhang *nidx += nvar; 299042dc13f1SHong Zhang } else { 299142dc13f1SHong Zhang *nidx += nselectedvar[j]*nvar/blocksize[j]; 299242dc13f1SHong Zhang } 299342dc13f1SHong Zhang } 299442dc13f1SHong Zhang } 299542dc13f1SHong Zhang } 299642dc13f1SHong Zhang PetscFunctionReturn(0); 299742dc13f1SHong Zhang } 299842dc13f1SHong Zhang 299942dc13f1SHong Zhang PETSC_STATIC_INLINE PetscErrorCode DMISComputeIdx_private(DM dm,PetscInt p,PetscInt numkeys,PetscInt keys[],PetscInt blocksize[],PetscInt nselectedvar[],PetscInt *selectedvar[],PetscInt *ii,PetscInt *idx) 300042dc13f1SHong Zhang { 300142dc13f1SHong Zhang PetscErrorCode ierr; 300242dc13f1SHong Zhang PetscInt i,j,ncomps,nvar,key,offsetg,k,k1,offset=0; 300342dc13f1SHong Zhang DM_Network *network = (DM_Network*)dm->data; 300442dc13f1SHong Zhang DMNetworkComponentHeader header; 300542dc13f1SHong Zhang 300642dc13f1SHong Zhang PetscFunctionBegin; 300742dc13f1SHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 300842dc13f1SHong Zhang ncomps = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 300942dc13f1SHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offset); 301042dc13f1SHong Zhang 301142dc13f1SHong Zhang for (i=0; i<ncomps; i++) { 301242dc13f1SHong Zhang key = header->key[i]; 301342dc13f1SHong Zhang nvar = header->nvar[i]; 301442dc13f1SHong Zhang for (j=0; j<numkeys; j++) { 301542dc13f1SHong Zhang if (key != keys[j]) continue; 301642dc13f1SHong Zhang 301742dc13f1SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,p,i,&offsetg);CHKERRQ(ierr); 301842dc13f1SHong Zhang if (!blocksize || blocksize[j] == -1) { 301942dc13f1SHong Zhang for (k=0; k<nvar; k++) idx[(*ii)++] = offsetg + k; 302042dc13f1SHong Zhang } else { 302142dc13f1SHong Zhang for (k=0; k<nvar; k+=blocksize[j]) { 302242dc13f1SHong Zhang for (k1=0; k1<nselectedvar[j]; k1++) idx[(*ii)++] = offsetg + k + selectedvar[j][k1]; 302342dc13f1SHong Zhang } 302442dc13f1SHong Zhang } 302542dc13f1SHong Zhang } 302642dc13f1SHong Zhang } 302742dc13f1SHong Zhang PetscFunctionReturn(0); 302842dc13f1SHong Zhang } 302942dc13f1SHong Zhang 303042dc13f1SHong Zhang /*@ 303142dc13f1SHong Zhang DMNetworkCreateIS - Create an index set object from the global vector of the network 303242dc13f1SHong Zhang 303342dc13f1SHong Zhang Collective 303442dc13f1SHong Zhang 303542dc13f1SHong Zhang Input Parameters: 303642dc13f1SHong Zhang + dm - DMNetwork object 303742dc13f1SHong Zhang . numkeys - number of keys 303842dc13f1SHong Zhang . keys - array of keys that define the components of the variables you wish to extract 303942dc13f1SHong Zhang . blocksize - block size of the variables associated to the component 304042dc13f1SHong Zhang . nselectedvar - number of variables in each block to select 304142dc13f1SHong Zhang - selectedvar - the offset into the block of each variable in each block to select 304242dc13f1SHong Zhang 304342dc13f1SHong Zhang Output Parameters: 304442dc13f1SHong Zhang . is - the index set 304542dc13f1SHong Zhang 304642dc13f1SHong Zhang Level: Advanced 304742dc13f1SHong Zhang 304842dc13f1SHong Zhang Notes: 304942dc13f1SHong Zhang Use blocksize[i] of -1 to indicate select all the variables of the i-th component, for which nselectvar[i] and selectedvar[i] are ignored. Use NULL, NULL, NULL to indicate for all selected components one wishes to obtain all the values of that component. For example, DMNetworkCreateIS(dm,1,&key,NULL,NULL,NULL,&is) will return an is that extracts all the variables for the 0-th component. 305042dc13f1SHong Zhang 305142dc13f1SHong Zhang .seealso: DMNetworkCreate(), ISCreateGeneral(), DMNetworkCreateLocalIS() 305242dc13f1SHong Zhang @*/ 305342dc13f1SHong Zhang PetscErrorCode DMNetworkCreateIS(DM dm,PetscInt numkeys,PetscInt keys[],PetscInt blocksize[],PetscInt nselectedvar[],PetscInt *selectedvar[],IS *is) 305442dc13f1SHong Zhang { 305542dc13f1SHong Zhang PetscErrorCode ierr; 305642dc13f1SHong Zhang MPI_Comm comm; 305742dc13f1SHong Zhang DM_Network *network = (DM_Network*)dm->data; 305842dc13f1SHong Zhang PetscInt i,p,estart,eend,vstart,vend,nidx,*idx; 305942dc13f1SHong Zhang PetscBool ghost; 306042dc13f1SHong Zhang 306142dc13f1SHong Zhang PetscFunctionBegin; 306242dc13f1SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 306342dc13f1SHong Zhang 306442dc13f1SHong Zhang /* Check input parameters */ 306542dc13f1SHong Zhang for (i=0; i<numkeys; i++) { 306642dc13f1SHong Zhang if (!blocksize || blocksize[i] == -1) continue; 306742dc13f1SHong Zhang if (nselectedvar[i] > blocksize[i]) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"number of selectedvariables %D cannot be larger than blocksize %D",nselectedvar[i],blocksize[i]); 306842dc13f1SHong Zhang } 306942dc13f1SHong Zhang 307042dc13f1SHong Zhang ierr = DMNetworkGetEdgeRange(dm,&estart,&eend);CHKERRQ(ierr); 307142dc13f1SHong Zhang ierr = DMNetworkGetVertexRange(dm,&vstart,&vend);CHKERRQ(ierr); 307242dc13f1SHong Zhang 307342dc13f1SHong Zhang /* Get local number of idx */ 307442dc13f1SHong Zhang nidx = 0; 307542dc13f1SHong Zhang for (p=estart; p<eend; p++) { 307642dc13f1SHong Zhang ierr = DMISAddSize_private(network,p,numkeys,keys,blocksize,nselectedvar,&nidx);CHKERRQ(ierr); 307742dc13f1SHong Zhang } 307842dc13f1SHong Zhang for (p=vstart; p<vend; p++) { 307942dc13f1SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 308042dc13f1SHong Zhang if (ghost) continue; 308142dc13f1SHong Zhang ierr = DMISAddSize_private(network,p,numkeys,keys,blocksize,nselectedvar,&nidx);CHKERRQ(ierr); 308242dc13f1SHong Zhang } 308342dc13f1SHong Zhang 308442dc13f1SHong Zhang /* Compute idx */ 308542dc13f1SHong Zhang ierr = PetscMalloc1(nidx,&idx);CHKERRQ(ierr); 308642dc13f1SHong Zhang i = 0; 308742dc13f1SHong Zhang for (p=estart; p<eend; p++) { 308842dc13f1SHong Zhang ierr = DMISComputeIdx_private(dm,p,numkeys,keys,blocksize,nselectedvar,selectedvar,&i,idx);CHKERRQ(ierr); 308942dc13f1SHong Zhang } 309042dc13f1SHong Zhang for (p=vstart; p<vend; p++) { 309142dc13f1SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 309242dc13f1SHong Zhang if (ghost) continue; 309342dc13f1SHong Zhang ierr = DMISComputeIdx_private(dm,p,numkeys,keys,blocksize,nselectedvar,selectedvar,&i,idx);CHKERRQ(ierr); 309442dc13f1SHong Zhang } 309542dc13f1SHong Zhang 309642dc13f1SHong Zhang /* Create is */ 309742dc13f1SHong Zhang ierr = ISCreateGeneral(comm,nidx,idx,PETSC_COPY_VALUES,is);CHKERRQ(ierr); 309842dc13f1SHong Zhang ierr = PetscFree(idx);CHKERRQ(ierr); 309942dc13f1SHong Zhang PetscFunctionReturn(0); 310042dc13f1SHong Zhang } 310142dc13f1SHong Zhang 310242dc13f1SHong Zhang PETSC_STATIC_INLINE PetscErrorCode DMISComputeLocalIdx_private(DM dm,PetscInt p,PetscInt numkeys,PetscInt keys[],PetscInt blocksize[],PetscInt nselectedvar[],PetscInt *selectedvar[],PetscInt *ii,PetscInt *idx) 310342dc13f1SHong Zhang { 310442dc13f1SHong Zhang PetscErrorCode ierr; 310542dc13f1SHong Zhang PetscInt i,j,ncomps,nvar,key,offsetl,k,k1,offset=0; 310642dc13f1SHong Zhang DM_Network *network = (DM_Network*)dm->data; 310742dc13f1SHong Zhang DMNetworkComponentHeader header; 310842dc13f1SHong Zhang 310942dc13f1SHong Zhang PetscFunctionBegin; 311042dc13f1SHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 311142dc13f1SHong Zhang ncomps = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 311242dc13f1SHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offset); 311342dc13f1SHong Zhang 311442dc13f1SHong Zhang for (i=0; i<ncomps; i++) { 311542dc13f1SHong Zhang key = header->key[i]; 311642dc13f1SHong Zhang nvar = header->nvar[i]; 311742dc13f1SHong Zhang for (j=0; j<numkeys; j++) { 311842dc13f1SHong Zhang if (key != keys[j]) continue; 311942dc13f1SHong Zhang 312042dc13f1SHong Zhang ierr = DMNetworkGetLocalVecOffset(dm,p,i,&offsetl);CHKERRQ(ierr); 312142dc13f1SHong Zhang if (!blocksize || blocksize[j] == -1) { 312242dc13f1SHong Zhang for (k=0; k<nvar; k++) idx[(*ii)++] = offsetl + k; 312342dc13f1SHong Zhang } else { 312442dc13f1SHong Zhang for (k=0; k<nvar; k+=blocksize[j]) { 312542dc13f1SHong Zhang for (k1=0; k1<nselectedvar[j]; k1++) idx[(*ii)++] = offsetl + k + selectedvar[j][k1]; 312642dc13f1SHong Zhang } 312742dc13f1SHong Zhang } 312842dc13f1SHong Zhang } 312942dc13f1SHong Zhang } 313042dc13f1SHong Zhang PetscFunctionReturn(0); 313142dc13f1SHong Zhang } 313242dc13f1SHong Zhang 313342dc13f1SHong Zhang /*@ 313442dc13f1SHong Zhang DMNetworkCreateLocalIS - Create an index set object from the local vector of the network 313542dc13f1SHong Zhang 313642dc13f1SHong Zhang Not collective 313742dc13f1SHong Zhang 313842dc13f1SHong Zhang Input Parameters: 313942dc13f1SHong Zhang + dm - DMNetwork object 314042dc13f1SHong Zhang . numkeys - number of keys 314142dc13f1SHong Zhang . keys - array of keys that define the components of the variables you wish to extract 314242dc13f1SHong Zhang . blocksize - block size of the variables associated to the component 314342dc13f1SHong Zhang . nselectedvar - number of variables in each block to select 314442dc13f1SHong Zhang - selectedvar - the offset into the block of each variable in each block to select 314542dc13f1SHong Zhang 314642dc13f1SHong Zhang Output Parameters: 314742dc13f1SHong Zhang . is - the index set 314842dc13f1SHong Zhang 314942dc13f1SHong Zhang Level: Advanced 315042dc13f1SHong Zhang 315142dc13f1SHong Zhang Notes: 315242dc13f1SHong Zhang Use blocksize[i] of -1 to indicate select all the variables of the i-th component, for which nselectvar[i] and selectedvar[i] are ignored. Use NULL, NULL, NULL to indicate for all selected components one wishes to obtain all the values of that component. For example, DMNetworkCreateLocalIS(dm,1,&key,NULL,NULL,NULL,&is) will return an is that extracts all the variables for the 0-th component. 315342dc13f1SHong Zhang 315442dc13f1SHong Zhang .seealso: DMNetworkCreate(), DMNetworkCreateIS, ISCreateGeneral() 315542dc13f1SHong Zhang @*/ 315642dc13f1SHong Zhang PetscErrorCode DMNetworkCreateLocalIS(DM dm,PetscInt numkeys,PetscInt keys[],PetscInt blocksize[],PetscInt nselectedvar[],PetscInt *selectedvar[],IS *is) 315742dc13f1SHong Zhang { 315842dc13f1SHong Zhang PetscErrorCode ierr; 315942dc13f1SHong Zhang DM_Network *network = (DM_Network*)dm->data; 316042dc13f1SHong Zhang PetscInt i,p,pstart,pend,nidx,*idx; 316142dc13f1SHong Zhang 316242dc13f1SHong Zhang PetscFunctionBegin; 316342dc13f1SHong Zhang /* Check input parameters */ 316442dc13f1SHong Zhang for (i=0; i<numkeys; i++) { 316542dc13f1SHong Zhang if (!blocksize || blocksize[i] == -1) continue; 316642dc13f1SHong Zhang if (nselectedvar[i] > blocksize[i]) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"number of selectedvariables %D cannot be larger than blocksize %D",nselectedvar[i],blocksize[i]); 316742dc13f1SHong Zhang } 316842dc13f1SHong Zhang 316942dc13f1SHong Zhang pstart = network->pStart; 317042dc13f1SHong Zhang pend = network->pEnd; 317142dc13f1SHong Zhang 317242dc13f1SHong Zhang /* Get local number of idx */ 317342dc13f1SHong Zhang nidx = 0; 317442dc13f1SHong Zhang for (p=pstart; p<pend; p++) { 317542dc13f1SHong Zhang ierr = DMISAddSize_private(network,p,numkeys,keys,blocksize,nselectedvar,&nidx);CHKERRQ(ierr); 317642dc13f1SHong Zhang } 317742dc13f1SHong Zhang 317842dc13f1SHong Zhang /* Compute local idx */ 317942dc13f1SHong Zhang ierr = PetscMalloc1(nidx,&idx);CHKERRQ(ierr); 318042dc13f1SHong Zhang i = 0; 318142dc13f1SHong Zhang for (p=pstart; p<pend; p++) { 318242dc13f1SHong Zhang ierr = DMISComputeLocalIdx_private(dm,p,numkeys,keys,blocksize,nselectedvar,selectedvar,&i,idx);CHKERRQ(ierr); 318342dc13f1SHong Zhang } 318442dc13f1SHong Zhang 318542dc13f1SHong Zhang /* Create is */ 318642dc13f1SHong Zhang ierr = ISCreateGeneral(PETSC_COMM_SELF,nidx,idx,PETSC_COPY_VALUES,is);CHKERRQ(ierr); 318742dc13f1SHong Zhang ierr = PetscFree(idx);CHKERRQ(ierr); 318842dc13f1SHong Zhang PetscFunctionReturn(0); 318942dc13f1SHong Zhang } 3190