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.
		
		
		
		
		
			
		
			
				
					
					
						
							151 lines
						
					
					
						
							4.4 KiB
						
					
					
				
			
		
		
	
	
							151 lines
						
					
					
						
							4.4 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 "smalloc.h" // for smalloc_ret
 | |
| #include "structs.h" // for vtx_data
 | |
| #include <stdio.h>   // for NULL, fprintf, printf, FILE
 | |
| 
 | |
| /* Change from a FORTRAN graph style to our graph data structure. */
 | |
| 
 | |
| int reformat(int *              start,     /* start of edge list for each vertex */
 | |
|              int *              adjacency, /* edge list data */
 | |
|              int                nvtxs,     /* number of vertices in graph */
 | |
|              int *              pnedges,   /* ptr to number of edges in graph */
 | |
|              int *              vwgts,     /* weights for all vertices */
 | |
|              float *            ewgts,     /* weights for all edges */
 | |
|              struct vtx_data ***pgraph     /* ptr to array of vtx data for graph */
 | |
| )
 | |
| {
 | |
|   extern FILE *     Output_File;      /* output file or null */
 | |
|   struct vtx_data **graph     = NULL; /* array of vtx data for graph */
 | |
|   struct vtx_data * links     = NULL; /* space for data for all vtxs */
 | |
|   int *             edges     = NULL; /* space for all adjacency lists */
 | |
|   float *           eweights  = NULL; /* space for all edge weights */
 | |
|   int *             eptr      = NULL; /* steps through adjacency list */
 | |
|   int *             eptr_save = NULL; /* saved index into adjacency list */
 | |
|   float *           wptr      = NULL; /* steps through edge weights list */
 | |
|   int               self_edge;        /* number of self loops detected */
 | |
|   int               size;             /* length of all edge lists */
 | |
|   double            sum;              /* sum of edge weights for a vtx */
 | |
|   int               using_ewgts;      /* are edge weights being used? */
 | |
|   int               using_vwgts;      /* are vertex weights being used? */
 | |
|   int               i, j;             /* loop counters */
 | |
| 
 | |
|   using_ewgts = (ewgts != NULL);
 | |
|   using_vwgts = (vwgts != NULL);
 | |
| 
 | |
|   graph   = smalloc_ret((nvtxs + 1) * sizeof(struct vtx_data *));
 | |
|   *pgraph = graph;
 | |
|   if (graph == NULL) {
 | |
|     return (1);
 | |
|   }
 | |
| 
 | |
|   graph[1] = NULL;
 | |
| 
 | |
|   /* Set up all the basic data structure for the vertices. */
 | |
|   /* Replace many small mallocs by a few large ones. */
 | |
|   links = smalloc_ret((nvtxs) * sizeof(struct vtx_data));
 | |
|   if (links == NULL) {
 | |
|     return (1);
 | |
|   }
 | |
| 
 | |
|   for (i = 1; i <= nvtxs; i++) {
 | |
|     graph[i] = links++;
 | |
|   }
 | |
| 
 | |
|   graph[1]->edges = NULL;
 | |
|   graph[1]->ewgts = NULL;
 | |
| 
 | |
|   /* Now fill in all the data fields. */
 | |
|   if (start != NULL) {
 | |
|     *pnedges = start[nvtxs] / 2;
 | |
|   }
 | |
|   else {
 | |
|     *pnedges = 0;
 | |
|   }
 | |
|   size  = 2 * (*pnedges) + nvtxs;
 | |
|   edges = smalloc_ret(size * sizeof(int));
 | |
|   if (edges == NULL) {
 | |
|     return (1);
 | |
|   }
 | |
| 
 | |
|   if (using_ewgts) {
 | |
|     eweights = smalloc_ret(size * sizeof(float));
 | |
|     if (eweights == NULL) {
 | |
|       return (1);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (start != NULL) {
 | |
|     eptr = adjacency + start[0];
 | |
|     wptr = ewgts;
 | |
|   }
 | |
|   self_edge = 0;
 | |
| 
 | |
|   for (i = 1; i <= nvtxs; i++) {
 | |
|     if (using_vwgts) {
 | |
|       graph[i]->vwgt = *(vwgts++);
 | |
|     }
 | |
|     else {
 | |
|       graph[i]->vwgt = 1;
 | |
|     }
 | |
|     if (start != NULL) {
 | |
|       size = start[i] - start[i - 1];
 | |
|     }
 | |
|     else {
 | |
|       size = 0;
 | |
|     }
 | |
|     graph[i]->nedges = size + 1;
 | |
|     graph[i]->edges  = edges;
 | |
|     *edges++         = i;
 | |
|     eptr_save        = eptr;
 | |
|     for (j = size; j; j--) {
 | |
|       if (*eptr != i) {
 | |
|         *edges++ = *eptr++;
 | |
|       }
 | |
|       else { /* Self edge, skip it. */
 | |
|         if (!self_edge) {
 | |
|           printf("WARNING: Self edge (%d,%d) being ignored\n", i, i);
 | |
|           if (Output_File != NULL) {
 | |
|             fprintf(Output_File, "WARNING: Self edge (%d,%d) being ignored\n", i, i);
 | |
|           }
 | |
|         }
 | |
|         ++self_edge;
 | |
|         eptr++;
 | |
|         --(graph[i]->nedges);
 | |
|         --(*pnedges);
 | |
|       }
 | |
|     }
 | |
|     if (using_ewgts) {
 | |
|       graph[i]->ewgts = eweights;
 | |
|       eweights++;
 | |
|       sum = 0;
 | |
|       for (j = size; j; j--) {
 | |
|         if (*eptr_save++ != i) {
 | |
|           sum += *wptr;
 | |
|           *eweights++ = *wptr++;
 | |
|         }
 | |
|         else {
 | |
|           wptr++;
 | |
|         }
 | |
|       }
 | |
|       graph[i]->ewgts[0] = -sum;
 | |
|     }
 | |
|     else {
 | |
|       graph[i]->ewgts = NULL;
 | |
|     }
 | |
|   }
 | |
|   if (self_edge > 1) {
 | |
|     printf("WARNING: %d self edges were detected and ignored\n", self_edge);
 | |
|     if (Output_File != NULL) {
 | |
|       fprintf(Output_File, "WARNING: %d self edges were detected and ignored\n", self_edge);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return (0);
 | |
| }
 | |
| 
 |