You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
4.7 KiB
122 lines
4.7 KiB
2 years ago
|
/*
|
||
|
* Copyright(C) 1999-2020 National Technology & Engineering Solutions
|
||
|
* of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
|
||
|
* NTESS, the U.S. Government retains certain rights in this software.
|
||
|
*
|
||
|
* See packages/seacas/LICENSE for details
|
||
|
*/
|
||
|
|
||
|
#include "structs.h" // for vtx_data
|
||
|
#include <stdio.h> // for NULL
|
||
|
|
||
|
/* Construct a subgraph of a graph. */
|
||
|
/* This reuses the graph storage, and can be undone. */
|
||
|
|
||
|
void make_subgraph(struct vtx_data **graph, /* graph data structure */
|
||
|
struct vtx_data **subgraph, /* subgraph data structure */
|
||
|
int subnvtxs, /* number of vtxs in subgraph */
|
||
|
int * psubnedges, /* ptr to number of edges in subgraph */
|
||
|
int * assignment, /* values designating subgraph inclusion */
|
||
|
int set, /* assignment value indicating inclusion */
|
||
|
int * glob2loc, /* mapping from graph to subgraph numbering */
|
||
|
int * loc2glob, /* mapping from subgraph to graph numbering */
|
||
|
int * degree, /* degrees of vertices in graph */
|
||
|
int using_ewgts /* are edge weights being used? */
|
||
|
)
|
||
|
{
|
||
|
struct vtx_data *subgptr = NULL; /* loops through subgraph */
|
||
|
float * fptr = NULL; /* loops through edge weights */
|
||
|
int * iptr = NULL; /* loops through edge list */
|
||
|
float tempwgt; /* weight of vertex being swapped */
|
||
|
double ewgtsum; /* sum of weights of subgraph edges */
|
||
|
int subnedges; /* number of edges in subgraph */
|
||
|
int neighbor; /* neighbor vertex in graph */
|
||
|
int newnedges; /* vertex degree in subgraph */
|
||
|
int tempvtx; /* vertex number being swapped */
|
||
|
int i, j; /* loop counter */
|
||
|
|
||
|
subnedges = 0;
|
||
|
for (i = 1; i <= subnvtxs; i++) {
|
||
|
/* First get the vertices organized properly. */
|
||
|
subgptr = subgraph[i] = graph[loc2glob[i]];
|
||
|
newnedges = degree[i] = subgptr->nedges;
|
||
|
|
||
|
/* Now work on the edges. */
|
||
|
subgptr->edges[0] = i;
|
||
|
ewgtsum = 0;
|
||
|
/* Move all deactivated edges to the end of the list. */
|
||
|
iptr = subgptr->edges + 1;
|
||
|
if (using_ewgts) {
|
||
|
fptr = subgptr->ewgts + 1;
|
||
|
}
|
||
|
for (j = 1; j < newnedges;) {
|
||
|
neighbor = *iptr;
|
||
|
if (assignment[neighbor] == set) { /* Keep vertex in edge list. */
|
||
|
subgptr->edges[j] = glob2loc[neighbor];
|
||
|
if (using_ewgts) {
|
||
|
ewgtsum += *fptr++;
|
||
|
}
|
||
|
j++;
|
||
|
iptr++;
|
||
|
}
|
||
|
else { /* Move vertex to back of edge list. */
|
||
|
--newnedges;
|
||
|
tempvtx = subgptr->edges[newnedges];
|
||
|
subgptr->edges[newnedges] = neighbor;
|
||
|
*iptr = tempvtx;
|
||
|
if (using_ewgts) {
|
||
|
tempwgt = subgptr->ewgts[newnedges];
|
||
|
subgptr->ewgts[newnedges] = *fptr;
|
||
|
*fptr = tempwgt;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
subgptr->nedges = newnedges;
|
||
|
subnedges += newnedges;
|
||
|
if (using_ewgts) {
|
||
|
subgptr->ewgts[0] = -ewgtsum;
|
||
|
}
|
||
|
}
|
||
|
*psubnedges = (subnedges - subnvtxs) / 2;
|
||
|
}
|
||
|
|
||
|
/* Undo the construction of the subgraph. */
|
||
|
void remake_graph(struct vtx_data **subgraph, /* subgraph data structure */
|
||
|
int subnvtxs, /* number of vtxs in subgraph */
|
||
|
int * loc2glob, /* mapping from subgraph to graph numbering */
|
||
|
int * degree, /* degrees of vertices in graph */
|
||
|
int using_ewgts /* are edge weights being used? */
|
||
|
)
|
||
|
{
|
||
|
struct vtx_data *subgptr; /* loops through subgraph */
|
||
|
float * fptr; /* loops through edge weights */
|
||
|
int * iptr; /* loops through adjacency list */
|
||
|
double ewgtsum; /* sum of weights of subgraph edges */
|
||
|
int nedges; /* vertex degree in subgraph */
|
||
|
int i, j; /* loop counter */
|
||
|
|
||
|
/* For each vertex in subgraph, expand the edge set back out. */
|
||
|
for (i = 1; i <= subnvtxs; i++) {
|
||
|
subgptr = subgraph[i];
|
||
|
subgptr->edges[0] = loc2glob[i];
|
||
|
nedges = subgptr->nedges;
|
||
|
/* Change edges back to global numbering system. */
|
||
|
iptr = subgptr->edges;
|
||
|
for (j = nedges - 1; j; j--) {
|
||
|
iptr++;
|
||
|
*iptr = loc2glob[*iptr];
|
||
|
}
|
||
|
subgptr->nedges = degree[i];
|
||
|
|
||
|
/* Now get the diagonal value right. */
|
||
|
if (using_ewgts) {
|
||
|
ewgtsum = 0;
|
||
|
fptr = subgptr->ewgts;
|
||
|
for (j = degree[i] - 1; j; j--) {
|
||
|
ewgtsum += *(++fptr);
|
||
|
}
|
||
|
subgptr->ewgts[0] = -ewgtsum;
|
||
|
}
|
||
|
}
|
||
|
}
|