FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
hecmw_dist_refine.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 <errno.h>
9 #include <string.h>
10 #include "hecmw_struct.h"
11 #include "hecmw_util.h"
12 #include "hecmw_common_define.h"
13 #include "hecmw_etype.h"
14 #include "hecmw_bit_array.h"
15 #include "hecmw_set_int.h"
16 #include "hecmw_varray_int.h"
17 #include "hecmw_dist_alloc.h"
18 #include "hecmw_dist_free.h"
19 #include "hecmw_dist_refine.h"
20 
21 #ifdef HECMW_WITH_REFINER
22 
23 #include "rcapRefiner.h"
24 
25 /*============================================================================*/
26 /* */
27 /* convert elem_node_item */
28 /* */
29 /*============================================================================*/
30 static const int *get_enode_h2r(int etype, int *ierror) {
31  /* tetra, prism, hexa: no need to convert */
32  static const int enode_pyr_h2r[13] = {4, 0, 1, 2, 3, 9, 10,
33  11, 12, 5, 6, 7, 8};
34  static const int enode_rod2_h2r[3] = {0, 2, 1};
35  const int *enode_h2r;
36 
37  *ierror = 0;
38 
39  if (HECMW_is_etype_link(etype)) return NULL;
40  if (HECMW_is_etype_truss(etype)) return NULL;
41 
42  switch (etype) {
43  case HECMW_ETYPE_ROD1:
44  /* case HECMW_ETYPE_ROD31: */
45  case HECMW_ETYPE_TRI1:
46  case HECMW_ETYPE_TRI2:
47  case HECMW_ETYPE_QUA1:
48  case HECMW_ETYPE_QUA2:
49  case HECMW_ETYPE_TET1:
50  case HECMW_ETYPE_TET1_4:
51  case HECMW_ETYPE_TET2:
52  case HECMW_ETYPE_PRI1:
53  case HECMW_ETYPE_PRI2:
54  case HECMW_ETYPE_HEX1:
55  case HECMW_ETYPE_HEX1_4:
56  case HECMW_ETYPE_HEX2:
57  case HECMW_ETYPE_BEM1:
58  case HECMW_ETYPE_BEM3:
59  case HECMW_ETYPE_SHT1:
60  case HECMW_ETYPE_SHT2:
61  case HECMW_ETYPE_SHT6:
62  case HECMW_ETYPE_SHQ1:
63  case HECMW_ETYPE_SHQ2:
64  case HECMW_ETYPE_SHQ8:
65  case HECMW_ETYPE_PTT1:
66  case HECMW_ETYPE_PTT2:
67  case HECMW_ETYPE_PTQ1:
68  case HECMW_ETYPE_PTQ2:
69  enode_h2r = NULL;
70  break;
71  case HECMW_ETYPE_PYR1:
72  case HECMW_ETYPE_PYR2:
73  enode_h2r = enode_pyr_h2r;
74  break;
75  case HECMW_ETYPE_ROD2:
76  case HECMW_ETYPE_BEM2:
77  enode_h2r = enode_rod2_h2r;
78  break;
79  default:
81  "Element type %d not supported for rerinement.\n", etype);
82  *ierror = 1;
83  enode_h2r = NULL;
84  break;
85  }
86  return enode_h2r;
87 }
88 
89 static const int *get_enode_r2h(int etype, int *ierror) {
90  /* tetra, prism, hexa: no need to convert */
91  static const int enode_pyr_r2h[13] = {1, 2, 3, 4, 0, 9, 10,
92  11, 12, 5, 6, 7, 8};
93  static const int enode_rod2_r2h[3] = {0, 2, 1};
94  const int *enode_r2h;
95 
96  *ierror = 0;
97 
98  if (HECMW_is_etype_link(etype)) return NULL;
99  if (HECMW_is_etype_truss(etype)) return NULL;
100 
101  switch (etype) {
102  case HECMW_ETYPE_ROD1:
103  case HECMW_ETYPE_ROD31:
104  case HECMW_ETYPE_TRI1:
105  case HECMW_ETYPE_TRI2:
106  case HECMW_ETYPE_QUA1:
107  case HECMW_ETYPE_QUA2:
108  case HECMW_ETYPE_TET1:
109  case HECMW_ETYPE_TET1_4:
110  case HECMW_ETYPE_TET2:
111  case HECMW_ETYPE_PRI1:
112  case HECMW_ETYPE_PRI2:
113  case HECMW_ETYPE_HEX1:
114  case HECMW_ETYPE_HEX1_4:
115  case HECMW_ETYPE_HEX2:
116  case HECMW_ETYPE_BEM1:
117  case HECMW_ETYPE_BEM3:
118  case HECMW_ETYPE_SHT1:
119  case HECMW_ETYPE_SHT2:
120  case HECMW_ETYPE_SHT6:
121  case HECMW_ETYPE_SHQ1:
122  case HECMW_ETYPE_SHQ2:
123  case HECMW_ETYPE_SHQ8:
124  case HECMW_ETYPE_PTT1:
125  case HECMW_ETYPE_PTT2:
126  case HECMW_ETYPE_PTQ1:
127  case HECMW_ETYPE_PTQ2:
128  enode_r2h = NULL;
129  break;
130  case HECMW_ETYPE_PYR1:
131  case HECMW_ETYPE_PYR2:
132  enode_r2h = enode_pyr_r2h;
133  break;
134  case HECMW_ETYPE_ROD2:
135  case HECMW_ETYPE_BEM2:
136  enode_r2h = enode_rod2_r2h;
137  break;
138  default:
140  "Element type %d not supported for refinement.\n", etype);
141  *ierror = 1;
142  enode_r2h = NULL;
143  }
144  return enode_r2h;
145 }
146 
147 static int elem_node_item_hecmw2rcap(struct hecmwST_local_mesh *mesh) {
148  int i, j;
149  int etype, ierror;
150  const int *enode_h2r;
151  int *enode;
152  int nn, istart, iend;
153  int temp_enode[HECMW_MAX_NODE_MAX];
154 
155  for (i = 0; i < mesh->n_elem_type; i++) {
156  etype = mesh->elem_type_item[i];
157  enode_h2r = get_enode_h2r(etype, &ierror);
158  if (ierror) return HECMW_ERROR;
159  if (enode_h2r == NULL) continue;
160  nn = HECMW_get_max_node(etype);
161  istart = mesh->elem_type_index[i];
162  iend = mesh->elem_type_index[i + 1];
163  for (j = istart; j < iend; j++) {
164  enode = mesh->elem_node_item + mesh->elem_node_index[i];
165  for (j = 0; j < nn; j++) temp_enode[j] = enode[enode_h2r[j]];
166  for (j = 0; j < nn; j++) enode[j] = temp_enode[j];
167  }
168  }
169  return HECMW_SUCCESS;
170 }
171 
172 static int elem_node_item_rcap2hecmw(struct hecmwST_local_mesh *mesh) {
173  int i, j;
174  int etype, ierror;
175  const int *enode_r2h;
176  int *enode;
177  int nn, istart, iend;
178  int temp_enode[HECMW_MAX_NODE_MAX];
179 
180  for (i = 0; i < mesh->n_elem_type; i++) {
181  etype = mesh->elem_type_item[i];
182  enode_r2h = get_enode_r2h(etype, &ierror);
183  if (ierror) return HECMW_ERROR;
184  if (enode_r2h == NULL) continue;
185  nn = HECMW_get_max_node(etype);
186  istart = mesh->elem_type_index[i];
187  iend = mesh->elem_type_index[i + 1];
188  for (j = istart; j < iend; j++) {
189  enode = mesh->elem_node_item + mesh->elem_node_index[i];
190  for (j = 0; j < nn; j++) temp_enode[j] = enode[enode_r2h[j]];
191  for (j = 0; j < nn; j++) enode[j] = temp_enode[j];
192  }
193  }
194  return HECMW_SUCCESS;
195 }
196 
197 /*============================================================================*/
198 /* */
199 /* convert surface IDs */
200 /* */
201 /*============================================================================*/
202 static const int *get_sid_h2r(int etype, int *ierror) {
203  /* HECMW to RCAP */
204  /*
205  static const int sid_tri_h2r[4] = {-1, 0, 1, 2};
206  static const int sid_qua_h2r[5] = {-1, 3, 1, 0, 2};
207  static const int sid_tet_h2r[5] = {-1, 0, 1, 2, 3};
208  static const int sid_pri_h2r[6] = {-1, 3, 4, 2, 0, 1};
209  static const int sid_hex_h2r[7] = {-1, 5, 3, 2, 4, 0, 1};
210  static const int sid_pyr_h2r[6] = {-1, 3, 1, 0, 2, 4};
211  */
212  /* FSTR to RCAP*/
213  static const int sid_tri_h2r[4] = {-1, 2, 0, 1};
214  static const int sid_qua_h2r[5] = {-1, 0, 1, 2, 3};
215  static const int sid_tet_h2r[5] = {-1, 3, 2, 0, 1};
216  static const int sid_pri_h2r[6] = {-1, 0, 1, 2, 3, 4};
217  static const int sid_hex_h2r[7] = {-1, 0, 1, 2, 3, 4, 5};
218  static const int sid_pyr_h2r[6] = {-1, 3, 1,
219  0, 2, 4}; /* TEMPORARY: same as HECMW */
220 
221  const int *sid_h2r;
222  *ierror = 0;
223  switch (etype) {
224  case HECMW_ETYPE_TRI1:
225  case HECMW_ETYPE_TRI2:
226  sid_h2r = sid_tri_h2r;
227  break;
228  case HECMW_ETYPE_QUA1:
229  case HECMW_ETYPE_QUA2:
230  sid_h2r = sid_qua_h2r;
231  break;
232  case HECMW_ETYPE_TET1:
233  case HECMW_ETYPE_TET1_4:
234  case HECMW_ETYPE_TET2:
235  sid_h2r = sid_tet_h2r;
236  break;
237  case HECMW_ETYPE_PRI1:
238  case HECMW_ETYPE_PRI2:
239  sid_h2r = sid_pri_h2r;
240  break;
241  case HECMW_ETYPE_HEX1:
242  case HECMW_ETYPE_HEX1_4:
243  case HECMW_ETYPE_HEX2:
244  sid_h2r = sid_hex_h2r;
245  break;
246  case HECMW_ETYPE_PYR1:
247  case HECMW_ETYPE_PYR2:
248  sid_h2r = sid_pyr_h2r;
249  break;
250  case HECMW_ETYPE_SHT1:
251  case HECMW_ETYPE_SHT2:
252  case HECMW_ETYPE_SHT6:
253  case HECMW_ETYPE_SHQ1:
254  case HECMW_ETYPE_SHQ2:
255  case HECMW_ETYPE_SHQ8:
256  case HECMW_ETYPE_PTT1:
257  case HECMW_ETYPE_PTT2:
258  case HECMW_ETYPE_PTQ1:
259  case HECMW_ETYPE_PTQ2:
260  sid_h2r = NULL;
261  break;
262  default:
264  "Element type %d not supported for refinement.\n", etype);
265  *ierror = 1;
266  sid_h2r = NULL;
267  }
268  return sid_h2r;
269 }
270 
271 static const int *get_sid_r2h(int etype, int *ierror) {
272  /* RCAP to HECMW */
273  /*
274  static const int sid_tri_r2h[3] = {1, 2, 3};
275  static const int sid_qua_r2h[4] = {3, 2, 4, 1};
276  static const int sid_tet_r2h[4] = {1, 2, 3, 4};
277  static const int sid_pri_r2h[5] = {4, 5, 3, 1, 2};
278  static const int sid_hex_r2h[6] = {1, 2, 3, 4, 5, 6};
279  static const int sid_pyr_r2h[5] = {3, 2, 4, 1, 5};
280  */
281  /* RCAP to FSTR */
282  static const int sid_tri_r2h[3] = {2, 3, 1};
283  static const int sid_qua_r2h[4] = {1, 2, 3, 4};
284  static const int sid_tet_r2h[4] = {3, 4, 2, 1};
285  static const int sid_pri_r2h[5] = {1, 2, 3, 4, 5};
286  static const int sid_hex_r2h[6] = {1, 2, 3, 4, 5, 6};
287  static const int sid_pyr_r2h[5] = {3, 2, 4, 1,
288  5}; /* TEMPORARY: same as HECMW */
289 
290  const int *sid_r2h;
291  *ierror = 0;
292  switch (etype) {
293  case HECMW_ETYPE_TRI1:
294  case HECMW_ETYPE_TRI2:
295  sid_r2h = sid_tri_r2h;
296  break;
297  case HECMW_ETYPE_QUA1:
298  case HECMW_ETYPE_QUA2:
299  sid_r2h = sid_qua_r2h;
300  break;
301  case HECMW_ETYPE_TET1:
302  case HECMW_ETYPE_TET1_4:
303  case HECMW_ETYPE_TET2:
304  sid_r2h = sid_tet_r2h;
305  break;
306  case HECMW_ETYPE_PRI1:
307  case HECMW_ETYPE_PRI2:
308  sid_r2h = sid_pri_r2h;
309  break;
310  case HECMW_ETYPE_HEX1:
311  case HECMW_ETYPE_HEX1_4:
312  case HECMW_ETYPE_HEX2:
313  sid_r2h = sid_hex_r2h;
314  break;
315  case HECMW_ETYPE_PYR1:
316  case HECMW_ETYPE_PYR2:
317  sid_r2h = sid_pyr_r2h;
318  break;
319  case HECMW_ETYPE_SHT1:
320  case HECMW_ETYPE_SHT2:
321  case HECMW_ETYPE_SHT6:
322  case HECMW_ETYPE_SHQ1:
323  case HECMW_ETYPE_SHQ2:
324  case HECMW_ETYPE_SHQ8:
325  case HECMW_ETYPE_PTT1:
326  case HECMW_ETYPE_PTT2:
327  case HECMW_ETYPE_PTQ1:
328  case HECMW_ETYPE_PTQ2:
329  sid_r2h = NULL;
330  break;
331  default:
333  "Element type %d not supported for refinement.\n", etype);
334  *ierror = 1;
335  sid_r2h = NULL;
336  }
337  return sid_r2h;
338 }
339 
340 static int surf_ID_hecmw2rcap(struct hecmwST_local_mesh *mesh) {
341  struct hecmwST_surf_grp *grp = mesh->surf_group;
342  int i;
343 
344  if (grp->n_grp == 0) return HECMW_SUCCESS;
345 
346  for (i = 0; i < grp->grp_index[grp->n_grp]; i++) {
347  int eid = grp->grp_item[2 * i];
348  int *sid_p = &(grp->grp_item[2 * i + 1]);
349  const int *sid_h2r;
350  int ierror;
351 
352  HECMW_assert(0 < eid && eid <= mesh->n_elem_gross);
353 
354  sid_h2r = get_sid_h2r(mesh->elem_type[eid - 1], &ierror);
355  if (ierror) return HECMW_ERROR;
356  if (sid_h2r) *sid_p = sid_h2r[*sid_p];
357  }
358  return HECMW_SUCCESS;
359 }
360 
361 static int surf_ID_rcap2hecmw(struct hecmwST_local_mesh *mesh) {
362  struct hecmwST_surf_grp *grp = mesh->surf_group;
363  int i;
364 
365  if (grp->n_grp == 0) return HECMW_SUCCESS;
366 
367  for (i = 0; i < grp->grp_index[grp->n_grp]; i++) {
368  int eid = grp->grp_item[2 * i];
369  int *sid_p = &(grp->grp_item[2 * i + 1]);
370  const int *sid_r2h;
371  int ierror;
372 
373  HECMW_assert(0 < eid && eid <= mesh->n_elem_gross);
374 
375  sid_r2h = get_sid_r2h(mesh->elem_type[eid - 1], &ierror);
376  if (ierror) return HECMW_ERROR;
377  if (sid_r2h) *sid_p = sid_r2h[*sid_p];
378  }
379  return HECMW_SUCCESS;
380 }
381 
382 /*============================================================================*/
383 /* */
384 /* for models with multiple element types */
385 /* */
386 /*============================================================================*/
387 #define NDIV_SEG 2
388 #define NDIV_SURF 4
389 #define NDIV_BODY 8
390 #define NDIV_OTHER 1
391 #define NDIV_MAX 8
392 
393 static int get_elem_ndiv(int etype, int *ierror) {
394  int ndiv;
395  *ierror = 0;
396  if (HECMW_is_etype_truss(etype)) {
397  ndiv = NDIV_OTHER;
398  } else if (HECMW_is_etype_rod(etype) || HECMW_is_etype_beam(etype)) {
399  ndiv = NDIV_SEG;
400  } else if (HECMW_is_etype_surface(etype) || HECMW_is_etype_shell(etype)
401  || HECMW_is_etype_patch(etype)) {
402  ndiv = NDIV_SURF;
403  } else if (HECMW_is_etype_solid(etype)) {
404  ndiv = NDIV_BODY;
405  } else if (HECMW_is_etype_link(etype)) {
406  ndiv = NDIV_OTHER;
407  } else {
409  "Element type %d not supported for refinement.\n", etype);
410  *ierror = 1;
411  ndiv = NDIV_OTHER;
412  }
413  return ndiv;
414 }
415 
416 /*============================================================================*/
417 /* */
418 /* prepare, clear and terminate REVOCAP_Refiner */
419 /* */
420 /*============================================================================*/
421 static void register_node(struct hecmwST_local_mesh *mesh) {
422  HECMW_log(HECMW_LOG_DEBUG, "Original Node Count = %d\n", mesh->n_node_gross);
423 
424 #ifdef DEBUG_REFINER
425  HECMW_log(HECMW_LOG_DEBUG, "RCAP: calling rcapSetNode64(num=%d, coords, globalIds, NULL)\n", mesh->n_node_gross);
426  {
427  char fname[256];
428  FILE *fp_dump;
429  snprintf(fname, sizeof(fname), "dump_rcapSetNode64.%d", HECMW_comm_get_rank());
430  fp_dump = fopen(fname, "w");
431  if (fp_dump == NULL) {
432  fprintf(stderr, "Error: cannot open file %s\n", fname);
433  } else {
434  HECMW_log(HECMW_LOG_DEBUG, "RCAP: writing num, coords[0..3*num-1], globalIds[0..num-1] to %s\n", fname);
435  fwrite(&(mesh->n_node_gross), sizeof(int), 1, fp_dump);
436  fwrite(mesh->node, sizeof(double), 3*mesh->n_node_gross, fp_dump);
437  fwrite(mesh->global_node_ID, sizeof(int), mesh->n_node_gross, fp_dump);
438  fclose(fp_dump);
439  }
440  }
441 #endif
442  rcapSetNode64(mesh->n_node_gross, mesh->node, mesh->global_node_ID, NULL);
443 
444  HECMW_assert(rcapGetNodeCount() == mesh->n_node_gross);
445 }
446 
447 static void register_node_groups(struct hecmwST_node_grp *grp) {
448  int i;
449  char rcap_name[80];
450 
451  HECMW_assert(strcmp(grp->grp_name[0], "ALL") == 0);
452 
453  for (i = 1; i < grp->n_grp; i++) {
454  int start = grp->grp_index[i];
455  int num = grp->grp_index[i + 1] - start;
456  int *array = grp->grp_item + start;
457  snprintf(rcap_name, sizeof(rcap_name), "NG_%s", grp->grp_name[i]);
458 
459 #ifdef DEBUG_REFINER
460  HECMW_log(HECMW_LOG_DEBUG, "RCAP: calling rcapAppendNodeGroup(dataname=%s, num=%d, nodeArray)\n", rcap_name, num);
461  {
462  char fname[256];
463  FILE *fp_dump;
464  snprintf(fname, sizeof(fname), "dump_rcapAppendNodeGroup_%s.%d", grp->grp_name[i], HECMW_comm_get_rank());
465  fp_dump = fopen(fname, "w");
466  if (fp_dump == NULL) {
467  fprintf(stderr, "Error: cannot open file %s\n", fname);
468  } else {
469  int len = strlen(rcap_name);
470  HECMW_log(HECMW_LOG_DEBUG, "RCAP: writing strlen(dataname), dataname[], num, nodeArray[0..num-1] to %s\n", fname);
471  fwrite(&len, sizeof(int), 1, fp_dump);
472  fwrite(rcap_name, sizeof(char), len, fp_dump);
473  fwrite(&num, sizeof(int), 1, fp_dump);
474  fwrite(array, sizeof(int), num, fp_dump);
475  fclose(fp_dump);
476  }
477  }
478 #endif
479  rcapAppendNodeGroup(rcap_name, num, array);
480  }
481 }
482 
483 static int register_surf_groups(struct hecmwST_local_mesh *mesh) {
484  struct hecmwST_surf_grp *grp = mesh->surf_group;
485  int i, j;
486  char rcap_name[80];
487 
488  struct hecmw_varray_int other;
489 
490  for (i = 0; i < grp->n_grp; i++) {
491  int start = grp->grp_index[i];
492  int num = grp->grp_index[i + 1] - start;
493  int *array = grp->grp_item + start * 2;
494 
495  if (HECMW_varray_int_init(&other) != HECMW_SUCCESS) return HECMW_ERROR;
496 
497  for (j = 0; j < num; j++) {
498  int elem = array[j * 2];
499  int surf = array[j * 2 + 1];
500  int etype = mesh->elem_type[elem - 1];
501 
502  /* ignore shell/patch surface */
503  if (HECMW_is_etype_shell(etype) || HECMW_is_etype_patch(etype)) continue;
504 
505  if (HECMW_varray_int_append(&other, elem) != HECMW_SUCCESS)
506  return HECMW_ERROR;
507  if (HECMW_varray_int_append(&other, surf) != HECMW_SUCCESS)
508  return HECMW_ERROR;
509  }
510 
511  snprintf(rcap_name, sizeof(rcap_name), "SG_%s", grp->grp_name[i]);
512  num = HECMW_varray_int_nval(&other) / 2;
513  array = HECMW_varray_int_get_v(&other);
514 
515 #ifdef DEBUG_REFINER
516  HECMW_log(HECMW_LOG_DEBUG, "RCAP: calling rcapAppendFaceGroup(dataname=%s, num=%d, faceArray)\n", rcap_name, num);
517  {
518  char fname[256];
519  FILE *fp_dump;
520  snprintf(fname, sizeof(fname), "dump_rcapAppendFaceGroup_%s.%d", grp->grp_name[i], HECMW_comm_get_rank());
521  fp_dump = fopen(fname, "w");
522  if (fp_dump == NULL) {
523  fprintf(stderr, "Error: cannot open file %s\n", fname);
524  } else {
525  int len = strlen(rcap_name);
526  HECMW_log(HECMW_LOG_DEBUG, "RCAP: writing strlen(dataname), dataname[], num, faceArray[0..2*num-1] to %s\n", fname);
527  fwrite(&len, sizeof(int), 1, fp_dump);
528  fwrite(rcap_name, sizeof(char), len, fp_dump);
529  fwrite(&num, sizeof(int), 1, fp_dump);
530  fwrite(array, sizeof(int), num*2, fp_dump);
531  fclose(fp_dump);
532  }
533  }
534 #endif
535  rcapAppendFaceGroup(rcap_name, num, array);
536 
538  }
539  return HECMW_SUCCESS;
540 }
541 
542 static int prepare_refiner(struct hecmwST_local_mesh *mesh,
543  const char *cad_filename,
544  const char *part_filename) {
545  HECMW_log(HECMW_LOG_DEBUG, "Started preparing refiner...\n");
546 
547  if (elem_node_item_hecmw2rcap(mesh) != HECMW_SUCCESS) return HECMW_ERROR;
548  if (surf_ID_hecmw2rcap(mesh) != HECMW_SUCCESS) return HECMW_ERROR;
549 
550 #ifdef DEBUG_REFINER
551  HECMW_log(HECMW_LOG_DEBUG, "RCAP: calling rcapInitRefiner(nodeOffset=1, elementOffset=1)\n");
552 #endif
553  rcapInitRefiner(1, 1);
554  if (cad_filename != NULL) {
555 #ifdef DEBUG_REFINER
556  HECMW_log(HECMW_LOG_DEBUG, "RCAP: calling rcapSetCADFilename(filename=%s)\n", cad_filename);
557 #endif
558  rcapSetCADFilename(cad_filename);
559  }
560  if (part_filename != NULL) {
561 #ifdef DEBUG_REFINER
562  HECMW_log(HECMW_LOG_DEBUG, "RCAP: calling rcapSetPartitionFilename(filename=%s)\n", part_filename);
563 #endif
564  rcapSetPartitionFilename(part_filename);
565  }
566  register_node(mesh);
567 
568  /* node groups are refined by REVOCAP_Refiner */
569  register_node_groups(mesh->node_group);
570 
571  /* element groups are refined by myself */
572 
573  /* surface groups are refined by REVOCAP_Refiner except for shell/patch surface */
574  if (register_surf_groups(mesh) != HECMW_SUCCESS) return HECMW_ERROR;
575 
576  HECMW_log(HECMW_LOG_DEBUG, "Finished preparing refiner.\n");
577  return HECMW_SUCCESS;
578 }
579 
580 static void clear_refiner(void) {
581 #ifdef DEBUG_REFINER
582  HECMW_log(HECMW_LOG_DEBUG, "RCAP: calling rcapClearRefiner()\n");
583 #endif
584  rcapClearRefiner();
585 }
586 
587 static int terminate_refiner(struct hecmwST_local_mesh *mesh) {
588 #ifdef DEBUG_REFINER
589  HECMW_log(HECMW_LOG_DEBUG, "RCAP: calling rcapTermRefiner()\n");
590 #endif
591  rcapTermRefiner();
592  if (surf_ID_rcap2hecmw(mesh) != HECMW_SUCCESS) return HECMW_ERROR;
593  if (elem_node_item_rcap2hecmw(mesh) != HECMW_SUCCESS) return HECMW_ERROR;
594  return HECMW_SUCCESS;
595 }
596 
597 /*============================================================================*/
598 /* */
599 /* call REVOCAP_Refiner */
600 /* */
601 /*============================================================================*/
602 static int elem_type_hecmw2rcap(int etype) {
603  switch (etype) {
604  case HECMW_ETYPE_ROD1:
605  return RCAP_SEGMENT;
606  case HECMW_ETYPE_ROD2:
607  return RCAP_SEGMENT2;
608  case HECMW_ETYPE_TRI1:
609  return RCAP_TRIANGLE;
610  case HECMW_ETYPE_TRI2:
611  return RCAP_TRIANGLE2;
612  case HECMW_ETYPE_QUA1:
613  return RCAP_QUAD;
614  case HECMW_ETYPE_QUA2:
615  return RCAP_QUAD2;
616  case HECMW_ETYPE_ROD31:
617  return RCAP_SEGMENT;
618  case HECMW_ETYPE_TET1:
619  return RCAP_TETRAHEDRON;
620  case HECMW_ETYPE_TET1_4:
621  return RCAP_TETRAHEDRON;
622  case HECMW_ETYPE_TET2:
623  return RCAP_TETRAHEDRON2;
624  case HECMW_ETYPE_PRI1:
625  return RCAP_WEDGE;
626  case HECMW_ETYPE_PRI2:
627  return RCAP_WEDGE2;
628  case HECMW_ETYPE_PYR1:
629  return RCAP_PYRAMID;
630  case HECMW_ETYPE_PYR2:
631  return RCAP_PYRAMID2;
632  case HECMW_ETYPE_HEX1:
633  return RCAP_HEXAHEDRON;
634  case HECMW_ETYPE_HEX1_4:
635  return RCAP_HEXAHEDRON;
636  case HECMW_ETYPE_HEX2:
637  return RCAP_HEXAHEDRON2;
638  case HECMW_ETYPE_BEM1:
639  return RCAP_SEGMENT;
640  case HECMW_ETYPE_BEM2:
641  return RCAP_SEGMENT2;
642  case HECMW_ETYPE_BEM3:
643  return RCAP_SEGMENT;
644  case HECMW_ETYPE_SHT1:
645  return RCAP_TRIANGLE;
646  case HECMW_ETYPE_SHT2:
647  return RCAP_TRIANGLE2;
648  case HECMW_ETYPE_SHT6:
649  return RCAP_TRIANGLE;
650  case HECMW_ETYPE_SHQ1:
651  return RCAP_QUAD;
652  case HECMW_ETYPE_SHQ2:
653  return RCAP_QUAD2;
654  case HECMW_ETYPE_SHQ8:
655  return RCAP_QUAD;
656  case HECMW_ETYPE_PTT1:
657  return RCAP_TRIANGLE;
658  case HECMW_ETYPE_PTT2:
659  return RCAP_TRIANGLE2;
660  case HECMW_ETYPE_PTQ1:
661  return RCAP_QUAD;
662  case HECMW_ETYPE_PTQ2:
663  return RCAP_QUAD2;
664  }
665  return RCAP_UNKNOWNTYPE;
666 }
667 
668 static int reorder_enode_33struct(int etype, int n_elem,
669  int *elem_node_item_ref) {
670  int nn, nn_2, ndiv, nn_tot, ierror;
671  int j, k, l;
672  int tmp[32];
673  int *enode1, *enode2;
674  nn = HECMW_get_max_node(etype);
675  nn_2 = nn / 2;
676  ndiv = get_elem_ndiv(etype, &ierror);
677  if (ierror) return HECMW_ERROR;
678  nn_tot = ndiv * nn;
679  enode1 = elem_node_item_ref;
680  enode2 = enode1 + nn_2 * ndiv;
681  for (j = 0; j < n_elem; j++) {
682  int *tmp_p = tmp;
683  int *en1 = enode1;
684  for (k = 0; k < ndiv; k++) {
685  for (l = 0; l < nn_2; l++) {
686  tmp_p[l] = enode1[l];
687  tmp_p[nn_2 + l] = enode2[l];
688  }
689  tmp_p += nn;
690  enode1 += nn_2;
691  enode2 += nn_2;
692  }
693  for (k = 0; k < nn_tot; k++) {
694  en1[k] = tmp[k];
695  }
696  enode1 += nn_2 * ndiv;
697  enode2 += nn_2 * ndiv;
698  }
699  return HECMW_SUCCESS;
700 }
701 
702 static int refine_element(struct hecmwST_local_mesh *mesh,
703  struct hecmwST_local_mesh *ref_mesh) {
704  int i, j;
705  int n_elem_ref_tot;
706  size_t n_enode_ref_tot;
707  long long *elem_node_index_ref;
708  int *elem_node_item_ref;
709 
710  HECMW_log(HECMW_LOG_DEBUG, "Original Element Count = %d\n", mesh->n_elem_gross);
711 
712  /*
713  * count num of elems after refinement
714  */
715  n_elem_ref_tot = 0;
716  n_enode_ref_tot = 0;
717  for (i = 0; i < mesh->n_elem_type; i++) {
718  int etype, istart, iend, n_elem, etype_rcap, nn;
719  size_t n_elem_ref;
720  int *elem_node_item;
721  etype = mesh->elem_type_item[i];
722  istart = mesh->elem_type_index[i];
723  iend = mesh->elem_type_index[i + 1];
724  n_elem = iend - istart;
725  if (HECMW_is_etype_link(etype) || HECMW_is_etype_truss(etype)) {
726  n_elem_ref = n_elem;
727  } else {
728  int is33 = HECMW_is_etype_33struct(etype);
729  if (is33) n_elem *= 2;
730  etype_rcap = elem_type_hecmw2rcap(etype);
731  HECMW_assert(etype_rcap != RCAP_UNKNOWNTYPE);
732  elem_node_item = mesh->elem_node_item + mesh->elem_node_index[istart];
733 
734 #ifdef DEBUG_REFINER
735  HECMW_log(HECMW_LOG_DEBUG, "RCAP: calling rcapRefineElement(num=%d, etype=%d, nodeArray, NULL)\n", n_elem, etype_rcap);
736  {
737  char fname[256];
738  FILE *fp_dump;
739  snprintf(fname, sizeof(fname), "dump_rcapRefineElement_pre_%d.%d", etype, HECMW_comm_get_rank());
740  fp_dump = fopen(fname, "w");
741  if (fp_dump == NULL) {
742  fprintf(stderr, "Error: cannot open file %s\n", fname);
743  } else {
744  int nn = HECMW_get_max_node(etype);
745  HECMW_log(HECMW_LOG_DEBUG, "RCAP: writing num, etype, nodeArray[0..%d*num-1] to %s\n", nn, fname);
746  fwrite(&n_elem, sizeof(int), 1, fp_dump);
747  fwrite(&etype_rcap, sizeof(int), 1, fp_dump);
748  fwrite(elem_node_item, sizeof(int), nn * n_elem, fp_dump);
749  fclose(fp_dump);
750  }
751  }
752 #endif
753  n_elem_ref = rcapRefineElement(n_elem, etype_rcap, elem_node_item, NULL);
754 #ifdef DEBUG_REFINER
755  HECMW_log(HECMW_LOG_DEBUG, "RCAP: return value was %d\n", n_elem_ref);
756 #endif
757  if (is33) {
758  n_elem_ref /= 2;
759  n_elem /= 2;
760  }
761  }
762 #ifdef DEBUG
763  {
764  int ndiv, ierror;
765  ndiv = get_elem_ndiv(etype, &ierror);
766  if (ierror) return HECMW_ERROR;
767  HECMW_assert(n_elem_ref == n_elem * ndiv);
768  }
769 #endif
770  n_elem_ref_tot += n_elem_ref;
771  nn = HECMW_get_max_node(etype);
772  n_enode_ref_tot += n_elem_ref * nn;
773  }
774  ref_mesh->n_elem_gross = n_elem_ref_tot;
775 
776  HECMW_log(HECMW_LOG_DEBUG, "Refined Element Count will be %d\n", ref_mesh->n_elem_gross);
777 
778  /*
779  * allocate memory
780  */
781  ref_mesh->elem_node_index =
782  (long long *)HECMW_malloc(sizeof(long long) * (n_elem_ref_tot + 1));
783  if (ref_mesh->elem_node_index == NULL) {
784  HECMW_set_error(errno, "");
785  return HECMW_ERROR;
786  }
787  ref_mesh->elem_node_item = (int *)HECMW_calloc(n_enode_ref_tot, sizeof(int));
788  if (ref_mesh->elem_node_item == NULL) {
789  HECMW_set_error(errno, "");
790  return HECMW_ERROR;
791  }
792 
793  HECMW_assert(rcapGetNodeCount() == mesh->n_node_gross);
794 
795  /*
796  * perform actual refinement
797  */
798  ref_mesh->elem_node_index[0] = 0;
799  elem_node_index_ref = ref_mesh->elem_node_index;
800  elem_node_item_ref = ref_mesh->elem_node_item;
801  n_elem_ref_tot = 0;
802  for (i = 0; i < mesh->n_elem_type; i++) {
803  int etype, istart, iend, n_elem, etype_rcap, n_elem_ref, nn;
804  long long jstart;
805  int *elem_node_item;
806  etype = mesh->elem_type_item[i];
807  istart = mesh->elem_type_index[i];
808  iend = mesh->elem_type_index[i + 1];
809  n_elem = iend - istart;
810  nn = HECMW_get_max_node(etype);
811  if (HECMW_is_etype_link(etype) || HECMW_is_etype_truss(etype)) {
812  n_elem_ref = n_elem;
813  for (j = 0; j < n_elem * nn; j++) {
814  /* elem_node_item_ref[j] = elem_node_item[j]; */
815  jstart = mesh->elem_node_index[istart];
816  /* printf("aa %d %d\n",jstart,j); */
817  elem_node_item_ref[j] = mesh->elem_node_item[jstart + j];
818  }
819  } else {
820  int is33 = HECMW_is_etype_33struct(etype);
821  if (is33) n_elem *= 2;
822  etype_rcap = elem_type_hecmw2rcap(etype);
823  elem_node_item = mesh->elem_node_item + mesh->elem_node_index[istart];
824 
825 #ifdef DEBUG_REFINER
826  HECMW_log(HECMW_LOG_DEBUG, "RCAP: calling rcapRefineElement(num=%d, etype=%d, nodeArray, resultNodeArray)\n", n_elem, etype_rcap);
827 #endif
828  n_elem_ref = rcapRefineElement(n_elem, etype_rcap, elem_node_item,
829  elem_node_item_ref);
830 #ifdef DEBUG_REFINER
831  {
832  char fname[256];
833  FILE *fp_dump;
834  snprintf(fname, sizeof(fname), "dump_rcapRefineElement_%d.%d", etype, HECMW_comm_get_rank());
835  fp_dump = fopen(fname, "w");
836  if (fp_dump == NULL) {
837  fprintf(stderr, "Error: cannot open file %s\n", fname);
838  } else {
839  int nn = HECMW_get_max_node(etype);
841  "RCAP: writing num, etype, nodeArray[0..%d*num-1], num_ref, resultNodeArray[0..%d*num_ref-1] to %s\n",
842  nn, nn, fname);
843  fwrite(&n_elem, sizeof(int), 1, fp_dump);
844  fwrite(&etype_rcap, sizeof(int), 1, fp_dump);
845  fwrite(elem_node_item, sizeof(int), nn * n_elem, fp_dump);
846  fwrite(&n_elem_ref, sizeof(int), 1, fp_dump);
847  fwrite(elem_node_item_ref, sizeof(int), nn * n_elem_ref, fp_dump);
848  fclose(fp_dump);
849  }
850  }
851 #endif
852 
853  if (is33) {
854  n_elem /= 2;
855  n_elem_ref /= 2;
856  reorder_enode_33struct(etype, n_elem, elem_node_item_ref);
857  }
858  }
859  for (j = 0; j < n_elem_ref; j++) {
860  elem_node_index_ref[j + 1] = elem_node_index_ref[j] + nn;
861  if (elem_node_index_ref[j + 1] < elem_node_index_ref[j]) {
863  "Integer overflow detected while creating elem_node_index\n");
864  return HECMW_ERROR;
865  }
866  }
867  elem_node_index_ref += n_elem_ref;
868  elem_node_item_ref += nn * n_elem_ref;
869  n_elem_ref_tot += n_elem_ref;
870  }
871 
872  HECMW_log(HECMW_LOG_DEBUG, "Refined Element Count = %d\n", n_elem_ref_tot);
873 
874  HECMW_assert(n_elem_ref_tot == ref_mesh->n_elem_gross);
875 
876 #ifdef DEBUG_REFINER
877  HECMW_log(HECMW_LOG_DEBUG, "RCAP: calling rcapCommit()\n");
878 #endif
879  rcapCommit();
880  return HECMW_SUCCESS;
881 }
882 
883 static int refine_node(struct hecmwST_local_mesh *mesh,
884  struct hecmwST_local_mesh *ref_mesh) {
885  /* n_node_gross */
886 #ifdef DEBUG_REFINER
887  HECMW_log(HECMW_LOG_DEBUG, "RCAP: calling rcapGetNodeCount()\n");
888 #endif
889  ref_mesh->n_node_gross = rcapGetNodeCount();
890 #ifdef DEBUG_REFINER
891  HECMW_log(HECMW_LOG_DEBUG, "RCAP: return value was %d\n", ref_mesh->n_node_gross);
892 #endif
893 
894  HECMW_log(HECMW_LOG_DEBUG, "Refined Node Count = %d\n", ref_mesh->n_node_gross);
895 
897 
898  /* node */
899  ref_mesh->node =
900  (double *)HECMW_malloc(sizeof(double) * ref_mesh->n_node_gross * 3);
901  if (ref_mesh->node == NULL) {
902  HECMW_set_error(errno, "");
903  return HECMW_ERROR;
904  }
905 #ifdef DEBUG_REFINER
906  HECMW_log(HECMW_LOG_DEBUG, "RCAP: calling rcapGetNodeSeq64(num=%d, initId=1, coords)\n", ref_mesh->n_node_gross);
907 #endif
908  rcapGetNodeSeq64(ref_mesh->n_node_gross, 1, ref_mesh->node);
909 #ifdef DEBUG_REFINER
910  {
911  char fname[256];
912  FILE *fp_dump;
913  snprintf(fname, sizeof(fname), "dump_rcapGetNodeSeq64.%d", HECMW_comm_get_rank());
914  fp_dump = fopen(fname, "w");
915  if (fp_dump == NULL) {
916  fprintf(stderr, "Error: cannot open file %s\n", fname);
917  } else {
918  int one = 1;
919  HECMW_log(HECMW_LOG_DEBUG, "RCAP: writing num, initId, coords[0..3*num-1] to %s\n", fname);
920  fwrite(&(ref_mesh->n_node_gross), sizeof(int), 1, fp_dump);
921  fwrite(&one, sizeof(int), 1, fp_dump);
922  fwrite(ref_mesh->node, sizeof(int), 3 * ref_mesh->n_node_gross, fp_dump);
923  fclose(fp_dump);
924  }
925  }
926 #endif
927 
928  return HECMW_SUCCESS;
929 }
930 
931 static int refine_node_group_info(struct hecmwST_node_grp *grp,
932  struct hecmwST_node_grp *ref_grp,
933  int ref_n_node_gross) {
934  int i;
935  char rcap_name[80];
936 
937  ref_grp->n_grp = grp->n_grp;
938 
939  /* grp_name (COPY) */
940  ref_grp->grp_name = (char **)HECMW_malloc(sizeof(char *) * grp->n_grp);
941  if (ref_grp->grp_name == NULL) {
942  HECMW_set_error(errno, "");
943  return HECMW_ERROR;
944  }
945  /* ALL */
946  ref_grp->grp_name[0] = HECMW_strdup("ALL");
947  if (ref_grp->grp_name[0] == NULL) {
948  HECMW_set_error(errno, "");
949  return HECMW_ERROR;
950  }
951  /* other groups */
952  for (i = 1; i < grp->n_grp; i++) {
953  ref_grp->grp_name[i] = HECMW_strdup(grp->grp_name[i]);
954  if (ref_grp->grp_name[i] == NULL) {
955  HECMW_set_error(errno, "");
956  return HECMW_ERROR;
957  }
958  }
959 
960  /* grp_index */
961  ref_grp->grp_index = (int *)HECMW_malloc(sizeof(int) * (grp->n_grp + 1));
962  if (ref_grp->grp_index == NULL) {
963  HECMW_set_error(errno, "");
964  return HECMW_ERROR;
965  }
966  ref_grp->grp_index[0] = 0;
967  /* ALL */
968  ref_grp->grp_index[1] = ref_n_node_gross;
969  /* other groups */
970  for (i = 1; i < grp->n_grp; i++) {
971  snprintf(rcap_name, sizeof(rcap_name), "NG_%s", grp->grp_name[i]);
972  ref_grp->grp_index[i + 1] =
973  ref_grp->grp_index[i] + rcapGetNodeGroupCount(rcap_name);
974  }
975 
976  /* grp_item */
977  if (ref_grp->grp_index[grp->n_grp] > 0) {
978  ref_grp->grp_item =
979  (int *)HECMW_calloc(ref_grp->grp_index[grp->n_grp], sizeof(int));
980  if (ref_grp->grp_item == NULL) {
981  HECMW_set_error(errno, "");
982  return HECMW_ERROR;
983  }
984  /* ALL */
985  for (i = 0; i < ref_n_node_gross; i++) {
986  ref_grp->grp_item[i] = i + 1;
987  }
988  /* other groups */
989  for (i = 1; i < grp->n_grp; i++) {
990  int start = ref_grp->grp_index[i];
991  int num = ref_grp->grp_index[i + 1] - start;
992  if (num > 0) {
993  int *array = ref_grp->grp_item + start;
994  snprintf(rcap_name, sizeof(rcap_name), "NG_%s", grp->grp_name[i]);
995  rcapGetNodeGroup(rcap_name, num, array);
996  }
997  }
998  } else {
999  ref_grp->grp_item = NULL;
1000  }
1001  return HECMW_SUCCESS;
1002 }
1003 
1004 /*
1005  * static functions for refining element groups
1006  */
1007 
1008 static int get_refined_element_count(const struct hecmwST_local_mesh *mesh,
1009  int n_elem, int *elem_list) {
1010  int i, eid, etype, ierror, ndiv;
1011  int n_elem_ref = 0;
1012  for (i = 0; i < n_elem; i++) {
1013  eid = elem_list[i];
1014  HECMW_assert(0 < eid && eid <= mesh->n_elem_gross);
1015  etype = mesh->elem_type[eid - 1];
1016  ndiv = get_elem_ndiv(etype, &ierror);
1017  if (ierror) return -1;
1018  n_elem_ref += ndiv;
1019  }
1020  return n_elem_ref;
1021 }
1022 
1023 static int get_refined_elements(const struct hecmwST_local_mesh *mesh,
1024  struct hecmwST_local_mesh *ref_mesh, int eid,
1025  int *eid_ref) {
1026  int i, etype, ierror, ndiv;
1027  int etype_idx, eid_type;
1028  int offset;
1029 
1030  HECMW_assert(0 < eid);
1031  HECMW_assert(eid <= mesh->n_elem_gross);
1032  HECMW_assert(eid_ref);
1033 
1034  etype = mesh->elem_type[eid - 1];
1035  ndiv = get_elem_ndiv(etype, &ierror);
1036  if (ierror) return -1;
1037  etype_idx = -1;
1038  eid_type = -1;
1039  for (i = 0; i < mesh->n_elem_type; i++) {
1040  if (mesh->elem_type_item[i] == etype) {
1041  etype_idx = i;
1042  HECMW_assert(mesh->elem_type_index[i] < eid);
1043  HECMW_assert(eid <= mesh->elem_type_index[i + 1]);
1044  eid_type = eid - mesh->elem_type_index[i];
1045  break;
1046  }
1047  }
1048  HECMW_assert(etype_idx >= 0);
1049  HECMW_assert(eid_type > 0);
1050 
1051  offset = ref_mesh->elem_type_index[etype_idx] + (eid_type - 1) * ndiv + 1;
1052  for (i = 0; i < ndiv; i++) {
1053  eid_ref[i] = offset + i;
1054  }
1055  return ndiv;
1056 }
1057 
1058 static int get_refined_elem_list(const struct hecmwST_local_mesh *mesh,
1059  struct hecmwST_local_mesh *ref_mesh,
1060  int n_elem, int *elem_list,
1061  int *elem_list_ref) {
1062  int i, j;
1063  int eid_ref[NDIV_MAX];
1064  int *el_ref = elem_list_ref;
1065  int n_elem_ref = 0;
1066  for (i = 0; i < n_elem; i++) {
1067  int ndiv = get_refined_elements(mesh, ref_mesh, elem_list[i], eid_ref);
1068  if (ndiv < 0) return -1;
1069  for (j = 0; j < ndiv; j++) {
1070  el_ref[j] = eid_ref[j];
1071  }
1072  el_ref += ndiv;
1073  n_elem_ref += ndiv;
1074  }
1075  return n_elem_ref;
1076 }
1077 
1078 /*
1079  * refinement of element groups is done by myself
1080  */
1081 
1082 static int refine_elem_group_info(struct hecmwST_local_mesh *mesh,
1083  struct hecmwST_local_mesh *ref_mesh) {
1084  int i;
1085  struct hecmwST_elem_grp *grp = mesh->elem_group;
1086  struct hecmwST_elem_grp *ref_grp = ref_mesh->elem_group;
1087  int ref_n_elem_gross = ref_mesh->n_elem_gross;
1088 
1089  ref_grp->n_grp = grp->n_grp;
1090 
1091  /* grp_name (COPY) */
1092  ref_grp->grp_name = (char **)HECMW_malloc(sizeof(char *) * grp->n_grp);
1093  if (ref_grp->grp_name == NULL) {
1094  HECMW_set_error(errno, "");
1095  return HECMW_ERROR;
1096  }
1097  /* ALL */
1098  HECMW_assert(strcmp(grp->grp_name[0], "ALL") == 0);
1099  ref_grp->grp_name[0] = HECMW_strdup("ALL");
1100  if (ref_grp->grp_name[0] == NULL) {
1101  HECMW_set_error(errno, "");
1102  return HECMW_ERROR;
1103  }
1104  /* other groups */
1105  for (i = 1; i < grp->n_grp; i++) {
1106  ref_grp->grp_name[i] = HECMW_strdup(grp->grp_name[i]);
1107  if (ref_grp->grp_name[i] == NULL) {
1108  HECMW_set_error(errno, "");
1109  return HECMW_ERROR;
1110  }
1111  }
1112 
1113  /* grp_index */
1114  ref_grp->grp_index = (int *)HECMW_malloc(sizeof(int) * (grp->n_grp + 1));
1115  if (ref_grp->grp_index == NULL) {
1116  HECMW_set_error(errno, "");
1117  return HECMW_ERROR;
1118  }
1119  ref_grp->grp_index[0] = 0;
1120  /* ALL */
1121  ref_grp->grp_index[1] = ref_n_elem_gross;
1122  /* other groups */
1123  for (i = 1; i < grp->n_grp; i++) {
1124  int start, n_elem, n_elem_ref;
1125  int *elem_list;
1126  start = grp->grp_index[i];
1127  n_elem = grp->grp_index[i + 1] - start;
1128  elem_list = grp->grp_item + start;
1129  n_elem_ref = get_refined_element_count(mesh, n_elem, elem_list);
1130  if (n_elem_ref < 0) return HECMW_ERROR;
1131  ref_grp->grp_index[i + 1] = ref_grp->grp_index[i] + n_elem_ref;
1132  }
1133 
1134  /* grp_item */
1135  if (ref_grp->grp_index[grp->n_grp] > 0) {
1136  ref_grp->grp_item =
1137  (int *)HECMW_calloc(ref_grp->grp_index[grp->n_grp], sizeof(int));
1138  if (ref_grp->grp_item == NULL) {
1139  HECMW_set_error(errno, "");
1140  return HECMW_ERROR;
1141  }
1142  /* ALL */
1143  for (i = 0; i < ref_n_elem_gross; i++) {
1144  ref_grp->grp_item[i] = i + 1;
1145  }
1146  /* other groups */
1147  for (i = 1; i < grp->n_grp; i++) {
1148  int start, start_ref, n_elem, n_elem_ref, ret;
1149  int *elem_list, *elem_list_ref;
1150  start_ref = ref_grp->grp_index[i];
1151  n_elem_ref = ref_grp->grp_index[i + 1] - start_ref;
1152  HECMW_assert(n_elem_ref >= 0);
1153  if (n_elem_ref == 0) continue;
1154  start = grp->grp_index[i];
1155  n_elem = grp->grp_index[i + 1] - start;
1156  elem_list = grp->grp_item + start;
1157  elem_list_ref = ref_grp->grp_item + start_ref;
1158  ret = get_refined_elem_list(mesh, ref_mesh, n_elem, elem_list,
1159  elem_list_ref);
1160  HECMW_assert(ret == n_elem_ref);
1161  }
1162  } else {
1163  ref_grp->grp_item = NULL;
1164  }
1165  return HECMW_SUCCESS;
1166 }
1167 
1168 /*
1169  * refinement of surface groups except for shell/patch surface is done
1170  * by REVOCAP_Refiner
1171  * refinement of shell/patch surfaces is done by myself
1172  */
1173 
1174 static int refine_surf_group_info(struct hecmwST_local_mesh *mesh,
1175  struct hecmwST_local_mesh *ref_mesh) {
1176  struct hecmwST_surf_grp *grp = mesh->surf_group;
1177  struct hecmwST_surf_grp *ref_grp = ref_mesh->surf_group;
1178  int i, j;
1179  char rcap_name[80];
1180 
1181  ref_grp->n_grp = grp->n_grp;
1182 
1183  /* grp_name (COPY) */
1184  ref_grp->grp_name = (char **)HECMW_malloc(sizeof(char *) * grp->n_grp);
1185  if (ref_grp->grp_name == NULL) {
1186  HECMW_set_error(errno, "");
1187  return HECMW_ERROR;
1188  }
1189  for (i = 0; i < grp->n_grp; i++) {
1190  ref_grp->grp_name[i] = HECMW_strdup(grp->grp_name[i]);
1191  if (ref_grp->grp_name[i] == NULL) {
1192  HECMW_set_error(errno, "");
1193  return HECMW_ERROR;
1194  }
1195  }
1196 
1197  /* grp_index */
1198  ref_grp->grp_index = (int *)HECMW_malloc(sizeof(int) * (grp->n_grp + 1));
1199  if (ref_grp->grp_index == NULL) {
1200  HECMW_set_error(errno, "");
1201  return HECMW_ERROR;
1202  }
1203  ref_grp->grp_index[0] = 0;
1204  for (i = 0; i < grp->n_grp; i++) {
1205  int start = grp->grp_index[i];
1206  int num = grp->grp_index[i + 1] - start;
1207  int *array = grp->grp_item + start * 2;
1208  int num_sh, num_other;
1209 
1210  /* count surfaces except for shell/patch */
1211  snprintf(rcap_name, sizeof(rcap_name), "SG_%s", grp->grp_name[i]);
1212  num_other = rcapGetFaceGroupCount(rcap_name);
1213 
1214  /* count shell/patch surfaces */
1215  num_sh = 0;
1216  for (j = 0; j < num; j++) {
1217  int elem = array[j * 2];
1218  int etype = mesh->elem_type[elem - 1];
1219  if (!(HECMW_is_etype_shell(etype) || HECMW_is_etype_patch(etype))) continue;
1220  num_sh += 1;
1221  }
1222  num_sh *= NDIV_SURF;
1223 
1224  ref_grp->grp_index[i + 1] = ref_grp->grp_index[i] + num_other + num_sh;
1225  }
1226  HECMW_assert(ref_grp->grp_index[grp->n_grp] >= 0);
1227 
1228  /* grp_item */
1229  if (ref_grp->grp_index[grp->n_grp] == 0) {
1230  ref_grp->grp_item = NULL;
1231  return HECMW_SUCCESS;
1232  }
1233  ref_grp->grp_item =
1234  (int *)HECMW_calloc(ref_grp->grp_index[grp->n_grp] * 2, sizeof(int));
1235  if (ref_grp->grp_item == NULL) {
1236  HECMW_set_error(errno, "");
1237  return HECMW_ERROR;
1238  }
1239  for (i = 0; i < grp->n_grp; i++) {
1240  struct hecmw_varray_int sh1, sh2;
1241  int start, num_tot, n_elem, ret;
1242  int start_ref, num_ref, num_tot_ref, n_elem_ref;
1243  int *array, *array_ref, *elem_list, *elem_list_ref;
1244 
1245  start_ref = ref_grp->grp_index[i];
1246  num_tot_ref = ref_grp->grp_index[i + 1] - start_ref;
1247  if (num_tot_ref == 0) continue;
1248  array_ref = ref_grp->grp_item + start_ref * 2;
1249 
1250  /* get surfaces from REVOCAP_Refiner */
1251  snprintf(rcap_name, sizeof(rcap_name), "SG_%s", grp->grp_name[i]);
1252  num_ref = rcapGetFaceGroupCount(rcap_name);
1253  rcapGetFaceGroup(rcap_name, num_ref, array_ref);
1254 
1255  num_tot_ref -= num_ref;
1256  if (num_tot_ref == 0) continue;
1257  array_ref += num_ref * 2;
1258 
1259  /*
1260  * make refined shell/patch surfaces by myself
1261  */
1262 
1263  if (HECMW_varray_int_init(&sh1) != HECMW_SUCCESS) return HECMW_ERROR;
1264  if (HECMW_varray_int_init(&sh2) != HECMW_SUCCESS) return HECMW_ERROR;
1265 
1266  /* collect shell/patch surface */
1267  start = grp->grp_index[i];
1268  num_tot = grp->grp_index[i + 1] - start;
1269  array = grp->grp_item + start * 2;
1270  for (j = 0; j < num_tot; j++) {
1271  int elem, etype, surf;
1272  elem = array[j * 2];
1273  surf = array[j * 2 + 1];
1274  etype = mesh->elem_type[elem - 1];
1275  if (!(HECMW_is_etype_shell(etype) || HECMW_is_etype_patch(etype))) continue;
1276  if (surf == 1) {
1277  if (HECMW_varray_int_append(&sh1, elem) != HECMW_SUCCESS)
1278  return HECMW_ERROR;
1279  } else {
1280  HECMW_assert(surf == 2);
1281  if (HECMW_varray_int_append(&sh2, elem) != HECMW_SUCCESS)
1282  return HECMW_ERROR;
1283  }
1284  }
1285 
1286  /* 1st surface of shells/patches */
1287  n_elem = HECMW_varray_int_nval(&sh1);
1288  if (n_elem > 0) {
1289  elem_list = HECMW_varray_int_get_v(&sh1);
1290  n_elem_ref = n_elem * NDIV_SURF;
1291  elem_list_ref = (int *)HECMW_calloc(n_elem_ref, sizeof(int));
1292  if (elem_list_ref == NULL) {
1293  HECMW_set_error(errno, "");
1294  return HECMW_ERROR;
1295  }
1296  ret = get_refined_elem_list(mesh, ref_mesh, n_elem, elem_list, elem_list_ref);
1297  HECMW_assert(ret == n_elem_ref);
1298  for (j = 0; j < n_elem_ref; j++) {
1299  array_ref[j * 2] = elem_list_ref[j];
1300  array_ref[j * 2 + 1] = 1;
1301  }
1302  HECMW_free(elem_list_ref);
1303 
1304  num_tot_ref -= n_elem_ref;
1305  array_ref += n_elem_ref * 2;
1306  }
1307 
1308  /* 2nd surface of shells */
1309  n_elem = HECMW_varray_int_nval(&sh2);
1310  if (n_elem > 0) {
1311  elem_list = HECMW_varray_int_get_v(&sh2);
1312  n_elem_ref = n_elem * NDIV_SURF;
1313  elem_list_ref = (int *)HECMW_calloc(n_elem_ref, sizeof(int));
1314  if (elem_list_ref == NULL) {
1315  HECMW_set_error(errno, "");
1316  return HECMW_ERROR;
1317  }
1318  ret = get_refined_elem_list(mesh, ref_mesh, n_elem, elem_list, elem_list_ref);
1319  HECMW_assert(ret == n_elem_ref);
1320  for (j = 0; j < n_elem_ref; j++) {
1321  array_ref[j * 2] = elem_list_ref[j];
1322  array_ref[j * 2 + 1] = 2;
1323  }
1324  HECMW_free(elem_list_ref);
1325 
1326  num_tot_ref -= n_elem_ref;
1327  }
1328 
1331 
1332  HECMW_assert(num_tot_ref == 0);
1333  }
1334  return HECMW_SUCCESS;
1335 }
1336 
1337 static int call_refiner(struct hecmwST_local_mesh *mesh,
1338  struct hecmwST_local_mesh *ref_mesh) {
1339  HECMW_log(HECMW_LOG_DEBUG, "Started calling refiner...\n");
1340 
1341  if (refine_element(mesh, ref_mesh) != HECMW_SUCCESS) {
1342  return HECMW_ERROR;
1343  }
1344  if (refine_node(mesh, ref_mesh) != HECMW_SUCCESS) {
1345  return HECMW_ERROR;
1346  }
1347  if (refine_node_group_info(mesh->node_group, ref_mesh->node_group,
1348  ref_mesh->n_node_gross) != HECMW_SUCCESS) {
1349  return HECMW_ERROR;
1350  }
1351  if (refine_elem_group_info(mesh, ref_mesh) != HECMW_SUCCESS) {
1352  return HECMW_ERROR;
1353  }
1354  if (refine_surf_group_info(mesh, ref_mesh) != HECMW_SUCCESS) {
1355  return HECMW_ERROR;
1356  }
1357  HECMW_log(HECMW_LOG_DEBUG, "Finished calling refiner.\n");
1358  return HECMW_SUCCESS;
1359 }
1360 
1361 /*============================================================================*/
1362 /* */
1363 /* rebuild information */
1364 /* */
1365 /*============================================================================*/
1366 static int rebuild_elem_ID(const struct hecmwST_local_mesh *mesh,
1367  struct hecmwST_local_mesh *ref_mesh) {
1368  int i, j, k;
1369  int count;
1370  int *elem_ID_org;
1371  int *elem_ID_ref;
1372 
1373  ref_mesh->elem_ID =
1374  (int *)HECMW_malloc(sizeof(int) * ref_mesh->n_elem_gross * 2);
1375  if (ref_mesh->elem_ID == NULL) {
1376  HECMW_set_error(errno, "");
1377  return HECMW_ERROR;
1378  }
1379  count = 0;
1380  elem_ID_org = mesh->elem_ID;
1381  elem_ID_ref = ref_mesh->elem_ID;
1382  for (i = 0; i < mesh->n_elem_type; i++) {
1383  int etype, istart, iend, n_elem, ierror, ndiv;
1384  etype = mesh->elem_type_item[i];
1385  istart = mesh->elem_type_index[i];
1386  iend = mesh->elem_type_index[i + 1];
1387  n_elem = iend - istart;
1388  ndiv = get_elem_ndiv(etype, &ierror);
1389  if (ierror) return HECMW_ERROR;
1390 
1391  for (j = 0; j < n_elem; j++) {
1392  int rank = elem_ID_org[1];
1393  for (k = 0; k < ndiv; k++) {
1394  count++;
1395  elem_ID_ref[0] = -count; /* TEMPORARY */
1396  elem_ID_ref[1] = rank; /* to be corrected later */
1397  elem_ID_ref += 2;
1398  }
1399  elem_ID_org += 2;
1400  }
1401  }
1402  return HECMW_SUCCESS;
1403 }
1404 
1405 static int rebuild_global_elem_ID(const struct hecmwST_local_mesh *mesh,
1406  struct hecmwST_local_mesh *ref_mesh) {
1407  int i, j, k;
1408  int min_ID;
1409  int *global_elem_ID_org;
1410  int *global_elem_ID_ref;
1411 
1412  ref_mesh->global_elem_ID =
1413  (int *)HECMW_malloc(sizeof(int) * ref_mesh->n_elem_gross);
1414  if (ref_mesh->global_elem_ID == NULL) {
1415  HECMW_set_error(errno, "");
1416  return HECMW_ERROR;
1417  }
1418  min_ID = 0;
1419  global_elem_ID_org = mesh->global_elem_ID;
1420  for (i = 0; i < mesh->n_elem_gross; i++) {
1421  if (global_elem_ID_org[i] < min_ID)
1422  min_ID = global_elem_ID_org[i];
1423  }
1424  global_elem_ID_ref = ref_mesh->global_elem_ID;
1425  for (i = 0; i < mesh->n_elem_type; i++) {
1426  int etype, istart, iend, n_elem, ierror, ndiv;
1427  etype = mesh->elem_type_item[i];
1428  istart = mesh->elem_type_index[i];
1429  iend = mesh->elem_type_index[i + 1];
1430  n_elem = iend - istart;
1431  ndiv = get_elem_ndiv(etype, &ierror);
1432  if (ierror) return HECMW_ERROR;
1433 
1434  for (j = 0; j < n_elem; j++) {
1435  global_elem_ID_ref[0] = global_elem_ID_org[0];
1436  for (k = 1; k < ndiv; k++) {
1437  min_ID--;
1438  global_elem_ID_ref[k] = min_ID;
1439  }
1440  global_elem_ID_org += 1;
1441  global_elem_ID_ref += ndiv;
1442  }
1443  }
1444  return HECMW_SUCCESS;
1445 }
1446 
1447 static int rebuild_elem_type(const struct hecmwST_local_mesh *mesh,
1448  struct hecmwST_local_mesh *ref_mesh) {
1449  int i, j, k;
1450  int *elem_type_ref;
1451 
1452  ref_mesh->elem_type =
1453  (int *)HECMW_malloc(sizeof(int) * ref_mesh->n_elem_gross);
1454  if (ref_mesh->elem_type == NULL) {
1455  HECMW_set_error(errno, "");
1456  return HECMW_ERROR;
1457  }
1458  elem_type_ref = ref_mesh->elem_type;
1459  for (i = 0; i < mesh->n_elem_type; i++) {
1460  int etype, istart, iend, n_elem, ierror, ndiv;
1461  etype = mesh->elem_type_item[i];
1462  istart = mesh->elem_type_index[i];
1463  iend = mesh->elem_type_index[i + 1];
1464  n_elem = iend - istart;
1465  ndiv = get_elem_ndiv(etype, &ierror);
1466  if (ierror) return HECMW_ERROR;
1467 
1468  for (j = 0; j < n_elem; j++) {
1469  for (k = 0; k < ndiv; k++) {
1470  elem_type_ref[k] = etype;
1471  }
1472  elem_type_ref += ndiv;
1473  }
1474  }
1475  return HECMW_SUCCESS;
1476 }
1477 
1478 static int rebuild_section_ID(const struct hecmwST_local_mesh *mesh,
1479  struct hecmwST_local_mesh *ref_mesh) {
1480  int i, j, k;
1481  int *section_ID_org;
1482  int *section_ID_ref;
1483  ref_mesh->section_ID =
1484  (int *)HECMW_malloc(sizeof(int) * ref_mesh->n_elem_gross);
1485  if (ref_mesh->section_ID == NULL) {
1486  HECMW_set_error(errno, "");
1487  return HECMW_ERROR;
1488  }
1489  section_ID_org = mesh->section_ID;
1490  section_ID_ref = ref_mesh->section_ID;
1491  for (i = 0; i < mesh->n_elem_type; i++) {
1492  int etype, istart, iend, n_elem, ierror, ndiv;
1493  etype = mesh->elem_type_item[i];
1494  istart = mesh->elem_type_index[i];
1495  iend = mesh->elem_type_index[i + 1];
1496  n_elem = iend - istart;
1497  ndiv = get_elem_ndiv(etype, &ierror);
1498  if (ierror) return HECMW_ERROR;
1499 
1500  for (j = 0; j < n_elem; j++) {
1501  int sect_id = section_ID_org[0];
1502  for (k = 0; k < ndiv; k++) {
1503  section_ID_ref[k] = sect_id;
1504  }
1505  section_ID_org += 1;
1506  section_ID_ref += ndiv;
1507  }
1508  }
1509  return HECMW_SUCCESS;
1510 }
1511 
1512 static int rebuild_elem_mat_ID_index(const struct hecmwST_local_mesh *mesh,
1513  struct hecmwST_local_mesh *ref_mesh) {
1514  int i, j, k;
1515  int *elem_mat_ID_index_org;
1516  int *elem_mat_ID_index_ref;
1517 
1518  ref_mesh->elem_mat_ID_index =
1519  (int *)HECMW_malloc(sizeof(int) * (ref_mesh->n_elem_gross + 1));
1520  if (ref_mesh->elem_mat_ID_index == NULL) {
1521  HECMW_set_error(errno, "");
1522  return HECMW_ERROR;
1523  }
1524  ref_mesh->elem_mat_ID_index[0] = 0;
1525  elem_mat_ID_index_org = mesh->elem_mat_ID_index;
1526  elem_mat_ID_index_ref = ref_mesh->elem_mat_ID_index;
1527  for (i = 0; i < mesh->n_elem_type; i++) {
1528  int etype, istart, iend, n_elem, ierror, ndiv;
1529  etype = mesh->elem_type_item[i];
1530  istart = mesh->elem_type_index[i];
1531  iend = mesh->elem_type_index[i + 1];
1532  n_elem = iend - istart;
1533  ndiv = get_elem_ndiv(etype, &ierror);
1534  if (ierror) return HECMW_ERROR;
1535 
1536  for (j = 0; j < n_elem; j++) {
1537  int n = elem_mat_ID_index_org[1] - elem_mat_ID_index_org[0];
1538  for (k = 0; k < ndiv; k++) {
1539  elem_mat_ID_index_ref[k + 1] = elem_mat_ID_index_ref[k] + n;
1540  }
1541  elem_mat_ID_index_org += 1;
1542  elem_mat_ID_index_ref += ndiv;
1543  }
1544  }
1545  return HECMW_SUCCESS;
1546 }
1547 
1548 static int rebuild_elem_mat_ID_item(const struct hecmwST_local_mesh *mesh,
1549  struct hecmwST_local_mesh *ref_mesh) {
1550  int i, j, k, l;
1551  int *elem_mat_ID_index_org;
1552  int *elem_mat_ID_item_org;
1553  int *elem_mat_ID_item_ref;
1554 
1555  ref_mesh->elem_mat_ID_item = (int *)HECMW_malloc(
1556  sizeof(int) * ref_mesh->elem_mat_ID_index[ref_mesh->n_elem_gross]);
1557  if (ref_mesh->elem_mat_ID_item == NULL) {
1558  HECMW_set_error(errno, "");
1559  return HECMW_ERROR;
1560  }
1561  elem_mat_ID_index_org = mesh->elem_mat_ID_index;
1562  elem_mat_ID_item_org = mesh->elem_mat_ID_item;
1563  elem_mat_ID_item_ref = ref_mesh->elem_mat_ID_item;
1564  for (i = 0; i < mesh->n_elem_type; i++) {
1565  int etype, istart, iend, n_elem, ierror, ndiv;
1566  etype = mesh->elem_type_item[i];
1567  istart = mesh->elem_type_index[i];
1568  iend = mesh->elem_type_index[i + 1];
1569  n_elem = iend - istart;
1570  ndiv = get_elem_ndiv(etype, &ierror);
1571  if (ierror) return HECMW_ERROR;
1572 
1573  for (j = 0; j < n_elem; j++) {
1574  int n = elem_mat_ID_index_org[1] - elem_mat_ID_index_org[0];
1575  for (k = 0; k < ndiv; k++) {
1576  for (l = 0; l < n; l++) {
1577  elem_mat_ID_item_ref[l] = elem_mat_ID_item_org[l];
1578  }
1579  elem_mat_ID_item_ref += n;
1580  }
1581  elem_mat_ID_index_org += 1;
1582  elem_mat_ID_item_org += n;
1583  }
1584  }
1585  return HECMW_SUCCESS;
1586 }
1587 
1588 static int rebuild_elem_info(const struct hecmwST_local_mesh *mesh,
1589  struct hecmwST_local_mesh *ref_mesh) {
1590  HECMW_log(HECMW_LOG_DEBUG, "Started rebuilding element info...\n");
1591 
1592  if (rebuild_elem_ID(mesh, ref_mesh) != HECMW_SUCCESS) return HECMW_ERROR;
1593  if (rebuild_global_elem_ID(mesh, ref_mesh) != HECMW_SUCCESS)
1594  return HECMW_ERROR;
1595  if (rebuild_elem_type(mesh, ref_mesh) != HECMW_SUCCESS) return HECMW_ERROR;
1596  if (rebuild_section_ID(mesh, ref_mesh) != HECMW_SUCCESS) return HECMW_ERROR;
1597  if (rebuild_elem_mat_ID_index(mesh, ref_mesh) != HECMW_SUCCESS)
1598  return HECMW_ERROR;
1599  if (rebuild_elem_mat_ID_item(mesh, ref_mesh) != HECMW_SUCCESS)
1600  return HECMW_ERROR;
1601 
1602  ref_mesh->n_elem_mat_ID = ref_mesh->elem_mat_ID_index[ref_mesh->n_elem_gross];
1603 
1604  HECMW_log(HECMW_LOG_DEBUG, "Finished rebuilding element info.\n");
1605  return HECMW_SUCCESS;
1606 }
1607 
1608 static int rebuild_node_info(const struct hecmwST_local_mesh *mesh,
1609  struct hecmwST_local_mesh *ref_mesh) {
1610  int i;
1611  int count, min_ID;
1612 
1613  HECMW_log(HECMW_LOG_DEBUG, "Started rebuilding node info...\n");
1614 
1615  /* allocate node_ID */
1616  ref_mesh->node_ID =
1617  (int *)HECMW_malloc(sizeof(int) * ref_mesh->n_node_gross * 2);
1618  if (ref_mesh->node_ID == NULL) {
1619  HECMW_set_error(errno, "");
1620  return HECMW_ERROR;
1621  }
1622 
1623  /* node_ID */
1624  for (i = 0; i < mesh->n_node_gross; i++) {
1625  ref_mesh->node_ID[2 * i] = mesh->node_ID[2 * i];
1626  ref_mesh->node_ID[2 * i + 1] = mesh->node_ID[2 * i + 1];
1627  }
1628  count = 0;
1629  for (i = mesh->n_node_gross; i < ref_mesh->n_node_gross; i++) {
1630  count++;
1631  ref_mesh->node_ID[2 * i] = -count; /* TEMPORARY */
1632  ref_mesh->node_ID[2 * i + 1] = mesh->my_rank; /* to be corrected later */
1633  }
1634 
1635  /* global_node_ID */
1636  ref_mesh->global_node_ID =
1637  (int *)HECMW_malloc(sizeof(int) * ref_mesh->n_node_gross);
1638  if (ref_mesh->global_node_ID == NULL) {
1639  HECMW_set_error(errno, "");
1640  return HECMW_ERROR;
1641  }
1642  min_ID = 0;
1643  for (i = 0; i < mesh->n_node_gross; i++) {
1644  ref_mesh->global_node_ID[i] = mesh->global_node_ID[i];
1645  if (mesh->global_node_ID[i] < min_ID)
1646  min_ID = mesh->global_node_ID[i];
1647  }
1648  for (i = mesh->n_node_gross; i < ref_mesh->n_node_gross; i++) {
1649  min_ID--;
1650  ref_mesh->global_node_ID[i] = min_ID;
1651  }
1652 
1653  if (mesh->hecmw_flag_initcon && mesh->n_node_gross > 0) {
1654  /* node_init_val_index */
1655  ref_mesh->node_init_val_index =
1656  (int *)HECMW_malloc(sizeof(int) * (ref_mesh->n_node_gross + 1));
1657  if (ref_mesh->node_init_val_index == NULL) {
1658  HECMW_set_error(errno, "");
1659  return HECMW_ERROR;
1660  }
1661  for (i = 0; i < mesh->n_node_gross + 1; i++) {
1662  ref_mesh->node_init_val_index[i] = mesh->node_init_val_index[i];
1663  }
1664  for (i = mesh->n_node_gross + 1; i < ref_mesh->n_node_gross + 1; i++) {
1665  ref_mesh->node_init_val_index[i] =
1667  }
1668 
1669  /* node_init_val_item */
1670  if (ref_mesh->node_init_val_index[ref_mesh->n_node_gross] == 0) {
1671  ref_mesh->node_init_val_item = NULL;
1672  } else {
1673  ref_mesh->node_init_val_item = (double *)HECMW_malloc(
1674  sizeof(double) * mesh->node_init_val_index[mesh->n_node_gross]);
1675  if (ref_mesh->node_init_val_item == NULL) {
1676  HECMW_set_error(errno, "");
1677  return HECMW_ERROR;
1678  }
1679  for (i = 0; i < mesh->node_init_val_index[mesh->n_node_gross]; i++) {
1680  ref_mesh->node_init_val_item[i] = mesh->node_init_val_item[i];
1681  }
1682  }
1683  }
1684 
1685  HECMW_log(HECMW_LOG_DEBUG, "Finished rebuilding node info.\n");
1686  return HECMW_SUCCESS;
1687 }
1688 
1689 /*
1690  * static functions called by rebuild_comm_tables
1691  */
1692 
1693 static int get_refined_shared(const struct hecmwST_local_mesh *mesh,
1694  struct hecmwST_local_mesh *ref_mesh,
1695  struct hecmw_varray_int *shared) {
1696  int i;
1697 
1698  for (i = 0; i < mesh->n_neighbor_pe; i++) {
1699  int start, n_elem, n_elem_ref, ret;
1700  int *elem_list, *elem_list_ref;
1701  start = mesh->shared_index[i];
1702  n_elem = mesh->shared_index[i + 1] - start;
1703  elem_list = mesh->shared_item + start;
1704  n_elem_ref = get_refined_element_count(mesh, n_elem, elem_list);
1705  if (n_elem_ref < 0) return HECMW_ERROR;
1706  HECMW_varray_int_resize(shared + i, n_elem_ref);
1707  elem_list_ref = HECMW_varray_int_get_v(shared + i);
1708  ret =
1709  get_refined_elem_list(mesh, ref_mesh, n_elem, elem_list, elem_list_ref);
1710  HECMW_assert(ret == n_elem_ref);
1711  }
1712  return HECMW_SUCCESS;
1713 }
1714 
1715 static int elem_type_rcap2hecmw(int etype) {
1716  switch (etype) {
1717  case RCAP_SEGMENT:
1718  return HECMW_ETYPE_ROD1;
1719  case RCAP_SEGMENT2:
1720  return HECMW_ETYPE_ROD2;
1721  case RCAP_TRIANGLE:
1722  return HECMW_ETYPE_TRI1;
1723  case RCAP_TRIANGLE2:
1724  return HECMW_ETYPE_TRI2;
1725  case RCAP_QUAD:
1726  return HECMW_ETYPE_QUA1;
1727  case RCAP_QUAD2:
1728  return HECMW_ETYPE_QUA2;
1729  case RCAP_TETRAHEDRON:
1730  return HECMW_ETYPE_TET1;
1731  case RCAP_TETRAHEDRON2:
1732  return HECMW_ETYPE_TET2;
1733  case RCAP_WEDGE:
1734  return HECMW_ETYPE_PRI1;
1735  case RCAP_WEDGE2:
1736  return HECMW_ETYPE_PRI2;
1737  case RCAP_PYRAMID:
1738  return HECMW_ETYPE_PYR1;
1739  case RCAP_PYRAMID2:
1740  return HECMW_ETYPE_PYR2;
1741  case RCAP_HEXAHEDRON:
1742  return HECMW_ETYPE_HEX1;
1743  case RCAP_HEXAHEDRON2:
1744  return HECMW_ETYPE_HEX2;
1745  }
1746  return HECMW_ERROR;
1747 }
1748 
1749 static int get_rcap_elem_max_node(int etype_rcap) {
1750  int etype_hecmw = elem_type_rcap2hecmw(etype_rcap);
1751  return HECMW_get_max_node(etype_hecmw);
1752 }
1753 
1754 static int determine_node_rank_of_purely_external_elems(
1755  const struct hecmwST_local_mesh *mesh,
1756  struct hecmwST_local_mesh *ref_mesh) {
1757  int eid, rank, k, nid;
1758  long long nn;
1759  int *elem_nodes;
1760 
1761  for (eid = 1; eid <= ref_mesh->n_elem_gross; eid++) {
1762  rank = ref_mesh->elem_ID[2 * (eid - 1) + 1];
1763 
1764  if (rank >= 0) continue; /* purely external elems have rank < 0 */
1765 
1766  nn = ref_mesh->elem_node_index[eid] - ref_mesh->elem_node_index[eid - 1];
1767  elem_nodes = ref_mesh->elem_node_item + ref_mesh->elem_node_index[eid - 1];
1768  for (k = 0; k < nn; k++) {
1769  nid = elem_nodes[k];
1770  if (nid <= mesh->n_node_gross) continue; /* skip old nodes */
1771 
1772  /* new nodes that have not been assigned new rank have default rank = my_rank */
1773  if (ref_mesh->node_ID[2 * (nid - 1) + 1] == ref_mesh->my_rank) {
1774  /* assign out-of-range rank = n_subdomain as purely external number = -rank-1 */
1775  ref_mesh->node_ID[2 * (nid - 1) + 1] = - ref_mesh->n_subdomain - 1;
1776  }
1777  }
1778  }
1779  return HECMW_SUCCESS;
1780 }
1781 
1782 static int determine_node_rank(const struct hecmwST_local_mesh *mesh,
1783  const struct hecmw_varray_int *shared,
1784  struct hecmwST_local_mesh *ref_mesh) {
1785  int i, j, k;
1786  struct hecmw_set_int boundary_nodes;
1787  int bnode;
1788 
1789  HECMW_log(HECMW_LOG_DEBUG, "Started determine_node_rank...\n");
1790 
1791  HECMW_set_int_init(&boundary_nodes);
1792 
1793  /* Collect nodes of the shared elements, except for the old nodes */
1794  for (i = 0; i < mesh->n_neighbor_pe; i++) {
1795  for (j = 0; j < HECMW_varray_int_nval(shared + i); j++) {
1796  int eid = HECMW_varray_int_get(shared + i, j);
1797  int nn =
1798  ref_mesh->elem_node_index[eid] - ref_mesh->elem_node_index[eid - 1];
1799  int *elem_nodes =
1800  ref_mesh->elem_node_item + ref_mesh->elem_node_index[eid - 1];
1801 
1802  for (k = 0; k < nn; k++) {
1803  if (elem_nodes[k] <= mesh->n_node_gross) continue;
1804 
1805  HECMW_set_int_add(&boundary_nodes, elem_nodes[k]);
1806  }
1807  }
1808  }
1809  HECMW_set_int_check_dup(&boundary_nodes);
1810 
1811  /* for each node: determine which domain it belongs to; save in node_ID */
1812  HECMW_set_int_iter_init(&boundary_nodes);
1813  while (HECMW_set_int_iter_next(&boundary_nodes, &bnode)) {
1814  int original[HECMW_MAX_NODE_MAX];
1815  int orig_type_rcap = rcapGetOriginal(bnode, original);
1816  int min_rank = mesh->n_subdomain;
1817  int max_rank = -1;
1818  int nn;
1819 
1820  HECMW_assert(orig_type_rcap != RCAP_UNKNOWNTYPE);
1821 
1822  nn = get_rcap_elem_max_node(orig_type_rcap);
1823 
1824  for (k = 0; k < nn; k++) {
1825  int rank;
1826 
1827  HECMW_assert(1 <= original[k] && original[k] < bnode);
1828 
1829  rank = ref_mesh->node_ID[2 * (original[k] - 1) + 1];
1830 
1831  /* for purely external nodes, rank (0, 1, ...) is stored as -rank-1 (-1,
1832  * -2, ...) */
1833  if (rank < 0) rank = -rank - 1;
1834 
1835  if (rank < min_rank) min_rank = rank;
1836  if (max_rank < rank) max_rank = rank;
1837  }
1838  HECMW_assert(0 <= min_rank && min_rank < mesh->n_subdomain);
1839  HECMW_assert(0 <= max_rank && max_rank < mesh->n_subdomain);
1840 
1841  /* min-rule for the first step, max-rule for the following steps */
1842  if (mesh->n_refine == 0) {
1843  ref_mesh->node_ID[2 * (bnode - 1) + 1] = min_rank;
1844  } else {
1845  ref_mesh->node_ID[2 * (bnode - 1) + 1] = max_rank;
1846  }
1847  }
1848 
1849  HECMW_set_int_finalize(&boundary_nodes);
1850 
1851  /* new nodes in purely external elems */
1852  if (determine_node_rank_of_purely_external_elems(mesh, ref_mesh) != HECMW_SUCCESS)
1853  return HECMW_ERROR;
1854 
1855  HECMW_log(HECMW_LOG_DEBUG, "Finished determine_node_rank.\n");
1856  return HECMW_SUCCESS;
1857 }
1858 
1859 static int *conv_index_ucd2hec(int etype)
1860 {
1861  static int conv_index_ucd2hec_rod1[] = {0, 1};
1862  static int conv_index_ucd2hec_rod2[] = {0, -1, 2};
1863  static int conv_index_ucd2hec_tri1[] = {0, 1, 2};
1864  static int conv_index_ucd2hec_tri2[] = {0, 1, 2, -1, -1, -1};
1865  static int conv_index_ucd2hec_qua1[] = {0, 1, 2, 3};
1866  static int conv_index_ucd2hec_qua2[] = {0, 1, 2, 3, -1, -1, -1, -1};
1867  static int conv_index_ucd2hec_tet1[] = {0, 3, 2, 1};
1868  static int conv_index_ucd2hec_tet2[] = {0, 3, 2, 1, -1, -1, -1, -1, -1, -1};
1869  static int conv_index_ucd2hec_pri1[] = {3, 4, 5, 0, 1, 2};
1870  static int conv_index_ucd2hec_pri2[] = {3, 4, 5, 0, 1, 2, -1, -1,
1871  -1, -1, -1, -1, -1, -1, -1};
1872  static int conv_index_ucd2hec_hex1[] = {4, 5, 6, 7, 0, 1, 2, 3};
1873  static int conv_index_ucd2hec_hex2[] = {4, 5, 6, 7, 0, 1, 2, 3, -1, -1,
1874  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
1875  static int conv_index_ucd2hec_pyr1[] = {4, 0, 1, 2, 3};
1876  static int conv_index_ucd2hec_pyr2[] = {4, 0, 1, 2, 3, -1, -1,
1877  -1, -1, -1, -1, -1, -1};
1878  static int conv_index_ucd2hec_mst1[] = {0, 1, 2, 3};
1879  static int conv_index_ucd2hec_mst2[] = {0, 1, 2, 3, -1, -1, -1, -1};
1880  static int conv_index_ucd2hec_msq1[] = {0, 1, 2, 3, 4};
1881  static int conv_index_ucd2hec_msq2[] = {0, 1, 2, 3, 4, -1, -1, -1, -1};
1882  static int conv_index_ucd2hec_jtt1[] = {3, 4, 5, 0, 1, 2};
1883  static int conv_index_ucd2hec_jtt2[] = {3, 4, 5, 0, 1, 2,
1884  -1, -1, -1, -1, -1, -1};
1885  static int conv_index_ucd2hec_jtq1[] = {4, 5, 6, 7, 0, 1, 2, 3};
1886  static int conv_index_ucd2hec_jtq2[] = {4, 5, 6, 7, 0, 1, 2, 3,
1887  -1, -1, -1, -1, -1, -1, -1, -1};
1888 #if 0
1889  static int conv_index_ucd2hec_bem1[] = {0, 1};
1890  static int conv_index_ucd2hec_bem2[] = {0, -1, 1};
1891 #endif
1892  static int conv_index_ucd2hec_sht1[] = {0, 1, 2};
1893  static int conv_index_ucd2hec_sht2[] = {0, 1, 2, -1, -1, -1};
1894  static int conv_index_ucd2hec_shq1[] = {0, 1, 2, 3};
1895  static int conv_index_ucd2hec_shq2[] = {0, 1, 2, 3, -1, -1, -1, -1};
1896  static int conv_index_ucd2hec_ln[] = {0, 1};
1897  switch (etype) {
1898  case HECMW_ETYPE_ROD1:
1899  return conv_index_ucd2hec_rod1;
1900  case HECMW_ETYPE_ROD2:
1901  return conv_index_ucd2hec_rod2;
1902  case HECMW_ETYPE_TRI1:
1903  return conv_index_ucd2hec_tri1;
1904  case HECMW_ETYPE_TRI2:
1905  return conv_index_ucd2hec_tri2;
1906  case HECMW_ETYPE_QUA1:
1907  return conv_index_ucd2hec_qua1;
1908  case HECMW_ETYPE_QUA2:
1909  return conv_index_ucd2hec_qua2;
1910  case HECMW_ETYPE_TET1:
1911  return conv_index_ucd2hec_tet1;
1912  case HECMW_ETYPE_TET2:
1913  return conv_index_ucd2hec_tet2;
1914  case HECMW_ETYPE_PRI1:
1915  return conv_index_ucd2hec_pri1;
1916  case HECMW_ETYPE_PRI2:
1917  return conv_index_ucd2hec_pri2;
1918  case HECMW_ETYPE_HEX1:
1919  return conv_index_ucd2hec_hex1;
1920  case HECMW_ETYPE_HEX2:
1921  return conv_index_ucd2hec_hex2;
1922  case HECMW_ETYPE_PYR1:
1923  return conv_index_ucd2hec_pyr1;
1924  case HECMW_ETYPE_PYR2:
1925  return conv_index_ucd2hec_pyr2;
1926  case HECMW_ETYPE_MST1:
1927  return conv_index_ucd2hec_mst1;
1928  case HECMW_ETYPE_MST2:
1929  return conv_index_ucd2hec_mst2;
1930  case HECMW_ETYPE_MSQ1:
1931  return conv_index_ucd2hec_msq1;
1932  case HECMW_ETYPE_MSQ2:
1933  return conv_index_ucd2hec_msq2;
1934  case HECMW_ETYPE_JTT1:
1935  return conv_index_ucd2hec_jtt1;
1936  case HECMW_ETYPE_JTT2:
1937  return conv_index_ucd2hec_jtt2;
1938  case HECMW_ETYPE_JTQ1:
1939  return conv_index_ucd2hec_jtq1;
1940  case HECMW_ETYPE_JTQ2:
1941  return conv_index_ucd2hec_jtq2;
1942  case HECMW_ETYPE_SHT1:
1943  return conv_index_ucd2hec_sht1;
1944  case HECMW_ETYPE_SHT2:
1945  return conv_index_ucd2hec_sht2;
1946  case HECMW_ETYPE_SHQ1:
1947  return conv_index_ucd2hec_shq1;
1948  case HECMW_ETYPE_SHQ2:
1949  return conv_index_ucd2hec_shq2;
1950  case HECMW_ETYPE_LN11:
1951  case HECMW_ETYPE_LN12:
1952  case HECMW_ETYPE_LN13:
1953  case HECMW_ETYPE_LN14:
1954  case HECMW_ETYPE_LN15:
1955  case HECMW_ETYPE_LN16:
1956  case HECMW_ETYPE_LN21:
1957  case HECMW_ETYPE_LN22:
1958  case HECMW_ETYPE_LN23:
1959  case HECMW_ETYPE_LN24:
1960  case HECMW_ETYPE_LN25:
1961  case HECMW_ETYPE_LN26:
1962  case HECMW_ETYPE_LN31:
1963  case HECMW_ETYPE_LN32:
1964  case HECMW_ETYPE_LN33:
1965  case HECMW_ETYPE_LN34:
1966  case HECMW_ETYPE_LN35:
1967  case HECMW_ETYPE_LN36:
1968  case HECMW_ETYPE_LN41:
1969  case HECMW_ETYPE_LN42:
1970  case HECMW_ETYPE_LN43:
1971  case HECMW_ETYPE_LN44:
1972  case HECMW_ETYPE_LN45:
1973  case HECMW_ETYPE_LN46:
1974  case HECMW_ETYPE_LN51:
1975  case HECMW_ETYPE_LN52:
1976  case HECMW_ETYPE_LN53:
1977  case HECMW_ETYPE_LN54:
1978  case HECMW_ETYPE_LN55:
1979  case HECMW_ETYPE_LN56:
1980  case HECMW_ETYPE_LN61:
1981  case HECMW_ETYPE_LN62:
1982  case HECMW_ETYPE_LN63:
1983  case HECMW_ETYPE_LN64:
1984  case HECMW_ETYPE_LN65:
1985  case HECMW_ETYPE_LN66:
1986  return conv_index_ucd2hec_ln;
1987  default:
1988  return NULL;
1989  }
1990 }
1991 
1992 static void write_elem_with_mismatching_refinement(const struct hecmwST_local_mesh *mesh,
1993  const struct hecmwST_local_mesh *ref_mesh,
1994  const struct hecmw_varray_int *shared,
1995  const struct hecmw_varray_int *shared_nodes,
1996  int i)
1997 {
1998  int irank = mesh->neighbor_pe[i];
1999  int j, k, l, nid;
2000  int n_shared_elem = HECMW_varray_int_nval(shared + i);
2001  int n_shared_node = HECMW_varray_int_nval(shared_nodes + i);
2002  struct hecmw_varray_int shared_elem_node_index;
2003  struct hecmw_varray_int shared_elem_node_item;
2004  int n_shared_elem_node;
2005  int n_shared_elem_r;
2006  int n_shared_elem_node_r;
2007  int *shared_elem_node_index_l = NULL;
2008  int *shared_elem_node_item_l = NULL;
2009  int *shared_elem_node_index_r = NULL;
2010  int *shared_elem_node_item_r = NULL;
2011  { /* create elem_node_index/item for shared elements */
2012  if (HECMW_varray_int_init(&shared_elem_node_index) != HECMW_SUCCESS) goto exit;
2013  if (HECMW_varray_int_init(&shared_elem_node_item) != HECMW_SUCCESS) goto exit;
2014  if (HECMW_varray_int_append(&shared_elem_node_index, 0) != HECMW_SUCCESS) goto exit;
2015  n_shared_elem_node = 0;
2016  for (j = 0; j < n_shared_elem; j++) {
2017  int eid = HECMW_varray_int_get(shared + i, j);
2018  int *elem_nodes = ref_mesh->elem_node_item + ref_mesh->elem_node_index[eid-1];
2019  long long nn = ref_mesh->elem_node_index[eid] - ref_mesh->elem_node_index[eid-1];
2020  for (k = 0; k < nn; k++) {
2021  nid = elem_nodes[k];
2022  /* find local ID within shared_nodes */
2023  for (l = 0; l < n_shared_node; l++) {
2024  if (HECMW_varray_int_get(shared_nodes + i, l) == nid) break;
2025  }
2026  if (HECMW_varray_int_append(&shared_elem_node_item, l+1) != HECMW_SUCCESS) goto exit;
2027  }
2028  n_shared_elem_node += nn;
2029  if (HECMW_varray_int_append(&shared_elem_node_index, n_shared_elem_node) != HECMW_SUCCESS) goto exit;
2030  }
2031  }
2032  shared_elem_node_index_l = HECMW_varray_int_get_v(&shared_elem_node_index);
2033  shared_elem_node_item_l = HECMW_varray_int_get_v(&shared_elem_node_item);
2034  { /* send/receive shared_elem_node_index/item */
2035  HECMW_Comm comm;
2036  HECMW_Request requests[3];
2037  HECMW_Status statuses[3];
2038  int tag;
2039  { /* send elem_node_index, elem_node_item */
2040  int send_buf[2];
2041  comm = HECMW_comm_get_comm();
2042  send_buf[0] = n_shared_elem;
2043  send_buf[1] = n_shared_elem_node;
2044  tag = 9801;
2045  HECMW_Isend(send_buf, 2, HECMW_INT, irank, tag, comm, &requests[0]);
2046  tag = 9802;
2047  HECMW_Isend(shared_elem_node_index_l, n_shared_elem + 1, HECMW_INT, irank, tag, comm, &requests[1]);
2048  tag = 9803;
2049  HECMW_Isend(shared_elem_node_item_l, n_shared_elem_node, HECMW_INT, irank, tag, comm, &requests[2]);
2050  }
2051  { /* receive elem_node_index, elem_node_item */
2052  int recv_buf[2];
2053  /* receive n_shared_elem/n_shared_elem_node */
2054  tag = 9801;
2055  HECMW_Recv(recv_buf, 2, HECMW_INT, irank, tag, comm, &statuses[0]);
2056  n_shared_elem_r = recv_buf[0];
2057  n_shared_elem_node_r = recv_buf[1];
2058  /* allocate */
2059  shared_elem_node_index_r = (int *)HECMW_malloc(sizeof(int) * (n_shared_elem_r + 1));
2060  if (shared_elem_node_index_r == NULL) {
2061  HECMW_set_error(errno, "");
2062  goto exit;
2063  }
2064  shared_elem_node_item_r = (int *)HECMW_malloc(sizeof(int) * n_shared_elem_node_r);
2065  if (shared_elem_node_item_r == NULL) {
2066  HECMW_set_error(errno, "");
2067  goto exit;
2068  }
2069  /* receive index/item */
2070  tag = 9802;
2071  HECMW_Recv(shared_elem_node_index_r, n_shared_elem_r + 1, HECMW_INT, irank, tag, comm, &statuses[1]);
2072  tag = 9803;
2073  HECMW_Recv(shared_elem_node_item_r, n_shared_elem_node_r, HECMW_INT, irank, tag, comm, &statuses[2]);
2074  }
2075  HECMW_Waitall(3, requests, statuses);
2076  }
2077  { /* compare */
2078  if (n_shared_elem != n_shared_elem_r) {
2079  HECMW_log(HECMW_LOG_ERROR, "rank %d has different number of shared elements\n", irank);
2080  goto exit;
2081  }
2082  for (j = 0; j < n_shared_elem; j++) {
2083  int is_error = 0;
2084  if (shared_elem_node_index_l[j+1] != shared_elem_node_index_r[j+1]) {
2085  HECMW_log(HECMW_LOG_ERROR, "rank %d has different number of nodes for %dth shared element\n", irank, j+1);
2086  goto exit;
2087  }
2088  for (k = shared_elem_node_index_l[j]; k < shared_elem_node_index_l[j+1]; k++) {
2089  if (shared_elem_node_item_l[k] != shared_elem_node_item_r[k]) {
2090  HECMW_log(HECMW_LOG_ERROR, "rank %d has different node for %dth node of %dth shared element\n", irank,
2091  k - shared_elem_node_index_l[j] + 1, j+1);
2092  is_error = 1;
2093  break;
2094  }
2095  }
2096  if (is_error) {
2097  int eid = HECMW_varray_int_get(shared + i, j);
2098  int *elem_nodes = ref_mesh->elem_node_item + ref_mesh->elem_node_index[eid-1];
2099  long long nn = ref_mesh->elem_node_index[eid] - ref_mesh->elem_node_index[eid-1];
2100  HECMW_log(HECMW_LOG_ERROR, "elem local ID: %d\n", eid);
2101  for (k = 0; k < nn; k++) {
2102  nid = elem_nodes[k];
2103  HECMW_log(HECMW_LOG_ERROR, "elem node (%2d) local ID: %10d, coordinates: %14.6e, %14.6e, %14.6e\n", k+1, nid,
2104  ref_mesh->node[3*(nid-1)], ref_mesh->node[3*(nid-1)+1], ref_mesh->node[3*(nid-1)+2]);
2105  }
2106  /* TODO: original element */
2107  /* TODO: origin of the node */
2108  goto exit;
2109  }
2110  }
2111  }
2112 
2113 exit:
2114  if (shared_elem_node_index_r != NULL) HECMW_free(shared_elem_node_index_r);
2115  if (shared_elem_node_item_r != NULL) HECMW_free(shared_elem_node_item_r);
2116  HECMW_varray_int_finalize(&shared_elem_node_index);
2117  HECMW_varray_int_finalize(&shared_elem_node_item);
2118 }
2119 
2120 static void write_refined_shared_in_ucd(const struct hecmwST_local_mesh *mesh,
2121  const struct hecmwST_local_mesh *ref_mesh,
2122  const struct hecmw_varray_int *shared,
2123  const struct hecmw_varray_int *shared_nodes,
2124  int i)
2125 {
2126  char fname[64];
2127  FILE *fp;
2128  int irank = mesh->neighbor_pe[i];
2129  int j, k, l, nid;
2130  int n_shared_elem = HECMW_varray_int_nval(shared + i);
2131  int n_shared_node = HECMW_varray_int_nval(shared_nodes + i);
2132  snprintf(fname, sizeof(fname), "shared_%d_%d.inp", mesh->my_rank, irank);
2133  HECMW_log(HECMW_LOG_DEBUG, "writing refined shared elements to %s\n", fname);
2134  fp = fopen(fname, "w");
2135  if (fp == NULL) {
2136  HECMW_log(HECMW_LOG_ERROR, "failed to open file %s\n", fname);
2137  } else {
2138  fprintf(fp, "%d %d 1 1 0\n", n_shared_node, n_shared_elem);
2139  for (j = 0; j < n_shared_node; j++) {
2140  nid = HECMW_varray_int_get(shared_nodes + i, j);
2141  fprintf(fp, "%d %e %e %e\n", j+1, ref_mesh->node[3*(nid-1)], ref_mesh->node[3*(nid-1)+1], ref_mesh->node[3*(nid-1)+2]);
2142  }
2143  for (j = 0; j < n_shared_elem; j++) {
2144  int eid = HECMW_varray_int_get(shared + i, j);
2145  int etype = ref_mesh->elem_type[eid-1];
2146  int *elem_nodes = ref_mesh->elem_node_item + ref_mesh->elem_node_index[eid-1];
2147  long long nn = ref_mesh->elem_node_index[eid] - ref_mesh->elem_node_index[eid-1];
2148  int *index_ucd = conv_index_ucd2hec(etype);
2149  HECMW_assert(index_ucd);
2150  fprintf(fp, "%d 0 %s", j+1, HECMW_get_ucd_label(etype));
2151  for (k = 0; k < nn; k++) {
2152  if (index_ucd[k] < 0) continue;
2153  nid = elem_nodes[index_ucd[k]];
2154  for (l = 0; l < n_shared_node; l++) {
2155  if (HECMW_varray_int_get(shared_nodes + i, l) == nid) break;
2156  }
2157  fprintf(fp, " %d", l+1);
2158  }
2159  fprintf(fp, "\n");
2160  }
2161  fclose(fp);
2162  }
2163 }
2164 
2165 static int check_node_rank(const struct hecmwST_local_mesh *mesh,
2166  const struct hecmw_varray_int *shared,
2167  const struct hecmwST_local_mesh *ref_mesh)
2168 {
2169  int *n_shared_nodes;
2170  struct hecmw_varray_int *shared_nodes, *shared_ranks;
2171  HECMW_Request *requests;
2172  HECMW_Status *statuses;
2173  HECMW_Comm comm;
2174  int *send_buf;
2175  int recv_buf[4];
2176  int n_error = 0, n_error_g;
2177  int i, j, k, irank, tag, nid, rank;
2178 
2179  HECMW_log(HECMW_LOG_DEBUG, "Started check_node_rank...\n");
2180 
2181  /* alloc memory */
2182  n_shared_nodes = (int *)HECMW_malloc(sizeof(int) * mesh->n_neighbor_pe);
2183  if (n_shared_nodes == NULL) {
2184  HECMW_set_error(errno, "");
2185  return HECMW_ERROR;
2186  }
2187 
2188  shared_nodes = (struct hecmw_varray_int *)HECMW_malloc(
2189  sizeof(struct hecmw_varray_int) * mesh->n_neighbor_pe);
2190  if (shared_nodes == NULL) {
2191  HECMW_set_error(errno, "");
2192  return HECMW_ERROR;
2193  }
2194 
2195  shared_ranks = (struct hecmw_varray_int *)HECMW_malloc(
2196  sizeof(struct hecmw_varray_int) * mesh->n_neighbor_pe);
2197  if (shared_ranks == NULL) {
2198  HECMW_set_error(errno, "");
2199  return HECMW_ERROR;
2200  }
2201 
2202  send_buf = (int *)HECMW_malloc(sizeof(int) * 4 * mesh->n_neighbor_pe);
2203  if (send_buf == NULL) {
2204  HECMW_set_error(errno, "");
2205  return HECMW_ERROR;
2206  }
2207 
2208  comm = HECMW_comm_get_comm();
2209 
2210  requests = (HECMW_Request *)HECMW_malloc(sizeof(HECMW_Request) * mesh->n_neighbor_pe);
2211  if (requests == NULL) {
2212  HECMW_set_error(errno, "");
2213  return HECMW_ERROR;
2214  }
2215 
2216  statuses = (HECMW_Status *)HECMW_malloc(sizeof(HECMW_Status) * mesh->n_neighbor_pe);
2217  if (statuses == NULL) {
2218  HECMW_set_error(errno, "");
2219  return HECMW_ERROR;
2220  }
2221 
2222  /*
2223  * check number of refined shared nodes
2224  */
2225 
2226  /* Collect nodes of the shared elements, and send size */
2227  for (i = 0; i < mesh->n_neighbor_pe; i++) {
2228  /* number of shared elements in original mesh */
2229  send_buf[4*i] = mesh->shared_index[i+1] - mesh->shared_index[i];
2230 
2231  /* number of refined shared elements */
2232  send_buf[4*i+1] = HECMW_varray_int_nval(shared + i);
2233 
2234  HECMW_varray_int_init(shared_nodes + i);
2235  for (j = 0; j < HECMW_varray_int_nval(shared + i); j++) {
2236  int eid = HECMW_varray_int_get(shared + i, j);
2237  long long nn = ref_mesh->elem_node_index[eid] - ref_mesh->elem_node_index[eid - 1];
2238  int *elem_nodes = ref_mesh->elem_node_item + ref_mesh->elem_node_index[eid - 1];
2239 
2240  for (k = 0; k < nn; k++) {
2241 #if 0 /* keep old nodes for plotting */
2242  if (elem_nodes[k] <= mesh->n_node_gross) continue; /* skip old nodes */
2243 #endif
2244 
2245  HECMW_varray_int_append(shared_nodes + i, elem_nodes[k]);
2246  }
2247  }
2248  /* number of shared nodes before removing duplication */
2249  send_buf[4*i+2] = HECMW_varray_int_nval(shared_nodes + i);
2250 
2251 #if 1
2252  HECMW_varray_int_rmdup(shared_nodes + i);
2253 #endif
2254  n_shared_nodes[i] = HECMW_varray_int_nval(shared_nodes + i);
2255 
2256  /* number of shared nodes after removing duplication */
2257  send_buf[4*i+3] = n_shared_nodes[i];
2258 
2259  /* send sizes */
2260  irank = mesh->neighbor_pe[i];
2261  tag = 9901;
2262  HECMW_Isend(send_buf + 4*i, 4, HECMW_INT, irank, tag, comm, requests + i);
2263  }
2264 
2265  /* receive size and check */
2266  for (i = 0; i < mesh->n_neighbor_pe; i++) {
2267  irank = mesh->neighbor_pe[i];
2268  tag = 9901;
2269  HECMW_Recv(recv_buf, 4, HECMW_INT, irank, tag, comm, statuses + i);
2270 
2271  if (recv_buf[0] != send_buf[4*i]) {
2273  "number of shared elements %d not match with %d in rank %d\n",
2274  send_buf[4*i], recv_buf[0], irank);
2275  n_error++;
2276  }
2277  if (recv_buf[1] != send_buf[4*i+1]) {
2279  "number of refined shared elements %d not match with %d in rank %d\n",
2280  send_buf[4*i+1], recv_buf[1], irank);
2281  }
2282  if (recv_buf[2] != send_buf[4*i+2]) {
2284  "number of new shared nodes before rmdup %d not match with %d in rank %d\n",
2285  send_buf[4*i+2], recv_buf[2], irank);
2286  n_error++;
2287  }
2288  if (recv_buf[3] != send_buf[4*i+3]) {
2290  "number of new shared nodes %d not match with %d in rank %d\n",
2291  send_buf[4*i+3], recv_buf[3], irank);
2292  n_error++;
2293  write_elem_with_mismatching_refinement(mesh, ref_mesh, shared, shared_nodes, i);
2294  write_refined_shared_in_ucd(mesh, ref_mesh, shared, shared_nodes, i);
2295  }
2296  }
2297  HECMW_Waitall(mesh->n_neighbor_pe, requests, statuses);
2298 
2299  HECMW_Allreduce(&n_error, &n_error_g, 1, HECMW_INT, HECMW_SUM, comm);
2300  if (n_error_g > 0) return HECMW_ERROR;
2301 
2302  /*
2303  * check rank of new shared nodes
2304  */
2305 
2306  n_error = 0;
2307 
2308  /* send rank of new shared nodes */
2309  for (i = 0; i < mesh->n_neighbor_pe; i++) {
2310  HECMW_varray_int_init(shared_ranks + i);
2311  /* HECMW_varray_int_resize(shared_ranks + i, n_shared_nodes[i]); */
2312  for (j = 0; j < n_shared_nodes[i]; j++) {
2313  nid = HECMW_varray_int_get(shared_nodes + i, j);
2314  rank = ref_mesh->node_ID[2 * (nid - 1) + 1];
2315  /* HECMW_varray_int_set(shared_ranks + i, j, rank); */
2316  HECMW_varray_int_append(shared_ranks + i, rank);
2317  }
2318 
2319  irank = mesh->neighbor_pe[i];
2320  tag = 9902;
2321  int *send_ranks = HECMW_varray_int_get_v(shared_ranks + i);
2322  HECMW_Isend(send_ranks, n_shared_nodes[i], HECMW_INT, irank, tag, comm, requests + i);
2323  }
2324 
2325  /* receive rank of new shared nodes */
2326  for (i = 0; i < mesh->n_neighbor_pe; i++) {
2327  int *recv_ranks = (int *)HECMW_malloc(sizeof(int) * n_shared_nodes[i]);
2328  if (recv_ranks == NULL) {
2329  HECMW_set_error(errno, "");
2330  return HECMW_ERROR;
2331  }
2332 
2333  irank = mesh->neighbor_pe[i];
2334  tag = 9902;
2335  HECMW_Recv(recv_ranks, n_shared_nodes[i], HECMW_INT, irank, tag, comm, statuses + i);
2336 
2337  for (j = 0; j < n_shared_nodes[i]; j++) {
2338  if (recv_ranks[j] != HECMW_varray_int_get(shared_ranks + i, j)) {
2340  "rank of new shared node %d: %d not match with %d in rank %d\n",
2341  HECMW_varray_int_get(shared_nodes + i, j),
2342  HECMW_varray_int_get(shared_ranks + i, j), recv_ranks[j], irank);
2343  n_error++;
2344  }
2345  }
2346  HECMW_free(recv_ranks);
2347  }
2348  HECMW_Waitall(mesh->n_neighbor_pe, requests, statuses);
2349 
2350  HECMW_Allreduce(&n_error, &n_error_g, 1, HECMW_INT, HECMW_SUM, comm);
2351  if (n_error_g > 0) return HECMW_ERROR;
2352 
2353  /* free memory */
2354  for (i = 0; i < mesh->n_neighbor_pe; i++) {
2355  HECMW_varray_int_finalize(shared_nodes + i);
2356  HECMW_varray_int_finalize(shared_ranks + i);
2357  }
2358  HECMW_free(shared_nodes);
2359  HECMW_free(shared_ranks);
2360  HECMW_free(n_shared_nodes);
2361  HECMW_free(send_buf);
2362  HECMW_free(requests);
2363  HECMW_free(statuses);
2364 
2365  HECMW_log(HECMW_LOG_DEBUG, "Finished check_node_rank.\n");
2366 
2367  return HECMW_SUCCESS;
2368 }
2369 
2370 static int count_internal(int my_rank, int n, int *ID) {
2371  int i, count = 0;
2372  for (i = 0; i < n; i++) {
2373  if (ID[2 * i + 1] == my_rank) {
2374  ID[2 * i] = ++count;
2375  }
2376  }
2377  return count;
2378 }
2379 
2380 static int count_purely_external(int n, int *ID) {
2381  int i, count = 0;
2382  for (i = 0; i < n; i++) {
2383  if (ID[2 * i + 1] < 0) {
2384  count++;
2385  }
2386  }
2387  return count;
2388 }
2389 
2390 static int *new_internal_list(int my_rank, int n, int n_internal, int *ID) {
2391  int i, k;
2392  int *internal_list;
2393 
2394  internal_list = (int *)HECMW_malloc(sizeof(int) * n_internal);
2395  if (internal_list == NULL) {
2396  HECMW_set_error(errno, "");
2397  return NULL;
2398  }
2399 
2400  for (i = 0, k = 0; i < n; i++) {
2401  if (ID[2 * i + 1] == my_rank) {
2402  internal_list[k] = i + 1;
2403  k++;
2404  }
2405  }
2406  return internal_list;
2407 }
2408 
2409 static int create_index_item(int n, const struct hecmw_varray_int *arrays,
2410  int **index, int **item) {
2411  int i, j, k;
2412 
2413  /* index */
2414  *index = (int *)HECMW_malloc(sizeof(int) * (n + 1));
2415  if (*index == NULL) {
2416  HECMW_set_error(errno, "");
2417  return HECMW_ERROR;
2418  }
2419  (*index)[0] = 0;
2420  for (i = 0; i < n; i++) {
2421  (*index)[i + 1] = (*index)[i] + HECMW_varray_int_nval(arrays + i);
2422  if ((*index)[i + 1] < (*index)[i]) {
2424  "Integer overflow detected while creating index array\n");
2425  return HECMW_ERROR;
2426  }
2427  }
2428 
2429  /* item */
2430  if ((*index)[n] == 0) {
2431  (*item) = NULL;
2432  return HECMW_SUCCESS;
2433  }
2434  *item = (int *)HECMW_malloc(sizeof(int) * (*index)[n]);
2435  if (*item == NULL) {
2436  HECMW_set_error(errno, "");
2437  return HECMW_ERROR;
2438  }
2439  k = 0;
2440  for (i = 0; i < n; i++) {
2441  for (j = 0; j < HECMW_varray_int_nval(arrays + i); j++) {
2442  (*item)[k] = HECMW_varray_int_get(arrays + i, j);
2443  k++;
2444  }
2445  }
2446  return HECMW_SUCCESS;
2447 }
2448 
2449 static int new_shared_export_import(const struct hecmwST_local_mesh *mesh,
2450  const struct hecmw_varray_int *shared,
2451  struct hecmwST_local_mesh *ref_mesh) {
2452  struct hecmw_varray_int *new_shared, *new_export, *new_import;
2453  int i;
2454 
2455  /* prepare new shared, import and export lists */
2456  new_shared = (struct hecmw_varray_int *)HECMW_malloc(
2457  sizeof(struct hecmw_varray_int) * mesh->n_neighbor_pe);
2458  if (new_shared == NULL) {
2459  HECMW_set_error(errno, "");
2460  return HECMW_ERROR;
2461  }
2462  new_export = (struct hecmw_varray_int *)HECMW_malloc(
2463  sizeof(struct hecmw_varray_int) * mesh->n_neighbor_pe);
2464  if (new_export == NULL) {
2465  HECMW_set_error(errno, "");
2466  return HECMW_ERROR;
2467  }
2468  new_import = (struct hecmw_varray_int *)HECMW_malloc(
2469  sizeof(struct hecmw_varray_int) * mesh->n_neighbor_pe);
2470  if (new_import == NULL) {
2471  HECMW_set_error(errno, "");
2472  return HECMW_ERROR;
2473  }
2474 
2475  /* for each refined shared list */
2476  for (i = 0; i < mesh->n_neighbor_pe; i++) {
2477  int j;
2478  int rank_i = mesh->neighbor_pe[i];
2479 
2480  HECMW_varray_int_init(new_shared + i);
2481  HECMW_varray_int_init(new_export + i);
2482  HECMW_varray_int_init(new_import + i);
2483 
2484  /* for each element in the list */
2485  for (j = 0; j < HECMW_varray_int_nval(shared + i); j++) {
2486  struct hecmw_varray_int exp_cand, imp_cand;
2487 
2488  int eid = HECMW_varray_int_get(shared + i, j);
2489  int nn =
2490  ref_mesh->elem_node_index[eid] - ref_mesh->elem_node_index[eid - 1];
2491  int *elem_nodes =
2492  ref_mesh->elem_node_item + ref_mesh->elem_node_index[eid - 1];
2493  int etype = ref_mesh->elem_type[eid - 1];
2494 
2495  int min_rank = mesh->n_subdomain;
2496  int myrank_included = 0;
2497  int rank_i_included = 0;
2498  int k;
2499 
2500  HECMW_varray_int_init(&exp_cand);
2501  HECMW_varray_int_init(&imp_cand);
2502 
2503  /* for each node in the element */
2504  for (k = 0; k < nn; k++) {
2505  int rank = ref_mesh->node_ID[2 * (elem_nodes[k] - 1) + 1];
2506 
2507  /* for purely external nodes, rank (0, 1, ...) is stored as -rank-1 (-1,
2508  * -2, ...) */
2509  if (rank < 0) rank = -rank - 1;
2510 
2511  if (rank < min_rank) min_rank = rank;
2512 
2513  if (rank == mesh->my_rank) {
2514  myrank_included = 1;
2515  HECMW_varray_int_append(&exp_cand, elem_nodes[k]);
2516  } else if (rank == rank_i) {
2517  rank_i_included = 1;
2518  HECMW_varray_int_append(&imp_cand, elem_nodes[k]);
2519  }
2520  }
2521  HECMW_assert(0 <= min_rank && min_rank < mesh->n_subdomain);
2522 
2523  ref_mesh->elem_ID[2 * (eid - 1) + 1] = min_rank;
2524 
2525  if (HECMW_is_etype_patch(etype)) {
2526  if (myrank_included || rank_i_included) HECMW_varray_int_append(new_shared + i, eid);
2527  if (myrank_included) HECMW_varray_int_cat(new_export + i, &exp_cand);
2528  if (rank_i_included) HECMW_varray_int_cat(new_import + i, &imp_cand);
2529  } else {
2530  if (myrank_included && rank_i_included) { /* the element is shared */
2531  HECMW_varray_int_append(new_shared + i, eid);
2532  HECMW_varray_int_cat(new_export + i, &exp_cand);
2533  HECMW_varray_int_cat(new_import + i, &imp_cand);
2534  } else if (myrank_included == 0) {
2535  /* for purely external elements, rank (0, 1, ...) is stored as -rank-1
2536  * (-1, -2, ...) */
2537  ref_mesh->elem_ID[2 * (eid - 1) + 1] = -min_rank - 1;
2538  }
2539  }
2540 
2541  HECMW_varray_int_finalize(&exp_cand);
2542  HECMW_varray_int_finalize(&imp_cand);
2543  }
2544  /* remove duplication */
2545  HECMW_varray_int_rmdup(new_export + i);
2546  HECMW_varray_int_rmdup(new_import + i);
2547  }
2548 
2549  /* new shared */
2550  if (create_index_item(mesh->n_neighbor_pe, new_shared, &(ref_mesh->shared_index),
2551  &(ref_mesh->shared_item)) != HECMW_SUCCESS) {
2552  HECMW_log(HECMW_LOG_ERROR, "Create shared_index and shared_item failed\n");
2553  return HECMW_ERROR;
2554  }
2555  HECMW_log(HECMW_LOG_DEBUG, "Total number of shared elements = %d\n",
2556  ref_mesh->shared_index[mesh->n_neighbor_pe]);
2557 
2558  /* new export */
2559  if (create_index_item(mesh->n_neighbor_pe, new_export, &(ref_mesh->export_index),
2560  &(ref_mesh->export_item)) != HECMW_SUCCESS) {
2561  HECMW_log(HECMW_LOG_ERROR, "Create export_index and export_item failed\n");
2562  return HECMW_ERROR;
2563  }
2564  HECMW_log(HECMW_LOG_DEBUG, "Total number of export nodes = %d\n",
2565  ref_mesh->export_index[mesh->n_neighbor_pe]);
2566 
2567  /* new import */
2568  if (create_index_item(mesh->n_neighbor_pe, new_import, &(ref_mesh->import_index),
2569  &(ref_mesh->import_item)) != HECMW_SUCCESS) {
2570  HECMW_log(HECMW_LOG_ERROR, "Create import_index and import_item failed\n");
2571  return HECMW_ERROR;
2572  }
2573  HECMW_log(HECMW_LOG_DEBUG, "Total number of import nodes = %d\n",
2574  ref_mesh->import_index[mesh->n_neighbor_pe]);
2575 
2576  /* deallocate new shared, import and export lists */
2577  for (i = 0; i < mesh->n_neighbor_pe; i++) {
2578  HECMW_varray_int_finalize(new_shared + i);
2579  HECMW_varray_int_finalize(new_export + i);
2580  HECMW_varray_int_finalize(new_import + i);
2581  }
2582  HECMW_free(new_shared);
2583  HECMW_free(new_export);
2584  HECMW_free(new_import);
2585 
2586  return HECMW_SUCCESS;
2587 }
2588 
2589 static int rebuild_comm_tables_serial(const struct hecmwST_local_mesh *mesh,
2590  struct hecmwST_local_mesh *ref_mesh) {
2591  int i;
2592 
2595 
2596  /* nn_internal, n_node */
2597  ref_mesh->nn_internal = count_internal(mesh->my_rank, ref_mesh->n_node_gross, ref_mesh->node_ID);
2598  ref_mesh->n_node = ref_mesh->n_node_gross;
2599  ref_mesh->nn_middle = ref_mesh->n_node;
2600 
2601  HECMW_log(HECMW_LOG_DEBUG, "nn_internal = %d, n_node = %d, nn_middle = %d\n",
2602  ref_mesh->nn_internal, ref_mesh->n_node, ref_mesh->nn_middle);
2603 
2604  /* node_internal_list */
2605  ref_mesh->node_internal_list =
2606  (int *)HECMW_malloc(sizeof(int) * ref_mesh->nn_internal);
2607  if (ref_mesh->node_internal_list == NULL) {
2608  HECMW_set_error(errno, "");
2609  return HECMW_ERROR;
2610  }
2611  for (i = 0; i < ref_mesh->nn_internal; i++) {
2612  ref_mesh->node_internal_list[i] = i + 1;
2613  }
2614 
2615  /* ne_internal, n_elem */
2616  ref_mesh->ne_internal = count_internal(mesh->my_rank, ref_mesh->n_elem_gross, ref_mesh->elem_ID);
2617  ref_mesh->n_elem = ref_mesh->n_elem_gross;
2618 
2619  HECMW_log(HECMW_LOG_DEBUG, "ne_internal = %d, n_elem = %d\n",
2620  ref_mesh->ne_internal, ref_mesh->n_elem);
2621 
2622  /* elem_internal_list */
2623  ref_mesh->elem_internal_list =
2624  (int *)HECMW_malloc(sizeof(int) * ref_mesh->ne_internal);
2625  if (ref_mesh->elem_internal_list == NULL) {
2626  HECMW_set_error(errno, "");
2627  return HECMW_ERROR;
2628  }
2629  for (i = 0; i < ref_mesh->ne_internal; i++) {
2630  ref_mesh->elem_internal_list[i] = i + 1;
2631  }
2632  return HECMW_SUCCESS;
2633 }
2634 
2635 static int mark_purely_external_nodes(int my_rank,
2636  struct hecmwST_local_mesh *ref_mesh) {
2637  struct hecmw_bit_array mark;
2638  int i;
2639 
2640  if (HECMW_bit_array_init(&mark, ref_mesh->n_node_gross) != HECMW_SUCCESS) {
2641  return HECMW_ERROR;
2642  }
2643  /* mark all nodes in the new import lists */
2644  for (i = 0; i < ref_mesh->import_index[ref_mesh->n_neighbor_pe]; i++) {
2645  HECMW_bit_array_set(&mark, ref_mesh->import_item[i] - 1);
2646  }
2647  /* scan for all external, unmarked nodes and set their rank to -rank-1 */
2648  for (i = 0; i < ref_mesh->n_node_gross; i++) {
2649  int rank = ref_mesh->node_ID[2 * i + 1];
2650  if (rank == my_rank || rank < 0) continue;
2651  if (!HECMW_bit_array_get(&mark, i)) {
2652  /* for purely external nodes, rank (0, 1, ...) is stored as -rank-1 (-1,
2653  * -2, ...) */
2654  ref_mesh->node_ID[2 * i + 1] = -rank - 1;
2655  }
2656  }
2657  HECMW_bit_array_finalize(&mark);
2658  return HECMW_SUCCESS;
2659 }
2660 
2661 static int rebuild_comm_tables(const struct hecmwST_local_mesh *mesh,
2662  struct hecmwST_local_mesh *ref_mesh) {
2663  int i;
2664  struct hecmw_varray_int *shared;
2665 
2666  if (mesh->n_neighbor_pe == 0) { /* SERIAL */
2667  return rebuild_comm_tables_serial(mesh, ref_mesh);
2668  }
2669 
2670  /* PARALLEL */
2671  HECMW_log(HECMW_LOG_DEBUG, "Started rebuilding communication tables...\n");
2672 
2673  /* check part-type */
2676  "Partitioning-type must be node-based for refinement.\n");
2677  return HECMW_ERROR;
2678  }
2679 
2680  /* Get refined shared element list */
2681  shared = (struct hecmw_varray_int *)HECMW_malloc(
2682  sizeof(struct hecmw_varray_int) * mesh->n_neighbor_pe);
2683  if (shared == NULL) {
2684  HECMW_set_error(errno, "");
2685  return HECMW_ERROR;
2686  }
2687  for (i = 0; i < mesh->n_neighbor_pe; i++) {
2688  HECMW_varray_int_init(shared + i);
2689  }
2690  if (get_refined_shared(mesh, ref_mesh, shared) != HECMW_SUCCESS) {
2691  return HECMW_ERROR;
2692  }
2693 
2694  /* Determine rank of new nodes */
2695  if (determine_node_rank(mesh, shared, ref_mesh) != HECMW_SUCCESS) {
2696  return HECMW_ERROR;
2697  }
2698 
2699  /* Check rank of new nodes with neighbor processes */
2700  if (check_node_rank(mesh, shared, ref_mesh) != HECMW_SUCCESS) {
2701  return HECMW_ERROR;
2702  }
2703 
2704  /* nn_internal */
2705  ref_mesh->nn_internal =
2706  count_internal(mesh->my_rank, ref_mesh->n_node_gross, ref_mesh->node_ID);
2707 
2709  NULL); /* because PARTTYPE is NODEBASED. */
2710 
2711  /* new shared, import and export lists */
2712  if (new_shared_export_import(mesh, shared, ref_mesh) != HECMW_SUCCESS) {
2713  return HECMW_ERROR;
2714  }
2715 
2716  /* deallocate refined shared list */
2717  for (i = 0; i < mesh->n_neighbor_pe; i++) {
2718  HECMW_varray_int_finalize(shared + i);
2719  }
2720  HECMW_free(shared);
2721 
2722  /* ne_internal */
2723  ref_mesh->ne_internal =
2724  count_internal(mesh->my_rank, ref_mesh->n_elem_gross, ref_mesh->elem_ID);
2725 
2726  /* n_elem */
2727  ref_mesh->n_elem =
2728  ref_mesh->n_elem_gross -
2729  count_purely_external(ref_mesh->n_elem_gross, ref_mesh->elem_ID);
2730 
2731  /* elem_internal_list */
2732  if (ref_mesh->ne_internal > 0) {
2733  ref_mesh->elem_internal_list =
2734  new_internal_list(mesh->my_rank, ref_mesh->n_elem_gross,
2735  ref_mesh->ne_internal, ref_mesh->elem_ID);
2736  if (ref_mesh->elem_internal_list == NULL) return HECMW_ERROR;
2737  }
2738 
2739  /* mark purely external nodes */
2740  if (mark_purely_external_nodes(mesh->my_rank, ref_mesh) != HECMW_SUCCESS) {
2741  return HECMW_ERROR;
2742  }
2743 
2744  /* n_node */
2745  ref_mesh->n_node =
2746  ref_mesh->n_node_gross -
2747  count_purely_external(ref_mesh->n_node_gross, ref_mesh->node_ID);
2748  ref_mesh->nn_middle = ref_mesh->n_node; /* not set properly (since it's never used) */
2749 
2750  HECMW_log(HECMW_LOG_DEBUG, "nn_internal = %d, n_node = %d nn_middle = %d, \n",
2751  ref_mesh->nn_internal, ref_mesh->n_node, ref_mesh->nn_middle);
2752  HECMW_log(HECMW_LOG_DEBUG, "ne_internal = %d, nelem = %d\n",
2753  ref_mesh->ne_internal, ref_mesh->n_elem);
2754 
2755  HECMW_log(HECMW_LOG_DEBUG, "Finished rebuilding communication tables.\n");
2756  return HECMW_SUCCESS;
2757 }
2758 
2759 static int check_comm_table_len(const struct hecmwST_local_mesh *ref_mesh) {
2760  int i, irank, js, je, len, tag, nsend;
2761  HECMW_Request *requests;
2762  HECMW_Status *statuses;
2763  HECMW_Comm comm;
2764  int *send_buf;
2765  int n_error = 0, n_error_g;
2766 
2767  if (ref_mesh->n_neighbor_pe == 0) return HECMW_SUCCESS;
2768 
2769  HECMW_log(HECMW_LOG_DEBUG, "Started checking communication tables...\n");
2770 
2771  comm = HECMW_comm_get_comm();
2772 
2773  send_buf = (int *)HECMW_malloc(sizeof(int) * ref_mesh->n_neighbor_pe);
2774  if (send_buf == 0) {
2775  HECMW_set_error(errno, "");
2776  HECMW_abort(comm);
2777  }
2778 
2779  requests = (HECMW_Request *)HECMW_malloc(sizeof(HECMW_Request) *
2780  ref_mesh->n_neighbor_pe);
2781  if (requests == NULL) {
2782  HECMW_set_error(errno, "");
2783  HECMW_abort(comm);
2784  }
2785  statuses = (HECMW_Status *)HECMW_malloc(sizeof(HECMW_Status) *
2786  ref_mesh->n_neighbor_pe);
2787  if (statuses == NULL) {
2788  HECMW_set_error(errno, "");
2789  HECMW_abort(comm);
2790  }
2791 
2792  /* export and import */
2793 
2794  for (i = 0; i < ref_mesh->n_neighbor_pe; i++) {
2795  irank = ref_mesh->neighbor_pe[i];
2796  js = ref_mesh->export_index[i];
2797  je = ref_mesh->export_index[i + 1];
2798  send_buf[i] = je - js;
2799  /* isend number of export nodes */
2800  tag = 0;
2801  HECMW_Isend(send_buf + i, 1, HECMW_INT, irank, tag, comm, requests + i);
2802  }
2803  for (i = 0; i < ref_mesh->n_neighbor_pe; i++) {
2804  irank = ref_mesh->neighbor_pe[i];
2805  js = ref_mesh->import_index[i];
2806  je = ref_mesh->import_index[i + 1];
2807  /* recv number of import nodes */
2808  tag = 0;
2809  HECMW_Recv(&len, 1, HECMW_INT, irank, tag, comm, statuses + i);
2810  if (len != je - js) {
2812  "inconsistent length of import (%d) with export on rank %d (%d)\n",
2813  je-js, irank, len);
2814  n_error++;
2815  }
2816  }
2817  HECMW_Waitall(ref_mesh->n_neighbor_pe, requests, statuses);
2818 
2819  /* shared */
2820 
2821  nsend = 0;
2822  for (i = 0; i < ref_mesh->n_neighbor_pe; i++) {
2823  irank = ref_mesh->neighbor_pe[i];
2824  if (irank < ref_mesh->my_rank) continue;
2825  js = ref_mesh->shared_index[i];
2826  je = ref_mesh->shared_index[i + 1];
2827  send_buf[i] = je - js;
2828  /* isend number of shared elems */
2829  tag = 1;
2830  HECMW_Isend(send_buf + i, 1, HECMW_INT, irank, tag, comm, requests + nsend);
2831  nsend++;
2832  }
2833  for (i = 0; i < ref_mesh->n_neighbor_pe; i++) {
2834  irank = ref_mesh->neighbor_pe[i];
2835  if (ref_mesh->my_rank < irank) continue;
2836  js = ref_mesh->shared_index[i];
2837  je = ref_mesh->shared_index[i + 1];
2838  /* recv number of shared elems */
2839  tag = 1;
2840  HECMW_Recv(&len, 1, HECMW_INT, irank, tag, comm, statuses);
2841  if (len != je - js) {
2843  "inconsistent length of shared (%d) with rank %d (%d)\n",
2844  je-js, irank, len);
2845  n_error++;
2846  }
2847  }
2848  HECMW_Waitall(nsend, requests, statuses);
2849 
2850  HECMW_free(send_buf);
2851  HECMW_free(requests);
2852  HECMW_free(statuses);
2853 
2854  HECMW_Allreduce(&n_error, &n_error_g, 1, HECMW_INT, HECMW_SUM, comm);
2855  if (n_error_g > 0) return HECMW_ERROR;
2856 
2857  HECMW_log(HECMW_LOG_DEBUG, "Finished checking communication tables.\n");
2858  return HECMW_SUCCESS;
2859 }
2860 
2861 static int rebuild_ID_external(struct hecmwST_local_mesh *ref_mesh) {
2862  int len_tot;
2863  int *sendbuf, *recvbuf, *srbuf;
2864  int i, j, irank, js, je, len, nid, tag, nsend, rank, lid;
2865  int *item_p, *sendbuf_p, *recvbuf_p, *srbuf_p;
2866  HECMW_Request *requests;
2867  HECMW_Status *statuses;
2868  HECMW_Comm comm;
2869 
2870  if (ref_mesh->n_neighbor_pe == 0) return HECMW_SUCCESS;
2871 
2872  HECMW_log(HECMW_LOG_DEBUG, "Started rebuilding external IDs...\n");
2873 
2874  comm = HECMW_comm_get_comm();
2875 
2876  requests = (HECMW_Request *)HECMW_malloc(sizeof(HECMW_Request) *
2877  ref_mesh->n_neighbor_pe);
2878  if (requests == NULL) {
2879  HECMW_set_error(errno, "");
2880  return HECMW_ERROR;
2881  }
2882  statuses = (HECMW_Status *)HECMW_malloc(sizeof(HECMW_Status) *
2883  ref_mesh->n_neighbor_pe);
2884  if (statuses == NULL) {
2885  HECMW_set_error(errno, "");
2886  return HECMW_ERROR;
2887  }
2888 
2889  /* node_ID (for external nodes) */
2890 
2891  /* send local IDs of export nodes */
2892  len_tot = ref_mesh->export_index[ref_mesh->n_neighbor_pe];
2893  sendbuf = (int *)HECMW_malloc(sizeof(int) * len_tot);
2894  if (sendbuf == NULL) {
2895  HECMW_set_error(errno, "");
2896  return HECMW_ERROR;
2897  }
2898  for (i = 0; i < ref_mesh->n_neighbor_pe; i++) {
2899  irank = ref_mesh->neighbor_pe[i];
2900  js = ref_mesh->export_index[i];
2901  je = ref_mesh->export_index[i + 1];
2902  len = je - js;
2903  item_p = ref_mesh->export_item + js;
2904  sendbuf_p = sendbuf + js;
2905  for (j = 0; j < len; j++) {
2906  nid = item_p[j] - 1;
2907  lid = ref_mesh->node_ID[2 * nid];
2908  HECMW_assert(0 < lid);
2909  HECMW_assert(lid <= ref_mesh->nn_internal);
2910  sendbuf_p[j] = lid;
2911  }
2912  /* isend local id of export nodes */
2913  tag = 0;
2914  HECMW_Isend(sendbuf_p, len, HECMW_INT, irank, tag, comm, requests + i);
2915  }
2916 
2917  /* recv local IDs of import nodes */
2918  len_tot = ref_mesh->import_index[ref_mesh->n_neighbor_pe];
2919  recvbuf = (int *)HECMW_malloc(sizeof(int) * len_tot);
2920  if (recvbuf == NULL) {
2921  HECMW_set_error(errno, "");
2922  return HECMW_ERROR;
2923  }
2924  for (i = 0; i < ref_mesh->n_neighbor_pe; i++) {
2925  irank = ref_mesh->neighbor_pe[i];
2926  js = ref_mesh->import_index[i];
2927  je = ref_mesh->import_index[i + 1];
2928  len = je - js;
2929  item_p = ref_mesh->import_item + js;
2930  recvbuf_p = recvbuf + js;
2931  /* recv local id of import nodes */
2932  tag = 0;
2933  HECMW_Recv(recvbuf_p, len, HECMW_INT, irank, tag, comm, statuses + i);
2934  /* set node_ID[2*j] */
2935  for (j = 0; j < len; j++) {
2936  nid = item_p[j] - 1;
2937  lid = recvbuf_p[j];
2938  HECMW_assert(0 < lid);
2939  ref_mesh->node_ID[2 * nid] = lid;
2940  }
2941  }
2942 
2943  HECMW_Waitall(ref_mesh->n_neighbor_pe, requests, statuses);
2944  HECMW_free(sendbuf);
2945  HECMW_free(recvbuf);
2946 
2947  /* elem_ID (for external elements) */
2948 
2949  len_tot = ref_mesh->shared_index[ref_mesh->n_neighbor_pe];
2950  srbuf = (int *)HECMW_malloc(sizeof(int) * len_tot);
2951  if (srbuf == NULL) {
2952  HECMW_set_error(errno, "");
2953  return HECMW_ERROR;
2954  }
2955  nsend = 0;
2956  for (i = 0; i < ref_mesh->n_neighbor_pe; i++) {
2957  irank = ref_mesh->neighbor_pe[i];
2958  if (irank < ref_mesh->my_rank) continue;
2959  js = ref_mesh->shared_index[i];
2960  je = ref_mesh->shared_index[i + 1];
2961  len = je - js;
2962  srbuf_p = srbuf + js;
2963  item_p = ref_mesh->shared_item + js;
2964  for (j = 0; j < len; j++) {
2965  nid = item_p[j] - 1;
2966  rank = ref_mesh->elem_ID[2 * nid + 1];
2967  lid = ref_mesh->elem_ID[2 * nid];
2968  if (rank == ref_mesh->my_rank && lid > 0) {
2969  HECMW_assert(lid <= ref_mesh->ne_internal);
2970  srbuf_p[j] = lid;
2971  } else {
2972  srbuf_p[j] = -1;
2973  }
2974  }
2975  /* isend list of local_ID of those elems */
2976  tag = 1;
2977  HECMW_Isend(srbuf_p, len, HECMW_INT, irank, tag, comm, requests + nsend);
2978  nsend++;
2979  }
2980  for (i = 0; i < ref_mesh->n_neighbor_pe; i++) {
2981  irank = ref_mesh->neighbor_pe[i];
2982  if (ref_mesh->my_rank < irank) continue;
2983  js = ref_mesh->shared_index[i];
2984  je = ref_mesh->shared_index[i + 1];
2985  len = je - js;
2986  srbuf_p = srbuf + js;
2987  item_p = ref_mesh->shared_item + js;
2988  /* recv list of local_ID of those elems */
2989  tag = 1;
2990  HECMW_Recv(srbuf_p, len, HECMW_INT, irank, tag, comm, statuses);
2991  /* set elem_ID[2*j] */
2992  for (j = 0; j < len; j++) {
2993  lid = srbuf_p[j];
2994  if (lid < 0) continue;
2995  nid = item_p[j] - 1;
2996  rank = ref_mesh->elem_ID[2 * nid + 1];
2997  HECMW_assert(rank == irank || rank == -irank - 1);
2998  if (rank < 0) continue;
2999  ref_mesh->elem_ID[2 * nid] = lid;
3000  }
3001  }
3002  HECMW_Waitall(nsend, requests, statuses);
3003  HECMW_free(srbuf);
3004 
3005  HECMW_free(requests);
3006  HECMW_free(statuses);
3007 
3008  HECMW_log(HECMW_LOG_DEBUG, "Finished rebuilding external IDs.\n");
3009  return HECMW_SUCCESS;
3010 }
3011 
3012 static int rebuild_refine_origin(const struct hecmwST_local_mesh *mesh,
3013  struct hecmwST_local_mesh *ref_mesh) {
3014  const struct hecmwST_refine_origin *reforg;
3015  struct hecmwST_refine_origin *ref_reforg;
3016  struct hecmw_varray_int ro_item;
3017  const int *ro_item_v;
3018  int n_refine, offset, cnt, cnt2, i, j;
3019 
3020  reforg = mesh->refine_origin;
3021  n_refine = mesh->n_refine + 1;
3022 
3023  ref_reforg = (struct hecmwST_refine_origin *)HECMW_malloc(
3024  sizeof(struct hecmwST_refine_origin));
3025  if (ref_reforg == NULL) {
3026  HECMW_set_error(errno, "");
3027  return HECMW_ERROR;
3028  }
3029 
3030  ref_reforg->index = (int *)HECMW_malloc(sizeof(int) * (n_refine + 1));
3031  if (ref_reforg->index == NULL) {
3032  HECMW_set_error(errno, "");
3033  return HECMW_ERROR;
3034  }
3035  ref_reforg->index[0] = 0;
3036  for (i = 1; i < n_refine; i++) {
3037  ref_reforg->index[i] = reforg->index[i];
3038  }
3039  ref_reforg->index[n_refine] =
3040  ref_reforg->index[n_refine - 1] + ref_mesh->n_node;
3041 
3042  ref_reforg->item_index =
3043  (int *)HECMW_malloc(sizeof(int) * (ref_reforg->index[n_refine] + 1));
3044  if (ref_reforg->item_index == NULL) {
3045  HECMW_set_error(errno, "");
3046  return HECMW_ERROR;
3047  }
3048 
3049  /* copy original-node information up to previous refinement */
3050  ref_reforg->item_index[0] = 0;
3051  for (i = 1; i <= ref_reforg->index[n_refine - 1]; i++) {
3052  ref_reforg->item_index[i] = reforg->item_index[i];
3053  }
3054  offset = ref_reforg->index[n_refine - 1];
3055  cnt = ref_reforg->item_index[offset];
3056  /* fprintf(stderr, "offset=%d, cnt=%d\n", offset, cnt); */
3057 
3058  /* get original nodes of newly generated nodes at current refinement */
3059  HECMW_varray_int_init(&ro_item);
3060  for (i = 0; i < ref_mesh->n_node; i++) {
3061  int iold;
3062  iold = ref_mesh->node_new2old ? ref_mesh->node_new2old[i] : i;
3063  if (iold < mesh->n_node_gross) {
3064  int org;
3065  org = mesh->node_old2new ? mesh->node_old2new[iold] + 1 : iold + 1;
3066  HECMW_varray_int_append(&ro_item, org);
3067  cnt++;
3068  } else {
3069  int original[HECMW_MAX_NODE_MAX];
3070  int orig_type_rcap = rcapGetOriginal(iold + 1, original);
3071  int nn;
3072  HECMW_assert(orig_type_rcap != RCAP_UNKNOWNTYPE);
3073  nn = get_rcap_elem_max_node(orig_type_rcap);
3074  for (j = 0; j < nn; j++) {
3075  int org = original[j];
3076  if (mesh->node_old2new) org = mesh->node_old2new[org - 1] + 1;
3077  HECMW_varray_int_append(&ro_item, org);
3078  }
3079  cnt += nn;
3080  }
3081  ref_reforg->item_index[offset + i + 1] = cnt;
3082  }
3083 
3084  ref_reforg->item_item = (int *)HECMW_malloc(sizeof(int) * cnt);
3085  if (ref_reforg->item_item == NULL) {
3086  HECMW_set_error(errno, "");
3087  return HECMW_ERROR;
3088  }
3089 
3090  /* copy original nodes generated until previous refinements */
3091  cnt = ref_reforg->item_index[ref_reforg->index[n_refine - 1]];
3092  for (i = 0; i < cnt; i++) {
3093  ref_reforg->item_item[i] = reforg->item_item[i];
3094  }
3095  /* copy original nodes generated at current refinement */
3096  cnt2 = HECMW_varray_int_nval(&ro_item);
3097  ro_item_v = HECMW_varray_int_get_cv(&ro_item);
3098  for (i = 0; i < cnt2; i++) {
3099  ref_reforg->item_item[cnt + i] = ro_item_v[i];
3100  }
3101  HECMW_varray_int_finalize(&ro_item);
3102 #if 0
3103  fprintf(stderr, "refine_origin->index:\n");
3104  for( i=0; i <= n_refine; i++ ) {
3105  fprintf(stderr, " %d", ref_reforg->index[i]);
3106  if( i % 10 == 9 ) fprintf(stderr, "\n");
3107  }
3108  if( i % 10 != 0 ) fprintf(stderr, "\n");
3109  fprintf(stderr, "refine_origin->item_index:\n");
3110  for( i=0; i <= ref_reforg->index[n_refine]; i++) {
3111  fprintf(stderr, " %d", ref_reforg->item_index[i]);
3112  if( i % 10 == 9 ) fprintf(stderr, "\n");
3113  }
3114  if( i % 10 != 0 ) fprintf(stderr, "\n");
3115  fprintf(stderr, "refine_origin->item_item:\n");
3116  for( i=0; i < ref_reforg->item_index[ref_reforg->index[n_refine]]; i++ ) {
3117  fprintf(stderr, " %d", ref_reforg->item_item[i]);
3118  if( i % 10 == 9 ) fprintf(stderr, "\n");
3119  }
3120  if( i % 10 != 0 ) fprintf(stderr, "\n");
3121 #endif
3122  ref_mesh->refine_origin = ref_reforg;
3123  return HECMW_SUCCESS;
3124 }
3125 
3126 static int rebuild_n_node_refine_hist(const struct hecmwST_local_mesh *mesh,
3127  struct hecmwST_local_mesh *ref_mesh) {
3128  int i;
3129 
3130  ref_mesh->n_node_refine_hist =
3131  (int *)HECMW_malloc((mesh->n_refine + 1) * sizeof(int));
3132  if (ref_mesh->n_node_refine_hist == NULL) {
3133  HECMW_set_error(errno, "");
3134  return HECMW_ERROR;
3135  }
3136 
3137  for (i = 0; i < mesh->n_refine; i++) {
3138  ref_mesh->n_node_refine_hist[i] = mesh->n_node_refine_hist[i];
3139  }
3140  ref_mesh->n_node_refine_hist[mesh->n_refine] = ref_mesh->n_node_gross;
3141 
3142  return HECMW_SUCCESS;
3143 }
3144 
3145 static int rebuild_refine_info(const struct hecmwST_local_mesh *mesh,
3146  struct hecmwST_local_mesh *ref_mesh) {
3147  ref_mesh->n_refine = mesh->n_refine + 1;
3148 
3149  if (rebuild_refine_origin(mesh, ref_mesh) != HECMW_SUCCESS)
3150  return HECMW_ERROR;
3151  if (rebuild_n_node_refine_hist(mesh, ref_mesh) != HECMW_SUCCESS)
3152  return HECMW_ERROR;
3153 
3154  return HECMW_SUCCESS;
3155 }
3156 
3157 static int renumber_nodes_generate_tables(struct hecmwST_local_mesh *mesh);
3158 static int renumber_elements_generate_tables(struct hecmwST_local_mesh *mesh);
3159 
3160 static int rebuild_info(const struct hecmwST_local_mesh *mesh,
3161  struct hecmwST_local_mesh *ref_mesh) {
3162  HECMW_log(HECMW_LOG_DEBUG, "Started rebuilding info...\n");
3163 
3164  if (rebuild_elem_info(mesh, ref_mesh) != HECMW_SUCCESS) return HECMW_ERROR;
3165  if (rebuild_node_info(mesh, ref_mesh) != HECMW_SUCCESS) return HECMW_ERROR;
3166  if (rebuild_comm_tables(mesh, ref_mesh) != HECMW_SUCCESS) return HECMW_ERROR;
3167  if (check_comm_table_len(ref_mesh) != HECMW_SUCCESS) {
3168  HECMW_log(HECMW_LOG_ERROR, "Check communication table failed. Checking original mesh...\n");
3169  if (check_comm_table_len(mesh) != HECMW_SUCCESS) {
3170  HECMW_log(HECMW_LOG_ERROR, "Original mesh has error\n");
3171  } else {
3172  HECMW_log(HECMW_LOG_ERROR, "Original mesh is OK\n");
3173  }
3174  return HECMW_ERROR;
3175  }
3176  if (rebuild_ID_external(ref_mesh) != HECMW_SUCCESS) return HECMW_ERROR;
3177 
3178  if (renumber_nodes_generate_tables(ref_mesh) != HECMW_SUCCESS)
3179  return HECMW_ERROR;
3180  if (renumber_elements_generate_tables(ref_mesh) != HECMW_SUCCESS)
3181  return HECMW_ERROR;
3182 
3183  if (rebuild_refine_info(mesh, ref_mesh) != HECMW_SUCCESS) return HECMW_ERROR;
3184 
3185  HECMW_log(HECMW_LOG_DEBUG, "Finished rebuilding info.\n");
3186  return HECMW_SUCCESS;
3187 }
3188 
3189 /*============================================================================*/
3190 /* */
3191 /* copy unchanging information */
3192 /* */
3193 /*============================================================================*/
3194 static int copy_global_info(const struct hecmwST_local_mesh *mesh,
3195  struct hecmwST_local_mesh *ref_mesh) {
3196  int i;
3197 
3198  ref_mesh->hecmw_flag_adapt = mesh->hecmw_flag_adapt;
3204  strcpy(ref_mesh->gridfile, mesh->gridfile);
3205  ref_mesh->hecmw_n_file = mesh->hecmw_n_file;
3206 
3207  /* files */
3208  if (mesh->hecmw_n_file > 0) {
3209  ref_mesh->files = (char **)HECMW_calloc(mesh->hecmw_n_file, sizeof(char *));
3210  if (ref_mesh->files == NULL) {
3211  HECMW_set_error(errno, "");
3212  return HECMW_ERROR;
3213  }
3214  for (i = 0; i < mesh->hecmw_n_file; i++) {
3215  ref_mesh->files[i] = HECMW_strdup(mesh->files[i]);
3216  if (ref_mesh->files[i] == NULL) {
3217  HECMW_set_error(errno, "");
3218  return HECMW_ERROR;
3219  }
3220  }
3221  } else {
3222  ref_mesh->files = NULL;
3223  }
3224 
3225  strcpy(ref_mesh->header, mesh->header);
3226  ref_mesh->zero_temp = mesh->zero_temp;
3227 
3228  return HECMW_SUCCESS;
3229 }
3230 
3231 static int copy_node_ndof(const struct hecmwST_local_mesh *mesh,
3232  struct hecmwST_local_mesh *ref_mesh) {
3233  int i;
3234 
3235  ref_mesh->n_dof = mesh->n_dof;
3236  ref_mesh->n_dof_grp = mesh->n_dof_grp;
3237  ref_mesh->n_dof_tot = mesh->n_dof_tot;
3238 
3239  if (mesh->n_dof_grp > 0) {
3240  /* node_dof_index */
3241  ref_mesh->node_dof_index =
3242  (int *)HECMW_malloc(sizeof(int) * (mesh->n_dof_grp + 1));
3243  if (ref_mesh->node_dof_index == NULL) {
3244  HECMW_set_error(errno, "");
3245  return HECMW_ERROR;
3246  }
3247  for (i = 0; i < mesh->n_dof_grp + 1; i++) {
3248  ref_mesh->node_dof_index[i] = mesh->node_dof_index[i];
3249  }
3250 
3251  /* node_dof_item */
3252  ref_mesh->node_dof_item =
3253  (int *)HECMW_malloc(sizeof(int) * mesh->n_dof_grp);
3254  if (ref_mesh->node_dof_item == NULL) {
3255  HECMW_set_error(errno, "");
3256  return HECMW_ERROR;
3257  }
3258  for (i = 0; i < mesh->n_dof_grp; i++) {
3259  ref_mesh->node_dof_item[i] = mesh->node_dof_item[i];
3260  }
3261  }
3262  return HECMW_SUCCESS;
3263 }
3264 
3265 static int copy_elem_etype(const struct hecmwST_local_mesh *mesh,
3266  struct hecmwST_local_mesh *ref_mesh) {
3267  int i;
3268 
3269  ref_mesh->n_elem_type = mesh->n_elem_type;
3270 
3271  if (mesh->n_elem_type > 0) {
3272  /* elem_type_index */
3273  ref_mesh->elem_type_index =
3274  (int *)HECMW_malloc(sizeof(int) * (mesh->n_elem_type + 1));
3275  if (ref_mesh->elem_type_index == NULL) {
3276  HECMW_set_error(errno, "");
3277  return HECMW_ERROR;
3278  }
3279 
3280  /* elem_type_item */
3281  ref_mesh->elem_type_item =
3282  (int *)HECMW_malloc(sizeof(int) * mesh->n_elem_type);
3283  if (ref_mesh->elem_type_item == NULL) {
3284  HECMW_set_error(errno, "");
3285  return HECMW_ERROR;
3286  }
3287 
3288  ref_mesh->elem_type_index[0] = 0;
3289  for (i = 0; i < mesh->n_elem_type; i++) {
3290  int etype, ierror, ndiv, nelem;
3291  etype = mesh->elem_type_item[i];
3292  ndiv = get_elem_ndiv(etype, &ierror);
3293  if (ierror) return HECMW_ERROR;
3294  nelem = mesh->elem_type_index[i + 1] - mesh->elem_type_index[i];
3295  ref_mesh->elem_type_index[i + 1] =
3296  ref_mesh->elem_type_index[i] + nelem * ndiv;
3297  ref_mesh->elem_type_item[i] = etype;
3298  }
3299  }
3300  return HECMW_SUCCESS;
3301 }
3302 
3303 static int copy_comm_info(const struct hecmwST_local_mesh *mesh,
3304  struct hecmwST_local_mesh *ref_mesh) {
3305  int i;
3306 
3307  ref_mesh->zero = mesh->zero;
3308  ref_mesh->HECMW_COMM = mesh->HECMW_COMM;
3309  ref_mesh->PETOT = mesh->PETOT;
3310  ref_mesh->PEsmpTOT = mesh->PEsmpTOT;
3311  ref_mesh->my_rank = mesh->my_rank;
3312  ref_mesh->errnof = mesh->errnof;
3313  ref_mesh->n_subdomain = mesh->n_subdomain;
3314  ref_mesh->n_neighbor_pe = mesh->n_neighbor_pe;
3315 
3316  if (mesh->n_neighbor_pe == 0) {
3317  ref_mesh->neighbor_pe = NULL;
3318  ref_mesh->import_item = NULL;
3319  ref_mesh->export_item = NULL;
3320  ref_mesh->shared_item = NULL;
3321 
3322  ref_mesh->import_index = (int *)HECMW_malloc(sizeof(int));
3323  if (ref_mesh->import_index == NULL) {
3324  HECMW_set_error(errno, "");
3325  return HECMW_ERROR;
3326  }
3327  ref_mesh->import_index[0] = 0;
3328 
3329  ref_mesh->export_index = (int *)HECMW_malloc(sizeof(int));
3330  if (ref_mesh->export_index == NULL) {
3331  HECMW_set_error(errno, "");
3332  return HECMW_ERROR;
3333  }
3334  ref_mesh->export_index[0] = 0;
3335 
3336  ref_mesh->shared_index = (int *)HECMW_malloc(sizeof(int));
3337  if (ref_mesh->shared_index == NULL) {
3338  HECMW_set_error(errno, "");
3339  return HECMW_ERROR;
3340  }
3341  ref_mesh->shared_index[0] = 0;
3342 
3343  return HECMW_SUCCESS;
3344  }
3345 
3346  /* neighbor_pe */
3347  ref_mesh->neighbor_pe =
3348  (int *)HECMW_malloc(sizeof(int) * mesh->n_neighbor_pe);
3349  if (ref_mesh->neighbor_pe == NULL) {
3350  HECMW_set_error(errno, "");
3351  return HECMW_ERROR;
3352  }
3353  for (i = 0; i < mesh->n_neighbor_pe; i++) {
3354  ref_mesh->neighbor_pe[i] = mesh->neighbor_pe[i];
3355  }
3356 
3357  return HECMW_SUCCESS;
3358 }
3359 
3360 static int copy_adapt_info(const struct hecmwST_local_mesh *mesh,
3361  struct hecmwST_local_mesh *ref_mesh) {
3362  if (mesh->hecmw_flag_adapt != 0) {
3363  HECMW_log(HECMW_LOG_ERROR, "Refinement of adaptation not supported\n");
3364  return HECMW_ERROR;
3365  }
3366  ref_mesh->coarse_grid_level = 0;
3367  ref_mesh->n_adapt = 0;
3368  ref_mesh->when_i_was_refined_node = NULL;
3369  ref_mesh->when_i_was_refined_elem = NULL;
3370  ref_mesh->adapt_parent_type = NULL;
3371  ref_mesh->adapt_type = NULL;
3372  ref_mesh->adapt_level = NULL;
3373  ref_mesh->adapt_parent = NULL;
3374  ref_mesh->adapt_children_index = NULL;
3375  ref_mesh->adapt_children_item = NULL;
3376  return HECMW_SUCCESS;
3377 }
3378 
3379 static int copy_section_info(const struct hecmwST_section *sect,
3380  struct hecmwST_section *ref_sect) {
3381  int i;
3382 
3383  ref_sect->n_sect = sect->n_sect;
3384 
3385  if (sect->n_sect == 0) {
3386  ref_sect->sect_type = NULL;
3387  ref_sect->sect_opt = NULL;
3388  ref_sect->sect_mat_ID_index = NULL;
3389  ref_sect->sect_mat_ID_item = NULL;
3390  ref_sect->sect_I_index = NULL;
3391  ref_sect->sect_I_item = NULL;
3392  ref_sect->sect_R_index = NULL;
3393  ref_sect->sect_R_item = NULL;
3394  return HECMW_SUCCESS;
3395  }
3396 
3397  /* sect_type */
3398  ref_sect->sect_type = (int *)HECMW_malloc(sizeof(int) * sect->n_sect);
3399  if (ref_sect->sect_type == NULL) {
3400  HECMW_set_error(errno, "");
3401  return HECMW_ERROR;
3402  }
3403  for (i = 0; i < sect->n_sect; i++) {
3404  ref_sect->sect_type[i] = sect->sect_type[i];
3405  }
3406 
3407  /* sect_opt */
3408  ref_sect->sect_opt = (int *)HECMW_malloc(sizeof(int) * sect->n_sect);
3409  if (ref_sect->sect_opt == NULL) {
3410  HECMW_set_error(errno, "");
3411  return HECMW_ERROR;
3412  }
3413  for (i = 0; i < sect->n_sect; i++) {
3414  ref_sect->sect_opt[i] = sect->sect_opt[i];
3415  }
3416 
3417  /* sect_mat_ID_index */
3418  ref_sect->sect_mat_ID_index =
3419  (int *)HECMW_malloc(sizeof(int) * (sect->n_sect + 1));
3420  if (ref_sect->sect_mat_ID_index == NULL) {
3421  HECMW_set_error(errno, "");
3422  return HECMW_ERROR;
3423  }
3424  for (i = 0; i < sect->n_sect + 1; i++) {
3425  ref_sect->sect_mat_ID_index[i] = sect->sect_mat_ID_index[i];
3426  }
3427 
3428  /* sect_mat_ID_item */
3429  if (sect->sect_mat_ID_index[sect->n_sect] > 0) {
3430  ref_sect->sect_mat_ID_item = (int *)HECMW_malloc(
3431  sizeof(int) * sect->sect_mat_ID_index[sect->n_sect]);
3432  if (ref_sect->sect_mat_ID_item == NULL) {
3433  HECMW_set_error(errno, "");
3434  return HECMW_ERROR;
3435  }
3436  for (i = 0; i < sect->sect_mat_ID_index[sect->n_sect]; i++) {
3437  ref_sect->sect_mat_ID_item[i] = sect->sect_mat_ID_item[i];
3438  }
3439  }
3440 
3441  /* sect_I_index */
3442  ref_sect->sect_I_index =
3443  (int *)HECMW_malloc(sizeof(int) * (sect->n_sect + 1));
3444  if (ref_sect->sect_I_index == NULL) {
3445  HECMW_set_error(errno, "");
3446  return HECMW_ERROR;
3447  }
3448  for (i = 0; i < sect->n_sect + 1; i++) {
3449  ref_sect->sect_I_index[i] = sect->sect_I_index[i];
3450  }
3451 
3452  /* sect_I_item */
3453  if (sect->sect_I_index[sect->n_sect] > 0) {
3454  ref_sect->sect_I_item =
3455  (int *)HECMW_malloc(sizeof(int) * sect->sect_I_index[sect->n_sect]);
3456  if (ref_sect->sect_I_item == NULL) {
3457  HECMW_set_error(errno, "");
3458  return HECMW_ERROR;
3459  }
3460  for (i = 0; i < sect->sect_I_index[sect->n_sect]; i++) {
3461  ref_sect->sect_I_item[i] = sect->sect_I_item[i];
3462  }
3463  }
3464 
3465  /* sect_R_index */
3466  ref_sect->sect_R_index =
3467  (int *)HECMW_malloc(sizeof(int) * (sect->n_sect + 1));
3468  if (ref_sect->sect_R_index == NULL) {
3469  HECMW_set_error(errno, "");
3470  return HECMW_ERROR;
3471  }
3472  for (i = 0; i < sect->n_sect + 1; i++) {
3473  ref_sect->sect_R_index[i] = sect->sect_R_index[i];
3474  }
3475 
3476  /* sect_R_item */
3477  if (sect->sect_R_index[sect->n_sect] > 0) {
3478  ref_sect->sect_R_item = (double *)HECMW_malloc(
3479  sizeof(double) * sect->sect_R_index[sect->n_sect]);
3480  if (ref_sect->sect_R_item == NULL) {
3481  HECMW_set_error(errno, "");
3482  return HECMW_ERROR;
3483  }
3484  for (i = 0; i < sect->sect_R_index[sect->n_sect]; i++) {
3485  ref_sect->sect_R_item[i] = sect->sect_R_item[i];
3486  }
3487  }
3488 
3489  return HECMW_SUCCESS;
3490 }
3491 
3492 static int copy_material_info(const struct hecmwST_material *mat,
3493  struct hecmwST_material *ref_mat) {
3494  int i;
3495 
3496  ref_mat->n_mat = mat->n_mat;
3497 
3498  if (mat->n_mat == 0) {
3499  ref_mat->n_mat_item = 0;
3500  ref_mat->n_mat_subitem = 0;
3501  ref_mat->n_mat_table = 0;
3502  ref_mat->mat_name = NULL;
3503  ref_mat->mat_item_index = NULL;
3504  ref_mat->mat_subitem_index = NULL;
3505  ref_mat->mat_table_index = NULL;
3506  ref_mat->mat_val = NULL;
3507  ref_mat->mat_temp = NULL;
3508  return HECMW_SUCCESS;
3509  }
3510 
3511  ref_mat->n_mat_item = mat->n_mat_item;
3512  ref_mat->n_mat_subitem = mat->n_mat_subitem;
3513  ref_mat->n_mat_table = mat->n_mat_table;
3514 
3515  /* mat_name */
3516  ref_mat->mat_name = (char **)HECMW_malloc(sizeof(char *) * mat->n_mat);
3517  if (ref_mat->mat_name == NULL) {
3518  HECMW_set_error(errno, "");
3519  return HECMW_ERROR;
3520  }
3521  for (i = 0; i < mat->n_mat; i++) {
3522  ref_mat->mat_name[i] = HECMW_strdup(mat->mat_name[i]);
3523  if (ref_mat->mat_name[i] == NULL) {
3524  HECMW_set_error(errno, "");
3525  return HECMW_ERROR;
3526  }
3527  }
3528 
3529  /* mat_item_index */
3530  ref_mat->mat_item_index = (int *)HECMW_malloc(sizeof(int) * (mat->n_mat + 1));
3531  if (ref_mat->mat_item_index == NULL) {
3532  HECMW_set_error(errno, "");
3533  return HECMW_ERROR;
3534  }
3535  for (i = 0; i < mat->n_mat + 1; i++) {
3536  ref_mat->mat_item_index[i] = mat->mat_item_index[i];
3537  }
3538 
3539  /* mat_subitem_index */
3540  ref_mat->mat_subitem_index =
3541  (int *)HECMW_malloc(sizeof(int) * (mat->n_mat_item + 1));
3542  if (ref_mat->mat_subitem_index == NULL) {
3543  HECMW_set_error(errno, "");
3544  return HECMW_ERROR;
3545  }
3546  for (i = 0; i < mat->n_mat_item + 1; i++) {
3547  ref_mat->mat_subitem_index[i] = mat->mat_subitem_index[i];
3548  }
3549 
3550  /* mat_table_index */
3551  ref_mat->mat_table_index =
3552  (int *)HECMW_malloc(sizeof(int) * (mat->n_mat_subitem + 1));
3553  if (ref_mat->mat_table_index == NULL) {
3554  HECMW_set_error(errno, "");
3555  return HECMW_ERROR;
3556  }
3557  for (i = 0; i < mat->n_mat_subitem + 1; i++) {
3558  ref_mat->mat_table_index[i] = mat->mat_table_index[i];
3559  }
3560 
3561  /* mat_val */
3562  ref_mat->mat_val = (double *)HECMW_malloc(sizeof(double) * mat->n_mat_table);
3563  if (ref_mat->mat_val == NULL) {
3564  HECMW_set_error(errno, "");
3565  return HECMW_ERROR;
3566  }
3567  for (i = 0; i < mat->n_mat_table; i++) {
3568  ref_mat->mat_val[i] = mat->mat_val[i];
3569  }
3570 
3571  /* mat_temp */
3572  ref_mat->mat_temp = (double *)HECMW_malloc(sizeof(double) * mat->n_mat_table);
3573  if (ref_mat->mat_temp == NULL) {
3574  HECMW_set_error(errno, "");
3575  return HECMW_ERROR;
3576  }
3577  for (i = 0; i < mat->n_mat_table; i++) {
3578  ref_mat->mat_temp[i] = mat->mat_temp[i];
3579  }
3580 
3581  return HECMW_SUCCESS;
3582 }
3583 
3584 static int copy_mpc_info(const struct hecmwST_mpc *mpc,
3585  struct hecmwST_mpc *ref_mpc) {
3586  int i;
3587 
3588  ref_mpc->n_mpc = mpc->n_mpc;
3589 
3590  if (mpc->n_mpc == 0) {
3591  ref_mpc->mpc_item = NULL;
3592  ref_mpc->mpc_dof = NULL;
3593  ref_mpc->mpc_val = NULL;
3594  ref_mpc->mpc_const = NULL;
3595  ref_mpc->mpc_index = HECMW_malloc(sizeof(int));
3596  if (ref_mpc->mpc_index == NULL) {
3597  HECMW_set_error(errno, "");
3598  return HECMW_ERROR;
3599  }
3600  ref_mpc->mpc_index[0] = 0;
3601  return HECMW_SUCCESS;
3602  }
3603 
3604 #if 0
3605  HECMW_log(HECMW_LOG_ERROR, "refinement of MPC information is not supported\n");
3606  return HECMW_ERROR;
3607 
3608 #else
3609  HECMW_log(HECMW_LOG_WARN, "MPC information is not refined\n");
3610 
3611  /* mpc_index */
3612  ref_mpc->mpc_index = (int *) HECMW_malloc( sizeof(int) * (mpc->n_mpc+1) );
3613  if( ref_mpc->mpc_index == NULL ) {
3614  HECMW_set_error(errno, "");
3615  return HECMW_ERROR;
3616  }
3617  for ( i = 0; i < mpc->n_mpc + 1; i++ ) {
3618  ref_mpc->mpc_index[i] = mpc->mpc_index[i];
3619  }
3620 
3621  /* mpc_item */
3622  ref_mpc->mpc_item = (int *) HECMW_malloc( sizeof(int) * mpc->mpc_index[mpc->n_mpc] );
3623  if( ref_mpc->mpc_item == NULL ) {
3624  HECMW_set_error(errno, "");
3625  return HECMW_ERROR;
3626  }
3627  for ( i = 0; i < mpc->mpc_index[mpc->n_mpc]; i++ ) {
3628  ref_mpc->mpc_item[i] = mpc->mpc_item[i];
3629  }
3630 
3631  /* mpc_dof */
3632  ref_mpc->mpc_dof = (int *) HECMW_malloc( sizeof(int) * mpc->mpc_index[mpc->n_mpc] );
3633  if( ref_mpc->mpc_dof == NULL ) {
3634  HECMW_set_error(errno, "");
3635  return HECMW_ERROR;
3636  }
3637  for ( i = 0; i < mpc->mpc_index[mpc->n_mpc]; i++ ) {
3638  ref_mpc->mpc_dof[i] = mpc->mpc_dof[i];
3639  }
3640 
3641  /* mpc_val */
3642  ref_mpc->mpc_val = (double *) HECMW_malloc( sizeof(double) * mpc->mpc_index[mpc->n_mpc] );
3643  if( ref_mpc->mpc_val == NULL ) {
3644  HECMW_set_error(errno, "");
3645  return HECMW_ERROR;
3646  }
3647  for ( i = 0; i < mpc->mpc_index[mpc->n_mpc]; i++ ) {
3648  ref_mpc->mpc_val[i] = mpc->mpc_val[i];
3649  }
3650 
3651  /* mpc_const */
3652  ref_mpc->mpc_const = (double *) HECMW_malloc( sizeof(double) * mpc->n_mpc );
3653  if( ref_mpc->mpc_const == NULL ) {
3654  HECMW_set_error(errno, "");
3655  return HECMW_ERROR;
3656  }
3657  for ( i = 0; i < mpc->n_mpc; i++ ) {
3658  ref_mpc->mpc_const[i] = mpc->mpc_const[i];
3659  }
3660 
3661  return HECMW_SUCCESS;
3662 #endif
3663 }
3664 
3665 static int copy_amp_info(const struct hecmwST_amplitude *amp,
3666  struct hecmwST_amplitude *ref_amp) {
3667  int i;
3668 
3669  ref_amp->n_amp = amp->n_amp;
3670 
3671  if (amp->n_amp <= 0) {
3672  ref_amp->amp_name = NULL;
3673  ref_amp->amp_type_definition = NULL;
3674  ref_amp->amp_type_time = NULL;
3675  ref_amp->amp_type_value = NULL;
3676  ref_amp->amp_val = NULL;
3677  ref_amp->amp_table = NULL;
3678  ref_amp->amp_index = (int *)HECMW_malloc(sizeof(int));
3679  if (ref_amp->amp_index == NULL) {
3680  HECMW_set_error(errno, "");
3681  return HECMW_ERROR;
3682  }
3683  ref_amp->amp_index[0] = 0;
3684  return HECMW_SUCCESS;
3685  }
3686 
3687  /* amp_name */
3688  ref_amp->amp_name = (char **)HECMW_malloc(sizeof(char *) * amp->n_amp);
3689  if (ref_amp->amp_name == NULL) {
3690  HECMW_set_error(errno, "");
3691  return HECMW_ERROR;
3692  }
3693  for (i = 0; i < amp->n_amp; i++) {
3694  ref_amp->amp_name[i] = HECMW_strdup(amp->amp_name[i]);
3695  if (ref_amp->amp_name[i] == NULL) {
3696  HECMW_set_error(errno, "");
3697  return HECMW_ERROR;
3698  }
3699  }
3700 
3701  /* amp_type_definition */
3702  ref_amp->amp_type_definition = (int *)HECMW_malloc(sizeof(int) * amp->n_amp);
3703  if (ref_amp->amp_type_definition == NULL) {
3704  HECMW_set_error(errno, "");
3705  return HECMW_ERROR;
3706  }
3707  for (i = 0; i < amp->n_amp; i++) {
3708  ref_amp->amp_type_definition[i] = amp->amp_type_definition[i];
3709  }
3710 
3711  /* amp_type_time */
3712  ref_amp->amp_type_time = (int *)HECMW_malloc(sizeof(int) * amp->n_amp);
3713  if (ref_amp->amp_type_time == NULL) {
3714  HECMW_set_error(errno, "");
3715  return HECMW_ERROR;
3716  }
3717  for (i = 0; i < amp->n_amp; i++) {
3718  ref_amp->amp_type_time[i] = amp->amp_type_time[i];
3719  }
3720 
3721  /* amp_type_value */
3722  ref_amp->amp_type_value = (int *)HECMW_malloc(sizeof(int) * amp->n_amp);
3723  if (ref_amp->amp_type_value == NULL) {
3724  HECMW_set_error(errno, "");
3725  return HECMW_ERROR;
3726  }
3727  for (i = 0; i < amp->n_amp; i++) {
3728  ref_amp->amp_type_value[i] = amp->amp_type_value[i];
3729  }
3730 
3731  /* amp_index */
3732  ref_amp->amp_index = (int *)HECMW_malloc(sizeof(int) * (amp->n_amp + 1));
3733  if (ref_amp->amp_index == NULL) {
3734  HECMW_set_error(errno, "");
3735  return HECMW_ERROR;
3736  }
3737  for (i = 0; i < amp->n_amp + 1; i++) {
3738  ref_amp->amp_index[i] = amp->amp_index[i];
3739  }
3740 
3741  /* amp_val */
3742  ref_amp->amp_val =
3743  (double *)HECMW_malloc(sizeof(double) * amp->amp_index[amp->n_amp]);
3744  if (ref_amp->amp_val == NULL) {
3745  HECMW_set_error(errno, "");
3746  return HECMW_ERROR;
3747  }
3748  for (i = 0; i < amp->amp_index[amp->n_amp]; i++) {
3749  ref_amp->amp_val[i] = amp->amp_val[i];
3750  }
3751 
3752  /* amp_table */
3753  ref_amp->amp_table =
3754  (double *)HECMW_malloc(sizeof(double) * amp->amp_index[amp->n_amp]);
3755  if (ref_amp->amp_table == NULL) {
3756  HECMW_set_error(errno, "");
3757  return HECMW_ERROR;
3758  }
3759  for (i = 0; i < amp->amp_index[amp->n_amp]; i++) {
3760  ref_amp->amp_table[i] = amp->amp_table[i];
3761  }
3762 
3763  return HECMW_SUCCESS;
3764 }
3765 
3766 static int copy_contact_pair(const struct hecmwST_contact_pair *cp,
3767  struct hecmwST_contact_pair *ref_cp) {
3768  int i;
3769 
3770  ref_cp->n_pair = cp->n_pair;
3771 
3772  /* name */
3773  ref_cp->name = (char **)HECMW_malloc(sizeof(char *) * cp->n_pair);
3774  if (ref_cp->name == NULL) {
3775  HECMW_set_error(errno, "");
3776  return HECMW_ERROR;
3777  }
3778  for (i = 0; i < cp->n_pair; i++) {
3779  ref_cp->name[i] = HECMW_strdup(cp->name[i]);
3780  if (ref_cp->name[i] == NULL) {
3781  HECMW_set_error(errno, "");
3782  return HECMW_ERROR;
3783  }
3784  }
3785 
3786  /* type */
3787  ref_cp->type = (int *)HECMW_malloc(sizeof(int) * cp->n_pair);
3788  if (ref_cp->type == NULL) {
3789  HECMW_set_error(errno, "");
3790  return HECMW_ERROR;
3791  }
3792  for (i = 0; i < cp->n_pair; i++) {
3793  ref_cp->type[i] = cp->type[i];
3794  }
3795 
3796  /* slave_grp_id */
3797  ref_cp->slave_grp_id = (int *)HECMW_malloc(sizeof(int) * cp->n_pair);
3798  if (ref_cp->slave_grp_id == NULL) {
3799  HECMW_set_error(errno, "");
3800  return HECMW_ERROR;
3801  }
3802  for (i = 0; i < cp->n_pair; i++) {
3803  ref_cp->slave_grp_id[i] = cp->slave_grp_id[i];
3804  }
3805 
3806  /* slave_orisgrp_id */
3807  ref_cp->slave_orisgrp_id = (int *)HECMW_malloc(sizeof(int) * cp->n_pair);
3808  if (ref_cp->slave_orisgrp_id == NULL) {
3809  HECMW_set_error(errno, "");
3810  return HECMW_ERROR;
3811  }
3812  for (i = 0; i < cp->n_pair; i++) {
3813  ref_cp->slave_orisgrp_id[i] = cp->slave_orisgrp_id[i];
3814  }
3815 
3816  /* master_grp_id */
3817  ref_cp->master_grp_id = (int *)HECMW_malloc(sizeof(int) * cp->n_pair);
3818  if (ref_cp->master_grp_id == NULL) {
3819  HECMW_set_error(errno, "");
3820  return HECMW_ERROR;
3821  }
3822  for (i = 0; i < cp->n_pair; i++) {
3823  ref_cp->master_grp_id[i] = cp->master_grp_id[i];
3824  }
3825 
3826  return HECMW_SUCCESS;
3827 }
3828 
3829 static int copy_unchanging_info(const struct hecmwST_local_mesh *mesh,
3830  struct hecmwST_local_mesh *ref_mesh) {
3831  HECMW_log(HECMW_LOG_DEBUG, "Started copying unchanging info...\n");
3832 
3833  if (copy_global_info(mesh, ref_mesh) != HECMW_SUCCESS) return HECMW_ERROR;
3834  if (copy_node_ndof(mesh, ref_mesh) != HECMW_SUCCESS) return HECMW_ERROR;
3835  if (copy_elem_etype(mesh, ref_mesh) != HECMW_SUCCESS) return HECMW_ERROR;
3836  if (copy_comm_info(mesh, ref_mesh) != HECMW_SUCCESS) return HECMW_ERROR;
3837  if (copy_adapt_info(mesh, ref_mesh) != HECMW_SUCCESS) return HECMW_ERROR;
3838  if (copy_section_info(mesh->section, ref_mesh->section) != HECMW_SUCCESS)
3839  return HECMW_ERROR;
3840  if (copy_material_info(mesh->material, ref_mesh->material) != HECMW_SUCCESS)
3841  return HECMW_ERROR;
3842  if (copy_mpc_info(mesh->mpc, ref_mesh->mpc) != HECMW_SUCCESS)
3843  return HECMW_ERROR;
3844  if (copy_amp_info(mesh->amp, ref_mesh->amp) != HECMW_SUCCESS)
3845  return HECMW_ERROR;
3846  if (copy_contact_pair(mesh->contact_pair, ref_mesh->contact_pair) !=
3847  HECMW_SUCCESS)
3848  return HECMW_ERROR;
3849 
3850  HECMW_log(HECMW_LOG_DEBUG, "Finished copying unchanging info.\n");
3851  return HECMW_SUCCESS;
3852 }
3853 
3854 /*============================================================================*/
3855 /* */
3856 /* renumber nodes */
3857 /* */
3858 /*============================================================================*/
3859 static int renumber_nodes_generate_tables(struct hecmwST_local_mesh *mesh) {
3860  int i;
3861  int count_in, count_ex, count_pex;
3862  int *old2new, *new2old;
3863 
3864  if (mesh->n_node_gross == mesh->nn_internal) return HECMW_SUCCESS;
3865 
3866  HECMW_log(HECMW_LOG_DEBUG, "Started generating renumbering tables...\n");
3867 
3868  old2new = (int *)HECMW_malloc(sizeof(int) * mesh->n_node_gross);
3869  if (old2new == NULL) {
3870  HECMW_set_error(errno, "");
3871  return HECMW_ERROR;
3872  }
3873  new2old = (int *)HECMW_malloc(sizeof(int) * mesh->n_node_gross);
3874  if (new2old == NULL) {
3875  HECMW_set_error(errno, "");
3876  return HECMW_ERROR;
3877  }
3878  count_in = 0;
3879  count_ex = mesh->nn_internal;
3880  count_pex = mesh->n_node;
3881  for (i = 0; i < mesh->n_node_gross; i++) {
3882  int rank = mesh->node_ID[i * 2 + 1];
3883  if (rank == mesh->my_rank) {
3884  old2new[i] = count_in;
3885  new2old[count_in] = i;
3886  count_in++;
3887  } else if (rank >= 0) {
3888  old2new[i] = count_ex;
3889  new2old[count_ex] = i;
3890  count_ex++;
3891  } else {
3892  old2new[i] = count_pex;
3893  new2old[count_pex] = i;
3894  count_pex++;
3895  }
3896  }
3897  mesh->node_old2new = old2new;
3898  mesh->node_new2old = new2old;
3899 
3900  HECMW_log(HECMW_LOG_DEBUG, "Finished generating renumbering tables.\n");
3901  return HECMW_SUCCESS;
3902 }
3903 
3904 static int reorder_nodes(struct hecmwST_local_mesh *mesh, int *old2new,
3905  int *new2old) {
3906  int i;
3907 
3908 #ifndef NDEBUG
3909  for (i = 0; i < mesh->n_node_gross; i++) {
3910  HECMW_assert(new2old[old2new[i]] == i);
3911  }
3912 #endif
3913 
3914  /*
3915  * Reorder using new2old
3916  */
3917  /* node_ID */
3918  {
3919  int *new_node_ID =
3920  (int *)HECMW_malloc(sizeof(int) * mesh->n_node_gross * 2);
3921  if (new_node_ID == NULL) {
3922  HECMW_set_error(errno, "");
3923  return HECMW_ERROR;
3924  }
3925  for (i = 0; i < mesh->n_node_gross; i++) {
3926  int old = new2old[i];
3927  new_node_ID[2 * i] = mesh->node_ID[2 * old];
3928  new_node_ID[2 * i + 1] = mesh->node_ID[2 * old + 1];
3929  }
3931  mesh->node_ID = new_node_ID;
3932  }
3933  /* global_node_ID */
3934  {
3935  int *new_global_node_ID =
3936  (int *)HECMW_malloc(sizeof(int) * mesh->n_node_gross);
3937  if (new_global_node_ID == NULL) {
3938  HECMW_set_error(errno, "");
3939  return HECMW_ERROR;
3940  }
3941  for (i = 0; i < mesh->n_node_gross; i++) {
3942  int old = new2old[i];
3943  new_global_node_ID[i] = mesh->global_node_ID[old];
3944  }
3946  mesh->global_node_ID = new_global_node_ID;
3947  }
3948  /* node */
3949  {
3950  double *new_node =
3951  (double *)HECMW_malloc(sizeof(double) * mesh->n_node_gross * 3);
3952  if (new_node == NULL) {
3953  HECMW_set_error(errno, "");
3954  return HECMW_ERROR;
3955  }
3956  for (i = 0; i < mesh->n_node_gross; i++) {
3957  int old = new2old[i];
3958  int j;
3959  for (j = 0; j < 3; j++) new_node[3 * i + j] = mesh->node[3 * old + j];
3960  }
3961  HECMW_free(mesh->node);
3962  mesh->node = new_node;
3963  }
3964  /* node_init_val_index, node_init_val_item */
3965  if (mesh->hecmw_flag_initcon && mesh->n_node_gross > 0) {
3966  /* node_init_val_index */
3967  int *new_node_init_val_index =
3968  (int *)HECMW_malloc(sizeof(int) * (mesh->n_node_gross + 1));
3969  if (new_node_init_val_index == NULL) {
3970  HECMW_set_error(errno, "");
3971  return HECMW_ERROR;
3972  }
3973  new_node_init_val_index[0] = 0;
3974  for (i = 0; i < mesh->n_node_gross; i++) {
3975  int old = new2old[i];
3976  int ninit =
3978  new_node_init_val_index[i + 1] = new_node_init_val_index[i] + ninit;
3979  }
3980 
3981  /* node_init_val_item */
3982  if (mesh->node_init_val_index[mesh->n_node_gross] != 0) {
3983  double *new_node_init_val_item = (double *)HECMW_malloc(
3984  sizeof(double) * mesh->node_init_val_index[mesh->n_node_gross]);
3985  if (new_node_init_val_item == NULL) {
3986  HECMW_set_error(errno, "");
3987  return HECMW_ERROR;
3988  }
3989  for (i = 0; i < mesh->n_node_gross; i++) {
3990  int old = new2old[i];
3991  int idx_new = new_node_init_val_index[i];
3992  int idx_old = mesh->node_init_val_index[old];
3993  int ninit = mesh->node_init_val_index[old + 1] - idx_old;
3994  int j;
3995  for (j = 0; j < ninit; j++) {
3996  new_node_init_val_item[idx_new + j] =
3997  mesh->node_init_val_item[idx_old + j];
3998  }
3999  }
4001  mesh->node_init_val_item = new_node_init_val_item;
4002  }
4004  mesh->node_init_val_index = new_node_init_val_index;
4005  }
4006 
4007  /*
4008  * Update using old2new
4009  */
4010  /* elem_node_item */
4011  {
4012  long long ii;
4013  for (ii = 0; ii < mesh->elem_node_index[mesh->n_elem_gross]; ii++) {
4014  int old = mesh->elem_node_item[ii];
4015  int new = old2new[old - 1] + 1;
4016  mesh->elem_node_item[ii] = new;
4017  }
4018  }
4019  /* import_item */
4020  for (i = 0; i < mesh->import_index[mesh->n_neighbor_pe]; i++) {
4021  int old = mesh->import_item[i];
4022  int new = old2new[old - 1] + 1;
4023  mesh->import_item[i] = new;
4024  }
4025  /* export_item */
4026  for (i = 0; i < mesh->export_index[mesh->n_neighbor_pe]; i++) {
4027  int old = mesh->export_item[i];
4028  int new = old2new[old - 1] + 1;
4029  mesh->export_item[i] = new;
4030  }
4031  /* mpc->mpc_item */
4032  for (i = 0; i < mesh->mpc->mpc_index[mesh->mpc->n_mpc]; i++) {
4033  int old = mesh->mpc->mpc_item[i];
4034  int new = old2new[old - 1] + 1;
4035  mesh->mpc->mpc_item[i] = new;
4036  }
4037  /* node_group->grp_item */
4038  for (i = 0; i < mesh->node_group->grp_index[mesh->node_group->n_grp]; i++) {
4039  int old = mesh->node_group->grp_item[i];
4040  int new = old2new[old - 1] + 1;
4041  mesh->node_group->grp_item[i] = new;
4042  }
4043  return HECMW_SUCCESS;
4044 }
4045 
4046 static int delete_external_items(int n_elem, int n_grp, int *index, int *item,
4047  int n_memb) {
4048  int i, j, k;
4049  int n_del = 0;
4050  int start = 0;
4051  for (i = 0; i < n_grp; i++) {
4052  int end = index[i + 1];
4053  for (j = start; j < end; j++) {
4054  if (item[j * n_memb] > n_elem) {
4055  n_del++;
4056  } else {
4057  for (k = 0; k < n_memb; k++)
4058  item[(j - n_del) * n_memb + k] = item[j * n_memb + k];
4059  }
4060  }
4061  /* start for next group */
4062  start = end;
4063  index[i + 1] = end - n_del;
4064  }
4065  return HECMW_SUCCESS;
4066 }
4067 
4068 static int delete_external_equations(int n_node, struct hecmwST_mpc *mpc) {
4069  int iold, inew, jold, jnew;
4070  int *active_eqn;
4071  int n_mpc_new;
4072  int *mpc_index_new, *mpc_item_new, *mpc_dof_new;
4073  double *mpc_val_new, *mpc_const_new;
4074  active_eqn = (int *) HECMW_malloc(sizeof(int) * mpc->n_mpc);
4075  if (active_eqn == NULL) {
4076  HECMW_set_error(errno, "");
4077  return HECMW_ERROR;
4078  }
4079  n_mpc_new = 0;
4080  for (iold = 0; iold < mpc->n_mpc; iold++) {
4081  int is_ext = 0;
4082  for (jold = mpc->mpc_index[iold]; jold < mpc->mpc_index[iold+1]; jold++) {
4083  if (mpc->mpc_item[jold] > n_node) {
4084  is_ext = 1;
4085  break;
4086  }
4087  }
4088  if (is_ext == 0) {
4089  active_eqn[n_mpc_new] = iold;
4090  n_mpc_new++;
4091  }
4092  }
4093  mpc_index_new = (int *) HECMW_malloc(sizeof(int) * (n_mpc_new + 1));
4094  if (mpc_index_new == NULL) {
4095  HECMW_set_error(errno, "");
4096  return HECMW_ERROR;
4097  }
4098  mpc_index_new[0] = 0;
4099  if (n_mpc_new == 0) {
4100  mpc_item_new = NULL;
4101  mpc_dof_new = NULL;
4102  mpc_val_new = NULL;
4103  mpc_const_new = NULL;
4104  } else {
4105  for (inew = 0; inew < n_mpc_new; inew++) {
4106  iold = active_eqn[inew];
4107  mpc_index_new[inew+1] = mpc_index_new[inew] + (mpc->mpc_index[iold+1] - mpc->mpc_index[iold]);
4108  }
4109  mpc_item_new = (int *) HECMW_malloc(sizeof(int) * mpc_index_new[n_mpc_new]);
4110  if (mpc_item_new == NULL) {
4111  HECMW_set_error(errno, "");
4112  return HECMW_ERROR;
4113  }
4114  mpc_dof_new = (int *) HECMW_malloc(sizeof(int) * mpc_index_new[n_mpc_new]);
4115  if (mpc_dof_new == NULL) {
4116  HECMW_set_error(errno, "");
4117  return HECMW_ERROR;
4118  }
4119  mpc_val_new = (double *) HECMW_malloc(sizeof(double) * mpc_index_new[n_mpc_new]);
4120  if (mpc_val_new == NULL) {
4121  HECMW_set_error(errno, "");
4122  return HECMW_ERROR;
4123  }
4124  mpc_const_new = (double *) HECMW_malloc(sizeof(double) * n_mpc_new);
4125  if (mpc_const_new == NULL) {
4126  HECMW_set_error(errno, "");
4127  return HECMW_ERROR;
4128  }
4129  for (inew = 0; inew < n_mpc_new; inew++) {
4130  iold = active_eqn[inew];
4131  for (jold = mpc->mpc_index[iold], jnew = mpc_index_new[inew]; jold < mpc->mpc_index[iold+1]; jold++, jnew++) {
4132  mpc_item_new[jnew] = mpc->mpc_item[jold];
4133  mpc_dof_new[jnew] = mpc->mpc_dof[jold];
4134  mpc_val_new[jnew] = mpc->mpc_val[jold];
4135  }
4136  mpc_const_new[inew] = mpc->mpc_const[iold];
4137  }
4138  }
4139  HECMW_free(active_eqn);
4140  mpc->n_mpc = n_mpc_new;
4141  HECMW_free(mpc->mpc_index);
4142  HECMW_free(mpc->mpc_item);
4143  HECMW_free(mpc->mpc_dof);
4144  HECMW_free(mpc->mpc_val);
4145  HECMW_free(mpc->mpc_const);
4146  mpc->mpc_index = mpc_index_new;
4147  mpc->mpc_item = mpc_item_new;
4148  mpc->mpc_dof = mpc_dof_new;
4149  mpc->mpc_val = mpc_val_new;
4150  mpc->mpc_const = mpc_const_new;
4151  return HECMW_SUCCESS;
4152 }
4153 
4154 static int renumber_nodes(struct hecmwST_local_mesh *mesh) {
4155  if (mesh->n_node_gross == mesh->nn_internal) return HECMW_SUCCESS;
4156 
4157  HECMW_log(HECMW_LOG_DEBUG, "Started renumbering nodes...\n");
4158 
4159  if (reorder_nodes(mesh, mesh->node_old2new, mesh->node_new2old) !=
4160  HECMW_SUCCESS) {
4161  return HECMW_ERROR;
4162  }
4163 
4164  if (delete_external_items(mesh->n_node, mesh->node_group->n_grp,
4166  1) != HECMW_SUCCESS) {
4167  return HECMW_ERROR;
4168  }
4169 
4170  if (delete_external_equations(mesh->n_node, mesh->mpc) != HECMW_SUCCESS) {
4171  return HECMW_ERROR;
4172  }
4173 
4174  HECMW_log(HECMW_LOG_DEBUG, "Finished renumbering nodes.\n");
4175  return HECMW_SUCCESS;
4176 }
4177 
4178 static int renumber_back_nodes(struct hecmwST_local_mesh *mesh) {
4179  if (mesh->n_node_gross == mesh->nn_internal) return HECMW_SUCCESS;
4180 
4181  HECMW_log(HECMW_LOG_DEBUG, "Started renumbering back nodes...\n");
4182 
4183  if (reorder_nodes(mesh, mesh->node_new2old, mesh->node_old2new) !=
4184  HECMW_SUCCESS) {
4185  return HECMW_ERROR;
4186  }
4187 
4188  HECMW_log(HECMW_LOG_DEBUG, "Finished renumbering back nodes.\n");
4189  return HECMW_SUCCESS;
4190 }
4191 
4192 /*============================================================================*/
4193 /* */
4194 /* renumber elements */
4195 /* */
4196 /*============================================================================*/
4197 static int renumber_elements_generate_tables(struct hecmwST_local_mesh *mesh) {
4198  int i;
4199  int count_rel, count_pex;
4200  int *old2new, *new2old;
4201 
4202  if (mesh->n_node_gross == mesh->nn_internal) return HECMW_SUCCESS;
4203 
4204  HECMW_log(HECMW_LOG_DEBUG, "Started generating renumbering tables...\n");
4205 
4206  old2new = (int *)HECMW_malloc(sizeof(int) * mesh->n_elem_gross);
4207  if (old2new == NULL) {
4208  HECMW_set_error(errno, "");
4209  return HECMW_ERROR;
4210  }
4211  new2old = (int *)HECMW_malloc(sizeof(int) * mesh->n_elem_gross);
4212  if (new2old == NULL) {
4213  HECMW_set_error(errno, "");
4214  return HECMW_ERROR;
4215  }
4216  count_rel = 0;
4217  count_pex = mesh->n_elem;
4218  for (i = 0; i < mesh->n_elem_gross; i++) {
4219  int rank = mesh->elem_ID[i * 2 + 1];
4220  if (rank >= 0) {
4221  old2new[i] = count_rel;
4222  new2old[count_rel] = i;
4223  count_rel++;
4224  } else {
4225  old2new[i] = count_pex;
4226  new2old[count_pex] = i;
4227  count_pex++;
4228  }
4229  }
4230  mesh->elem_old2new = old2new;
4231  mesh->elem_new2old = new2old;
4232 
4233  HECMW_log(HECMW_LOG_DEBUG, "Finished generating renumbering tables.\n");
4234  return HECMW_SUCCESS;
4235 }
4236 
4237 static int reorder_elems(struct hecmwST_local_mesh *mesh, int *old2new,
4238  int *new2old) {
4239  int i;
4240 
4241 #ifndef NDEBUG
4242  for (i = 0; i < mesh->n_elem_gross; i++) {
4243  HECMW_assert(new2old[old2new[i]] == i);
4244  }
4245 #endif
4246 
4247  /*
4248  * Reorder using new2old
4249  */
4250  /* elem_ID */
4251  {
4252  int *new_elem_ID =
4253  (int *)HECMW_malloc(sizeof(int) * mesh->n_elem_gross * 2);
4254  if (new_elem_ID == NULL) {
4255  HECMW_set_error(errno, "");
4256  return HECMW_ERROR;
4257  }
4258  for (i = 0; i < mesh->n_elem_gross; i++) {
4259  int old = new2old[i];
4260  new_elem_ID[2 * i] = mesh->elem_ID[2 * old];
4261  new_elem_ID[2 * i + 1] = mesh->elem_ID[2 * old + 1];
4262  }
4264  mesh->elem_ID = new_elem_ID;
4265  }
4266  /* global_elem_ID */
4267  {
4268  int *new_global_elem_ID =
4269  (int *)HECMW_malloc(sizeof(int) * mesh->n_elem_gross);
4270  if (new_global_elem_ID == NULL) {
4271  HECMW_set_error(errno, "");
4272  return HECMW_ERROR;
4273  }
4274  for (i = 0; i < mesh->n_elem_gross; i++) {
4275  int old = new2old[i];
4276  new_global_elem_ID[i] = mesh->global_elem_ID[old];
4277  }
4279  mesh->global_elem_ID = new_global_elem_ID;
4280  }
4281  /* elem_type */
4282  {
4283  int *new_elem_type = (int *)HECMW_malloc(sizeof(int) * mesh->n_elem_gross);
4284  if (new_elem_type == NULL) {
4285  HECMW_set_error(errno, "");
4286  return HECMW_ERROR;
4287  }
4288  for (i = 0; i < mesh->n_elem_gross; i++) {
4289  int old = new2old[i];
4290  new_elem_type[i] = mesh->elem_type[old];
4291  }
4293  mesh->elem_type = new_elem_type;
4294  }
4295  /* elem_type_index, elem_type_item */
4296  {
4297  for (i = 0; i < mesh->n_elem_type; i++) {
4298  int j;
4299  for (j = mesh->elem_type_index[i]; j < mesh->n_elem; j++) {
4300  if (mesh->elem_type[j] != mesh->elem_type_item[i]) {
4301  break;
4302  }
4303  }
4304  mesh->elem_type_index[i + 1] = j;
4305  }
4306  }
4307  /* elem_node_index, elem_node_item */
4308  {
4309  long long *new_elem_node_index =
4310  (long long *)HECMW_malloc(sizeof(long long) * (mesh->n_elem_gross + 1));
4311  int *new_elem_node_item = (int *)HECMW_malloc(
4312  sizeof(int) * mesh->elem_node_index[mesh->n_elem_gross]);
4313  if (new_elem_node_index == NULL || new_elem_node_item == NULL) {
4314  HECMW_set_error(errno, "");
4315  return HECMW_ERROR;
4316  }
4317  new_elem_node_index[0] = 0;
4318  for (i = 0; i < mesh->n_elem_gross; i++) {
4319  int old = new2old[i];
4320  long long nn = mesh->elem_node_index[old + 1] - mesh->elem_node_index[old];
4321  new_elem_node_index[i + 1] = new_elem_node_index[i] + nn;
4322  }
4323  for (i = 0; i < mesh->n_elem_gross; i++) {
4324  int old = new2old[i];
4325  long long start_old = mesh->elem_node_index[old];
4326  long long start_new = new_elem_node_index[i];
4327  long long nn = new_elem_node_index[i + 1] - start_new;
4328  long long j;
4329  for (j = 0; j < nn; j++)
4330  new_elem_node_item[start_new + j] = mesh->elem_node_item[start_old + j];
4331  }
4334  mesh->elem_node_index = new_elem_node_index;
4335  mesh->elem_node_item = new_elem_node_item;
4336  }
4337  /* section_ID */
4338  {
4339  int *new_section_ID = (int *)HECMW_malloc(sizeof(int) * mesh->n_elem_gross);
4340  if (new_section_ID == NULL) {
4341  HECMW_set_error(errno, "");
4342  return HECMW_ERROR;
4343  }
4344  for (i = 0; i < mesh->n_elem_gross; i++) {
4345  int old = new2old[i];
4346  new_section_ID[i] = mesh->section_ID[old];
4347  }
4349  mesh->section_ID = new_section_ID;
4350  }
4351  /* elem_mat_ID_index, elem_mat_ID_item */
4352  {
4353  int *new_emID_index, *new_emID_item;
4354  new_emID_index =
4355  (int *)HECMW_malloc(sizeof(int) * (mesh->n_elem_gross + 1));
4356  if (new_emID_index == NULL) {
4357  HECMW_set_error(errno, "");
4358  return HECMW_ERROR;
4359  }
4360  new_emID_item = (int *)HECMW_malloc(
4361  sizeof(int) * mesh->elem_mat_ID_index[mesh->n_elem_gross]);
4362  if (new_emID_item == NULL) {
4363  HECMW_set_error(errno, "");
4364  return HECMW_ERROR;
4365  }
4366  new_emID_index[0] = 0;
4367  for (i = 0; i < mesh->n_elem_gross; i++) {
4368  int old, js_old, je_old, len, js_new, j;
4369  old = new2old[i];
4370  js_old = mesh->elem_mat_ID_index[old];
4371  je_old = mesh->elem_mat_ID_index[old + 1];
4372  len = je_old - js_old;
4373  js_new = new_emID_index[i];
4374  new_emID_index[i + 1] = js_new + len;
4375  for (j = 0; j < len; j++) {
4376  new_emID_item[js_new + j] = mesh->elem_mat_ID_item[js_old + j];
4377  }
4378  }
4381  mesh->elem_mat_ID_index = new_emID_index;
4382  mesh->elem_mat_ID_item = new_emID_item;
4383  }
4384 
4385  /*
4386  * Update using old2new
4387  */
4388  /* elem_internal_list */
4389  for (i = 0; i < mesh->ne_internal; i++) {
4390  int old = mesh->elem_internal_list[i];
4391  int new = old2new[old - 1] + 1;
4392  mesh->elem_internal_list[i] = new;
4393  }
4394  /* shared_item */
4395  for (i = 0; i < mesh->shared_index[mesh->n_neighbor_pe]; i++) {
4396  int old = mesh->shared_item[i];
4397  int new = old2new[old - 1] + 1;
4398  mesh->shared_item[i] = new;
4399  }
4400  /* elem_groups->grp_item */
4401  for (i = 0; i < mesh->elem_group->grp_index[mesh->elem_group->n_grp]; i++) {
4402  int old = mesh->elem_group->grp_item[i];
4403  int new = old2new[old - 1] + 1;
4404  mesh->elem_group->grp_item[i] = new;
4405  }
4406  /* surf_groups->grp_item */
4407  for (i = 0; i < mesh->surf_group->grp_index[mesh->surf_group->n_grp]; i++) {
4408  int old = mesh->surf_group->grp_item[2 * i];
4409  int new = old2new[old - 1] + 1;
4410  mesh->surf_group->grp_item[2 * i] = new;
4411  }
4412  return HECMW_SUCCESS;
4413 }
4414 
4415 static int renumber_elements(struct hecmwST_local_mesh *mesh) {
4416  if (mesh->n_elem_gross == mesh->n_elem) return HECMW_SUCCESS;
4417 
4418  HECMW_log(HECMW_LOG_DEBUG, "Started renumbering elements...\n");
4419 
4420  if (reorder_elems(mesh, mesh->elem_old2new, mesh->elem_new2old) !=
4421  HECMW_SUCCESS) {
4422  return HECMW_ERROR;
4423  }
4424 
4425  /* if (delete_external_items( mesh->n_elem, mesh->n_neighbor_pe, */
4426  /* mesh->shared_index, mesh->shared_item, 1 ) != */
4427  /* HECMW_SUCCESS) { */
4428  /* return HECMW_ERROR; */
4429  /* } */
4430  if (delete_external_items(mesh->n_elem, mesh->elem_group->n_grp,
4432  1) != HECMW_SUCCESS) {
4433  return HECMW_ERROR;
4434  }
4435  if (delete_external_items(mesh->n_elem, mesh->surf_group->n_grp,
4437  2) != HECMW_SUCCESS) {
4438  return HECMW_ERROR;
4439  }
4440 
4441  HECMW_log(HECMW_LOG_DEBUG, "Finished renumbering elements.\n");
4442  return HECMW_SUCCESS;
4443 }
4444 
4445 static int renumber_back_elements(struct hecmwST_local_mesh *mesh) {
4446  if (mesh->n_elem_gross == mesh->n_elem) return HECMW_SUCCESS;
4447 
4448  HECMW_log(HECMW_LOG_DEBUG, "Started renumbering back elements...\n");
4449 
4450  if (reorder_elems(mesh, mesh->elem_new2old, mesh->elem_old2new) !=
4451  HECMW_SUCCESS) {
4452  return HECMW_ERROR;
4453  }
4454 
4455  HECMW_log(HECMW_LOG_DEBUG, "Finished renumbering back elements.\n");
4456  return HECMW_SUCCESS;
4457 }
4458 
4459 /*============================================================================*/
4460 /* */
4461 /* refine distributed mesh ONCE */
4462 /* */
4463 /*============================================================================*/
4464 static int refine_dist_mesh(struct hecmwST_local_mesh *mesh,
4465  struct hecmwST_local_mesh *ref_mesh) {
4466  HECMW_log(HECMW_LOG_DEBUG, "Started refining mesh...\n");
4467 
4468  if (copy_unchanging_info(mesh, ref_mesh) != HECMW_SUCCESS) return HECMW_ERROR;
4469  if (call_refiner(mesh, ref_mesh) != HECMW_SUCCESS) return HECMW_ERROR;
4470  if (rebuild_info(mesh, ref_mesh) != HECMW_SUCCESS) return HECMW_ERROR;
4471 
4472  HECMW_log(HECMW_LOG_DEBUG, "Finished refining mesh.\n");
4473  return HECMW_SUCCESS;
4474 }
4475 
4476 /*============================================================================*/
4477 /* */
4478 /* refine HEC-MW distributed mesh data */
4479 /* */
4480 /*============================================================================*/
4481 int HECMW_dist_refine(struct hecmwST_local_mesh **mesh, int refine,
4482  const char *cad_filename, const char *part_filename) {
4483  int error_flag = HECMW_SUCCESS;
4484  int i;
4485 
4486  if (refine <= 0) return HECMW_SUCCESS;
4487 
4488  HECMW_log(HECMW_LOG_DEBUG, "Refinement requested; starting...\n");
4489 
4490  if ((*mesh)->n_refine > 0) {
4491  if (renumber_back_elements(*mesh) != HECMW_SUCCESS) return HECMW_ERROR;
4492  if (renumber_back_nodes(*mesh) != HECMW_SUCCESS) return HECMW_ERROR;
4493  }
4494 
4495  if (prepare_refiner(*mesh, cad_filename, part_filename) != HECMW_SUCCESS)
4496  return HECMW_ERROR;
4497 
4498  for (i = 0; i < refine; i++) {
4499  struct hecmwST_local_mesh *ref_mesh = HECMW_dist_alloc();
4500  if (ref_mesh == NULL) {
4501  error_flag = HECMW_ERROR;
4502  break;
4503  }
4504 
4505  if (i > 0) {
4506  clear_refiner();
4507  }
4508 
4509  HECMW_log(HECMW_LOG_DEBUG, "Refining(%d)...\n", i + 1);
4510 
4511  if (refine_dist_mesh(*mesh, ref_mesh) != HECMW_SUCCESS) {
4512  HECMW_log(HECMW_LOG_ERROR, "Refinement failed\n");
4513  error_flag = HECMW_ERROR;
4514  break;
4515  }
4516 
4517  HECMW_dist_free(*mesh);
4518  *mesh = ref_mesh;
4519  }
4520 
4521  if (terminate_refiner(*mesh) != HECMW_SUCCESS) return HECMW_ERROR;
4522 
4523  if (error_flag != HECMW_SUCCESS) return HECMW_ERROR;
4524 
4525  if (renumber_nodes(*mesh) != HECMW_SUCCESS) return HECMW_ERROR;
4526  if (renumber_elements(*mesh) != HECMW_SUCCESS) return HECMW_ERROR;
4527 
4528  HECMW_log(HECMW_LOG_DEBUG, "Refinement finished.\n");
4529 
4530  return HECMW_SUCCESS;
4531 }
4532 
4533 #else /* HECMW_WITH_REFINER */
4534 
4535 int HECMW_dist_refine(struct hecmwST_local_mesh **mesh, int refine,
4536  const char *cad_filename, const char *part_filename) {
4537  if (refine > 0) {
4538  HECMW_log(HECMW_LOG_WARN, "Refiner not enabled; ignoring...\n");
4539  }
4540  return HECMW_SUCCESS;
4541 }
4542 #endif /* HECMW_WITH_REFINER */
int HECMW_bit_array_init(struct hecmw_bit_array *ba, size_t len)
int HECMW_bit_array_get(struct hecmw_bit_array *ba, size_t index)
void HECMW_bit_array_set(struct hecmw_bit_array *ba, size_t index)
void HECMW_bit_array_finalize(struct hecmw_bit_array *ba)
int HECMW_Isend(void *buffer, int count, HECMW_Datatype datatype, int dest, int tag, HECMW_Comm comm, HECMW_Request *request)
Definition: hecmw_comm.c:302
int HECMW_Waitall(int count, HECMW_Request *array_of_requests, HECMW_Status *array_of_statuses)
Definition: hecmw_comm.c:132
HECMW_Comm HECMW_comm_get_comm(void)
Definition: hecmw_comm.c:751
int HECMW_Allreduce(void *sendbuf, void *recvbuf, int count, HECMW_Datatype datatype, HECMW_Op op, HECMW_Comm comm)
Definition: hecmw_comm.c:404
int HECMW_comm_get_rank(void)
Definition: hecmw_comm.c:759
int HECMW_Recv(void *buffer, int count, HECMW_Datatype datatype, int source, int tag, HECMW_Comm comm, HECMW_Status *status)
Definition: hecmw_comm.c:251
#define HECMW_ETYPE_PRI1
#define HECMW_ETYPE_PRI2
#define HECMW_ETYPE_LN24
#define HECMW_ETYPE_MST1
#define HECMW_ETYPE_TET1_4
#define HECMW_ETYPE_BEM3
#define HECMW_ETYPE_LN54
#define HECMW_ETYPE_LN51
#define HECMW_ETYPE_LN15
#define HECMW_ETYPE_PYR1
#define HECMW_ETYPE_LN66
#define HECMW_ETYPE_LN65
#define HECMW_ETYPE_LN11
#define HECMW_ETYPE_LN43
#define HECMW_ETYPE_QUA2
#define HECMW_ETYPE_LN42
#define HECMW_ETYPE_LN32
#define HECMW_ETYPE_LN55
#define HECMW_ETYPE_MSQ2
#define HECMW_ETYPE_LN61
#define HECMW_ETYPE_JTQ2
#define HECMW_ETYPE_LN22
#define HECMW_ETYPE_SHQ1
#define HECMW_ETYPE_SHT1
#define HECMW_ETYPE_TET2
#define HECMW_ETYPE_PTQ1
#define HECMW_ETYPE_JTT2
#define HECMW_ETYPE_PTT1
#define HECMW_ETYPE_LN26
#define HECMW_ETYPE_LN33
#define HECMW_ETYPE_LN53
#define HECMW_ETYPE_LN64
#define HECMW_ETYPE_LN13
#define HECMW_ETYPE_LN46
#define HECMW_ETYPE_SHT2
#define HECMW_ETYPE_LN34
#define HECMW_ETYPE_TRI1
#define HECMW_ETYPE_SHT6
#define HECMW_ETYPE_LN41
#define HECMW_ETYPE_ROD2
#define HECMW_ETYPE_ROD31
#define HECMW_MAX_NODE_MAX
#define HECMW_ETYPE_HEX1
#define HECMW_ETYPE_JTT1
#define HECMW_ETYPE_ROD1
#define HECMW_ETYPE_LN62
#define HECMW_ETYPE_LN45
#define HECMW_ETYPE_JTQ1
#define HECMW_ETYPE_BEM1
#define HECMW_ETYPE_QUA1
#define HECMW_ETYPE_BEM2
#define HECMW_ETYPE_SHQ8
#define HECMW_ETYPE_LN35
#define HECMW_ETYPE_LN63
#define HECMW_ETYPE_LN25
#define HECMW_ETYPE_PYR2
#define HECMW_ETYPE_LN36
#define HECMW_ETYPE_TET1
#define HECMW_ETYPE_LN52
#define HECMW_ETYPE_LN16
#define HECMW_ETYPE_HEX1_4
#define HECMW_ETYPE_LN12
#define HECMW_ETYPE_MSQ1
#define HECMW_ETYPE_LN23
#define HECMW_ETYPE_HEX2
#define HECMW_ETYPE_TRI2
#define HECMW_ETYPE_PTT2
#define HECMW_ETYPE_LN31
#define HECMW_ETYPE_LN21
#define HECMW_ETYPE_PTQ2
#define HECMW_ETYPE_LN56
#define HECMW_ETYPE_LN44
#define HECMW_ETYPE_MST2
#define HECMW_ETYPE_SHQ2
#define HECMW_ETYPE_LN14
#define HECMW_INT
Definition: hecmw_config.h:48
MPI_Status HECMW_Status
Definition: hecmw_config.h:36
MPI_Comm HECMW_Comm
Definition: hecmw_config.h:30
MPI_Request HECMW_Request
Definition: hecmw_config.h:34
#define HECMW_SUM
Definition: hecmw_config.h:60
#define HECMW_ERROR
Definition: hecmw_config.h:68
#define HECMW_SUCCESS
Definition: hecmw_config.h:66
struct hecmwST_local_mesh * HECMW_dist_alloc()
void HECMW_dist_free(struct hecmwST_local_mesh *mesh)
int HECMW_dist_refine(struct hecmwST_local_mesh **mesh, int refine, const char *cad_filename, const char *part_filename)
struct hecmwST_local_mesh * mesh
Definition: hecmw_repart.h:71
int HECMW_set_error(int errorno, const char *fmt,...)
Definition: hecmw_error.c:37
int HECMW_get_max_node(int etype)
Definition: hecmw_etype.c:413
int HECMW_is_etype_33struct(int etype)
Definition: hecmw_etype.c:2030
int HECMW_is_etype_link(int etype)
Definition: hecmw_etype.c:1987
int HECMW_is_etype_surface(int etype)
Definition: hecmw_etype.c:1913
int HECMW_is_etype_truss(int etype)
Definition: hecmw_etype.c:2040
char * HECMW_get_ucd_label(int etype)
Definition: hecmw_etype.c:1230
int HECMW_is_etype_patch(int etype)
Definition: hecmw_etype.c:2048
int HECMW_is_etype_beam(int etype)
Definition: hecmw_etype.c:1963
int HECMW_is_etype_solid(int etype)
Definition: hecmw_etype.c:1925
int HECMW_is_etype_shell(int etype)
Definition: hecmw_etype.c:1973
int HECMW_is_etype_rod(int etype)
Definition: hecmw_etype.c:1904
#define NULL
int HECMW_log(int loglv, const char *fmt,...)
Definition: hecmw_log.c:260
#define HECMW_LOG_ERROR
Definition: hecmw_log.h:15
#define HECMW_LOG_WARN
Definition: hecmw_log.h:17
#define HECMW_LOG_DEBUG
Definition: hecmw_log.h:21
#define HECMW_calloc(nmemb, size)
Definition: hecmw_malloc.h:21
#define HECMW_free(ptr)
Definition: hecmw_malloc.h:24
#define HECMW_strdup(s)
Definition: hecmw_malloc.h:23
#define HECMW_malloc(size)
Definition: hecmw_malloc.h:20
int HECMW_set_int_iter_next(struct hecmw_set_int *set, int *value)
void HECMW_set_int_finalize(struct hecmw_set_int *set)
Definition: hecmw_set_int.c:36
int HECMW_set_int_add(struct hecmw_set_int *set, int value)
Definition: hecmw_set_int.c:60
int HECMW_set_int_init(struct hecmw_set_int *set)
Definition: hecmw_set_int.c:16
void HECMW_set_int_iter_init(struct hecmw_set_int *set)
size_t HECMW_set_int_check_dup(struct hecmw_set_int *set)
Definition: hecmw_set_int.c:78
#define HECMW_FLAG_PARTTYPE_UNKNOWN
Definition: hecmw_struct.h:143
#define HECMW_FLAG_PARTTYPE_NODEBASED
Definition: hecmw_struct.h:144
void HECMW_abort(HECMW_Comm comm)
Definition: hecmw_util.c:88
#define HECMW_assert(cond)
Definition: hecmw_util.h:40
int HECMW_varray_int_rmdup(struct hecmw_varray_int *varray)
size_t HECMW_varray_int_nval(const struct hecmw_varray_int *varray)
int * HECMW_varray_int_get_v(struct hecmw_varray_int *varray)
int HECMW_varray_int_get(const struct hecmw_varray_int *varray, size_t index)
int HECMW_varray_int_init(struct hecmw_varray_int *varray)
void HECMW_varray_int_finalize(struct hecmw_varray_int *varray)
const int * HECMW_varray_int_get_cv(const struct hecmw_varray_int *varray)
int HECMW_varray_int_append(struct hecmw_varray_int *varray, int value)
int HECMW_varray_int_cat(struct hecmw_varray_int *varray, const struct hecmw_varray_int *varray2)
int HECMW_varray_int_resize(struct hecmw_varray_int *varray, size_t len)
int * amp_type_definition
Definition: hecmw_struct.h:61
double * amp_table
Definition: hecmw_struct.h:72
struct hecmwST_section * section
Definition: hecmw_struct.h:245
struct hecmwST_amplitude * amp
Definition: hecmw_struct.h:248
struct hecmwST_material * material
Definition: hecmw_struct.h:246
struct hecmwST_refine_origin * refine_origin
Definition: hecmw_struct.h:253
struct hecmwST_mpc * mpc
Definition: hecmw_struct.h:247
struct hecmwST_node_grp * node_group
Definition: hecmw_struct.h:249
double * node_init_val_item
Definition: hecmw_struct.h:181
struct hecmwST_contact_pair * contact_pair
Definition: hecmw_struct.h:252
struct hecmwST_surf_grp * surf_group
Definition: hecmw_struct.h:251
long long * elem_node_index
Definition: hecmw_struct.h:195
char gridfile[HECMW_FILENAME_LEN+1]
Definition: hecmw_struct.h:154
char header[HECMW_HEADER_LEN+1]
Definition: hecmw_struct.h:157
HECMW_Comm HECMW_COMM
Definition: hecmw_struct.h:209
struct hecmwST_elem_grp * elem_group
Definition: hecmw_struct.h:250
int * when_i_was_refined_node
Definition: hecmw_struct.h:227
int * when_i_was_refined_elem
Definition: hecmw_struct.h:228
int * mat_subitem_index
Definition: hecmw_struct.h:42
double * mat_val
Definition: hecmw_struct.h:44
double * mat_temp
Definition: hecmw_struct.h:45
int * mpc_dof
Definition: hecmw_struct.h:52
double * mpc_val
Definition: hecmw_struct.h:53
double * mpc_const
Definition: hecmw_struct.h:54
int * mpc_index
Definition: hecmw_struct.h:50
int * mpc_item
Definition: hecmw_struct.h:51
double * sect_R_item
Definition: hecmw_struct.h:32
int * sect_mat_ID_index
Definition: hecmw_struct.h:27
int * sect_mat_ID_item
Definition: hecmw_struct.h:28