1 /*****************************************************************************
2  * Copyright (c) 2019 FrontISTR Commons
3  * This software is released under the MIT License, see LICENSE.txt
4  *****************************************************************************/
5 
6 #include "hecmw_repart.h"
7 
find_new_v8(int new_v8[24])8 void find_new_v8(int new_v8[24]) {
9   new_v8[0]         = 1;
10   new_v8[1]         = 3;
11   new_v8[2]         = 4;
12   new_v8[1 * 3]     = 0;
13   new_v8[1 * 3 + 1] = 2;
14   new_v8[1 * 3 + 2] = 5;
15   new_v8[2 * 3]     = 1;
16   new_v8[2 * 3 + 1] = 3;
17   new_v8[2 * 3 + 2] = 6;
18   new_v8[3 * 3]     = 0;
19   new_v8[3 * 3 + 1] = 2;
20   new_v8[3 * 3 + 2] = 7;
21   new_v8[4 * 3]     = 0;
22   new_v8[4 * 3 + 1] = 5;
23   new_v8[4 * 3 + 2] = 7;
24   new_v8[5 * 3]     = 1;
25   new_v8[5 * 3 + 1] = 4;
26   new_v8[5 * 3 + 2] = 6;
27   new_v8[6 * 3]     = 2;
28   new_v8[6 * 3 + 1] = 5;
29   new_v8[6 * 3 + 2] = 7;
30   new_v8[7 * 3]     = 3;
31   new_v8[7 * 3 + 1] = 4;
32   new_v8[7 * 3 + 2] = 6;
33   return;
34 }
35 
find_new_v6(int new_v6[18])36 void find_new_v6(int new_v6[18]) {
37   new_v6[0]         = 1;
38   new_v6[1]         = 2;
39   new_v6[2]         = 3;
40   new_v6[1 * 3]     = 0;
41   new_v6[1 * 3 + 1] = 2;
42   new_v6[1 * 3 + 2] = 4;
43   new_v6[2 * 3]     = 0;
44   new_v6[2 * 3 + 1] = 1;
45   new_v6[2 * 3 + 2] = 5;
46   new_v6[3 * 3]     = 0;
47   new_v6[3 * 3 + 1] = 4;
48   new_v6[3 * 3 + 2] = 5;
49   new_v6[4 * 3]     = 1;
50   new_v6[4 * 3 + 1] = 3;
51   new_v6[4 * 3 + 2] = 5;
52   new_v6[5 * 3]     = 2;
53   new_v6[5 * 3 + 1] = 3;
54   new_v6[5 * 3 + 2] = 4;
55   return;
56 }
57 
find_new_v4(int new_v4[12])58 void find_new_v4(int new_v4[12]) {
59   new_v4[0]         = 1;
60   new_v4[1]         = 2;
61   new_v4[2]         = 3;
62   new_v4[1 * 3]     = 0;
63   new_v4[1 * 3 + 1] = 2;
64   new_v4[1 * 3 + 2] = 3;
65   new_v4[2 * 3]     = 0;
66   new_v4[2 * 3 + 1] = 1;
67   new_v4[2 * 3 + 2] = 3;
68   new_v4[3 * 3]     = 0;
69   new_v4[3 * 3 + 1] = 1;
70   new_v4[3 * 3 + 2] = 2;
71   return;
72 }
73 
add8_adj_link(Adj_find * adj_link,int id_elem,struct hecmwST_local_mesh * mesh,int new_v8[24])74 void add8_adj_link(Adj_find *adj_link, int id_elem,
75                    struct hecmwST_local_mesh *mesh, int new_v8[24]) {
76   Adj_find *p1, *p2;
77   int i, j, k, m;
78   int new_v, id_node, flag_hit;
79   int ncon;
80 
81   ncon = mesh->elem_node_index[id_elem + 1] - mesh->elem_node_index[id_elem];
82   if (ncon != 8)
83     HECMW_dlb_print_exit(
84         "The type of element is conflict with its index: data error\n");
85   for (j = mesh->elem_node_index[id_elem];
86        j < mesh->elem_node_index[id_elem + 1]; j++) {
87     id_node = mesh->elem_node_item[j] - 1;
88     if ((id_node > mesh->n_node) || (id_node < 0))
89       HECMW_dlb_print_exit("There is something wrong in index_elem\n");
90     if (id_node < mesh->nn_internal) {
91       for (k = 0; k < 3; k++) {
92         new_v = mesh->elem_node_item
93                     [mesh->elem_node_index[id_elem] +
94                      new_v8[(j - mesh->elem_node_index[id_elem]) * 3 + k]] -
95                 1;
96         flag_hit = 0;
97         p1       = adj_link[id_node].next_vertex;
98         for (m = 0; m < adj_link[id_node].vertex_num; m++) {
99           if (new_v == p1->vertex_num) {
100             flag_hit = 1;
101             break;
102           }
103           p1 = p1->next_vertex;
104         }
105         if (flag_hit == 0) { /* adding the vertex new_v */
106           p1 = (Adj_find *)malloc(sizeof(Adj_find));
107           if (p1 == NULL) {
108             fprintf(stderr, "There is no enough memory for p1 in adj_link\n");
109             exit(0);
110           }
111           p2 = adj_link[id_node].next_vertex;
112           adj_link[id_node].vertex_num++;
113           adj_link[id_node].next_vertex = p1;
114           p1->next_vertex               = p2;
115           p1->vertex_num                = new_v;
116         }
117       }
118     }
119   }
120   return;
121 }
122 
add6_adj_link(Adj_find * adj_link,int id_elem,struct hecmwST_local_mesh * mesh,int new_v6[18])123 void add6_adj_link(Adj_find *adj_link, int id_elem,
124                    struct hecmwST_local_mesh *mesh, int new_v6[18]) {
125   Adj_find *p1, *p2;
126   int i, j, k, m;
127   int new_v, id_node, flag_hit;
128   int ncon;
129 
130   ncon = mesh->elem_node_index[id_elem + 1] - mesh->elem_node_index[id_elem];
131   if (ncon != 6)
132     HECMW_dlb_print_exit(
133         "The type of element is conflict with its index: data error\n");
134   for (j = mesh->elem_node_index[id_elem];
135        j < mesh->elem_node_index[id_elem + 1]; j++) {
136     id_node = mesh->elem_node_item[j] - 1;
137     if ((id_node >= mesh->n_node) || (id_node < 0))
138       HECMW_dlb_print_exit("There is something wrong in index_elem\n");
139     if (id_node < mesh->nn_internal) {
140       for (k = 0; k < 3; k++) {
141         new_v = mesh->elem_node_item
142                     [mesh->elem_node_index[id_elem] +
143                      new_v6[(j - mesh->elem_node_index[id_elem]) * 3 + k]] -
144                 1;
145         flag_hit = 0;
146         p1       = adj_link[id_node].next_vertex;
147         for (m = 0; m < adj_link[id_node].vertex_num; m++) {
148           if (new_v == p1->vertex_num) {
149             flag_hit = 1;
150             break;
151           }
152           p1 = p1->next_vertex;
153         }
154         if (flag_hit == 0) { /* adding the vertex new_v */
155           p1 = (Adj_find *)malloc(sizeof(Adj_find));
156           if (p1 == NULL) {
157             fprintf(stderr, "There is no enough memory for p1 in adj_link\n");
158             exit(0);
159           }
160           p2 = adj_link[id_node].next_vertex;
161           adj_link[id_node].vertex_num++;
162           adj_link[id_node].next_vertex = p1;
163           p1->next_vertex               = p2;
164           p1->vertex_num                = new_v;
165         }
166       }
167     }
168   }
169   return;
170 }
171 
add4_adj_link(Adj_find * adj_link,int id_elem,struct hecmwST_local_mesh * mesh,int new_v4[12])172 void add4_adj_link(Adj_find *adj_link, int id_elem,
173                    struct hecmwST_local_mesh *mesh, int new_v4[12]) {
174   Adj_find *p1, *p2;
175   int i, j, k, m;
176   int new_v, id_node, flag_hit;
177   int ncon;
178 
179   ncon = mesh->elem_node_index[id_elem + 1] - mesh->elem_node_index[id_elem];
180   if (ncon != 4)
181     HECMW_dlb_print_exit(
182         "The type of element is conflict with its index: data error\n");
183   for (j = mesh->elem_node_index[id_elem];
184        j < mesh->elem_node_index[id_elem + 1]; j++) {
185     id_node = mesh->elem_node_item[j] - 1;
186     if ((id_node >= mesh->n_node) || (id_node < 0))
187       HECMW_dlb_print_exit("There is something wrong in index_elem\n");
188     if (id_node < mesh->nn_internal) {
189       for (k = 0; k < 3; k++) {
190         new_v = mesh->elem_node_item
191                     [mesh->elem_node_index[id_elem] +
192                      new_v4[(j - mesh->elem_node_index[id_elem]) * 3 + k]] -
193                 1;
194         flag_hit = 0;
195         p1       = adj_link[id_node].next_vertex;
196         for (m = 0; m < adj_link[id_node].vertex_num; m++) {
197           if (new_v == p1->vertex_num) {
198             flag_hit = 1;
199             break;
200           }
201           p1 = p1->next_vertex;
202         }
203         if (flag_hit == 0) { /* adding the vertex new_v */
204           p1 = (Adj_find *)malloc(sizeof(Adj_find));
205           if (p1 == NULL) HECMW_dlb_memory_exit("Adj_find: p1");
206           p2 = adj_link[id_node].next_vertex;
207           adj_link[id_node].vertex_num++;
208           adj_link[id_node].next_vertex = p1;
209           p1->next_vertex               = p2;
210           p1->vertex_num                = new_v;
211         }
212       }
213     }
214   }
215   return;
216 }
217 
adj_link_free(Adj_find * adj_link,int num)218 void adj_link_free(Adj_find *adj_link, int num) {
219   Adj_find *p1, *p2;
220   int i, j;
221   for (i = 0; i < num; i++) {
222     p1 = adj_link[i].next_vertex;
223     for (j = 0; j < adj_link[i].vertex_num; j++) {
224       p2 = p1;
225       p1 = p1->next_vertex;
226       free(p2);
227     }
228   }
229   free(adj_link);
230   return;
231 }
232 
mesh2graph(struct hecmwST_local_mesh * mesh,GraphType * graph,Control_para * ctl_para,int stat_para[NUM_CONTROL_PARAS],Result_part * result,HECMW_Comm repart_comm)233 void mesh2graph(struct hecmwST_local_mesh *mesh, GraphType *graph,
234                 Control_para *ctl_para, int stat_para[NUM_CONTROL_PARAS],
235                 Result_part *result, HECMW_Comm repart_comm) {
236   int i, j, k, m;
237   int mynode, pesize;
238   Adj_find *adj_link;
239   Adj_find *p1, *p2;
240   int new_v8[3 * 8], new_v4[3 * 4], new_v6[3 * 6];
241   int nvtxs = 0, nedges = 0, global_num_node = 0;
242 
243   int readew = -1, readvw = -1, dummy, edge;
244   int *vtxdist, *xadj, *adjncy, *vwgts, *adjwgts;
245   int wgtflag, numflag, ncon, nparts, edgecut, options[4];
246   float *tpwgts, *ubvec, itr;
247   HECMW_Status stat;
248   int *tmp_index, tmp_nvtxs, tmp_sum, tmp_pe, tmp_lid;
249   FILE *fp_test, *fp_wgts;
250   char test_file[128];
251   float *xyz;
252   int ndim;
253   int tmp_int;
254   int flag_count;
255 
256   HECMW_Comm_rank(repart_comm, &mynode);
257   HECMW_Comm_size(repart_comm, &pesize);
258   /*
259      mynode=mesh->my_rank;
260      pesize=mesh->PEtotMESH;
261      */
262   /*
263      fprintf(stderr, "In PE %d  pesize=%d\n", mynode, pesize);
264       fprintf(stderr, "wgtflag=%d \n", ctl_para->wgtflag);
265       fprintf(stderr, "ncon=%d\n", ctl_para->num_repartition);
266   */
267   if (mynode == 0)
268     fprintf(stderr,
269             "Start transform original mesh data into graph structure of "
270             "ParMetis\n");
271 
272   if (pesize > 1)
273     HECMW_Allreduce(&mesh->nn_internal, &global_num_node, 1, HECMW_INT,
274                     HECMW_SUM, repart_comm);
275   else
276     global_num_node = mesh->nn_internal;
277   /*
278           fprintf(stderr, "the global node number is %d\n", global_num_node);
279   */
280   result->t_node = global_num_node;
281   nvtxs          = mesh->nn_internal;
282   graph->vtxdist = (int *)calloc((pesize + 1), sizeof(int));
283   if (graph->vtxdist == NULL) HECMW_dlb_memory_exit("graph->vtxdist");
284   if (mynode == 0) {
285     graph->vtxdist[0] = 0;
286     graph->vtxdist[1] = nvtxs;
287     tmp_sum           = nvtxs;
288     for (i = 1; i < pesize; i++) {
289       HECMW_Recv(&tmp_nvtxs, 1, HECMW_INT, i, HECMW_ANY_TAG, repart_comm,
290                  &stat);
291       tmp_sum += tmp_nvtxs;
292       graph->vtxdist[i + 1] = tmp_sum;
293     }
294     for (i = 1; i < pesize; i++)
295       HECMW_Send(graph->vtxdist, pesize + 1, HECMW_INT, i, 0, repart_comm);
296   } else {
297     HECMW_Send(&nvtxs, 1, HECMW_INT, 0, 0, repart_comm);
298     HECMW_Recv(graph->vtxdist, pesize + 1, HECMW_INT, 0, HECMW_ANY_TAG,
299                repart_comm, &stat);
300   }
301   /*
302           if(mynode==0) {
303                   for(i=0;i<pesize+1;i++)
304                           fprintf(stderr, "vtxdist=%d ", graph->vtxdist[i]);
305                   fprintf(stderr, "\n");
306           }
307   */
308 
309   adj_link = (Adj_find *)calloc(mesh->nn_internal, sizeof(Adj_find));
310   if (adj_link == NULL) HECMW_dlb_memory_exit("adj_link");
311   for (i = 0; i < mesh->nn_internal; i++) adj_link[i].vertex_num = 0;
312   find_new_v8(new_v8);
313   find_new_v6(new_v6);
314   find_new_v4(new_v4);
315   for (i = 0; i < mesh->n_elem; i++) {
316     flag_count = 1;
317     if (mesh->hecmw_flag_adapt == 1) {
318       if (mesh->adapt_type[i] != 0) flag_count = 0;
319     }
320     if (flag_count == 1) {
321       if (mesh->elem_type[i] == 341)
322         add4_adj_link(adj_link, i, mesh, new_v4);
323       else if (mesh->elem_type[i] == 351)
324         add6_adj_link(adj_link, i, mesh, new_v6);
325       else if (mesh->elem_type[i] == 361)
326         add8_adj_link(adj_link, i, mesh, new_v8);
327     }
328   }
329   for (i      = 0; i < mesh->nn_internal; i++) nedges += adj_link[i].vertex_num;
330   graph->xadj = (int *)calloc(nvtxs + 1, sizeof(int));
331   graph->adjncy = (int *)calloc(nedges, sizeof(int));
332   if ((graph->xadj == NULL) || (graph->adjncy == NULL))
333     HECMW_dlb_memory_exit("graph: xadj and adjncy");
334   m              = 0;
335   graph->xadj[0] = 0;
336   for (i = 0; i < mesh->nn_internal; i++) {
337     graph->xadj[i + 1] = m + adj_link[i].vertex_num;
338     p1                 = adj_link[i].next_vertex;
339     for (j = 0; j < adj_link[i].vertex_num; j++) {
340       if (p1->vertex_num < mesh->nn_internal)
341         graph->adjncy[m + j] = graph->vtxdist[mynode] + p1->vertex_num;
342       else {
343         tmp_pe               = mesh->node_ID[p1->vertex_num * 2 + 1];
344         tmp_lid              = mesh->node_ID[p1->vertex_num * 2] - 1;
345         graph->adjncy[m + j] = graph->vtxdist[tmp_pe] + tmp_lid;
346       }
347       p1 = p1->next_vertex;
348     }
349     m += adj_link[i].vertex_num;
350   }
351   adj_link_free(adj_link, mesh->nn_internal);
352   /*
353           sprintf(test_file, "test.%d", mynode);
354           fp_test=fopen(test_file, "w");
355           tmp_int=0;
356       for(i=0;i<mesh->n_internal;i++) {
357                   fprintf(fp_test, "%d  %d\n", i+1,
358      graph->xadj[i+1]-graph->xadj[i]);
359                   if((graph->xadj[i+1]-graph->xadj[i])==27) {
360                           tmp_int++;
361                           fprintf(stderr, "the num of 27 edges is in PE %d
362      nodeid is %d\n", mynode, i+1);
363                   }
364                   for(j=graph->xadj[i];j<graph->xadj[i+1];j++)
365                           fprintf(fp_test, "%d  ", graph->adjncy[j]+1);
366                   fprintf(fp_test, "\n");
367           }
368                   fprintf(stderr, "the num of 27 edges is %d in PE %d\n",
369      tmp_int, mynode);
370           fclose(fp_test);
371           */
372   graph->gnvtxs = global_num_node;
373   graph->ncon   = 0;
374   graph->nobj   = 0;
375   wgtflag       = ctl_para->wgtflag;
376   numflag       = 0;
377   ncon          = ctl_para->num_criteria;
378   nparts        = ctl_para->num_repartition;
379   /*	graph->vwgt=(int *)calloc(nvtxs, sizeof(int));
380           if(graph->vwgt==NULL) {
381                   fprintf(stderr, "There is no enough memory for vwgt\n");
382           HECMW_Finalize();
383                   exit(0);
384           }
385           for(i=0;i<nvtxs;i++)
386                   graph->vwgt[i]=1;
387   */
388   /*	tpwgts=(float *)calloc(pesize, sizeof(float));
389           if(tpwgts==NULL) {
390                   fprintf(stderr, "There is no enough memory for tpwgts\n");
391           HECMW_Finalize();
392                   exit(0);
393           }
394       for(i=0;i<pesize;i++)
395                   tpwgts[i]=ctl_para;
396 
397           ubvec=(float *)calloc(ncon, sizeof(float));
398           if(ubvec==NULL)
399                   HECMW_dlb_memory_exit("ubvec");
400           for(i=0;i<ncon;i++)
401                   ubvec[i]=1.05;
402           */
403   options[0]   = 1;
404   options[1]   = 3;
405   options[2]   = 1;
406   options[3]   = 1;
407   edgecut      = 0;
408   result->part = (int *)calloc(nvtxs, sizeof(int));
409   if (result->part == NULL) HECMW_dlb_memory_exit("result: part");
410 
411   /*	xyz=(float *)calloc(mesh->n_internal*3, sizeof(float));
412           for(i=0;i<mesh->n_internal;i++) {
413                   xyz[i*3]=(float)mesh->node[i];
414                   xyz[i*3+1]=(float)mesh->node[i+mesh->n_node];
415                   xyz[i*3+2]=(float)mesh->node[i+2*mesh->n_node];
416           }
417           ndim=3;
418       ParMETIS_V3_PartGeomKway(graph->vtxdist, graph->xadj, graph->adjncy, NULL,
419      NULL, &wgtflag,
420           &numflag, &ndim, xyz, &ncon, &nparts, tpwgts, ubvec, options,
421      &edgecut, result->part, &repart_comm);
422           result->edgecut=edgecut;
423   */
424   if (strncmp(ctl_para->adaptive_repartition, "off", 3) == 0) {
425     if (ctl_para->wgtflag == 0)
426       ParMETIS_V3_PartKway(graph->vtxdist, graph->xadj, graph->adjncy, NULL,
427                            NULL, &(ctl_para->wgtflag), &numflag,
428                            &(ctl_para->num_criteria),
429                            &(ctl_para->num_repartition), ctl_para->machine_wgt,
430                            ctl_para->balance_rate, options, &edgecut,
431                            result->part, &repart_comm);
432     else if ((stat_para[6] != 0) && (stat_para[7] == 0)) {
433       vwgts = (int *)calloc(mesh->nn_internal, sizeof(int));
434       if (vwgts == NULL) HECMW_dlb_memory_exit("vwgts");
435       fp_wgts = fopen(ctl_para->vwgt_filename, "r");
436       if (fp_wgts == NULL) {
437         fprintf(stderr, "control file wrong: vwgt_filename\n");
438         exit(0);
439       }
440       for (i = 0; i < mesh->nn_internal; i++) fscanf(fp_wgts, "%d", &vwgts[i]);
441       fclose(fp_wgts);
442       ParMETIS_V3_PartKway(graph->vtxdist, graph->xadj, graph->adjncy, vwgts,
443                            NULL, &(ctl_para->wgtflag), &numflag,
444                            &(ctl_para->num_criteria),
445                            &(ctl_para->num_repartition), ctl_para->machine_wgt,
446                            ctl_para->balance_rate, options, &edgecut,
447                            result->part, &repart_comm);
448       free(vwgts);
449     } else if ((stat_para[6] == 0) && (stat_para[7] != 0)) {
450       adjwgts = (int *)calloc(graph->xadj[mesh->nn_internal], sizeof(int));
451       if (adjwgts == NULL) HECMW_dlb_memory_exit("adjwgts");
452       fp_wgts = fopen(ctl_para->adjwgt_filename, "r");
453       if (fp_wgts == NULL) {
454         fprintf(stderr, "control file wrong: adjwgt_filename\n");
455         exit(0);
456       }
457       for (i = 0; i < graph->xadj[mesh->nn_internal]; i++)
458         fscanf(fp_wgts, "%d", &adjwgts[i]);
459       fclose(fp_wgts);
460       ParMETIS_V3_PartKway(graph->vtxdist, graph->xadj, graph->adjncy, NULL,
461                            adjwgts, &(ctl_para->wgtflag), &numflag,
462                            &(ctl_para->num_criteria),
463                            &(ctl_para->num_repartition), ctl_para->machine_wgt,
464                            ctl_para->balance_rate, options, &edgecut,
465                            result->part, &repart_comm);
466       free(adjwgts);
467     } else if ((stat_para[6] != 0) && (stat_para[7] != 0)) {
468       vwgts = (int *)calloc(mesh->nn_internal, sizeof(int));
469       if (vwgts == NULL) HECMW_dlb_memory_exit("vwgts");
470       fp_wgts = fopen(ctl_para->vwgt_filename, "r");
471       if (fp_wgts == NULL) {
472         fprintf(stderr, "control file wrong: vwgt_filename\n");
473         exit(0);
474       }
475       for (i = 0; i < mesh->nn_internal; i++) fscanf(fp_wgts, "%d", &vwgts[i]);
476       fclose(fp_wgts);
477       adjwgts = (int *)calloc(graph->xadj[mesh->nn_internal], sizeof(int));
478       if (adjwgts == NULL) HECMW_dlb_memory_exit("adjwgts");
479       fp_wgts = fopen(ctl_para->adjwgt_filename, "r");
480       if (fp_wgts == NULL) {
481         fprintf(stderr, "control file wrong: adjwgt_filename\n");
482         exit(0);
483       }
484       for (i = 0; i < graph->xadj[mesh->nn_internal]; i++)
485         fscanf(fp_wgts, "%d", &adjwgts[i]);
486       fclose(fp_wgts);
487       ParMETIS_V3_PartKway(graph->vtxdist, graph->xadj, graph->adjncy, vwgts,
488                            adjwgts, &(ctl_para->wgtflag), &numflag,
489                            &(ctl_para->num_criteria),
490                            &(ctl_para->num_repartition), ctl_para->machine_wgt,
491                            ctl_para->balance_rate, options, &edgecut,
492                            result->part, &repart_comm);
493       free(adjwgts);
494       free(vwgts);
495     }
496 
497     result->edgecut = edgecut;
498   } else if (strncmp(ctl_para->adaptive_repartition, "on", 2) == 0) {
499     if (ctl_para->wgtflag == 0)
500       ParMETIS_V3_AdaptiveRepart(
501           graph->vtxdist, graph->xadj, graph->adjncy, NULL, NULL, NULL,
502           &(ctl_para->wgtflag), &numflag, &(ctl_para->num_criteria),
503           &(ctl_para->num_repartition), ctl_para->machine_wgt,
504           ctl_para->balance_rate, &(ctl_para->itr_rate), options, &edgecut,
505           result->part, &repart_comm);
506 
507     else if ((stat_para[6] != 0) && (stat_para[7] == 0)) {
508       vwgts = (int *)calloc(mesh->nn_internal, sizeof(int));
509       if (vwgts == NULL) HECMW_dlb_memory_exit("vwgts");
510       fp_wgts = fopen(ctl_para->vwgt_filename, "r");
511       if (fp_wgts == NULL) {
512         fprintf(stderr, "control file wrong: vwgt_filename\n");
513         exit(0);
514       }
515       for (i = 0; i < mesh->nn_internal; i++) fscanf(fp_wgts, "%d", &vwgts[i]);
516       fclose(fp_wgts);
517       ParMETIS_V3_AdaptiveRepart(
518           graph->vtxdist, graph->xadj, graph->adjncy, vwgts, NULL, NULL,
519           &(ctl_para->wgtflag), &numflag, &(ctl_para->num_criteria),
520           &(ctl_para->num_repartition), ctl_para->machine_wgt,
521           ctl_para->balance_rate, &(ctl_para->itr_rate), options, &edgecut,
522           result->part, &repart_comm);
523       free(vwgts);
524     } else if ((stat_para[6] == 0) && (stat_para[7] != 0)) {
525       adjwgts = (int *)calloc(graph->xadj[mesh->nn_internal], sizeof(int));
526       if (adjwgts == NULL) HECMW_dlb_memory_exit("adjwgts");
527       fp_wgts = fopen(ctl_para->adjwgt_filename, "r");
528       if (fp_wgts == NULL) {
529         fprintf(stderr, "control file wrong: adjwgt_filename\n");
530         exit(0);
531       }
532       for (i = 0; i < graph->xadj[mesh->nn_internal]; i++)
533         fscanf(fp_wgts, "%d", &adjwgts[i]);
534       fclose(fp_wgts);
535       ParMETIS_V3_AdaptiveRepart(
536           graph->vtxdist, graph->xadj, graph->adjncy, NULL, NULL, adjwgts,
537           &(ctl_para->wgtflag), &numflag, &(ctl_para->num_criteria),
538           &(ctl_para->num_repartition), ctl_para->machine_wgt,
539           ctl_para->balance_rate, &(ctl_para->itr_rate), options, &edgecut,
540           result->part, &repart_comm);
541       free(adjwgts);
542     } else if ((stat_para[6] != 0) && (stat_para[7] != 0)) {
543       vwgts = (int *)calloc(mesh->nn_internal, sizeof(int));
544       if (vwgts == NULL) HECMW_dlb_memory_exit("vwgts");
545       fp_wgts = fopen(ctl_para->vwgt_filename, "r");
546       if (fp_wgts == NULL) {
547         fprintf(stderr, "control file wrong: vwgt_filename\n");
548         exit(0);
549       }
550       for (i = 0; i < mesh->nn_internal; i++) fscanf(fp_wgts, "%d", &vwgts[i]);
551       fclose(fp_wgts);
552       adjwgts = (int *)calloc(graph->xadj[mesh->nn_internal], sizeof(int));
553       if (adjwgts == NULL) HECMW_dlb_memory_exit("adjwgts");
554       fp_wgts = fopen(ctl_para->adjwgt_filename, "r");
555       if (fp_wgts == NULL) {
556         fprintf(stderr, "control file wrong: adjwgt_filename\n");
557         exit(0);
558       }
559       for (i = 0; i < graph->xadj[mesh->nn_internal]; i++)
560         fscanf(fp_wgts, "%d", &adjwgts[i]);
561       fclose(fp_wgts);
562       ParMETIS_V3_AdaptiveRepart(
563           graph->vtxdist, graph->xadj, graph->adjncy, vwgts, NULL, adjwgts,
564           &(ctl_para->wgtflag), &numflag, &(ctl_para->num_criteria),
565           &(ctl_para->num_repartition), ctl_para->machine_wgt,
566           ctl_para->balance_rate, &(ctl_para->itr_rate), options, &edgecut,
567           result->part, &repart_comm);
568       free(adjwgts);
569       free(vwgts);
570     }
571 
572     result->edgecut = edgecut;
573   }
574   /* write test file */
575   /*    for(i=0;i<mesh->n_internal;i++) {
576                   fprintf(fp_test, "%d \n", result->part[i]);
577           }
578 
579           fclose(fp_test);
580   */
581   free(graph->xadj);
582   free(graph->adjncy);
583 
584   return;
585 }
586