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.
87 lines
3.0 KiB
87 lines
3.0 KiB
/*
|
|
* 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
|
|
|
|
/* Interpolate the eigenvector from the coarsened to the original graph.
|
|
This may require regenerating mflag and v2cv arrays from merged array.
|
|
|
|
I also need to undo the merged edges in the reverse order from that in
|
|
which they were collapsed.
|
|
*/
|
|
|
|
void ch_interpolate(double ** vecs, /* approximate eigenvectors for graph */
|
|
double ** cvecs, /* exact eigenvectors for coarse graph */
|
|
int ndims, /* number of vectors to interpolate */
|
|
struct vtx_data **graph, /* array of vtx data for graph */
|
|
int nvtxs, /* number of vertices in graph */
|
|
int * v2cv, /* mapping from vtxs to cvtxs */
|
|
int using_ewgts /* are edge weights being used in fine graph? */
|
|
)
|
|
{
|
|
double *vec, *cvec; /* pointers into vecs and vecs */
|
|
int * eptr; /* loops through edge lists */
|
|
float * ewptr; /* loops through edge weights */
|
|
float ewgt; /* value for edge weight */
|
|
double ewsum; /* sum of incident edge weights */
|
|
double sum; /* sum of values of neighbors */
|
|
int neighbor; /* neighboring vertex */
|
|
int degree; /* number of neighbors */
|
|
int npasses = 1; /* number of Gauss-Seidel iterations */
|
|
int pass; /* loops through Gauss-Seidel iterations */
|
|
int i, j, k; /* loop counters */
|
|
|
|
/* Uncompress the coarse eigenvector by replicating matched values. */
|
|
for (j = 1; j <= ndims; j++) {
|
|
vec = vecs[j];
|
|
cvec = cvecs[j];
|
|
for (i = 1; i <= nvtxs; i++) {
|
|
vec[i] = cvec[v2cv[i]];
|
|
}
|
|
}
|
|
|
|
/* Now do a single pass of Gauss-Seidel to smooth eigenvectors. */
|
|
|
|
for (pass = 1; pass <= npasses; pass++) {
|
|
if (using_ewgts) {
|
|
for (j = 1; j <= ndims; j++) {
|
|
vec = vecs[j];
|
|
for (i = 1; i <= nvtxs; i++) {
|
|
eptr = graph[i]->edges;
|
|
ewptr = graph[i]->ewgts;
|
|
sum = 0;
|
|
ewsum = 0;
|
|
degree = graph[i]->nedges - 1;
|
|
for (k = degree; k; k--) {
|
|
neighbor = *(++eptr);
|
|
ewgt = *(++ewptr);
|
|
sum += ewgt * vec[neighbor];
|
|
ewsum += ewgt;
|
|
}
|
|
vec[i] = sum / ewsum;
|
|
}
|
|
}
|
|
}
|
|
|
|
else {
|
|
for (j = 1; j <= ndims; j++) {
|
|
vec = vecs[j];
|
|
for (i = 1; i <= nvtxs; i++) {
|
|
eptr = graph[i]->edges;
|
|
sum = 0;
|
|
degree = graph[i]->nedges - 1;
|
|
for (k = degree; k; k--) {
|
|
neighbor = *(++eptr);
|
|
sum += vec[neighbor];
|
|
}
|
|
vec[i] = sum / degree;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|