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 1238d1cd658SBarry 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, 1248d1cd658SBarry 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 1338d1cd658SBarry 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, 1348d1cd658SBarry 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; 1948d1cd658SBarry Smith for (i=0; i<ne; i++) { 1958d1cd658SBarry 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]); 1968d1cd658SBarry 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 1083*f2f58720SBarry Smith .seealso: DMNetworkGetGlobalEdgeIndex(), DMNetworkGetLocalVertexIndex() 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 1129*f2f58720SBarry Smith . p - the edge or 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 1135*f2f58720SBarry Smith Notes: 1136*f2f58720SBarry Smith These offsets can be passed to MatSetValuesLocal() for matrices obtained with DMCreateMatrix(). 1137*f2f58720SBarry Smith 1138*f2f58720SBarry Smith For vectors obtained with DMCreateLocalVector() the offsets can be used with VecSetValues(). 1139*f2f58720SBarry Smith 1140*f2f58720SBarry Smith For vectors obtained with DMCreateLocalVector() and the array obtained with VecGetArray(vec,&array) you can access or set 1141*f2f58720SBarry Smith the vector values with array[offset]. 1142*f2f58720SBarry Smith 1143*f2f58720SBarry Smith For vectors obtained with DMCreateGlobalVector() the offsets can be used with VecSetValuesLocal(). 1144*f2f58720SBarry Smith 11459988b915SShri Abhyankar Level: intermediate 11469988b915SShri Abhyankar 1147*f2f58720SBarry Smith .seealso: DMGetLocalVector(), DMNetworkGetComponent(), DMNetworkGetGlobalVecOffset(), DMCreateGlobalVector(), VecGetArray(), VecSetValuesLocal(), MatSetValuesLocal() 11489988b915SShri Abhyankar @*/ 11492bf73ac6SHong Zhang PetscErrorCode DMNetworkGetLocalVecOffset(DM dm,PetscInt p,PetscInt compnum,PetscInt *offset) 11509988b915SShri Abhyankar { 11519988b915SShri Abhyankar PetscErrorCode ierr; 11529988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 11539988b915SShri Abhyankar PetscInt offsetp,offsetd; 11549988b915SShri Abhyankar DMNetworkComponentHeader header; 11559988b915SShri Abhyankar 11569988b915SShri Abhyankar PetscFunctionBegin; 11572bf73ac6SHong Zhang ierr = PetscSectionGetOffset(network->plex->localSection,p,&offsetp);CHKERRQ(ierr); 11582bf73ac6SHong Zhang if (compnum == ALL_COMPONENTS) { 11592bf73ac6SHong Zhang *offset = offsetp; 11602bf73ac6SHong Zhang PetscFunctionReturn(0); 11612bf73ac6SHong Zhang } 11622bf73ac6SHong Zhang 11639988b915SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetd);CHKERRQ(ierr); 11649988b915SShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetd); 11659988b915SShri Abhyankar *offset = offsetp + header->offsetvarrel[compnum]; 11669988b915SShri Abhyankar PetscFunctionReturn(0); 11679988b915SShri Abhyankar } 11689988b915SShri Abhyankar 11699988b915SShri Abhyankar /*@ 11702bf73ac6SHong Zhang DMNetworkGetGlobalVecOffset - Get the global offset for accessing the variables associated with a component for the given vertex/edge from the global vector 11719988b915SShri Abhyankar 11729988b915SShri Abhyankar Not Collective 11739988b915SShri Abhyankar 11749988b915SShri Abhyankar Input Parameters: 11752bf73ac6SHong Zhang + dm - the DMNetwork object 1176*f2f58720SBarry Smith . p - the edge or vertex point 11772bf73ac6SHong Zhang - compnum - component number; use ALL_COMPONENTS if no specific component is requested 11789988b915SShri Abhyankar 11799988b915SShri Abhyankar Output Parameters: 11809988b915SShri Abhyankar . offsetg - the global offset 11819988b915SShri Abhyankar 1182*f2f58720SBarry Smith Notes: 1183*f2f58720SBarry Smith These offsets can be passed to MatSetValues() for matrices obtained with DMCreateMatrix(). 1184*f2f58720SBarry Smith 1185*f2f58720SBarry Smith For vectors obtained with DMCreateGlobalVector() the offsets can be used with VecSetValues(). 1186*f2f58720SBarry Smith 1187*f2f58720SBarry Smith For vectors obtained with DMCreateGlobalVector() and the array obtained with VecGetArray(vec,&array) you can access or set 1188*f2f58720SBarry Smith the vector values with array[offset - rstart] where restart is obtained with VecGetOwnershipRange(v,&rstart,NULL); 1189*f2f58720SBarry Smith 11909988b915SShri Abhyankar Level: intermediate 11919988b915SShri Abhyankar 1192*f2f58720SBarry Smith .seealso: DMNetworkGetLocalVecOffset(), DMGetGlobalVector(), DMNetworkGetComponent(), DMCreateGlobalVector(), VecGetArray(), VecSetValues(), MatSetValues() 11939988b915SShri Abhyankar @*/ 11942bf73ac6SHong Zhang PetscErrorCode DMNetworkGetGlobalVecOffset(DM dm,PetscInt p,PetscInt compnum,PetscInt *offsetg) 11959988b915SShri Abhyankar { 11969988b915SShri Abhyankar PetscErrorCode ierr; 11979988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 11989988b915SShri Abhyankar PetscInt offsetp,offsetd; 11999988b915SShri Abhyankar DMNetworkComponentHeader header; 12009988b915SShri Abhyankar 12019988b915SShri Abhyankar PetscFunctionBegin; 12022bf73ac6SHong Zhang ierr = PetscSectionGetOffset(network->plex->globalSection,p,&offsetp);CHKERRQ(ierr); 12032bf73ac6SHong Zhang if (offsetp < 0) offsetp = -(offsetp + 1); /* Convert to actual global offset for ghost vertex */ 12042bf73ac6SHong Zhang 12052bf73ac6SHong Zhang if (compnum == ALL_COMPONENTS) { 12062bf73ac6SHong Zhang *offsetg = offsetp; 12072bf73ac6SHong Zhang PetscFunctionReturn(0); 12082bf73ac6SHong Zhang } 12099988b915SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetd);CHKERRQ(ierr); 12109988b915SShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetd); 12119988b915SShri Abhyankar *offsetg = offsetp + header->offsetvarrel[compnum]; 12129988b915SShri Abhyankar PetscFunctionReturn(0); 12139988b915SShri Abhyankar } 12149988b915SShri Abhyankar 12159988b915SShri Abhyankar /*@ 12162bf73ac6SHong Zhang DMNetworkGetEdgeOffset - Get the offset for accessing the variables associated with the given edge from the local subvector 121724121865SAdrian Maldonado 121824121865SAdrian Maldonado Not Collective 121924121865SAdrian Maldonado 122024121865SAdrian Maldonado Input Parameters: 12212bf73ac6SHong Zhang + dm - the DMNetwork object 122224121865SAdrian Maldonado - p - the edge point 122324121865SAdrian Maldonado 122424121865SAdrian Maldonado Output Parameters: 122524121865SAdrian Maldonado . offset - the offset 122624121865SAdrian Maldonado 122724121865SAdrian Maldonado Level: intermediate 122824121865SAdrian Maldonado 12292bf73ac6SHong Zhang .seealso: DMNetworkGetLocalVecOffset(), DMGetLocalVector() 123024121865SAdrian Maldonado @*/ 123124121865SAdrian Maldonado PetscErrorCode DMNetworkGetEdgeOffset(DM dm,PetscInt p,PetscInt *offset) 123224121865SAdrian Maldonado { 123324121865SAdrian Maldonado PetscErrorCode ierr; 123424121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 123524121865SAdrian Maldonado 123624121865SAdrian Maldonado PetscFunctionBegin; 123724121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->edge.DofSection,p,offset);CHKERRQ(ierr); 123824121865SAdrian Maldonado PetscFunctionReturn(0); 123924121865SAdrian Maldonado } 124024121865SAdrian Maldonado 124124121865SAdrian Maldonado /*@ 12422bf73ac6SHong Zhang DMNetworkGetVertexOffset - Get the offset for accessing the variables associated with the given vertex from the local subvector 124324121865SAdrian Maldonado 124424121865SAdrian Maldonado Not Collective 124524121865SAdrian Maldonado 124624121865SAdrian Maldonado Input Parameters: 12472bf73ac6SHong Zhang + dm - the DMNetwork object 124824121865SAdrian Maldonado - p - the vertex point 124924121865SAdrian Maldonado 125024121865SAdrian Maldonado Output Parameters: 125124121865SAdrian Maldonado . offset - the offset 125224121865SAdrian Maldonado 125324121865SAdrian Maldonado Level: intermediate 125424121865SAdrian Maldonado 12552bf73ac6SHong Zhang .seealso: DMNetworkGetEdgeOffset(), DMGetLocalVector() 125624121865SAdrian Maldonado @*/ 125724121865SAdrian Maldonado PetscErrorCode DMNetworkGetVertexOffset(DM dm,PetscInt p,PetscInt *offset) 125824121865SAdrian Maldonado { 125924121865SAdrian Maldonado PetscErrorCode ierr; 126024121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 126124121865SAdrian Maldonado 126224121865SAdrian Maldonado PetscFunctionBegin; 126324121865SAdrian Maldonado p -= network->vStart; 126424121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->vertex.DofSection,p,offset);CHKERRQ(ierr); 126524121865SAdrian Maldonado PetscFunctionReturn(0); 126624121865SAdrian Maldonado } 12672bf73ac6SHong Zhang 12685f2c45f1SShri Abhyankar /*@ 12692bf73ac6SHong Zhang DMNetworkAddComponent - Adds a network component and number of variables at the given point (vertex/edge) 12705f2c45f1SShri Abhyankar 12715f2c45f1SShri Abhyankar Not Collective 12725f2c45f1SShri Abhyankar 12735f2c45f1SShri Abhyankar Input Parameters: 12744dc646bcSBarry Smith + dm - the DMNetwork 12755f2c45f1SShri Abhyankar . p - the vertex/edge point 12762bf73ac6SHong Zhang . componentkey - component key returned while registering the component; ignored if compvalue=NULL 12772bf73ac6SHong Zhang . compvalue - pointer to the data structure for the component, or NULL if not required. 12782bf73ac6SHong Zhang - nvar - number of variables for the component at the vertex/edge point 12795f2c45f1SShri Abhyankar 128097bb938eSShri Abhyankar Level: beginner 12815f2c45f1SShri Abhyankar 12822bf73ac6SHong Zhang .seealso: DMNetworkGetComponent() 12835f2c45f1SShri Abhyankar @*/ 12842bf73ac6SHong Zhang PetscErrorCode DMNetworkAddComponent(DM dm,PetscInt p,PetscInt componentkey,void* compvalue,PetscInt nvar) 12855f2c45f1SShri Abhyankar { 12865f2c45f1SShri Abhyankar PetscErrorCode ierr; 12875f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 12882bf73ac6SHong Zhang DMNetworkComponent *component = &network->component[componentkey]; 128954dfd506SHong Zhang DMNetworkComponentHeader header; 129054dfd506SHong Zhang DMNetworkComponentValue cvalue; 12912bf73ac6SHong Zhang PetscBool sharedv=PETSC_FALSE; 129254dfd506SHong Zhang PetscInt compnum; 129354dfd506SHong Zhang PetscInt *compsize,*compkey,*compoffset,*compnvar,*compoffsetvarrel; 129454dfd506SHong Zhang void* *compdata; 12955f2c45f1SShri Abhyankar 12965f2c45f1SShri Abhyankar PetscFunctionBegin; 12975f2c45f1SShri Abhyankar ierr = PetscSectionAddDof(network->DofSection,p,nvar);CHKERRQ(ierr); 12982bf73ac6SHong Zhang if (!compvalue) PetscFunctionReturn(0); 12992bf73ac6SHong Zhang 13002bf73ac6SHong Zhang ierr = DMNetworkIsSharedVertex(dm,p,&sharedv);CHKERRQ(ierr); 13012bf73ac6SHong Zhang if (sharedv) { 13022bf73ac6SHong Zhang PetscBool ghost; 13032bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 13042bf73ac6SHong Zhang if (ghost) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Adding a component at a leaf(ghost) shared vertex is not supported"); 13052bf73ac6SHong Zhang } 13062bf73ac6SHong Zhang 130754dfd506SHong Zhang header = &network->header[p]; 130854dfd506SHong Zhang cvalue = &network->cvalue[p]; 130954dfd506SHong Zhang if (header->ndata == header->maxcomps) { 1310f11a936eSBarry Smith PetscInt additional_size; 1311f11a936eSBarry Smith 131254dfd506SHong Zhang /* Reached limit so resize header component arrays */ 131354dfd506SHong Zhang header->maxcomps += 2; 131454dfd506SHong Zhang 131554dfd506SHong Zhang /* Allocate arrays for component information and value */ 131654dfd506SHong Zhang ierr = PetscCalloc5(header->maxcomps,&compsize,header->maxcomps,&compkey,header->maxcomps,&compoffset,header->maxcomps,&compnvar,header->maxcomps,&compoffsetvarrel);CHKERRQ(ierr); 131754dfd506SHong Zhang ierr = PetscMalloc1(header->maxcomps,&compdata);CHKERRQ(ierr); 131854dfd506SHong Zhang 131954dfd506SHong Zhang /* Recalculate header size */ 132054dfd506SHong Zhang header->hsize = sizeof(struct _p_DMNetworkComponentHeader) + 5*header->maxcomps*sizeof(PetscInt); 132154dfd506SHong Zhang 132254dfd506SHong Zhang header->hsize /= sizeof(DMNetworkComponentGenericDataType); 132354dfd506SHong Zhang 132454dfd506SHong Zhang /* Copy over component info */ 132554dfd506SHong Zhang ierr = PetscMemcpy(compsize,header->size,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 132654dfd506SHong Zhang ierr = PetscMemcpy(compkey,header->key,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 132754dfd506SHong Zhang ierr = PetscMemcpy(compoffset,header->offset,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 132854dfd506SHong Zhang ierr = PetscMemcpy(compnvar,header->nvar,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 132954dfd506SHong Zhang ierr = PetscMemcpy(compoffsetvarrel,header->offsetvarrel,header->ndata*sizeof(PetscInt));CHKERRQ(ierr); 133054dfd506SHong Zhang 133154dfd506SHong Zhang /* Copy over component data pointers */ 133254dfd506SHong Zhang ierr = PetscMemcpy(compdata,cvalue->data,header->ndata*sizeof(void*));CHKERRQ(ierr); 133354dfd506SHong Zhang 133454dfd506SHong Zhang /* Free old arrays */ 133554dfd506SHong Zhang ierr = PetscFree5(header->size,header->key,header->offset,header->nvar,header->offsetvarrel);CHKERRQ(ierr); 133654dfd506SHong Zhang ierr = PetscFree(cvalue->data);CHKERRQ(ierr); 133754dfd506SHong Zhang 133854dfd506SHong Zhang /* Update pointers */ 133954dfd506SHong Zhang header->size = compsize; 134054dfd506SHong Zhang header->key = compkey; 134154dfd506SHong Zhang header->offset = compoffset; 134254dfd506SHong Zhang header->nvar = compnvar; 134354dfd506SHong Zhang header->offsetvarrel = compoffsetvarrel; 134454dfd506SHong Zhang 134554dfd506SHong Zhang cvalue->data = compdata; 134654dfd506SHong Zhang 134754dfd506SHong Zhang /* Update DataSection Dofs */ 134854dfd506SHong 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 */ 1349f11a936eSBarry Smith additional_size = (5*(header->maxcomps - header->ndata)*sizeof(PetscInt))/sizeof(DMNetworkComponentGenericDataType); 135054dfd506SHong Zhang ierr = PetscSectionAddDof(network->DataSection,p,additional_size);CHKERRQ(ierr); 135154dfd506SHong Zhang } 135254dfd506SHong Zhang header = &network->header[p]; 135354dfd506SHong Zhang cvalue = &network->cvalue[p]; 135454dfd506SHong Zhang 135554dfd506SHong Zhang compnum = header->ndata; 13562bf73ac6SHong Zhang 13572bf73ac6SHong Zhang header->size[compnum] = component->size; 13582bf73ac6SHong Zhang ierr = PetscSectionAddDof(network->DataSection,p,component->size);CHKERRQ(ierr); 13592bf73ac6SHong Zhang header->key[compnum] = componentkey; 13602bf73ac6SHong Zhang if (compnum != 0) header->offset[compnum] = header->offset[compnum-1] + header->size[compnum-1]; 13612bf73ac6SHong Zhang cvalue->data[compnum] = (void*)compvalue; 13622bf73ac6SHong Zhang 13632bf73ac6SHong Zhang /* variables */ 13642bf73ac6SHong Zhang header->nvar[compnum] += nvar; 13652bf73ac6SHong Zhang if (compnum != 0) header->offsetvarrel[compnum] = header->offsetvarrel[compnum-1] + header->nvar[compnum-1]; 13662bf73ac6SHong Zhang 13672bf73ac6SHong Zhang header->ndata++; 13685f2c45f1SShri Abhyankar PetscFunctionReturn(0); 13695f2c45f1SShri Abhyankar } 13705f2c45f1SShri Abhyankar 137127f51fceSHong Zhang /*@ 13722bf73ac6SHong Zhang DMNetworkGetComponent - Gets the component key, the component data, and the number of variables at a given network point 137327f51fceSHong Zhang 137427f51fceSHong Zhang Not Collective 137527f51fceSHong Zhang 137627f51fceSHong Zhang Input Parameters: 13772bf73ac6SHong Zhang + dm - the DMNetwork object 13782bf73ac6SHong Zhang . p - vertex/edge point 137999c90e12SSatish Balay - compnum - component number; use ALL_COMPONENTS if sum up all the components 138027f51fceSHong Zhang 138127f51fceSHong Zhang Output Parameters: 13822bf73ac6SHong Zhang + compkey - the key obtained when registering the component (use NULL if not required) 13832bf73ac6SHong Zhang . component - the component data (use NULL if not required) 13842bf73ac6SHong Zhang - nvar - number of variables (use NULL if not required) 138527f51fceSHong Zhang 138697bb938eSShri Abhyankar Level: beginner 138727f51fceSHong Zhang 13882bf73ac6SHong Zhang .seealso: DMNetworkAddComponent(), DMNetworkGetNumComponents() 138927f51fceSHong Zhang @*/ 13902bf73ac6SHong Zhang PetscErrorCode DMNetworkGetComponent(DM dm,PetscInt p,PetscInt compnum,PetscInt *compkey,void **component,PetscInt *nvar) 139127f51fceSHong Zhang { 139227f51fceSHong Zhang PetscErrorCode ierr; 139327f51fceSHong Zhang DM_Network *network = (DM_Network*)dm->data; 13942bf73ac6SHong Zhang PetscInt offset = 0; 13952bf73ac6SHong Zhang DMNetworkComponentHeader header; 139627f51fceSHong Zhang 139727f51fceSHong Zhang PetscFunctionBegin; 13982bf73ac6SHong Zhang if (compnum == ALL_COMPONENTS) { 139927f51fceSHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 140027f51fceSHong Zhang PetscFunctionReturn(0); 140127f51fceSHong Zhang } 140227f51fceSHong Zhang 14032bf73ac6SHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 140442dc13f1SHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offset); 14055f2c45f1SShri Abhyankar 14062bf73ac6SHong Zhang if (compnum >= 0) { 14072bf73ac6SHong Zhang if (compkey) *compkey = header->key[compnum]; 14082bf73ac6SHong Zhang if (component) { 140954dfd506SHong Zhang offset += header->hsize+header->offset[compnum]; 14102bf73ac6SHong Zhang *component = network->componentdataarray+offset; 14112bf73ac6SHong Zhang } 14122bf73ac6SHong Zhang } 14135f2c45f1SShri Abhyankar 14142bf73ac6SHong Zhang if (nvar) *nvar = header->nvar[compnum]; 141554dfd506SHong Zhang 14165f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14175f2c45f1SShri Abhyankar } 14185f2c45f1SShri Abhyankar 14192bf73ac6SHong Zhang /* 14202bf73ac6SHong Zhang Sets up the array that holds the data for all components and its associated section. 14212bf73ac6SHong 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. 14222bf73ac6SHong Zhang */ 14235f2c45f1SShri Abhyankar PetscErrorCode DMNetworkComponentSetUp(DM dm) 14245f2c45f1SShri Abhyankar { 14255f2c45f1SShri Abhyankar PetscErrorCode ierr; 14265f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 1427f11a936eSBarry Smith PetscInt arr_size,p,offset,offsetp,ncomp,i,*headerarr; 14285f2c45f1SShri Abhyankar DMNetworkComponentHeader header; 14295f2c45f1SShri Abhyankar DMNetworkComponentValue cvalue; 1430f11a936eSBarry Smith DMNetworkComponentHeader headerinfo; 14315f2c45f1SShri Abhyankar DMNetworkComponentGenericDataType *componentdataarray; 14325f2c45f1SShri Abhyankar 14335f2c45f1SShri Abhyankar PetscFunctionBegin; 14345f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr); 14355f2c45f1SShri Abhyankar ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr); 1436f11a936eSBarry Smith /* arr_size+1 fixes pipeline test of opensolaris-misc for src/dm/tests/ex10.c -- Do not know why */ 1437f11a936eSBarry Smith ierr = PetscCalloc1(arr_size+1,&network->componentdataarray);CHKERRQ(ierr); 14385f2c45f1SShri Abhyankar componentdataarray = network->componentdataarray; 14395f2c45f1SShri Abhyankar for (p = network->pStart; p < network->pEnd; p++) { 14405f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 14415f2c45f1SShri Abhyankar /* Copy header */ 14425f2c45f1SShri Abhyankar header = &network->header[p]; 1443f11a936eSBarry Smith headerinfo = (DMNetworkComponentHeader)(componentdataarray+offsetp); 144454dfd506SHong Zhang ierr = PetscMemcpy(headerinfo,header,sizeof(struct _p_DMNetworkComponentHeader));CHKERRQ(ierr); 1445f11a936eSBarry Smith headerarr = (PetscInt*)(headerinfo+1); 144654dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->size,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 144754dfd506SHong Zhang headerarr += header->maxcomps; 144854dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->key,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 144954dfd506SHong Zhang headerarr += header->maxcomps; 145054dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->offset,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 145154dfd506SHong Zhang headerarr += header->maxcomps; 145254dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->nvar,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 145354dfd506SHong Zhang headerarr += header->maxcomps; 145454dfd506SHong Zhang ierr = PetscMemcpy(headerarr,header->offsetvarrel,header->maxcomps*sizeof(PetscInt));CHKERRQ(ierr); 145554dfd506SHong Zhang 14565f2c45f1SShri Abhyankar /* Copy data */ 14575f2c45f1SShri Abhyankar cvalue = &network->cvalue[p]; 14585f2c45f1SShri Abhyankar ncomp = header->ndata; 14592bf73ac6SHong Zhang 14605f2c45f1SShri Abhyankar for (i = 0; i < ncomp; i++) { 146154dfd506SHong Zhang offset = offsetp + header->hsize + header->offset[i]; 1462302440fdSBarry Smith ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 14635f2c45f1SShri Abhyankar } 14645f2c45f1SShri Abhyankar } 14655f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14665f2c45f1SShri Abhyankar } 14675f2c45f1SShri Abhyankar 14685f2c45f1SShri Abhyankar /* Sets up the section for dofs. This routine is called during DMSetUp() */ 14692bf73ac6SHong Zhang static PetscErrorCode DMNetworkVariablesSetUp(DM dm) 14705f2c45f1SShri Abhyankar { 14715f2c45f1SShri Abhyankar PetscErrorCode ierr; 14725f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 14732bf73ac6SHong Zhang MPI_Comm comm; 14742bf73ac6SHong Zhang PetscMPIInt size; 14755f2c45f1SShri Abhyankar 14765f2c45f1SShri Abhyankar PetscFunctionBegin; 14772bf73ac6SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 14782bf73ac6SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 14792bf73ac6SHong Zhang 14802bf73ac6SHong Zhang if (size > 1) { /* Sync nvar at shared vertices for all processes */ 14812bf73ac6SHong Zhang PetscSF sf = network->plex->sf; 14822bf73ac6SHong Zhang PetscInt *local_nvar, *remote_nvar,nroots,nleaves,p=-1,i,nsv; 14832bf73ac6SHong Zhang const PetscInt *svtx; 14842bf73ac6SHong Zhang PetscBool ghost; 14852bf73ac6SHong Zhang /* 14862bf73ac6SHong Zhang PetscMPIInt rank; 14872bf73ac6SHong Zhang const PetscInt *ilocal; 14882bf73ac6SHong Zhang const PetscSFNode *iremote; 14892bf73ac6SHong Zhang ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 14902bf73ac6SHong Zhang ierr = PetscSFGetGraph(sf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr); 14912bf73ac6SHong Zhang */ 14922bf73ac6SHong Zhang ierr = PetscSFGetGraph(sf,&nroots,&nleaves,NULL,NULL);CHKERRQ(ierr); 14932bf73ac6SHong Zhang ierr = PetscCalloc2(nroots,&local_nvar,nroots,&remote_nvar);CHKERRQ(ierr); 14942bf73ac6SHong Zhang 14952bf73ac6SHong Zhang /* Leaves copy user's nvar to local_nvar */ 14962bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&nsv,&svtx);CHKERRQ(ierr); 14972bf73ac6SHong Zhang for (i=0; i<nsv; i++) { 14982bf73ac6SHong Zhang p = svtx[i]; 14992bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 15002bf73ac6SHong Zhang if (!ghost) continue; 15012bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,&local_nvar[p]);CHKERRQ(ierr); 15022bf73ac6SHong Zhang /* printf("[%d] Before SFReduce: leaf local_nvar[%d] = %d\n",rank,p,local_nvar[p]); */ 15032bf73ac6SHong Zhang } 15042bf73ac6SHong Zhang 15052bf73ac6SHong Zhang /* Leaves add local_nvar to root remote_nvar */ 15062bf73ac6SHong Zhang ierr = PetscSFReduceBegin(sf, MPIU_INT, local_nvar, remote_nvar, MPI_SUM);CHKERRQ(ierr); 15072bf73ac6SHong Zhang ierr = PetscSFReduceEnd(sf, MPIU_INT, local_nvar, remote_nvar, MPI_SUM);CHKERRQ(ierr); 15082bf73ac6SHong Zhang /* printf("[%d] remote_nvar[%d] = %d\n",rank,p,remote_nvar[p]); */ 15092bf73ac6SHong Zhang 15102bf73ac6SHong Zhang /* Update roots' local_nvar */ 15112bf73ac6SHong Zhang for (i=0; i<nsv; i++) { 15122bf73ac6SHong Zhang p = svtx[i]; 15132bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 15142bf73ac6SHong Zhang if (ghost) continue; 15152bf73ac6SHong Zhang 15162bf73ac6SHong Zhang ierr = PetscSectionAddDof(network->DofSection,p,remote_nvar[p]);CHKERRQ(ierr); 15172bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,&local_nvar[p]);CHKERRQ(ierr); 15182bf73ac6SHong Zhang /* printf("[%d] After SFReduce: root local_nvar[%d] = %d\n",rank,p,local_nvar[p]); */ 15192bf73ac6SHong Zhang } 15202bf73ac6SHong Zhang 15212bf73ac6SHong Zhang /* Roots Bcast nvar to leaves */ 1522ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sf, MPIU_INT, local_nvar, remote_nvar,MPI_REPLACE);CHKERRQ(ierr); 1523ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sf, MPIU_INT, local_nvar, remote_nvar,MPI_REPLACE);CHKERRQ(ierr); 15242bf73ac6SHong Zhang 15252bf73ac6SHong Zhang /* Leaves reset receved/remote nvar to dm */ 15262bf73ac6SHong Zhang for (i=0; i<nsv; i++) { 15272bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 15282bf73ac6SHong Zhang if (!ghost) continue; 15292bf73ac6SHong Zhang p = svtx[i]; 15302bf73ac6SHong Zhang /* printf("[%d] leaf reset nvar %d at p= %d \n",rank,remote_nvar[p],p); */ 15312bf73ac6SHong Zhang /* DMNetworkSetNumVariables(dm,p,remote_nvar[p]) */ 15322bf73ac6SHong Zhang ierr = PetscSectionSetDof(network->DofSection,p,remote_nvar[p]);CHKERRQ(ierr); 15332bf73ac6SHong Zhang } 15342bf73ac6SHong Zhang 15352bf73ac6SHong Zhang ierr = PetscFree2(local_nvar,remote_nvar);CHKERRQ(ierr); 15362bf73ac6SHong Zhang } 15372bf73ac6SHong Zhang 15385f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr); 15395f2c45f1SShri Abhyankar PetscFunctionReturn(0); 15405f2c45f1SShri Abhyankar } 15415f2c45f1SShri Abhyankar 154224121865SAdrian Maldonado /* Get a subsection from a range of points */ 15439dddd249SSatish Balay static PetscErrorCode DMNetworkGetSubSection_private(PetscSection main,PetscInt pstart,PetscInt pend,PetscSection *subsection) 154424121865SAdrian Maldonado { 154524121865SAdrian Maldonado PetscErrorCode ierr; 154624121865SAdrian Maldonado PetscInt i, nvar; 154724121865SAdrian Maldonado 154824121865SAdrian Maldonado PetscFunctionBegin; 15499dddd249SSatish Balay ierr = PetscSectionCreate(PetscObjectComm((PetscObject)main), subsection);CHKERRQ(ierr); 155024121865SAdrian Maldonado ierr = PetscSectionSetChart(*subsection, 0, pend - pstart);CHKERRQ(ierr); 155124121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 15529dddd249SSatish Balay ierr = PetscSectionGetDof(main,i,&nvar);CHKERRQ(ierr); 155324121865SAdrian Maldonado ierr = PetscSectionSetDof(*subsection, i - pstart, nvar);CHKERRQ(ierr); 155424121865SAdrian Maldonado } 155524121865SAdrian Maldonado 155624121865SAdrian Maldonado ierr = PetscSectionSetUp(*subsection);CHKERRQ(ierr); 155724121865SAdrian Maldonado PetscFunctionReturn(0); 155824121865SAdrian Maldonado } 155924121865SAdrian Maldonado 156024121865SAdrian Maldonado /* Create a submap of points with a GlobalToLocal structure */ 15612bf73ac6SHong Zhang static PetscErrorCode DMNetworkSetSubMap_private(PetscInt pstart, PetscInt pend, ISLocalToGlobalMapping *map) 156224121865SAdrian Maldonado { 156324121865SAdrian Maldonado PetscErrorCode ierr; 156424121865SAdrian Maldonado PetscInt i, *subpoints; 156524121865SAdrian Maldonado 156624121865SAdrian Maldonado PetscFunctionBegin; 156724121865SAdrian Maldonado /* Create index sets to map from "points" to "subpoints" */ 156824121865SAdrian Maldonado ierr = PetscMalloc1(pend - pstart, &subpoints);CHKERRQ(ierr); 156924121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 157024121865SAdrian Maldonado subpoints[i - pstart] = i; 157124121865SAdrian Maldonado } 1572459726d8SSatish Balay ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,pend-pstart,subpoints,PETSC_COPY_VALUES,map);CHKERRQ(ierr); 157324121865SAdrian Maldonado ierr = PetscFree(subpoints);CHKERRQ(ierr); 157424121865SAdrian Maldonado PetscFunctionReturn(0); 157524121865SAdrian Maldonado } 157624121865SAdrian Maldonado 157724121865SAdrian Maldonado /*@ 15782bf73ac6SHong Zhang DMNetworkAssembleGraphStructures - Assembles vertex and edge data structures. Must be called after DMNetworkDistribute 157924121865SAdrian Maldonado 15802bf73ac6SHong Zhang Collective on dm 158124121865SAdrian Maldonado 158224121865SAdrian Maldonado Input Parameters: 15832bf73ac6SHong Zhang . dm - the DMNetworkObject 158424121865SAdrian Maldonado 158524121865SAdrian Maldonado Note: the routine will create alternative orderings for the vertices and edges. Assume global network points are: 158624121865SAdrian Maldonado 158724121865SAdrian Maldonado points = [0 1 2 3 4 5 6] 158824121865SAdrian Maldonado 1589caf410d2SHong 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]). 159024121865SAdrian Maldonado 159124121865SAdrian Maldonado With this new ordering a local PetscSection, global PetscSection and PetscSF will be created specific to the subset. 159224121865SAdrian Maldonado 159324121865SAdrian Maldonado Level: intermediate 159424121865SAdrian Maldonado 159524121865SAdrian Maldonado @*/ 159624121865SAdrian Maldonado PetscErrorCode DMNetworkAssembleGraphStructures(DM dm) 159724121865SAdrian Maldonado { 159824121865SAdrian Maldonado PetscErrorCode ierr; 159924121865SAdrian Maldonado MPI_Comm comm; 1600f11a936eSBarry Smith PetscMPIInt size; 160124121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 160224121865SAdrian Maldonado 1603eab1376dSHong Zhang PetscFunctionBegin; 160424121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 1605ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 160624121865SAdrian Maldonado 160724121865SAdrian Maldonado /* Create maps for vertices and edges */ 160824121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 160924121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->eStart,network->eEnd,&network->edge.mapping);CHKERRQ(ierr); 161024121865SAdrian Maldonado 161124121865SAdrian Maldonado /* Create local sub-sections */ 161224121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->vStart,network->vEnd,&network->vertex.DofSection);CHKERRQ(ierr); 161324121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->eStart,network->eEnd,&network->edge.DofSection);CHKERRQ(ierr); 161424121865SAdrian Maldonado 16159852e123SBarry Smith if (size > 1) { 161624121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 161722bbedd7SHong Zhang 161824121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->vertex.DofSection, network->vertex.sf, PETSC_FALSE, PETSC_FALSE, &network->vertex.GlobalDofSection);CHKERRQ(ierr); 161924121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->edge.mapping, &network->edge.sf);CHKERRQ(ierr); 162024121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->edge.DofSection, network->edge.sf, PETSC_FALSE, PETSC_FALSE, &network->edge.GlobalDofSection);CHKERRQ(ierr); 162124121865SAdrian Maldonado } else { 162224121865SAdrian Maldonado /* create structures for vertex */ 162324121865SAdrian Maldonado ierr = PetscSectionClone(network->vertex.DofSection,&network->vertex.GlobalDofSection);CHKERRQ(ierr); 162424121865SAdrian Maldonado /* create structures for edge */ 162524121865SAdrian Maldonado ierr = PetscSectionClone(network->edge.DofSection,&network->edge.GlobalDofSection);CHKERRQ(ierr); 162624121865SAdrian Maldonado } 162724121865SAdrian Maldonado 162824121865SAdrian Maldonado /* Add viewers */ 162924121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->edge.GlobalDofSection,"Global edge dof section");CHKERRQ(ierr); 163024121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->vertex.GlobalDofSection,"Global vertex dof section");CHKERRQ(ierr); 163124121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->edge.GlobalDofSection, NULL, "-edge_global_section_view");CHKERRQ(ierr); 163224121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->vertex.GlobalDofSection, NULL, "-vertex_global_section_view");CHKERRQ(ierr); 163324121865SAdrian Maldonado PetscFunctionReturn(0); 163424121865SAdrian Maldonado } 16357b6afd5bSHong Zhang 1636f11a936eSBarry Smith /* 1637f11a936eSBarry Smith Add all subnetid for the input vertex v in this process to the btable 1638f11a936eSBarry Smith vertex_subnetid = supportingedge_subnetid 1639f11a936eSBarry Smith */ 1640f11a936eSBarry Smith PETSC_STATIC_INLINE PetscErrorCode SetSubnetIdLookupBT(DM dm,PetscInt v,PetscInt Nsubnet,PetscBT btable) 1641f11a936eSBarry Smith { 1642f11a936eSBarry Smith PetscErrorCode ierr; 1643f11a936eSBarry Smith PetscInt e,nedges,offset; 1644f11a936eSBarry Smith const PetscInt *edges; 1645f11a936eSBarry Smith DM_Network *newDMnetwork = (DM_Network*)dm->data; 1646f11a936eSBarry Smith DMNetworkComponentHeader header; 1647f11a936eSBarry Smith 1648f11a936eSBarry Smith PetscFunctionBegin; 1649f11a936eSBarry Smith ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 1650f11a936eSBarry Smith ierr = PetscBTMemzero(Nsubnet,btable);CHKERRQ(ierr); 1651f11a936eSBarry Smith for (e=0; e<nedges; e++) { 1652f11a936eSBarry Smith ierr = PetscSectionGetOffset(newDMnetwork->DataSection,edges[e],&offset);CHKERRQ(ierr); 1653f11a936eSBarry Smith header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset); 1654f11a936eSBarry Smith ierr = PetscBTSet(btable,header->subnetid);CHKERRQ(ierr); 1655f11a936eSBarry Smith } 1656f11a936eSBarry Smith PetscFunctionReturn(0); 1657f11a936eSBarry Smith } 1658f11a936eSBarry Smith 16595f2c45f1SShri Abhyankar /*@ 16602bf73ac6SHong Zhang DMNetworkDistribute - Distributes the network and moves associated component data 16615f2c45f1SShri Abhyankar 16625f2c45f1SShri Abhyankar Collective 16635f2c45f1SShri Abhyankar 1664d8d19677SJose E. Roman Input Parameters: 1665d3464fd4SAdrian Maldonado + DM - the DMNetwork object 16662bf73ac6SHong Zhang - overlap - the overlap of partitions, 0 is the default 16675f2c45f1SShri Abhyankar 16685b3f975aSHong Zhang Options Database Key: 16695b3f975aSHong Zhang + -dmnetwork_view - Calls DMView() at the conclusion of DMSetUp() 16705b3f975aSHong Zhang - -dmnetwork_view_distributed - Calls DMView() at the conclusion of DMNetworkDistribute() 16715b3f975aSHong Zhang 16725f2c45f1SShri Abhyankar Notes: 16738b171c8eSHong Zhang Distributes the network with <overlap>-overlapping partitioning of the edges. 16745f2c45f1SShri Abhyankar 16755f2c45f1SShri Abhyankar Level: intermediate 16765f2c45f1SShri Abhyankar 16772bf73ac6SHong Zhang .seealso: DMNetworkCreate() 16785f2c45f1SShri Abhyankar @*/ 1679d3464fd4SAdrian Maldonado PetscErrorCode DMNetworkDistribute(DM *dm,PetscInt overlap) 16805f2c45f1SShri Abhyankar { 1681d3464fd4SAdrian Maldonado MPI_Comm comm; 16825f2c45f1SShri Abhyankar PetscErrorCode ierr; 1683d3464fd4SAdrian Maldonado PetscMPIInt size; 1684d3464fd4SAdrian Maldonado DM_Network *oldDMnetwork = (DM_Network*)((*dm)->data); 1685d3464fd4SAdrian Maldonado DM_Network *newDMnetwork; 1686caf410d2SHong Zhang PetscSF pointsf=NULL; 16875f2c45f1SShri Abhyankar DM newDM; 1688f11a936eSBarry Smith PetscInt j,e,v,offset,*subnetvtx,*subnetedge,Nsubnet,gidx,svtx_idx,nv; 16892bf73ac6SHong Zhang PetscInt to_net,from_net,*svto; 1690f11a936eSBarry Smith PetscBT btable; 169151ac5effSHong Zhang PetscPartitioner part; 1692b9c6e19dSShri Abhyankar DMNetworkComponentHeader header; 16935f2c45f1SShri Abhyankar 16945f2c45f1SShri Abhyankar PetscFunctionBegin; 1695d3464fd4SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)*dm,&comm);CHKERRQ(ierr); 1696ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 1697d3464fd4SAdrian Maldonado if (size == 1) PetscFunctionReturn(0); 1698d3464fd4SAdrian Maldonado 16995b3f975aSHong Zhang if (overlap) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"overlap %D != 0 is not supported yet",overlap); 17005b3f975aSHong Zhang 17012bf73ac6SHong 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. */ 1702d3464fd4SAdrian Maldonado ierr = DMNetworkCreate(PetscObjectComm((PetscObject)*dm),&newDM);CHKERRQ(ierr); 17035f2c45f1SShri Abhyankar newDMnetwork = (DM_Network*)newDM->data; 170454dfd506SHong Zhang newDMnetwork->max_comps_registered = oldDMnetwork->max_comps_registered; 170554dfd506SHong Zhang ierr = PetscMalloc1(newDMnetwork->max_comps_registered,&newDMnetwork->component);CHKERRQ(ierr); 170651ac5effSHong Zhang 170751ac5effSHong Zhang /* Enable runtime options for petscpartitioner */ 170851ac5effSHong Zhang ierr = DMPlexGetPartitioner(oldDMnetwork->plex,&part);CHKERRQ(ierr); 170951ac5effSHong Zhang ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); 171051ac5effSHong Zhang 17112bf73ac6SHong Zhang /* Distribute plex dm */ 171280cf41d5SMatthew G. Knepley ierr = DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr); 171351ac5effSHong Zhang 17145f2c45f1SShri Abhyankar /* Distribute dof section */ 17152bf73ac6SHong Zhang ierr = PetscSectionCreate(comm,&newDMnetwork->DofSection);CHKERRQ(ierr); 17165f2c45f1SShri Abhyankar ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr); 171751ac5effSHong Zhang 17185f2c45f1SShri Abhyankar /* Distribute data and associated section */ 17192bf73ac6SHong Zhang ierr = PetscSectionCreate(comm,&newDMnetwork->DataSection);CHKERRQ(ierr); 172031da1fc8SHong Zhang ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPIU_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr); 172124121865SAdrian Maldonado 17225f2c45f1SShri Abhyankar ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr); 17235f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr); 17245f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr); 17255f2c45f1SShri Abhyankar newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart; 17266fefedf4SHong Zhang newDMnetwork->nVertices = newDMnetwork->vEnd - newDMnetwork->vStart; 17276fefedf4SHong Zhang newDMnetwork->NVertices = oldDMnetwork->NVertices; 17285f2c45f1SShri Abhyankar newDMnetwork->NEdges = oldDMnetwork->NEdges; 1729f11a936eSBarry Smith newDMnetwork->svtable = oldDMnetwork->svtable; /* global table! */ 17302bf73ac6SHong Zhang oldDMnetwork->svtable = NULL; 173124121865SAdrian Maldonado 17321bb6d2a8SBarry Smith /* Set Dof section as the section for dm */ 173392fd8e1eSJed Brown ierr = DMSetLocalSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr); 1734e87a4003SBarry Smith ierr = DMGetGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr); 17355f2c45f1SShri Abhyankar 1736b9c6e19dSShri Abhyankar /* Setup subnetwork info in the newDM */ 17372bf73ac6SHong Zhang newDMnetwork->Nsubnet = oldDMnetwork->Nsubnet; 17382bf73ac6SHong Zhang newDMnetwork->Nsvtx = oldDMnetwork->Nsvtx; 17392bf73ac6SHong Zhang oldDMnetwork->Nsvtx = 0; 17402bf73ac6SHong Zhang newDMnetwork->svtx = oldDMnetwork->svtx; /* global vertices! */ 17412bf73ac6SHong Zhang oldDMnetwork->svtx = NULL; 17422bf73ac6SHong Zhang ierr = PetscCalloc1(newDMnetwork->Nsubnet,&newDMnetwork->subnet);CHKERRQ(ierr); 17432bf73ac6SHong Zhang 17442bf73ac6SHong Zhang /* Copy over the global number of vertices and edges in each subnetwork. 17452bf73ac6SHong Zhang Note: these are calculated in DMNetworkLayoutSetUp() 1746b9c6e19dSShri Abhyankar */ 1747f11a936eSBarry Smith Nsubnet = newDMnetwork->Nsubnet; 1748f11a936eSBarry Smith for (j = 0; j < Nsubnet; j++) { 1749b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nvtx = oldDMnetwork->subnet[j].Nvtx; 1750b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nedge = oldDMnetwork->subnet[j].Nedge; 1751b9c6e19dSShri Abhyankar } 1752b9c6e19dSShri Abhyankar 1753f11a936eSBarry Smith /* Count local nedges for subnetworks */ 1754b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++) { 1755b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 175654dfd506SHong Zhang header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset); 175754dfd506SHong Zhang /* Update pointers */ 175854dfd506SHong Zhang header->size = (PetscInt*)(header + 1); 175954dfd506SHong Zhang header->key = header->size + header->maxcomps; 176054dfd506SHong Zhang header->offset = header->key + header->maxcomps; 176154dfd506SHong Zhang header->nvar = header->offset + header->maxcomps; 176254dfd506SHong Zhang header->offsetvarrel = header->nvar + header->maxcomps; 176354dfd506SHong Zhang 1764b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nedge++; 1765b9c6e19dSShri Abhyankar } 1766b9c6e19dSShri Abhyankar 1767f11a936eSBarry Smith /* Count local nvtx for subnetworks */ 1768f11a936eSBarry Smith ierr = PetscBTCreate(Nsubnet,&btable);CHKERRQ(ierr); 1769b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++) { 1770b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1771b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 177254dfd506SHong Zhang /* Update pointers */ 177354dfd506SHong Zhang header->size = (PetscInt*)(header + 1); 177454dfd506SHong Zhang header->key = header->size + header->maxcomps; 177554dfd506SHong Zhang header->offset = header->key + header->maxcomps; 177654dfd506SHong Zhang header->nvar = header->offset + header->maxcomps; 177754dfd506SHong Zhang header->offsetvarrel = header->nvar + header->maxcomps; 177854dfd506SHong Zhang 17792bf73ac6SHong Zhang /* shared vertices: use gidx=header->index to check if v is a shared vertex */ 17802bf73ac6SHong Zhang gidx = header->index; 17812bf73ac6SHong Zhang ierr = PetscTableFind(newDMnetwork->svtable,gidx+1,&svtx_idx);CHKERRQ(ierr); 17822bf73ac6SHong Zhang svtx_idx--; 17832bf73ac6SHong Zhang 17842bf73ac6SHong Zhang if (svtx_idx < 0) { /* not a shared vertex */ 1785b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nvtx++; 17862bf73ac6SHong Zhang } else { /* a shared vertex belongs to more than one subnetworks, it is being counted by multiple subnets */ 1787f11a936eSBarry Smith ierr = SetSubnetIdLookupBT(newDM,v,Nsubnet,btable);CHKERRQ(ierr); 1788f11a936eSBarry Smith 17892bf73ac6SHong Zhang from_net = newDMnetwork->svtx[svtx_idx].sv[0]; 1790f11a936eSBarry Smith if (PetscBTLookup(btable,from_net)) newDMnetwork->subnet[from_net].nvtx++; /* sv is on from_net */ 1791f11a936eSBarry Smith 17922bf73ac6SHong Zhang for (j=1; j<newDMnetwork->svtx[svtx_idx].n; j++) { 17932bf73ac6SHong Zhang svto = newDMnetwork->svtx[svtx_idx].sv + 2*j; 17942bf73ac6SHong Zhang to_net = svto[0]; 1795f11a936eSBarry Smith if (PetscBTLookup(btable,to_net)) newDMnetwork->subnet[to_net].nvtx++; /* sv is on to_net */ 17962bf73ac6SHong Zhang } 17972bf73ac6SHong Zhang } 1798b9c6e19dSShri Abhyankar } 1799b9c6e19dSShri Abhyankar 18002bf73ac6SHong Zhang /* Get total local nvtx for subnetworks */ 18012bf73ac6SHong Zhang nv = 0; 1802f11a936eSBarry Smith for (j=0; j<Nsubnet; j++) nv += newDMnetwork->subnet[j].nvtx; 18032bf73ac6SHong Zhang nv += newDMnetwork->Nsvtx; 1804caf410d2SHong Zhang 18052bf73ac6SHong Zhang /* Now create the vertices and edge arrays for the subnetworks */ 1806f11a936eSBarry Smith ierr = PetscCalloc2(newDMnetwork->nEdges,&subnetedge,nv,&subnetvtx);CHKERRQ(ierr); /* Maps local vertex to local subnetwork's vertex */ 1807f11a936eSBarry Smith newDMnetwork->subnetedge = subnetedge; 18082bf73ac6SHong Zhang newDMnetwork->subnetvtx = subnetvtx; 1809f11a936eSBarry Smith for (j=0; j < newDMnetwork->Nsubnet; j++) { 1810f11a936eSBarry Smith newDMnetwork->subnet[j].edges = subnetedge; 1811f11a936eSBarry Smith subnetedge += newDMnetwork->subnet[j].nedge; 18122bf73ac6SHong Zhang 1813caf410d2SHong Zhang newDMnetwork->subnet[j].vertices = subnetvtx; 1814caf410d2SHong Zhang subnetvtx += newDMnetwork->subnet[j].nvtx; 1815caf410d2SHong Zhang 18162bf73ac6SHong 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. */ 1817b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].nvtx = newDMnetwork->subnet[j].nedge = 0; 1818b9c6e19dSShri Abhyankar } 18192bf73ac6SHong Zhang newDMnetwork->svertices = subnetvtx; 1820b9c6e19dSShri Abhyankar 18212bf73ac6SHong Zhang /* Set the edges and vertices in each subnetwork */ 1822b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++) { 1823b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 1824b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1825b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].edges[newDMnetwork->subnet[header->subnetid].nedge++] = e; 1826b9c6e19dSShri Abhyankar } 1827b9c6e19dSShri Abhyankar 18282bf73ac6SHong Zhang nv = 0; 1829b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++) { 1830b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1831b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 18322bf73ac6SHong Zhang 18332bf73ac6SHong Zhang /* coupling vertices: use gidx = header->index to check if v is a coupling vertex */ 18342bf73ac6SHong Zhang ierr = PetscTableFind(newDMnetwork->svtable,header->index+1,&svtx_idx);CHKERRQ(ierr); 18352bf73ac6SHong Zhang svtx_idx--; 18362bf73ac6SHong Zhang if (svtx_idx < 0) { 1837b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].vertices[newDMnetwork->subnet[header->subnetid].nvtx++] = v; 18382bf73ac6SHong Zhang } else { /* a shared vertex */ 18392bf73ac6SHong Zhang newDMnetwork->svertices[nv++] = v; 18402bf73ac6SHong Zhang 1841f11a936eSBarry Smith /* add all subnetid for this shared vertex in this process to btable */ 1842f11a936eSBarry Smith ierr = SetSubnetIdLookupBT(newDM,v,Nsubnet,btable);CHKERRQ(ierr); 1843f11a936eSBarry Smith 18442bf73ac6SHong Zhang from_net = newDMnetwork->svtx[svtx_idx].sv[0]; 1845f11a936eSBarry Smith if (PetscBTLookup(btable,from_net)) 18462bf73ac6SHong Zhang newDMnetwork->subnet[from_net].vertices[newDMnetwork->subnet[from_net].nvtx++] = v; 18472bf73ac6SHong Zhang 18482bf73ac6SHong Zhang for (j=1; j<newDMnetwork->svtx[svtx_idx].n; j++) { 18492bf73ac6SHong Zhang svto = newDMnetwork->svtx[svtx_idx].sv + 2*j; 18502bf73ac6SHong Zhang to_net = svto[0]; 1851f11a936eSBarry Smith if (PetscBTLookup(btable,to_net)) 18522bf73ac6SHong Zhang newDMnetwork->subnet[to_net].vertices[newDMnetwork->subnet[to_net].nvtx++] = v; 1853b9c6e19dSShri Abhyankar } 18542bf73ac6SHong Zhang } 18552bf73ac6SHong Zhang } 18562bf73ac6SHong Zhang newDMnetwork->nsvtx = nv; /* num of local shared vertices */ 1857b9c6e19dSShri Abhyankar 1858caf410d2SHong Zhang newDM->setupcalled = (*dm)->setupcalled; 185922bbedd7SHong Zhang newDMnetwork->distributecalled = PETSC_TRUE; 1860caf410d2SHong Zhang 18612bf73ac6SHong Zhang /* Free spaces */ 186224121865SAdrian Maldonado ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr); 1863d3464fd4SAdrian Maldonado ierr = DMDestroy(dm);CHKERRQ(ierr); 1864f11a936eSBarry Smith ierr = PetscBTDestroy(&btable);CHKERRQ(ierr); 18652bf73ac6SHong Zhang 18665b3f975aSHong Zhang /* View distributed dmnetwork */ 18675b3f975aSHong Zhang ierr = DMViewFromOptions(newDM,NULL,"-dmnetwork_view_distributed");CHKERRQ(ierr); 18685b3f975aSHong Zhang 1869d3464fd4SAdrian Maldonado *dm = newDM; 18705f2c45f1SShri Abhyankar PetscFunctionReturn(0); 18715f2c45f1SShri Abhyankar } 18725f2c45f1SShri Abhyankar 187324121865SAdrian Maldonado /*@C 18742bf73ac6SHong Zhang PetscSFGetSubSF - Returns an SF for a specific subset of points. Leaves are re-numbered to reflect the new ordering 18752bf73ac6SHong Zhang 18762bf73ac6SHong Zhang Collective 187724121865SAdrian Maldonado 187824121865SAdrian Maldonado Input Parameters: 18799dddd249SSatish Balay + mainSF - the original SF structure 188024121865SAdrian Maldonado - map - a ISLocalToGlobal mapping that contains the subset of points 188124121865SAdrian Maldonado 188297bb3fdcSJose E. Roman Output Parameter: 18839dddd249SSatish Balay . subSF - a subset of the mainSF for the desired subset. 1884ee300463SSatish Balay 1885ee300463SSatish Balay Level: intermediate 18867d928bffSSatish Balay @*/ 18879dddd249SSatish Balay PetscErrorCode PetscSFGetSubSF(PetscSF mainsf,ISLocalToGlobalMapping map,PetscSF *subSF) 18882bf73ac6SHong Zhang { 188924121865SAdrian Maldonado PetscErrorCode ierr; 189024121865SAdrian Maldonado PetscInt nroots, nleaves, *ilocal_sub; 189124121865SAdrian Maldonado PetscInt i, *ilocal_map, nroots_sub, nleaves_sub = 0; 189224121865SAdrian Maldonado PetscInt *local_points, *remote_points; 189324121865SAdrian Maldonado PetscSFNode *iremote_sub; 189424121865SAdrian Maldonado const PetscInt *ilocal; 189524121865SAdrian Maldonado const PetscSFNode *iremote; 189624121865SAdrian Maldonado 189724121865SAdrian Maldonado PetscFunctionBegin; 18989dddd249SSatish Balay ierr = PetscSFGetGraph(mainsf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr); 189924121865SAdrian Maldonado 190024121865SAdrian Maldonado /* Look for leaves that pertain to the subset of points. Get the local ordering */ 190124121865SAdrian Maldonado ierr = PetscMalloc1(nleaves,&ilocal_map);CHKERRQ(ierr); 190224121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nleaves,ilocal,NULL,ilocal_map);CHKERRQ(ierr); 190324121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 190424121865SAdrian Maldonado if (ilocal_map[i] != -1) nleaves_sub += 1; 190524121865SAdrian Maldonado } 190624121865SAdrian Maldonado /* Re-number ilocal with subset numbering. Need information from roots */ 190724121865SAdrian Maldonado ierr = PetscMalloc2(nroots,&local_points,nroots,&remote_points);CHKERRQ(ierr); 190824121865SAdrian Maldonado for (i = 0; i < nroots; i++) local_points[i] = i; 190924121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nroots,local_points,NULL,local_points);CHKERRQ(ierr); 1910ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(mainsf, MPIU_INT, local_points, remote_points,MPI_REPLACE);CHKERRQ(ierr); 1911ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(mainsf, MPIU_INT, local_points, remote_points,MPI_REPLACE);CHKERRQ(ierr); 191224121865SAdrian Maldonado /* Fill up graph using local (that is, local to the subset) numbering. */ 19134b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&ilocal_sub);CHKERRQ(ierr); 19144b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&iremote_sub);CHKERRQ(ierr); 191524121865SAdrian Maldonado nleaves_sub = 0; 191624121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 191724121865SAdrian Maldonado if (ilocal_map[i] != -1) { 191824121865SAdrian Maldonado ilocal_sub[nleaves_sub] = ilocal_map[i]; 19194b70a8deSAdrian Maldonado iremote_sub[nleaves_sub].rank = iremote[i].rank; 192024121865SAdrian Maldonado iremote_sub[nleaves_sub].index = remote_points[ilocal[i]]; 192124121865SAdrian Maldonado nleaves_sub += 1; 192224121865SAdrian Maldonado } 192324121865SAdrian Maldonado } 192424121865SAdrian Maldonado ierr = PetscFree2(local_points,remote_points);CHKERRQ(ierr); 192524121865SAdrian Maldonado ierr = ISLocalToGlobalMappingGetSize(map,&nroots_sub);CHKERRQ(ierr); 192624121865SAdrian Maldonado 192724121865SAdrian Maldonado /* Create new subSF */ 192824121865SAdrian Maldonado ierr = PetscSFCreate(PETSC_COMM_WORLD,subSF);CHKERRQ(ierr); 192924121865SAdrian Maldonado ierr = PetscSFSetFromOptions(*subSF);CHKERRQ(ierr); 19304b70a8deSAdrian Maldonado ierr = PetscSFSetGraph(*subSF,nroots_sub,nleaves_sub,ilocal_sub,PETSC_OWN_POINTER,iremote_sub,PETSC_COPY_VALUES);CHKERRQ(ierr); 193124121865SAdrian Maldonado ierr = PetscFree(ilocal_map);CHKERRQ(ierr); 19324b70a8deSAdrian Maldonado ierr = PetscFree(iremote_sub);CHKERRQ(ierr); 193324121865SAdrian Maldonado PetscFunctionReturn(0); 193424121865SAdrian Maldonado } 193524121865SAdrian Maldonado 19365f2c45f1SShri Abhyankar /*@C 19375f2c45f1SShri Abhyankar DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point 19385f2c45f1SShri Abhyankar 19395f2c45f1SShri Abhyankar Not Collective 19405f2c45f1SShri Abhyankar 19415f2c45f1SShri Abhyankar Input Parameters: 19422bf73ac6SHong Zhang + dm - the DMNetwork object 19435f2c45f1SShri Abhyankar - p - the vertex point 19445f2c45f1SShri Abhyankar 1945fd292e60Sprj- Output Parameters: 19465f2c45f1SShri Abhyankar + nedges - number of edges connected to this vertex point 19472bf73ac6SHong Zhang - edges - list of edge points 19485f2c45f1SShri Abhyankar 194997bb938eSShri Abhyankar Level: beginner 19505f2c45f1SShri Abhyankar 19515f2c45f1SShri Abhyankar Fortran Notes: 19525f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 19535f2c45f1SShri Abhyankar include petsc.h90 in your code. 19545f2c45f1SShri Abhyankar 19552bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkGetConnectedVertices() 19565f2c45f1SShri Abhyankar @*/ 19575f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[]) 19585f2c45f1SShri Abhyankar { 19595f2c45f1SShri Abhyankar PetscErrorCode ierr; 19605f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 19615f2c45f1SShri Abhyankar 19625f2c45f1SShri Abhyankar PetscFunctionBegin; 19635f2c45f1SShri Abhyankar ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr); 1964a9b4a83eSHong Zhang if (edges) {ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr);} 19655f2c45f1SShri Abhyankar PetscFunctionReturn(0); 19665f2c45f1SShri Abhyankar } 19675f2c45f1SShri Abhyankar 19685f2c45f1SShri Abhyankar /*@C 1969d842c372SHong Zhang DMNetworkGetConnectedVertices - Return the connected vertices for this edge point 19705f2c45f1SShri Abhyankar 19715f2c45f1SShri Abhyankar Not Collective 19725f2c45f1SShri Abhyankar 19735f2c45f1SShri Abhyankar Input Parameters: 19742bf73ac6SHong Zhang + dm - the DMNetwork object 19755f2c45f1SShri Abhyankar - p - the edge point 19765f2c45f1SShri Abhyankar 1977fd292e60Sprj- Output Parameters: 19785f2c45f1SShri Abhyankar . vertices - vertices connected to this edge 19795f2c45f1SShri Abhyankar 198097bb938eSShri Abhyankar Level: beginner 19815f2c45f1SShri Abhyankar 19825f2c45f1SShri Abhyankar Fortran Notes: 19835f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 19845f2c45f1SShri Abhyankar include petsc.h90 in your code. 19855f2c45f1SShri Abhyankar 19862bf73ac6SHong Zhang .seealso: DMNetworkCreate(), DMNetworkGetSupportingEdges() 19875f2c45f1SShri Abhyankar @*/ 1988d842c372SHong Zhang PetscErrorCode DMNetworkGetConnectedVertices(DM dm,PetscInt edge,const PetscInt *vertices[]) 19895f2c45f1SShri Abhyankar { 19905f2c45f1SShri Abhyankar PetscErrorCode ierr; 19915f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 19925f2c45f1SShri Abhyankar 19935f2c45f1SShri Abhyankar PetscFunctionBegin; 19945f2c45f1SShri Abhyankar ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr); 19955f2c45f1SShri Abhyankar PetscFunctionReturn(0); 19965f2c45f1SShri Abhyankar } 19975f2c45f1SShri Abhyankar 19985f2c45f1SShri Abhyankar /*@ 19992bf73ac6SHong Zhang DMNetworkIsSharedVertex - Returns TRUE if the vertex is shared by subnetworks 20002bf73ac6SHong Zhang 20012bf73ac6SHong Zhang Not Collective 20022bf73ac6SHong Zhang 20032bf73ac6SHong Zhang Input Parameters: 20042bf73ac6SHong Zhang + dm - the DMNetwork object 20052bf73ac6SHong Zhang - p - the vertex point 20062bf73ac6SHong Zhang 20072bf73ac6SHong Zhang Output Parameter: 20082bf73ac6SHong Zhang . flag - TRUE if the vertex is shared by subnetworks 20092bf73ac6SHong Zhang 20102bf73ac6SHong Zhang Level: beginner 20112bf73ac6SHong Zhang 20122bf73ac6SHong Zhang .seealso: DMNetworkAddSharedVertices(), DMNetworkIsGhostVertex() 20132bf73ac6SHong Zhang @*/ 20142bf73ac6SHong Zhang PetscErrorCode DMNetworkIsSharedVertex(DM dm,PetscInt p,PetscBool *flag) 20152bf73ac6SHong Zhang { 20162bf73ac6SHong Zhang PetscErrorCode ierr; 20172bf73ac6SHong Zhang PetscInt i; 20182bf73ac6SHong Zhang 20192bf73ac6SHong Zhang PetscFunctionBegin; 20202bf73ac6SHong Zhang *flag = PETSC_FALSE; 20212bf73ac6SHong Zhang 20222bf73ac6SHong Zhang if (dm->setupcalled) { /* DMNetworkGetGlobalVertexIndex() requires DMSetUp() be called */ 20232bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 20242bf73ac6SHong Zhang PetscInt gidx; 20252bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,p,&gidx);CHKERRQ(ierr); 20262bf73ac6SHong Zhang ierr = PetscTableFind(network->svtable,gidx+1,&i);CHKERRQ(ierr); 20272bf73ac6SHong Zhang if (i) *flag = PETSC_TRUE; 20282bf73ac6SHong Zhang } else { /* would be removed? */ 20292bf73ac6SHong Zhang PetscInt nv; 20302bf73ac6SHong Zhang const PetscInt *vtx; 20312bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&nv,&vtx);CHKERRQ(ierr); 20322bf73ac6SHong Zhang for (i=0; i<nv; i++) { 20332bf73ac6SHong Zhang if (p == vtx[i]) { 20342bf73ac6SHong Zhang *flag = PETSC_TRUE; 20352bf73ac6SHong Zhang break; 20362bf73ac6SHong Zhang } 20372bf73ac6SHong Zhang } 20382bf73ac6SHong Zhang } 20392bf73ac6SHong Zhang PetscFunctionReturn(0); 20402bf73ac6SHong Zhang } 20412bf73ac6SHong Zhang 20422bf73ac6SHong Zhang /*@ 20435f2c45f1SShri Abhyankar DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex 20445f2c45f1SShri Abhyankar 20455f2c45f1SShri Abhyankar Not Collective 20465f2c45f1SShri Abhyankar 20475f2c45f1SShri Abhyankar Input Parameters: 20482bf73ac6SHong Zhang + dm - the DMNetwork object 2049a2b725a8SWilliam Gropp - p - the vertex point 20505f2c45f1SShri Abhyankar 20515f2c45f1SShri Abhyankar Output Parameter: 20525f2c45f1SShri Abhyankar . isghost - TRUE if the vertex is a ghost point 20535f2c45f1SShri Abhyankar 205497bb938eSShri Abhyankar Level: beginner 20555f2c45f1SShri Abhyankar 20562bf73ac6SHong Zhang .seealso: DMNetworkGetConnectedVertices(), DMNetworkGetVertexRange(), DMNetworkIsSharedVertex() 20575f2c45f1SShri Abhyankar @*/ 20585f2c45f1SShri Abhyankar PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost) 20595f2c45f1SShri Abhyankar { 20605f2c45f1SShri Abhyankar PetscErrorCode ierr; 20615f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 20625f2c45f1SShri Abhyankar PetscInt offsetg; 20635f2c45f1SShri Abhyankar PetscSection sectiong; 20645f2c45f1SShri Abhyankar 20655f2c45f1SShri Abhyankar PetscFunctionBegin; 20665f2c45f1SShri Abhyankar *isghost = PETSC_FALSE; 2067e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§iong);CHKERRQ(ierr); 20685f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr); 20695f2c45f1SShri Abhyankar if (offsetg < 0) *isghost = PETSC_TRUE; 20705f2c45f1SShri Abhyankar PetscFunctionReturn(0); 20715f2c45f1SShri Abhyankar } 20725f2c45f1SShri Abhyankar 20735f2c45f1SShri Abhyankar PetscErrorCode DMSetUp_Network(DM dm) 20745f2c45f1SShri Abhyankar { 20755f2c45f1SShri Abhyankar PetscErrorCode ierr; 20765f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 20775f2c45f1SShri Abhyankar 20785f2c45f1SShri Abhyankar PetscFunctionBegin; 20795f2c45f1SShri Abhyankar ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr); 20805f2c45f1SShri Abhyankar ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr); 20815f2c45f1SShri Abhyankar 208292fd8e1eSJed Brown ierr = DMSetLocalSection(network->plex,network->DofSection);CHKERRQ(ierr); 2083e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr); 20849e1d080bSHong Zhang 20859e1d080bSHong Zhang dm->setupcalled = PETSC_TRUE; 20865b3f975aSHong Zhang 20875b3f975aSHong Zhang /* View dmnetwork */ 20885b3f975aSHong Zhang ierr = DMViewFromOptions(dm,NULL,"-dmnetwork_view");CHKERRQ(ierr); 20895f2c45f1SShri Abhyankar PetscFunctionReturn(0); 20905f2c45f1SShri Abhyankar } 20915f2c45f1SShri Abhyankar 20921ad426b7SHong Zhang /*@ 209317df6e9eSHong Zhang DMNetworkHasJacobian - Sets global flag for using user's sub Jacobian matrices 20941ad426b7SHong Zhang -- replaced by DMNetworkSetOption(network,userjacobian,PETSC_TURE)? 20951ad426b7SHong Zhang 20961ad426b7SHong Zhang Collective 20971ad426b7SHong Zhang 20981ad426b7SHong Zhang Input Parameters: 20992bf73ac6SHong Zhang + dm - the DMNetwork object 210083b2e829SHong Zhang . eflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for edges 210183b2e829SHong Zhang - vflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for vertices 21021ad426b7SHong Zhang 21031ad426b7SHong Zhang Level: intermediate 21041ad426b7SHong Zhang 21051ad426b7SHong Zhang @*/ 210683b2e829SHong Zhang PetscErrorCode DMNetworkHasJacobian(DM dm,PetscBool eflg,PetscBool vflg) 21071ad426b7SHong Zhang { 21081ad426b7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 21098675203cSHong Zhang PetscErrorCode ierr; 211066b4e0ffSHong Zhang PetscInt nVertices = network->nVertices; 21111ad426b7SHong Zhang 21121ad426b7SHong Zhang PetscFunctionBegin; 211383b2e829SHong Zhang network->userEdgeJacobian = eflg; 211483b2e829SHong Zhang network->userVertexJacobian = vflg; 21158675203cSHong Zhang 21168675203cSHong Zhang if (eflg && !network->Je) { 21178675203cSHong Zhang ierr = PetscCalloc1(3*network->nEdges,&network->Je);CHKERRQ(ierr); 21188675203cSHong Zhang } 21198675203cSHong Zhang 212066b4e0ffSHong Zhang if (vflg && !network->Jv && nVertices) { 21218675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 212266b4e0ffSHong Zhang PetscInt nedges_total; 21238675203cSHong Zhang const PetscInt *edges; 21248675203cSHong Zhang 21258675203cSHong Zhang /* count nvertex_total */ 21268675203cSHong Zhang nedges_total = 0; 21278675203cSHong Zhang ierr = PetscMalloc1(nVertices+1,&vptr);CHKERRQ(ierr); 21288675203cSHong Zhang 21298675203cSHong Zhang vptr[0] = 0; 21308675203cSHong Zhang for (i=0; i<nVertices; i++) { 21318675203cSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,i+vStart,&nedges,&edges);CHKERRQ(ierr); 21328675203cSHong Zhang nedges_total += nedges; 21338675203cSHong Zhang vptr[i+1] = vptr[i] + 2*nedges + 1; 21348675203cSHong Zhang } 21358675203cSHong Zhang 21368675203cSHong Zhang ierr = PetscCalloc1(2*nedges_total+nVertices,&network->Jv);CHKERRQ(ierr); 21378675203cSHong Zhang network->Jvptr = vptr; 21388675203cSHong Zhang } 21391ad426b7SHong Zhang PetscFunctionReturn(0); 21401ad426b7SHong Zhang } 21411ad426b7SHong Zhang 21421ad426b7SHong Zhang /*@ 214383b2e829SHong Zhang DMNetworkEdgeSetMatrix - Sets user-provided Jacobian matrices for this edge to the network 214483b2e829SHong Zhang 214583b2e829SHong Zhang Not Collective 214683b2e829SHong Zhang 214783b2e829SHong Zhang Input Parameters: 21482bf73ac6SHong Zhang + dm - the DMNetwork object 214983b2e829SHong Zhang . p - the edge point 21503e97b6e8SHong Zhang - J - array (size = 3) of Jacobian submatrices for this edge point: 21513e97b6e8SHong Zhang J[0]: this edge 2152d842c372SHong Zhang J[1] and J[2]: connected vertices, obtained by calling DMNetworkGetConnectedVertices() 215383b2e829SHong Zhang 215497bb938eSShri Abhyankar Level: advanced 215583b2e829SHong Zhang 21562bf73ac6SHong Zhang .seealso: DMNetworkVertexSetMatrix() 215783b2e829SHong Zhang @*/ 215883b2e829SHong Zhang PetscErrorCode DMNetworkEdgeSetMatrix(DM dm,PetscInt p,Mat J[]) 215983b2e829SHong Zhang { 216083b2e829SHong Zhang DM_Network *network=(DM_Network*)dm->data; 216183b2e829SHong Zhang 216283b2e829SHong Zhang PetscFunctionBegin; 21638675203cSHong Zhang if (!network->Je) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkEdgeSetMatrix"); 21648675203cSHong Zhang 21658675203cSHong Zhang if (J) { 2166883e35e8SHong Zhang network->Je[3*p] = J[0]; 2167883e35e8SHong Zhang network->Je[3*p+1] = J[1]; 2168883e35e8SHong Zhang network->Je[3*p+2] = J[2]; 21698675203cSHong Zhang } 217083b2e829SHong Zhang PetscFunctionReturn(0); 217183b2e829SHong Zhang } 217283b2e829SHong Zhang 217383b2e829SHong Zhang /*@ 217476ddfea5SHong Zhang DMNetworkVertexSetMatrix - Sets user-provided Jacobian matrix for this vertex to the network 21751ad426b7SHong Zhang 21761ad426b7SHong Zhang Not Collective 21771ad426b7SHong Zhang 21781ad426b7SHong Zhang Input Parameters: 21791ad426b7SHong Zhang + dm - The DMNetwork object 21801ad426b7SHong Zhang . p - the vertex point 21813e97b6e8SHong Zhang - J - array of Jacobian (size = 2*(num of supporting edges) + 1) submatrices for this vertex point: 21823e97b6e8SHong Zhang J[0]: this vertex 21833e97b6e8SHong Zhang J[1+2*i]: i-th supporting edge 21843e97b6e8SHong Zhang J[1+2*i+1]: i-th connected vertex 21851ad426b7SHong Zhang 218697bb938eSShri Abhyankar Level: advanced 21871ad426b7SHong Zhang 21882bf73ac6SHong Zhang .seealso: DMNetworkEdgeSetMatrix() 21891ad426b7SHong Zhang @*/ 2190883e35e8SHong Zhang PetscErrorCode DMNetworkVertexSetMatrix(DM dm,PetscInt p,Mat J[]) 21915f2c45f1SShri Abhyankar { 21925f2c45f1SShri Abhyankar PetscErrorCode ierr; 21935f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 21948675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 2195883e35e8SHong Zhang const PetscInt *edges; 21965f2c45f1SShri Abhyankar 21975f2c45f1SShri Abhyankar PetscFunctionBegin; 21988675203cSHong Zhang if (!network->Jv) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkVertexSetMatrix"); 2199883e35e8SHong Zhang 22008675203cSHong Zhang if (J) { 2201883e35e8SHong Zhang vptr = network->Jvptr; 22023e97b6e8SHong Zhang network->Jv[vptr[p-vStart]] = J[0]; /* Set Jacobian for this vertex */ 22033e97b6e8SHong Zhang 22043e97b6e8SHong Zhang /* Set Jacobian for each supporting edge and connected vertex */ 2205883e35e8SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,p,&nedges,&edges);CHKERRQ(ierr); 2206883e35e8SHong Zhang for (i=1; i<=2*nedges; i++) network->Jv[vptr[p-vStart]+i] = J[i]; 22078675203cSHong Zhang } 2208883e35e8SHong Zhang PetscFunctionReturn(0); 2209883e35e8SHong Zhang } 2210883e35e8SHong Zhang 2211e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 22125cf7da58SHong Zhang { 22135cf7da58SHong Zhang PetscErrorCode ierr; 22145cf7da58SHong Zhang PetscInt j; 22155cf7da58SHong Zhang PetscScalar val=(PetscScalar)ncols; 22165cf7da58SHong Zhang 22175cf7da58SHong Zhang PetscFunctionBegin; 22185cf7da58SHong Zhang if (!ghost) { 22195cf7da58SHong Zhang for (j=0; j<nrows; j++) { 22205cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 22215cf7da58SHong Zhang } 22225cf7da58SHong Zhang } else { 22235cf7da58SHong Zhang for (j=0; j<nrows; j++) { 22245cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 22255cf7da58SHong Zhang } 22265cf7da58SHong Zhang } 22275cf7da58SHong Zhang PetscFunctionReturn(0); 22285cf7da58SHong Zhang } 22295cf7da58SHong Zhang 2230e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 22315cf7da58SHong Zhang { 22325cf7da58SHong Zhang PetscErrorCode ierr; 22335cf7da58SHong Zhang PetscInt j,ncols_u; 22345cf7da58SHong Zhang PetscScalar val; 22355cf7da58SHong Zhang 22365cf7da58SHong Zhang PetscFunctionBegin; 22375cf7da58SHong Zhang if (!ghost) { 22385cf7da58SHong Zhang for (j=0; j<nrows; j++) { 22395cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 22405cf7da58SHong Zhang val = (PetscScalar)ncols_u; 22415cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 22425cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 22435cf7da58SHong Zhang } 22445cf7da58SHong Zhang } else { 22455cf7da58SHong Zhang for (j=0; j<nrows; j++) { 22465cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 22475cf7da58SHong Zhang val = (PetscScalar)ncols_u; 22485cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 22495cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 22505cf7da58SHong Zhang } 22515cf7da58SHong Zhang } 22525cf7da58SHong Zhang PetscFunctionReturn(0); 22535cf7da58SHong Zhang } 22545cf7da58SHong Zhang 2255e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 22565cf7da58SHong Zhang { 22575cf7da58SHong Zhang PetscErrorCode ierr; 22585cf7da58SHong Zhang 22595cf7da58SHong Zhang PetscFunctionBegin; 22605cf7da58SHong Zhang if (Ju) { 22615cf7da58SHong Zhang ierr = MatSetPreallocationUserblock_private(Ju,nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 22625cf7da58SHong Zhang } else { 22635cf7da58SHong Zhang ierr = MatSetPreallocationDenseblock_private(nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 22645cf7da58SHong Zhang } 22655cf7da58SHong Zhang PetscFunctionReturn(0); 22665cf7da58SHong Zhang } 22675cf7da58SHong Zhang 2268e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 2269883e35e8SHong Zhang { 2270883e35e8SHong Zhang PetscErrorCode ierr; 2271883e35e8SHong Zhang PetscInt j,*cols; 2272883e35e8SHong Zhang PetscScalar *zeros; 2273883e35e8SHong Zhang 2274883e35e8SHong Zhang PetscFunctionBegin; 2275883e35e8SHong Zhang ierr = PetscCalloc2(ncols,&cols,nrows*ncols,&zeros);CHKERRQ(ierr); 2276883e35e8SHong Zhang for (j=0; j<ncols; j++) cols[j] = j+ cstart; 2277883e35e8SHong Zhang ierr = MatSetValues(*J,nrows,rows,ncols,cols,zeros,INSERT_VALUES);CHKERRQ(ierr); 2278883e35e8SHong Zhang ierr = PetscFree2(cols,zeros);CHKERRQ(ierr); 22791ad426b7SHong Zhang PetscFunctionReturn(0); 22801ad426b7SHong Zhang } 2281a4e85ca8SHong Zhang 2282e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 22833e97b6e8SHong Zhang { 22843e97b6e8SHong Zhang PetscErrorCode ierr; 22853e97b6e8SHong Zhang PetscInt j,M,N,row,col,ncols_u; 22863e97b6e8SHong Zhang const PetscInt *cols; 22873e97b6e8SHong Zhang PetscScalar zero=0.0; 22883e97b6e8SHong Zhang 22893e97b6e8SHong Zhang PetscFunctionBegin; 22903e97b6e8SHong Zhang ierr = MatGetSize(Ju,&M,&N);CHKERRQ(ierr); 22913e97b6e8SHong 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); 22923e97b6e8SHong Zhang 22933e97b6e8SHong Zhang for (row=0; row<nrows; row++) { 22943e97b6e8SHong Zhang ierr = MatGetRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 22953e97b6e8SHong Zhang for (j=0; j<ncols_u; j++) { 22963e97b6e8SHong Zhang col = cols[j] + cstart; 22973e97b6e8SHong Zhang ierr = MatSetValues(*J,1,&rows[row],1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr); 22983e97b6e8SHong Zhang } 22993e97b6e8SHong Zhang ierr = MatRestoreRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 23003e97b6e8SHong Zhang } 23013e97b6e8SHong Zhang PetscFunctionReturn(0); 23023e97b6e8SHong Zhang } 23031ad426b7SHong Zhang 2304e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 2305a4e85ca8SHong Zhang { 2306a4e85ca8SHong Zhang PetscErrorCode ierr; 2307f4431b8cSHong Zhang 2308a4e85ca8SHong Zhang PetscFunctionBegin; 2309a4e85ca8SHong Zhang if (Ju) { 2310a4e85ca8SHong Zhang ierr = MatSetUserblock_private(Ju,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 2311a4e85ca8SHong Zhang } else { 2312a4e85ca8SHong Zhang ierr = MatSetDenseblock_private(nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 2313a4e85ca8SHong Zhang } 2314a4e85ca8SHong Zhang PetscFunctionReturn(0); 2315a4e85ca8SHong Zhang } 2316a4e85ca8SHong Zhang 231724121865SAdrian 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. 231824121865SAdrian Maldonado */ 231924121865SAdrian Maldonado PetscErrorCode CreateSubGlobalToLocalMapping_private(PetscSection globalsec, PetscSection localsec, ISLocalToGlobalMapping *ltog) 232024121865SAdrian Maldonado { 232124121865SAdrian Maldonado PetscErrorCode ierr; 232224121865SAdrian Maldonado PetscInt i,size,dof; 232324121865SAdrian Maldonado PetscInt *glob2loc; 232424121865SAdrian Maldonado 232524121865SAdrian Maldonado PetscFunctionBegin; 232624121865SAdrian Maldonado ierr = PetscSectionGetStorageSize(localsec,&size);CHKERRQ(ierr); 232724121865SAdrian Maldonado ierr = PetscMalloc1(size,&glob2loc);CHKERRQ(ierr); 232824121865SAdrian Maldonado 232924121865SAdrian Maldonado for (i = 0; i < size; i++) { 233024121865SAdrian Maldonado ierr = PetscSectionGetOffset(globalsec,i,&dof);CHKERRQ(ierr); 233124121865SAdrian Maldonado dof = (dof >= 0) ? dof : -(dof + 1); 233224121865SAdrian Maldonado glob2loc[i] = dof; 233324121865SAdrian Maldonado } 233424121865SAdrian Maldonado 233524121865SAdrian Maldonado ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,size,glob2loc,PETSC_OWN_POINTER,ltog);CHKERRQ(ierr); 233624121865SAdrian Maldonado #if 0 233724121865SAdrian Maldonado ierr = PetscIntView(size,glob2loc,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 233824121865SAdrian Maldonado #endif 233924121865SAdrian Maldonado PetscFunctionReturn(0); 234024121865SAdrian Maldonado } 234124121865SAdrian Maldonado 234201ad2aeeSHong Zhang #include <petsc/private/matimpl.h> 23439e1d080bSHong Zhang 23449e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network_Nest(DM dm,Mat *J) 23451ad426b7SHong Zhang { 23461ad426b7SHong Zhang PetscErrorCode ierr; 23471ad426b7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 234824121865SAdrian Maldonado PetscInt eDof,vDof; 234924121865SAdrian Maldonado Mat j11,j12,j21,j22,bA[2][2]; 23509e1d080bSHong Zhang MPI_Comm comm; 235124121865SAdrian Maldonado ISLocalToGlobalMapping eISMap,vISMap; 235224121865SAdrian Maldonado 23539e1d080bSHong Zhang PetscFunctionBegin; 235424121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 235524121865SAdrian Maldonado 235624121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->edge.GlobalDofSection,&eDof);CHKERRQ(ierr); 235724121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->vertex.GlobalDofSection,&vDof);CHKERRQ(ierr); 235824121865SAdrian Maldonado 235901ad2aeeSHong Zhang ierr = MatCreate(comm, &j11);CHKERRQ(ierr); 236024121865SAdrian Maldonado ierr = MatSetSizes(j11, eDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 236124121865SAdrian Maldonado ierr = MatSetType(j11, MATMPIAIJ);CHKERRQ(ierr); 236224121865SAdrian Maldonado 236301ad2aeeSHong Zhang ierr = MatCreate(comm, &j12);CHKERRQ(ierr); 236424121865SAdrian Maldonado ierr = MatSetSizes(j12, eDof, vDof, PETSC_DETERMINE ,PETSC_DETERMINE);CHKERRQ(ierr); 236524121865SAdrian Maldonado ierr = MatSetType(j12, MATMPIAIJ);CHKERRQ(ierr); 236624121865SAdrian Maldonado 236701ad2aeeSHong Zhang ierr = MatCreate(comm, &j21);CHKERRQ(ierr); 236824121865SAdrian Maldonado ierr = MatSetSizes(j21, vDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 236924121865SAdrian Maldonado ierr = MatSetType(j21, MATMPIAIJ);CHKERRQ(ierr); 237024121865SAdrian Maldonado 237101ad2aeeSHong Zhang ierr = MatCreate(comm, &j22);CHKERRQ(ierr); 237224121865SAdrian Maldonado ierr = MatSetSizes(j22, vDof, vDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 237324121865SAdrian Maldonado ierr = MatSetType(j22, MATMPIAIJ);CHKERRQ(ierr); 237424121865SAdrian Maldonado 23753f6a6bdaSHong Zhang bA[0][0] = j11; 23763f6a6bdaSHong Zhang bA[0][1] = j12; 23773f6a6bdaSHong Zhang bA[1][0] = j21; 23783f6a6bdaSHong Zhang bA[1][1] = j22; 237924121865SAdrian Maldonado 238024121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->edge.GlobalDofSection,network->edge.DofSection,&eISMap);CHKERRQ(ierr); 238124121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->vertex.GlobalDofSection,network->vertex.DofSection,&vISMap);CHKERRQ(ierr); 238224121865SAdrian Maldonado 238324121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j11,eISMap,eISMap);CHKERRQ(ierr); 238424121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j12,eISMap,vISMap);CHKERRQ(ierr); 238524121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j21,vISMap,eISMap);CHKERRQ(ierr); 238624121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j22,vISMap,vISMap);CHKERRQ(ierr); 238724121865SAdrian Maldonado 238824121865SAdrian Maldonado ierr = MatSetUp(j11);CHKERRQ(ierr); 238924121865SAdrian Maldonado ierr = MatSetUp(j12);CHKERRQ(ierr); 239024121865SAdrian Maldonado ierr = MatSetUp(j21);CHKERRQ(ierr); 239124121865SAdrian Maldonado ierr = MatSetUp(j22);CHKERRQ(ierr); 239224121865SAdrian Maldonado 239301ad2aeeSHong Zhang ierr = MatCreateNest(comm,2,NULL,2,NULL,&bA[0][0],J);CHKERRQ(ierr); 239424121865SAdrian Maldonado ierr = MatSetUp(*J);CHKERRQ(ierr); 239524121865SAdrian Maldonado ierr = MatNestSetVecType(*J,VECNEST);CHKERRQ(ierr); 239624121865SAdrian Maldonado ierr = MatDestroy(&j11);CHKERRQ(ierr); 239724121865SAdrian Maldonado ierr = MatDestroy(&j12);CHKERRQ(ierr); 239824121865SAdrian Maldonado ierr = MatDestroy(&j21);CHKERRQ(ierr); 239924121865SAdrian Maldonado ierr = MatDestroy(&j22);CHKERRQ(ierr); 240024121865SAdrian Maldonado 240124121865SAdrian Maldonado ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 240224121865SAdrian Maldonado ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24039e1d080bSHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 240424121865SAdrian Maldonado 240524121865SAdrian Maldonado /* Free structures */ 240624121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&eISMap);CHKERRQ(ierr); 240724121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&vISMap);CHKERRQ(ierr); 240824121865SAdrian Maldonado PetscFunctionReturn(0); 24099e1d080bSHong Zhang } 24109e1d080bSHong Zhang 24119e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J) 24129e1d080bSHong Zhang { 24139e1d080bSHong Zhang PetscErrorCode ierr; 24149e1d080bSHong Zhang DM_Network *network = (DM_Network*)dm->data; 24159e1d080bSHong Zhang PetscInt eStart,eEnd,vStart,vEnd,rstart,nrows,*rows,localSize; 24169e1d080bSHong Zhang PetscInt cstart,ncols,j,e,v; 24179e1d080bSHong Zhang PetscBool ghost,ghost_vc,ghost2,isNest; 24189e1d080bSHong Zhang Mat Juser; 24199e1d080bSHong Zhang PetscSection sectionGlobal; 24209e1d080bSHong Zhang PetscInt nedges,*vptr=NULL,vc,*rows_v; /* suppress maybe-uninitialized warning */ 24219e1d080bSHong Zhang const PetscInt *edges,*cone; 24229e1d080bSHong Zhang MPI_Comm comm; 24239e1d080bSHong Zhang MatType mtype; 24249e1d080bSHong Zhang Vec vd_nz,vo_nz; 24259e1d080bSHong Zhang PetscInt *dnnz,*onnz; 24269e1d080bSHong Zhang PetscScalar *vdnz,*vonz; 24279e1d080bSHong Zhang 24289e1d080bSHong Zhang PetscFunctionBegin; 24299e1d080bSHong Zhang mtype = dm->mattype; 24309e1d080bSHong Zhang ierr = PetscStrcmp(mtype,MATNEST,&isNest);CHKERRQ(ierr); 24319e1d080bSHong Zhang if (isNest) { 24329e1d080bSHong Zhang ierr = DMCreateMatrix_Network_Nest(dm,J);CHKERRQ(ierr); 2433c6b011d8SStefano Zampini ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 24349e1d080bSHong Zhang PetscFunctionReturn(0); 24359e1d080bSHong Zhang } 24369e1d080bSHong Zhang 24379e1d080bSHong Zhang if (!network->userEdgeJacobian && !network->userVertexJacobian) { 2438a4e85ca8SHong Zhang /* user does not provide Jacobian blocks */ 24399e1d080bSHong Zhang ierr = DMCreateMatrix_Plex(network->plex,J);CHKERRQ(ierr); 2440bfbc38dcSHong Zhang ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 24411ad426b7SHong Zhang PetscFunctionReturn(0); 24421ad426b7SHong Zhang } 24431ad426b7SHong Zhang 2444bfbc38dcSHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)dm),J);CHKERRQ(ierr); 2445e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§ionGlobal);CHKERRQ(ierr); 2446bfbc38dcSHong Zhang ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal,&localSize);CHKERRQ(ierr); 2447bfbc38dcSHong Zhang ierr = MatSetSizes(*J,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 24482a945128SHong Zhang 24492a945128SHong Zhang ierr = MatSetType(*J,MATAIJ);CHKERRQ(ierr); 24502a945128SHong Zhang ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 245189898e50SHong Zhang 245289898e50SHong Zhang /* (1) Set matrix preallocation */ 245389898e50SHong Zhang /*------------------------------*/ 2454840c2264SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 2455840c2264SHong Zhang ierr = VecCreate(comm,&vd_nz);CHKERRQ(ierr); 2456840c2264SHong Zhang ierr = VecSetSizes(vd_nz,localSize,PETSC_DECIDE);CHKERRQ(ierr); 2457840c2264SHong Zhang ierr = VecSetFromOptions(vd_nz);CHKERRQ(ierr); 2458840c2264SHong Zhang ierr = VecSet(vd_nz,0.0);CHKERRQ(ierr); 2459840c2264SHong Zhang ierr = VecDuplicate(vd_nz,&vo_nz);CHKERRQ(ierr); 2460840c2264SHong Zhang 246189898e50SHong Zhang /* Set preallocation for edges */ 246289898e50SHong Zhang /*-----------------------------*/ 2463840c2264SHong Zhang ierr = DMNetworkGetEdgeRange(dm,&eStart,&eEnd);CHKERRQ(ierr); 2464840c2264SHong Zhang 2465bdcb62a2SHong Zhang ierr = PetscMalloc1(localSize,&rows);CHKERRQ(ierr); 2466840c2264SHong Zhang for (e=eStart; e<eEnd; e++) { 2467840c2264SHong Zhang /* Get row indices */ 24682bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,e,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 24692bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,e,&nrows);CHKERRQ(ierr); 2470840c2264SHong Zhang if (nrows) { 2471840c2264SHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 2472840c2264SHong Zhang 2473a5b23f4aSJose E. Roman /* Set preallocation for connected vertices */ 2474d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 2475840c2264SHong Zhang for (v=0; v<2; v++) { 24762bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,cone[v],&ncols);CHKERRQ(ierr); 2477840c2264SHong Zhang 24788675203cSHong Zhang if (network->Je) { 2479840c2264SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 24808675203cSHong Zhang } else Juser = NULL; 2481840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,cone[v],&ghost);CHKERRQ(ierr); 24825cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 2483840c2264SHong Zhang } 2484840c2264SHong Zhang 248589898e50SHong Zhang /* Set preallocation for edge self */ 2486840c2264SHong Zhang cstart = rstart; 24878675203cSHong Zhang if (network->Je) { 2488840c2264SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 24898675203cSHong Zhang } else Juser = NULL; 24905cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 2491840c2264SHong Zhang } 2492840c2264SHong Zhang } 2493840c2264SHong Zhang 249489898e50SHong Zhang /* Set preallocation for vertices */ 249589898e50SHong Zhang /*--------------------------------*/ 2496840c2264SHong Zhang ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 24978675203cSHong Zhang if (vEnd - vStart) vptr = network->Jvptr; 2498840c2264SHong Zhang 2499840c2264SHong Zhang for (v=vStart; v<vEnd; v++) { 2500840c2264SHong Zhang /* Get row indices */ 25012bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 25022bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,v,&nrows);CHKERRQ(ierr); 2503840c2264SHong Zhang if (!nrows) continue; 2504840c2264SHong Zhang 2505bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 2506bdcb62a2SHong Zhang if (ghost) { 2507bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 2508bdcb62a2SHong Zhang } else { 2509bdcb62a2SHong Zhang rows_v = rows; 2510bdcb62a2SHong Zhang } 2511bdcb62a2SHong Zhang 2512bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 2513840c2264SHong Zhang 2514840c2264SHong Zhang /* Get supporting edges and connected vertices */ 2515840c2264SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 2516840c2264SHong Zhang 2517840c2264SHong Zhang for (e=0; e<nedges; e++) { 2518840c2264SHong Zhang /* Supporting edges */ 25192bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,edges[e],ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 25202bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,edges[e],&ncols);CHKERRQ(ierr); 2521840c2264SHong Zhang 25228675203cSHong Zhang if (network->Jv) { 2523840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 25248675203cSHong Zhang } else Juser = NULL; 2525bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 2526840c2264SHong Zhang 2527840c2264SHong Zhang /* Connected vertices */ 2528d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 2529840c2264SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 2530840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,vc,&ghost_vc);CHKERRQ(ierr); 2531840c2264SHong Zhang 25322bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,vc,&ncols);CHKERRQ(ierr); 2533840c2264SHong Zhang 25348675203cSHong Zhang if (network->Jv) { 2535840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 25368675203cSHong Zhang } else Juser = NULL; 2537e102a522SHong Zhang if (ghost_vc||ghost) { 2538e102a522SHong Zhang ghost2 = PETSC_TRUE; 2539e102a522SHong Zhang } else { 2540e102a522SHong Zhang ghost2 = PETSC_FALSE; 2541e102a522SHong Zhang } 2542e102a522SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost2,vd_nz,vo_nz);CHKERRQ(ierr); 2543840c2264SHong Zhang } 2544840c2264SHong Zhang 254589898e50SHong Zhang /* Set preallocation for vertex self */ 2546840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 2547840c2264SHong Zhang if (!ghost) { 25482bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 25498675203cSHong Zhang if (network->Jv) { 2550840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 25518675203cSHong Zhang } else Juser = NULL; 2552bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 2553840c2264SHong Zhang } 2554bdcb62a2SHong Zhang if (ghost) { 2555bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 2556bdcb62a2SHong Zhang } 2557840c2264SHong Zhang } 2558840c2264SHong Zhang 2559840c2264SHong Zhang ierr = VecAssemblyBegin(vd_nz);CHKERRQ(ierr); 2560840c2264SHong Zhang ierr = VecAssemblyBegin(vo_nz);CHKERRQ(ierr); 25615cf7da58SHong Zhang 25625cf7da58SHong Zhang ierr = PetscMalloc2(localSize,&dnnz,localSize,&onnz);CHKERRQ(ierr); 25635cf7da58SHong Zhang 25645cf7da58SHong Zhang ierr = VecAssemblyEnd(vd_nz);CHKERRQ(ierr); 2565840c2264SHong Zhang ierr = VecAssemblyEnd(vo_nz);CHKERRQ(ierr); 2566840c2264SHong Zhang 2567840c2264SHong Zhang ierr = VecGetArray(vd_nz,&vdnz);CHKERRQ(ierr); 2568840c2264SHong Zhang ierr = VecGetArray(vo_nz,&vonz);CHKERRQ(ierr); 2569840c2264SHong Zhang for (j=0; j<localSize; j++) { 2570e102a522SHong Zhang dnnz[j] = (PetscInt)PetscRealPart(vdnz[j]); 2571e102a522SHong Zhang onnz[j] = (PetscInt)PetscRealPart(vonz[j]); 2572840c2264SHong Zhang } 2573840c2264SHong Zhang ierr = VecRestoreArray(vd_nz,&vdnz);CHKERRQ(ierr); 2574840c2264SHong Zhang ierr = VecRestoreArray(vo_nz,&vonz);CHKERRQ(ierr); 2575840c2264SHong Zhang ierr = VecDestroy(&vd_nz);CHKERRQ(ierr); 2576840c2264SHong Zhang ierr = VecDestroy(&vo_nz);CHKERRQ(ierr); 2577840c2264SHong Zhang 25785cf7da58SHong Zhang ierr = MatSeqAIJSetPreallocation(*J,0,dnnz);CHKERRQ(ierr); 25795cf7da58SHong Zhang ierr = MatMPIAIJSetPreallocation(*J,0,dnnz,0,onnz);CHKERRQ(ierr); 25805cf7da58SHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 25815cf7da58SHong Zhang 25825cf7da58SHong Zhang ierr = PetscFree2(dnnz,onnz);CHKERRQ(ierr); 25835cf7da58SHong Zhang 258489898e50SHong Zhang /* (2) Set matrix entries for edges */ 258589898e50SHong Zhang /*----------------------------------*/ 25861ad426b7SHong Zhang for (e=eStart; e<eEnd; e++) { 2587bfbc38dcSHong Zhang /* Get row indices */ 25882bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,e,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 25892bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,e,&nrows);CHKERRQ(ierr); 25904b976069SHong Zhang if (nrows) { 259117df6e9eSHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 25921ad426b7SHong Zhang 2593a5b23f4aSJose E. Roman /* Set matrix entries for connected vertices */ 2594d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 2595bfbc38dcSHong Zhang for (v=0; v<2; v++) { 25962bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,cone[v],ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 25972bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,cone[v],&ncols);CHKERRQ(ierr); 25983e97b6e8SHong Zhang 25998675203cSHong Zhang if (network->Je) { 2600a4e85ca8SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 26018675203cSHong Zhang } else Juser = NULL; 2602a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 2603bfbc38dcSHong Zhang } 260417df6e9eSHong Zhang 2605bfbc38dcSHong Zhang /* Set matrix entries for edge self */ 26063e97b6e8SHong Zhang cstart = rstart; 26078675203cSHong Zhang if (network->Je) { 2608a4e85ca8SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 26098675203cSHong Zhang } else Juser = NULL; 2610a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,nrows,cstart,J);CHKERRQ(ierr); 26111ad426b7SHong Zhang } 26124b976069SHong Zhang } 26131ad426b7SHong Zhang 2614bfbc38dcSHong Zhang /* Set matrix entries for vertices */ 261583b2e829SHong Zhang /*---------------------------------*/ 26161ad426b7SHong Zhang for (v=vStart; v<vEnd; v++) { 2617bfbc38dcSHong Zhang /* Get row indices */ 26182bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&rstart);CHKERRQ(ierr); 26192bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,v,&nrows);CHKERRQ(ierr); 26204b976069SHong Zhang if (!nrows) continue; 2621596e729fSHong Zhang 2622bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 2623bdcb62a2SHong Zhang if (ghost) { 2624bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 2625bdcb62a2SHong Zhang } else { 2626bdcb62a2SHong Zhang rows_v = rows; 2627bdcb62a2SHong Zhang } 2628bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 2629596e729fSHong Zhang 2630bfbc38dcSHong Zhang /* Get supporting edges and connected vertices */ 2631596e729fSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 2632596e729fSHong Zhang 2633596e729fSHong Zhang for (e=0; e<nedges; e++) { 2634bfbc38dcSHong Zhang /* Supporting edges */ 26352bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,edges[e],ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 26362bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,edges[e],&ncols);CHKERRQ(ierr); 2637596e729fSHong Zhang 26388675203cSHong Zhang if (network->Jv) { 2639a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 26408675203cSHong Zhang } else Juser = NULL; 2641bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 2642596e729fSHong Zhang 2643bfbc38dcSHong Zhang /* Connected vertices */ 2644d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 26452a945128SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 26462a945128SHong Zhang 26472bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,vc,ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 26482bf73ac6SHong Zhang ierr = PetscSectionGetDof(network->DofSection,vc,&ncols);CHKERRQ(ierr); 2649a4e85ca8SHong Zhang 26508675203cSHong Zhang if (network->Jv) { 2651a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 26528675203cSHong Zhang } else Juser = NULL; 2653bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 2654596e729fSHong Zhang } 2655596e729fSHong Zhang 2656bfbc38dcSHong Zhang /* Set matrix entries for vertex self */ 26571ad426b7SHong Zhang if (!ghost) { 26582bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,v,ALL_COMPONENTS,&cstart);CHKERRQ(ierr); 26598675203cSHong Zhang if (network->Jv) { 2660a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 26618675203cSHong Zhang } else Juser = NULL; 2662bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,nrows,cstart,J);CHKERRQ(ierr); 2663bdcb62a2SHong Zhang } 2664bdcb62a2SHong Zhang if (ghost) { 2665bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 2666bdcb62a2SHong Zhang } 26671ad426b7SHong Zhang } 2668a4e85ca8SHong Zhang ierr = PetscFree(rows);CHKERRQ(ierr); 2669bdcb62a2SHong Zhang 26701ad426b7SHong Zhang ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 26711ad426b7SHong Zhang ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2672dd6f46cdSHong Zhang 26735f2c45f1SShri Abhyankar ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 26745f2c45f1SShri Abhyankar PetscFunctionReturn(0); 26755f2c45f1SShri Abhyankar } 26765f2c45f1SShri Abhyankar 26775f2c45f1SShri Abhyankar PetscErrorCode DMDestroy_Network(DM dm) 26785f2c45f1SShri Abhyankar { 26795f2c45f1SShri Abhyankar PetscErrorCode ierr; 26805f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 268154dfd506SHong Zhang PetscInt j,np; 26825f2c45f1SShri Abhyankar 26835f2c45f1SShri Abhyankar PetscFunctionBegin; 26848415c774SShri Abhyankar if (--network->refct > 0) PetscFunctionReturn(0); 268583b2e829SHong Zhang if (network->Je) { 268683b2e829SHong Zhang ierr = PetscFree(network->Je);CHKERRQ(ierr); 268783b2e829SHong Zhang } 268883b2e829SHong Zhang if (network->Jv) { 2689883e35e8SHong Zhang ierr = PetscFree(network->Jvptr);CHKERRQ(ierr); 269083b2e829SHong Zhang ierr = PetscFree(network->Jv);CHKERRQ(ierr); 26911ad426b7SHong Zhang } 269213c2a604SAdrian Maldonado 269313c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->vertex.mapping);CHKERRQ(ierr); 269413c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.DofSection);CHKERRQ(ierr); 269513c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.GlobalDofSection);CHKERRQ(ierr); 2696f5427c60SHong Zhang if (network->vltog) { 2697f5427c60SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 2698f5427c60SHong Zhang } 269913c2a604SAdrian Maldonado if (network->vertex.sf) { 270013c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->vertex.sf);CHKERRQ(ierr); 270113c2a604SAdrian Maldonado } 270213c2a604SAdrian Maldonado /* edge */ 270313c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->edge.mapping);CHKERRQ(ierr); 270413c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.DofSection);CHKERRQ(ierr); 270513c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.GlobalDofSection);CHKERRQ(ierr); 270613c2a604SAdrian Maldonado if (network->edge.sf) { 270713c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->edge.sf);CHKERRQ(ierr); 270813c2a604SAdrian Maldonado } 27095f2c45f1SShri Abhyankar ierr = DMDestroy(&network->plex);CHKERRQ(ierr); 27105f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr); 27115f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr); 271283b2e829SHong Zhang 27132bf73ac6SHong Zhang for (j=0; j<network->Nsvtx; j++) { 27142bf73ac6SHong Zhang ierr = PetscFree(network->svtx[j].sv);CHKERRQ(ierr); 27152bf73ac6SHong Zhang } 27162bf73ac6SHong Zhang if (network->svtx) {ierr = PetscFree(network->svtx);CHKERRQ(ierr);} 2717f11a936eSBarry Smith ierr = PetscFree2(network->subnetedge,network->subnetvtx);CHKERRQ(ierr); 2718caf410d2SHong Zhang 27192bf73ac6SHong Zhang ierr = PetscTableDestroy(&network->svtable);CHKERRQ(ierr); 2720e2aaf10cSShri Abhyankar ierr = PetscFree(network->subnet);CHKERRQ(ierr); 272154dfd506SHong Zhang ierr = PetscFree(network->component);CHKERRQ(ierr); 27225f2c45f1SShri Abhyankar ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr); 272354dfd506SHong Zhang 272454dfd506SHong Zhang if (network->header) { 272554dfd506SHong Zhang np = network->pEnd - network->pStart; 272654dfd506SHong Zhang for (j=0; j < np; j++) { 272754dfd506SHong 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); 272854dfd506SHong Zhang ierr = PetscFree(network->cvalue[j].data);CHKERRQ(ierr); 272954dfd506SHong Zhang } 2730caf410d2SHong Zhang ierr = PetscFree2(network->header,network->cvalue);CHKERRQ(ierr); 273154dfd506SHong Zhang } 27325f2c45f1SShri Abhyankar ierr = PetscFree(network);CHKERRQ(ierr); 27335f2c45f1SShri Abhyankar PetscFunctionReturn(0); 27345f2c45f1SShri Abhyankar } 27355f2c45f1SShri Abhyankar 27365f2c45f1SShri Abhyankar PetscErrorCode DMView_Network(DM dm,PetscViewer viewer) 27375f2c45f1SShri Abhyankar { 27385f2c45f1SShri Abhyankar PetscErrorCode ierr; 2739caf410d2SHong Zhang PetscBool iascii; 2740caf410d2SHong Zhang PetscMPIInt rank; 27415f2c45f1SShri Abhyankar 27425f2c45f1SShri Abhyankar PetscFunctionBegin; 2743caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 2744ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRMPI(ierr); 2745caf410d2SHong Zhang PetscValidHeaderSpecific(dm,DM_CLASSID, 1); 2746caf410d2SHong Zhang PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2747caf410d2SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 2748caf410d2SHong Zhang if (iascii) { 2749caf410d2SHong Zhang const PetscInt *cone,*vtx,*edges; 27502bf73ac6SHong Zhang PetscInt vfrom,vto,i,j,nv,ne,ncv,p,nsubnet; 27512bf73ac6SHong Zhang DM_Network *network = (DM_Network*)dm->data; 2752caf410d2SHong Zhang 27532bf73ac6SHong Zhang nsubnet = network->Nsubnet; /* num of subnetworks */ 2754dd400576SPatrick Sanan if (rank == 0) { 27552bf73ac6SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF," NSubnets: %D; NEdges: %D; NVertices: %D; NSharedVertices: %D.\n",nsubnet,network->NEdges,network->NVertices,network->Nsvtx);CHKERRQ(ierr); 27562bf73ac6SHong Zhang } 27572bf73ac6SHong Zhang 27582bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&ncv,&vtx);CHKERRQ(ierr); 2759caf410d2SHong Zhang ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 27602bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " [%d] nEdges: %D; nVertices: %D; nSharedVertices: %D\n",rank,network->nEdges,network->nVertices,ncv);CHKERRQ(ierr); 2761caf410d2SHong Zhang 2762caf410d2SHong Zhang for (i=0; i<nsubnet; i++) { 27632bf73ac6SHong Zhang ierr = DMNetworkGetSubnetwork(dm,i,&nv,&ne,&vtx,&edges);CHKERRQ(ierr); 2764caf410d2SHong Zhang if (ne) { 27652bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " Subnet %D: nEdges %D, nVertices(include shared vertices) %D\n",i,ne,nv);CHKERRQ(ierr); 2766caf410d2SHong Zhang for (j=0; j<ne; j++) { 2767caf410d2SHong Zhang p = edges[j]; 2768caf410d2SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,p,&cone);CHKERRQ(ierr); 2769caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[0],&vfrom);CHKERRQ(ierr); 2770caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[1],&vto);CHKERRQ(ierr); 2771caf410d2SHong Zhang ierr = DMNetworkGetGlobalEdgeIndex(dm,edges[j],&p);CHKERRQ(ierr); 2772caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " edge %D: %D ----> %D\n",p,vfrom,vto);CHKERRQ(ierr); 2773caf410d2SHong Zhang } 2774caf410d2SHong Zhang } 2775caf410d2SHong Zhang } 27762bf73ac6SHong Zhang 27772bf73ac6SHong Zhang /* Shared vertices */ 27782bf73ac6SHong Zhang ierr = DMNetworkGetSharedVertices(dm,&ncv,&vtx);CHKERRQ(ierr); 27792bf73ac6SHong Zhang if (ncv) { 27802bf73ac6SHong Zhang SVtx *svtx = network->svtx; 27812bf73ac6SHong Zhang PetscInt gidx,svtx_idx,nvto,vfrom_net,vfrom_idx,*svto; 27822bf73ac6SHong Zhang PetscBool ghost; 27832bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " SharedVertices:\n");CHKERRQ(ierr); 27842bf73ac6SHong Zhang for (i=0; i<ncv; i++) { 27852bf73ac6SHong Zhang ierr = DMNetworkIsGhostVertex(dm,vtx[i],&ghost);CHKERRQ(ierr); 27862bf73ac6SHong Zhang if (ghost) continue; 27872bf73ac6SHong Zhang 27882bf73ac6SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,vtx[i],&gidx);CHKERRQ(ierr); 27892bf73ac6SHong Zhang ierr = PetscTableFind(network->svtable,gidx+1,&svtx_idx);CHKERRQ(ierr); 27902bf73ac6SHong Zhang svtx_idx--; 27912bf73ac6SHong Zhang nvto = svtx[svtx_idx].n; 27922bf73ac6SHong Zhang 27932bf73ac6SHong Zhang vfrom_net = svtx[svtx_idx].sv[0]; 27942bf73ac6SHong Zhang vfrom_idx = svtx[svtx_idx].sv[1]; 27952bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " svtx %D: global index %D, subnet[%D].%D ---->\n",i,gidx,vfrom_net,vfrom_idx);CHKERRQ(ierr); 27962bf73ac6SHong Zhang for (j=1; j<nvto; j++) { 27972bf73ac6SHong Zhang svto = svtx[svtx_idx].sv + 2*j; 27982bf73ac6SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " ----> subnet[%D].%D\n",svto[0],svto[1]);CHKERRQ(ierr); 2799caf410d2SHong Zhang } 2800caf410d2SHong Zhang } 2801caf410d2SHong Zhang } 2802caf410d2SHong Zhang ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2803caf410d2SHong Zhang ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 2804caf410d2SHong Zhang } else SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMNetwork writing", ((PetscObject)viewer)->type_name); 28055f2c45f1SShri Abhyankar PetscFunctionReturn(0); 28065f2c45f1SShri Abhyankar } 28075f2c45f1SShri Abhyankar 28085f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l) 28095f2c45f1SShri Abhyankar { 28105f2c45f1SShri Abhyankar PetscErrorCode ierr; 28115f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 28125f2c45f1SShri Abhyankar 28135f2c45f1SShri Abhyankar PetscFunctionBegin; 28145f2c45f1SShri Abhyankar ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr); 28155f2c45f1SShri Abhyankar PetscFunctionReturn(0); 28165f2c45f1SShri Abhyankar } 28175f2c45f1SShri Abhyankar 28185f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l) 28195f2c45f1SShri Abhyankar { 28205f2c45f1SShri Abhyankar PetscErrorCode ierr; 28215f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 28225f2c45f1SShri Abhyankar 28235f2c45f1SShri Abhyankar PetscFunctionBegin; 28245f2c45f1SShri Abhyankar ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr); 28255f2c45f1SShri Abhyankar PetscFunctionReturn(0); 28265f2c45f1SShri Abhyankar } 28275f2c45f1SShri Abhyankar 28285f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g) 28295f2c45f1SShri Abhyankar { 28305f2c45f1SShri Abhyankar PetscErrorCode ierr; 28315f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 28325f2c45f1SShri Abhyankar 28335f2c45f1SShri Abhyankar PetscFunctionBegin; 28345f2c45f1SShri Abhyankar ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr); 28355f2c45f1SShri Abhyankar PetscFunctionReturn(0); 28365f2c45f1SShri Abhyankar } 28375f2c45f1SShri Abhyankar 28385f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g) 28395f2c45f1SShri Abhyankar { 28405f2c45f1SShri Abhyankar PetscErrorCode ierr; 28415f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 28425f2c45f1SShri Abhyankar 28435f2c45f1SShri Abhyankar PetscFunctionBegin; 28445f2c45f1SShri Abhyankar ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr); 28455f2c45f1SShri Abhyankar PetscFunctionReturn(0); 28465f2c45f1SShri Abhyankar } 284722bbedd7SHong Zhang 284822bbedd7SHong Zhang /*@ 284964238763SRodolfo Oliveira DMNetworkGetVertexLocalToGlobalOrdering - Get vertex global index 285022bbedd7SHong Zhang 285122bbedd7SHong Zhang Not collective 285222bbedd7SHong Zhang 28537a7aea1fSJed Brown Input Parameters: 285422bbedd7SHong Zhang + dm - the dm object 285522bbedd7SHong Zhang - vloc - local vertex ordering, start from 0 285622bbedd7SHong Zhang 28577a7aea1fSJed Brown Output Parameters: 2858f0fc11ceSJed Brown . vg - global vertex ordering, start from 0 285922bbedd7SHong Zhang 286097bb938eSShri Abhyankar Level: advanced 286122bbedd7SHong Zhang 286222bbedd7SHong Zhang .seealso: DMNetworkSetVertexLocalToGlobalOrdering() 286322bbedd7SHong Zhang @*/ 286422bbedd7SHong Zhang PetscErrorCode DMNetworkGetVertexLocalToGlobalOrdering(DM dm,PetscInt vloc,PetscInt *vg) 286522bbedd7SHong Zhang { 286622bbedd7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 286722bbedd7SHong Zhang PetscInt *vltog = network->vltog; 286822bbedd7SHong Zhang 286922bbedd7SHong Zhang PetscFunctionBegin; 287022bbedd7SHong Zhang if (!vltog) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkSetVertexLocalToGlobalOrdering() first"); 287122bbedd7SHong Zhang *vg = vltog[vloc]; 287222bbedd7SHong Zhang PetscFunctionReturn(0); 287322bbedd7SHong Zhang } 287422bbedd7SHong Zhang 287522bbedd7SHong Zhang /*@ 287664238763SRodolfo Oliveira DMNetworkSetVertexLocalToGlobalOrdering - Create and setup vertex local to global map 287722bbedd7SHong Zhang 287822bbedd7SHong Zhang Collective 287922bbedd7SHong Zhang 288022bbedd7SHong Zhang Input Parameters: 2881f0fc11ceSJed Brown . dm - the dm object 288222bbedd7SHong Zhang 288397bb938eSShri Abhyankar Level: advanced 288422bbedd7SHong Zhang 288563029d29SHong Zhang .seealso: DMNetworkGetGlobalVertexIndex() 288622bbedd7SHong Zhang @*/ 288722bbedd7SHong Zhang PetscErrorCode DMNetworkSetVertexLocalToGlobalOrdering(DM dm) 288822bbedd7SHong Zhang { 288922bbedd7SHong Zhang PetscErrorCode ierr; 289022bbedd7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 289122bbedd7SHong Zhang MPI_Comm comm; 28922bf73ac6SHong Zhang PetscMPIInt rank,size,*displs=NULL,*recvcounts=NULL,remoterank; 289322bbedd7SHong Zhang PetscBool ghost; 289463029d29SHong Zhang PetscInt *vltog,nroots,nleaves,i,*vrange,k,N,lidx; 289522bbedd7SHong Zhang const PetscSFNode *iremote; 289622bbedd7SHong Zhang PetscSF vsf; 289763029d29SHong Zhang Vec Vleaves,Vleaves_seq; 289863029d29SHong Zhang VecScatter ctx; 289963029d29SHong Zhang PetscScalar *varr,val; 290063029d29SHong Zhang const PetscScalar *varr_read; 290122bbedd7SHong Zhang 290222bbedd7SHong Zhang PetscFunctionBegin; 290322bbedd7SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 2904ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 2905ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 290622bbedd7SHong Zhang 290722bbedd7SHong Zhang if (size == 1) { 290822bbedd7SHong Zhang nroots = network->vEnd - network->vStart; 290922bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 291022bbedd7SHong Zhang for (i=0; i<nroots; i++) vltog[i] = i; 291122bbedd7SHong Zhang network->vltog = vltog; 291222bbedd7SHong Zhang PetscFunctionReturn(0); 291322bbedd7SHong Zhang } 291422bbedd7SHong Zhang 291522bbedd7SHong Zhang if (!network->distributecalled) SETERRQ(comm, PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkDistribute() first"); 291622bbedd7SHong Zhang if (network->vltog) { 291722bbedd7SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 291822bbedd7SHong Zhang } 291922bbedd7SHong Zhang 292022bbedd7SHong Zhang ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 292122bbedd7SHong Zhang ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 292222bbedd7SHong Zhang vsf = network->vertex.sf; 292322bbedd7SHong Zhang 29242bf73ac6SHong Zhang ierr = PetscMalloc3(size+1,&vrange,size,&displs,size,&recvcounts);CHKERRQ(ierr); 2925f5427c60SHong Zhang ierr = PetscSFGetGraph(vsf,&nroots,&nleaves,NULL,&iremote);CHKERRQ(ierr); 292622bbedd7SHong Zhang 292722bbedd7SHong Zhang for (i=0; i<size; i++) { displs[i] = i; recvcounts[i] = 1;} 292822bbedd7SHong Zhang 292922bbedd7SHong Zhang i = nroots - nleaves; /* local number of vertices, excluding ghosts */ 293022bbedd7SHong Zhang vrange[0] = 0; 2931ffc4695bSBarry Smith ierr = MPI_Allgatherv(&i,1,MPIU_INT,vrange+1,recvcounts,displs,MPIU_INT,comm);CHKERRMPI(ierr); 293267dd800bSHong Zhang for (i=2; i<size+1; i++) {vrange[i] += vrange[i-1];} 293322bbedd7SHong Zhang 293422bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 293522bbedd7SHong Zhang network->vltog = vltog; 293622bbedd7SHong Zhang 293763029d29SHong Zhang /* Set vltog for non-ghost vertices */ 293863029d29SHong Zhang k = 0; 293922bbedd7SHong Zhang for (i=0; i<nroots; i++) { 294022bbedd7SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 294163029d29SHong Zhang if (ghost) continue; 294263029d29SHong Zhang vltog[i] = vrange[rank] + k++; 294322bbedd7SHong Zhang } 2944f5427c60SHong Zhang ierr = PetscFree3(vrange,displs,recvcounts);CHKERRQ(ierr); 294563029d29SHong Zhang 294663029d29SHong Zhang /* Set vltog for ghost vertices */ 294763029d29SHong Zhang /* (a) create parallel Vleaves and sequential Vleaves_seq to convert local iremote[*].index to global index */ 294863029d29SHong Zhang ierr = VecCreate(comm,&Vleaves);CHKERRQ(ierr); 294963029d29SHong Zhang ierr = VecSetSizes(Vleaves,2*nleaves,PETSC_DETERMINE);CHKERRQ(ierr); 295063029d29SHong Zhang ierr = VecSetFromOptions(Vleaves);CHKERRQ(ierr); 295163029d29SHong Zhang ierr = VecGetArray(Vleaves,&varr);CHKERRQ(ierr); 295263029d29SHong Zhang for (i=0; i<nleaves; i++) { 295363029d29SHong Zhang varr[2*i] = (PetscScalar)(iremote[i].rank); /* rank of remote process */ 295463029d29SHong Zhang varr[2*i+1] = (PetscScalar)(iremote[i].index); /* local index in remote process */ 295563029d29SHong Zhang } 295663029d29SHong Zhang ierr = VecRestoreArray(Vleaves,&varr);CHKERRQ(ierr); 295763029d29SHong Zhang 295863029d29SHong Zhang /* (b) scatter local info to remote processes via VecScatter() */ 295963029d29SHong Zhang ierr = VecScatterCreateToAll(Vleaves,&ctx,&Vleaves_seq);CHKERRQ(ierr); 296063029d29SHong Zhang ierr = VecScatterBegin(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 296163029d29SHong Zhang ierr = VecScatterEnd(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 296263029d29SHong Zhang 296363029d29SHong Zhang /* (c) convert local indices to global indices in parallel vector Vleaves */ 296463029d29SHong Zhang ierr = VecGetSize(Vleaves_seq,&N);CHKERRQ(ierr); 296563029d29SHong Zhang ierr = VecGetArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 296663029d29SHong Zhang for (i=0; i<N; i+=2) { 29672e4cff2eSHong Zhang remoterank = (PetscMPIInt)PetscRealPart(varr_read[i]); 296863029d29SHong Zhang if (remoterank == rank) { 296963029d29SHong Zhang k = i+1; /* row number */ 29702e4cff2eSHong Zhang lidx = (PetscInt)PetscRealPart(varr_read[i+1]); 297163029d29SHong Zhang val = (PetscScalar)vltog[lidx]; /* global index for non-ghost vertex computed above */ 297263029d29SHong Zhang ierr = VecSetValues(Vleaves,1,&k,&val,INSERT_VALUES);CHKERRQ(ierr); 297363029d29SHong Zhang } 297463029d29SHong Zhang } 297563029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 297663029d29SHong Zhang ierr = VecAssemblyBegin(Vleaves);CHKERRQ(ierr); 297763029d29SHong Zhang ierr = VecAssemblyEnd(Vleaves);CHKERRQ(ierr); 297863029d29SHong Zhang 297963029d29SHong Zhang /* (d) Set vltog for ghost vertices by copying local values of Vleaves */ 298063029d29SHong Zhang ierr = VecGetArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 298163029d29SHong Zhang k = 0; 298263029d29SHong Zhang for (i=0; i<nroots; i++) { 298363029d29SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 298463029d29SHong Zhang if (!ghost) continue; 29852e4cff2eSHong Zhang vltog[i] = (PetscInt)PetscRealPart(varr_read[2*k+1]); k++; 298663029d29SHong Zhang } 298763029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 298863029d29SHong Zhang 298963029d29SHong Zhang ierr = VecDestroy(&Vleaves);CHKERRQ(ierr); 299063029d29SHong Zhang ierr = VecDestroy(&Vleaves_seq);CHKERRQ(ierr); 299163029d29SHong Zhang ierr = VecScatterDestroy(&ctx);CHKERRQ(ierr); 299222bbedd7SHong Zhang PetscFunctionReturn(0); 299322bbedd7SHong Zhang } 299442dc13f1SHong Zhang 299542dc13f1SHong Zhang PETSC_STATIC_INLINE PetscErrorCode DMISAddSize_private(DM_Network *network,PetscInt p,PetscInt numkeys,PetscInt keys[],PetscInt blocksize[],PetscInt nselectedvar[],PetscInt *nidx) 299642dc13f1SHong Zhang { 299742dc13f1SHong Zhang PetscErrorCode ierr; 299842dc13f1SHong Zhang PetscInt i,j,ncomps,nvar,key,offset=0; 299942dc13f1SHong Zhang DMNetworkComponentHeader header; 300042dc13f1SHong Zhang 300142dc13f1SHong Zhang PetscFunctionBegin; 300242dc13f1SHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 300342dc13f1SHong Zhang ncomps = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 300442dc13f1SHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offset); 300542dc13f1SHong Zhang 300642dc13f1SHong Zhang for (i=0; i<ncomps; i++) { 300742dc13f1SHong Zhang key = header->key[i]; 300842dc13f1SHong Zhang nvar = header->nvar[i]; 300942dc13f1SHong Zhang for (j=0; j<numkeys; j++) { 301042dc13f1SHong Zhang if (key == keys[j]) { 301142dc13f1SHong Zhang if (!blocksize || blocksize[j] == -1) { 301242dc13f1SHong Zhang *nidx += nvar; 301342dc13f1SHong Zhang } else { 301442dc13f1SHong Zhang *nidx += nselectedvar[j]*nvar/blocksize[j]; 301542dc13f1SHong Zhang } 301642dc13f1SHong Zhang } 301742dc13f1SHong Zhang } 301842dc13f1SHong Zhang } 301942dc13f1SHong Zhang PetscFunctionReturn(0); 302042dc13f1SHong Zhang } 302142dc13f1SHong Zhang 302242dc13f1SHong 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) 302342dc13f1SHong Zhang { 302442dc13f1SHong Zhang PetscErrorCode ierr; 302542dc13f1SHong Zhang PetscInt i,j,ncomps,nvar,key,offsetg,k,k1,offset=0; 302642dc13f1SHong Zhang DM_Network *network = (DM_Network*)dm->data; 302742dc13f1SHong Zhang DMNetworkComponentHeader header; 302842dc13f1SHong Zhang 302942dc13f1SHong Zhang PetscFunctionBegin; 303042dc13f1SHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 303142dc13f1SHong Zhang ncomps = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 303242dc13f1SHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offset); 303342dc13f1SHong Zhang 303442dc13f1SHong Zhang for (i=0; i<ncomps; i++) { 303542dc13f1SHong Zhang key = header->key[i]; 303642dc13f1SHong Zhang nvar = header->nvar[i]; 303742dc13f1SHong Zhang for (j=0; j<numkeys; j++) { 303842dc13f1SHong Zhang if (key != keys[j]) continue; 303942dc13f1SHong Zhang 304042dc13f1SHong Zhang ierr = DMNetworkGetGlobalVecOffset(dm,p,i,&offsetg);CHKERRQ(ierr); 304142dc13f1SHong Zhang if (!blocksize || blocksize[j] == -1) { 304242dc13f1SHong Zhang for (k=0; k<nvar; k++) idx[(*ii)++] = offsetg + k; 304342dc13f1SHong Zhang } else { 304442dc13f1SHong Zhang for (k=0; k<nvar; k+=blocksize[j]) { 304542dc13f1SHong Zhang for (k1=0; k1<nselectedvar[j]; k1++) idx[(*ii)++] = offsetg + k + selectedvar[j][k1]; 304642dc13f1SHong Zhang } 304742dc13f1SHong Zhang } 304842dc13f1SHong Zhang } 304942dc13f1SHong Zhang } 305042dc13f1SHong Zhang PetscFunctionReturn(0); 305142dc13f1SHong Zhang } 305242dc13f1SHong Zhang 305342dc13f1SHong Zhang /*@ 305442dc13f1SHong Zhang DMNetworkCreateIS - Create an index set object from the global vector of the network 305542dc13f1SHong Zhang 305642dc13f1SHong Zhang Collective 305742dc13f1SHong Zhang 305842dc13f1SHong Zhang Input Parameters: 305942dc13f1SHong Zhang + dm - DMNetwork object 306042dc13f1SHong Zhang . numkeys - number of keys 306142dc13f1SHong Zhang . keys - array of keys that define the components of the variables you wish to extract 306242dc13f1SHong Zhang . blocksize - block size of the variables associated to the component 306342dc13f1SHong Zhang . nselectedvar - number of variables in each block to select 306442dc13f1SHong Zhang - selectedvar - the offset into the block of each variable in each block to select 306542dc13f1SHong Zhang 306642dc13f1SHong Zhang Output Parameters: 306742dc13f1SHong Zhang . is - the index set 306842dc13f1SHong Zhang 306942dc13f1SHong Zhang Level: Advanced 307042dc13f1SHong Zhang 307142dc13f1SHong Zhang Notes: 307242dc13f1SHong 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. 307342dc13f1SHong Zhang 307442dc13f1SHong Zhang .seealso: DMNetworkCreate(), ISCreateGeneral(), DMNetworkCreateLocalIS() 307542dc13f1SHong Zhang @*/ 307642dc13f1SHong Zhang PetscErrorCode DMNetworkCreateIS(DM dm,PetscInt numkeys,PetscInt keys[],PetscInt blocksize[],PetscInt nselectedvar[],PetscInt *selectedvar[],IS *is) 307742dc13f1SHong Zhang { 307842dc13f1SHong Zhang PetscErrorCode ierr; 307942dc13f1SHong Zhang MPI_Comm comm; 308042dc13f1SHong Zhang DM_Network *network = (DM_Network*)dm->data; 308142dc13f1SHong Zhang PetscInt i,p,estart,eend,vstart,vend,nidx,*idx; 308242dc13f1SHong Zhang PetscBool ghost; 308342dc13f1SHong Zhang 308442dc13f1SHong Zhang PetscFunctionBegin; 308542dc13f1SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 308642dc13f1SHong Zhang 308742dc13f1SHong Zhang /* Check input parameters */ 308842dc13f1SHong Zhang for (i=0; i<numkeys; i++) { 308942dc13f1SHong Zhang if (!blocksize || blocksize[i] == -1) continue; 309042dc13f1SHong 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]); 309142dc13f1SHong Zhang } 309242dc13f1SHong Zhang 309342dc13f1SHong Zhang ierr = DMNetworkGetEdgeRange(dm,&estart,&eend);CHKERRQ(ierr); 309442dc13f1SHong Zhang ierr = DMNetworkGetVertexRange(dm,&vstart,&vend);CHKERRQ(ierr); 309542dc13f1SHong Zhang 309642dc13f1SHong Zhang /* Get local number of idx */ 309742dc13f1SHong Zhang nidx = 0; 309842dc13f1SHong Zhang for (p=estart; p<eend; p++) { 309942dc13f1SHong Zhang ierr = DMISAddSize_private(network,p,numkeys,keys,blocksize,nselectedvar,&nidx);CHKERRQ(ierr); 310042dc13f1SHong Zhang } 310142dc13f1SHong Zhang for (p=vstart; p<vend; p++) { 310242dc13f1SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 310342dc13f1SHong Zhang if (ghost) continue; 310442dc13f1SHong Zhang ierr = DMISAddSize_private(network,p,numkeys,keys,blocksize,nselectedvar,&nidx);CHKERRQ(ierr); 310542dc13f1SHong Zhang } 310642dc13f1SHong Zhang 310742dc13f1SHong Zhang /* Compute idx */ 310842dc13f1SHong Zhang ierr = PetscMalloc1(nidx,&idx);CHKERRQ(ierr); 310942dc13f1SHong Zhang i = 0; 311042dc13f1SHong Zhang for (p=estart; p<eend; p++) { 311142dc13f1SHong Zhang ierr = DMISComputeIdx_private(dm,p,numkeys,keys,blocksize,nselectedvar,selectedvar,&i,idx);CHKERRQ(ierr); 311242dc13f1SHong Zhang } 311342dc13f1SHong Zhang for (p=vstart; p<vend; p++) { 311442dc13f1SHong Zhang ierr = DMNetworkIsGhostVertex(dm,p,&ghost);CHKERRQ(ierr); 311542dc13f1SHong Zhang if (ghost) continue; 311642dc13f1SHong Zhang ierr = DMISComputeIdx_private(dm,p,numkeys,keys,blocksize,nselectedvar,selectedvar,&i,idx);CHKERRQ(ierr); 311742dc13f1SHong Zhang } 311842dc13f1SHong Zhang 311942dc13f1SHong Zhang /* Create is */ 312042dc13f1SHong Zhang ierr = ISCreateGeneral(comm,nidx,idx,PETSC_COPY_VALUES,is);CHKERRQ(ierr); 312142dc13f1SHong Zhang ierr = PetscFree(idx);CHKERRQ(ierr); 312242dc13f1SHong Zhang PetscFunctionReturn(0); 312342dc13f1SHong Zhang } 312442dc13f1SHong Zhang 312542dc13f1SHong 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) 312642dc13f1SHong Zhang { 312742dc13f1SHong Zhang PetscErrorCode ierr; 312842dc13f1SHong Zhang PetscInt i,j,ncomps,nvar,key,offsetl,k,k1,offset=0; 312942dc13f1SHong Zhang DM_Network *network = (DM_Network*)dm->data; 313042dc13f1SHong Zhang DMNetworkComponentHeader header; 313142dc13f1SHong Zhang 313242dc13f1SHong Zhang PetscFunctionBegin; 313342dc13f1SHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 313442dc13f1SHong Zhang ncomps = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 313542dc13f1SHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offset); 313642dc13f1SHong Zhang 313742dc13f1SHong Zhang for (i=0; i<ncomps; i++) { 313842dc13f1SHong Zhang key = header->key[i]; 313942dc13f1SHong Zhang nvar = header->nvar[i]; 314042dc13f1SHong Zhang for (j=0; j<numkeys; j++) { 314142dc13f1SHong Zhang if (key != keys[j]) continue; 314242dc13f1SHong Zhang 314342dc13f1SHong Zhang ierr = DMNetworkGetLocalVecOffset(dm,p,i,&offsetl);CHKERRQ(ierr); 314442dc13f1SHong Zhang if (!blocksize || blocksize[j] == -1) { 314542dc13f1SHong Zhang for (k=0; k<nvar; k++) idx[(*ii)++] = offsetl + k; 314642dc13f1SHong Zhang } else { 314742dc13f1SHong Zhang for (k=0; k<nvar; k+=blocksize[j]) { 314842dc13f1SHong Zhang for (k1=0; k1<nselectedvar[j]; k1++) idx[(*ii)++] = offsetl + k + selectedvar[j][k1]; 314942dc13f1SHong Zhang } 315042dc13f1SHong Zhang } 315142dc13f1SHong Zhang } 315242dc13f1SHong Zhang } 315342dc13f1SHong Zhang PetscFunctionReturn(0); 315442dc13f1SHong Zhang } 315542dc13f1SHong Zhang 315642dc13f1SHong Zhang /*@ 315742dc13f1SHong Zhang DMNetworkCreateLocalIS - Create an index set object from the local vector of the network 315842dc13f1SHong Zhang 315942dc13f1SHong Zhang Not collective 316042dc13f1SHong Zhang 316142dc13f1SHong Zhang Input Parameters: 316242dc13f1SHong Zhang + dm - DMNetwork object 316342dc13f1SHong Zhang . numkeys - number of keys 316442dc13f1SHong Zhang . keys - array of keys that define the components of the variables you wish to extract 316542dc13f1SHong Zhang . blocksize - block size of the variables associated to the component 316642dc13f1SHong Zhang . nselectedvar - number of variables in each block to select 316742dc13f1SHong Zhang - selectedvar - the offset into the block of each variable in each block to select 316842dc13f1SHong Zhang 316942dc13f1SHong Zhang Output Parameters: 317042dc13f1SHong Zhang . is - the index set 317142dc13f1SHong Zhang 317242dc13f1SHong Zhang Level: Advanced 317342dc13f1SHong Zhang 317442dc13f1SHong Zhang Notes: 317542dc13f1SHong 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. 317642dc13f1SHong Zhang 317742dc13f1SHong Zhang .seealso: DMNetworkCreate(), DMNetworkCreateIS, ISCreateGeneral() 317842dc13f1SHong Zhang @*/ 317942dc13f1SHong Zhang PetscErrorCode DMNetworkCreateLocalIS(DM dm,PetscInt numkeys,PetscInt keys[],PetscInt blocksize[],PetscInt nselectedvar[],PetscInt *selectedvar[],IS *is) 318042dc13f1SHong Zhang { 318142dc13f1SHong Zhang PetscErrorCode ierr; 318242dc13f1SHong Zhang DM_Network *network = (DM_Network*)dm->data; 318342dc13f1SHong Zhang PetscInt i,p,pstart,pend,nidx,*idx; 318442dc13f1SHong Zhang 318542dc13f1SHong Zhang PetscFunctionBegin; 318642dc13f1SHong Zhang /* Check input parameters */ 318742dc13f1SHong Zhang for (i=0; i<numkeys; i++) { 318842dc13f1SHong Zhang if (!blocksize || blocksize[i] == -1) continue; 318942dc13f1SHong 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]); 319042dc13f1SHong Zhang } 319142dc13f1SHong Zhang 319242dc13f1SHong Zhang pstart = network->pStart; 319342dc13f1SHong Zhang pend = network->pEnd; 319442dc13f1SHong Zhang 319542dc13f1SHong Zhang /* Get local number of idx */ 319642dc13f1SHong Zhang nidx = 0; 319742dc13f1SHong Zhang for (p=pstart; p<pend; p++) { 319842dc13f1SHong Zhang ierr = DMISAddSize_private(network,p,numkeys,keys,blocksize,nselectedvar,&nidx);CHKERRQ(ierr); 319942dc13f1SHong Zhang } 320042dc13f1SHong Zhang 320142dc13f1SHong Zhang /* Compute local idx */ 320242dc13f1SHong Zhang ierr = PetscMalloc1(nidx,&idx);CHKERRQ(ierr); 320342dc13f1SHong Zhang i = 0; 320442dc13f1SHong Zhang for (p=pstart; p<pend; p++) { 320542dc13f1SHong Zhang ierr = DMISComputeLocalIdx_private(dm,p,numkeys,keys,blocksize,nselectedvar,selectedvar,&i,idx);CHKERRQ(ierr); 320642dc13f1SHong Zhang } 320742dc13f1SHong Zhang 320842dc13f1SHong Zhang /* Create is */ 320942dc13f1SHong Zhang ierr = ISCreateGeneral(PETSC_COMM_SELF,nidx,idx,PETSC_COPY_VALUES,is);CHKERRQ(ierr); 321042dc13f1SHong Zhang ierr = PetscFree(idx);CHKERRQ(ierr); 321142dc13f1SHong Zhang PetscFunctionReturn(0); 321242dc13f1SHong Zhang } 3213