Cloned SEACAS for EXODUS library with extra build files for internal package management.
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.

88 lines
3.0 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
/* 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;
}
}
}
}
}