FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
matrix_repart.c
Go to the documentation of this file.
1 /*****************************************************************************
2  * Copyright (c) 2019 FrontISTR Commons
3  * This software is released under the MIT License, see LICENSE.txt
4  *****************************************************************************/
5 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include "hecmw_util.h"
9 
10 #ifdef HECMW_WITH_METIS
11 #include "metis.h"
12 #endif
13 
14 #include "matrix2graph.h"
15 #include "separator.h"
17 
18 void bi_part_directive(int *neqns, int *nttbr, int *irow, int *jcol,
19  int *num_graph1, int *num_graph2, int *num_separator) {
20 #ifdef HECMW_WITH_METIS
21  graph_type *graph;
22  int num_of_row, num_of_col, num_of_nzero;
23 
24  int *perm, *iperm;
25 
26  num_of_row = *neqns;
27  num_of_col = *neqns;
28  num_of_nzero = *nttbr;
29 
30  graph = (graph_type *)malloc(sizeof(graph_type));
31  if (graph == NULL) separator_memory_exit("graph");
32 
33  fprintf(stderr, "Start transforming matrix to graph\n");
34  matrix2graph(num_of_row, num_of_col, num_of_nzero, irow, jcol, graph);
35  fprintf(stderr,
36  "Graph Information "
37  "---------------------------------------------------\n");
38  fprintf(stderr, "#Vertices: %d, #Edges: %d\n\n", graph->nvtxs,
39  graph->nedges / 2);
40  perm = (int *)calloc(num_of_col, sizeof(int));
41  iperm = (int *)calloc(num_of_col, sizeof(int));
42  if ((perm == NULL) || (iperm == NULL))
43  separator_memory_exit("matrix_repart: perm, iperm");
44 
45 #if defined(METIS_VER_MAJOR) && (METIS_VER_MAJOR == 5)
46  {
47  /* The graph and the permutation are sized by the number of equations, so
48  * they stay int; idx_t copies are needed only because METIS 5 takes them */
49  idx_t options[METIS_NOPTIONS];
50  idx_t nvtxs_metis = graph->nvtxs;
51  idx_t *xadj_metis, *adjncy_metis, *perm_metis, *iperm_metis;
52  int i;
53 
54  xadj_metis = (idx_t *)calloc(num_of_col + 1, sizeof(idx_t));
55  adjncy_metis = (idx_t *)calloc(graph->nedges, sizeof(idx_t));
56  perm_metis = (idx_t *)calloc(num_of_col, sizeof(idx_t));
57  iperm_metis = (idx_t *)calloc(num_of_col, sizeof(idx_t));
58  if ((xadj_metis == NULL) || (adjncy_metis == NULL) ||
59  (perm_metis == NULL) || (iperm_metis == NULL))
60  separator_memory_exit("matrix_repart: metis arrays");
61 
62  for (i = 0; i <= num_of_col; i++) xadj_metis[i] = graph->xadj[i];
63  for (i = 0; i < graph->nedges; i++) adjncy_metis[i] = graph->adjncy[i];
64 
65  METIS_SetDefaultOptions(options);
66  options[METIS_OPTION_COMPRESS] = 0;
67  METIS_NodeND(&nvtxs_metis, xadj_metis, adjncy_metis, NULL, options,
68  perm_metis, iperm_metis);
69 
70  for (i = 0; i < num_of_col; i++) {
71  perm[i] = (int)perm_metis[i];
72  iperm[i] = (int)iperm_metis[i];
73  }
74 
75  free(xadj_metis);
76  free(adjncy_metis);
77  free(perm_metis);
78  free(iperm_metis);
79  }
80 #else
81  {
82  int options[8];
83  int num_flag;
84  /* the following are options. see METIS manual for METIS_NODEND() */
85  options[0] = 1; /* specify parameters */
86  options[1] = 3; /* default */
87  options[2] = 1; /* default */
88  options[3] = 2; /* default */
89  options[4] = 0; /* default */
90  options[5] = 0; /* do not try to compress the matrix */
91  options[6] = 0; /* default */
92  options[7] = 1; /* default */
93 
94  num_flag = 0;
95  METIS_NodeND(&graph->nvtxs, graph->xadj, graph->adjncy, &num_flag, options,
96  perm, iperm);
97  }
98 #endif
99  /* copy to separator */
100 
101  *num_graph1 = separator->num_of_lgraph;
102  *num_graph2 = separator->num_of_rgraph;
103  *num_separator = separator->num_of_separator;
104 
105  free(perm);
106  free(iperm);
107  free(graph->xadj);
108  free(graph->adjncy);
109  free(graph);
110 
111 #else
112  fprintf(
113  stderr,
114  "Error: Direct Parallel Solver not available. Please install Metis.\n");
116 #endif
117 
118  return;
119 }
120 
121 void bi_part_directive_(int *neqns, int *nttbr, int *irow, int *jcol,
122  int *num_graph1, int *num_graph2, int *num_separator) {
123  bi_part_directive(neqns, nttbr, irow, jcol, num_graph1, num_graph2,
124  num_separator);
125 }
126 
127 void bi_part_directive__(int *neqns, int *nttbr, int *irow, int *jcol,
128  int *num_graph1, int *num_graph2, int *num_separator) {
129  bi_part_directive(neqns, nttbr, irow, jcol, num_graph1, num_graph2,
130  num_separator);
131 }
132 
133 void BI_PART_DIRECTIVE(int *neqns, int *nttbr, int *irow, int *jcol,
134  int *num_graph1, int *num_graph2, int *num_separator) {
135  bi_part_directive(neqns, nttbr, irow, jcol, num_graph1, num_graph2,
136  num_separator);
137 }
HECMW_Comm HECMW_comm_get_comm(void)
Definition: hecmw_comm.c:751
#define NULL
void HECMW_abort(HECMW_Comm comm)
Definition: hecmw_util.c:88
long long idx_t
struct option_rec options[]
specify command line option name and executing function name.
Definition: main.c:286
void matrix2graph(int num_of_row, int num_of_col, int num_of_nzero, int *irow, int *jcol, graph_type *graph)
Definition: matrix2graph.c:12
Separator_result * separator
Definition: matrix_repart.c:16
void bi_part_directive__(int *neqns, int *nttbr, int *irow, int *jcol, int *num_graph1, int *num_graph2, int *num_separator)
void bi_part_directive(int *neqns, int *nttbr, int *irow, int *jcol, int *num_graph1, int *num_graph2, int *num_separator)
Definition: matrix_repart.c:18
void bi_part_directive_(int *neqns, int *nttbr, int *irow, int *jcol, int *num_graph1, int *num_graph2, int *num_separator)
void BI_PART_DIRECTIVE(int *neqns, int *nttbr, int *irow, int *jcol, int *num_graph1, int *num_graph2, int *num_separator)
void separator_memory_exit(char *var)
Definition: mem_util.c:9
int * xadj
Definition: matrix2graph.h:13
int * adjncy
Definition: matrix2graph.h:14