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 51f899ff85SJose E. Roman Input Parameter: 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 123*8d1cd658SBarry Smith - edgelist - list of edges for this subnetwork, this is a one dimensional array with pairs of entries being the two vertices (in global numbering of the vertices) of each edge, 124*8d1cd658SBarry Smith $ [first vertex of first edge, second vertex of first edge, first vertex of second edge, second vertex of second edge, etc] 1252bf73ac6SHong Zhang 1262bf73ac6SHong Zhang Output Parameters: 1272bf73ac6SHong Zhang . netnum - global index of the subnetwork 1285f2c45f1SShri Abhyankar 1295f2c45f1SShri Abhyankar Notes: 1305f2c45f1SShri Abhyankar There is no copy involved in this operation, only the pointer is referenced. The edgelist should 1312bf73ac6SHong Zhang not be destroyed before the call to DMNetworkLayoutSetUp() 1325f2c45f1SShri Abhyankar 133*8d1cd658SBarry 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, 134*8d1cd658SBarry Smith 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. 135f11a936eSBarry Smith 13697bb938eSShri Abhyankar Level: beginner 1375f2c45f1SShri Abhyankar 138e3e68989SHong Zhang Example usage: 139f11a936eSBarry Smith Consider the following networks: 140f11a936eSBarry Smith 1) A sigle subnetwork: 141e3e68989SHong Zhang .vb 142f11a936eSBarry Smith network 0: 143f11a936eSBarry Smith rank[0]: 144f11a936eSBarry Smith v0 --> v2; v1 --> v2 145f11a936eSBarry Smith rank[1]: 146f11a936eSBarry Smith v3 --> v5; v4 --> v5 147e3e68989SHong Zhang .ve 148e3e68989SHong Zhang 149e3e68989SHong Zhang The resulting input 150f11a936eSBarry Smith network 0: 151f11a936eSBarry Smith rank[0]: 152f11a936eSBarry Smith ne = 2 153f11a936eSBarry Smith edgelist = [0 2 | 1 2] 154f11a936eSBarry Smith rank[1]: 155f11a936eSBarry Smith ne = 2 156f11a936eSBarry Smith edgelist = [3 5 | 4 5] 157f11a936eSBarry Smith 158f11a936eSBarry Smith 2) Two subnetworks: 159f11a936eSBarry Smith .vb 160f11a936eSBarry Smith subnetwork 0: 161f11a936eSBarry Smith rank[0]: 162f11a936eSBarry Smith v0 --> v2; v2 --> v1; v1 --> v3; 163f11a936eSBarry Smith subnetwork 1: 164f11a936eSBarry Smith rank[1]: 165f11a936eSBarry Smith v0 --> v3; v3 --> v2; v2 --> v1; 166f11a936eSBarry Smith .ve 167f11a936eSBarry Smith 168f11a936eSBarry Smith The resulting input 169f11a936eSBarry Smith subnetwork 0: 170f11a936eSBarry Smith rank[0]: 171f11a936eSBarry Smith ne = 3 172f11a936eSBarry Smith edgelist = [0 2 | 2 1 | 1 3] 173f11a936eSBarry Smith rank[1]: 174f11a936eSBarry Smith ne = 0 175f11a936eSBarry Smith edgelist = NULL 176f11a936eSBarry Smith 177f11a936eSBarry Smith subnetwork 1: 178f11a936eSBarry Smith rank[0]: 179f11a936eSBarry Smith ne = 0 180f11a936eSBarry Smith edgelist = NULL 181f11a936eSBarry Smith rank[1]: 182f11a936eSBarry Smith edgelist = [0 3 | 3 2 | 2 1] 183e3e68989SHong Zhang 1842bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkSetNumSubnetworks() 1855f2c45f1SShri Abhyankar @*/ 186f11a936eSBarry Smith PetscErrorCode DMNetworkAddSubnetwork(DM dm,const char* name,PetscInt ne,PetscInt edgelist[],PetscInt *netnum) 1875f2c45f1SShri Abhyankar { 1882bf73ac6SHong Zhang PetscErrorCode ierr; 1895f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 190f11a936eSBarry Smith PetscInt i,Nedge,j,Nvtx,nvtx; 191f11a936eSBarry Smith PetscBT table; 1925f2c45f1SShri Abhyankar 1935f2c45f1SShri Abhyankar PetscFunctionBegin; 194*8d1cd658SBarry Smith for (i=0; i<ne; i++) { 195*8d1cd658SBarry Smith if (edgelist[2*i] == edgelist[2*i+1]) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Edge %D has the same vertex %D at each endpoint",i,edgelist[2*i]); 196*8d1cd658SBarry Smith } 197f11a936eSBarry Smith /* Get global total Nvtx = max(edgelist[])+1 for this subnet */ 198f11a936eSBarry Smith nvtx = -1; i = 0; 199f11a936eSBarry Smith for (j=0; j<ne; j++) { 200f11a936eSBarry Smith nvtx = PetscMax(nvtx, edgelist[i]); i++; 201f11a936eSBarry Smith nvtx = PetscMax(nvtx, edgelist[i]); i++; 202f11a936eSBarry Smith } 203f11a936eSBarry Smith nvtx++; 204f11a936eSBarry Smith ierr = MPIU_Allreduce(&nvtx,&Nvtx,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 205f11a936eSBarry Smith 206f11a936eSBarry Smith /* Get local nvtx for this subnet */ 207f11a936eSBarry Smith ierr = PetscBTCreate(Nvtx,&table);CHKERRQ(ierr); 208f11a936eSBarry Smith ierr = PetscBTMemzero(Nvtx,table);CHKERRQ(ierr); 209f11a936eSBarry Smith i = 0; 210f11a936eSBarry Smith for (j=0; j<ne; j++) { 211f11a936eSBarry Smith ierr = PetscBTSet(table,edgelist[i]);CHKERRQ(ierr); 212f11a936eSBarry Smith i++; 213f11a936eSBarry Smith ierr = PetscBTSet(table,edgelist[i]);CHKERRQ(ierr); 214f11a936eSBarry Smith i++; 215f11a936eSBarry Smith } 216f11a936eSBarry Smith nvtx = 0; 217f11a936eSBarry Smith for (j=0; j<Nvtx; j++) { 218f11a936eSBarry Smith if (PetscBTLookup(table,j)) nvtx++; 219f11a936eSBarry Smith } 220f11a936eSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 221f11a936eSBarry Smith 222f11a936eSBarry Smith /* Get global total Nedge for this subnet */ 223f11a936eSBarry Smith ierr = MPIU_Allreduce(&ne,&Nedge,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 224f11a936eSBarry Smith 225f11a936eSBarry Smith i = network->nsubnet; 2262bf73ac6SHong Zhang if (name) { 2272bf73ac6SHong Zhang ierr = PetscStrcpy(network->subnet[i].name,name);CHKERRQ(ierr); 228e3e68989SHong Zhang } 229f11a936eSBarry Smith network->subnet[i].nvtx = nvtx; /* include ghost vertices */ 2302bf73ac6SHong Zhang network->subnet[i].nedge = ne; 2312bf73ac6SHong Zhang network->subnet[i].edgelist = edgelist; 232f11a936eSBarry Smith network->subnet[i].Nvtx = Nvtx; 233f11a936eSBarry Smith network->subnet[i].Nedge = Nedge; 2342bf73ac6SHong Zhang 2352bf73ac6SHong Zhang /* ---------------------------------------------------------- 2362bf73ac6SHong Zhang p=v or e; 2372bf73ac6SHong Zhang subnet[0].pStart = 0 2382bf73ac6SHong Zhang subnet[i+1].pStart = subnet[i].pEnd = subnet[i].pStart + (nE[i] or NV[i]) 2392bf73ac6SHong Zhang ----------------------------------------------------------------------- */ 2402bf73ac6SHong Zhang /* GLOBAL subnet[].vStart and vEnd, used by DMNetworkLayoutSetUp() */ 2412bf73ac6SHong Zhang network->subnet[i].vStart = network->NVertices; 2422bf73ac6SHong Zhang network->subnet[i].vEnd = network->subnet[i].vStart + network->subnet[i].Nvtx; /* global vEnd of subnet[i] */ 2432bf73ac6SHong Zhang 244f11a936eSBarry Smith network->nVertices += nvtx; /* include ghost vertices */ 2452bf73ac6SHong Zhang network->NVertices += network->subnet[i].Nvtx; 2462bf73ac6SHong Zhang 2472bf73ac6SHong Zhang /* LOCAL subnet[].eStart and eEnd, used by DMNetworkLayoutSetUp() */ 2482bf73ac6SHong Zhang network->subnet[i].eStart = network->nEdges; 2492bf73ac6SHong Zhang network->subnet[i].eEnd = network->subnet[i].eStart + ne; 2502bf73ac6SHong Zhang network->nEdges += ne; 2512bf73ac6SHong Zhang network->NEdges += network->subnet[i].Nedge; 2522bf73ac6SHong Zhang 2532bf73ac6SHong Zhang ierr = PetscStrcpy(network->subnet[i].name,name);CHKERRQ(ierr); 2542bf73ac6SHong Zhang if (netnum) *netnum = network->nsubnet; 2552bf73ac6SHong Zhang network->nsubnet++; 2562bf73ac6SHong Zhang PetscFunctionReturn(0); 2572bf73ac6SHong Zhang } 2582bf73ac6SHong Zhang 2592bf73ac6SHong Zhang /* 2602bf73ac6SHong Zhang SetUp a single svtx struct. See SVtx defined in dmnetworkimpl.h 2612bf73ac6SHong Zhang Set gidx and type if input v=(net,idx) is a from_vertex; 2622bf73ac6SHong Zhang Get gid, type and index in the svtx array if input v=(net,idx) is a to_vertex. 2632bf73ac6SHong Zhang 2642bf73ac6SHong Zhang Input: Nsvtx, svtx, net, idx, gidx 2652bf73ac6SHong Zhang Output: gidx, svtype, svtx_idx 2662bf73ac6SHong Zhang */ 2672bf73ac6SHong Zhang static PetscErrorCode SVtxSetUp(PetscInt Nsvtx,SVtx *svtx,PetscInt net,PetscInt idx,PetscInt *gidx,SVtxType *svtype,PetscInt *svtx_idx) 2682bf73ac6SHong Zhang { 2692bf73ac6SHong Zhang PetscInt i,j,*svto; 2702bf73ac6SHong Zhang SVtxType vtype; 2712bf73ac6SHong Zhang 2722bf73ac6SHong Zhang PetscFunctionBegin; 2732bf73ac6SHong Zhang if (!Nsvtx) PetscFunctionReturn(0); 2742bf73ac6SHong Zhang 2752bf73ac6SHong Zhang vtype = SVNONE; 2762bf73ac6SHong Zhang for (i=0; i<Nsvtx; i++) { 2772bf73ac6SHong Zhang if (net == svtx[i].sv[0] && idx == svtx[i].sv[1]) { 2782bf73ac6SHong Zhang /* (1) input vertex net.idx is a shared from_vertex, set its global index and output its svtype */ 2792bf73ac6SHong Zhang svtx[i].gidx = *gidx; /* set gidx */ 2802bf73ac6SHong Zhang vtype = SVFROM; 2812bf73ac6SHong Zhang } else { /* loop over svtx[i].n */ 2822bf73ac6SHong Zhang for (j=1; j<svtx[i].n; j++) { 2832bf73ac6SHong Zhang svto = svtx[i].sv + 2*j; 2842bf73ac6SHong Zhang if (net == svto[0] && idx == svto[1]) { 2852bf73ac6SHong Zhang /* input vertex net.idx is a shared to_vertex, output its global index and its svtype */ 2862bf73ac6SHong Zhang *gidx = svtx[i].gidx; /* output gidx for to_vertex */ 2872bf73ac6SHong Zhang vtype = SVTO; 2882bf73ac6SHong Zhang } 2892bf73ac6SHong Zhang } 2902bf73ac6SHong Zhang } 2912bf73ac6SHong Zhang if (vtype != SVNONE) break; 2922bf73ac6SHong Zhang } 2932bf73ac6SHong Zhang if (svtype) *svtype = vtype; 2942bf73ac6SHong Zhang if (svtx_idx) *svtx_idx = i; 2952bf73ac6SHong Zhang PetscFunctionReturn(0); 2962bf73ac6SHong Zhang } 2972bf73ac6SHong Zhang 2982bf73ac6SHong Zhang /* 2992bf73ac6SHong Zhang Add a new shared vertex sv=(net,idx) to table svtas[ita] 3002bf73ac6SHong Zhang */ 3012bf73ac6SHong Zhang static PetscErrorCode TableAddSVtx(PetscTable *svtas,PetscInt ita,PetscInt* tdata,PetscInt *sv_wk,PetscInt *ii,PetscInt *sedgelist,PetscInt k,DM_Network *network,PetscInt **ta2sv) 3022bf73ac6SHong Zhang { 3032bf73ac6SHong Zhang PetscInt net,idx,gidx,i=*ii; 3042bf73ac6SHong Zhang PetscErrorCode ierr; 3052bf73ac6SHong Zhang 3062bf73ac6SHong Zhang PetscFunctionBegin; 3072bf73ac6SHong Zhang net = sv_wk[2*i] = sedgelist[k]; 3082bf73ac6SHong Zhang idx = sv_wk[2*i+1] = sedgelist[k+1]; 3092bf73ac6SHong Zhang gidx = network->subnet[net].vStart + idx; 3102bf73ac6SHong Zhang ierr = PetscTableAdd(svtas[ita],gidx+1,tdata[ita]+1,INSERT_VALUES);CHKERRQ(ierr); 3112bf73ac6SHong Zhang *(ta2sv[ita] + tdata[ita]) = i; /* maps tdata to index of sv_wk; sv_wk keeps (net,idx) info */ 3122bf73ac6SHong Zhang tdata[ita]++; (*ii)++; 3132bf73ac6SHong Zhang PetscFunctionReturn(0); 3142bf73ac6SHong Zhang } 3152bf73ac6SHong Zhang 3162bf73ac6SHong Zhang /* 3172bf73ac6SHong Zhang Create an array of shared vertices. See SVtx and SVtxType in dmnetworkimpl.h 3182bf73ac6SHong Zhang 3192bf73ac6SHong Zhang Input: dm, Nsedgelist, sedgelist 3202bf73ac6SHong Zhang Output: Nsvtx,svtx 3212bf73ac6SHong Zhang 3222bf73ac6SHong Zhang Note: Output svtx is organized as 3232bf73ac6SHong Zhang sv(net[0],idx[0]) --> sv(net[1],idx[1]) 3242bf73ac6SHong Zhang --> sv(net[1],idx[1]) 3252bf73ac6SHong Zhang ... 3262bf73ac6SHong Zhang --> sv(net[n-1],idx[n-1]) 3272bf73ac6SHong Zhang and net[0] < net[1] < ... < net[n-1] 3282bf73ac6SHong Zhang where sv[0] has SVFROM type, sv[i], i>0, has SVTO type. 3292bf73ac6SHong Zhang */ 3302bf73ac6SHong Zhang static PetscErrorCode SVtxCreate(DM dm,PetscInt Nsedgelist,PetscInt *sedgelist,PetscInt *Nsvtx,SVtx **svtx) 3312bf73ac6SHong Zhang { 3322bf73ac6SHong Zhang PetscErrorCode ierr; 3332bf73ac6SHong Zhang SVtx *sedges = NULL; 3342bf73ac6SHong Zhang PetscInt *sv,k,j,nsv,*tdata,**ta2sv; 3352bf73ac6SHong Zhang PetscTable *svtas; 3362bf73ac6SHong Zhang PetscInt gidx,net,idx,i,nta,ita,idx_from,idx_to,n,*sv_wk; 3372bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 3382bf73ac6SHong Zhang PetscTablePosition ppos; 3392bf73ac6SHong Zhang 3402bf73ac6SHong Zhang PetscFunctionBegin; 3412bf73ac6SHong Zhang /* (1) Crete ctables svtas */ 3422bf73ac6SHong Zhang ierr = PetscCalloc4(Nsedgelist,&svtas,Nsedgelist,&tdata,4*Nsedgelist,&sv_wk,2*Nsedgelist,&ta2sv);CHKERRQ(ierr); 3432bf73ac6SHong Zhang 3442bf73ac6SHong Zhang j = 0; /* sedgelist counter */ 3452bf73ac6SHong Zhang k = 0; /* sedgelist vertex counter j = 4*k */ 3462bf73ac6SHong Zhang i = 0; /* sv_wk (vertices added to the ctables) counter */ 3472bf73ac6SHong Zhang nta = 0; /* num of sv tables created */ 3482bf73ac6SHong Zhang 3492bf73ac6SHong Zhang /* for j=0 */ 3502bf73ac6SHong Zhang ierr = PetscTableCreate(2*Nsedgelist,network->NVertices+1,&svtas[nta]);CHKERRQ(ierr); 3512bf73ac6SHong Zhang ierr = PetscMalloc1(2*Nsedgelist,&ta2sv[nta]);CHKERRQ(ierr); 3522bf73ac6SHong Zhang 3532bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,nta,tdata,sv_wk,&i,sedgelist,k,network,ta2sv);CHKERRQ(ierr); 3542bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,nta,tdata,sv_wk,&i,sedgelist,k+2,network,ta2sv);CHKERRQ(ierr); 3552bf73ac6SHong Zhang nta++; k += 4; 3562bf73ac6SHong Zhang 3572bf73ac6SHong Zhang for (j = 1; j < Nsedgelist; j++) { 3582bf73ac6SHong Zhang for (ita = 0; ita < nta; ita++) { 3592bf73ac6SHong Zhang /* vfrom */ 3602bf73ac6SHong Zhang net = sedgelist[k]; idx = sedgelist[k+1]; 3612bf73ac6SHong Zhang gidx = network->subnet[net].vStart + idx; /* global index of the vertex net.idx before merging shared vertices */ 3622bf73ac6SHong Zhang ierr = PetscTableFind(svtas[ita],gidx+1,&idx_from);CHKERRQ(ierr); 3632bf73ac6SHong Zhang 3642bf73ac6SHong Zhang /* vto */ 3652bf73ac6SHong Zhang net = sedgelist[k+2]; idx = sedgelist[k+3]; 3662bf73ac6SHong Zhang gidx = network->subnet[net].vStart + idx; 3672bf73ac6SHong Zhang ierr = PetscTableFind(svtas[ita],gidx+1,&idx_to);CHKERRQ(ierr); 3682bf73ac6SHong Zhang 3692bf73ac6SHong Zhang if (idx_from || idx_to) { /* vfrom or vto is on table svtas[ita] */ 3702bf73ac6SHong Zhang idx_from--; idx_to--; 3712bf73ac6SHong Zhang if (idx_from < 0) { /* vto is on svtas[ita] */ 3722bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,ita,tdata,sv_wk,&i,sedgelist,k,network,ta2sv);CHKERRQ(ierr); 3732bf73ac6SHong Zhang break; 3742bf73ac6SHong Zhang } else if (idx_to < 0) { 3752bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,ita,tdata,sv_wk,&i,sedgelist,k+2,network,ta2sv);CHKERRQ(ierr); 3762bf73ac6SHong Zhang break; 3772bf73ac6SHong Zhang } 3782bf73ac6SHong Zhang } 3792bf73ac6SHong Zhang } 3802bf73ac6SHong Zhang 3812bf73ac6SHong Zhang if (ita == nta) { 3822bf73ac6SHong Zhang ierr = PetscTableCreate(2*Nsedgelist,network->NVertices+1,&svtas[nta]);CHKERRQ(ierr); 3832bf73ac6SHong Zhang ierr = PetscMalloc1(2*Nsedgelist, &ta2sv[nta]);CHKERRQ(ierr); 3842bf73ac6SHong Zhang 3852bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,nta,tdata,sv_wk,&i,sedgelist,k,network,ta2sv);CHKERRQ(ierr); 3862bf73ac6SHong Zhang ierr = TableAddSVtx(svtas,nta,tdata,sv_wk,&i,sedgelist,k+2,network,ta2sv);CHKERRQ(ierr); 3872bf73ac6SHong Zhang nta++; 3882bf73ac6SHong Zhang } 3892bf73ac6SHong Zhang k += 4; 3902bf73ac6SHong Zhang } 3912bf73ac6SHong Zhang 3922bf73ac6SHong Zhang /* (2) Construct sedges from ctable 3932bf73ac6SHong Zhang sedges: edges connect vertex sv[0]=(net[0],idx[0]) to vertices sv[k], k=1,...,n-1; 3944f5c2772SJose E. Roman net[k], k=0, ...,n-1, are in ascending order */ 3952bf73ac6SHong Zhang ierr = PetscMalloc1(nta,&sedges);CHKERRQ(ierr); 3962bf73ac6SHong Zhang for (nsv = 0; nsv < nta; nsv++) { 3974f5c2772SJose E. Roman /* for a single svtx, put shared vertices in ascending order of gidx */ 3984f5c2772SJose E. Roman ierr = PetscTableGetCount(svtas[nsv],&n);CHKERRQ(ierr); 3992bf73ac6SHong Zhang ierr = PetscCalloc1(2*n,&sv);CHKERRQ(ierr); 4002bf73ac6SHong Zhang sedges[nsv].sv = sv; 4012bf73ac6SHong Zhang sedges[nsv].n = n; 4022bf73ac6SHong Zhang sedges[nsv].gidx = -1; /* initialization */ 4032bf73ac6SHong Zhang 4042bf73ac6SHong Zhang ierr = PetscTableGetHeadPosition(svtas[nsv],&ppos);CHKERRQ(ierr); 4054f5c2772SJose E. Roman for (k=0; k<n; k++) { /* gidx is sorted in ascending order */ 4062bf73ac6SHong Zhang ierr = PetscTableGetNext(svtas[nsv],&ppos,&gidx,&i);CHKERRQ(ierr); 4072bf73ac6SHong Zhang gidx--; i--; 4082bf73ac6SHong Zhang 4092bf73ac6SHong Zhang j = ta2sv[nsv][i]; /* maps i to index of sv_wk */ 4102bf73ac6SHong Zhang sv[2*k] = sv_wk[2*j]; 4112bf73ac6SHong Zhang sv[2*k+1] = sv_wk[2*j + 1]; 4122bf73ac6SHong Zhang } 4132bf73ac6SHong Zhang } 4142bf73ac6SHong Zhang 4152bf73ac6SHong Zhang for (j=0; j<nta; j++) { 4162bf73ac6SHong Zhang ierr = PetscTableDestroy(&svtas[j]);CHKERRQ(ierr); 4172bf73ac6SHong Zhang ierr = PetscFree(ta2sv[j]);CHKERRQ(ierr); 4182bf73ac6SHong Zhang } 4192bf73ac6SHong Zhang ierr = PetscFree4(svtas,tdata,sv_wk,ta2sv);CHKERRQ(ierr); 4202bf73ac6SHong Zhang 4212bf73ac6SHong Zhang *Nsvtx = nta; 4222bf73ac6SHong Zhang *svtx = sedges; 4232bf73ac6SHong Zhang PetscFunctionReturn(0); 4242bf73ac6SHong Zhang } 4252bf73ac6SHong Zhang 4262bf73ac6SHong Zhang static PetscErrorCode DMNetworkLayoutSetUp_Coupling(DM dm) 4272bf73ac6SHong Zhang { 4282bf73ac6SHong Zhang PetscErrorCode ierr; 4292bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 430f11a936eSBarry Smith PetscInt i,j,ctr,np,*edges,*subnetvtx,*subnetedge,vStart; 4312bf73ac6SHong Zhang PetscInt k,*vidxlTog,Nsv=0,Nsubnet=network->Nsubnet; 4322bf73ac6SHong Zhang PetscInt *sedgelist=network->sedgelist; 4332bf73ac6SHong Zhang const PetscInt *cone; 4342bf73ac6SHong Zhang MPI_Comm comm; 4352bf73ac6SHong Zhang PetscMPIInt size,rank,*recvcounts=NULL,*displs=NULL; 4362bf73ac6SHong Zhang PetscInt net,idx,gidx,nmerged,e,v,vfrom,vto,*vrange,*eowners,gidx_from,net_from,sv_idx; 4372bf73ac6SHong Zhang SVtxType svtype = SVNONE; 4382bf73ac6SHong Zhang SVtx *svtx=NULL; 4392bf73ac6SHong Zhang PetscSection sectiong; 4402bf73ac6SHong Zhang 4412bf73ac6SHong Zhang PetscFunctionBegin; 4422bf73ac6SHong Zhang /* This implementation requires user input each subnet by a single processor, thus subnet[net].nvtx=subnet[net].Nvtx */ 4432bf73ac6SHong Zhang for (net=0; net<Nsubnet; net++) { 4442bf73ac6SHong 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); 4452bf73ac6SHong Zhang } 4462bf73ac6SHong Zhang 4472bf73ac6SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 44855b25c41SPierre Jolivet ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 44955b25c41SPierre Jolivet ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 4502bf73ac6SHong Zhang 4512bf73ac6SHong Zhang /* (1) Create svtx[] from sedgelist */ 4522bf73ac6SHong Zhang /* -------------------------------- */ 4532bf73ac6SHong Zhang /* Nsv: global number of SVtx; svtx: shared vertices, see SVtx in dmnetworkimpl.h */ 4542bf73ac6SHong Zhang ierr = SVtxCreate(dm,network->Nsvtx,sedgelist,&Nsv,&svtx);CHKERRQ(ierr); 4552bf73ac6SHong Zhang 4562bf73ac6SHong Zhang /* (2) Setup svtx; Shared vto vertices are merged to their vfrom vertex with same global vetex index (gidx) */ 4572bf73ac6SHong Zhang /* -------------------------------------------------------------------------------------------------------- */ 4582bf73ac6SHong Zhang /* (2.1) compute vrage[rank]: global index of 1st local vertex in proc[rank] */ 4592bf73ac6SHong Zhang ierr = PetscMalloc3(size+1,&vrange,size,&displs,size,&recvcounts);CHKERRQ(ierr); 4602bf73ac6SHong Zhang for (i=0; i<size; i++) {displs[i] = i; recvcounts[i] = 1;} 4612bf73ac6SHong Zhang 4622bf73ac6SHong Zhang vrange[0] = 0; 4632bf73ac6SHong Zhang ierr = MPI_Allgatherv(&network->nVertices,1,MPIU_INT,vrange+1,recvcounts,displs,MPIU_INT,comm);CHKERRMPI(ierr); 4642bf73ac6SHong Zhang for (i=2; i<size+1; i++) { 4652bf73ac6SHong Zhang vrange[i] += vrange[i-1]; 4662bf73ac6SHong Zhang } 4672bf73ac6SHong Zhang 4682bf73ac6SHong Zhang /* (2.2) Create vidxlTog: maps UN-MERGED local vertex index i to global index gidx (plex, excluding ghost vertices) */ 4692bf73ac6SHong Zhang ierr = PetscMalloc1(network->nVertices,&vidxlTog);CHKERRQ(ierr); 4702bf73ac6SHong Zhang i = 0; gidx = 0; 4712bf73ac6SHong Zhang nmerged = 0; /* local num of merged vertices */ 4722bf73ac6SHong Zhang network->nsvtx = 0; 4732bf73ac6SHong Zhang for (net=0; net<Nsubnet; net++) { 4742bf73ac6SHong Zhang for (idx=0; idx<network->subnet[net].Nvtx; idx++) { 4752bf73ac6SHong Zhang gidx_from = gidx; 4762bf73ac6SHong Zhang sv_idx = -1; 4772bf73ac6SHong Zhang 4782bf73ac6SHong Zhang ierr = SVtxSetUp(Nsv,svtx,net,idx,&gidx_from,&svtype,&sv_idx);CHKERRQ(ierr); 4792bf73ac6SHong Zhang if (svtype == SVTO) { 4802bf73ac6SHong Zhang if (network->subnet[net].nvtx) {/* this proc owns sv_to */ 4812bf73ac6SHong Zhang net_from = svtx[sv_idx].sv[0]; /* subnet num of its shared vertex */ 4822bf73ac6SHong Zhang if (network->subnet[net_from].nvtx == 0) { 4832bf73ac6SHong Zhang /* this proc does not own v_from, thus a new local coupling vertex */ 4842bf73ac6SHong Zhang network->nsvtx++; 4852bf73ac6SHong Zhang } 4862bf73ac6SHong Zhang vidxlTog[i++] = gidx_from; 4872bf73ac6SHong Zhang nmerged++; /* a coupling vertex -- merged */ 4882bf73ac6SHong Zhang } 4892bf73ac6SHong Zhang } else { 4902bf73ac6SHong Zhang if (svtype == SVFROM) { 4912bf73ac6SHong Zhang if (network->subnet[net].nvtx) { 4922bf73ac6SHong Zhang /* this proc owns this v_from, a new local coupling vertex */ 4932bf73ac6SHong Zhang network->nsvtx++; 4942bf73ac6SHong Zhang } 4952bf73ac6SHong Zhang } 4962bf73ac6SHong Zhang if (network->subnet[net].nvtx) vidxlTog[i++] = gidx; 4972bf73ac6SHong Zhang gidx++; 4982bf73ac6SHong Zhang } 4992bf73ac6SHong Zhang } 5002bf73ac6SHong Zhang } 5012bf73ac6SHong Zhang #if defined(PETSC_USE_DEBUG) 5022bf73ac6SHong Zhang if (i != network->nVertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"%D != %D nVertices",i,network->nVertices); 5032bf73ac6SHong Zhang #endif 5042bf73ac6SHong Zhang 5052bf73ac6SHong Zhang /* (2.3) Setup svtable for querry shared vertices */ 5062bf73ac6SHong Zhang for (v=0; v<Nsv; v++) { 5072bf73ac6SHong Zhang gidx = svtx[v].gidx; 5082bf73ac6SHong Zhang ierr = PetscTableAdd(network->svtable,gidx+1,v+1,INSERT_VALUES);CHKERRQ(ierr); 5092bf73ac6SHong Zhang } 5102bf73ac6SHong Zhang 5112bf73ac6SHong Zhang /* (2.4) Shared vertices in the subnetworks are merged, update global NVertices: np = sum(local nmerged) */ 5122bf73ac6SHong Zhang ierr = MPI_Allreduce(&nmerged,&np,1,MPIU_INT,MPI_SUM,comm);CHKERRMPI(ierr); 5132bf73ac6SHong Zhang network->NVertices -= np; 5142bf73ac6SHong Zhang 5152bf73ac6SHong Zhang ierr = PetscCalloc1(2*network->nEdges,&edges);CHKERRQ(ierr); 5162bf73ac6SHong Zhang 5172bf73ac6SHong Zhang ctr = 0; 5182bf73ac6SHong Zhang for (net=0; net<Nsubnet; net++) { 5192bf73ac6SHong Zhang for (j = 0; j < network->subnet[net].nedge; j++) { 5202bf73ac6SHong Zhang /* vfrom: */ 5212bf73ac6SHong Zhang i = network->subnet[net].edgelist[2*j] + (network->subnet[net].vStart - vrange[rank]); 5222bf73ac6SHong Zhang edges[2*ctr] = vidxlTog[i]; 5232bf73ac6SHong Zhang 5242bf73ac6SHong Zhang /* vto */ 5252bf73ac6SHong Zhang i = network->subnet[net].edgelist[2*j+1] + (network->subnet[net].vStart - vrange[rank]); 5262bf73ac6SHong Zhang edges[2*ctr+1] = vidxlTog[i]; 5272bf73ac6SHong Zhang ctr++; 5282bf73ac6SHong Zhang } 5292bf73ac6SHong Zhang } 5302bf73ac6SHong Zhang ierr = PetscFree3(vrange,displs,recvcounts);CHKERRQ(ierr); 5312bf73ac6SHong Zhang ierr = PetscFree(vidxlTog);CHKERRQ(ierr); 5322bf73ac6SHong Zhang 5332bf73ac6SHong Zhang /* (3) Create network->plex */ 5342bf73ac6SHong Zhang ierr = DMCreate(comm,&network->plex);CHKERRQ(ierr); 5352bf73ac6SHong Zhang ierr = DMSetType(network->plex,DMPLEX);CHKERRQ(ierr); 5362bf73ac6SHong Zhang ierr = DMSetDimension(network->plex,1);CHKERRQ(ierr); 5372bf73ac6SHong Zhang if (size == 1) { 5382bf73ac6SHong Zhang ierr = DMPlexBuildFromCellList(network->plex,network->nEdges,network->nVertices-nmerged,2,edges);CHKERRQ(ierr); 5392bf73ac6SHong Zhang } else { 5402bf73ac6SHong Zhang ierr = DMPlexBuildFromCellListParallel(network->plex,network->nEdges,network->nVertices-nmerged,PETSC_DECIDE,2,edges,NULL);CHKERRQ(ierr); 5412bf73ac6SHong Zhang } 5422bf73ac6SHong Zhang 5432bf73ac6SHong Zhang ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr); 5442bf73ac6SHong Zhang ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr); 5452bf73ac6SHong Zhang ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr); 5462bf73ac6SHong Zhang vStart = network->vStart; 5472bf73ac6SHong Zhang 5482bf73ac6SHong Zhang ierr = PetscSectionCreate(comm,&network->DataSection);CHKERRQ(ierr); 5492bf73ac6SHong Zhang ierr = PetscSectionCreate(comm,&network->DofSection);CHKERRQ(ierr); 5502bf73ac6SHong Zhang ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr); 5512bf73ac6SHong Zhang ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr); 5522bf73ac6SHong Zhang 5532bf73ac6SHong Zhang np = network->pEnd - network->pStart; 5542bf73ac6SHong Zhang ierr = PetscCalloc2(np,&network->header,np,&network->cvalue);CHKERRQ(ierr); 55554dfd506SHong Zhang for (i=0; i<np; i++) { 55654dfd506SHong Zhang network->header[i].maxcomps = 1; 55754dfd506SHong Zhang ierr = SetUpNetworkHeaderComponentValue(dm,&network->header[i],&network->cvalue[i]);CHKERRQ(ierr); 55854dfd506SHong Zhang } 5592bf73ac6SHong Zhang 560f11a936eSBarry Smith /* (4) Create edge and vertex arrays for the subnetworks */ 561f11a936eSBarry Smith ierr = PetscCalloc2(network->nEdges,&subnetedge,network->nVertices+network->nsvtx,&subnetvtx);CHKERRQ(ierr); /* Maps local edge/vertex to local subnetwork's edge/vertex */ 562f11a936eSBarry Smith network->subnetedge = subnetedge; 563f11a936eSBarry Smith network->subnetvtx = subnetvtx; 5642bf73ac6SHong Zhang for (j=0; j < Nsubnet; j++) { 565f11a936eSBarry Smith network->subnet[j].edges = subnetedge; 566f11a936eSBarry Smith subnetedge += network->subnet[j].nedge; 567f11a936eSBarry Smith 5682bf73ac6SHong Zhang network->subnet[j].vertices = subnetvtx; 5692bf73ac6SHong Zhang subnetvtx += network->subnet[j].nvtx; 5702bf73ac6SHong Zhang } 5712bf73ac6SHong Zhang network->svertices = subnetvtx; 5722bf73ac6SHong Zhang 5732bf73ac6SHong Zhang /* Get edge ownership */ 574f11a936eSBarry Smith ierr = PetscMalloc1(size+1,&eowners);CHKERRQ(ierr); 5752bf73ac6SHong Zhang np = network->eEnd - network->eStart; /* num of local edges */ 5762bf73ac6SHong Zhang ierr = MPI_Allgather(&np,1,MPIU_INT,eowners+1,1,MPIU_INT,comm);CHKERRMPI(ierr); 5772bf73ac6SHong Zhang eowners[0] = 0; 5782bf73ac6SHong Zhang for (i=2; i<=size; i++) eowners[i] += eowners[i-1]; 5792bf73ac6SHong Zhang 580f11a936eSBarry Smith /* Setup edge and vertex arrays for subnetworks */ 5812bf73ac6SHong Zhang e = 0; 5822bf73ac6SHong Zhang for (i=0; i < Nsubnet; i++) { 583f11a936eSBarry Smith ctr = 0; 5842bf73ac6SHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 5852bf73ac6SHong Zhang /* edge e */ 5862bf73ac6SHong Zhang network->header[e].index = e + eowners[rank]; /* Global edge index */ 5872bf73ac6SHong Zhang network->header[e].subnetid = i; /* Subnetwork id */ 5882bf73ac6SHong Zhang network->subnet[i].edges[j] = e; 5892bf73ac6SHong Zhang network->header[e].ndata = 0; 5902bf73ac6SHong Zhang network->header[e].offset[0] = 0; 5912bf73ac6SHong Zhang network->header[e].offsetvarrel[0] = 0; 59254dfd506SHong Zhang ierr = PetscSectionAddDof(network->DataSection,e,network->header[e].hsize);CHKERRQ(ierr); 5932bf73ac6SHong Zhang 5942bf73ac6SHong Zhang /* connected vertices */ 5952bf73ac6SHong Zhang ierr = DMPlexGetCone(network->plex,e,&cone);CHKERRQ(ierr); 5962bf73ac6SHong Zhang 5972bf73ac6SHong Zhang /* vertex cone[0] */ 598f11a936eSBarry Smith v = cone[0]; 599f11a936eSBarry Smith network->header[v].index = edges[2*e]; /* Global vertex index */ 600f11a936eSBarry Smith network->header[v].subnetid = i; /* Subnetwork id */ 601f11a936eSBarry Smith vfrom = network->subnet[i].edgelist[2*ctr]; 602f11a936eSBarry Smith network->subnet[i].vertices[vfrom] = v; /* user's subnet[].dix = petsc's v */ 6032bf73ac6SHong Zhang 6042bf73ac6SHong Zhang /* vertex cone[1] */ 605f11a936eSBarry Smith v = cone[1]; 606f11a936eSBarry Smith network->header[v].index = edges[2*e+1]; /* Global vertex index */ 607f11a936eSBarry Smith network->header[v].subnetid = i; 608f11a936eSBarry Smith vto = network->subnet[i].edgelist[2*ctr+1]; 609f11a936eSBarry Smith network->subnet[i].vertices[vto]= v; 6102bf73ac6SHong Zhang 611f11a936eSBarry Smith e++; ctr++; 6122bf73ac6SHong Zhang } 6132bf73ac6SHong Zhang } 614f11a936eSBarry Smith ierr = PetscFree(eowners);CHKERRQ(ierr); 615f11a936eSBarry Smith ierr = PetscFree(edges);CHKERRQ(ierr); 6162bf73ac6SHong Zhang 6172bf73ac6SHong Zhang /* Set vertex array for the subnetworks */ 6182bf73ac6SHong Zhang k = 0; 6192bf73ac6SHong Zhang for (v=vStart; v<network->vEnd; v++) { /* local vertices, including ghosts */ 6202bf73ac6SHong Zhang network->header[v].ndata = 0; 6212bf73ac6SHong Zhang network->header[v].offset[0] = 0; 6222bf73ac6SHong Zhang network->header[v].offsetvarrel[0] = 0; 62354dfd506SHong Zhang ierr = PetscSectionAddDof(network->DataSection,v,network->header[v].hsize);CHKERRQ(ierr); 6242bf73ac6SHong Zhang 6252bf73ac6SHong Zhang /* shared vertex */ 626f11a936eSBarry Smith ierr = PetscTableFind(network->svtable,network->header[v].index+1,&i);CHKERRQ(ierr); 6272bf73ac6SHong Zhang if (i) network->svertices[k++] = v; 6282bf73ac6SHong Zhang } 6292bf73ac6SHong Zhang #if defined(PETSC_USE_DEBUG) 6302bf73ac6SHong Zhang if (k != network->nsvtx) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"k %D != %D nsvtx",k,network->nsvtx); 6312bf73ac6SHong Zhang #endif 6322bf73ac6SHong Zhang 6332bf73ac6SHong Zhang network->svtx = svtx; 6342bf73ac6SHong Zhang network->Nsvtx = Nsv; 6352bf73ac6SHong Zhang ierr = PetscFree(sedgelist);CHKERRQ(ierr); 6362bf73ac6SHong Zhang 6372bf73ac6SHong Zhang /* Create a global section to be used by DMNetworkIsGhostVertex() which is a non-collective routine */ 638f11a936eSBarry Smith /* see snes_tutorials_network-ex1_4 */ 6392bf73ac6SHong Zhang ierr = DMGetGlobalSection(network->plex,§iong);CHKERRQ(ierr); 6405f2c45f1SShri Abhyankar PetscFunctionReturn(0); 6415f2c45f1SShri Abhyankar } 6425f2c45f1SShri Abhyankar 6435f2c45f1SShri Abhyankar /*@ 6445f2c45f1SShri Abhyankar DMNetworkLayoutSetUp - Sets up the bare layout (graph) for the network 6455f2c45f1SShri Abhyankar 646d083f849SBarry Smith Collective on dm 6475f2c45f1SShri Abhyankar 6487a7aea1fSJed Brown Input Parameters: 649f11a936eSBarry Smith . dm - the dmnetwork object 6505f2c45f1SShri Abhyankar 6515f2c45f1SShri Abhyankar Notes: 6525f2c45f1SShri Abhyankar This routine should be called after the network sizes and edgelists have been provided. It creates 6535f2c45f1SShri Abhyankar the bare layout of the network and sets up the network to begin insertion of components. 6545f2c45f1SShri Abhyankar 6555f2c45f1SShri Abhyankar All the components should be registered before calling this routine. 6565f2c45f1SShri Abhyankar 65797bb938eSShri Abhyankar Level: beginner 6585f2c45f1SShri Abhyankar 6592bf73ac6SHong Zhang .seealso: DMNetworkSetNumSubNetworks(), DMNetworkAddSubnetwork() 6605f2c45f1SShri Abhyankar @*/ 6615f2c45f1SShri Abhyankar PetscErrorCode DMNetworkLayoutSetUp(DM dm) 6625f2c45f1SShri Abhyankar { 6635f2c45f1SShri Abhyankar PetscErrorCode ierr; 6645f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 665f11a936eSBarry Smith PetscInt i,j,ctr,Nsubnet=network->Nsubnet,*eowners,np,*edges,*subnetvtx,*subnetedge,e,v,vfrom,vto; 666caf410d2SHong Zhang const PetscInt *cone; 667caf410d2SHong Zhang MPI_Comm comm; 668caf410d2SHong Zhang PetscMPIInt size,rank; 6696500d4abSHong Zhang 6706500d4abSHong Zhang PetscFunctionBegin; 6712bf73ac6SHong Zhang if (network->nsubnet != network->Nsubnet) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Must call DMNetworkAddSubnetwork() %D times",network->Nsubnet); 6722bf73ac6SHong Zhang 6732bf73ac6SHong Zhang /* Create svtable for querry shared vertices */ 6742bf73ac6SHong Zhang ierr = PetscTableCreate(network->Nsvtx,network->NVertices+1,&network->svtable);CHKERRQ(ierr); 6752bf73ac6SHong Zhang 6762bf73ac6SHong Zhang if (network->Nsvtx) { 6772bf73ac6SHong Zhang ierr = DMNetworkLayoutSetUp_Coupling(dm);CHKERRQ(ierr); 6782bf73ac6SHong Zhang PetscFunctionReturn(0); 6792bf73ac6SHong Zhang } 6802bf73ac6SHong Zhang 681caf410d2SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 682ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 683ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 6846500d4abSHong Zhang 685f11a936eSBarry Smith /* Create LOCAL edgelist in global vertex ordering for the network by concatenating local input edgelists of the subnetworks */ 6868e71b177SVaclav Hapla ierr = PetscCalloc1(2*network->nEdges,&edges);CHKERRQ(ierr); 687caf410d2SHong Zhang ctr = 0; 6882bf73ac6SHong Zhang for (i=0; i < Nsubnet; i++) { 6896500d4abSHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 690ba38b151SHong Zhang edges[2*ctr] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j]; 691ba38b151SHong Zhang edges[2*ctr+1] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j+1]; 6926500d4abSHong Zhang ctr++; 6936500d4abSHong Zhang } 6946500d4abSHong Zhang } 6957765340cSHong Zhang 6962bf73ac6SHong Zhang /* Create network->plex; One dimensional network, numCorners=2 */ 6978e71b177SVaclav Hapla ierr = DMCreate(comm,&network->plex);CHKERRQ(ierr); 6988e71b177SVaclav Hapla ierr = DMSetType(network->plex,DMPLEX);CHKERRQ(ierr); 6992bf73ac6SHong Zhang ierr = DMSetDimension(network->plex,1);CHKERRQ(ierr); 700caf410d2SHong Zhang if (size == 1) { 7012bf73ac6SHong Zhang ierr = DMPlexBuildFromCellList(network->plex,network->nEdges,network->nVertices,2,edges);CHKERRQ(ierr); 702caf410d2SHong Zhang } else { 7032bf73ac6SHong Zhang ierr = DMPlexBuildFromCellListParallel(network->plex,network->nEdges,network->nVertices,PETSC_DECIDE,2,edges,NULL);CHKERRQ(ierr); 704acdb140fSBarry Smith } 7056500d4abSHong Zhang 7066500d4abSHong Zhang ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr); 7076500d4abSHong Zhang ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr); 7086500d4abSHong Zhang ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr); 7096500d4abSHong Zhang 710caf410d2SHong Zhang ierr = PetscSectionCreate(comm,&network->DataSection);CHKERRQ(ierr); 711caf410d2SHong Zhang ierr = PetscSectionCreate(comm,&network->DofSection);CHKERRQ(ierr); 7126500d4abSHong Zhang ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr); 7136500d4abSHong Zhang ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr); 7146500d4abSHong Zhang 715caf410d2SHong Zhang np = network->pEnd - network->pStart; 716caf410d2SHong Zhang ierr = PetscCalloc2(np,&network->header,np,&network->cvalue);CHKERRQ(ierr); 71754dfd506SHong Zhang for (i=0; i < np; i++) { 71854dfd506SHong Zhang network->header[i].maxcomps = 1; 71954dfd506SHong Zhang ierr = SetUpNetworkHeaderComponentValue(dm,&network->header[i],&network->cvalue[i]);CHKERRQ(ierr); 72054dfd506SHong Zhang } 721caf410d2SHong Zhang 722f11a936eSBarry Smith /* Create edge and vertex arrays for the subnetworks 723f11a936eSBarry Smith This implementation assumes that DMNetwork reads 724f11a936eSBarry Smith (1) a single subnetwork in parallel; or 725f11a936eSBarry Smith (2) n subnetworks using n processors, one subnetwork/processor. 726f11a936eSBarry Smith */ 727f11a936eSBarry Smith ierr = PetscCalloc2(network->nEdges,&subnetedge,network->nVertices,&subnetvtx);CHKERRQ(ierr); /* Maps local edge/vertex to local subnetwork's edge/vertex */ 728f11a936eSBarry Smith 729f11a936eSBarry Smith network->subnetedge = subnetedge; 730f11a936eSBarry Smith network->subnetvtx = subnetvtx; 7312bf73ac6SHong Zhang for (j=0; j < network->Nsubnet; j++) { 732f11a936eSBarry Smith network->subnet[j].edges = subnetedge; 733f11a936eSBarry Smith subnetedge += network->subnet[j].nedge; 734f11a936eSBarry Smith 735f11a936eSBarry Smith network->subnet[j].vertices = subnetvtx; 736f11a936eSBarry Smith subnetvtx += network->subnet[j].nvtx; 7376500d4abSHong Zhang } 738caf410d2SHong Zhang 739caf410d2SHong Zhang /* Get edge ownership */ 7402bf73ac6SHong Zhang ierr = PetscMalloc1(size+1,&eowners);CHKERRQ(ierr); 741caf410d2SHong Zhang np = network->eEnd - network->eStart; 742ffc4695bSBarry Smith ierr = MPI_Allgather(&np,1,MPIU_INT,eowners+1,1,MPIU_INT,comm);CHKERRMPI(ierr); 743caf410d2SHong Zhang eowners[0] = 0; 744caf410d2SHong Zhang for (i=2; i<=size; i++) eowners[i] += eowners[i-1]; 745caf410d2SHong Zhang 7462bf73ac6SHong Zhang /* Setup edge and vertex arrays for subnetworks */ 7472bf73ac6SHong Zhang e = 0; 7482bf73ac6SHong Zhang for (i=0; i < Nsubnet; i++) { 749f11a936eSBarry Smith ctr = 0; 7502bf73ac6SHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 7512bf73ac6SHong Zhang /* edge e */ 7522bf73ac6SHong Zhang network->header[e].index = e + eowners[rank]; /* Global edge index */ 7532bf73ac6SHong Zhang network->header[e].subnetid = i; 7542bf73ac6SHong Zhang network->subnet[i].edges[j] = e; 755caf410d2SHong Zhang 7562bf73ac6SHong Zhang network->header[e].ndata = 0; 7572bf73ac6SHong Zhang network->header[e].offset[0] = 0; 7582bf73ac6SHong Zhang network->header[e].offsetvarrel[0] = 0; 75954dfd506SHong Zhang ierr = PetscSectionAddDof(network->DataSection,e,network->header[e].hsize);CHKERRQ(ierr); 7602bf73ac6SHong Zhang 7612bf73ac6SHong Zhang /* connected vertices */ 7622bf73ac6SHong Zhang ierr = DMPlexGetCone(network->plex,e,&cone);CHKERRQ(ierr); 7632bf73ac6SHong Zhang 7642bf73ac6SHong Zhang /* vertex cone[0] */ 765f11a936eSBarry Smith v = cone[0]; 766f11a936eSBarry Smith network->header[v].index = edges[2*e]; /* Global vertex index */ 767f11a936eSBarry Smith network->header[v].subnetid = i; /* Subnetwork id */ 768f11a936eSBarry Smith if (Nsubnet == 1) { 769f11a936eSBarry Smith network->subnet[i].vertices[v - network->vStart] = v; /* user's subnet[].idx = petsc's v */ 770f11a936eSBarry Smith } else { 771f11a936eSBarry Smith vfrom = network->subnet[i].edgelist[2*ctr]; /* =subnet[i].idx, Global index! */ 772f11a936eSBarry Smith network->subnet[i].vertices[vfrom] = v; /* user's subnet[].dix = petsc's v */ 773f11a936eSBarry Smith } 7742bf73ac6SHong Zhang 7752bf73ac6SHong Zhang /* vertex cone[1] */ 776f11a936eSBarry Smith v = cone[1]; 777f11a936eSBarry Smith network->header[v].index = edges[2*e+1]; /* Global vertex index */ 778f11a936eSBarry Smith network->header[v].subnetid = i; /* Subnetwork id */ 779f11a936eSBarry Smith if (Nsubnet == 1) { 780f11a936eSBarry Smith network->subnet[i].vertices[v - network->vStart] = v; /* user's subnet[].idx = petsc's v */ 781f11a936eSBarry Smith } else { 782f11a936eSBarry Smith vto = network->subnet[i].edgelist[2*ctr+1]; /* =subnet[i].idx, Global index! */ 783f11a936eSBarry Smith network->subnet[i].vertices[vto] = v; /* user's subnet[].dix = petsc's v */ 784f11a936eSBarry Smith } 7852bf73ac6SHong Zhang 786f11a936eSBarry Smith e++; ctr++; 7876500d4abSHong Zhang } 7886500d4abSHong Zhang } 7892bf73ac6SHong Zhang ierr = PetscFree(eowners);CHKERRQ(ierr); 790f11a936eSBarry Smith ierr = PetscFree(edges);CHKERRQ(ierr); /* local edge list with global idx used by DMPlexBuildFromCellList() */ 791caf410d2SHong Zhang 7922bf73ac6SHong Zhang for (v = network->vStart; v < network->vEnd; v++) { 7932bf73ac6SHong Zhang network->header[v].ndata = 0; 7942bf73ac6SHong Zhang network->header[v].offset[0] = 0; 7952bf73ac6SHong Zhang network->header[v].offsetvarrel[0] = 0; 79654dfd506SHong Zhang ierr = PetscSectionAddDof(network->DataSection,v,network->header[e].hsize);CHKERRQ(ierr); 7976500d4abSHong Zhang } 7985f2c45f1SShri Abhyankar PetscFunctionReturn(0); 7995f2c45f1SShri Abhyankar } 8005f2c45f1SShri Abhyankar 80194ef8ddeSSatish Balay /*@C 8022bf73ac6SHong Zhang DMNetworkGetSubnetwork - Returns the information about a requested subnetwork 8032bf73ac6SHong Zhang 8042bf73ac6SHong Zhang Not collective 8052727e31bSShri Abhyankar 8067a7aea1fSJed Brown Input Parameters: 807caf410d2SHong Zhang + dm - the DM object 8082bf73ac6SHong Zhang - netnum - the global index of the subnetwork 8092727e31bSShri Abhyankar 8107a7aea1fSJed Brown Output Parameters: 8112727e31bSShri Abhyankar + nv - number of vertices (local) 8122727e31bSShri Abhyankar . ne - number of edges (local) 8132bf73ac6SHong Zhang . vtx - local vertices of the subnetwork 8142bf73ac6SHong Zhang - edge - local edges of the subnetwork 8152727e31bSShri Abhyankar 8162727e31bSShri Abhyankar Notes: 8172727e31bSShri Abhyankar Cannot call this routine before DMNetworkLayoutSetup() 8182727e31bSShri Abhyankar 81906dd6b0eSSatish Balay Level: intermediate 82006dd6b0eSSatish Balay 8212bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkAddSubnetwork(), DMNetworkLayoutSetUp() 8222727e31bSShri Abhyankar @*/ 8232bf73ac6SHong Zhang PetscErrorCode DMNetworkGetSubnetwork(DM dm,PetscInt netnum,PetscInt *nv,PetscInt *ne,const PetscInt **vtx,const PetscInt **edge) 8242727e31bSShri Abhyankar { 825caf410d2SHong Zhang DM_Network *network = (DM_Network*)dm->data; 8262727e31bSShri Abhyankar 8272727e31bSShri Abhyankar PetscFunctionBegin; 8282bf73ac6SHong 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); 8292bf73ac6SHong Zhang if (nv) *nv = network->subnet[netnum].nvtx; 8302bf73ac6SHong Zhang if (ne) *ne = network->subnet[netnum].nedge; 8312bf73ac6SHong Zhang if (vtx) *vtx = network->subnet[netnum].vertices; 8322bf73ac6SHong Zhang if (edge) *edge = network->subnet[netnum].edges; 8332bf73ac6SHong Zhang PetscFunctionReturn(0); 8342bf73ac6SHong Zhang } 8352bf73ac6SHong Zhang 8362bf73ac6SHong Zhang /*@ 8372bf73ac6SHong Zhang DMNetworkAddSharedVertices - Add shared vertices that connect two given subnetworks 8382bf73ac6SHong Zhang 8392bf73ac6SHong Zhang Collective on dm 8402bf73ac6SHong Zhang 8412bf73ac6SHong Zhang Input Parameters: 8422bf73ac6SHong Zhang + dm - the dm object 8432bf73ac6SHong Zhang . anetnum - first subnetwork global numbering returned by DMNetworkAddSubnetwork() 8442bf73ac6SHong Zhang . bnetnum - second subnetwork global numbering returned by DMNetworkAddSubnetwork() 8452bf73ac6SHong Zhang . nsvtx - number of vertices that are shared by the two subnetworks 8462bf73ac6SHong Zhang . asvtx - vertex index in the first subnetwork 8472bf73ac6SHong Zhang - bsvtx - vertex index in the second subnetwork 8482bf73ac6SHong Zhang 8492bf73ac6SHong Zhang Level: beginner 8502bf73ac6SHong Zhang 8512bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkAddSubnetwork(), DMNetworkGetSharedVertices() 8522bf73ac6SHong Zhang @*/ 8532bf73ac6SHong Zhang PetscErrorCode DMNetworkAddSharedVertices(DM dm,PetscInt anetnum,PetscInt bnetnum,PetscInt nsvtx,PetscInt asvtx[],PetscInt bsvtx[]) 8542bf73ac6SHong Zhang { 8552bf73ac6SHong Zhang PetscErrorCode ierr; 8562bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 8572bf73ac6SHong Zhang PetscInt i,nsubnet = network->Nsubnet,*sedgelist,Nsvtx=network->Nsvtx; 8582bf73ac6SHong Zhang 8592bf73ac6SHong Zhang PetscFunctionBegin; 8602bf73ac6SHong Zhang if (anetnum == bnetnum) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Subnetworks must have different netnum"); 8612bf73ac6SHong Zhang if (anetnum < 0 || bnetnum < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"netnum cannot be negative"); 8622bf73ac6SHong Zhang if (!Nsvtx) { 8632bf73ac6SHong Zhang /* allocate network->sedgelist to hold at most 2*nsubnet pairs of shared vertices */ 8642bf73ac6SHong Zhang ierr = PetscMalloc1(2*4*nsubnet,&network->sedgelist);CHKERRQ(ierr); 8652bf73ac6SHong Zhang } 8662bf73ac6SHong Zhang 8672bf73ac6SHong Zhang sedgelist = network->sedgelist; 8682bf73ac6SHong Zhang for (i=0; i<nsvtx; i++) { 8692bf73ac6SHong Zhang sedgelist[4*Nsvtx] = anetnum; sedgelist[4*Nsvtx+1] = asvtx[i]; 8702bf73ac6SHong Zhang sedgelist[4*Nsvtx+2] = bnetnum; sedgelist[4*Nsvtx+3] = bsvtx[i]; 8712bf73ac6SHong Zhang Nsvtx++; 8722bf73ac6SHong Zhang } 8732bf73ac6SHong Zhang if (Nsvtx > 2*nsubnet) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"allocate more space for coupling edgelist"); 8742bf73ac6SHong Zhang network->Nsvtx = Nsvtx; 8752727e31bSShri Abhyankar PetscFunctionReturn(0); 8762727e31bSShri Abhyankar } 8772727e31bSShri Abhyankar 8782727e31bSShri Abhyankar /*@C 8792bf73ac6SHong Zhang DMNetworkGetSharedVertices - Returns the info for the shared vertices 8802bf73ac6SHong Zhang 8812bf73ac6SHong Zhang Not collective 882caf410d2SHong Zhang 883f899ff85SJose E. Roman Input Parameter: 8842bf73ac6SHong Zhang . dm - the DM object 885caf410d2SHong Zhang 8867a7aea1fSJed Brown Output Parameters: 8872bf73ac6SHong Zhang + nsv - number of local shared vertices 8882bf73ac6SHong Zhang - svtx - local shared vertices 889caf410d2SHong Zhang 890caf410d2SHong Zhang Notes: 891caf410d2SHong Zhang Cannot call this routine before DMNetworkLayoutSetup() 892caf410d2SHong Zhang 893caf410d2SHong Zhang Level: intermediate 894caf410d2SHong Zhang 8952bf73ac6SHong Zhang .seealso: DMNetworkGetSubnetwork(), DMNetworkLayoutSetUp(), DMNetworkAddSharedVertices() 896caf410d2SHong Zhang @*/ 8972bf73ac6SHong Zhang PetscErrorCode DMNetworkGetSharedVertices(DM dm,PetscInt *nsv,const PetscInt **svtx) 898caf410d2SHong Zhang { 899caf410d2SHong Zhang DM_Network *net = (DM_Network*)dm->data; 900caf410d2SHong Zhang 901caf410d2SHong Zhang PetscFunctionBegin; 9022bf73ac6SHong Zhang if (net->Nsvtx) { 9032bf73ac6SHong Zhang *nsv = net->nsvtx; 9042bf73ac6SHong Zhang *svtx = net->svertices; 90572c3e9f7SHong Zhang } else { 9062bf73ac6SHong Zhang *nsv = 0; 9072bf73ac6SHong Zhang *svtx = NULL; 90872c3e9f7SHong Zhang } 909caf410d2SHong Zhang PetscFunctionReturn(0); 910caf410d2SHong Zhang } 911caf410d2SHong Zhang 912caf410d2SHong Zhang /*@C 9135f2c45f1SShri Abhyankar DMNetworkRegisterComponent - Registers the network component 9145f2c45f1SShri Abhyankar 915d083f849SBarry Smith Logically collective on dm 9165f2c45f1SShri Abhyankar 9177a7aea1fSJed Brown Input Parameters: 9185f2c45f1SShri Abhyankar + dm - the network object 9195f2c45f1SShri Abhyankar . name - the component name 9205f2c45f1SShri Abhyankar - size - the storage size in bytes for this component data 9215f2c45f1SShri Abhyankar 9227a7aea1fSJed Brown Output Parameters: 9235f2c45f1SShri Abhyankar . key - an integer key that defines the component 9245f2c45f1SShri Abhyankar 9255f2c45f1SShri Abhyankar Notes 9265f2c45f1SShri Abhyankar This routine should be called by all processors before calling DMNetworkLayoutSetup(). 9275f2c45f1SShri Abhyankar 92897bb938eSShri Abhyankar Level: beginner 9295f2c45f1SShri Abhyankar 9302bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkLayoutSetUp() 9315f2c45f1SShri Abhyankar @*/ 932caf410d2SHong Zhang PetscErrorCode DMNetworkRegisterComponent(DM dm,const char *name,size_t size,PetscInt *key) 9335f2c45f1SShri Abhyankar { 9345f2c45f1SShri Abhyankar PetscErrorCode ierr; 9355f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 93654dfd506SHong Zhang DMNetworkComponent *component=NULL,*newcomponent=NULL; 9375f2c45f1SShri Abhyankar PetscBool flg=PETSC_FALSE; 9385f2c45f1SShri Abhyankar PetscInt i; 9395f2c45f1SShri Abhyankar 9405f2c45f1SShri Abhyankar PetscFunctionBegin; 94154dfd506SHong Zhang if (!network->component) { 94254dfd506SHong Zhang ierr = PetscCalloc1(network->max_comps_registered,&network->component);CHKERRQ(ierr); 94354dfd506SHong Zhang } 94454dfd506SHong Zhang 9455f2c45f1SShri Abhyankar for (i=0; i < network->ncomponent; i++) { 94654dfd506SHong Zhang ierr = PetscStrcmp(network->component[i].name,name,&flg);CHKERRQ(ierr); 9475f2c45f1SShri Abhyankar if (flg) { 9485f2c45f1SShri Abhyankar *key = i; 9495f2c45f1SShri Abhyankar PetscFunctionReturn(0); 9505f2c45f1SShri Abhyankar } 9516d64e262SShri Abhyankar } 95254dfd506SHong Zhang 95354dfd506SHong Zhang if (network->ncomponent == network->max_comps_registered) { 95454dfd506SHong Zhang /* Reached max allowed so resize component */ 95554dfd506SHong Zhang network->max_comps_registered += 2; 95654dfd506SHong Zhang ierr = PetscCalloc1(network->max_comps_registered,&newcomponent);CHKERRQ(ierr); 95754dfd506SHong Zhang /* Copy over the previous component info */ 95854dfd506SHong Zhang for (i=0; i < network->ncomponent; i++) { 95954dfd506SHong Zhang ierr = PetscStrcpy(newcomponent[i].name,network->component[i].name);CHKERRQ(ierr); 96054dfd506SHong Zhang newcomponent[i].size = network->component[i].size; 9615f2c45f1SShri Abhyankar } 96254dfd506SHong Zhang /* Free old one */ 96354dfd506SHong Zhang ierr = PetscFree(network->component);CHKERRQ(ierr); 96454dfd506SHong Zhang /* Update pointer */ 96554dfd506SHong Zhang network->component = newcomponent; 96654dfd506SHong Zhang } 96754dfd506SHong Zhang 96854dfd506SHong Zhang component = &network->component[network->ncomponent]; 9695f2c45f1SShri Abhyankar 9705f2c45f1SShri Abhyankar ierr = PetscStrcpy(component->name,name);CHKERRQ(ierr); 9715f2c45f1SShri Abhyankar component->size = size/sizeof(DMNetworkComponentGenericDataType); 9725f2c45f1SShri Abhyankar *key = network->ncomponent; 9735f2c45f1SShri Abhyankar network->ncomponent++; 9745f2c45f1SShri Abhyankar PetscFunctionReturn(0); 9755f2c45f1SShri Abhyankar } 9765f2c45f1SShri Abhyankar 9775f2c45f1SShri Abhyankar /*@ 9782bf73ac6SHong Zhang DMNetworkGetVertexRange - Get the bounds [start, end) for the local vertices 9795f2c45f1SShri Abhyankar 9805f2c45f1SShri Abhyankar Not Collective 9815f2c45f1SShri Abhyankar 982f899ff85SJose E. Roman Input Parameter: 9832bf73ac6SHong Zhang . dm - the DMNetwork object 9845f2c45f1SShri Abhyankar 985fd292e60Sprj- Output Parameters: 9862bf73ac6SHong Zhang + vStart - the first vertex point 9872bf73ac6SHong Zhang - vEnd - one beyond the last vertex point 9885f2c45f1SShri Abhyankar 98997bb938eSShri Abhyankar Level: beginner 9905f2c45f1SShri Abhyankar 9912bf73ac6SHong Zhang .seealso: DMNetworkGetEdgeRange() 9925f2c45f1SShri Abhyankar @*/ 9935f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVertexRange(DM dm,PetscInt *vStart,PetscInt *vEnd) 9945f2c45f1SShri Abhyankar { 9955f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 9965f2c45f1SShri Abhyankar 9975f2c45f1SShri Abhyankar PetscFunctionBegin; 9985f2c45f1SShri Abhyankar if (vStart) *vStart = network->vStart; 9995f2c45f1SShri Abhyankar if (vEnd) *vEnd = network->vEnd; 10005f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10015f2c45f1SShri Abhyankar } 10025f2c45f1SShri Abhyankar 10035f2c45f1SShri Abhyankar /*@ 10042bf73ac6SHong Zhang DMNetworkGetEdgeRange - Get the bounds [start, end) for the local edges 10055f2c45f1SShri Abhyankar 10065f2c45f1SShri Abhyankar Not Collective 10075f2c45f1SShri Abhyankar 1008f899ff85SJose E. Roman Input Parameter: 10092bf73ac6SHong Zhang . dm - the DMNetwork object 10105f2c45f1SShri Abhyankar 1011fd292e60Sprj- Output Parameters: 10125f2c45f1SShri Abhyankar + eStart - The first edge point 10135f2c45f1SShri Abhyankar - eEnd - One beyond the last edge point 10145f2c45f1SShri Abhyankar 101597bb938eSShri Abhyankar Level: beginner 10165f2c45f1SShri Abhyankar 10172bf73ac6SHong Zhang .seealso: DMNetworkGetVertexRange() 10185f2c45f1SShri Abhyankar @*/ 10195f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetEdgeRange(DM dm,PetscInt *eStart,PetscInt *eEnd) 10205f2c45f1SShri Abhyankar { 10215f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10225f2c45f1SShri Abhyankar 10235f2c45f1SShri Abhyankar PetscFunctionBegin; 10245f2c45f1SShri Abhyankar if (eStart) *eStart = network->eStart; 10255f2c45f1SShri Abhyankar if (eEnd) *eEnd = network->eEnd; 10265f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10275f2c45f1SShri Abhyankar } 10285f2c45f1SShri Abhyankar 10292bf73ac6SHong Zhang static PetscErrorCode DMNetworkGetIndex(DM dm,PetscInt p,PetscInt *index) 10302bf73ac6SHong Zhang { 10312bf73ac6SHong Zhang PetscErrorCode ierr; 10322bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 10332bf73ac6SHong Zhang PetscInt offsetp; 10342bf73ac6SHong Zhang DMNetworkComponentHeader header; 10352bf73ac6SHong Zhang 10362bf73ac6SHong Zhang PetscFunctionBegin; 10372bf73ac6SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 10382bf73ac6SHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 10392bf73ac6SHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 10402bf73ac6SHong Zhang *index = header->index; 10412bf73ac6SHong Zhang PetscFunctionReturn(0); 10422bf73ac6SHong Zhang } 10432bf73ac6SHong Zhang 10447b6afd5bSHong Zhang /*@ 10452bf73ac6SHong Zhang DMNetworkGetGlobalEdgeIndex - Get the global numbering for the edge on the network 10467b6afd5bSHong Zhang 10477b6afd5bSHong Zhang Not Collective 10487b6afd5bSHong Zhang 10497b6afd5bSHong Zhang Input Parameters: 10507b6afd5bSHong Zhang + dm - DMNetwork object 1051e85e6aecSHong Zhang - p - edge point 10527b6afd5bSHong Zhang 1053fd292e60Sprj- Output Parameters: 10542bf73ac6SHong Zhang . index - the global numbering for the edge 10557b6afd5bSHong Zhang 10567b6afd5bSHong Zhang Level: intermediate 10577b6afd5bSHong Zhang 10582bf73ac6SHong Zhang .seealso: DMNetworkGetGlobalVertexIndex() 10597b6afd5bSHong Zhang @*/ 1060e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalEdgeIndex(DM dm,PetscInt p,PetscInt *index) 10617b6afd5bSHong Zhang { 10627b6afd5bSHong Zhang PetscErrorCode ierr; 10637b6afd5bSHong Zhang 10647b6afd5bSHong Zhang PetscFunctionBegin; 10652bf73ac6SHong Zhang ierr = DMNetworkGetIndex(dm,p,index);CHKERRQ(ierr); 10667b6afd5bSHong Zhang PetscFunctionReturn(0); 10677b6afd5bSHong Zhang } 10687b6afd5bSHong Zhang 10695f2c45f1SShri Abhyankar /*@ 10702bf73ac6SHong Zhang DMNetworkGetGlobalVertexIndex - Get the global numbering for the vertex on the network 1071e85e6aecSHong Zhang 1072e85e6aecSHong Zhang Not Collective 1073e85e6aecSHong Zhang 1074e85e6aecSHong Zhang Input Parameters: 1075e85e6aecSHong Zhang + dm - DMNetwork object 1076e85e6aecSHong Zhang - p - vertex point 1077e85e6aecSHong Zhang 1078fd292e60Sprj- Output Parameters: 10792bf73ac6SHong Zhang . index - the global numbering for the vertex 1080e85e6aecSHong Zhang 1081e85e6aecSHong Zhang Level: intermediate 1082e85e6aecSHong Zhang 10832bf73ac6SHong Zhang .seealso: DMNetworkGetGlobalEdgeIndex() 1084e85e6aecSHong Zhang @*/ 1085e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalVertexIndex(DM dm,PetscInt p,PetscInt *index) 1086e85e6aecSHong Zhang { 1087e85e6aecSHong Zhang PetscErrorCode ierr; 1088e85e6aecSHong Zhang 1089e85e6aecSHong Zhang PetscFunctionBegin; 10902bf73ac6SHong Zhang ierr = DMNetworkGetIndex(dm,p,index);CHKERRQ(ierr); 10919988b915SShri Abhyankar PetscFunctionReturn(0); 10929988b915SShri Abhyankar } 10939988b915SShri Abhyankar 10949988b915SShri Abhyankar /*@ 10955f2c45f1SShri Abhyankar DMNetworkGetNumComponents - Get the number of components at a vertex/edge 10965f2c45f1SShri Abhyankar 10975f2c45f1SShri Abhyankar Not Collective 10985f2c45f1SShri Abhyankar 10995f2c45f1SShri Abhyankar Input Parameters: 11002bf73ac6SHong Zhang + dm - the DMNetwork object 1101a2b725a8SWilliam Gropp - p - vertex/edge point 11025f2c45f1SShri Abhyankar 11035f2c45f1SShri Abhyankar Output Parameters: 11045f2c45f1SShri Abhyankar . numcomponents - Number of components at the vertex/edge 11055f2c45f1SShri Abhyankar 110697bb938eSShri Abhyankar Level: beginner 11075f2c45f1SShri Abhyankar 11082bf73ac6SHong Zhang .seealso: DMNetworkRegisterComponent(), DMNetworkAddComponent() 11095f2c45f1SShri Abhyankar @*/ 11105f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetNumComponents(DM dm,PetscInt p,PetscInt *numcomponents) 11115f2c45f1SShri Abhyankar { 11125f2c45f1SShri Abhyankar PetscErrorCode ierr; 11135f2c45f1SShri Abhyankar PetscInt offset; 11145f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 11155f2c45f1SShri Abhyankar 11165f2c45f1SShri Abhyankar PetscFunctionBegin; 11175f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 11185f2c45f1SShri Abhyankar *numcomponents = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 11195f2c45f1SShri Abhyankar PetscFunctionReturn(0); 11205f2c45f1SShri Abhyankar } 11215f2c45f1SShri Abhyankar 11225f2c45f1SShri Abhyankar /*@ 11232bf73ac6SHong Zhang DMNetworkGetLocalVecOffset - Get the offset for accessing the variables associated with a component at the given vertex/edge from the local vector 11245f2c45f1SShri Abhyankar 11255f2c45f1SShri Abhyankar Not Collective 11265f2c45f1SShri Abhyankar 11275f2c45f1SShri Abhyankar Input Parameters: 11282bf73ac6SHong Zhang + dm - the DMNetwork object 11297d928bffSSatish Balay . p - the edge/vertex point 11302bf73ac6SHong Zhang - compnum - component number; use ALL_COMPONENTS if no specific component is requested 11319988b915SShri Abhyankar 11329988b915SShri Abhyankar Output Parameters: 11332bf73ac6SHong Zhang . offset - the local offset 11349988b915SShri Abhyankar 11359988b915SShri Abhyankar Level: intermediate 11369988b915SShri Abhyankar 11372bf73ac6SHong Zhang .seealso: DMGetLocalVector(), DMNetworkGetComponent(), DMNetworkGetGlobalVecOffset() 11389988b915SShri Abhyankar @*/ 11392bf73ac6SHong Zhang PetscErrorCode DMNetworkGetLocalVecOffset(DM dm,PetscInt p,PetscInt compnum,PetscInt *offset) 11409988b915SShri Abhyankar { 11419988b915SShri Abhyankar PetscErrorCode ierr; 11429988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 11439988b915SShri Abhyankar PetscInt offsetp,offsetd; 11449988b915SShri Abhyankar DMNetworkComponentHeader header; 11459988b915SShri Abhyankar 11469988b915SShri Abhyankar PetscFunctionBegin; 11472bf73ac6SHong Zhang ierr = PetscSectionGetOffset(network->plex->localSection,p,&offsetp);CHKERRQ(ierr); 11482bf73ac6SHong Zhang if (compnum == ALL_COMPONENTS) { 11492bf73ac6SHong Zhang *offset = offsetp; 11502bf73ac6SHong Zhang PetscFunctionReturn(0); 11512bf73ac6SHong Zhang } 11522bf73ac6SHong Zhang 11539988b915SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetd);CHKERRQ(ierr); 11549988b915SShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetd); 11559988b915SShri Abhyankar *offset = offsetp + header->offsetvarrel[compnum]; 11569988b915SShri Abhyankar PetscFunctionReturn(0); 11579988b915SShri Abhyankar } 11589988b915SShri Abhyankar 11599988b915SShri Abhyankar /*@ 11602bf73ac6SHong Zhang DMNetworkGetGlobalVecOffset - Get the global offset for accessing the variables associated with a component for the given vertex/edge from the global vector 11619988b915SShri Abhyankar 11629988b915SShri Abhyankar Not Collective 11639988b915SShri Abhyankar 11649988b915SShri Abhyankar Input Parameters: 11652bf73ac6SHong Zhang + dm - the DMNetwork object 11667d928bffSSatish Balay . p - the edge/vertex point 11672bf73ac6SHong Zhang - compnum - component number; use ALL_COMPONENTS if no specific component is requested 11689988b915SShri Abhyankar 11699988b915SShri Abhyankar Output Parameters: 11709988b915SShri Abhyankar . offsetg - the global offset 11719988b915SShri Abhyankar 11729988b915SShri Abhyankar Level: intermediate 11739988b915SShri Abhyankar 11742bf73ac6SHong Zhang .seealso: DMNetworkGetLocalVecOffset(), DMGetGlobalVector(), DMNetworkGetComponent() 11759988b915SShri Abhyankar @*/ 11762bf73ac6SHong Zhang PetscErrorCode DMNetworkGetGlobalVecOffset(DM dm,PetscInt p,PetscInt compnum,PetscInt *offsetg) 11779988b915SShri Abhyankar { 11789988b915SShri Abhyankar PetscErrorCode ierr; 11799988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 11809988b915SShri Abhyankar PetscInt offsetp,offsetd; 11819988b915SShri Abhyankar DMNetworkComponentHeader header; 11829988b915SShri Abhyankar 11839988b915SShri Abhyankar PetscFunctionBegin; 11842bf73ac6SHong Zhang ierr = PetscSectionGetOffset(network->plex->globalSection,p,&offsetp);CHKERRQ(ierr); 11852bf73ac6SHong Zhang if (offsetp < 0) offsetp = -(offsetp + 1); /* Convert to actual global offset for ghost vertex */ 11862bf73ac6SHong Zhang 11872bf73ac6SHong Zhang if (compnum == ALL_COMPONENTS) { 11882bf73ac6SHong Zhang *offsetg = offsetp; 11892bf73ac6SHong Zhang PetscFunctionReturn(0); 11902bf73ac6SHong Zhang } 11919988b915SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetd);CHKERRQ(ierr); 11929988b915SShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetd); 11939988b915SShri Abhyankar *offsetg = offsetp + header->offsetvarrel[compnum]; 11949988b915SShri Abhyankar PetscFunctionReturn(0); 11959988b915SShri Abhyankar } 11969988b915SShri Abhyankar 11979988b915SShri Abhyankar /*@ 11982bf73ac6SHong Zhang DMNetworkGetEdgeOffset - Get the offset for accessing the variables associated with the given edge from the local subvector 119924121865SAdrian Maldonado 120024121865SAdrian Maldonado Not Collective 120124121865SAdrian Maldonado 120224121865SAdrian Maldonado Input Parameters: 12032bf73ac6SHong Zhang + dm - the DMNetwork object 120424121865SAdrian Maldonado - p - the edge point 120524121865SAdrian Maldonado 120624121865SAdrian Maldonado Output Parameters: 120724121865SAdrian Maldonado . offset - the offset 120824121865SAdrian Maldonado 120924121865SAdrian Maldonado Level: intermediate 121024121865SAdrian Maldonado 12112bf73ac6SHong Zhang .seealso: DMNetworkGetLocalVecOffset(), DMGetLocalVector() 121224121865SAdrian Maldonado @*/ 121324121865SAdrian Maldonado PetscErrorCode DMNetworkGetEdgeOffset(DM dm,PetscInt p,PetscInt *offset) 121424121865SAdrian Maldonado { 121524121865SAdrian Maldonado PetscErrorCode ierr; 121624121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 121724121865SAdrian Maldonado 121824121865SAdrian Maldonado PetscFunctionBegin; 121924121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->edge.DofSection,p,offset);CHKERRQ(ierr); 122024121865SAdrian Maldonado PetscFunctionReturn(0); 122124121865SAdrian Maldonado } 122224121865SAdrian Maldonado 122324121865SAdrian Maldonado /*@ 12242bf73ac6SHong Zhang DMNetworkGetVertexOffset - Get the offset for accessing the variables associated with the given vertex from the local subvector 122524121865SAdrian Maldonado 122624121865SAdrian Maldonado Not Collective 122724121865SAdrian Maldonado 122824121865SAdrian Maldonado Input Parameters: 12292bf73ac6SHong Zhang + dm - the DMNetwork object 123024121865SAdrian Maldonado - p - the vertex point 123124121865SAdrian Maldonado 123224121865SAdrian Maldonado Output Parameters: 123324121865SAdrian Maldonado . offset - the offset 123424121865SAdrian Maldonado 123524121865SAdrian Maldonado Level: intermediate 123624121865SAdrian Maldonado 12372bf73ac6SHong Zhang .seealso: DMNetworkGetEdgeOffset(), DMGetLocalVector() 123824121865SAdrian Maldonado @*/ 123924121865SAdrian Maldonado PetscErrorCode DMNetworkGetVertexOffset(DM dm,PetscInt p,PetscInt *offset) 124024121865SAdrian Maldonado { 124124121865SAdrian Maldonado PetscErrorCode ierr; 124224121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 124324121865SAdrian Maldonado 124424121865SAdrian Maldonado PetscFunctionBegin; 124524121865SAdrian Maldonado p -= network->vStart; 124624121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->vertex.DofSection,p,offset);CHKERRQ(ierr); 124724121865SAdrian Maldonado PetscFunctionReturn(0); 124824121865SAdrian Maldonado } 12492bf73ac6SHong Zhang 12505f2c45f1SShri Abhyankar /*@ 12512bf73ac6SHong Zhang DMNetworkAddComponent - Adds a network component and number of variables at the given point (vertex/edge) 12525f2c45f1SShri Abhyankar 12535f2c45f1SShri Abhyankar Not Collective 12545f2c45f1SShri Abhyankar 12555f2c45f1SShri Abhyankar Input Parameters: 12564dc646bcSBarry Smith + dm - the DMNetwork 12575f2c45f1SShri Abhyankar . p - the vertex/edge point 12582bf73ac6SHong Zhang . componentkey - component key returned while registering the component; ignored if compvalue=NULL 12592bf73ac6SHong Zhang . compvalue - pointer to the data structure for the component, or NULL if not required. 12602bf73ac6SHong Zhang - nvar - number of variables for the component at the vertex/edge point 12615f2c45f1SShri Abhyankar 126297bb938eSShri Abhyankar Level: beginner 12635f2c45f1SShri Abhyankar 12642bf73ac6SHong Zhang .seealso: DMNetworkGetComponent() 12655f2c45f1SShri Abhyankar @*/ 12662bf73ac6SHong Zhang PetscErrorCode DMNetworkAddComponent(DM dm,PetscInt p,PetscInt componentkey,void* compvalue,PetscInt nvar) 12675f2c45f1SShri Abhyankar { 12685f2c45f1SShri Abhyankar PetscErrorCode ierr; 12695f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 12702bf73ac6SHong Zhang DMNetworkComponent *component = &network->component[componentkey]; 127154dfd506SHong Zhang DMNetworkComponentHeader header; 127254dfd506SHong Zhang DMNetworkComponentValue cvalue; 12732bf73ac6SHong Zhang PetscBool sharedv=PETSC_FALSE; 127454dfd506SHong Zhang PetscInt compnum; 127554dfd506SHong Zhang PetscInt *compsize,*compkey,*compoffset,*compnvar,*compoffsetvarrel; 127654dfd506SHong Zhang void* *compdata; 12775f2c45f1SShri Abhyankar 12785f2c45f1SShri Abhyankar PetscFunctionBegin; 12795f2c45f1SShri Abhyankar ierr = PetscSectionAddDof(network->DofSection,p,nvar);CHKERRQ(ierr); 12802bf73ac6SHong Zhang if (!compvalue) PetscFunctionReturn(0); 12812bf73ac6SHong Zhang 12822bf73ac6SHong Zhang ierr = DMNetworkIsSharedVertex(dm,p,&sharedv);CHKERRQ(ierr); 12832bf73ac6SHong Zhang if (sharedv) { 12842bf73ac6SHong Zhang PetscBool ghost; 12852bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 12862bf73ac6SHong Zhang if (ghost) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Adding a component at a leaf(ghost) shared vertex is not supported"); 12872bf73ac6SHong Zhang } 12882bf73ac6SHong Zhang 128954dfd506SHong Zhang header = &network->header[p]; 129054dfd506SHong Zhang cvalue = &network->cvalue[p]; 129154dfd506SHong Zhang if (header->ndata == header->maxcomps) { 1292f11a936eSBarry Smith PetscInt additional_size; 1293f11a936eSBarry Smith 129454dfd506SHong Zhang /* Reached limit so resize header component arrays */ 129554dfd506SHong Zhang header->maxcomps += 2; 129654dfd506SHong Zhang 129754dfd506SHong Zhang /* Allocate arrays for component information and value */ 129854dfd506SHong Zhang ierr = PetscCalloc5(header->maxcomps,&compsize,header->maxcomps,&compkey,header->maxcomps,&compoffset,header->maxcomps,&compnvar,header->maxcomps,&compoffsetvarrel);CHKERRQ(ierr); 129954dfd506SHong Zhang ierr = PetscMalloc1(header->maxcomps,&compdata);CHKERRQ(ierr); 130054dfd506SHong Zhang 130154dfd506SHong Zhang /* Recalculate header size */ 130254dfd506SHong Zhang header->hsize = sizeof(struct _p_DMNetworkComponentHeader) + 5*header->maxcomps*sizeof(PetscInt); 130354dfd506SHong Zhang 130454dfd506SHong Zhang header->hsize /= sizeof(DMNetworkComponentGenericDataType); 130554dfd506SHong Zhang 130654dfd506SHong Zhang /* Copy over component info */ 130754dfd506SHong Zhang ierr = PetscMemcpy(compsize,header->size,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 130854dfd506SHong Zhang ierr = PetscMemcpy(compkey,header->key,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 130954dfd506SHong Zhang ierr = PetscMemcpy(compoffset,header->offset,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 131054dfd506SHong Zhang ierr = PetscMemcpy(compnvar,header->nvar,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 131154dfd506SHong Zhang ierr = PetscMemcpy(compoffsetvarrel,header->offsetvarrel,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 131254dfd506SHong Zhang 131354dfd506SHong Zhang /* Copy over component data pointers */ 131454dfd506SHong Zhang ierr = PetscMemcpy(compdata,cvalue->data,header->ndata*sizeof(void*));CHKERRQ(ierr); 131554dfd506SHong Zhang 131654dfd506SHong Zhang /* Free old arrays */ 131754dfd506SHong Zhang ierr = PetscFree5(header->size,header->key,header->offset,header->nvar,header->offsetvarrel);CHKERRQ(ierr); 131854dfd506SHong Zhang ierr = PetscFree(cvalue->data);CHKERRQ(ierr); 131954dfd506SHong Zhang 132054dfd506SHong Zhang /* Update pointers */ 132154dfd506SHong Zhang header->size = compsize; 132254dfd506SHong Zhang header->key = compkey; 132354dfd506SHong Zhang header->offset = compoffset; 132454dfd506SHong Zhang header->nvar = compnvar; 132554dfd506SHong Zhang header->offsetvarrel = compoffsetvarrel; 132654dfd506SHong Zhang 132754dfd506SHong Zhang cvalue->data = compdata; 132854dfd506SHong Zhang 132954dfd506SHong Zhang /* Update DataSection Dofs */ 133054dfd506SHong 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 */ 1331f11a936eSBarry Smith additional_size = (5*(header->maxcomps - header->ndata)*sizeof(PetscInt))/sizeof(DMNetworkComponentGenericDataType); 133254dfd506SHong Zhang ierr = PetscSectionAddDof(network->DataSection,p,additional_size);CHKERRQ(ierr); 133354dfd506SHong Zhang } 133454dfd506SHong Zhang header = &network->header[p]; 133554dfd506SHong Zhang cvalue = &network->cvalue[p]; 133654dfd506SHong Zhang 133754dfd506SHong Zhang compnum = header->ndata; 13382bf73ac6SHong Zhang 13392bf73ac6SHong Zhang header->size[compnum] = component->size; 13402bf73ac6SHong Zhang ierr = PetscSectionAddDof(network->DataSection,p,component->size);CHKERRQ(ierr); 13412bf73ac6SHong Zhang header->key[compnum] = componentkey; 13422bf73ac6SHong Zhang if (compnum != 0) header->offset[compnum] = header->offset[compnum-1] + header->size[compnum-1]; 13432bf73ac6SHong Zhang cvalue->data[compnum] = (void*)compvalue; 13442bf73ac6SHong Zhang 13452bf73ac6SHong Zhang /* variables */ 13462bf73ac6SHong Zhang header->nvar[compnum] += nvar; 13472bf73ac6SHong Zhang if (compnum != 0) header->offsetvarrel[compnum] = header->offsetvarrel[compnum-1] + header->nvar[compnum-1]; 13482bf73ac6SHong Zhang 13492bf73ac6SHong Zhang header->ndata++; 13505f2c45f1SShri Abhyankar PetscFunctionReturn(0); 13515f2c45f1SShri Abhyankar } 13525f2c45f1SShri Abhyankar 135327f51fceSHong Zhang /*@ 13542bf73ac6SHong Zhang DMNetworkGetComponent - Gets the component key, the component data, and the number of variables at a given network point 135527f51fceSHong Zhang 135627f51fceSHong Zhang Not Collective 135727f51fceSHong Zhang 135827f51fceSHong Zhang Input Parameters: 13592bf73ac6SHong Zhang + dm - the DMNetwork object 13602bf73ac6SHong Zhang . p - vertex/edge point 136199c90e12SSatish Balay - compnum - component number; use ALL_COMPONENTS if sum up all the components 136227f51fceSHong Zhang 136327f51fceSHong Zhang Output Parameters: 13642bf73ac6SHong Zhang + compkey - the key obtained when registering the component (use NULL if not required) 13652bf73ac6SHong Zhang . component - the component data (use NULL if not required) 13662bf73ac6SHong Zhang - nvar - number of variables (use NULL if not required) 136727f51fceSHong Zhang 136897bb938eSShri Abhyankar Level: beginner 136927f51fceSHong Zhang 13702bf73ac6SHong Zhang .seealso: DMNetworkAddComponent(), DMNetworkGetNumComponents() 137127f51fceSHong Zhang @*/ 13722bf73ac6SHong Zhang PetscErrorCode DMNetworkGetComponent(DM dm,PetscInt p,PetscInt compnum,PetscInt *compkey,void **component,PetscInt *nvar) 137327f51fceSHong Zhang { 137427f51fceSHong Zhang PetscErrorCode ierr; 137527f51fceSHong Zhang DM_Network *network = (DM_Network*)dm->data; 13762bf73ac6SHong Zhang PetscInt offset = 0; 13772bf73ac6SHong Zhang DMNetworkComponentHeader header; 137827f51fceSHong Zhang 137927f51fceSHong Zhang PetscFunctionBegin; 13802bf73ac6SHong Zhang if (compnum == ALL_COMPONENTS) { 138127f51fceSHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 138227f51fceSHong Zhang PetscFunctionReturn(0); 138327f51fceSHong Zhang } 138427f51fceSHong Zhang 13852bf73ac6SHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 138642dc13f1SHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offset); 13875f2c45f1SShri Abhyankar 13882bf73ac6SHong Zhang if (compnum >= 0) { 13892bf73ac6SHong Zhang if (compkey) *compkey = header->key[compnum]; 13902bf73ac6SHong Zhang if (component) { 139154dfd506SHong Zhang offset += header->hsize+header->offset[compnum]; 13922bf73ac6SHong Zhang *component = network->componentdataarray+offset; 13932bf73ac6SHong Zhang } 13942bf73ac6SHong Zhang } 13955f2c45f1SShri Abhyankar 13962bf73ac6SHong Zhang if (nvar) *nvar = header->nvar[compnum]; 139754dfd506SHong Zhang 13985f2c45f1SShri Abhyankar PetscFunctionReturn(0); 13995f2c45f1SShri Abhyankar } 14005f2c45f1SShri Abhyankar 14012bf73ac6SHong Zhang /* 14022bf73ac6SHong Zhang Sets up the array that holds the data for all components and its associated section. 14032bf73ac6SHong 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. 14042bf73ac6SHong Zhang */ 14055f2c45f1SShri Abhyankar PetscErrorCode DMNetworkComponentSetUp(DM dm) 14065f2c45f1SShri Abhyankar { 14075f2c45f1SShri Abhyankar PetscErrorCode ierr; 14085f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 1409f11a936eSBarry Smith PetscInt arr_size,p,offset,offsetp,ncomp,i,*headerarr; 14105f2c45f1SShri Abhyankar DMNetworkComponentHeader header; 14115f2c45f1SShri Abhyankar DMNetworkComponentValue cvalue; 1412f11a936eSBarry Smith DMNetworkComponentHeader headerinfo; 14135f2c45f1SShri Abhyankar DMNetworkComponentGenericDataType *componentdataarray; 14145f2c45f1SShri Abhyankar 14155f2c45f1SShri Abhyankar PetscFunctionBegin; 14165f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr); 14175f2c45f1SShri Abhyankar ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr); 1418f11a936eSBarry Smith /* arr_size+1 fixes pipeline test of opensolaris-misc for src/dm/tests/ex10.c -- Do not know why */ 1419f11a936eSBarry Smith ierr = PetscCalloc1(arr_size+1,&network->componentdataarray);CHKERRQ(ierr); 14205f2c45f1SShri Abhyankar componentdataarray = network->componentdataarray; 14215f2c45f1SShri Abhyankar for (p = network->pStart; p < network->pEnd; p++) { 14225f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 14235f2c45f1SShri Abhyankar /* Copy header */ 14245f2c45f1SShri Abhyankar header = &network->header[p]; 1425f11a936eSBarry Smith headerinfo = (DMNetworkComponentHeader)(componentdataarray+offsetp); 142654dfd506SHong Zhang ierr = PetscMemcpy(headerinfo,header,sizeof(struct _p_DMNetworkComponentHeader));CHKERRQ(ierr); 1427f11a936eSBarry Smith headerarr = (PetscInt*)(headerinfo+1); 142854dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->size,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 142954dfd506SHong Zhang headerarr += header->maxcomps; 143054dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->key,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 143154dfd506SHong Zhang headerarr += header->maxcomps; 143254dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->offset,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 143354dfd506SHong Zhang headerarr += header->maxcomps; 143454dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->nvar,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 143554dfd506SHong Zhang headerarr += header->maxcomps; 143654dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->offsetvarrel,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 143754dfd506SHong Zhang 14385f2c45f1SShri Abhyankar /* Copy data */ 14395f2c45f1SShri Abhyankar cvalue = &network->cvalue[p]; 14405f2c45f1SShri Abhyankar ncomp = header->ndata; 14412bf73ac6SHong Zhang 14425f2c45f1SShri Abhyankar for (i = 0; i < ncomp; i++) { 144354dfd506SHong Zhang offset = offsetp + header->hsize + header->offset[i]; 1444302440fdSBarry Smith ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 14455f2c45f1SShri Abhyankar } 14465f2c45f1SShri Abhyankar } 14475f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14485f2c45f1SShri Abhyankar } 14495f2c45f1SShri Abhyankar 14505f2c45f1SShri Abhyankar /* Sets up the section for dofs. This routine is called during DMSetUp() */ 14512bf73ac6SHong Zhang static PetscErrorCode DMNetworkVariablesSetUp(DM dm) 14525f2c45f1SShri Abhyankar { 14535f2c45f1SShri Abhyankar PetscErrorCode ierr; 14545f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 14552bf73ac6SHong Zhang MPI_Comm comm; 14562bf73ac6SHong Zhang PetscMPIInt size; 14575f2c45f1SShri Abhyankar 14585f2c45f1SShri Abhyankar PetscFunctionBegin; 14592bf73ac6SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 14602bf73ac6SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 14612bf73ac6SHong Zhang 14622bf73ac6SHong Zhang if (size > 1) { /* Sync nvar at shared vertices for all processes */ 14632bf73ac6SHong Zhang PetscSF sf = network->plex->sf; 14642bf73ac6SHong Zhang PetscInt *local_nvar, *remote_nvar,nroots,nleaves,p=-1,i,nsv; 14652bf73ac6SHong Zhang const PetscInt *svtx; 14662bf73ac6SHong Zhang PetscBool ghost; 14672bf73ac6SHong Zhang /* 14682bf73ac6SHong Zhang PetscMPIInt rank; 14692bf73ac6SHong Zhang const PetscInt *ilocal; 14702bf73ac6SHong Zhang const PetscSFNode *iremote; 14712bf73ac6SHong Zhang ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 14722bf73ac6SHong Zhang ierr = PetscSFGetGraph(sf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr); 14732bf73ac6SHong Zhang */ 14742bf73ac6SHong Zhang ierr = PetscSFGetGraph(sf,&nroots,&nleaves,NULL,NULL);CHKERRQ(ierr); 14752bf73ac6SHong Zhang ierr = PetscCalloc2(nroots,&local_nvar,nroots,&remote_nvar);CHKERRQ(ierr); 14762bf73ac6SHong Zhang 14772bf73ac6SHong Zhang /* Leaves copy user's nvar to local_nvar */ 14782bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&nsv,&svtx);CHKERRQ(ierr); 14792bf73ac6SHong Zhang for (i=0; i<nsv; i++) { 14802bf73ac6SHong Zhang p = svtx[i]; 14812bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 14822bf73ac6SHong Zhang if (!ghost) continue; 14832bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,&local_nvar[p]);CHKERRQ(ierr); 14842bf73ac6SHong Zhang /* printf("[%d] Before SFReduce: leaf local_nvar[%d] = %d\n",rank,p,local_nvar[p]); */ 14852bf73ac6SHong Zhang } 14862bf73ac6SHong Zhang 14872bf73ac6SHong Zhang /* Leaves add local_nvar to root remote_nvar */ 14882bf73ac6SHong Zhang ierr = PetscSFReduceBegin(sf, MPIU_INT, local_nvar, remote_nvar, MPI_SUM);CHKERRQ(ierr); 14892bf73ac6SHong Zhang ierr = PetscSFReduceEnd(sf, MPIU_INT, local_nvar, remote_nvar, MPI_SUM);CHKERRQ(ierr); 14902bf73ac6SHong Zhang /* printf("[%d] remote_nvar[%d] = %d\n",rank,p,remote_nvar[p]); */ 14912bf73ac6SHong Zhang 14922bf73ac6SHong Zhang /* Update roots' local_nvar */ 14932bf73ac6SHong Zhang for (i=0; i<nsv; i++) { 14942bf73ac6SHong Zhang p = svtx[i]; 14952bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 14962bf73ac6SHong Zhang if (ghost) continue; 14972bf73ac6SHong Zhang 14982bf73ac6SHong Zhang ierr = PetscSectionAddDof(network->DofSection,p,remote_nvar[p]);CHKERRQ(ierr); 14992bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,&local_nvar[p]);CHKERRQ(ierr); 15002bf73ac6SHong Zhang /* printf("[%d] After SFReduce: root local_nvar[%d] = %d\n",rank,p,local_nvar[p]); */ 15012bf73ac6SHong Zhang } 15022bf73ac6SHong Zhang 15032bf73ac6SHong Zhang /* Roots Bcast nvar to leaves */ 1504ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sf, MPIU_INT, local_nvar, remote_nvar,MPI_REPLACE);CHKERRQ(ierr); 1505ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sf, MPIU_INT, local_nvar, remote_nvar,MPI_REPLACE);CHKERRQ(ierr); 15062bf73ac6SHong Zhang 15072bf73ac6SHong Zhang /* Leaves reset receved/remote nvar to dm */ 15082bf73ac6SHong Zhang for (i=0; i<nsv; i++) { 15092bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 15102bf73ac6SHong Zhang if (!ghost) continue; 15112bf73ac6SHong Zhang p = svtx[i]; 15122bf73ac6SHong Zhang /* printf("[%d] leaf reset nvar %d at p= %d \n",rank,remote_nvar[p],p); */ 15132bf73ac6SHong Zhang /* DMNetworkSetNumVariables(dm,p,remote_nvar[p]) */ 15142bf73ac6SHong Zhang ierr = PetscSectionSetDof(network->DofSection,p,remote_nvar[p]);CHKERRQ(ierr); 15152bf73ac6SHong Zhang } 15162bf73ac6SHong Zhang 15172bf73ac6SHong Zhang ierr = PetscFree2(local_nvar,remote_nvar);CHKERRQ(ierr); 15182bf73ac6SHong Zhang } 15192bf73ac6SHong Zhang 15205f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr); 15215f2c45f1SShri Abhyankar PetscFunctionReturn(0); 15225f2c45f1SShri Abhyankar } 15235f2c45f1SShri Abhyankar 152424121865SAdrian Maldonado /* Get a subsection from a range of points */ 15259dddd249SSatish Balay static PetscErrorCode DMNetworkGetSubSection_private(PetscSection main,PetscInt pstart,PetscInt pend,PetscSection *subsection) 152624121865SAdrian Maldonado { 152724121865SAdrian Maldonado PetscErrorCode ierr; 152824121865SAdrian Maldonado PetscInt i, nvar; 152924121865SAdrian Maldonado 153024121865SAdrian Maldonado PetscFunctionBegin; 15319dddd249SSatish Balay ierr = PetscSectionCreate(PetscObjectComm((PetscObject)main), subsection);CHKERRQ(ierr); 153224121865SAdrian Maldonado ierr = PetscSectionSetChart(*subsection, 0, pend - pstart);CHKERRQ(ierr); 153324121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 15349dddd249SSatish Balay ierr = PetscSectionGetDof(main,i,&nvar);CHKERRQ(ierr); 153524121865SAdrian Maldonado ierr = PetscSectionSetDof(*subsection, i - pstart, nvar);CHKERRQ(ierr); 153624121865SAdrian Maldonado } 153724121865SAdrian Maldonado 153824121865SAdrian Maldonado ierr = PetscSectionSetUp(*subsection);CHKERRQ(ierr); 153924121865SAdrian Maldonado PetscFunctionReturn(0); 154024121865SAdrian Maldonado } 154124121865SAdrian Maldonado 154224121865SAdrian Maldonado /* Create a submap of points with a GlobalToLocal structure */ 15432bf73ac6SHong Zhang static PetscErrorCode DMNetworkSetSubMap_private(PetscInt pstart, PetscInt pend, ISLocalToGlobalMapping *map) 154424121865SAdrian Maldonado { 154524121865SAdrian Maldonado PetscErrorCode ierr; 154624121865SAdrian Maldonado PetscInt i, *subpoints; 154724121865SAdrian Maldonado 154824121865SAdrian Maldonado PetscFunctionBegin; 154924121865SAdrian Maldonado /* Create index sets to map from "points" to "subpoints" */ 155024121865SAdrian Maldonado ierr = PetscMalloc1(pend - pstart, &subpoints);CHKERRQ(ierr); 155124121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 155224121865SAdrian Maldonado subpoints[i - pstart] = i; 155324121865SAdrian Maldonado } 1554459726d8SSatish Balay ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,pend-pstart,subpoints,PETSC_COPY_VALUES,map);CHKERRQ(ierr); 155524121865SAdrian Maldonado ierr = PetscFree(subpoints);CHKERRQ(ierr); 155624121865SAdrian Maldonado PetscFunctionReturn(0); 155724121865SAdrian Maldonado } 155824121865SAdrian Maldonado 155924121865SAdrian Maldonado /*@ 15602bf73ac6SHong Zhang DMNetworkAssembleGraphStructures - Assembles vertex and edge data structures. Must be called after DMNetworkDistribute 156124121865SAdrian Maldonado 15622bf73ac6SHong Zhang Collective on dm 156324121865SAdrian Maldonado 156424121865SAdrian Maldonado Input Parameters: 15652bf73ac6SHong Zhang . dm - the DMNetworkObject 156624121865SAdrian Maldonado 156724121865SAdrian Maldonado Note: the routine will create alternative orderings for the vertices and edges. Assume global network points are: 156824121865SAdrian Maldonado 156924121865SAdrian Maldonado points = [0 1 2 3 4 5 6] 157024121865SAdrian Maldonado 1571caf410d2SHong 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]). 157224121865SAdrian Maldonado 157324121865SAdrian Maldonado With this new ordering a local PetscSection, global PetscSection and PetscSF will be created specific to the subset. 157424121865SAdrian Maldonado 157524121865SAdrian Maldonado Level: intermediate 157624121865SAdrian Maldonado 157724121865SAdrian Maldonado @*/ 157824121865SAdrian Maldonado PetscErrorCode DMNetworkAssembleGraphStructures(DM dm) 157924121865SAdrian Maldonado { 158024121865SAdrian Maldonado PetscErrorCode ierr; 158124121865SAdrian Maldonado MPI_Comm comm; 1582f11a936eSBarry Smith PetscMPIInt size; 158324121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 158424121865SAdrian Maldonado 1585eab1376dSHong Zhang PetscFunctionBegin; 158624121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 1587ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 158824121865SAdrian Maldonado 158924121865SAdrian Maldonado /* Create maps for vertices and edges */ 159024121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 159124121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->eStart,network->eEnd,&network->edge.mapping);CHKERRQ(ierr); 159224121865SAdrian Maldonado 159324121865SAdrian Maldonado /* Create local sub-sections */ 159424121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->vStart,network->vEnd,&network->vertex.DofSection);CHKERRQ(ierr); 159524121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->eStart,network->eEnd,&network->edge.DofSection);CHKERRQ(ierr); 159624121865SAdrian Maldonado 15979852e123SBarry Smith if (size > 1) { 159824121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 159922bbedd7SHong Zhang 160024121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->vertex.DofSection, network->vertex.sf, PETSC_FALSE, PETSC_FALSE, &network->vertex.GlobalDofSection);CHKERRQ(ierr); 160124121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->edge.mapping, &network->edge.sf);CHKERRQ(ierr); 160224121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->edge.DofSection, network->edge.sf, PETSC_FALSE, PETSC_FALSE, &network->edge.GlobalDofSection);CHKERRQ(ierr); 160324121865SAdrian Maldonado } else { 160424121865SAdrian Maldonado /* create structures for vertex */ 160524121865SAdrian Maldonado ierr = PetscSectionClone(network->vertex.DofSection,&network->vertex.GlobalDofSection);CHKERRQ(ierr); 160624121865SAdrian Maldonado /* create structures for edge */ 160724121865SAdrian Maldonado ierr = PetscSectionClone(network->edge.DofSection,&network->edge.GlobalDofSection);CHKERRQ(ierr); 160824121865SAdrian Maldonado } 160924121865SAdrian Maldonado 161024121865SAdrian Maldonado /* Add viewers */ 161124121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->edge.GlobalDofSection,"Global edge dof section");CHKERRQ(ierr); 161224121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->vertex.GlobalDofSection,"Global vertex dof section");CHKERRQ(ierr); 161324121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->edge.GlobalDofSection, NULL, "-edge_global_section_view");CHKERRQ(ierr); 161424121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->vertex.GlobalDofSection, NULL, "-vertex_global_section_view");CHKERRQ(ierr); 161524121865SAdrian Maldonado PetscFunctionReturn(0); 161624121865SAdrian Maldonado } 16177b6afd5bSHong Zhang 1618f11a936eSBarry Smith /* 1619f11a936eSBarry Smith Add all subnetid for the input vertex v in this process to the btable 1620f11a936eSBarry Smith vertex_subnetid = supportingedge_subnetid 1621f11a936eSBarry Smith */ 1622f11a936eSBarry Smith PETSC_STATIC_INLINE PetscErrorCode SetSubnetIdLookupBT(DM dm,PetscInt v,PetscInt Nsubnet,PetscBT btable) 1623f11a936eSBarry Smith { 1624f11a936eSBarry Smith PetscErrorCode ierr; 1625f11a936eSBarry Smith PetscInt e,nedges,offset; 1626f11a936eSBarry Smith const PetscInt *edges; 1627f11a936eSBarry Smith DM_Network *newDMnetwork = (DM_Network*)dm->data; 1628f11a936eSBarry Smith DMNetworkComponentHeader header; 1629f11a936eSBarry Smith 1630f11a936eSBarry Smith PetscFunctionBegin; 1631f11a936eSBarry Smith ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 1632f11a936eSBarry Smith ierr = PetscBTMemzero(Nsubnet,btable);CHKERRQ(ierr); 1633f11a936eSBarry Smith for (e=0; e<nedges; e++) { 1634f11a936eSBarry Smith ierr = PetscSectionGetOffset(newDMnetwork->DataSection,edges[e],&offset);CHKERRQ(ierr); 1635f11a936eSBarry Smith header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset); 1636f11a936eSBarry Smith ierr = PetscBTSet(btable,header->subnetid);CHKERRQ(ierr); 1637f11a936eSBarry Smith } 1638f11a936eSBarry Smith PetscFunctionReturn(0); 1639f11a936eSBarry Smith } 1640f11a936eSBarry Smith 16415f2c45f1SShri Abhyankar /*@ 16422bf73ac6SHong Zhang DMNetworkDistribute - Distributes the network and moves associated component data 16435f2c45f1SShri Abhyankar 16445f2c45f1SShri Abhyankar Collective 16455f2c45f1SShri Abhyankar 1646d8d19677SJose E. Roman Input Parameters: 1647d3464fd4SAdrian Maldonado + DM - the DMNetwork object 16482bf73ac6SHong Zhang - overlap - the overlap of partitions, 0 is the default 16495f2c45f1SShri Abhyankar 16505b3f975aSHong Zhang Options Database Key: 16515b3f975aSHong Zhang + -dmnetwork_view - Calls DMView() at the conclusion of DMSetUp() 16525b3f975aSHong Zhang - -dmnetwork_view_distributed - Calls DMView() at the conclusion of DMNetworkDistribute() 16535b3f975aSHong Zhang 16545f2c45f1SShri Abhyankar Notes: 16558b171c8eSHong Zhang Distributes the network with <overlap>-overlapping partitioning of the edges. 16565f2c45f1SShri Abhyankar 16575f2c45f1SShri Abhyankar Level: intermediate 16585f2c45f1SShri Abhyankar 16592bf73ac6SHong Zhang .seealso: DMNetworkCreate() 16605f2c45f1SShri Abhyankar @*/ 1661d3464fd4SAdrian Maldonado PetscErrorCode DMNetworkDistribute(DM *dm,PetscInt overlap) 16625f2c45f1SShri Abhyankar { 1663d3464fd4SAdrian Maldonado MPI_Comm comm; 16645f2c45f1SShri Abhyankar PetscErrorCode ierr; 1665d3464fd4SAdrian Maldonado PetscMPIInt size; 1666d3464fd4SAdrian Maldonado DM_Network *oldDMnetwork = (DM_Network*)((*dm)->data); 1667d3464fd4SAdrian Maldonado DM_Network *newDMnetwork; 1668caf410d2SHong Zhang PetscSF pointsf=NULL; 16695f2c45f1SShri Abhyankar DM newDM; 1670f11a936eSBarry Smith PetscInt j,e,v,offset,*subnetvtx,*subnetedge,Nsubnet,gidx,svtx_idx,nv; 16712bf73ac6SHong Zhang PetscInt to_net,from_net,*svto; 1672f11a936eSBarry Smith PetscBT btable; 167351ac5effSHong Zhang PetscPartitioner part; 1674b9c6e19dSShri Abhyankar DMNetworkComponentHeader header; 16755f2c45f1SShri Abhyankar 16765f2c45f1SShri Abhyankar PetscFunctionBegin; 1677d3464fd4SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)*dm,&comm);CHKERRQ(ierr); 1678ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 1679d3464fd4SAdrian Maldonado if (size == 1) PetscFunctionReturn(0); 1680d3464fd4SAdrian Maldonado 16815b3f975aSHong Zhang if (overlap) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"overlap %D != 0 is not supported yet",overlap); 16825b3f975aSHong Zhang 16832bf73ac6SHong 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. */ 1684d3464fd4SAdrian Maldonado ierr = DMNetworkCreate(PetscObjectComm((PetscObject)*dm),&newDM);CHKERRQ(ierr); 16855f2c45f1SShri Abhyankar newDMnetwork = (DM_Network*)newDM->data; 168654dfd506SHong Zhang newDMnetwork->max_comps_registered = oldDMnetwork->max_comps_registered; 168754dfd506SHong Zhang ierr = PetscMalloc1(newDMnetwork->max_comps_registered,&newDMnetwork->component);CHKERRQ(ierr); 168851ac5effSHong Zhang 168951ac5effSHong Zhang /* Enable runtime options for petscpartitioner */ 169051ac5effSHong Zhang ierr = DMPlexGetPartitioner(oldDMnetwork->plex,&part);CHKERRQ(ierr); 169151ac5effSHong Zhang ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); 169251ac5effSHong Zhang 16932bf73ac6SHong Zhang /* Distribute plex dm */ 169480cf41d5SMatthew G. Knepley ierr = DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr); 169551ac5effSHong Zhang 16965f2c45f1SShri Abhyankar /* Distribute dof section */ 16972bf73ac6SHong Zhang ierr = PetscSectionCreate(comm,&newDMnetwork->DofSection);CHKERRQ(ierr); 16985f2c45f1SShri Abhyankar ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr); 169951ac5effSHong Zhang 17005f2c45f1SShri Abhyankar /* Distribute data and associated section */ 17012bf73ac6SHong Zhang ierr = PetscSectionCreate(comm,&newDMnetwork->DataSection);CHKERRQ(ierr); 170231da1fc8SHong Zhang ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPIU_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr); 170324121865SAdrian Maldonado 17045f2c45f1SShri Abhyankar ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr); 17055f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr); 17065f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr); 17075f2c45f1SShri Abhyankar newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart; 17086fefedf4SHong Zhang newDMnetwork->nVertices = newDMnetwork->vEnd - newDMnetwork->vStart; 17096fefedf4SHong Zhang newDMnetwork->NVertices = oldDMnetwork->NVertices; 17105f2c45f1SShri Abhyankar newDMnetwork->NEdges = oldDMnetwork->NEdges; 1711f11a936eSBarry Smith newDMnetwork->svtable = oldDMnetwork->svtable; /* global table! */ 17122bf73ac6SHong Zhang oldDMnetwork->svtable = NULL; 171324121865SAdrian Maldonado 17141bb6d2a8SBarry Smith /* Set Dof section as the section for dm */ 171592fd8e1eSJed Brown ierr = DMSetLocalSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr); 1716e87a4003SBarry Smith ierr = DMGetGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr); 17175f2c45f1SShri Abhyankar 1718b9c6e19dSShri Abhyankar /* Setup subnetwork info in the newDM */ 17192bf73ac6SHong Zhang newDMnetwork->Nsubnet = oldDMnetwork->Nsubnet; 17202bf73ac6SHong Zhang newDMnetwork->Nsvtx = oldDMnetwork->Nsvtx; 17212bf73ac6SHong Zhang oldDMnetwork->Nsvtx = 0; 17222bf73ac6SHong Zhang newDMnetwork->svtx = oldDMnetwork->svtx; /* global vertices! */ 17232bf73ac6SHong Zhang oldDMnetwork->svtx = NULL; 17242bf73ac6SHong Zhang ierr = PetscCalloc1(newDMnetwork->Nsubnet,&newDMnetwork->subnet);CHKERRQ(ierr); 17252bf73ac6SHong Zhang 17262bf73ac6SHong Zhang /* Copy over the global number of vertices and edges in each subnetwork. 17272bf73ac6SHong Zhang Note: these are calculated in DMNetworkLayoutSetUp() 1728b9c6e19dSShri Abhyankar */ 1729f11a936eSBarry Smith Nsubnet = newDMnetwork->Nsubnet; 1730f11a936eSBarry Smith for (j = 0; j < Nsubnet; j++) { 1731b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nvtx = oldDMnetwork->subnet[j].Nvtx; 1732b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nedge = oldDMnetwork->subnet[j].Nedge; 1733b9c6e19dSShri Abhyankar } 1734b9c6e19dSShri Abhyankar 1735f11a936eSBarry Smith /* Count local nedges for subnetworks */ 1736b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++) { 1737b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 173854dfd506SHong Zhang header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset); 173954dfd506SHong Zhang /* Update pointers */ 174054dfd506SHong Zhang header->size = (PetscInt*)(header + 1); 174154dfd506SHong Zhang header->key = header->size + header->maxcomps; 174254dfd506SHong Zhang header->offset = header->key + header->maxcomps; 174354dfd506SHong Zhang header->nvar = header->offset + header->maxcomps; 174454dfd506SHong Zhang header->offsetvarrel = header->nvar + header->maxcomps; 174554dfd506SHong Zhang 1746b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nedge++; 1747b9c6e19dSShri Abhyankar } 1748b9c6e19dSShri Abhyankar 1749f11a936eSBarry Smith /* Count local nvtx for subnetworks */ 1750f11a936eSBarry Smith ierr = PetscBTCreate(Nsubnet,&btable);CHKERRQ(ierr); 1751b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++) { 1752b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1753b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 175454dfd506SHong Zhang /* Update pointers */ 175554dfd506SHong Zhang header->size = (PetscInt*)(header + 1); 175654dfd506SHong Zhang header->key = header->size + header->maxcomps; 175754dfd506SHong Zhang header->offset = header->key + header->maxcomps; 175854dfd506SHong Zhang header->nvar = header->offset + header->maxcomps; 175954dfd506SHong Zhang header->offsetvarrel = header->nvar + header->maxcomps; 176054dfd506SHong Zhang 17612bf73ac6SHong Zhang /* shared vertices: use gidx=header->index to check if v is a shared vertex */ 17622bf73ac6SHong Zhang gidx = header->index; 17632bf73ac6SHong Zhang ierr = PetscTableFind(newDMnetwork->svtable,gidx+1,&svtx_idx);CHKERRQ(ierr); 17642bf73ac6SHong Zhang svtx_idx--; 17652bf73ac6SHong Zhang 17662bf73ac6SHong Zhang if (svtx_idx < 0) { /* not a shared vertex */ 1767b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nvtx++; 17682bf73ac6SHong Zhang } else { /* a shared vertex belongs to more than one subnetworks, it is being counted by multiple subnets */ 1769f11a936eSBarry Smith ierr = SetSubnetIdLookupBT(newDM,v,Nsubnet,btable);CHKERRQ(ierr); 1770f11a936eSBarry Smith 17712bf73ac6SHong Zhang from_net = newDMnetwork->svtx[svtx_idx].sv[0]; 1772f11a936eSBarry Smith if (PetscBTLookup(btable,from_net)) newDMnetwork->subnet[from_net].nvtx++; /* sv is on from_net */ 1773f11a936eSBarry Smith 17742bf73ac6SHong Zhang for (j=1; j<newDMnetwork->svtx[svtx_idx].n; j++) { 17752bf73ac6SHong Zhang svto = newDMnetwork->svtx[svtx_idx].sv + 2*j; 17762bf73ac6SHong Zhang to_net = svto[0]; 1777f11a936eSBarry Smith if (PetscBTLookup(btable,to_net)) newDMnetwork->subnet[to_net].nvtx++; /* sv is on to_net */ 17782bf73ac6SHong Zhang } 17792bf73ac6SHong Zhang } 1780b9c6e19dSShri Abhyankar } 1781b9c6e19dSShri Abhyankar 17822bf73ac6SHong Zhang /* Get total local nvtx for subnetworks */ 17832bf73ac6SHong Zhang nv = 0; 1784f11a936eSBarry Smith for (j=0; j<Nsubnet; j++) nv += newDMnetwork->subnet[j].nvtx; 17852bf73ac6SHong Zhang nv += newDMnetwork->Nsvtx; 1786caf410d2SHong Zhang 17872bf73ac6SHong Zhang /* Now create the vertices and edge arrays for the subnetworks */ 1788f11a936eSBarry Smith ierr = PetscCalloc2(newDMnetwork->nEdges,&subnetedge,nv,&subnetvtx);CHKERRQ(ierr); /* Maps local vertex to local subnetwork's vertex */ 1789f11a936eSBarry Smith newDMnetwork->subnetedge = subnetedge; 17902bf73ac6SHong Zhang newDMnetwork->subnetvtx = subnetvtx; 1791f11a936eSBarry Smith for (j=0; j < newDMnetwork->Nsubnet; j++) { 1792f11a936eSBarry Smith newDMnetwork->subnet[j].edges = subnetedge; 1793f11a936eSBarry Smith subnetedge += newDMnetwork->subnet[j].nedge; 17942bf73ac6SHong Zhang 1795caf410d2SHong Zhang newDMnetwork->subnet[j].vertices = subnetvtx; 1796caf410d2SHong Zhang subnetvtx += newDMnetwork->subnet[j].nvtx; 1797caf410d2SHong Zhang 17982bf73ac6SHong 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. */ 1799b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].nvtx = newDMnetwork->subnet[j].nedge = 0; 1800b9c6e19dSShri Abhyankar } 18012bf73ac6SHong Zhang newDMnetwork->svertices = subnetvtx; 1802b9c6e19dSShri Abhyankar 18032bf73ac6SHong Zhang /* Set the edges and vertices in each subnetwork */ 1804b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++) { 1805b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 1806b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1807b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].edges[newDMnetwork->subnet[header->subnetid].nedge++] = e; 1808b9c6e19dSShri Abhyankar } 1809b9c6e19dSShri Abhyankar 18102bf73ac6SHong Zhang nv = 0; 1811b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++) { 1812b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1813b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 18142bf73ac6SHong Zhang 18152bf73ac6SHong Zhang /* coupling vertices: use gidx = header->index to check if v is a coupling vertex */ 18162bf73ac6SHong Zhang ierr = PetscTableFind(newDMnetwork->svtable,header->index+1,&svtx_idx);CHKERRQ(ierr); 18172bf73ac6SHong Zhang svtx_idx--; 18182bf73ac6SHong Zhang if (svtx_idx < 0) { 1819b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].vertices[newDMnetwork->subnet[header->subnetid].nvtx++] = v; 18202bf73ac6SHong Zhang } else { /* a shared vertex */ 18212bf73ac6SHong Zhang newDMnetwork->svertices[nv++] = v; 18222bf73ac6SHong Zhang 1823f11a936eSBarry Smith /* add all subnetid for this shared vertex in this process to btable */ 1824f11a936eSBarry Smith ierr = SetSubnetIdLookupBT(newDM,v,Nsubnet,btable);CHKERRQ(ierr); 1825f11a936eSBarry Smith 18262bf73ac6SHong Zhang from_net = newDMnetwork->svtx[svtx_idx].sv[0]; 1827f11a936eSBarry Smith if (PetscBTLookup(btable,from_net)) 18282bf73ac6SHong Zhang newDMnetwork->subnet[from_net].vertices[newDMnetwork->subnet[from_net].nvtx++] = v; 18292bf73ac6SHong Zhang 18302bf73ac6SHong Zhang for (j=1; j<newDMnetwork->svtx[svtx_idx].n; j++) { 18312bf73ac6SHong Zhang svto = newDMnetwork->svtx[svtx_idx].sv + 2*j; 18322bf73ac6SHong Zhang to_net = svto[0]; 1833f11a936eSBarry Smith if (PetscBTLookup(btable,to_net)) 18342bf73ac6SHong Zhang newDMnetwork->subnet[to_net].vertices[newDMnetwork->subnet[to_net].nvtx++] = v; 1835b9c6e19dSShri Abhyankar } 18362bf73ac6SHong Zhang } 18372bf73ac6SHong Zhang } 18382bf73ac6SHong Zhang newDMnetwork->nsvtx = nv; /* num of local shared vertices */ 1839b9c6e19dSShri Abhyankar 1840caf410d2SHong Zhang newDM->setupcalled = (*dm)->setupcalled; 184122bbedd7SHong Zhang newDMnetwork->distributecalled = PETSC_TRUE; 1842caf410d2SHong Zhang 18432bf73ac6SHong Zhang /* Free spaces */ 184424121865SAdrian Maldonado ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr); 1845d3464fd4SAdrian Maldonado ierr = DMDestroy(dm);CHKERRQ(ierr); 1846f11a936eSBarry Smith ierr = PetscBTDestroy(&btable);CHKERRQ(ierr); 18472bf73ac6SHong Zhang 18485b3f975aSHong Zhang /* View distributed dmnetwork */ 18495b3f975aSHong Zhang ierr = DMViewFromOptions(newDM,NULL,"-dmnetwork_view_distributed");CHKERRQ(ierr); 18505b3f975aSHong Zhang 1851d3464fd4SAdrian Maldonado *dm = newDM; 18525f2c45f1SShri Abhyankar PetscFunctionReturn(0); 18535f2c45f1SShri Abhyankar } 18545f2c45f1SShri Abhyankar 185524121865SAdrian Maldonado /*@C 18562bf73ac6SHong Zhang PetscSFGetSubSF - Returns an SF for a specific subset of points. Leaves are re-numbered to reflect the new ordering 18572bf73ac6SHong Zhang 18582bf73ac6SHong Zhang Collective 185924121865SAdrian Maldonado 186024121865SAdrian Maldonado Input Parameters: 18619dddd249SSatish Balay + mainSF - the original SF structure 186224121865SAdrian Maldonado - map - a ISLocalToGlobal mapping that contains the subset of points 186324121865SAdrian Maldonado 186497bb3fdcSJose E. Roman Output Parameter: 18659dddd249SSatish Balay . subSF - a subset of the mainSF for the desired subset. 1866ee300463SSatish Balay 1867ee300463SSatish Balay Level: intermediate 18687d928bffSSatish Balay @*/ 18699dddd249SSatish Balay PetscErrorCode PetscSFGetSubSF(PetscSF mainsf,ISLocalToGlobalMapping map,PetscSF *subSF) 18702bf73ac6SHong Zhang { 187124121865SAdrian Maldonado PetscErrorCode ierr; 187224121865SAdrian Maldonado PetscInt nroots, nleaves, *ilocal_sub; 187324121865SAdrian Maldonado PetscInt i, *ilocal_map, nroots_sub, nleaves_sub = 0; 187424121865SAdrian Maldonado PetscInt *local_points, *remote_points; 187524121865SAdrian Maldonado PetscSFNode *iremote_sub; 187624121865SAdrian Maldonado const PetscInt *ilocal; 187724121865SAdrian Maldonado const PetscSFNode *iremote; 187824121865SAdrian Maldonado 187924121865SAdrian Maldonado PetscFunctionBegin; 18809dddd249SSatish Balay ierr = PetscSFGetGraph(mainsf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr); 188124121865SAdrian Maldonado 188224121865SAdrian Maldonado /* Look for leaves that pertain to the subset of points. Get the local ordering */ 188324121865SAdrian Maldonado ierr = PetscMalloc1(nleaves,&ilocal_map);CHKERRQ(ierr); 188424121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nleaves,ilocal,NULL,ilocal_map);CHKERRQ(ierr); 188524121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 188624121865SAdrian Maldonado if (ilocal_map[i] != -1) nleaves_sub += 1; 188724121865SAdrian Maldonado } 188824121865SAdrian Maldonado /* Re-number ilocal with subset numbering. Need information from roots */ 188924121865SAdrian Maldonado ierr = PetscMalloc2(nroots,&local_points,nroots,&remote_points);CHKERRQ(ierr); 189024121865SAdrian Maldonado for (i = 0; i < nroots; i++) local_points[i] = i; 189124121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nroots,local_points,NULL,local_points);CHKERRQ(ierr); 1892ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(mainsf, MPIU_INT, local_points, remote_points,MPI_REPLACE);CHKERRQ(ierr); 1893ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(mainsf, MPIU_INT, local_points, remote_points,MPI_REPLACE);CHKERRQ(ierr); 189424121865SAdrian Maldonado /* Fill up graph using local (that is, local to the subset) numbering. */ 18954b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&ilocal_sub);CHKERRQ(ierr); 18964b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&iremote_sub);CHKERRQ(ierr); 189724121865SAdrian Maldonado nleaves_sub = 0; 189824121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 189924121865SAdrian Maldonado if (ilocal_map[i] != -1) { 190024121865SAdrian Maldonado ilocal_sub[nleaves_sub] = ilocal_map[i]; 19014b70a8deSAdrian Maldonado iremote_sub[nleaves_sub].rank = iremote[i].rank; 190224121865SAdrian Maldonado iremote_sub[nleaves_sub].index = remote_points[ilocal[i]]; 190324121865SAdrian Maldonado nleaves_sub += 1; 190424121865SAdrian Maldonado } 190524121865SAdrian Maldonado } 190624121865SAdrian Maldonado ierr = PetscFree2(local_points,remote_points);CHKERRQ(ierr); 190724121865SAdrian Maldonado ierr = ISLocalToGlobalMappingGetSize(map,&nroots_sub);CHKERRQ(ierr); 190824121865SAdrian Maldonado 190924121865SAdrian Maldonado /* Create new subSF */ 191024121865SAdrian Maldonado ierr = PetscSFCreate(PETSC_COMM_WORLD,subSF);CHKERRQ(ierr); 191124121865SAdrian Maldonado ierr = PetscSFSetFromOptions(*subSF);CHKERRQ(ierr); 19124b70a8deSAdrian Maldonado ierr = PetscSFSetGraph(*subSF,nroots_sub,nleaves_sub,ilocal_sub,PETSC_OWN_POINTER,iremote_sub,PETSC_COPY_VALUES);CHKERRQ(ierr); 191324121865SAdrian Maldonado ierr = PetscFree(ilocal_map);CHKERRQ(ierr); 19144b70a8deSAdrian Maldonado ierr = PetscFree(iremote_sub);CHKERRQ(ierr); 191524121865SAdrian Maldonado PetscFunctionReturn(0); 191624121865SAdrian Maldonado } 191724121865SAdrian Maldonado 19185f2c45f1SShri Abhyankar /*@C 19195f2c45f1SShri Abhyankar DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point 19205f2c45f1SShri Abhyankar 19215f2c45f1SShri Abhyankar Not Collective 19225f2c45f1SShri Abhyankar 19235f2c45f1SShri Abhyankar Input Parameters: 19242bf73ac6SHong Zhang + dm - the DMNetwork object 19255f2c45f1SShri Abhyankar - p - the vertex point 19265f2c45f1SShri Abhyankar 1927fd292e60Sprj- Output Parameters: 19285f2c45f1SShri Abhyankar + nedges - number of edges connected to this vertex point 19292bf73ac6SHong Zhang - edges - list of edge points 19305f2c45f1SShri Abhyankar 193197bb938eSShri Abhyankar Level: beginner 19325f2c45f1SShri Abhyankar 19335f2c45f1SShri Abhyankar Fortran Notes: 19345f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 19355f2c45f1SShri Abhyankar include petsc.h90 in your code. 19365f2c45f1SShri Abhyankar 19372bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkGetConnectedVertices() 19385f2c45f1SShri Abhyankar @*/ 19395f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[]) 19405f2c45f1SShri Abhyankar { 19415f2c45f1SShri Abhyankar PetscErrorCode ierr; 19425f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 19435f2c45f1SShri Abhyankar 19445f2c45f1SShri Abhyankar PetscFunctionBegin; 19455f2c45f1SShri Abhyankar ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr); 1946a9b4a83eSHong Zhang if (edges) {ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr);} 19475f2c45f1SShri Abhyankar PetscFunctionReturn(0); 19485f2c45f1SShri Abhyankar } 19495f2c45f1SShri Abhyankar 19505f2c45f1SShri Abhyankar /*@C 1951d842c372SHong Zhang DMNetworkGetConnectedVertices - Return the connected vertices for this edge point 19525f2c45f1SShri Abhyankar 19535f2c45f1SShri Abhyankar Not Collective 19545f2c45f1SShri Abhyankar 19555f2c45f1SShri Abhyankar Input Parameters: 19562bf73ac6SHong Zhang + dm - the DMNetwork object 19575f2c45f1SShri Abhyankar - p - the edge point 19585f2c45f1SShri Abhyankar 1959fd292e60Sprj- Output Parameters: 19605f2c45f1SShri Abhyankar . vertices - vertices connected to this edge 19615f2c45f1SShri Abhyankar 196297bb938eSShri Abhyankar Level: beginner 19635f2c45f1SShri Abhyankar 19645f2c45f1SShri Abhyankar Fortran Notes: 19655f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 19665f2c45f1SShri Abhyankar include petsc.h90 in your code. 19675f2c45f1SShri Abhyankar 19682bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkGetSupportingEdges() 19695f2c45f1SShri Abhyankar @*/ 1970d842c372SHong Zhang PetscErrorCode DMNetworkGetConnectedVertices(DM dm,PetscInt edge,const PetscInt *vertices[]) 19715f2c45f1SShri Abhyankar { 19725f2c45f1SShri Abhyankar PetscErrorCode ierr; 19735f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 19745f2c45f1SShri Abhyankar 19755f2c45f1SShri Abhyankar PetscFunctionBegin; 19765f2c45f1SShri Abhyankar ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr); 19775f2c45f1SShri Abhyankar PetscFunctionReturn(0); 19785f2c45f1SShri Abhyankar } 19795f2c45f1SShri Abhyankar 19805f2c45f1SShri Abhyankar /*@ 19812bf73ac6SHong Zhang DMNetworkIsSharedVertex - Returns TRUE if the vertex is shared by subnetworks 19822bf73ac6SHong Zhang 19832bf73ac6SHong Zhang Not Collective 19842bf73ac6SHong Zhang 19852bf73ac6SHong Zhang Input Parameters: 19862bf73ac6SHong Zhang + dm - the DMNetwork object 19872bf73ac6SHong Zhang - p - the vertex point 19882bf73ac6SHong Zhang 19892bf73ac6SHong Zhang Output Parameter: 19902bf73ac6SHong Zhang . flag - TRUE if the vertex is shared by subnetworks 19912bf73ac6SHong Zhang 19922bf73ac6SHong Zhang Level: beginner 19932bf73ac6SHong Zhang 19942bf73ac6SHong Zhang .seealso: DMNetworkAddSharedVertices(), DMNetworkIsGhostVertex() 19952bf73ac6SHong Zhang @*/ 19962bf73ac6SHong Zhang PetscErrorCode DMNetworkIsSharedVertex(DM dm,PetscInt p,PetscBool *flag) 19972bf73ac6SHong Zhang { 19982bf73ac6SHong Zhang PetscErrorCode ierr; 19992bf73ac6SHong Zhang PetscInt i; 20002bf73ac6SHong Zhang 20012bf73ac6SHong Zhang PetscFunctionBegin; 20022bf73ac6SHong Zhang *flag = PETSC_FALSE; 20032bf73ac6SHong Zhang 20042bf73ac6SHong Zhang if (dm->setupcalled) { /* DMNetworkGetGlobalVertexIndex() requires DMSetUp() be called */ 20052bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 20062bf73ac6SHong Zhang PetscInt gidx; 20072bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,p,&gidx);CHKERRQ(ierr); 20082bf73ac6SHong Zhang ierr = PetscTableFind(network->svtable,gidx+1,&i);CHKERRQ(ierr); 20092bf73ac6SHong Zhang if (i) *flag = PETSC_TRUE; 20102bf73ac6SHong Zhang } else { /* would be removed? */ 20112bf73ac6SHong Zhang PetscInt nv; 20122bf73ac6SHong Zhang const PetscInt *vtx; 20132bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&nv,&vtx);CHKERRQ(ierr); 20142bf73ac6SHong Zhang for (i=0; i<nv; i++) { 20152bf73ac6SHong Zhang if (p == vtx[i]) { 20162bf73ac6SHong Zhang *flag = PETSC_TRUE; 20172bf73ac6SHong Zhang break; 20182bf73ac6SHong Zhang } 20192bf73ac6SHong Zhang } 20202bf73ac6SHong Zhang } 20212bf73ac6SHong Zhang PetscFunctionReturn(0); 20222bf73ac6SHong Zhang } 20232bf73ac6SHong Zhang 20242bf73ac6SHong Zhang /*@ 20255f2c45f1SShri Abhyankar DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex 20265f2c45f1SShri Abhyankar 20275f2c45f1SShri Abhyankar Not Collective 20285f2c45f1SShri Abhyankar 20295f2c45f1SShri Abhyankar Input Parameters: 20302bf73ac6SHong Zhang + dm - the DMNetwork object 2031a2b725a8SWilliam Gropp - p - the vertex point 20325f2c45f1SShri Abhyankar 20335f2c45f1SShri Abhyankar Output Parameter: 20345f2c45f1SShri Abhyankar . isghost - TRUE if the vertex is a ghost point 20355f2c45f1SShri Abhyankar 203697bb938eSShri Abhyankar Level: beginner 20375f2c45f1SShri Abhyankar 20382bf73ac6SHong Zhang .seealso: DMNetworkGetConnectedVertices(), DMNetworkGetVertexRange(), DMNetworkIsSharedVertex() 20395f2c45f1SShri Abhyankar @*/ 20405f2c45f1SShri Abhyankar PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost) 20415f2c45f1SShri Abhyankar { 20425f2c45f1SShri Abhyankar PetscErrorCode ierr; 20435f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 20445f2c45f1SShri Abhyankar PetscInt offsetg; 20455f2c45f1SShri Abhyankar PetscSection sectiong; 20465f2c45f1SShri Abhyankar 20475f2c45f1SShri Abhyankar PetscFunctionBegin; 20485f2c45f1SShri Abhyankar *isghost = PETSC_FALSE; 2049e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§iong);CHKERRQ(ierr); 20505f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr); 20515f2c45f1SShri Abhyankar if (offsetg < 0) *isghost = PETSC_TRUE; 20525f2c45f1SShri Abhyankar PetscFunctionReturn(0); 20535f2c45f1SShri Abhyankar } 20545f2c45f1SShri Abhyankar 20555f2c45f1SShri Abhyankar PetscErrorCode DMSetUp_Network(DM dm) 20565f2c45f1SShri Abhyankar { 20575f2c45f1SShri Abhyankar PetscErrorCode ierr; 20585f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 20595f2c45f1SShri Abhyankar 20605f2c45f1SShri Abhyankar PetscFunctionBegin; 20615f2c45f1SShri Abhyankar ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr); 20625f2c45f1SShri Abhyankar ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr); 20635f2c45f1SShri Abhyankar 206492fd8e1eSJed Brown ierr = DMSetLocalSection(network->plex,network->DofSection);CHKERRQ(ierr); 2065e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr); 20669e1d080bSHong Zhang 20679e1d080bSHong Zhang dm->setupcalled = PETSC_TRUE; 20685b3f975aSHong Zhang 20695b3f975aSHong Zhang /* View dmnetwork */ 20705b3f975aSHong Zhang ierr = DMViewFromOptions(dm,NULL,"-dmnetwork_view");CHKERRQ(ierr); 20715f2c45f1SShri Abhyankar PetscFunctionReturn(0); 20725f2c45f1SShri Abhyankar } 20735f2c45f1SShri Abhyankar 20741ad426b7SHong Zhang /*@ 207517df6e9eSHong Zhang DMNetworkHasJacobian - Sets global flag for using user's sub Jacobian matrices 20761ad426b7SHong Zhang -- replaced by DMNetworkSetOption(network,userjacobian,PETSC_TURE)? 20771ad426b7SHong Zhang 20781ad426b7SHong Zhang Collective 20791ad426b7SHong Zhang 20801ad426b7SHong Zhang Input Parameters: 20812bf73ac6SHong Zhang + dm - the DMNetwork object 208283b2e829SHong Zhang . eflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for edges 208383b2e829SHong Zhang - vflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for vertices 20841ad426b7SHong Zhang 20851ad426b7SHong Zhang Level: intermediate 20861ad426b7SHong Zhang 20871ad426b7SHong Zhang @*/ 208883b2e829SHong Zhang PetscErrorCode DMNetworkHasJacobian(DM dm,PetscBool eflg,PetscBool vflg) 20891ad426b7SHong Zhang { 20901ad426b7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 20918675203cSHong Zhang PetscErrorCode ierr; 209266b4e0ffSHong Zhang PetscInt nVertices = network->nVertices; 20931ad426b7SHong Zhang 20941ad426b7SHong Zhang PetscFunctionBegin; 209583b2e829SHong Zhang network->userEdgeJacobian = eflg; 209683b2e829SHong Zhang network->userVertexJacobian = vflg; 20978675203cSHong Zhang 20988675203cSHong Zhang if (eflg && !network->Je) { 20998675203cSHong Zhang ierr = PetscCalloc1(3*network->nEdges,&network->Je);CHKERRQ(ierr); 21008675203cSHong Zhang } 21018675203cSHong Zhang 210266b4e0ffSHong Zhang if (vflg && !network->Jv && nVertices) { 21038675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 210466b4e0ffSHong Zhang PetscInt nedges_total; 21058675203cSHong Zhang const PetscInt *edges; 21068675203cSHong Zhang 21078675203cSHong Zhang /* count nvertex_total */ 21088675203cSHong Zhang nedges_total = 0; 21098675203cSHong Zhang ierr = PetscMalloc1(nVertices+1,&vptr);CHKERRQ(ierr); 21108675203cSHong Zhang 21118675203cSHong Zhang vptr[0] = 0; 21128675203cSHong Zhang for (i=0; i<nVertices; i++) { 21138675203cSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,i+vStart,&nedges,&edges);CHKERRQ(ierr); 21148675203cSHong Zhang nedges_total += nedges; 21158675203cSHong Zhang vptr[i+1] = vptr[i] + 2*nedges + 1; 21168675203cSHong Zhang } 21178675203cSHong Zhang 21188675203cSHong Zhang ierr = PetscCalloc1(2*nedges_total+nVertices,&network->Jv);CHKERRQ(ierr); 21198675203cSHong Zhang network->Jvptr = vptr; 21208675203cSHong Zhang } 21211ad426b7SHong Zhang PetscFunctionReturn(0); 21221ad426b7SHong Zhang } 21231ad426b7SHong Zhang 21241ad426b7SHong Zhang /*@ 212583b2e829SHong Zhang DMNetworkEdgeSetMatrix - Sets user-provided Jacobian matrices for this edge to the network 212683b2e829SHong Zhang 212783b2e829SHong Zhang Not Collective 212883b2e829SHong Zhang 212983b2e829SHong Zhang Input Parameters: 21302bf73ac6SHong Zhang + dm - the DMNetwork object 213183b2e829SHong Zhang . p - the edge point 21323e97b6e8SHong Zhang - J - array (size = 3) of Jacobian submatrices for this edge point: 21333e97b6e8SHong Zhang J[0]: this edge 2134d842c372SHong Zhang J[1] and J[2]: connected vertices, obtained by calling DMNetworkGetConnectedVertices() 213583b2e829SHong Zhang 213697bb938eSShri Abhyankar Level: advanced 213783b2e829SHong Zhang 21382bf73ac6SHong Zhang .seealso: DMNetworkVertexSetMatrix() 213983b2e829SHong Zhang @*/ 214083b2e829SHong Zhang PetscErrorCode DMNetworkEdgeSetMatrix(DM dm,PetscInt p,Mat J[]) 214183b2e829SHong Zhang { 214283b2e829SHong Zhang DM_Network *network=(DM_Network*)dm->data; 214383b2e829SHong Zhang 214483b2e829SHong Zhang PetscFunctionBegin; 21458675203cSHong Zhang if (!network->Je) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkEdgeSetMatrix"); 21468675203cSHong Zhang 21478675203cSHong Zhang if (J) { 2148883e35e8SHong Zhang network->Je[3*p] = J[0]; 2149883e35e8SHong Zhang network->Je[3*p+1] = J[1]; 2150883e35e8SHong Zhang network->Je[3*p+2] = J[2]; 21518675203cSHong Zhang } 215283b2e829SHong Zhang PetscFunctionReturn(0); 215383b2e829SHong Zhang } 215483b2e829SHong Zhang 215583b2e829SHong Zhang /*@ 215676ddfea5SHong Zhang DMNetworkVertexSetMatrix - Sets user-provided Jacobian matrix for this vertex to the network 21571ad426b7SHong Zhang 21581ad426b7SHong Zhang Not Collective 21591ad426b7SHong Zhang 21601ad426b7SHong Zhang Input Parameters: 21611ad426b7SHong Zhang + dm - The DMNetwork object 21621ad426b7SHong Zhang . p - the vertex point 21633e97b6e8SHong Zhang - J - array of Jacobian (size = 2*(num of supporting edges) + 1) submatrices for this vertex point: 21643e97b6e8SHong Zhang J[0]: this vertex 21653e97b6e8SHong Zhang J[1+2*i]: i-th supporting edge 21663e97b6e8SHong Zhang J[1+2*i+1]: i-th connected vertex 21671ad426b7SHong Zhang 216897bb938eSShri Abhyankar Level: advanced 21691ad426b7SHong Zhang 21702bf73ac6SHong Zhang .seealso: DMNetworkEdgeSetMatrix() 21711ad426b7SHong Zhang @*/ 2172883e35e8SHong Zhang PetscErrorCode DMNetworkVertexSetMatrix(DM dm,PetscInt p,Mat J[]) 21735f2c45f1SShri Abhyankar { 21745f2c45f1SShri Abhyankar PetscErrorCode ierr; 21755f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 21768675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 2177883e35e8SHong Zhang const PetscInt *edges; 21785f2c45f1SShri Abhyankar 21795f2c45f1SShri Abhyankar PetscFunctionBegin; 21808675203cSHong Zhang if (!network->Jv) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkVertexSetMatrix"); 2181883e35e8SHong Zhang 21828675203cSHong Zhang if (J) { 2183883e35e8SHong Zhang vptr = network->Jvptr; 21843e97b6e8SHong Zhang network->Jv[vptr[p-vStart]] = J[0]; /* Set Jacobian for this vertex */ 21853e97b6e8SHong Zhang 21863e97b6e8SHong Zhang /* Set Jacobian for each supporting edge and connected vertex */ 2187883e35e8SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,p,&nedges,&edges);CHKERRQ(ierr); 2188883e35e8SHong Zhang for (i=1; i<=2*nedges; i++) network->Jv[vptr[p-vStart]+i] = J[i]; 21898675203cSHong Zhang } 2190883e35e8SHong Zhang PetscFunctionReturn(0); 2191883e35e8SHong Zhang } 2192883e35e8SHong Zhang 2193e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 21945cf7da58SHong Zhang { 21955cf7da58SHong Zhang PetscErrorCode ierr; 21965cf7da58SHong Zhang PetscInt j; 21975cf7da58SHong Zhang PetscScalar val=(PetscScalar)ncols; 21985cf7da58SHong Zhang 21995cf7da58SHong Zhang PetscFunctionBegin; 22005cf7da58SHong Zhang if (!ghost) { 22015cf7da58SHong Zhang for (j=0; j<nrows; j++) { 22025cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 22035cf7da58SHong Zhang } 22045cf7da58SHong Zhang } else { 22055cf7da58SHong Zhang for (j=0; j<nrows; j++) { 22065cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 22075cf7da58SHong Zhang } 22085cf7da58SHong Zhang } 22095cf7da58SHong Zhang PetscFunctionReturn(0); 22105cf7da58SHong Zhang } 22115cf7da58SHong Zhang 2212e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 22135cf7da58SHong Zhang { 22145cf7da58SHong Zhang PetscErrorCode ierr; 22155cf7da58SHong Zhang PetscInt j,ncols_u; 22165cf7da58SHong Zhang PetscScalar val; 22175cf7da58SHong Zhang 22185cf7da58SHong Zhang PetscFunctionBegin; 22195cf7da58SHong Zhang if (!ghost) { 22205cf7da58SHong Zhang for (j=0; j<nrows; j++) { 22215cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 22225cf7da58SHong Zhang val = (PetscScalar)ncols_u; 22235cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 22245cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 22255cf7da58SHong Zhang } 22265cf7da58SHong Zhang } else { 22275cf7da58SHong Zhang for (j=0; j<nrows; j++) { 22285cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 22295cf7da58SHong Zhang val = (PetscScalar)ncols_u; 22305cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 22315cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 22325cf7da58SHong Zhang } 22335cf7da58SHong Zhang } 22345cf7da58SHong Zhang PetscFunctionReturn(0); 22355cf7da58SHong Zhang } 22365cf7da58SHong Zhang 2237e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 22385cf7da58SHong Zhang { 22395cf7da58SHong Zhang PetscErrorCode ierr; 22405cf7da58SHong Zhang 22415cf7da58SHong Zhang PetscFunctionBegin; 22425cf7da58SHong Zhang if (Ju) { 22435cf7da58SHong Zhang ierr = MatSetPreallocationUserblock_private(Ju,nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 22445cf7da58SHong Zhang } else { 22455cf7da58SHong Zhang ierr = MatSetPreallocationDenseblock_private(nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 22465cf7da58SHong Zhang } 22475cf7da58SHong Zhang PetscFunctionReturn(0); 22485cf7da58SHong Zhang } 22495cf7da58SHong Zhang 2250e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 2251883e35e8SHong Zhang { 2252883e35e8SHong Zhang PetscErrorCode ierr; 2253883e35e8SHong Zhang PetscInt j,*cols; 2254883e35e8SHong Zhang PetscScalar *zeros; 2255883e35e8SHong Zhang 2256883e35e8SHong Zhang PetscFunctionBegin; 2257883e35e8SHong Zhang ierr = PetscCalloc2(ncols,&cols,nrows*ncols,&zeros);CHKERRQ(ierr); 2258883e35e8SHong Zhang for (j=0; j<ncols; j++) cols[j] = j+ cstart; 2259883e35e8SHong Zhang ierr = MatSetValues(*J,nrows,rows,ncols,cols,zeros,INSERT_VALUES);CHKERRQ(ierr); 2260883e35e8SHong Zhang ierr = PetscFree2(cols,zeros);CHKERRQ(ierr); 22611ad426b7SHong Zhang PetscFunctionReturn(0); 22621ad426b7SHong Zhang } 2263a4e85ca8SHong Zhang 2264e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 22653e97b6e8SHong Zhang { 22663e97b6e8SHong Zhang PetscErrorCode ierr; 22673e97b6e8SHong Zhang PetscInt j,M,N,row,col,ncols_u; 22683e97b6e8SHong Zhang const PetscInt *cols; 22693e97b6e8SHong Zhang PetscScalar zero=0.0; 22703e97b6e8SHong Zhang 22713e97b6e8SHong Zhang PetscFunctionBegin; 22723e97b6e8SHong Zhang ierr = MatGetSize(Ju,&M,&N);CHKERRQ(ierr); 22733e97b6e8SHong 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); 22743e97b6e8SHong Zhang 22753e97b6e8SHong Zhang for (row=0; row<nrows; row++) { 22763e97b6e8SHong Zhang ierr = MatGetRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 22773e97b6e8SHong Zhang for (j=0; j<ncols_u; j++) { 22783e97b6e8SHong Zhang col = cols[j] + cstart; 22793e97b6e8SHong Zhang ierr = MatSetValues(*J,1,&rows[row],1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr); 22803e97b6e8SHong Zhang } 22813e97b6e8SHong Zhang ierr = MatRestoreRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 22823e97b6e8SHong Zhang } 22833e97b6e8SHong Zhang PetscFunctionReturn(0); 22843e97b6e8SHong Zhang } 22851ad426b7SHong Zhang 2286e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 2287a4e85ca8SHong Zhang { 2288a4e85ca8SHong Zhang PetscErrorCode ierr; 2289f4431b8cSHong Zhang 2290a4e85ca8SHong Zhang PetscFunctionBegin; 2291a4e85ca8SHong Zhang if (Ju) { 2292a4e85ca8SHong Zhang ierr = MatSetUserblock_private(Ju,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 2293a4e85ca8SHong Zhang } else { 2294a4e85ca8SHong Zhang ierr = MatSetDenseblock_private(nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 2295a4e85ca8SHong Zhang } 2296a4e85ca8SHong Zhang PetscFunctionReturn(0); 2297a4e85ca8SHong Zhang } 2298a4e85ca8SHong Zhang 229924121865SAdrian 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. 230024121865SAdrian Maldonado */ 230124121865SAdrian Maldonado PetscErrorCode CreateSubGlobalToLocalMapping_private(PetscSection globalsec, PetscSection localsec, ISLocalToGlobalMapping *ltog) 230224121865SAdrian Maldonado { 230324121865SAdrian Maldonado PetscErrorCode ierr; 230424121865SAdrian Maldonado PetscInt i,size,dof; 230524121865SAdrian Maldonado PetscInt *glob2loc; 230624121865SAdrian Maldonado 230724121865SAdrian Maldonado PetscFunctionBegin; 230824121865SAdrian Maldonado ierr = PetscSectionGetStorageSize(localsec,&size);CHKERRQ(ierr); 230924121865SAdrian Maldonado ierr = PetscMalloc1(size,&glob2loc);CHKERRQ(ierr); 231024121865SAdrian Maldonado 231124121865SAdrian Maldonado for (i = 0; i < size; i++) { 231224121865SAdrian Maldonado ierr = PetscSectionGetOffset(globalsec,i,&dof);CHKERRQ(ierr); 231324121865SAdrian Maldonado dof = (dof >= 0) ? dof : -(dof + 1); 231424121865SAdrian Maldonado glob2loc[i] = dof; 231524121865SAdrian Maldonado } 231624121865SAdrian Maldonado 231724121865SAdrian Maldonado ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,size,glob2loc,PETSC_OWN_POINTER,ltog);CHKERRQ(ierr); 231824121865SAdrian Maldonado #if 0 231924121865SAdrian Maldonado ierr = PetscIntView(size,glob2loc,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 232024121865SAdrian Maldonado #endif 232124121865SAdrian Maldonado PetscFunctionReturn(0); 232224121865SAdrian Maldonado } 232324121865SAdrian Maldonado 232401ad2aeeSHong Zhang #include <petsc/private/matimpl.h> 23259e1d080bSHong Zhang 23269e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network_Nest(DM dm,Mat *J) 23271ad426b7SHong Zhang { 23281ad426b7SHong Zhang PetscErrorCode ierr; 23291ad426b7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 233024121865SAdrian Maldonado PetscInt eDof,vDof; 233124121865SAdrian Maldonado Mat j11,j12,j21,j22,bA[2][2]; 23329e1d080bSHong Zhang MPI_Comm comm; 233324121865SAdrian Maldonado ISLocalToGlobalMapping eISMap,vISMap; 233424121865SAdrian Maldonado 23359e1d080bSHong Zhang PetscFunctionBegin; 233624121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 233724121865SAdrian Maldonado 233824121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->edge.GlobalDofSection,&eDof);CHKERRQ(ierr); 233924121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->vertex.GlobalDofSection,&vDof);CHKERRQ(ierr); 234024121865SAdrian Maldonado 234101ad2aeeSHong Zhang ierr = MatCreate(comm, &j11);CHKERRQ(ierr); 234224121865SAdrian Maldonado ierr = MatSetSizes(j11, eDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 234324121865SAdrian Maldonado ierr = MatSetType(j11, MATMPIAIJ);CHKERRQ(ierr); 234424121865SAdrian Maldonado 234501ad2aeeSHong Zhang ierr = MatCreate(comm, &j12);CHKERRQ(ierr); 234624121865SAdrian Maldonado ierr = MatSetSizes(j12, eDof, vDof, PETSC_DETERMINE ,PETSC_DETERMINE);CHKERRQ(ierr); 234724121865SAdrian Maldonado ierr = MatSetType(j12, MATMPIAIJ);CHKERRQ(ierr); 234824121865SAdrian Maldonado 234901ad2aeeSHong Zhang ierr = MatCreate(comm, &j21);CHKERRQ(ierr); 235024121865SAdrian Maldonado ierr = MatSetSizes(j21, vDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 235124121865SAdrian Maldonado ierr = MatSetType(j21, MATMPIAIJ);CHKERRQ(ierr); 235224121865SAdrian Maldonado 235301ad2aeeSHong Zhang ierr = MatCreate(comm, &j22);CHKERRQ(ierr); 235424121865SAdrian Maldonado ierr = MatSetSizes(j22, vDof, vDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 235524121865SAdrian Maldonado ierr = MatSetType(j22, MATMPIAIJ);CHKERRQ(ierr); 235624121865SAdrian Maldonado 23573f6a6bdaSHong Zhang bA[0][0] = j11; 23583f6a6bdaSHong Zhang bA[0][1] = j12; 23593f6a6bdaSHong Zhang bA[1][0] = j21; 23603f6a6bdaSHong Zhang bA[1][1] = j22; 236124121865SAdrian Maldonado 236224121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->edge.GlobalDofSection,network->edge.DofSection,&eISMap);CHKERRQ(ierr); 236324121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->vertex.GlobalDofSection,network->vertex.DofSection,&vISMap);CHKERRQ(ierr); 236424121865SAdrian Maldonado 236524121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j11,eISMap,eISMap);CHKERRQ(ierr); 236624121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j12,eISMap,vISMap);CHKERRQ(ierr); 236724121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j21,vISMap,eISMap);CHKERRQ(ierr); 236824121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j22,vISMap,vISMap);CHKERRQ(ierr); 236924121865SAdrian Maldonado 237024121865SAdrian Maldonado ierr = MatSetUp(j11);CHKERRQ(ierr); 237124121865SAdrian Maldonado ierr = MatSetUp(j12);CHKERRQ(ierr); 237224121865SAdrian Maldonado ierr = MatSetUp(j21);CHKERRQ(ierr); 237324121865SAdrian Maldonado ierr = MatSetUp(j22);CHKERRQ(ierr); 237424121865SAdrian Maldonado 237501ad2aeeSHong Zhang ierr = MatCreateNest(comm,2,NULL,2,NULL,&bA[0][0],J);CHKERRQ(ierr); 237624121865SAdrian Maldonado ierr = MatSetUp(*J);CHKERRQ(ierr); 237724121865SAdrian Maldonado ierr = MatNestSetVecType(*J,VECNEST);CHKERRQ(ierr); 237824121865SAdrian Maldonado ierr = MatDestroy(&j11);CHKERRQ(ierr); 237924121865SAdrian Maldonado ierr = MatDestroy(&j12);CHKERRQ(ierr); 238024121865SAdrian Maldonado ierr = MatDestroy(&j21);CHKERRQ(ierr); 238124121865SAdrian Maldonado ierr = MatDestroy(&j22);CHKERRQ(ierr); 238224121865SAdrian Maldonado 238324121865SAdrian Maldonado ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 238424121865SAdrian Maldonado ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 23859e1d080bSHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 238624121865SAdrian Maldonado 238724121865SAdrian Maldonado /* Free structures */ 238824121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&eISMap);CHKERRQ(ierr); 238924121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&vISMap);CHKERRQ(ierr); 239024121865SAdrian Maldonado PetscFunctionReturn(0); 23919e1d080bSHong Zhang } 23929e1d080bSHong Zhang 23939e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J) 23949e1d080bSHong Zhang { 23959e1d080bSHong Zhang PetscErrorCode ierr; 23969e1d080bSHong Zhang DM_Network *network = (DM_Network*)dm->data; 23979e1d080bSHong Zhang PetscInt eStart,eEnd,vStart,vEnd,rstart,nrows,*rows,localSize; 23989e1d080bSHong Zhang PetscInt cstart,ncols,j,e,v; 23999e1d080bSHong Zhang PetscBool ghost,ghost_vc,ghost2,isNest; 24009e1d080bSHong Zhang Mat Juser; 24019e1d080bSHong Zhang PetscSection sectionGlobal; 24029e1d080bSHong Zhang PetscInt nedges,*vptr=NULL,vc,*rows_v; /* suppress maybe-uninitialized warning */ 24039e1d080bSHong Zhang const PetscInt *edges,*cone; 24049e1d080bSHong Zhang MPI_Comm comm; 24059e1d080bSHong Zhang MatType mtype; 24069e1d080bSHong Zhang Vec vd_nz,vo_nz; 24079e1d080bSHong Zhang PetscInt *dnnz,*onnz; 24089e1d080bSHong Zhang PetscScalar *vdnz,*vonz; 24099e1d080bSHong Zhang 24109e1d080bSHong Zhang PetscFunctionBegin; 24119e1d080bSHong Zhang mtype = dm->mattype; 24129e1d080bSHong Zhang ierr = PetscStrcmp(mtype,MATNEST,&isNest);CHKERRQ(ierr); 24139e1d080bSHong Zhang if (isNest) { 24149e1d080bSHong Zhang ierr = DMCreateMatrix_Network_Nest(dm,J);CHKERRQ(ierr); 2415c6b011d8SStefano Zampini ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 24169e1d080bSHong Zhang PetscFunctionReturn(0); 24179e1d080bSHong Zhang } 24189e1d080bSHong Zhang 24199e1d080bSHong Zhang if (!network->userEdgeJacobian && !network->userVertexJacobian) { 2420a4e85ca8SHong Zhang /* user does not provide Jacobian blocks */ 24219e1d080bSHong Zhang ierr = DMCreateMatrix_Plex(network->plex,J);CHKERRQ(ierr); 2422bfbc38dcSHong Zhang ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 24231ad426b7SHong Zhang PetscFunctionReturn(0); 24241ad426b7SHong Zhang } 24251ad426b7SHong Zhang 2426bfbc38dcSHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)dm),J);CHKERRQ(ierr); 2427e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§ionGlobal);CHKERRQ(ierr); 2428bfbc38dcSHong Zhang ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal,&localSize);CHKERRQ(ierr); 2429bfbc38dcSHong Zhang ierr = MatSetSizes(*J,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 24302a945128SHong Zhang 24312a945128SHong Zhang ierr = MatSetType(*J,MATAIJ);CHKERRQ(ierr); 24322a945128SHong Zhang ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 243389898e50SHong Zhang 243489898e50SHong Zhang /* (1) Set matrix preallocation */ 243589898e50SHong Zhang /*------------------------------*/ 2436840c2264SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 2437840c2264SHong Zhang ierr = VecCreate(comm,&vd_nz);CHKERRQ(ierr); 2438840c2264SHong Zhang ierr = VecSetSizes(vd_nz,localSize,PETSC_DECIDE);CHKERRQ(ierr); 2439840c2264SHong Zhang ierr = VecSetFromOptions(vd_nz);CHKERRQ(ierr); 2440840c2264SHong Zhang ierr = VecSet(vd_nz,0.0);CHKERRQ(ierr); 2441840c2264SHong Zhang ierr = VecDuplicate(vd_nz,&vo_nz);CHKERRQ(ierr); 2442840c2264SHong Zhang 244389898e50SHong Zhang /* Set preallocation for edges */ 244489898e50SHong Zhang /*-----------------------------*/ 2445840c2264SHong Zhang ierr = DMNetworkGetEdgeRange(dm,&eStart,&eEnd);CHKERRQ(ierr); 2446840c2264SHong Zhang 2447bdcb62a2SHong Zhang ierr = PetscMalloc1(localSize,&rows);CHKERRQ(ierr); 2448840c2264SHong Zhang for (e=eStart; e<eEnd; e++) { 2449840c2264SHong Zhang /* Get row indices */ 24502bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,e,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 24512bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,e,&nrows);CHKERRQ(ierr); 2452840c2264SHong Zhang if (nrows) { 2453840c2264SHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 2454840c2264SHong Zhang 2455a5b23f4aSJose E. Roman /* Set preallocation for connected vertices */ 2456d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 2457840c2264SHong Zhang for (v=0; v<2; v++) { 24582bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,cone[v],&ncols);CHKERRQ(ierr); 2459840c2264SHong Zhang 24608675203cSHong Zhang if (network->Je) { 2461840c2264SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 24628675203cSHong Zhang } else Juser = NULL; 2463840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,cone[v],&ghost);CHKERRQ(ierr); 24645cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 2465840c2264SHong Zhang } 2466840c2264SHong Zhang 246789898e50SHong Zhang /* Set preallocation for edge self */ 2468840c2264SHong Zhang cstart = rstart; 24698675203cSHong Zhang if (network->Je) { 2470840c2264SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 24718675203cSHong Zhang } else Juser = NULL; 24725cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 2473840c2264SHong Zhang } 2474840c2264SHong Zhang } 2475840c2264SHong Zhang 247689898e50SHong Zhang /* Set preallocation for vertices */ 247789898e50SHong Zhang /*--------------------------------*/ 2478840c2264SHong Zhang ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 24798675203cSHong Zhang if (vEnd - vStart) vptr = network->Jvptr; 2480840c2264SHong Zhang 2481840c2264SHong Zhang for (v=vStart; v<vEnd; v++) { 2482840c2264SHong Zhang /* Get row indices */ 24832bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 24842bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,v,&nrows);CHKERRQ(ierr); 2485840c2264SHong Zhang if (!nrows) continue; 2486840c2264SHong Zhang 2487bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 2488bdcb62a2SHong Zhang if (ghost) { 2489bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 2490bdcb62a2SHong Zhang } else { 2491bdcb62a2SHong Zhang rows_v = rows; 2492bdcb62a2SHong Zhang } 2493bdcb62a2SHong Zhang 2494bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 2495840c2264SHong Zhang 2496840c2264SHong Zhang /* Get supporting edges and connected vertices */ 2497840c2264SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 2498840c2264SHong Zhang 2499840c2264SHong Zhang for (e=0; e<nedges; e++) { 2500840c2264SHong Zhang /* Supporting edges */ 25012bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,edges[e],ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 25022bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,edges[e],&ncols);CHKERRQ(ierr); 2503840c2264SHong Zhang 25048675203cSHong Zhang if (network->Jv) { 2505840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 25068675203cSHong Zhang } else Juser = NULL; 2507bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 2508840c2264SHong Zhang 2509840c2264SHong Zhang /* Connected vertices */ 2510d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 2511840c2264SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 2512840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,vc,&ghost_vc);CHKERRQ(ierr); 2513840c2264SHong Zhang 25142bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,vc,&ncols);CHKERRQ(ierr); 2515840c2264SHong Zhang 25168675203cSHong Zhang if (network->Jv) { 2517840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 25188675203cSHong Zhang } else Juser = NULL; 2519e102a522SHong Zhang if (ghost_vc||ghost) { 2520e102a522SHong Zhang ghost2 = PETSC_TRUE; 2521e102a522SHong Zhang } else { 2522e102a522SHong Zhang ghost2 = PETSC_FALSE; 2523e102a522SHong Zhang } 2524e102a522SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost2,vd_nz,vo_nz);CHKERRQ(ierr); 2525840c2264SHong Zhang } 2526840c2264SHong Zhang 252789898e50SHong Zhang /* Set preallocation for vertex self */ 2528840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 2529840c2264SHong Zhang if (!ghost) { 25302bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 25318675203cSHong Zhang if (network->Jv) { 2532840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 25338675203cSHong Zhang } else Juser = NULL; 2534bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 2535840c2264SHong Zhang } 2536bdcb62a2SHong Zhang if (ghost) { 2537bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 2538bdcb62a2SHong Zhang } 2539840c2264SHong Zhang } 2540840c2264SHong Zhang 2541840c2264SHong Zhang ierr = VecAssemblyBegin(vd_nz);CHKERRQ(ierr); 2542840c2264SHong Zhang ierr = VecAssemblyBegin(vo_nz);CHKERRQ(ierr); 25435cf7da58SHong Zhang 25445cf7da58SHong Zhang ierr = PetscMalloc2(localSize,&dnnz,localSize,&onnz);CHKERRQ(ierr); 25455cf7da58SHong Zhang 25465cf7da58SHong Zhang ierr = VecAssemblyEnd(vd_nz);CHKERRQ(ierr); 2547840c2264SHong Zhang ierr = VecAssemblyEnd(vo_nz);CHKERRQ(ierr); 2548840c2264SHong Zhang 2549840c2264SHong Zhang ierr = VecGetArray(vd_nz,&vdnz);CHKERRQ(ierr); 2550840c2264SHong Zhang ierr = VecGetArray(vo_nz,&vonz);CHKERRQ(ierr); 2551840c2264SHong Zhang for (j=0; j<localSize; j++) { 2552e102a522SHong Zhang dnnz[j] = (PetscInt)PetscRealPart(vdnz[j]); 2553e102a522SHong Zhang onnz[j] = (PetscInt)PetscRealPart(vonz[j]); 2554840c2264SHong Zhang } 2555840c2264SHong Zhang ierr = VecRestoreArray(vd_nz,&vdnz);CHKERRQ(ierr); 2556840c2264SHong Zhang ierr = VecRestoreArray(vo_nz,&vonz);CHKERRQ(ierr); 2557840c2264SHong Zhang ierr = VecDestroy(&vd_nz);CHKERRQ(ierr); 2558840c2264SHong Zhang ierr = VecDestroy(&vo_nz);CHKERRQ(ierr); 2559840c2264SHong Zhang 25605cf7da58SHong Zhang ierr = MatSeqAIJSetPreallocation(*J,0,dnnz);CHKERRQ(ierr); 25615cf7da58SHong Zhang ierr = MatMPIAIJSetPreallocation(*J,0,dnnz,0,onnz);CHKERRQ(ierr); 25625cf7da58SHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 25635cf7da58SHong Zhang 25645cf7da58SHong Zhang ierr = PetscFree2(dnnz,onnz);CHKERRQ(ierr); 25655cf7da58SHong Zhang 256689898e50SHong Zhang /* (2) Set matrix entries for edges */ 256789898e50SHong Zhang /*----------------------------------*/ 25681ad426b7SHong Zhang for (e=eStart; e<eEnd; e++) { 2569bfbc38dcSHong Zhang /* Get row indices */ 25702bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,e,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 25712bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,e,&nrows);CHKERRQ(ierr); 25724b976069SHong Zhang if (nrows) { 257317df6e9eSHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 25741ad426b7SHong Zhang 2575a5b23f4aSJose E. Roman /* Set matrix entries for connected vertices */ 2576d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 2577bfbc38dcSHong Zhang for (v=0; v<2; v++) { 25782bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,cone[v],ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 25792bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,cone[v],&ncols);CHKERRQ(ierr); 25803e97b6e8SHong Zhang 25818675203cSHong Zhang if (network->Je) { 2582a4e85ca8SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 25838675203cSHong Zhang } else Juser = NULL; 2584a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 2585bfbc38dcSHong Zhang } 258617df6e9eSHong Zhang 2587bfbc38dcSHong Zhang /* Set matrix entries for edge self */ 25883e97b6e8SHong Zhang cstart = rstart; 25898675203cSHong Zhang if (network->Je) { 2590a4e85ca8SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 25918675203cSHong Zhang } else Juser = NULL; 2592a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,nrows,cstart,J);CHKERRQ(ierr); 25931ad426b7SHong Zhang } 25944b976069SHong Zhang } 25951ad426b7SHong Zhang 2596bfbc38dcSHong Zhang /* Set matrix entries for vertices */ 259783b2e829SHong Zhang /*---------------------------------*/ 25981ad426b7SHong Zhang for (v=vStart; v<vEnd; v++) { 2599bfbc38dcSHong Zhang /* Get row indices */ 26002bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 26012bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,v,&nrows);CHKERRQ(ierr); 26024b976069SHong Zhang if (!nrows) continue; 2603596e729fSHong Zhang 2604bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 2605bdcb62a2SHong Zhang if (ghost) { 2606bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 2607bdcb62a2SHong Zhang } else { 2608bdcb62a2SHong Zhang rows_v = rows; 2609bdcb62a2SHong Zhang } 2610bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 2611596e729fSHong Zhang 2612bfbc38dcSHong Zhang /* Get supporting edges and connected vertices */ 2613596e729fSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 2614596e729fSHong Zhang 2615596e729fSHong Zhang for (e=0; e<nedges; e++) { 2616bfbc38dcSHong Zhang /* Supporting edges */ 26172bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,edges[e],ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 26182bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,edges[e],&ncols);CHKERRQ(ierr); 2619596e729fSHong Zhang 26208675203cSHong Zhang if (network->Jv) { 2621a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 26228675203cSHong Zhang } else Juser = NULL; 2623bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 2624596e729fSHong Zhang 2625bfbc38dcSHong Zhang /* Connected vertices */ 2626d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 26272a945128SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 26282a945128SHong Zhang 26292bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,vc,ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 26302bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,vc,&ncols);CHKERRQ(ierr); 2631a4e85ca8SHong Zhang 26328675203cSHong Zhang if (network->Jv) { 2633a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 26348675203cSHong Zhang } else Juser = NULL; 2635bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 2636596e729fSHong Zhang } 2637596e729fSHong Zhang 2638bfbc38dcSHong Zhang /* Set matrix entries for vertex self */ 26391ad426b7SHong Zhang if (!ghost) { 26402bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 26418675203cSHong Zhang if (network->Jv) { 2642a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 26438675203cSHong Zhang } else Juser = NULL; 2644bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,nrows,cstart,J);CHKERRQ(ierr); 2645bdcb62a2SHong Zhang } 2646bdcb62a2SHong Zhang if (ghost) { 2647bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 2648bdcb62a2SHong Zhang } 26491ad426b7SHong Zhang } 2650a4e85ca8SHong Zhang ierr = PetscFree(rows);CHKERRQ(ierr); 2651bdcb62a2SHong Zhang 26521ad426b7SHong Zhang ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 26531ad426b7SHong Zhang ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2654dd6f46cdSHong Zhang 26555f2c45f1SShri Abhyankar ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 26565f2c45f1SShri Abhyankar PetscFunctionReturn(0); 26575f2c45f1SShri Abhyankar } 26585f2c45f1SShri Abhyankar 26595f2c45f1SShri Abhyankar PetscErrorCode DMDestroy_Network(DM dm) 26605f2c45f1SShri Abhyankar { 26615f2c45f1SShri Abhyankar PetscErrorCode ierr; 26625f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 266354dfd506SHong Zhang PetscInt j,np; 26645f2c45f1SShri Abhyankar 26655f2c45f1SShri Abhyankar PetscFunctionBegin; 26668415c774SShri Abhyankar if (--network->refct > 0) PetscFunctionReturn(0); 266783b2e829SHong Zhang if (network->Je) { 266883b2e829SHong Zhang ierr = PetscFree(network->Je);CHKERRQ(ierr); 266983b2e829SHong Zhang } 267083b2e829SHong Zhang if (network->Jv) { 2671883e35e8SHong Zhang ierr = PetscFree(network->Jvptr);CHKERRQ(ierr); 267283b2e829SHong Zhang ierr = PetscFree(network->Jv);CHKERRQ(ierr); 26731ad426b7SHong Zhang } 267413c2a604SAdrian Maldonado 267513c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->vertex.mapping);CHKERRQ(ierr); 267613c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.DofSection);CHKERRQ(ierr); 267713c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.GlobalDofSection);CHKERRQ(ierr); 2678f5427c60SHong Zhang if (network->vltog) { 2679f5427c60SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 2680f5427c60SHong Zhang } 268113c2a604SAdrian Maldonado if (network->vertex.sf) { 268213c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->vertex.sf);CHKERRQ(ierr); 268313c2a604SAdrian Maldonado } 268413c2a604SAdrian Maldonado /* edge */ 268513c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->edge.mapping);CHKERRQ(ierr); 268613c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.DofSection);CHKERRQ(ierr); 268713c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.GlobalDofSection);CHKERRQ(ierr); 268813c2a604SAdrian Maldonado if (network->edge.sf) { 268913c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->edge.sf);CHKERRQ(ierr); 269013c2a604SAdrian Maldonado } 26915f2c45f1SShri Abhyankar ierr = DMDestroy(&network->plex);CHKERRQ(ierr); 26925f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr); 26935f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr); 269483b2e829SHong Zhang 26952bf73ac6SHong Zhang for (j=0; j<network->Nsvtx; j++) { 26962bf73ac6SHong Zhang ierr = PetscFree(network->svtx[j].sv);CHKERRQ(ierr); 26972bf73ac6SHong Zhang } 26982bf73ac6SHong Zhang if (network->svtx) {ierr = PetscFree(network->svtx);CHKERRQ(ierr);} 2699f11a936eSBarry Smith ierr = PetscFree2(network->subnetedge,network->subnetvtx);CHKERRQ(ierr); 2700caf410d2SHong Zhang 27012bf73ac6SHong Zhang ierr = PetscTableDestroy(&network->svtable);CHKERRQ(ierr); 2702e2aaf10cSShri Abhyankar ierr = PetscFree(network->subnet);CHKERRQ(ierr); 270354dfd506SHong Zhang ierr = PetscFree(network->component);CHKERRQ(ierr); 27045f2c45f1SShri Abhyankar ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr); 270554dfd506SHong Zhang 270654dfd506SHong Zhang if (network->header) { 270754dfd506SHong Zhang np = network->pEnd - network->pStart; 270854dfd506SHong Zhang for (j=0; j < np; j++) { 270954dfd506SHong 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); 271054dfd506SHong Zhang ierr = PetscFree(network->cvalue[j].data);CHKERRQ(ierr); 271154dfd506SHong Zhang } 2712caf410d2SHong Zhang ierr = PetscFree2(network->header,network->cvalue);CHKERRQ(ierr); 271354dfd506SHong Zhang } 27145f2c45f1SShri Abhyankar ierr = PetscFree(network);CHKERRQ(ierr); 27155f2c45f1SShri Abhyankar PetscFunctionReturn(0); 27165f2c45f1SShri Abhyankar } 27175f2c45f1SShri Abhyankar 27185f2c45f1SShri Abhyankar PetscErrorCode DMView_Network(DM dm,PetscViewer viewer) 27195f2c45f1SShri Abhyankar { 27205f2c45f1SShri Abhyankar PetscErrorCode ierr; 2721caf410d2SHong Zhang PetscBool iascii; 2722caf410d2SHong Zhang PetscMPIInt rank; 27235f2c45f1SShri Abhyankar 27245f2c45f1SShri Abhyankar PetscFunctionBegin; 2725caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 2726ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRMPI(ierr); 2727caf410d2SHong Zhang PetscValidHeaderSpecific(dm,DM_CLASSID, 1); 2728caf410d2SHong Zhang PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2729caf410d2SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 2730caf410d2SHong Zhang if (iascii) { 2731caf410d2SHong Zhang const PetscInt *cone,*vtx,*edges; 27322bf73ac6SHong Zhang PetscInt vfrom,vto,i,j,nv,ne,ncv,p,nsubnet; 27332bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 2734caf410d2SHong Zhang 27352bf73ac6SHong Zhang nsubnet = network->Nsubnet; /* num of subnetworks */ 2736dd400576SPatrick Sanan if (rank == 0) { 27372bf73ac6SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF," NSubnets: %D; NEdges: %D; NVertices: %D; NSharedVertices: %D.\n",nsubnet,network->NEdges,network->NVertices,network->Nsvtx);CHKERRQ(ierr); 27382bf73ac6SHong Zhang } 27392bf73ac6SHong Zhang 27402bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&ncv,&vtx);CHKERRQ(ierr); 2741caf410d2SHong Zhang ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 27422bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " [%d] nEdges: %D; nVertices: %D; nSharedVertices: %D\n",rank,network->nEdges,network->nVertices,ncv);CHKERRQ(ierr); 2743caf410d2SHong Zhang 2744caf410d2SHong Zhang for (i=0; i<nsubnet; i++) { 27452bf73ac6SHong Zhang ierr = DMNetworkGetSubnetwork(dm,i,&nv,&ne,&vtx,&edges);CHKERRQ(ierr); 2746caf410d2SHong Zhang if (ne) { 27472bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " Subnet %D: nEdges %D, nVertices(include shared vertices) %D\n",i,ne,nv);CHKERRQ(ierr); 2748caf410d2SHong Zhang for (j=0; j<ne; j++) { 2749caf410d2SHong Zhang p = edges[j]; 2750caf410d2SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,p,&cone);CHKERRQ(ierr); 2751caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[0],&vfrom);CHKERRQ(ierr); 2752caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[1],&vto);CHKERRQ(ierr); 2753caf410d2SHong Zhang ierr = DMNetworkGetGlobalEdgeIndex(dm,edges[j],&p);CHKERRQ(ierr); 2754caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " edge %D: %D ----> %D\n",p,vfrom,vto);CHKERRQ(ierr); 2755caf410d2SHong Zhang } 2756caf410d2SHong Zhang } 2757caf410d2SHong Zhang } 27582bf73ac6SHong Zhang 27592bf73ac6SHong Zhang /* Shared vertices */ 27602bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&ncv,&vtx);CHKERRQ(ierr); 27612bf73ac6SHong Zhang if (ncv) { 27622bf73ac6SHong Zhang SVtx *svtx = network->svtx; 27632bf73ac6SHong Zhang PetscInt gidx,svtx_idx,nvto,vfrom_net,vfrom_idx,*svto; 27642bf73ac6SHong Zhang PetscBool ghost; 27652bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " SharedVertices:\n");CHKERRQ(ierr); 27662bf73ac6SHong Zhang for (i=0; i<ncv; i++) { 27672bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,vtx[i],&ghost);CHKERRQ(ierr); 27682bf73ac6SHong Zhang if (ghost) continue; 27692bf73ac6SHong Zhang 27702bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,vtx[i],&gidx);CHKERRQ(ierr); 27712bf73ac6SHong Zhang ierr = PetscTableFind(network->svtable,gidx+1,&svtx_idx);CHKERRQ(ierr); 27722bf73ac6SHong Zhang svtx_idx--; 27732bf73ac6SHong Zhang nvto = svtx[svtx_idx].n; 27742bf73ac6SHong Zhang 27752bf73ac6SHong Zhang vfrom_net = svtx[svtx_idx].sv[0]; 27762bf73ac6SHong Zhang vfrom_idx = svtx[svtx_idx].sv[1]; 27772bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " svtx %D: global index %D, subnet[%D].%D ---->\n",i,gidx,vfrom_net,vfrom_idx);CHKERRQ(ierr); 27782bf73ac6SHong Zhang for (j=1; j<nvto; j++) { 27792bf73ac6SHong Zhang svto = svtx[svtx_idx].sv + 2*j; 27802bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " ----> subnet[%D].%D\n",svto[0],svto[1]);CHKERRQ(ierr); 2781caf410d2SHong Zhang } 2782caf410d2SHong Zhang } 2783caf410d2SHong Zhang } 2784caf410d2SHong Zhang ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2785caf410d2SHong Zhang ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 2786caf410d2SHong Zhang } else SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMNetwork writing", ((PetscObject)viewer)->type_name); 27875f2c45f1SShri Abhyankar PetscFunctionReturn(0); 27885f2c45f1SShri Abhyankar } 27895f2c45f1SShri Abhyankar 27905f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l) 27915f2c45f1SShri Abhyankar { 27925f2c45f1SShri Abhyankar PetscErrorCode ierr; 27935f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 27945f2c45f1SShri Abhyankar 27955f2c45f1SShri Abhyankar PetscFunctionBegin; 27965f2c45f1SShri Abhyankar ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr); 27975f2c45f1SShri Abhyankar PetscFunctionReturn(0); 27985f2c45f1SShri Abhyankar } 27995f2c45f1SShri Abhyankar 28005f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l) 28015f2c45f1SShri Abhyankar { 28025f2c45f1SShri Abhyankar PetscErrorCode ierr; 28035f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 28045f2c45f1SShri Abhyankar 28055f2c45f1SShri Abhyankar PetscFunctionBegin; 28065f2c45f1SShri Abhyankar ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr); 28075f2c45f1SShri Abhyankar PetscFunctionReturn(0); 28085f2c45f1SShri Abhyankar } 28095f2c45f1SShri Abhyankar 28105f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g) 28115f2c45f1SShri Abhyankar { 28125f2c45f1SShri Abhyankar PetscErrorCode ierr; 28135f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 28145f2c45f1SShri Abhyankar 28155f2c45f1SShri Abhyankar PetscFunctionBegin; 28165f2c45f1SShri Abhyankar ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr); 28175f2c45f1SShri Abhyankar PetscFunctionReturn(0); 28185f2c45f1SShri Abhyankar } 28195f2c45f1SShri Abhyankar 28205f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g) 28215f2c45f1SShri Abhyankar { 28225f2c45f1SShri Abhyankar PetscErrorCode ierr; 28235f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 28245f2c45f1SShri Abhyankar 28255f2c45f1SShri Abhyankar PetscFunctionBegin; 28265f2c45f1SShri Abhyankar ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr); 28275f2c45f1SShri Abhyankar PetscFunctionReturn(0); 28285f2c45f1SShri Abhyankar } 282922bbedd7SHong Zhang 283022bbedd7SHong Zhang /*@ 283164238763SRodolfo Oliveira DMNetworkGetVertexLocalToGlobalOrdering - Get vertex global index 283222bbedd7SHong Zhang 283322bbedd7SHong Zhang Not collective 283422bbedd7SHong Zhang 28357a7aea1fSJed Brown Input Parameters: 283622bbedd7SHong Zhang + dm - the dm object 283722bbedd7SHong Zhang - vloc - local vertex ordering, start from 0 283822bbedd7SHong Zhang 28397a7aea1fSJed Brown Output Parameters: 2840f0fc11ceSJed Brown . vg - global vertex ordering, start from 0 284122bbedd7SHong Zhang 284297bb938eSShri Abhyankar Level: advanced 284322bbedd7SHong Zhang 284422bbedd7SHong Zhang .seealso: DMNetworkSetVertexLocalToGlobalOrdering() 284522bbedd7SHong Zhang @*/ 284622bbedd7SHong Zhang PetscErrorCode DMNetworkGetVertexLocalToGlobalOrdering(DM dm,PetscInt vloc,PetscInt *vg) 284722bbedd7SHong Zhang { 284822bbedd7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 284922bbedd7SHong Zhang PetscInt *vltog = network->vltog; 285022bbedd7SHong Zhang 285122bbedd7SHong Zhang PetscFunctionBegin; 285222bbedd7SHong Zhang if (!vltog) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkSetVertexLocalToGlobalOrdering() first"); 285322bbedd7SHong Zhang *vg = vltog[vloc]; 285422bbedd7SHong Zhang PetscFunctionReturn(0); 285522bbedd7SHong Zhang } 285622bbedd7SHong Zhang 285722bbedd7SHong Zhang /*@ 285864238763SRodolfo Oliveira DMNetworkSetVertexLocalToGlobalOrdering - Create and setup vertex local to global map 285922bbedd7SHong Zhang 286022bbedd7SHong Zhang Collective 286122bbedd7SHong Zhang 286222bbedd7SHong Zhang Input Parameters: 2863f0fc11ceSJed Brown . dm - the dm object 286422bbedd7SHong Zhang 286597bb938eSShri Abhyankar Level: advanced 286622bbedd7SHong Zhang 286763029d29SHong Zhang .seealso: DMNetworkGetGlobalVertexIndex() 286822bbedd7SHong Zhang @*/ 286922bbedd7SHong Zhang PetscErrorCode DMNetworkSetVertexLocalToGlobalOrdering(DM dm) 287022bbedd7SHong Zhang { 287122bbedd7SHong Zhang PetscErrorCode ierr; 287222bbedd7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 287322bbedd7SHong Zhang MPI_Comm comm; 28742bf73ac6SHong Zhang PetscMPIInt rank,size,*displs=NULL,*recvcounts=NULL,remoterank; 287522bbedd7SHong Zhang PetscBool ghost; 287663029d29SHong Zhang PetscInt *vltog,nroots,nleaves,i,*vrange,k,N,lidx; 287722bbedd7SHong Zhang const PetscSFNode *iremote; 287822bbedd7SHong Zhang PetscSF vsf; 287963029d29SHong Zhang Vec Vleaves,Vleaves_seq; 288063029d29SHong Zhang VecScatter ctx; 288163029d29SHong Zhang PetscScalar *varr,val; 288263029d29SHong Zhang const PetscScalar *varr_read; 288322bbedd7SHong Zhang 288422bbedd7SHong Zhang PetscFunctionBegin; 288522bbedd7SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 2886ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 2887ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 288822bbedd7SHong Zhang 288922bbedd7SHong Zhang if (size == 1) { 289022bbedd7SHong Zhang nroots = network->vEnd - network->vStart; 289122bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 289222bbedd7SHong Zhang for (i=0; i<nroots; i++) vltog[i] = i; 289322bbedd7SHong Zhang network->vltog = vltog; 289422bbedd7SHong Zhang PetscFunctionReturn(0); 289522bbedd7SHong Zhang } 289622bbedd7SHong Zhang 289722bbedd7SHong Zhang if (!network->distributecalled) SETERRQ(comm, PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkDistribute() first"); 289822bbedd7SHong Zhang if (network->vltog) { 289922bbedd7SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 290022bbedd7SHong Zhang } 290122bbedd7SHong Zhang 290222bbedd7SHong Zhang ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 290322bbedd7SHong Zhang ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 290422bbedd7SHong Zhang vsf = network->vertex.sf; 290522bbedd7SHong Zhang 29062bf73ac6SHong Zhang ierr = PetscMalloc3(size+1,&vrange,size,&displs,size,&recvcounts);CHKERRQ(ierr); 2907f5427c60SHong Zhang ierr = PetscSFGetGraph(vsf,&nroots,&nleaves,NULL,&iremote);CHKERRQ(ierr); 290822bbedd7SHong Zhang 290922bbedd7SHong Zhang for (i=0; i<size; i++) { displs[i] = i; recvcounts[i] = 1;} 291022bbedd7SHong Zhang 291122bbedd7SHong Zhang i = nroots - nleaves; /* local number of vertices, excluding ghosts */ 291222bbedd7SHong Zhang vrange[0] = 0; 2913ffc4695bSBarry Smith ierr = MPI_Allgatherv(&i,1,MPIU_INT,vrange+1,recvcounts,displs,MPIU_INT,comm);CHKERRMPI(ierr); 291467dd800bSHong Zhang for (i=2; i<size+1; i++) {vrange[i] += vrange[i-1];} 291522bbedd7SHong Zhang 291622bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 291722bbedd7SHong Zhang network->vltog = vltog; 291822bbedd7SHong Zhang 291963029d29SHong Zhang /* Set vltog for non-ghost vertices */ 292063029d29SHong Zhang k = 0; 292122bbedd7SHong Zhang for (i=0; i<nroots; i++) { 292222bbedd7SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 292363029d29SHong Zhang if (ghost) continue; 292463029d29SHong Zhang vltog[i] = vrange[rank] + k++; 292522bbedd7SHong Zhang } 2926f5427c60SHong Zhang ierr = PetscFree3(vrange,displs,recvcounts);CHKERRQ(ierr); 292763029d29SHong Zhang 292863029d29SHong Zhang /* Set vltog for ghost vertices */ 292963029d29SHong Zhang /* (a) create parallel Vleaves and sequential Vleaves_seq to convert local iremote[*].index to global index */ 293063029d29SHong Zhang ierr = VecCreate(comm,&Vleaves);CHKERRQ(ierr); 293163029d29SHong Zhang ierr = VecSetSizes(Vleaves,2*nleaves,PETSC_DETERMINE);CHKERRQ(ierr); 293263029d29SHong Zhang ierr = VecSetFromOptions(Vleaves);CHKERRQ(ierr); 293363029d29SHong Zhang ierr = VecGetArray(Vleaves,&varr);CHKERRQ(ierr); 293463029d29SHong Zhang for (i=0; i<nleaves; i++) { 293563029d29SHong Zhang varr[2*i] = (PetscScalar)(iremote[i].rank); /* rank of remote process */ 293663029d29SHong Zhang varr[2*i+1] = (PetscScalar)(iremote[i].index); /* local index in remote process */ 293763029d29SHong Zhang } 293863029d29SHong Zhang ierr = VecRestoreArray(Vleaves,&varr);CHKERRQ(ierr); 293963029d29SHong Zhang 294063029d29SHong Zhang /* (b) scatter local info to remote processes via VecScatter() */ 294163029d29SHong Zhang ierr = VecScatterCreateToAll(Vleaves,&ctx,&Vleaves_seq);CHKERRQ(ierr); 294263029d29SHong Zhang ierr = VecScatterBegin(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 294363029d29SHong Zhang ierr = VecScatterEnd(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 294463029d29SHong Zhang 294563029d29SHong Zhang /* (c) convert local indices to global indices in parallel vector Vleaves */ 294663029d29SHong Zhang ierr = VecGetSize(Vleaves_seq,&N);CHKERRQ(ierr); 294763029d29SHong Zhang ierr = VecGetArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 294863029d29SHong Zhang for (i=0; i<N; i+=2) { 29492e4cff2eSHong Zhang remoterank = (PetscMPIInt)PetscRealPart(varr_read[i]); 295063029d29SHong Zhang if (remoterank == rank) { 295163029d29SHong Zhang k = i+1; /* row number */ 29522e4cff2eSHong Zhang lidx = (PetscInt)PetscRealPart(varr_read[i+1]); 295363029d29SHong Zhang val = (PetscScalar)vltog[lidx]; /* global index for non-ghost vertex computed above */ 295463029d29SHong Zhang ierr = VecSetValues(Vleaves,1,&k,&val,INSERT_VALUES);CHKERRQ(ierr); 295563029d29SHong Zhang } 295663029d29SHong Zhang } 295763029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 295863029d29SHong Zhang ierr = VecAssemblyBegin(Vleaves);CHKERRQ(ierr); 295963029d29SHong Zhang ierr = VecAssemblyEnd(Vleaves);CHKERRQ(ierr); 296063029d29SHong Zhang 296163029d29SHong Zhang /* (d) Set vltog for ghost vertices by copying local values of Vleaves */ 296263029d29SHong Zhang ierr = VecGetArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 296363029d29SHong Zhang k = 0; 296463029d29SHong Zhang for (i=0; i<nroots; i++) { 296563029d29SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 296663029d29SHong Zhang if (!ghost) continue; 29672e4cff2eSHong Zhang vltog[i] = (PetscInt)PetscRealPart(varr_read[2*k+1]); k++; 296863029d29SHong Zhang } 296963029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 297063029d29SHong Zhang 297163029d29SHong Zhang ierr = VecDestroy(&Vleaves);CHKERRQ(ierr); 297263029d29SHong Zhang ierr = VecDestroy(&Vleaves_seq);CHKERRQ(ierr); 297363029d29SHong Zhang ierr = VecScatterDestroy(&ctx);CHKERRQ(ierr); 297422bbedd7SHong Zhang PetscFunctionReturn(0); 297522bbedd7SHong Zhang } 297642dc13f1SHong Zhang 297742dc13f1SHong Zhang PETSC_STATIC_INLINE PetscErrorCode DMISAddSize_private(DM_Network *network,PetscInt p,PetscInt numkeys,PetscInt keys[],PetscInt blocksize[],PetscInt nselectedvar[],PetscInt *nidx) 297842dc13f1SHong Zhang { 297942dc13f1SHong Zhang PetscErrorCode ierr; 298042dc13f1SHong Zhang PetscInt i,j,ncomps,nvar,key,offset=0; 298142dc13f1SHong Zhang DMNetworkComponentHeader header; 298242dc13f1SHong Zhang 298342dc13f1SHong Zhang PetscFunctionBegin; 298442dc13f1SHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 298542dc13f1SHong Zhang ncomps = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 298642dc13f1SHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offset); 298742dc13f1SHong Zhang 298842dc13f1SHong Zhang for (i=0; i<ncomps; i++) { 298942dc13f1SHong Zhang key = header->key[i]; 299042dc13f1SHong Zhang nvar = header->nvar[i]; 299142dc13f1SHong Zhang for (j=0; j<numkeys; j++) { 299242dc13f1SHong Zhang if (key == keys[j]) { 299342dc13f1SHong Zhang if (!blocksize || blocksize[j] == -1) { 299442dc13f1SHong Zhang *nidx += nvar; 299542dc13f1SHong Zhang } else { 299642dc13f1SHong Zhang *nidx += nselectedvar[j]*nvar/blocksize[j]; 299742dc13f1SHong Zhang } 299842dc13f1SHong Zhang } 299942dc13f1SHong Zhang } 300042dc13f1SHong Zhang } 300142dc13f1SHong Zhang PetscFunctionReturn(0); 300242dc13f1SHong Zhang } 300342dc13f1SHong Zhang 300442dc13f1SHong 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) 300542dc13f1SHong Zhang { 300642dc13f1SHong Zhang PetscErrorCode ierr; 300742dc13f1SHong Zhang PetscInt i,j,ncomps,nvar,key,offsetg,k,k1,offset=0; 300842dc13f1SHong Zhang DM_Network *network = (DM_Network*)dm->data; 300942dc13f1SHong Zhang DMNetworkComponentHeader header; 301042dc13f1SHong Zhang 301142dc13f1SHong Zhang PetscFunctionBegin; 301242dc13f1SHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 301342dc13f1SHong Zhang ncomps = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 301442dc13f1SHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offset); 301542dc13f1SHong Zhang 301642dc13f1SHong Zhang for (i=0; i<ncomps; i++) { 301742dc13f1SHong Zhang key = header->key[i]; 301842dc13f1SHong Zhang nvar = header->nvar[i]; 301942dc13f1SHong Zhang for (j=0; j<numkeys; j++) { 302042dc13f1SHong Zhang if (key != keys[j]) continue; 302142dc13f1SHong Zhang 302242dc13f1SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,p,i,&offsetg);CHKERRQ(ierr); 302342dc13f1SHong Zhang if (!blocksize || blocksize[j] == -1) { 302442dc13f1SHong Zhang for (k=0; k<nvar; k++) idx[(*ii)++] = offsetg + k; 302542dc13f1SHong Zhang } else { 302642dc13f1SHong Zhang for (k=0; k<nvar; k+=blocksize[j]) { 302742dc13f1SHong Zhang for (k1=0; k1<nselectedvar[j]; k1++) idx[(*ii)++] = offsetg + k + selectedvar[j][k1]; 302842dc13f1SHong Zhang } 302942dc13f1SHong Zhang } 303042dc13f1SHong Zhang } 303142dc13f1SHong Zhang } 303242dc13f1SHong Zhang PetscFunctionReturn(0); 303342dc13f1SHong Zhang } 303442dc13f1SHong Zhang 303542dc13f1SHong Zhang /*@ 303642dc13f1SHong Zhang DMNetworkCreateIS - Create an index set object from the global vector of the network 303742dc13f1SHong Zhang 303842dc13f1SHong Zhang Collective 303942dc13f1SHong Zhang 304042dc13f1SHong Zhang Input Parameters: 304142dc13f1SHong Zhang + dm - DMNetwork object 304242dc13f1SHong Zhang . numkeys - number of keys 304342dc13f1SHong Zhang . keys - array of keys that define the components of the variables you wish to extract 304442dc13f1SHong Zhang . blocksize - block size of the variables associated to the component 304542dc13f1SHong Zhang . nselectedvar - number of variables in each block to select 304642dc13f1SHong Zhang - selectedvar - the offset into the block of each variable in each block to select 304742dc13f1SHong Zhang 304842dc13f1SHong Zhang Output Parameters: 304942dc13f1SHong Zhang . is - the index set 305042dc13f1SHong Zhang 305142dc13f1SHong Zhang Level: Advanced 305242dc13f1SHong Zhang 305342dc13f1SHong Zhang Notes: 305442dc13f1SHong 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. 305542dc13f1SHong Zhang 305642dc13f1SHong Zhang .seealso: DMNetworkCreate(), ISCreateGeneral(), DMNetworkCreateLocalIS() 305742dc13f1SHong Zhang @*/ 305842dc13f1SHong Zhang PetscErrorCode DMNetworkCreateIS(DM dm,PetscInt numkeys,PetscInt keys[],PetscInt blocksize[],PetscInt nselectedvar[],PetscInt *selectedvar[],IS *is) 305942dc13f1SHong Zhang { 306042dc13f1SHong Zhang PetscErrorCode ierr; 306142dc13f1SHong Zhang MPI_Comm comm; 306242dc13f1SHong Zhang DM_Network *network = (DM_Network*)dm->data; 306342dc13f1SHong Zhang PetscInt i,p,estart,eend,vstart,vend,nidx,*idx; 306442dc13f1SHong Zhang PetscBool ghost; 306542dc13f1SHong Zhang 306642dc13f1SHong Zhang PetscFunctionBegin; 306742dc13f1SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 306842dc13f1SHong Zhang 306942dc13f1SHong Zhang /* Check input parameters */ 307042dc13f1SHong Zhang for (i=0; i<numkeys; i++) { 307142dc13f1SHong Zhang if (!blocksize || blocksize[i] == -1) continue; 307242dc13f1SHong 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]); 307342dc13f1SHong Zhang } 307442dc13f1SHong Zhang 307542dc13f1SHong Zhang ierr = DMNetworkGetEdgeRange(dm,&estart,&eend);CHKERRQ(ierr); 307642dc13f1SHong Zhang ierr = DMNetworkGetVertexRange(dm,&vstart,&vend);CHKERRQ(ierr); 307742dc13f1SHong Zhang 307842dc13f1SHong Zhang /* Get local number of idx */ 307942dc13f1SHong Zhang nidx = 0; 308042dc13f1SHong Zhang for (p=estart; p<eend; p++) { 308142dc13f1SHong Zhang ierr = DMISAddSize_private(network,p,numkeys,keys,blocksize,nselectedvar,&nidx);CHKERRQ(ierr); 308242dc13f1SHong Zhang } 308342dc13f1SHong Zhang for (p=vstart; p<vend; p++) { 308442dc13f1SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 308542dc13f1SHong Zhang if (ghost) continue; 308642dc13f1SHong Zhang ierr = DMISAddSize_private(network,p,numkeys,keys,blocksize,nselectedvar,&nidx);CHKERRQ(ierr); 308742dc13f1SHong Zhang } 308842dc13f1SHong Zhang 308942dc13f1SHong Zhang /* Compute idx */ 309042dc13f1SHong Zhang ierr = PetscMalloc1(nidx,&idx);CHKERRQ(ierr); 309142dc13f1SHong Zhang i = 0; 309242dc13f1SHong Zhang for (p=estart; p<eend; p++) { 309342dc13f1SHong Zhang ierr = DMISComputeIdx_private(dm,p,numkeys,keys,blocksize,nselectedvar,selectedvar,&i,idx);CHKERRQ(ierr); 309442dc13f1SHong Zhang } 309542dc13f1SHong Zhang for (p=vstart; p<vend; p++) { 309642dc13f1SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 309742dc13f1SHong Zhang if (ghost) continue; 309842dc13f1SHong Zhang ierr = DMISComputeIdx_private(dm,p,numkeys,keys,blocksize,nselectedvar,selectedvar,&i,idx);CHKERRQ(ierr); 309942dc13f1SHong Zhang } 310042dc13f1SHong Zhang 310142dc13f1SHong Zhang /* Create is */ 310242dc13f1SHong Zhang ierr = ISCreateGeneral(comm,nidx,idx,PETSC_COPY_VALUES,is);CHKERRQ(ierr); 310342dc13f1SHong Zhang ierr = PetscFree(idx);CHKERRQ(ierr); 310442dc13f1SHong Zhang PetscFunctionReturn(0); 310542dc13f1SHong Zhang } 310642dc13f1SHong Zhang 310742dc13f1SHong 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) 310842dc13f1SHong Zhang { 310942dc13f1SHong Zhang PetscErrorCode ierr; 311042dc13f1SHong Zhang PetscInt i,j,ncomps,nvar,key,offsetl,k,k1,offset=0; 311142dc13f1SHong Zhang DM_Network *network = (DM_Network*)dm->data; 311242dc13f1SHong Zhang DMNetworkComponentHeader header; 311342dc13f1SHong Zhang 311442dc13f1SHong Zhang PetscFunctionBegin; 311542dc13f1SHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 311642dc13f1SHong Zhang ncomps = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 311742dc13f1SHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offset); 311842dc13f1SHong Zhang 311942dc13f1SHong Zhang for (i=0; i<ncomps; i++) { 312042dc13f1SHong Zhang key = header->key[i]; 312142dc13f1SHong Zhang nvar = header->nvar[i]; 312242dc13f1SHong Zhang for (j=0; j<numkeys; j++) { 312342dc13f1SHong Zhang if (key != keys[j]) continue; 312442dc13f1SHong Zhang 312542dc13f1SHong Zhang ierr = DMNetworkGetLocalVecOffset(dm,p,i,&offsetl);CHKERRQ(ierr); 312642dc13f1SHong Zhang if (!blocksize || blocksize[j] == -1) { 312742dc13f1SHong Zhang for (k=0; k<nvar; k++) idx[(*ii)++] = offsetl + k; 312842dc13f1SHong Zhang } else { 312942dc13f1SHong Zhang for (k=0; k<nvar; k+=blocksize[j]) { 313042dc13f1SHong Zhang for (k1=0; k1<nselectedvar[j]; k1++) idx[(*ii)++] = offsetl + k + selectedvar[j][k1]; 313142dc13f1SHong Zhang } 313242dc13f1SHong Zhang } 313342dc13f1SHong Zhang } 313442dc13f1SHong Zhang } 313542dc13f1SHong Zhang PetscFunctionReturn(0); 313642dc13f1SHong Zhang } 313742dc13f1SHong Zhang 313842dc13f1SHong Zhang /*@ 313942dc13f1SHong Zhang DMNetworkCreateLocalIS - Create an index set object from the local vector of the network 314042dc13f1SHong Zhang 314142dc13f1SHong Zhang Not collective 314242dc13f1SHong Zhang 314342dc13f1SHong Zhang Input Parameters: 314442dc13f1SHong Zhang + dm - DMNetwork object 314542dc13f1SHong Zhang . numkeys - number of keys 314642dc13f1SHong Zhang . keys - array of keys that define the components of the variables you wish to extract 314742dc13f1SHong Zhang . blocksize - block size of the variables associated to the component 314842dc13f1SHong Zhang . nselectedvar - number of variables in each block to select 314942dc13f1SHong Zhang - selectedvar - the offset into the block of each variable in each block to select 315042dc13f1SHong Zhang 315142dc13f1SHong Zhang Output Parameters: 315242dc13f1SHong Zhang . is - the index set 315342dc13f1SHong Zhang 315442dc13f1SHong Zhang Level: Advanced 315542dc13f1SHong Zhang 315642dc13f1SHong Zhang Notes: 315742dc13f1SHong 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. 315842dc13f1SHong Zhang 315942dc13f1SHong Zhang .seealso: DMNetworkCreate(), DMNetworkCreateIS, ISCreateGeneral() 316042dc13f1SHong Zhang @*/ 316142dc13f1SHong Zhang PetscErrorCode DMNetworkCreateLocalIS(DM dm,PetscInt numkeys,PetscInt keys[],PetscInt blocksize[],PetscInt nselectedvar[],PetscInt *selectedvar[],IS *is) 316242dc13f1SHong Zhang { 316342dc13f1SHong Zhang PetscErrorCode ierr; 316442dc13f1SHong Zhang DM_Network *network = (DM_Network*)dm->data; 316542dc13f1SHong Zhang PetscInt i,p,pstart,pend,nidx,*idx; 316642dc13f1SHong Zhang 316742dc13f1SHong Zhang PetscFunctionBegin; 316842dc13f1SHong Zhang /* Check input parameters */ 316942dc13f1SHong Zhang for (i=0; i<numkeys; i++) { 317042dc13f1SHong Zhang if (!blocksize || blocksize[i] == -1) continue; 317142dc13f1SHong 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]); 317242dc13f1SHong Zhang } 317342dc13f1SHong Zhang 317442dc13f1SHong Zhang pstart = network->pStart; 317542dc13f1SHong Zhang pend = network->pEnd; 317642dc13f1SHong Zhang 317742dc13f1SHong Zhang /* Get local number of idx */ 317842dc13f1SHong Zhang nidx = 0; 317942dc13f1SHong Zhang for (p=pstart; p<pend; p++) { 318042dc13f1SHong Zhang ierr = DMISAddSize_private(network,p,numkeys,keys,blocksize,nselectedvar,&nidx);CHKERRQ(ierr); 318142dc13f1SHong Zhang } 318242dc13f1SHong Zhang 318342dc13f1SHong Zhang /* Compute local idx */ 318442dc13f1SHong Zhang ierr = PetscMalloc1(nidx,&idx);CHKERRQ(ierr); 318542dc13f1SHong Zhang i = 0; 318642dc13f1SHong Zhang for (p=pstart; p<pend; p++) { 318742dc13f1SHong Zhang ierr = DMISComputeLocalIdx_private(dm,p,numkeys,keys,blocksize,nselectedvar,selectedvar,&i,idx);CHKERRQ(ierr); 318842dc13f1SHong Zhang } 318942dc13f1SHong Zhang 319042dc13f1SHong Zhang /* Create is */ 319142dc13f1SHong Zhang ierr = ISCreateGeneral(PETSC_COMM_SELF,nidx,idx,PETSC_COPY_VALUES,is);CHKERRQ(ierr); 319242dc13f1SHong Zhang ierr = PetscFree(idx);CHKERRQ(ierr); 319342dc13f1SHong Zhang PetscFunctionReturn(0); 319442dc13f1SHong Zhang } 3195