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