FrontISTR  6.0.0
Large-scale structural analysis program with finit element method
hecmw_partition.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 #define INAGAKI_PARTITIONER
7 
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <assert.h>
12 #include <errno.h>
13 #include <math.h>
14 
15 #include "hecmw_util.h"
16 #include "hecmw_common.h"
17 #include "hecmw_io.h"
18 
19 #include "hecmw_part_define.h"
20 #include "hecmw_part_struct.h"
21 #include "hecmw_part_log.h"
22 #include "hecmw_mesh_hash_sort.h"
23 #include "hecmw_mesh_edge_info.h"
24 #include "hecmw_part_get_control.h"
25 #include "hecmw_partition.h"
26 #include "hecmw_ucd_print.h"
27 #include "hecmw_varray_idx.h"
28 #include "hecmw_graph.h"
29 #include "hecmw_common_define.h"
30 
31 #ifdef _OPENMP
32 #include <omp.h>
33 #endif
34 
35 #define INTERNAL 1
36 
37 #define EXTERNAL 2
38 
39 #define BOUNDARY 4
40 
41 #define OVERLAP 8
42 
43 #define MASK 16
44 
45 #define MARK 32
46 
47 #define MY_DOMAIN 1
48 
49 #define NEIGHBOR_DOMAIN 2
50 
51 #define MPC_BLOCK 4
52 
53 #define CANDIDATE 8
54 
55 #define EPS (1.0E-12)
56 
57 #define F_1_2 (0.5)
58 
59 #define F_6_10 (0.6)
60 
61 #define QSORT_LOWER 50
62 
63 #define MASK_BIT(map, bit) ((map) |= (bit))
64 
65 #define EVAL_BIT(map, bit) ((map) & (bit))
66 
67 #define INV_BIT(map, bit) ((map) ^= (bit))
68 
69 #define CLEAR_BIT(map, bit) \
70  ((map) |= (bit)); \
71  ((map) ^= (bit))
72 
73 #define CLEAR_IEB(map) \
74  ((map) |= (7)); \
75  ((map) ^= (7))
76 
77 #define CLEAR_MM(map) \
78  ((map) |= (48)); \
79  ((map) ^= (48))
80 
81 #define DSWAP(a, aa) \
82  atemp = (a); \
83  (a) = (aa); \
84  (aa) = atemp;
85 
86 #define ISWAP(b, bb) \
87  btemp = (b); \
88  (b) = (bb); \
89  (bb) = btemp;
90 
91 #define RTC_NORMAL 0
92 
93 #define RTC_ERROR (-1)
94 
95 #define RTC_WARN 1
96 
97 #define MAX_NODE_SIZE 20
98 
99 struct link_unit {
100  int id;
101 
102  struct link_unit *next;
103 };
104 
105 struct link_list {
106  int n;
107 
108  struct link_unit *list;
109 
110  struct link_unit *last;
111 };
112 
113 /*===== internal/boundary node/element list of each domain =======*/
114 static int *n_int_nlist = NULL;
115 static int *n_bnd_nlist = NULL;
116 static int *n_int_elist = NULL;
117 static int *n_bnd_elist = NULL;
118 static int **int_nlist = NULL;
119 static int **bnd_nlist = NULL;
120 static int **int_elist = NULL;
121 static int **bnd_elist = NULL;
122 static int **ngrp_idx = NULL;
123 static int **ngrp_item = NULL;
124 static int **egrp_idx = NULL;
125 static int **egrp_item = NULL;
126 
127 static int spdup_clear_MMbnd(char *node_flag, char *elem_flag,
128  int current_domain) {
129  int i, node, elem;
130 
131  for (i = 0; i < n_bnd_nlist[2 * current_domain + 1]; i++) {
132  node = bnd_nlist[current_domain][i];
133  CLEAR_MM(node_flag[node - 1]);
134  }
135  for (i = 0; i < n_bnd_elist[2 * current_domain + 1]; i++) {
136  elem = bnd_elist[current_domain][i];
137  CLEAR_MM(elem_flag[elem - 1]);
138  }
139  return RTC_NORMAL;
140 }
141 
142 static int spdup_clear_IEB(char *node_flag, char *elem_flag,
143  int current_domain) {
144  int i, node, elem;
145 
146  for (i = 0; i < n_int_nlist[current_domain]; i++) {
147  node = int_nlist[current_domain][i];
148  CLEAR_IEB(node_flag[node - 1]);
149  }
150  for (i = 0; i < n_bnd_nlist[2 * current_domain + 1]; i++) {
151  node = bnd_nlist[current_domain][i];
152  CLEAR_IEB(node_flag[node - 1]);
153  }
154  for (i = 0; i < n_int_elist[current_domain]; i++) {
155  elem = int_elist[current_domain][i];
156  CLEAR_IEB(elem_flag[elem - 1]);
157  }
158  for (i = 0; i < n_bnd_elist[2 * current_domain + 1]; i++) {
159  elem = bnd_elist[current_domain][i];
160  CLEAR_IEB(elem_flag[elem - 1]);
161  }
162 
163  return RTC_NORMAL;
164 }
165 
166 static int spdup_init_list(const struct hecmwST_local_mesh *global_mesh) {
167  int i;
168  long long j, k;
169  long long js, je;
170  int node, n_domain, domain[20], flag;
171 
172  /*init lists for count (calloc) */
173  n_int_nlist = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
174  if (n_int_nlist == NULL) {
175  HECMW_set_error(errno, "");
176  goto error;
177  }
178  n_bnd_nlist = (int *)HECMW_calloc(2 * global_mesh->n_subdomain, sizeof(int));
179  if (n_bnd_nlist == NULL) {
180  HECMW_set_error(errno, "");
181  goto error;
182  }
183  n_int_elist = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
184  if (n_int_elist == NULL) {
185  HECMW_set_error(errno, "");
186  goto error;
187  }
188  n_bnd_elist = (int *)HECMW_calloc(2 * global_mesh->n_subdomain, sizeof(int));
189  if (n_bnd_elist == NULL) {
190  HECMW_set_error(errno, "");
191  goto error;
192  }
193  int_nlist = (int **)HECMW_malloc((size_t)global_mesh->n_subdomain * sizeof(int *));
194  if (int_nlist == NULL) {
195  HECMW_set_error(errno, "");
196  goto error;
197  }
198  bnd_nlist = (int **)HECMW_malloc((size_t)global_mesh->n_subdomain * sizeof(int *));
199  if (bnd_nlist == NULL) {
200  HECMW_set_error(errno, "");
201  goto error;
202  }
203  int_elist = (int **)HECMW_malloc((size_t)global_mesh->n_subdomain * sizeof(int *));
204  if (int_elist == NULL) {
205  HECMW_set_error(errno, "");
206  goto error;
207  }
208  bnd_elist = (int **)HECMW_malloc((size_t)global_mesh->n_subdomain * sizeof(int *));
209  if (bnd_elist == NULL) {
210  HECMW_set_error(errno, "");
211  goto error;
212  }
213 
214  /* count internal node */
215  for (i = 0; i < global_mesh->n_node; i++) {
216  n_int_nlist[global_mesh->node_ID[2 * i + 1]]++;
217  }
218 
219  /*count internal elem */
220  for (i = 0; i < global_mesh->n_elem; i++) {
221  n_int_elist[global_mesh->elem_ID[2 * i + 1]]++;
222  }
223 
224  /*count boundary node and elem */
225  for (i = 0; i < global_mesh->n_elem; i++) {
226  js = global_mesh->elem_node_index[i];
227  je = global_mesh->elem_node_index[i + 1];
228  node = global_mesh->elem_node_item[js];
229  n_domain = 1;
230  domain[0] = global_mesh->node_ID[2 * node - 1];
231  for (j = js + 1; j < je; j++) {
232  node = global_mesh->elem_node_item[j];
233  for (flag = 0, k = 0; k < n_domain; k++) {
234  if (global_mesh->node_ID[2 * node - 1] == domain[k]) {
235  flag++;
236  break;
237  }
238  }
239  if (flag == 0) {
240  domain[n_domain] = global_mesh->node_ID[2 * node - 1];
241  n_domain++;
242  }
243  }
244 
245  if (n_domain > 1) {
246  for (j = 0; j < n_domain; j++) {
247  n_bnd_elist[domain[j]]++;
248  n_bnd_nlist[domain[j]] += (int)(je - js);
249  }
250  }
251  }
252 
253  /*allocate node/element list of each domain */
254  for (i = 0; i < global_mesh->n_subdomain; i++) {
255  int_nlist[i] = (int *)HECMW_calloc(n_int_nlist[i], sizeof(int));
256  if (int_nlist[i] == NULL) {
257  HECMW_set_error(errno, "");
258  goto error;
259  }
260  bnd_nlist[i] = (int *)HECMW_calloc(n_bnd_nlist[i], sizeof(int));
261  if (bnd_nlist[i] == NULL) {
262  HECMW_set_error(errno, "");
263  goto error;
264  }
265  int_elist[i] = (int *)HECMW_calloc(n_int_elist[i], sizeof(int));
266  if (int_elist[i] == NULL) {
267  HECMW_set_error(errno, "");
268  goto error;
269  }
270  bnd_elist[i] = (int *)HECMW_calloc(n_bnd_elist[i], sizeof(int));
271  if (bnd_elist[i] == NULL) {
272  HECMW_set_error(errno, "");
273  goto error;
274  }
275  }
276 
277  return RTC_NORMAL;
278 
279 error:
280  return RTC_ERROR;
281 }
282 
283 static int int_cmp(const void *v1, const void *v2) {
284  const int *i1, *i2;
285 
286  i1 = (const int *)v1;
287  i2 = (const int *)v2;
288 
289  if (*i1 < *i2) return -1;
290  if (*i1 > *i2) return 1;
291  return 0;
292 }
293 
294 static int get_boundary_nodelist(const struct hecmwST_local_mesh *global_mesh,
295  int domain) {
296  int i, j;
297  long long k;
298  int node, elem, counter;
299  long long ks, ke;
300 
301  for (counter = 0, j = 0; j < n_bnd_elist[2 * domain + 1]; j++) {
302  elem = bnd_elist[domain][j];
303  ks = global_mesh->elem_node_index[elem - 1];
304  ke = global_mesh->elem_node_index[elem];
305  for (k = ks; k < ke; k++) {
306  node = global_mesh->elem_node_item[k];
307  bnd_nlist[domain][counter] = node;
308  counter++;
309  }
310  }
311 
312  qsort(bnd_nlist[domain], counter, sizeof(int), int_cmp);
313 
314  if (counter > 1) {
315  i = 1;
316  for (j = 1; j < counter; j++) {
317  if (bnd_nlist[domain][j - 1] != bnd_nlist[domain][j]) {
318  bnd_nlist[domain][i] = bnd_nlist[domain][j];
319  i++;
320  }
321  }
322  } else {
323  i = counter;
324  }
325 
326  n_bnd_nlist[2 * domain + 1] = i;
327 
328  return RTC_NORMAL;
329 }
330 
331 static int sort_and_resize_bndlist(const struct hecmwST_local_mesh *global_mesh,
332  int domain) {
333  int i, node, elem;
334  int *work = NULL;
335  int bnd_and_int, bnd_not_int;
336  int n_nlist, n_elist;
337 
338  /*boundary node list */
339  n_nlist = n_bnd_nlist[2 * domain + 1];
340  work = (int *)HECMW_malloc(n_nlist * sizeof(int));
341  if (work == NULL) {
342  HECMW_set_error(errno, "");
343  goto error;
344  }
345 
346  /*sort */
347  bnd_and_int = 0;
348  bnd_not_int = 0;
349  for (i = 0; i < n_nlist; i++) {
350  node = bnd_nlist[domain][i];
351  if (global_mesh->node_ID[2 * node - 1] == domain) {
352  work[bnd_and_int] = node;
353  bnd_and_int++;
354  }
355  }
356  for (i = 0; i < n_nlist; i++) {
357  node = bnd_nlist[domain][i];
358  if (global_mesh->node_ID[2 * node - 1] != domain) {
359  work[bnd_and_int + bnd_not_int] = node;
360  bnd_not_int++;
361  }
362  }
363  n_bnd_nlist[2 * domain] = bnd_and_int;
364  n_bnd_nlist[2 * domain + 1] = bnd_and_int + bnd_not_int;
365  HECMW_assert(n_nlist == n_bnd_nlist[2 * domain + 1]);
366 
367  /*resize */
368  HECMW_free(bnd_nlist[domain]);
369  bnd_nlist[domain] = (int *)HECMW_calloc(n_nlist, sizeof(int));
370  if (bnd_nlist[domain] == NULL) {
371  HECMW_set_error(errno, "");
372  goto error;
373  }
374  for (i = 0; i < n_nlist; i++) {
375  bnd_nlist[domain][i] = work[i];
376  }
377  HECMW_free(work);
378 
379  /*boundary element list */
380  n_elist = n_bnd_elist[2 * domain + 1];
381  work = (int *)HECMW_malloc(n_elist * sizeof(int));
382  if (work == NULL) {
383  HECMW_set_error(errno, "");
384  goto error;
385  }
386 
387  /*sort */
388  bnd_and_int = 0;
389  bnd_not_int = 0;
390  for (i = 0; i < n_elist; i++) {
391  elem = bnd_elist[domain][i];
392  if (global_mesh->elem_ID[2 * elem - 1] == domain) {
393  work[bnd_and_int] = elem;
394  bnd_and_int++;
395  }
396  }
397  for (i = 0; i < n_elist; i++) {
398  elem = bnd_elist[domain][i];
399  if (global_mesh->elem_ID[2 * elem - 1] != domain) {
400  work[bnd_and_int + bnd_not_int] = elem;
401  bnd_not_int++;
402  }
403  }
404  n_bnd_elist[2 * domain] = bnd_and_int;
405  n_bnd_elist[2 * domain + 1] = bnd_and_int + bnd_not_int;
406  for (i = 0; i < n_elist; i++) {
407  bnd_elist[domain][i] = work[i];
408  }
409  HECMW_free(work);
410  HECMW_assert(n_elist == n_bnd_elist[2 * domain + 1]);
411 
412  return RTC_NORMAL;
413 
414 error:
415  return RTC_ERROR;
416 }
417 
418 static int spdup_make_list(const struct hecmwST_local_mesh *global_mesh) {
419  int i;
420  long long j, k;
421  long long js, je;
422  int node, n_domain, domain[20], flag;
423  int current_domain;
424  int rtc;
425 
426  /*clear counters */
427  for (i = 0; i < global_mesh->n_subdomain; i++) {
428  n_int_nlist[i] = 0;
429  n_bnd_nlist[2 * i] = 0;
430  n_bnd_nlist[2 * i + 1] = 0;
431  n_int_elist[i] = 0;
432  n_bnd_elist[2 * i] = 0;
433  n_bnd_elist[2 * i + 1] = 0;
434  }
435 
436  /* internal nodelist for each domain */
437  for (i = 0; i < global_mesh->n_node; i++) {
438  current_domain = global_mesh->node_ID[2 * i + 1];
439  int_nlist[current_domain][n_int_nlist[current_domain]] = i + 1;
440  n_int_nlist[current_domain]++;
441  }
442 
443  /* internal elemlist for each domain */
444  for (i = 0; i < global_mesh->n_elem; i++) {
445  current_domain = global_mesh->elem_ID[2 * i + 1];
446  int_elist[current_domain][n_int_elist[current_domain]] = i + 1;
447  n_int_elist[current_domain]++;
448  }
449 
450  /* boundary elemlist for each domain */
451  for (i = 0; i < global_mesh->n_elem; i++) {
452  js = global_mesh->elem_node_index[i];
453  je = global_mesh->elem_node_index[i + 1];
454  node = global_mesh->elem_node_item[js];
455  n_domain = 1;
456  domain[0] = global_mesh->node_ID[2 * node - 1];
457  for (j = js + 1; j < je; j++) {
458  node = global_mesh->elem_node_item[j];
459  for (flag = 0, k = 0; k < n_domain; k++) {
460  if (global_mesh->node_ID[2 * node - 1] == domain[k]) {
461  flag++;
462  break;
463  }
464  }
465  if (flag == 0) {
466  domain[n_domain] = global_mesh->node_ID[2 * node - 1];
467  n_domain++;
468  }
469  }
470 
471  if (n_domain > 1) {
472  for (j = 0; j < n_domain; j++) {
473  bnd_elist[domain[j]][n_bnd_elist[2 * domain[j] + 1]] = i + 1;
474  n_bnd_elist[2 * domain[j] + 1]++;
475  }
476  }
477  }
478 
479  /* boundary nodelist for each domain */
480  for (i = 0; i < global_mesh->n_subdomain; i++) {
481  rtc = get_boundary_nodelist(global_mesh, i);
482  if (rtc != RTC_NORMAL) goto error;
483  }
484 
485  for (i = 0; i < global_mesh->n_subdomain; i++) {
486  rtc = sort_and_resize_bndlist(global_mesh, i);
487  if (rtc != RTC_NORMAL) goto error;
488  }
489 
490  return RTC_NORMAL;
491 
492 error:
493  return RTC_ERROR;
494 }
495 
496 static int spdup_make_node_grouplist(
497  const struct hecmwST_local_mesh *global_mesh) {
498  struct hecmwST_node_grp *node_group_global = global_mesh->node_group;
499  int i, j, k, node, n_bnd, n_out;
500  int *n_domain = NULL;
501  int **domain = NULL;
502  int current_domain;
503  int counter[global_mesh->n_subdomain];
504 
505  /*make list of node to domain(both internal and boundary) */
506  n_domain = (int *)HECMW_calloc(global_mesh->n_node, sizeof(int));
507  if (n_domain == NULL) {
508  HECMW_set_error(errno, "");
509  goto error;
510  }
511  /*count outer node(boundary and not internal) */
512  for (i = 0; i < global_mesh->n_subdomain; i++) {
513  n_bnd = n_bnd_nlist[2 * i];
514  n_out = n_bnd_nlist[2 * i + 1] - n_bnd_nlist[2 * i];
515  if (n_out == 0) continue;
516  for (j = 0; j < n_out; j++) {
517  node = bnd_nlist[i][n_bnd + j];
518  n_domain[node - 1]++;
519  }
520  }
521  /*make list */
522  domain = (int **)HECMW_malloc((size_t)global_mesh->n_node * sizeof(int *));
523  if (domain == NULL) {
524  HECMW_set_error(errno, "");
525  goto error;
526  }
527  for (i = 0; i < global_mesh->n_node; i++) {
528  domain[i] = (int *)HECMW_malloc((n_domain[i] + 1) *
529  sizeof(int)); /*+1 means internal node */
530  if (domain[i] == NULL) {
531  HECMW_set_error(errno, "");
532  goto error;
533  }
534  domain[i][0] = global_mesh->node_ID[2 * i + 1];
535  n_domain[i] = 1;
536  }
537  for (i = 0; i < global_mesh->n_subdomain; i++) {
538  n_bnd = n_bnd_nlist[2 * i];
539  n_out = n_bnd_nlist[2 * i + 1] - n_bnd_nlist[2 * i];
540  if (n_out == 0) continue;
541  for (j = 0; j < n_out; j++) {
542  node = bnd_nlist[i][n_bnd + j];
543  domain[node - 1][n_domain[node - 1]] = i;
544  n_domain[node - 1]++;
545  }
546  }
547 
548  /*make ngroup index list */
549  ngrp_idx = (int **)HECMW_malloc((size_t)global_mesh->n_subdomain * sizeof(int *));
550  if (ngrp_idx == NULL) {
551  HECMW_set_error(errno, "");
552  goto error;
553  }
554  for (i = 0; i < global_mesh->n_subdomain; i++) {
555  ngrp_idx[i] =
556  (int *)HECMW_calloc((node_group_global->n_grp + 1), sizeof(int));
557  if (ngrp_idx[i] == NULL) {
558  HECMW_set_error(errno, "");
559  goto error;
560  }
561  }
562  for (i = 0; i < node_group_global->n_grp; i++) { /*skip group "ALL" */
563  for (j = 0; j < global_mesh->n_subdomain; j++) {
564  ngrp_idx[j][i + 1] = ngrp_idx[j][i];
565  }
566  if (node_group_global->grp_index[i + 1] - node_group_global->grp_index[i] ==
567  global_mesh->n_node) {
568  continue;
569  }
570  for (j = node_group_global->grp_index[i];
571  j < node_group_global->grp_index[i + 1]; j++) {
572  node = node_group_global->grp_item[j];
573  for (k = 0; k < n_domain[node - 1]; k++) {
574  current_domain = domain[node - 1][k];
575  ngrp_idx[current_domain][i + 1]++;
576  }
577  }
578  }
579 
580  /*make ngroup item list */
581  ngrp_item = (int **)HECMW_malloc((size_t)global_mesh->n_subdomain * sizeof(int *));
582  if (ngrp_item == NULL) {
583  HECMW_set_error(errno, "");
584  goto error;
585  }
586  for (i = 0; i < global_mesh->n_subdomain; i++) {
587  ngrp_item[i] = (int *)HECMW_malloc(ngrp_idx[i][node_group_global->n_grp] *
588  sizeof(int));
589  if (ngrp_item[i] == NULL) {
590  HECMW_set_error(errno, "");
591  goto error;
592  }
593  counter[i] = 0;
594  }
595  for (i = 0; i < node_group_global->n_grp; i++) { /*skip group "ALL" */
596  if (node_group_global->grp_index[i + 1] - node_group_global->grp_index[i] ==
597  global_mesh->n_node) {
598  continue;
599  }
600  for (j = node_group_global->grp_index[i];
601  j < node_group_global->grp_index[i + 1]; j++) {
602  node = node_group_global->grp_item[j];
603  for (k = 0; k < n_domain[node - 1]; k++) {
604  current_domain = domain[node - 1][k];
605  ngrp_item[current_domain][counter[current_domain]] = node;
606  counter[current_domain]++;
607  }
608  }
609  }
610 
611  for (i = 0; i < global_mesh->n_node; i++) {
612  HECMW_free(domain[i]);
613  }
614  HECMW_free(n_domain);
615  HECMW_free(domain);
616  return RTC_NORMAL;
617 
618 error:
619  return RTC_ERROR;
620 }
621 
622 static int spdup_make_element_grouplist(
623  const struct hecmwST_local_mesh *global_mesh) {
624  struct hecmwST_elem_grp *elem_group_global = global_mesh->elem_group;
625  int i, j, k, elem, n_bnd, n_out;
626  int *n_domain = NULL;
627  int **domain = NULL;
628  int current_domain;
629  int counter[global_mesh->n_subdomain];
630 
631  /*make list of elem to domain(both internal and boundary) */
632  n_domain = (int *)HECMW_calloc(global_mesh->n_elem, sizeof(int));
633  if (n_domain == NULL) {
634  HECMW_set_error(errno, "");
635  goto error;
636  }
637  /*count outer elem(boundary and not internal) */
638  for (i = 0; i < global_mesh->n_subdomain; i++) {
639  n_bnd = n_bnd_elist[2 * i];
640  n_out = n_bnd_elist[2 * i + 1] - n_bnd_elist[2 * i];
641  if (n_out == 0) continue;
642  for (j = 0; j < n_out; j++) {
643  elem = bnd_elist[i][n_bnd + j];
644  n_domain[elem - 1]++;
645  }
646  }
647  /*make list */
648  domain = (int **)HECMW_malloc((size_t)global_mesh->n_elem * sizeof(int *));
649  if (domain == NULL) {
650  HECMW_set_error(errno, "");
651  goto error;
652  }
653  for (i = 0; i < global_mesh->n_elem; i++) {
654  domain[i] = (int *)HECMW_malloc((n_domain[i] + 1) *
655  sizeof(int)); /*+1 means internal elem */
656  if (domain[i] == NULL) {
657  HECMW_set_error(errno, "");
658  goto error;
659  }
660  domain[i][0] = global_mesh->elem_ID[2 * i + 1];
661  n_domain[i] = 1;
662  }
663  for (i = 0; i < global_mesh->n_subdomain; i++) {
664  n_bnd = n_bnd_elist[2 * i];
665  n_out = n_bnd_elist[2 * i + 1] - n_bnd_elist[2 * i];
666  if (n_out == 0) continue;
667  for (j = 0; j < n_out; j++) {
668  elem = bnd_elist[i][n_bnd + j];
669  domain[elem - 1][n_domain[elem - 1]] = i;
670  n_domain[elem - 1]++;
671  }
672  }
673 
674  /*make egroup index list */
675  egrp_idx = (int **)HECMW_malloc((size_t)global_mesh->n_subdomain * sizeof(int *));
676  if (egrp_idx == NULL) {
677  HECMW_set_error(errno, "");
678  goto error;
679  }
680  for (i = 0; i < global_mesh->n_subdomain; i++) {
681  egrp_idx[i] =
682  (int *)HECMW_calloc((elem_group_global->n_grp + 1), sizeof(int));
683  if (egrp_idx[i] == NULL) {
684  HECMW_set_error(errno, "");
685  goto error;
686  }
687  }
688  for (i = 0; i < elem_group_global->n_grp; i++) { /*skip group "ALL" */
689  for (j = 0; j < global_mesh->n_subdomain; j++) {
690  egrp_idx[j][i + 1] = egrp_idx[j][i];
691  }
692  if (elem_group_global->grp_index[i + 1] - elem_group_global->grp_index[i] ==
693  global_mesh->n_elem) {
694  continue;
695  }
696  for (j = elem_group_global->grp_index[i];
697  j < elem_group_global->grp_index[i + 1]; j++) {
698  elem = elem_group_global->grp_item[j];
699  for (k = 0; k < n_domain[elem - 1]; k++) {
700  current_domain = domain[elem - 1][k];
701  egrp_idx[current_domain][i + 1]++;
702  }
703  }
704  }
705 
706  /*make egroup item list */
707  egrp_item = (int **)HECMW_malloc((size_t)global_mesh->n_subdomain * sizeof(int *));
708  if (egrp_item == NULL) {
709  HECMW_set_error(errno, "");
710  goto error;
711  }
712  for (i = 0; i < global_mesh->n_subdomain; i++) {
713  egrp_item[i] = (int *)HECMW_malloc(egrp_idx[i][elem_group_global->n_grp] *
714  sizeof(int));
715  if (egrp_item[i] == NULL) {
716  HECMW_set_error(errno, "");
717  goto error;
718  }
719  counter[i] = 0;
720  }
721  for (i = 0; i < elem_group_global->n_grp; i++) { /*skip group "ALL" */
722  if (elem_group_global->grp_index[i + 1] - elem_group_global->grp_index[i] ==
723  global_mesh->n_elem) {
724  continue;
725  }
726  for (j = elem_group_global->grp_index[i];
727  j < elem_group_global->grp_index[i + 1]; j++) {
728  elem = elem_group_global->grp_item[j];
729  for (k = 0; k < n_domain[elem - 1]; k++) {
730  current_domain = domain[elem - 1][k];
731  egrp_item[current_domain][counter[current_domain]] = elem;
732  counter[current_domain]++;
733  }
734  }
735  }
736 
737  for (i = 0; i < global_mesh->n_elem; i++) {
738  HECMW_free(domain[i]);
739  }
740  HECMW_free(n_domain);
741  HECMW_free(domain);
742  return RTC_NORMAL;
743 
744 error:
745  return RTC_ERROR;
746 }
747 
748 static int spdup_makelist_main(const struct hecmwST_local_mesh *global_mesh) {
749  int rtc;
750 
751  rtc = spdup_init_list(global_mesh);
752  if (rtc != RTC_NORMAL) goto error;
753 
754  rtc = spdup_make_list(global_mesh);
755  if (rtc != RTC_NORMAL) goto error;
756 
757  rtc = spdup_make_node_grouplist(global_mesh);
758  if (rtc != RTC_NORMAL) goto error;
759 
760  rtc = spdup_make_element_grouplist(global_mesh);
761  if (rtc != RTC_NORMAL) goto error;
762 
763  return RTC_NORMAL;
764 
765 error:
766  return RTC_ERROR;
767 }
768 
769 static void spdup_freelist(const struct hecmwST_local_mesh *global_mesh) {
770  int i;
771 
772  HECMW_free(n_int_nlist);
773  HECMW_free(n_bnd_nlist);
774  HECMW_free(n_int_elist);
775  HECMW_free(n_bnd_elist);
776 
777  for (i = 0; i < global_mesh->n_subdomain; i++) {
778  HECMW_free(int_nlist[i]);
779  HECMW_free(bnd_nlist[i]);
780  HECMW_free(int_elist[i]);
781  HECMW_free(bnd_elist[i]);
782  HECMW_free(ngrp_idx[i]);
783  HECMW_free(ngrp_item[i]);
784  HECMW_free(egrp_idx[i]);
785  HECMW_free(egrp_item[i]);
786  }
787 
788  HECMW_free(int_nlist);
789  HECMW_free(bnd_nlist);
790  HECMW_free(int_elist);
791  HECMW_free(bnd_elist);
792  HECMW_free(ngrp_idx);
793  HECMW_free(ngrp_item);
794  HECMW_free(egrp_idx);
795  HECMW_free(egrp_item);
796 }
797 
798 static int is_spdup_available(const struct hecmwST_local_mesh *global_mesh) {
799  return global_mesh->hecmw_flag_parttype == HECMW_FLAG_PARTTYPE_NODEBASED &&
800  global_mesh->hecmw_flag_partdepth == 1 &&
801  global_mesh->mpc->n_mpc == 0 && global_mesh->contact_pair->n_pair == 0;
802 }
803 
804 /*================================================================================================*/
805 
806 static char *get_dist_file_name(char *header, int domain, char *fname,
807  size_t fname_size) {
808  snprintf(fname, fname_size, "%s.%d", header, domain);
809  return fname;
810 }
811 
812 static void free_link_list(struct link_unit *llist) {
813  struct link_unit *p, *q;
814 
815  for (p = llist; p; p = q) {
816  q = p->next;
817  HECMW_free(p);
818  }
819  llist = NULL;
820 }
821 
822 /*================================================================================================*/
823 
824 static int init_struct_global(struct hecmwST_local_mesh *local_mesh) {
825  if (local_mesh == NULL) {
826  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh\' is NULL");
827  goto error;
828  }
829 
830  memset(local_mesh->gridfile, 0, HECMW_NAME_LEN + 1);
831  local_mesh->hecmw_n_file = 0;
832  local_mesh->files = NULL;
833  memset(local_mesh->header, 0, HECMW_HEADER_LEN + 1);
834 
835  local_mesh->hecmw_flag_adapt = 0;
836  local_mesh->hecmw_flag_initcon = 0;
837  local_mesh->hecmw_flag_parttype = 0;
838  local_mesh->hecmw_flag_partdepth = 0;
839  local_mesh->hecmw_flag_version = 0;
840  local_mesh->hecmw_flag_partcontact = 0;
841 
842  local_mesh->zero_temp = 0.0;
843 
844  return RTC_NORMAL;
845 
846 error:
847  return RTC_ERROR;
848 }
849 
850 static int init_struct_node(struct hecmwST_local_mesh *local_mesh) {
851  if (local_mesh == NULL) {
852  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh\' is NULL");
853  goto error;
854  }
855 
856  local_mesh->n_node = 0;
857  local_mesh->n_node_gross = 0;
858  local_mesh->nn_internal = 0;
859  local_mesh->node_internal_list = NULL;
860 
861  local_mesh->node = NULL;
862  local_mesh->node_ID = NULL;
863  local_mesh->global_node_ID = NULL;
864 
865  local_mesh->n_dof = 0;
866  local_mesh->n_dof_grp = 0;
867  local_mesh->node_dof_index = NULL;
868  local_mesh->node_dof_item = NULL;
869 
870  local_mesh->node_val_index = NULL;
871  local_mesh->node_val_item = NULL;
872 
873  local_mesh->node_init_val_index = NULL;
874  local_mesh->node_init_val_item = NULL;
875 
876  return RTC_NORMAL;
877 
878 error:
879  return RTC_ERROR;
880 }
881 
882 static int init_struct_elem(struct hecmwST_local_mesh *local_mesh) {
883  if (local_mesh == NULL) {
884  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh\' is NULL");
885  goto error;
886  }
887 
888  local_mesh->n_elem = 0;
889  local_mesh->n_elem_gross = 0;
890  local_mesh->ne_internal = 0;
891  local_mesh->elem_internal_list = NULL;
892 
893  local_mesh->elem_ID = NULL;
894  local_mesh->global_elem_ID = NULL;
895 
896  local_mesh->n_elem_type = 0;
897  local_mesh->elem_type = NULL;
898  local_mesh->elem_type_index = NULL;
899  local_mesh->elem_type_item = NULL;
900 
901  local_mesh->elem_node_index = NULL;
902  local_mesh->elem_node_item = NULL;
903 
904  local_mesh->section_ID = NULL;
905 
906  local_mesh->n_elem_mat_ID = 0;
907  local_mesh->elem_mat_ID_index = NULL;
908  local_mesh->elem_mat_ID_item = NULL;
909 
910  local_mesh->elem_mat_int_index = NULL;
911  local_mesh->elem_mat_int_val = NULL;
912 
913  local_mesh->elem_val_index = NULL;
914  local_mesh->elem_val_item = NULL;
915 
916  return RTC_NORMAL;
917 
918 error:
919  return RTC_ERROR;
920 }
921 
922 static int init_struct_comm(struct hecmwST_local_mesh *local_mesh) {
923  if (local_mesh == NULL) {
924  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh\' is NULL");
925  goto error;
926  }
927 
928  local_mesh->zero = 0;
929  local_mesh->PETOT = 0;
930  local_mesh->PEsmpTOT = 0;
931  local_mesh->my_rank = 0;
932  local_mesh->errnof = 0;
933  local_mesh->n_subdomain = 0;
934 
935  local_mesh->n_neighbor_pe = 0;
936  local_mesh->neighbor_pe = NULL;
937 
938  local_mesh->import_index = NULL;
939  local_mesh->import_item = NULL;
940  local_mesh->export_index = NULL;
941  local_mesh->export_item = NULL;
942  local_mesh->shared_index = NULL;
943  local_mesh->shared_item = NULL;
944 
945  return RTC_NORMAL;
946 
947 error:
948  return RTC_ERROR;
949 }
950 
951 static int init_struct_adapt(struct hecmwST_local_mesh *local_mesh) {
952  if (local_mesh == NULL) {
953  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh\' is NULL");
954  goto error;
955  }
956 
957  local_mesh->coarse_grid_level = 0;
958  local_mesh->n_adapt = 0;
959  local_mesh->when_i_was_refined_node = NULL;
960  local_mesh->when_i_was_refined_elem = NULL;
961  local_mesh->adapt_parent_type = NULL;
962  local_mesh->adapt_type = NULL;
963  local_mesh->adapt_level = NULL;
964  local_mesh->adapt_parent = NULL;
965  local_mesh->adapt_children_index = NULL;
966  local_mesh->adapt_children_item = NULL;
967 
968  return RTC_NORMAL;
969 
970 error:
971  return RTC_ERROR;
972 }
973 
974 static int init_struct_sect(struct hecmwST_local_mesh *local_mesh) {
975  if (local_mesh == NULL) {
976  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh\' is NULL");
977  goto error;
978  }
979  if (local_mesh->section == NULL) {
980  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh->section\' is NULL");
981  goto error;
982  }
983 
984  local_mesh->section->n_sect = 0;
985  local_mesh->section->sect_type = NULL;
986  local_mesh->section->sect_opt = NULL;
987  local_mesh->section->sect_mat_ID_index = NULL;
988  local_mesh->section->sect_mat_ID_item = NULL;
989  local_mesh->section->sect_I_index = NULL;
990  local_mesh->section->sect_I_item = NULL;
991  local_mesh->section->sect_R_index = NULL;
992  local_mesh->section->sect_R_item = NULL;
993 
994  return RTC_NORMAL;
995 
996 error:
997  return RTC_ERROR;
998 }
999 
1000 static int init_struct_mat(struct hecmwST_local_mesh *local_mesh) {
1001  if (local_mesh == NULL) {
1002  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh\' is NULL");
1003  goto error;
1004  }
1005  if (local_mesh->material == NULL) {
1006  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh->material\' is NULL");
1007  goto error;
1008  }
1009 
1010  local_mesh->material->n_mat = 0;
1011  local_mesh->material->n_mat_item = 0;
1012  local_mesh->material->n_mat_subitem = 0;
1013  local_mesh->material->n_mat_table = 0;
1014  local_mesh->material->mat_name = NULL;
1015  local_mesh->material->mat_item_index = NULL;
1016  local_mesh->material->mat_subitem_index = NULL;
1017  local_mesh->material->mat_table_index = NULL;
1018  local_mesh->material->mat_val = NULL;
1019  local_mesh->material->mat_temp = NULL;
1020 
1021  return RTC_NORMAL;
1022 
1023 error:
1024  return RTC_ERROR;
1025 }
1026 
1027 static int init_struct_mpc(struct hecmwST_local_mesh *local_mesh) {
1028  if (local_mesh == NULL) {
1029  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh\' is NULL");
1030  return -1;
1031  }
1032  if (local_mesh->mpc == NULL) {
1033  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh->mpc\' is NULL");
1034  goto error;
1035  }
1036 
1037  local_mesh->mpc->n_mpc = 0;
1038  local_mesh->mpc->mpc_index = NULL;
1039  local_mesh->mpc->mpc_item = NULL;
1040  local_mesh->mpc->mpc_dof = NULL;
1041  local_mesh->mpc->mpc_val = NULL;
1042  local_mesh->mpc->mpc_const = NULL;
1043 
1044  return RTC_NORMAL;
1045 
1046 error:
1047  return RTC_ERROR;
1048 }
1049 
1050 static int init_struct_amp(struct hecmwST_local_mesh *local_mesh) {
1051  if (local_mesh == NULL) {
1052  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh\' is NULL");
1053  goto error;
1054  }
1055 
1056  if (local_mesh->amp == NULL) {
1057  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh->amp\' is NULL");
1058  goto error;
1059  }
1060 
1061  local_mesh->amp->n_amp = 0;
1062  local_mesh->amp->amp_name = NULL;
1063  local_mesh->amp->amp_type_definition = NULL;
1064  local_mesh->amp->amp_type_time = NULL;
1065  local_mesh->amp->amp_type_value = NULL;
1066  local_mesh->amp->amp_index = NULL;
1067  local_mesh->amp->amp_val = NULL;
1068  local_mesh->amp->amp_table = NULL;
1069 
1070  return RTC_NORMAL;
1071 
1072 error:
1073  return RTC_ERROR;
1074 }
1075 
1076 static int init_struct_node_grp(struct hecmwST_local_mesh *local_mesh) {
1077  if (local_mesh == NULL) {
1078  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh\' is NULL");
1079  goto error;
1080  }
1081 
1082  if (local_mesh->node_group == NULL) {
1083  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh->node_group\' is NULL");
1084  goto error;
1085  }
1086 
1087  local_mesh->node_group->n_grp = 0;
1088  local_mesh->node_group->grp_name = NULL;
1089  local_mesh->node_group->grp_index = NULL;
1090  local_mesh->node_group->grp_item = NULL;
1091 
1092  local_mesh->node_group->n_bc = 0;
1093  local_mesh->node_group->bc_grp_ID = 0;
1094  local_mesh->node_group->bc_grp_type = 0;
1095  local_mesh->node_group->bc_grp_index = 0;
1096  local_mesh->node_group->bc_grp_dof = 0;
1097  local_mesh->node_group->bc_grp_val = 0;
1098 
1099  return RTC_NORMAL;
1100 
1101 error:
1102  return RTC_ERROR;
1103 }
1104 
1105 static int init_struct_elem_grp(struct hecmwST_local_mesh *local_mesh) {
1106  if (local_mesh == NULL) {
1107  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh\' is NULL");
1108  goto error;
1109  }
1110 
1111  if (local_mesh->elem_group == NULL) {
1112  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh->elem_group\' is NULL");
1113  goto error;
1114  }
1115 
1116  local_mesh->elem_group->n_grp = 0;
1117  local_mesh->elem_group->grp_name = NULL;
1118  local_mesh->elem_group->grp_index = NULL;
1119  local_mesh->elem_group->grp_item = NULL;
1120 
1121  local_mesh->elem_group->n_bc = 0;
1122  local_mesh->elem_group->bc_grp_ID = NULL;
1123  local_mesh->elem_group->bc_grp_type = NULL;
1124  local_mesh->elem_group->bc_grp_index = NULL;
1125  local_mesh->elem_group->bc_grp_val = NULL;
1126 
1127  return RTC_NORMAL;
1128 
1129 error:
1130  return RTC_ERROR;
1131 }
1132 
1133 static int init_struct_surf_grp(struct hecmwST_local_mesh *local_mesh) {
1134  if (local_mesh == NULL) {
1135  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh\' is NULL");
1136  goto error;
1137  }
1138 
1139  if (local_mesh->surf_group == NULL) {
1140  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh->surf_group\' is NULL");
1141  goto error;
1142  }
1143 
1144  local_mesh->surf_group->n_grp = 0;
1145  local_mesh->surf_group->grp_name = NULL;
1146  local_mesh->surf_group->grp_index = NULL;
1147  local_mesh->surf_group->grp_item = NULL;
1148 
1149  local_mesh->surf_group->n_bc = 0;
1150  local_mesh->surf_group->bc_grp_ID = NULL;
1151  local_mesh->surf_group->bc_grp_type = NULL;
1152  local_mesh->surf_group->bc_grp_index = NULL;
1153  local_mesh->surf_group->bc_grp_val = NULL;
1154 
1155  return RTC_NORMAL;
1156 
1157 error:
1158  return RTC_ERROR;
1159 }
1160 
1161 static int init_struct_contact_pair(struct hecmwST_local_mesh *local_mesh) {
1162  if (local_mesh == NULL) {
1163  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'local_mesh\' is NULL");
1164  goto error;
1165  }
1166 
1167  if (local_mesh->contact_pair == NULL) {
1169  "\'local_mesh->contact_pair\' is NULL");
1170  goto error;
1171  }
1172 
1173  local_mesh->contact_pair->n_pair = 0;
1174  local_mesh->contact_pair->name = NULL;
1175  local_mesh->contact_pair->type = NULL;
1176  local_mesh->contact_pair->slave_grp_id = NULL;
1177  local_mesh->contact_pair->slave_orisgrp_id = NULL;
1178  local_mesh->contact_pair->master_grp_id = NULL;
1179 
1180  return RTC_NORMAL;
1181 
1182 error:
1183  return RTC_ERROR;
1184 }
1185 
1186 /*================================================================================================*/
1187 
1188 static void clean_struct_global(struct hecmwST_local_mesh *local_mesh) {
1189  if (local_mesh == NULL) return;
1190 
1191  init_struct_global(local_mesh);
1192 }
1193 
1194 static void clean_struct_node(struct hecmwST_local_mesh *local_mesh) {
1195  if (local_mesh == NULL) return;
1196 
1197  if (local_mesh->node_internal_list) {
1198  HECMW_free(local_mesh->node_internal_list);
1199  }
1200  if (local_mesh->node) {
1201  HECMW_free(local_mesh->node);
1202  }
1203  if (local_mesh->node_ID) {
1204  HECMW_free(local_mesh->node_ID);
1205  }
1206  if (local_mesh->global_node_ID) {
1207  HECMW_free(local_mesh->global_node_ID);
1208  }
1209  if (local_mesh->node_dof_index) {
1210  HECMW_free(local_mesh->node_dof_index);
1211  }
1212  if (local_mesh->node_init_val_index) {
1213  HECMW_free(local_mesh->node_init_val_index);
1214  }
1215  if (local_mesh->node_init_val_item) {
1216  HECMW_free(local_mesh->node_init_val_item);
1217  }
1218 
1219  init_struct_node(local_mesh);
1220 }
1221 
1222 static void clean_struct_elem(struct hecmwST_local_mesh *local_mesh) {
1223  if (local_mesh == NULL) return;
1224 
1225  if (local_mesh->elem_internal_list) {
1226  HECMW_free(local_mesh->elem_internal_list);
1227  }
1228  if (local_mesh->elem_ID) {
1229  HECMW_free(local_mesh->elem_ID);
1230  }
1231  if (local_mesh->global_elem_ID) {
1232  HECMW_free(local_mesh->global_elem_ID);
1233  }
1234  if (local_mesh->elem_type) {
1235  HECMW_free(local_mesh->elem_type);
1236  }
1237  if (local_mesh->elem_type_index) {
1238  HECMW_free(local_mesh->elem_type_index);
1239  }
1240  if (local_mesh->elem_node_index) {
1241  HECMW_free(local_mesh->elem_node_index);
1242  }
1243  if (local_mesh->elem_node_item) {
1244  HECMW_free(local_mesh->elem_node_item);
1245  }
1246  if (local_mesh->section_ID) {
1247  HECMW_free(local_mesh->section_ID);
1248  }
1249  if (local_mesh->elem_mat_ID_index) {
1250  HECMW_free(local_mesh->elem_mat_ID_index);
1251  }
1252  if (local_mesh->elem_mat_ID_item) {
1253  HECMW_free(local_mesh->elem_mat_ID_item);
1254  }
1255 
1256  init_struct_elem(local_mesh);
1257 }
1258 
1259 static void clean_struct_comm(struct hecmwST_local_mesh *local_mesh) {
1260  if (local_mesh == NULL) return;
1261 
1262  if (local_mesh->neighbor_pe) {
1263  HECMW_free(local_mesh->neighbor_pe);
1264  }
1265  if (local_mesh->import_index) {
1266  HECMW_free(local_mesh->import_index);
1267  }
1268  if (local_mesh->import_item) {
1269  HECMW_free(local_mesh->import_item);
1270  }
1271  if (local_mesh->export_index) {
1272  HECMW_free(local_mesh->export_index);
1273  }
1274  if (local_mesh->export_item) {
1275  HECMW_free(local_mesh->export_item);
1276  }
1277  if (local_mesh->shared_index) {
1278  HECMW_free(local_mesh->shared_index);
1279  }
1280  if (local_mesh->shared_item) {
1281  HECMW_free(local_mesh->shared_item);
1282  }
1283 
1284  init_struct_comm(local_mesh);
1285 }
1286 
1287 static void clean_struct_adapt(struct hecmwST_local_mesh *local_mesh) {
1288  if (local_mesh == NULL) return;
1289 
1290  init_struct_adapt(local_mesh);
1291 }
1292 
1293 static void clean_struct_sect(struct hecmwST_local_mesh *local_mesh) {
1294  if (local_mesh == NULL) return;
1295  if (local_mesh->section == NULL) return;
1296 
1297  init_struct_sect(local_mesh);
1298 }
1299 
1300 static void clean_struct_mat(struct hecmwST_local_mesh *local_mesh) {
1301  if (local_mesh == NULL) return;
1302  if (local_mesh->material == NULL) return;
1303 
1304  init_struct_mat(local_mesh);
1305 }
1306 
1307 static void clean_struct_mpc(struct hecmwST_local_mesh *local_mesh) {
1308  if (local_mesh == NULL) return;
1309  if (local_mesh->mpc == NULL) return;
1310 
1311  HECMW_free(local_mesh->mpc->mpc_index);
1312  HECMW_free(local_mesh->mpc->mpc_item);
1313  HECMW_free(local_mesh->mpc->mpc_dof);
1314  HECMW_free(local_mesh->mpc->mpc_val);
1315  HECMW_free(local_mesh->mpc->mpc_const);
1316 
1317  init_struct_mpc(local_mesh);
1318 }
1319 
1320 static void clean_struct_amp(struct hecmwST_local_mesh *local_mesh) {
1321  if (local_mesh == NULL) return;
1322  if (local_mesh->amp == NULL) return;
1323 
1324  init_struct_amp(local_mesh);
1325 }
1326 
1327 static void clean_struct_node_grp(struct hecmwST_local_mesh *local_mesh) {
1328  if (local_mesh == NULL) return;
1329  if (local_mesh->node_group == NULL) return;
1330 
1331  if (local_mesh->node_group->grp_index) {
1332  HECMW_free(local_mesh->node_group->grp_index);
1333  }
1334  if (local_mesh->node_group->grp_item) {
1335  HECMW_free(local_mesh->node_group->grp_item);
1336  }
1337 
1338  init_struct_node_grp(local_mesh);
1339 }
1340 
1341 static void clean_struct_elem_grp(struct hecmwST_local_mesh *local_mesh) {
1342  if (local_mesh == NULL) return;
1343  if (local_mesh->elem_group == NULL) return;
1344 
1345  if (local_mesh->elem_group->grp_index) {
1346  HECMW_free(local_mesh->elem_group->grp_index);
1347  }
1348  if (local_mesh->elem_group->grp_item) {
1349  HECMW_free(local_mesh->elem_group->grp_item);
1350  }
1351 
1352  init_struct_elem_grp(local_mesh);
1353 }
1354 
1355 static void clean_struct_surf_grp(struct hecmwST_local_mesh *local_mesh) {
1356  if (local_mesh == NULL) return;
1357  if (local_mesh->surf_group == NULL) return;
1358 
1359  if (local_mesh->surf_group->grp_index) {
1360  HECMW_free(local_mesh->surf_group->grp_index);
1361  }
1362  if (local_mesh->surf_group->grp_item) {
1363  HECMW_free(local_mesh->surf_group->grp_item);
1364  }
1365 
1366  init_struct_surf_grp(local_mesh);
1367 }
1368 
1369 static void clean_struct_contact_pair(struct hecmwST_local_mesh *local_mesh) {
1370  if (local_mesh == NULL) return;
1371  if (local_mesh->contact_pair == NULL) return;
1372 
1373  if (local_mesh->contact_pair->type) {
1374  HECMW_free(local_mesh->contact_pair->type);
1375  }
1376  if (local_mesh->contact_pair->slave_grp_id) {
1377  HECMW_free(local_mesh->contact_pair->slave_grp_id);
1378  }
1379  if (local_mesh->contact_pair->slave_orisgrp_id) {
1381  }
1382  if (local_mesh->contact_pair->master_grp_id) {
1383  HECMW_free(local_mesh->contact_pair->master_grp_id);
1384  }
1385 
1386  init_struct_contact_pair(local_mesh);
1387 }
1388 
1389 static void clean_struct_local_mesh(struct hecmwST_local_mesh *local_mesh) {
1390  if (local_mesh == NULL) return;
1391 
1392  clean_struct_global(local_mesh);
1393  clean_struct_node(local_mesh);
1394  clean_struct_elem(local_mesh);
1395  clean_struct_comm(local_mesh);
1396  clean_struct_adapt(local_mesh);
1397  clean_struct_sect(local_mesh);
1398  clean_struct_mat(local_mesh);
1399  clean_struct_mpc(local_mesh);
1400  clean_struct_amp(local_mesh);
1401  clean_struct_node_grp(local_mesh);
1402  clean_struct_elem_grp(local_mesh);
1403  clean_struct_surf_grp(local_mesh);
1404  clean_struct_contact_pair(local_mesh);
1405 }
1406 
1407 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1408  * - - - - - - - - - */
1409 
1410 static int init_struct_result_data(struct hecmwST_result_data *result_data) {
1411  if (result_data == NULL) {
1412  HECMW_set_error(errno, "\'result_data\' is NULL");
1413  goto error;
1414  }
1415 
1416  result_data->nn_dof = NULL;
1417  result_data->node_label = NULL;
1418  result_data->node_val_item = NULL;
1419 
1420  result_data->ne_dof = NULL;
1421  result_data->elem_label = NULL;
1422  result_data->elem_val_item = NULL;
1423 
1424  return RTC_NORMAL;
1425 
1426 error:
1427  return RTC_ERROR;
1428 }
1429 
1430 static void free_struct_result_data(struct hecmwST_result_data *result_data) {
1431  int i;
1432 
1433  if (result_data == NULL) return;
1434 
1435  HECMW_free(result_data->nn_dof);
1436  HECMW_free(result_data->ne_dof);
1437 
1438  if (result_data->node_label) {
1439  for (i = 0; i < result_data->nn_component; i++) {
1440  HECMW_free(result_data->node_label[i]);
1441  }
1442  HECMW_free(result_data->node_label);
1443  }
1444  if (result_data->elem_label) {
1445  for (i = 0; i < result_data->ne_component; i++) {
1446  HECMW_free(result_data->elem_label[i]);
1447  }
1448  HECMW_free(result_data->elem_label);
1449  }
1450 
1451  HECMW_free(result_data->node_val_item);
1452  HECMW_free(result_data->elem_val_item);
1453 
1454  HECMW_free(result_data);
1455  result_data = NULL;
1456 }
1457 
1458 /*================================================================================================*/
1459 
1460 static int search_eqn_block_idx(const struct hecmwST_local_mesh *mesh) {
1461  int i;
1462 
1463  for (i = 0; i < mesh->node_group->n_grp; i++) {
1465  return i;
1466  }
1467 
1468  return -1;
1469 }
1470 
1471 /*================================================================================================*/
1472 
1473 static int quick_sort(int no, int n, double *arr, int *brr, int *istack) {
1474  double a, atemp;
1475  int b, btemp;
1476  int i, ir, j, k, l;
1477  int jstack = 0;
1478  int nstack;
1479 
1480  nstack = no;
1481  l = 0;
1482  ir = n - 1;
1483 
1484  for (;;) {
1485  if (ir - l < QSORT_LOWER) {
1486  for (j = l + 1; j <= ir; j++) {
1487  a = arr[j];
1488  b = brr[j];
1489  for (i = j - 1; i >= l; i--) {
1490  if (arr[i] <= a) break;
1491  arr[i + 1] = arr[i];
1492  brr[i + 1] = brr[i];
1493  }
1494  arr[i + 1] = a;
1495  brr[i + 1] = b;
1496  }
1497 
1498  if (!jstack) return 0;
1499 
1500  ir = istack[jstack];
1501  l = istack[jstack - 1];
1502  jstack -= 2;
1503 
1504  } else {
1505  k = (l + ir) >> 1;
1506 
1507  DSWAP(arr[k], arr[l + 1])
1508  ISWAP(brr[k], brr[l + 1])
1509 
1510  if (arr[l] > arr[ir]) {
1511  DSWAP(arr[l], arr[ir])
1512  ISWAP(brr[l], brr[ir])
1513  }
1514 
1515  if (arr[l + 1] > arr[ir]) {
1516  DSWAP(arr[l + 1], arr[ir])
1517  ISWAP(brr[l + 1], brr[ir])
1518  }
1519 
1520  if (arr[l] > arr[l + 1]) {
1521  DSWAP(arr[l], arr[l + 1])
1522  ISWAP(brr[l], brr[l + 1])
1523  }
1524 
1525  i = l + 1;
1526  j = ir;
1527  a = arr[l + 1];
1528  b = brr[l + 1];
1529 
1530  for (;;) {
1531  do
1532  i++;
1533  while (arr[i] < a);
1534  do
1535  j--;
1536  while (arr[j] > a);
1537 
1538  if (j < i) break;
1539 
1540  DSWAP(arr[i], arr[j])
1541  ISWAP(brr[i], brr[j])
1542  }
1543 
1544  arr[l + 1] = arr[j];
1545  arr[j] = a;
1546  brr[l + 1] = brr[j];
1547  brr[j] = b;
1548 
1549  jstack += 2;
1550 
1551  if (jstack > nstack) {
1553  return -1;
1554  }
1555 
1556  if (ir - i + 1 >= j - l) {
1557  istack[jstack] = ir;
1558  istack[jstack - 1] = i;
1559  ir = j - 1;
1560  } else {
1561  istack[jstack] = j - 1;
1562  istack[jstack - 1] = l;
1563  l = i;
1564  }
1565  }
1566  }
1567 }
1568 
1569 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1570  * - - - - - - - - - */
1571 
1572 static int rcb_partition(int n, const double *coord, int *wnum,
1573  const struct hecmw_part_cont_data *cont_data) {
1574  double *value;
1575  int *id, *stack;
1576  int rtc;
1577  int counter;
1578  int i, j, k;
1579 
1580  id = (int *)HECMW_malloc(sizeof(int) * n);
1581  if (id == NULL) {
1582  HECMW_set_error(errno, "");
1583  goto error;
1584  }
1585  stack = (int *)HECMW_malloc(sizeof(int) * n);
1586  if (stack == NULL) {
1587  HECMW_set_error(errno, "");
1588  goto error;
1589  }
1590  value = (double *)HECMW_malloc(sizeof(double) * n);
1591  if (value == NULL) {
1592  HECMW_set_error(errno, "");
1593  goto error;
1594  }
1595 
1596  for (i = 0; i < cont_data->n_rcb_div; i++) {
1597  for (j = 0; j < pow(2, i); j++) {
1598  counter = 0;
1599 
1600  switch (cont_data->rcb_axis[i]) {
1601  case HECMW_PART_RCB_X_AXIS: /* X-axis */
1602  for (k = 0; k < n; k++) {
1603  if (wnum[2 * k + 1] == j) {
1604  id[counter] = k;
1605  value[counter] = coord[3 * k];
1606  counter++;
1607  }
1608  }
1609  break;
1610 
1611  case HECMW_PART_RCB_Y_AXIS: /* Y-axis */
1612  for (k = 0; k < n; k++) {
1613  if (wnum[2 * k + 1] == j) {
1614  id[counter] = k;
1615  value[counter] = coord[3 * k + 1];
1616  counter++;
1617  }
1618  }
1619  break;
1620 
1621  case HECMW_PART_RCB_Z_AXIS: /* Z-axis */
1622  for (k = 0; k < n; k++) {
1623  if (wnum[2 * k + 1] == j) {
1624  id[counter] = k;
1625  value[counter] = coord[3 * k + 2];
1626  counter++;
1627  }
1628  }
1629  break;
1630 
1631  default:
1633  goto error;
1634  }
1635 
1636  /* quick sort */
1637  rtc = quick_sort(n, counter, value, id, stack);
1638  if (rtc != RTC_NORMAL) goto error;
1639 
1640  /* belonging domain of node */
1641  for (k = 0; k < counter * F_1_2; k++) {
1642  wnum[2 * id[k] + 1] = j + (int)pow(2, i);
1643  }
1644  }
1645  }
1646 
1647  HECMW_free(id);
1648  HECMW_free(stack);
1649  HECMW_free(value);
1650 
1651  return RTC_NORMAL;
1652 
1653 error:
1654  HECMW_free(id);
1655  HECMW_free(stack);
1656  HECMW_free(value);
1657 
1658  return RTC_ERROR;
1659 }
1660 
1661 /*------------------------------------------------------------------------------------------------*/
1662 
1663 static int calc_gravity(const struct hecmwST_local_mesh *global_mesh,
1664  double *coord) {
1665  double coord_x, coord_y, coord_z;
1666  int node;
1667  long long js, je;
1668  int i, j;
1669 
1670  for (i = 0; i < global_mesh->n_elem; i++) {
1671  js = global_mesh->elem_node_index[i];
1672  je = global_mesh->elem_node_index[i + 1];
1673 
1674  for (coord_x = 0.0, coord_y = 0.0, coord_z = 0.0, j = js; j < je; j++) {
1675  node = global_mesh->elem_node_item[j];
1676 
1677  coord_x += global_mesh->node[3 * (node - 1)];
1678  coord_y += global_mesh->node[3 * (node - 1) + 1];
1679  coord_z += global_mesh->node[3 * (node - 1) + 2];
1680  }
1681 
1682  coord[3 * i] = coord_x / (je - js);
1683  coord[3 * i + 1] = coord_y / (je - js);
1684  coord[3 * i + 2] = coord_z / (je - js);
1685  }
1686 
1687  return RTC_NORMAL;
1688 }
1689 
1690 static int rcb_partition_eb(struct hecmwST_local_mesh *global_mesh,
1691  const struct hecmw_part_cont_data *cont_data) {
1692  double *coord = NULL;
1693  int rtc;
1694 
1695  coord = (double *)HECMW_malloc(sizeof(double) * (size_t)global_mesh->n_elem * 3);
1696  if (coord == NULL) {
1697  HECMW_set_error(errno, "");
1698  goto error;
1699  }
1700 
1701  rtc = calc_gravity(global_mesh, coord);
1702  if (rtc != RTC_NORMAL) goto error;
1703 
1704  rtc = rcb_partition(global_mesh->n_elem, coord, global_mesh->elem_ID,
1705  cont_data);
1706  if (rtc != RTC_NORMAL) goto error;
1707 
1708  HECMW_free(coord);
1709 
1710  return RTC_NORMAL;
1711 
1712 error:
1713  HECMW_free(coord);
1714 
1715  return RTC_ERROR;
1716 }
1717 
1718 /*================================================================================================*/
1719 
1720 static int create_node_graph_link_list(
1721  const struct hecmwST_local_mesh *global_mesh,
1722  const struct hecmw_part_edge_data *edge_data, struct link_list **graph) {
1723  int node1, node2;
1724  long long int i;
1725 
1726  for (i = 0; i < edge_data->n_edge; i++) {
1727  node1 = edge_data->edge_node_item[2 * i];
1728  node2 = edge_data->edge_node_item[2 * i + 1];
1729 
1730  /* node 1 */
1731  graph[node1 - 1]->last->next =
1732  (struct link_unit *)HECMW_malloc(sizeof(struct link_unit));
1733  if (graph[node1 - 1]->last->next == NULL) {
1734  HECMW_set_error(errno, "");
1735  goto error;
1736  }
1737 
1738  graph[node1 - 1]->n += 1;
1739  graph[node1 - 1]->last->next->id = node2;
1740  graph[node1 - 1]->last->next->next = NULL;
1741  graph[node1 - 1]->last = graph[node1 - 1]->last->next;
1742 
1743  /* node 2 */
1744  graph[node2 - 1]->last->next =
1745  (struct link_unit *)HECMW_malloc(sizeof(struct link_unit));
1746  if (graph[node2 - 1]->last->next == NULL) {
1747  HECMW_set_error(errno, "");
1748  goto error;
1749  }
1750 
1751  graph[node2 - 1]->n += 1;
1752  graph[node2 - 1]->last->next->id = node1;
1753  graph[node2 - 1]->last->next->next = NULL;
1754  graph[node2 - 1]->last = graph[node2 - 1]->last->next;
1755  }
1756 
1757  return RTC_NORMAL;
1758 
1759 error:
1760  return RTC_ERROR;
1761 }
1762 
1763 static int create_node_graph_compress(
1764  const struct hecmwST_local_mesh *global_mesh, struct link_list **graph,
1765  idx_t *node_graph_index, idx_t *node_graph_item) {
1766  long long int counter;
1767  int i, j;
1768  struct link_unit *p;
1769 
1770  for (counter = 0, i = 0; i < global_mesh->n_node; i++) {
1771  node_graph_index[i + 1] = node_graph_index[i] + graph[i]->n;
1772 
1773  for (p = graph[i]->list, j = 0; j < graph[i]->n; j++) {
1774  p = p->next;
1775  node_graph_item[counter++] = p->id - 1;
1776  }
1777  }
1778 
1779  return RTC_NORMAL;
1780 }
1781 
1782 static int create_node_graph(const struct hecmwST_local_mesh *global_mesh,
1783  const struct hecmw_part_edge_data *edge_data,
1784  idx_t *node_graph_index, idx_t *node_graph_item) {
1785  struct link_list **graph = NULL;
1786  int rtc;
1787  int i;
1788 
1789  graph = (struct link_list **)HECMW_malloc(sizeof(struct link_list *) *
1790  (size_t)global_mesh->n_node);
1791  if (graph == NULL) {
1792  HECMW_set_error(errno, "");
1793  goto error;
1794  } else {
1795  for (i = 0; i < global_mesh->n_node; i++) {
1796  graph[i] = NULL;
1797  }
1798  }
1799  for (i = 0; i < global_mesh->n_node; i++) {
1800  graph[i] = (struct link_list *)HECMW_malloc(sizeof(struct link_list));
1801  if (graph[i] == NULL) {
1802  HECMW_set_error(errno, "");
1803  goto error;
1804  } else {
1805  graph[i]->list = NULL;
1806  }
1807  }
1808  for (i = 0; i < global_mesh->n_node; i++) {
1809  graph[i]->list = (struct link_unit *)HECMW_malloc(sizeof(struct link_unit));
1810  if (graph[i]->list == NULL) {
1811  HECMW_set_error(errno, "");
1812  goto error;
1813  } else {
1814  graph[i]->n = 0;
1815  graph[i]->list->next = NULL;
1816  graph[i]->last = graph[i]->list;
1817  }
1818  }
1819 
1820  rtc = create_node_graph_link_list(global_mesh, edge_data, graph);
1821  if (rtc != RTC_NORMAL) goto error;
1822 
1823  rtc = create_node_graph_compress(global_mesh, graph, node_graph_index,
1824  node_graph_item);
1825  if (rtc != RTC_NORMAL) goto error;
1826 
1827  for (i = 0; i < global_mesh->n_node; i++) {
1828  free_link_list(graph[i]->list);
1829  HECMW_free(graph[i]);
1830  }
1831  HECMW_free(graph);
1832 
1833  return RTC_NORMAL;
1834 
1835 error:
1836  if (graph) {
1837  for (i = 0; i < global_mesh->n_node; i++) {
1838  if (graph[i]) {
1839  free_link_list(graph[i]->list);
1840  HECMW_free(graph[i]);
1841  }
1842  }
1843  HECMW_free(graph);
1844  }
1845 
1846  return RTC_ERROR;
1847 }
1848 
1849 /*------------------------------------------------------------------------------------------------*/
1850 
1851 static int set_node_belong_elem(const struct hecmwST_local_mesh *global_mesh,
1852  struct hecmw_part_node_data *node_data) {
1853  int node, counter;
1854  struct link_list **node_list = NULL;
1855  struct link_unit *p;
1856  int size;
1857  int i;
1858  long long j;
1859 
1860  node_data->node_elem_index = NULL;
1861  node_data->node_elem_item = NULL;
1862 
1863  node_list = (struct link_list **)HECMW_malloc(sizeof(struct link_list *) *
1864  (size_t)global_mesh->n_node);
1865  if (node_list == NULL) {
1866  HECMW_set_error(errno, "");
1867  goto error;
1868  } else {
1869  for (i = 0; i < global_mesh->n_node; i++) {
1870  node_list[i] = NULL;
1871  }
1872  }
1873  for (i = 0; i < global_mesh->n_node; i++) {
1874  node_list[i] = (struct link_list *)HECMW_malloc(sizeof(struct link_list));
1875  if (node_list[i] == NULL) {
1876  HECMW_set_error(errno, "");
1877  goto error;
1878  } else {
1879  node_list[i]->list = NULL;
1880  }
1881  }
1882  for (i = 0; i < global_mesh->n_node; i++) {
1883  node_list[i]->list =
1884  (struct link_unit *)HECMW_malloc(sizeof(struct link_unit));
1885  if (node_list[i]->list == NULL) {
1886  HECMW_set_error(errno, "");
1887  goto error;
1888  } else {
1889  node_list[i]->n = 0;
1890  node_list[i]->list->next = NULL;
1891  node_list[i]->last = node_list[i]->list;
1892  }
1893  }
1894 
1895  for (i = 0; i < global_mesh->n_elem; i++) {
1896  for (j = global_mesh->elem_node_index[i];
1897  j < global_mesh->elem_node_index[i + 1]; j++) {
1898  node = global_mesh->elem_node_item[j];
1899 
1900  size = sizeof(struct link_list);
1901  node_list[node - 1]->last->next = (struct link_unit *)HECMW_malloc(size);
1902  if (node_list[node - 1]->last->next == NULL) {
1903  HECMW_set_error(errno, "");
1904  goto error;
1905  }
1906 
1907  node_list[node - 1]->last = node_list[node - 1]->last->next;
1908  node_list[node - 1]->last->id = i + 1;
1909  node_list[node - 1]->last->next = NULL;
1910  node_list[node - 1]->n += 1;
1911  }
1912  }
1913 
1914  node_data->node_elem_index =
1915  (int *)HECMW_calloc(global_mesh->n_node + 1, sizeof(int));
1916  if (node_data->node_elem_index == NULL) {
1917  HECMW_set_error(errno, "");
1918  goto error;
1919  }
1920  for (i = 0; i < global_mesh->n_node; i++) {
1921  node_data->node_elem_index[i + 1] =
1922  node_data->node_elem_index[i] + node_list[i]->n;
1923  }
1924 
1925  size = sizeof(int) * node_data->node_elem_index[global_mesh->n_node];
1926  node_data->node_elem_item = (int *)HECMW_malloc(size);
1927  if (node_data->node_elem_item == NULL) {
1928  HECMW_set_error(errno, "");
1929  goto error;
1930  }
1931  for (counter = 0, i = 0; i < global_mesh->n_node; i++) {
1932  for (p = node_list[i]->list, j = 0; j < node_list[i]->n; j++) {
1933  p = p->next;
1934  node_data->node_elem_item[counter++] = p->id;
1935  }
1936  HECMW_assert(counter == node_data->node_elem_index[i + 1]);
1937  }
1938 
1939  for (i = 0; i < global_mesh->n_node; i++) {
1940  free_link_list(node_list[i]->list);
1941  HECMW_free(node_list[i]);
1942  }
1943  HECMW_free(node_list);
1944 
1945  return RTC_NORMAL;
1946 
1947 error:
1948  if (node_list) {
1949  for (i = 0; i < global_mesh->n_node; i++) {
1950  if (node_list[i]) {
1951  free_link_list(node_list[i]->list);
1952  HECMW_free(node_list[i]);
1953  }
1954  }
1955  HECMW_free(node_list);
1956  }
1957 
1958  HECMW_free(node_data->node_elem_index);
1959  HECMW_free(node_data->node_elem_item);
1960  node_data->node_elem_index = NULL;
1961  node_data->node_elem_item = NULL;
1962 
1963  return RTC_ERROR;
1964 }
1965 
1966 static long long create_elem_graph_link_list(
1967  const struct hecmwST_local_mesh *global_mesh,
1968  const struct hecmw_part_node_data *node_data, struct link_list **graph) {
1969  char *elem_flag = NULL;
1970  int elem, node;
1971  int size;
1972  long long counter;
1973  int i;
1974  long long j, k;
1975 
1976  elem_flag = (char *)HECMW_malloc(sizeof(char) * global_mesh->n_elem);
1977  if (elem_flag == NULL) {
1978  HECMW_set_error(errno, "");
1979  goto error;
1980  }
1981 
1982  for (counter = 0, i = 0; i < global_mesh->n_elem; i++) {
1983  memset(elem_flag, 0, sizeof(char) * global_mesh->n_elem);
1984  MASK_BIT(elem_flag[i], MASK);
1985 
1986  for (j = global_mesh->elem_node_index[i];
1987  j < global_mesh->elem_node_index[i + 1]; j++) {
1988  node = global_mesh->elem_node_item[j];
1989 
1990  for (k = node_data->node_elem_index[node - 1];
1991  k < node_data->node_elem_index[node]; k++) {
1992  elem = node_data->node_elem_item[k];
1993 
1994  if (!EVAL_BIT(elem_flag[elem - 1], MASK)) {
1995  MASK_BIT(elem_flag[elem - 1], MASK);
1996 
1997  size = sizeof(struct link_unit);
1998  graph[i]->last->next = (struct link_unit *)HECMW_malloc(size);
1999  if (graph[i]->last->next == NULL) {
2000  HECMW_set_error(errno, "");
2001  goto error;
2002  }
2003 
2004  graph[i]->n += 1;
2005  graph[i]->last->next->id = elem;
2006  graph[i]->last->next->next = NULL;
2007  graph[i]->last = graph[i]->last->next;
2008  counter++;
2009  }
2010  }
2011  }
2012  }
2013 
2014  HECMW_free(elem_flag);
2015 
2016  return counter;
2017 
2018 error:
2019  HECMW_free(elem_flag);
2020 
2021  return -1;
2022 }
2023 
2024 static int create_elem_graph_compress(
2025  const struct hecmwST_local_mesh *global_mesh, struct link_list **graph,
2026  idx_t *elem_graph_index, idx_t *elem_graph_item) {
2027  struct link_unit *p;
2028  long long int counter;
2029  int i, j;
2030 
2031  for (counter = 0, i = 0; i < global_mesh->n_elem; i++) {
2032  elem_graph_index[i + 1] = elem_graph_index[i] + graph[i]->n;
2033 
2034  for (p = graph[i]->list, j = 0; j < graph[i]->n; j++) {
2035  p = p->next;
2036  elem_graph_item[counter++] = p->id - 1;
2037  }
2038  }
2039  HECMW_assert(elem_graph_index[global_mesh->n_elem] == counter);
2040 
2041  return RTC_NORMAL;
2042 }
2043 
2044 static idx_t *create_elem_graph(const struct hecmwST_local_mesh *global_mesh,
2045  idx_t *elem_graph_index) {
2046  struct hecmw_part_node_data *node_data = NULL;
2047  struct link_list **graph = NULL;
2048  idx_t *elem_graph_item = NULL;
2049  long long n_graph;
2050  int rtc;
2051  int i;
2052 
2053  node_data = (struct hecmw_part_node_data *)HECMW_malloc(
2054  sizeof(struct hecmw_part_node_data));
2055  if (node_data == NULL) {
2056  HECMW_set_error(errno, "");
2057  goto error;
2058  } else {
2059  node_data->node_elem_index = NULL;
2060  node_data->node_elem_item = NULL;
2061  }
2062 
2063  rtc = set_node_belong_elem(global_mesh, node_data);
2064  if (rtc != RTC_NORMAL) goto error;
2065 
2066  graph = (struct link_list **)HECMW_malloc(sizeof(struct link_list *) *
2067  (size_t)global_mesh->n_elem);
2068  if (graph == NULL) {
2069  HECMW_set_error(errno, "");
2070  goto error;
2071  } else {
2072  for (i = 0; i < global_mesh->n_elem; i++) {
2073  graph[i] = NULL;
2074  }
2075  }
2076  for (i = 0; i < global_mesh->n_elem; i++) {
2077  graph[i] = (struct link_list *)HECMW_malloc(sizeof(struct link_list));
2078  if (graph[i] == NULL) {
2079  HECMW_set_error(errno, "");
2080  goto error;
2081  } else {
2082  graph[i]->list = NULL;
2083  }
2084  }
2085  for (i = 0; i < global_mesh->n_elem; i++) {
2086  graph[i]->list = (struct link_unit *)HECMW_malloc(sizeof(struct link_unit));
2087  if (graph[i]->list == NULL) {
2088  HECMW_set_error(errno, "");
2089  goto error;
2090  } else {
2091  graph[i]->n = 0;
2092  graph[i]->list->next = NULL;
2093  graph[i]->last = graph[i]->list;
2094  }
2095  }
2096 
2097  n_graph = create_elem_graph_link_list(global_mesh, node_data, graph);
2098  if (n_graph < 0) goto error;
2099 
2100  elem_graph_item = (idx_t *)HECMW_malloc(sizeof(idx_t) * (size_t)n_graph);
2101  if (elem_graph_item == NULL) {
2102  HECMW_set_error(errno, "");
2103  goto error;
2104  }
2105 
2106  rtc = create_elem_graph_compress(global_mesh, graph, elem_graph_index,
2107  elem_graph_item);
2108  if (rtc != RTC_NORMAL) goto error;
2109 
2110  HECMW_free(node_data->node_elem_index);
2111  HECMW_free(node_data->node_elem_item);
2112  HECMW_free(node_data);
2113  for (i = 0; i < global_mesh->n_elem; i++) {
2114  free_link_list(graph[i]->list);
2115  HECMW_free(graph[i]);
2116  }
2117  HECMW_free(graph);
2118 
2119  return elem_graph_item;
2120 
2121 error:
2122  if (node_data) {
2123  HECMW_free(node_data->node_elem_index);
2124  HECMW_free(node_data->node_elem_item);
2125  HECMW_free(node_data);
2126  }
2127  if (graph) {
2128  for (i = 0; i < global_mesh->n_elem; i++) {
2129  if (graph[i]) {
2130  free_link_list(graph[i]->list);
2131  HECMW_free(graph[i]);
2132  }
2133  }
2134  HECMW_free(graph);
2135  }
2136  HECMW_free(elem_graph_item);
2137 
2138  return NULL;
2139 }
2140 
2141 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2142  * - - - - - - - - - */
2143 
2144 static int pmetis_interface(const int n_vertex, const int n_domain, idx_t *xadj,
2145  idx_t *adjncy, idx_t *part) {
2146  idx_t edgecut = 0; /* number of edge-cut */
2147 #ifdef HECMW_PART_WITH_METIS
2148  idx_t n = (idx_t)n_vertex; /* number of vertices */
2149  idx_t *vwgt = NULL; /* weight for vertices */
2150  idx_t nparts = (idx_t)n_domain; /* number of sub-domains */
2151 
2152  idx_t ncon = 1; /* number of balancing constraints */
2153  idx_t *vsize = NULL;
2154  real_t *tpwgts = NULL;
2155  real_t *ubvec = NULL;
2156  idx_t *options = NULL;
2157 
2158  HECMW_log(HECMW_LOG_DEBUG, "Entering pmetis(v5)...\n");
2159  METIS_PartGraphRecursive(&n, &ncon, xadj, adjncy, vwgt, vsize, NULL,
2160  &nparts, tpwgts, ubvec, options, &edgecut, part);
2161  HECMW_log(HECMW_LOG_DEBUG, "Returned from pmetis(v5)\n");
2162 #endif
2163 
2164  return (int)edgecut;
2165 }
2166 
2167 static int kmetis_interface(const int n_vertex, const int n_domain, idx_t *xadj,
2168  idx_t *adjncy, idx_t *part) {
2169  idx_t edgecut = 0; /* number of edge-cut */
2170 #ifdef HECMW_PART_WITH_METIS
2171  idx_t n = (idx_t)n_vertex; /* number of vertices */
2172  idx_t *vwgt = NULL; /* weight for vertices */
2173  idx_t nparts = (idx_t)n_domain; /* number of sub-domains */
2174 
2175  idx_t ncon = 1; /* number of balancing constraints */
2176  idx_t *vsize = NULL;
2177  real_t *tpwgts = NULL;
2178  real_t *ubvec = NULL;
2179  idx_t *options = NULL;
2180 
2181  HECMW_log(HECMW_LOG_DEBUG, "Entering kmetis(v5)...\n");
2182  METIS_PartGraphKway(&n, &ncon, xadj, adjncy, vwgt, vsize, NULL, &nparts,
2183  tpwgts, ubvec, options, &edgecut, part);
2184  HECMW_log(HECMW_LOG_DEBUG, "Returned from kmetis(v5)\n");
2185 #endif
2186 
2187  return (int)edgecut;
2188 }
2189 
2190 static int pmetis_interface_with_weight(int n_vertex, int n_con, int n_domain,
2191  idx_t *xadj, idx_t *adjncy,
2192  idx_t *vwgt, idx_t *part) {
2193  idx_t edgecut = 0; /* number of edge-cut */
2194 #ifdef HECMW_PART_WITH_METIS
2195  idx_t n = (idx_t)n_vertex; /* number of vertices */
2196  idx_t *adjwgt = NULL; /* weight for edges */
2197  idx_t nparts = (idx_t)n_domain; /* number of sub-domains */
2198 
2199  idx_t ncon = (idx_t)n_con; /* number of balancing constraints */
2200  idx_t *vsize = NULL;
2201  real_t *tpwgts = NULL;
2202  real_t *ubvec = NULL;
2203  idx_t *options = NULL;
2204 
2205  HECMW_log(HECMW_LOG_DEBUG, "Entering pmetis(v5)...\n");
2206  METIS_PartGraphRecursive(&n, &ncon, xadj, adjncy, vwgt, vsize, adjwgt,
2207  &nparts, tpwgts, ubvec, options, &edgecut, part);
2208  HECMW_log(HECMW_LOG_DEBUG, "Returned from pmetis(v5)\n");
2209 #endif
2210 
2211  return (int)edgecut;
2212 }
2213 
2214 static int kmetis_interface_with_weight(int n_vertex, int n_con, int n_domain,
2215  idx_t *xadj, idx_t *adjncy,
2216  idx_t *vwgt, idx_t *part) {
2217  idx_t edgecut = 0; /* number of edge-cut */
2218 #ifdef HECMW_PART_WITH_METIS
2219  idx_t n = (idx_t)n_vertex; /* number of vertices */
2220  idx_t *adjwgt = NULL; /* weight for edges */
2221  idx_t nparts = (idx_t)n_domain; /* number of sub-domains */
2222 
2223  idx_t ncon = (idx_t)n_con; /* number of balancing constraints */
2224  idx_t *vsize = NULL;
2225  real_t *tpwgts = NULL;
2226  real_t *ubvec = NULL;
2227  idx_t *options = NULL;
2228 
2229  HECMW_log(HECMW_LOG_DEBUG, "Entering kmetis(v5)...\n");
2230  METIS_PartGraphKway(&n, &ncon, xadj, adjncy, vwgt, vsize, adjwgt, &nparts,
2231  tpwgts, ubvec, options, &edgecut, part);
2232  HECMW_log(HECMW_LOG_DEBUG, "Returned from kmetis(v5)\n");
2233 #endif
2234 
2235  return (int)edgecut;
2236 }
2237 
2238 static int contact_agg_mark_node_group(int *mark,
2239  struct hecmwST_local_mesh *global_mesh,
2240  int gid, int agg_id, int *agg_dup) {
2241  struct hecmwST_node_grp *ngrp = global_mesh->node_group;
2242  int istart, iend, i;
2243 
2244  HECMW_assert(0 < gid && gid <= ngrp->n_grp);
2245 
2246  istart = ngrp->grp_index[gid - 1];
2247  iend = ngrp->grp_index[gid];
2248  for (i = istart; i < iend; i++) {
2249  int nid = ngrp->grp_item[i] - 1;
2250  HECMW_assert(0 <= nid && nid < global_mesh->n_node);
2251  if (0 <= mark[nid] && mark[nid] < agg_id) {
2252  /* the node is included in some other contact pair */
2253  if (*agg_dup == -1) {
2254  *agg_dup = mark[nid];
2255  } else if (mark[nid] != *agg_dup) {
2256  fprintf(stderr,
2257  "ERROR: node included in multiple node groups in different "
2258  "contact pairs,\n"
2259  " which is not supported by CONTACT=AGGREGATE\n");
2261  }
2262  }
2263  mark[nid] = agg_id;
2264  }
2265  return RTC_NORMAL;
2266 }
2267 
2268 static int HECMW_get_num_surf_node(int etype, int sid) {
2269  switch (etype) {
2270  case HECMW_ETYPE_TET1:
2271  case HECMW_ETYPE_PTT1:
2272  return 3;
2273  case HECMW_ETYPE_TET2:
2274  case HECMW_ETYPE_PTT2:
2275  return 6;
2276  case HECMW_ETYPE_HEX1:
2277  case HECMW_ETYPE_PTQ1:
2278  return 4;
2279  case HECMW_ETYPE_HEX2:
2280  case HECMW_ETYPE_PTQ2:
2281  return 8;
2282  case HECMW_ETYPE_PRI1:
2283  if (1 <= sid && sid <= 3) return 4;
2284  if (4 <= sid && sid <= 5) return 3;
2285  case HECMW_ETYPE_PRI2:
2286  if (1 <= sid && sid <= 3) return 8;
2287  if (4 <= sid && sid <= 5) return 6;
2288  default:
2289  fprintf(
2290  stderr,
2291  "ERROR: parallel contact analysis of elem type %d not supported\n",
2292  etype);
2293  return -1;
2294  }
2295  return -1;
2296 }
2297 
2298 static const int *HECMW_get_surf_node(int etype, int sid) {
2299  HECMW_assert(0 < sid);
2300 
2301  static const int elem_surf_tet1[4][3] = {
2302  {1, 2, 3}, {0, 3, 2}, {0, 1, 3}, {0, 2, 1}};
2303  static const int elem_surf_tet2[4][6] = {{1, 4, 2, 9, 3, 8},
2304  {0, 7, 3, 9, 2, 5},
2305  {0, 6, 1, 8, 3, 7},
2306  {0, 5, 2, 4, 1, 6}};
2307  static const int elem_surf_hex1[6][4] = {{3, 0, 4, 7}, {1, 2, 6, 5},
2308  {0, 1, 5, 4}, {2, 3, 7, 6},
2309  {3, 2, 1, 0}, {4, 5, 6, 7}};
2310  static const int elem_surf_hex2[6][8] = {
2311  {3, 11, 0, 16, 4, 15, 7, 19}, {1, 9, 2, 18, 6, 13, 5, 17},
2312  {0, 8, 1, 17, 5, 12, 4, 16}, {2, 10, 3, 19, 7, 14, 6, 18},
2313  {3, 10, 2, 9, 1, 8, 0, 11}, {4, 12, 5, 13, 6, 14, 7, 15}};
2314  static const int elem_surf_pri1[5][4] = {
2315  {1, 2, 5, 4}, {2, 0, 3, 5}, {0, 1, 4, 3}, {2, 1, 0, -1}, {3, 4, 5, -1}};
2316  static const int elem_surf_pri2[5][8] = {{1, 6, 2, 14, 5, 9, 4, 13},
2317  {2, 7, 0, 12, 3, 10, 5, 14},
2318  {0, 8, 1, 13, 4, 11, 3, 12},
2319  {2, 6, 1, 8, 0, 7, -1, -1},
2320  {3, 11, 4, 9, 5, 10, -1, -1}};
2321  static const int elem_surf_ptt1[3] = {0, 1, 2};
2322  static const int elem_surf_ptt2[6] = {0, 1, 2, 3, 4, 5};
2323  static const int elem_surf_ptq1[4] = {0, 1, 2, 3};
2324  static const int elem_surf_ptq2[8] = {0, 1, 2, 3, 4, 5, 6, 7};
2325  switch (etype) {
2326  case HECMW_ETYPE_TET1:
2327  return elem_surf_tet1[sid - 1];
2328  case HECMW_ETYPE_TET2:
2329  return elem_surf_tet2[sid - 1];
2330  case HECMW_ETYPE_HEX1:
2331  return elem_surf_hex1[sid - 1];
2332  case HECMW_ETYPE_HEX2:
2333  return elem_surf_hex2[sid - 1];
2334  case HECMW_ETYPE_PRI1:
2335  return elem_surf_pri1[sid - 1];
2336  case HECMW_ETYPE_PRI2:
2337  return elem_surf_pri2[sid - 1];
2338  case HECMW_ETYPE_PTT1:
2339  return elem_surf_ptt1;
2340  case HECMW_ETYPE_PTT2:
2341  return elem_surf_ptt2;
2342  case HECMW_ETYPE_PTQ1:
2343  return elem_surf_ptq1;
2344  case HECMW_ETYPE_PTQ2:
2345  return elem_surf_ptq2;
2346  }
2347  fprintf(stderr,
2348  "ERROR: parallel contact analysis of element type %d not supported\n",
2349  etype);
2350  return NULL;
2351 }
2352 
2353 static int HECMW_fistr_get_num_surf_node(int etype, int sid) {
2354  switch (etype) {
2355  case HECMW_ETYPE_TET1:
2356  case HECMW_ETYPE_PTT1:
2357  return 3;
2358  case HECMW_ETYPE_TET2:
2359  case HECMW_ETYPE_PTT2:
2360  return 6;
2361  case HECMW_ETYPE_HEX1:
2362  case HECMW_ETYPE_PTQ1:
2363  return 4;
2364  case HECMW_ETYPE_HEX2:
2365  case HECMW_ETYPE_PTQ2:
2366  return 8;
2367  case HECMW_ETYPE_PRI1:
2368  if (1 <= sid && sid <= 2) return 3;
2369  if (3 <= sid && sid <= 5) return 4;
2370  case HECMW_ETYPE_PRI2:
2371  if (1 <= sid && sid <= 2) return 6;
2372  if (3 <= sid && sid <= 5) return 8;
2373  default:
2374  fprintf(
2375  stderr,
2376  "ERROR: parallel contact analysis of elem type %d not supported\n",
2377  etype);
2378  return -1;
2379  }
2380  return -1;
2381 }
2382 
2383 static const int *HECMW_fistr_get_surf_node(int etype, int sid) {
2384  HECMW_assert(0 < sid);
2385 
2386  static const int elem_surf_tet1[4][3] = {
2387  {0, 1, 2}, {0, 1, 3}, {1, 2, 3}, {2, 0, 3}};
2388  static const int elem_surf_tet2[4][6] = {{0, 6, 1, 4, 2, 5},
2389  {0, 6, 1, 8, 3, 7},
2390  {1, 4, 2, 9, 3, 8},
2391  {2, 5, 0, 9, 3, 7}};
2392  static const int elem_surf_hex1[6][4] = {{0, 1, 2, 3}, {4, 5, 6, 7},
2393  {0, 1, 5, 4}, {1, 2, 6, 5},
2394  {2, 3, 7, 6}, {3, 0, 4, 7}};
2395  static const int elem_surf_hex2[6][8] = {
2396  {0, 8, 1, 9, 2, 10, 3, 11}, {4, 12, 5, 13, 6, 14, 7, 15},
2397  {0, 8, 1, 17, 5, 12, 4, 16}, {1, 9, 2, 18, 6, 13, 5, 17},
2398  {2, 10, 3, 19, 7, 14, 6, 18}, {3, 11, 0, 16, 4, 15, 7, 19}};
2399  static const int elem_surf_pri1[5][4] = {
2400  {0, 1, 2, -1}, {3, 4, 5, -1}, {0, 1, 4, 3}, {1, 2, 5, 4}, {2, 0, 3, 5}};
2401  static const int elem_surf_pri2[5][8] = {{0, 8, 1, 6, 2, 7, -1, -1},
2402  {3, 11, 4, 9, 5, 10, -1, -1},
2403  {0, 8, 1, 13, 4, 11, 3, 12},
2404  {1, 6, 2, 14, 5, 9, 4, 13},
2405  {2, 7, 0, 12, 3, 10, 5, 14}};
2406  static const int elem_surf_ptt1[3] = {0, 1, 2};
2407  static const int elem_surf_ptt2[6] = {0, 1, 2, 3, 4, 5};
2408  static const int elem_surf_ptq1[4] = {0, 1, 2, 3};
2409  static const int elem_surf_ptq2[8] = {0, 1, 2, 3, 4, 5, 6, 7};
2410  switch (etype) {
2411  case HECMW_ETYPE_TET1:
2412  return elem_surf_tet1[sid - 1];
2413  case HECMW_ETYPE_TET2:
2414  return elem_surf_tet2[sid - 1];
2415  case HECMW_ETYPE_HEX1:
2416  return elem_surf_hex1[sid - 1];
2417  case HECMW_ETYPE_HEX2:
2418  return elem_surf_hex2[sid - 1];
2419  case HECMW_ETYPE_PRI1:
2420  return elem_surf_pri1[sid - 1];
2421  case HECMW_ETYPE_PRI2:
2422  return elem_surf_pri2[sid - 1];
2423  case HECMW_ETYPE_PTT1:
2424  return elem_surf_ptt1;
2425  case HECMW_ETYPE_PTT2:
2426  return elem_surf_ptt2;
2427  case HECMW_ETYPE_PTQ1:
2428  return elem_surf_ptq1;
2429  case HECMW_ETYPE_PTQ2:
2430  return elem_surf_ptq2;
2431  }
2432  fprintf(stderr,
2433  "ERROR: parallel contact analysis of element type %d not supported\n",
2434  etype);
2435  return NULL;
2436 }
2437 
2438 static int mark_contact_master_nodes(struct hecmwST_local_mesh *global_mesh,
2439  int *mark) {
2440  int i, j, k;
2441  struct hecmwST_contact_pair *cp = global_mesh->contact_pair;
2442  struct hecmwST_surf_grp *sgrp = global_mesh->surf_group;
2443 
2444  for (i = 0; i < global_mesh->n_node; i++) {
2445  mark[i] = 0;
2446  }
2447 
2448  for (i = 0; i < cp->n_pair; i++) {
2449  int gid = cp->master_grp_id[i];
2450  int jstart = sgrp->grp_index[gid - 1];
2451  int jend = sgrp->grp_index[gid];
2452  for (j = jstart; j < jend; j++) {
2453  int eid = sgrp->grp_item[j * 2] - 1;
2454  int sid = sgrp->grp_item[j * 2 + 1];
2455  int *nop =
2456  global_mesh->elem_node_item + global_mesh->elem_node_index[eid];
2457  int etype = global_mesh->elem_type[eid];
2458 
2460  /* int num_snode = HECMW_get_num_surf_node(etype, sid); */
2461  /* const int *snode = HECMW_get_surf_node(etype, sid); */
2463  int num_snode = HECMW_fistr_get_num_surf_node(etype, sid);
2464  const int *snode = HECMW_fistr_get_surf_node(etype, sid);
2467  if (num_snode < 0 || snode == NULL) return RTC_ERROR;
2468  for (k = 0; k < num_snode; k++) {
2469  int nid = nop[snode[k]] - 1;
2470  HECMW_assert(0 <= nid && nid < global_mesh->n_node);
2471  mark[nid] = 1;
2472  }
2473  }
2474  }
2475  return RTC_NORMAL;
2476 }
2477 
2478 static int contact_agg_mark_surf_group(int *mark,
2479  struct hecmwST_local_mesh *global_mesh,
2480  int gid, int agg_id, int *agg_dup) {
2481  struct hecmwST_surf_grp *sgrp = global_mesh->surf_group;
2482  int istart, iend, i, j;
2483 
2484  HECMW_assert(0 < gid && gid <= sgrp->n_grp);
2485 
2486  /* get all nodes in the surface and mark them!!! */
2487  istart = sgrp->grp_index[gid - 1];
2488  iend = sgrp->grp_index[gid];
2489  for (i = istart; i < iend; i++) {
2490  int eid = sgrp->grp_item[i * 2] - 1;
2491  int sid = sgrp->grp_item[i * 2 + 1];
2492  int *nop = global_mesh->elem_node_item + global_mesh->elem_node_index[eid];
2493  int etype = global_mesh->elem_type[eid];
2495  /* int num_snode = HECMW_get_num_surf_node(etype, sid); */
2496  /* const int *snode = HECMW_get_surf_node(etype, sid); */
2498  int num_snode = HECMW_fistr_get_num_surf_node(etype, sid);
2499  const int *snode = HECMW_fistr_get_surf_node(etype, sid);
2501  if (num_snode < 0 || snode == NULL) return RTC_ERROR;
2502  for (j = 0; j < num_snode; j++) {
2503  int nid = nop[snode[j]] - 1;
2504  HECMW_assert(0 <= nid && nid < global_mesh->n_node);
2505  if (0 <= mark[nid] && mark[nid] < agg_id) {
2506  /* the node is included in some other contact pair */
2507  if (*agg_dup == -1) {
2508  *agg_dup = mark[nid];
2509  } else if (mark[nid] != *agg_dup) {
2510  fprintf(stderr,
2511  "ERROR: node included in multiple surface groups in "
2512  "different contact pairs,\n"
2513  " which is not supported by CONTACT=AGGREGATE\n");
2515  }
2516  }
2517  mark[nid] = agg_id;
2518  }
2519  }
2520  return RTC_NORMAL;
2521 }
2522 
2523 static int metis_partition_nb_contact_agg(
2524  struct hecmwST_local_mesh *global_mesh,
2525  const struct hecmw_part_cont_data *cont_data,
2526  const struct hecmw_part_edge_data *edge_data) {
2527  int n_edgecut;
2528  idx_t *node_graph_index = NULL; /* index for nodal graph */
2529  idx_t *node_graph_item = NULL; /* member of nodal graph */
2530  idx_t *belong_domain = NULL;
2531  int rtc;
2532  int i;
2533  struct hecmwST_contact_pair *cp;
2534  int *mark;
2535  int agg_id, agg_dup, gid;
2536  int n_node2;
2537  const idx_t *node_graph_index2;
2538  const idx_t *node_graph_item2;
2539  idx_t *node_weight2;
2540  struct hecmw_graph graph1, graph2;
2541  const int ncon = 1;
2542 
2545 
2546  node_graph_index = (idx_t *)HECMW_calloc(global_mesh->n_node + 1, sizeof(idx_t));
2547  if (node_graph_index == NULL) {
2548  HECMW_set_error(errno, "");
2549  goto error;
2550  }
2551  node_graph_item = (idx_t *)HECMW_malloc(sizeof(idx_t) * (size_t)(edge_data->n_edge * 2));
2552  if (node_graph_item == NULL) {
2553  HECMW_set_error(errno, "");
2554  goto error;
2555  }
2556 
2557  HECMW_log(HECMW_LOG_DEBUG, "Starting creation of node graph...\n");
2558 
2559  rtc = create_node_graph(global_mesh, edge_data, node_graph_index,
2560  node_graph_item);
2561  if (rtc != RTC_NORMAL) goto error;
2562 
2563  HECMW_log(HECMW_LOG_DEBUG, "Creation of node graph done\n");
2564 
2565  HECMW_log(HECMW_LOG_DEBUG, "Partitioning mode: contact-aggregate\n");
2566 
2567  HECMW_log(HECMW_LOG_DEBUG, "Starting aggregation of contact pairs...\n");
2568 
2569  /* aggregate contact pair if requested */
2570  cp = global_mesh->contact_pair;
2571  mark = (int *)HECMW_malloc(global_mesh->n_node * sizeof(int));
2572  if (mark == NULL) {
2573  HECMW_set_error(errno, "");
2574  goto error;
2575  }
2576  for (i = 0; i < global_mesh->n_node; i++) {
2577  mark[i] = -1;
2578  }
2579  agg_id = 0;
2580  /* mark contact pairs */
2581  for (i = 0; i < cp->n_pair; i++) {
2582  agg_dup = -1;
2583  /* slave */
2584  if (cp->type[i] == HECMW_CONTACT_TYPE_NODE_SURF) {
2585  gid = cp->slave_grp_id[i];
2586  rtc =
2587  contact_agg_mark_node_group(mark, global_mesh, gid, agg_id, &agg_dup);
2588  if (rtc != RTC_NORMAL) goto error;
2589  } else if(cp->type[i] == HECMW_CONTACT_TYPE_SURF_SURF) {
2590  gid = cp->slave_grp_id[i];
2591  rtc =
2592  contact_agg_mark_surf_group(mark, global_mesh, gid, agg_id, &agg_dup);
2593  if (rtc != RTC_NORMAL) goto error;
2594  } else if(cp->type[i] == HECMW_CONTACT_TYPE_NODE_ELEM) {
2595  gid = cp->slave_grp_id[i];
2596  rtc =
2597  contact_agg_mark_surf_group(mark, global_mesh, gid, agg_id, &agg_dup);
2598  if (rtc != RTC_NORMAL) goto error;
2599  }
2600  /* master */
2601  gid = cp->master_grp_id[i];
2602  rtc = contact_agg_mark_surf_group(mark, global_mesh, gid, agg_id, &agg_dup);
2603  if (rtc != RTC_NORMAL) goto error;
2604 
2605  if (agg_dup >= 0) {
2606  for (i = 0; i < global_mesh->n_node; i++) {
2607  if (mark[i] == agg_id) {
2608  mark[i] = agg_dup;
2609  }
2610  }
2611  } else {
2612  agg_id++;
2613  }
2614  }
2615  /* mark other nodes */
2616  for (i = 0; i < global_mesh->n_node; i++) {
2617  if (mark[i] < 0) {
2618  mark[i] = agg_id++;
2619  }
2620  }
2621  n_node2 = agg_id;
2622 
2623  /* degenerate node graph */
2624  rtc = HECMW_graph_init_with_arrays(&graph1, global_mesh->n_node,
2625  node_graph_index, node_graph_item);
2626  if (rtc != RTC_NORMAL) goto error;
2627  rtc = HECMW_graph_init(&graph2);
2628  if (rtc != RTC_NORMAL) goto error;
2629  rtc = HECMW_graph_degeneGraph(&graph2, &graph1, n_node2, mark);
2630  if (rtc != RTC_NORMAL) goto error;
2631  HECMW_graph_finalize(&graph1);
2632  node_graph_index2 = HECMW_graph_getEdgeIndex(&graph2);
2633  node_graph_item2 = HECMW_graph_getEdgeItem(&graph2);
2634 
2635  node_weight2 = (idx_t *)HECMW_calloc(n_node2, sizeof(idx_t));
2636  if (node_weight2 == NULL) {
2637  HECMW_set_error(errno, "");
2638  goto error;
2639  }
2640  for (i = 0; i < global_mesh->n_node; i++) {
2641  node_weight2[mark[i]] += 1;
2642  }
2643 
2644  HECMW_log(HECMW_LOG_DEBUG, "Aggregation of contact pairs done\n");
2645 
2646  belong_domain = (idx_t *)HECMW_calloc(n_node2, sizeof(idx_t));
2647  if (belong_domain == NULL) {
2648  HECMW_set_error(errno, "");
2649  goto error;
2650  }
2651 
2652  switch (cont_data->method) {
2653  case HECMW_PART_METHOD_PMETIS: /* pMETIS */
2654  n_edgecut = pmetis_interface_with_weight(
2655  n_node2, ncon, global_mesh->n_subdomain, (idx_t *)node_graph_index2,
2656  (idx_t *)node_graph_item2, node_weight2, belong_domain);
2657  if (n_edgecut < 0) goto error;
2658  break;
2659 
2660  case HECMW_PART_METHOD_KMETIS: /* kMETIS */
2661  n_edgecut = kmetis_interface_with_weight(
2662  n_node2, ncon, global_mesh->n_subdomain, (idx_t *)node_graph_index2,
2663  (idx_t *)node_graph_item2, node_weight2, belong_domain);
2664  if (n_edgecut < 0) goto error;
2665  break;
2666 
2667  default:
2669  goto error;
2670  }
2671 
2672  for (i = 0; i < global_mesh->n_node; i++) {
2673  global_mesh->node_ID[2 * i + 1] = (int)belong_domain[mark[i]];
2674  }
2675 
2676  HECMW_graph_finalize(&graph2);
2677  HECMW_free(node_graph_index);
2678  HECMW_free(node_graph_item);
2679  HECMW_free(mark);
2680  HECMW_free(node_weight2);
2681  HECMW_free(belong_domain);
2682 
2683  return n_edgecut;
2684 
2685 error:
2686  HECMW_free(node_graph_index);
2687  HECMW_free(node_graph_item);
2688  HECMW_free(mark);
2689  HECMW_free(node_weight2);
2690  HECMW_free(belong_domain);
2691 
2692  return -1;
2693 }
2694 
2695 static int metis_partition_nb_contact_dist(
2696  struct hecmwST_local_mesh *global_mesh,
2697  const struct hecmw_part_cont_data *cont_data,
2698  const struct hecmw_part_edge_data *edge_data) {
2699  int n_edgecut;
2700  idx_t *node_graph_index = NULL; /* index for nodal graph */
2701  idx_t *node_graph_item = NULL; /* member of nodal graph */
2702  idx_t *belong_domain = NULL;
2703  int rtc;
2704  int i;
2705  int ncon;
2706  idx_t *node_weight = NULL;
2707  int *mark = NULL;
2708 
2709  HECMW_assert(
2714 
2715  node_graph_index = (idx_t *)HECMW_calloc(global_mesh->n_node + 1, sizeof(idx_t));
2716  if (node_graph_index == NULL) {
2717  HECMW_set_error(errno, "");
2718  goto error;
2719  }
2720  node_graph_item = (idx_t *)HECMW_malloc(sizeof(idx_t) * (size_t)(edge_data->n_edge * 2));
2721  if (node_graph_item == NULL) {
2722  HECMW_set_error(errno, "");
2723  goto error;
2724  }
2725 
2726  HECMW_log(HECMW_LOG_DEBUG, "Starting creation of node graph...\n");
2727 
2728  rtc = create_node_graph(global_mesh, edge_data, node_graph_index,
2729  node_graph_item);
2730  if (rtc != RTC_NORMAL) goto error;
2731 
2732  HECMW_log(HECMW_LOG_DEBUG, "Creation of node graph done\n");
2733 
2736  HECMW_log(HECMW_LOG_DEBUG, "Partitioning mode: contact-simple\n");
2737 
2738  ncon = 1;
2739  node_weight = NULL;
2740  } else /* HECMW_FLAG_PARTCONTACT_DISTRIBUTE */
2741  {
2742  HECMW_log(HECMW_LOG_DEBUG, "Partitioning mode: contact-distribute\n");
2743 
2744  ncon = 2;
2745 
2746  mark = (int *)HECMW_calloc(global_mesh->n_node, sizeof(int));
2747  if (mark == NULL) {
2748  HECMW_set_error(errno, "");
2749  goto error;
2750  }
2751 
2752  rtc = mark_contact_master_nodes(global_mesh, mark);
2753  if (rtc != RTC_NORMAL) goto error;
2754 
2755  node_weight =
2756  (idx_t *)HECMW_calloc(global_mesh->n_node * ncon, sizeof(idx_t));
2757  if (node_weight == NULL) {
2758  HECMW_set_error(errno, "");
2759  goto error;
2760  }
2761 
2762  for (i = 0; i < global_mesh->n_node; i++) {
2763  /* 1st condition: distribute nodes equally */
2764  node_weight[i * ncon] = 1;
2765  /* 2nd condition: distribute master nodes equally */
2766  node_weight[i * ncon + 1] = mark[i];
2767  }
2768 
2769  HECMW_free(mark);
2770  }
2771 
2772  belong_domain = (idx_t *)HECMW_calloc(global_mesh->n_node, sizeof(idx_t));
2773  if (belong_domain == NULL) {
2774  HECMW_set_error(errno, "");
2775  goto error;
2776  }
2777 
2778  switch (cont_data->method) {
2779  case HECMW_PART_METHOD_PMETIS: /* pMETIS */
2780  n_edgecut = pmetis_interface_with_weight(
2781  global_mesh->n_node, ncon, global_mesh->n_subdomain, node_graph_index,
2782  node_graph_item, node_weight, belong_domain);
2783  if (n_edgecut < 0) goto error;
2784  break;
2785 
2786  case HECMW_PART_METHOD_KMETIS: /* kMETIS */
2787  n_edgecut = kmetis_interface_with_weight(
2788  global_mesh->n_node, ncon, global_mesh->n_subdomain, node_graph_index,
2789  node_graph_item, node_weight, belong_domain);
2790  if (n_edgecut < 0) goto error;
2791  break;
2792 
2793  default:
2795  goto error;
2796  }
2797 
2798  for (i = 0; i < global_mesh->n_node; i++) {
2799  global_mesh->node_ID[2 * i + 1] = (int)belong_domain[i];
2800  }
2801 
2802  HECMW_free(node_graph_index);
2803  HECMW_free(node_graph_item);
2804  HECMW_free(belong_domain);
2805  if (node_weight) HECMW_free(node_weight);
2806 
2807  return n_edgecut;
2808 
2809 error:
2810  HECMW_free(node_graph_index);
2811  HECMW_free(node_graph_item);
2812  HECMW_free(belong_domain);
2813  if (node_weight) HECMW_free(node_weight);
2814  if (mark) HECMW_free(mark);
2815 
2816  return -1;
2817 }
2818 
2819 static int metis_partition_nb_default(
2820  struct hecmwST_local_mesh *global_mesh,
2821  const struct hecmw_part_cont_data *cont_data,
2822  const struct hecmw_part_edge_data *edge_data) {
2823  int n_edgecut;
2824  idx_t *node_graph_index = NULL; /* index for nodal graph */
2825  idx_t *node_graph_item = NULL; /* member of nodal graph */
2826  idx_t *belong_domain = NULL;
2827  int rtc;
2828  int i;
2829 
2830  node_graph_index = (idx_t *)HECMW_calloc(global_mesh->n_node + 1, sizeof(idx_t));
2831  if (node_graph_index == NULL) {
2832  HECMW_set_error(errno, "");
2833  goto error;
2834  }
2835  node_graph_item = (idx_t *)HECMW_malloc(sizeof(idx_t) * (size_t)(edge_data->n_edge * 2));
2836  if (node_graph_item == NULL) {
2837  HECMW_set_error(errno, "");
2838  goto error;
2839  }
2840 
2841  HECMW_log(HECMW_LOG_DEBUG, "Starting creation of node graph...\n");
2842 
2843  rtc = create_node_graph(global_mesh, edge_data, node_graph_index,
2844  node_graph_item);
2845  if (rtc != RTC_NORMAL) goto error;
2846 
2847  HECMW_log(HECMW_LOG_DEBUG, "Creation of node graph done\n");
2848 
2849  belong_domain = (idx_t *)HECMW_calloc(global_mesh->n_node, sizeof(idx_t));
2850  if (belong_domain == NULL) {
2851  HECMW_set_error(errno, "");
2852  goto error;
2853  }
2854 
2855  HECMW_log(HECMW_LOG_DEBUG, "Partitioning mode: default\n");
2856 
2857  switch (cont_data->method) {
2858  case HECMW_PART_METHOD_PMETIS: /* pMETIS */
2859  n_edgecut =
2860  pmetis_interface(global_mesh->n_node, global_mesh->n_subdomain,
2861  node_graph_index, node_graph_item, belong_domain);
2862  if (n_edgecut < 0) goto error;
2863  break;
2864 
2865  case HECMW_PART_METHOD_KMETIS: /* kMETIS */
2866  n_edgecut =
2867  kmetis_interface(global_mesh->n_node, global_mesh->n_subdomain,
2868  node_graph_index, node_graph_item, belong_domain);
2869  if (n_edgecut < 0) goto error;
2870  break;
2871 
2872  default:
2874  goto error;
2875  }
2876 
2877  for (i = 0; i < global_mesh->n_node; i++) {
2878  global_mesh->node_ID[2 * i + 1] = (int)belong_domain[i];
2879  }
2880 
2881  HECMW_free(node_graph_index);
2882  HECMW_free(node_graph_item);
2883  HECMW_free(belong_domain);
2884 
2885  return n_edgecut;
2886 
2887 error:
2888  HECMW_free(node_graph_index);
2889  HECMW_free(node_graph_item);
2890  HECMW_free(belong_domain);
2891 
2892  return -1;
2893 }
2894 
2895 static int metis_partition_nb_ndweight(
2896  struct hecmwST_local_mesh *global_mesh,
2897  const struct hecmw_part_cont_data *cont_data,
2898  const struct hecmw_part_edge_data *edge_data) {
2899 #ifdef HECMW_ARCH_FX64
2900  int n_edgecut;
2901  idx_t *node_graph_index = NULL; /* index for nodal graph */
2902  idx_t *node_graph_item = NULL; /* member of nodal graph */
2903  idx_t *belong_domain = NULL;
2904  int rtc;
2905  int i, j, node, nn;
2906  int ncon;
2907  idx_t *node_weight = NULL;
2908  int *mark = NULL;
2909 
2910  int *count = NULL; /* tmp */
2911 
2912  node_graph_index = (idx_t *)HECMW_calloc(global_mesh->n_node + 1, sizeof(idx_t));
2913  if (node_graph_index == NULL) {
2914  HECMW_set_error(errno, "");
2915  goto error;
2916  }
2917  node_graph_item = (idx_t *)HECMW_malloc(sizeof(idx_t) * (size_t)(edge_data->n_edge * 2));
2918  if (node_graph_item == NULL) {
2919  HECMW_set_error(errno, "");
2920  goto error;
2921  }
2922 
2923  HECMW_log(HECMW_LOG_DEBUG, "Starting creation of node graph...\n");
2924 
2925  rtc = create_node_graph(global_mesh, edge_data, node_graph_index,
2926  node_graph_item);
2927  if (rtc != RTC_NORMAL) goto error;
2928 
2929  HECMW_log(HECMW_LOG_DEBUG, "Creation of node graph done\n");
2930 
2931  ncon = 1;
2932  node_weight = (idx_t *)HECMW_calloc(global_mesh->n_node * ncon, sizeof(idx_t));
2933  if (node_weight == NULL) {
2934  HECMW_set_error(errno, "");
2935  goto error;
2936  }
2937 
2938  for (i = 0; i < global_mesh->n_node; i++) {
2939  node_weight[i] = 1;
2940  }
2941  for (i = 0; i < edge_data->n_edge * 2; i++) {
2942  node_weight[node_graph_item[i]] += 1;
2943  }
2944 
2945  belong_domain = (idx_t *)HECMW_calloc(global_mesh->n_node, sizeof(idx_t));
2946  if (belong_domain == NULL) {
2947  HECMW_set_error(errno, "");
2948  goto error;
2949  }
2950 
2951  switch (cont_data->method) {
2952  case HECMW_PART_METHOD_PMETIS: /* pMETIS */
2953  n_edgecut = pmetis_interface_with_weight(
2954  global_mesh->n_node, ncon, global_mesh->n_subdomain, node_graph_index,
2955  node_graph_item, node_weight, belong_domain);
2956  if (n_edgecut < 0) goto error;
2957  break;
2958 
2959  case HECMW_PART_METHOD_KMETIS: /* kMETIS */
2960  n_edgecut = kmetis_interface_with_weight(
2961  global_mesh->n_node, ncon, global_mesh->n_subdomain, node_graph_index,
2962  node_graph_item, node_weight, belong_domain);
2963  if (n_edgecut < 0) goto error;
2964  break;
2965 
2966  default:
2968  goto error;
2969  }
2970 
2971  for (i = 0; i < global_mesh->n_node; i++) {
2972  global_mesh->node_ID[2 * i + 1] = (int)belong_domain[i];
2973  }
2974 
2975  HECMW_free(node_graph_index);
2976  HECMW_free(node_graph_item);
2977  HECMW_free(belong_domain);
2978  if (node_weight) HECMW_free(node_weight);
2979 
2980  return n_edgecut;
2981 
2982 error:
2983  HECMW_free(node_graph_index);
2984  HECMW_free(node_graph_item);
2985  HECMW_free(belong_domain);
2986  if (node_weight) HECMW_free(node_weight);
2987  if (mark) HECMW_free(mark);
2988 
2989  return -1;
2990 #else
2991  return -1;
2992 #endif
2993 }
2994 
2995 static int metis_partition_nb(struct hecmwST_local_mesh *global_mesh,
2996  const struct hecmw_part_cont_data *cont_data,
2997  const struct hecmw_part_edge_data *edge_data) {
2998  if (global_mesh->contact_pair->n_pair > 0) {
2999  switch (HECMW_partcontact_get_mode(global_mesh->hecmw_flag_partcontact)) {
3001  return metis_partition_nb_contact_agg(global_mesh, cont_data,
3002  edge_data);
3003 
3006  return metis_partition_nb_contact_dist(global_mesh, cont_data,
3007  edge_data);
3008 
3009  default:
3010  return -1;
3011  }
3012  } else {
3013 #ifdef HECMW_ARCH_FX64
3014  return metis_partition_nb_ndweight(global_mesh, cont_data, edge_data);
3015 #else
3016  return metis_partition_nb_default(global_mesh, cont_data, edge_data);
3017 #endif
3018  }
3019 }
3020 
3021 static int metis_partition_eb(struct hecmwST_local_mesh *global_mesh,
3022  const struct hecmw_part_cont_data *cont_data,
3023  idx_t *elem_graph_index, idx_t *elem_graph_item) {
3024  int n_edgecut;
3025  idx_t *belong_domain = NULL;
3026  int i;
3027 
3028  belong_domain = (idx_t *)HECMW_calloc(global_mesh->n_elem, sizeof(idx_t));
3029  if (belong_domain == NULL) {
3030  HECMW_set_error(errno, "");
3031  goto error;
3032  }
3033 
3034  switch (cont_data->method) {
3035  case HECMW_PART_METHOD_PMETIS: /* pMETIS */
3036  n_edgecut =
3037  pmetis_interface(global_mesh->n_elem, global_mesh->n_subdomain,
3038  elem_graph_index, elem_graph_item, belong_domain);
3039  if (n_edgecut < 0) goto error;
3040  break;
3041 
3042  case HECMW_PART_METHOD_KMETIS: /* kMETIS */
3043  n_edgecut =
3044  kmetis_interface(global_mesh->n_elem, global_mesh->n_subdomain,
3045  elem_graph_index, elem_graph_item, belong_domain);
3046  if (n_edgecut < 0) goto error;
3047  break;
3048 
3049  default:
3051  goto error;
3052  }
3053 
3054  for (i = 0; i < global_mesh->n_elem; i++) {
3055  global_mesh->elem_ID[2 * i + 1] = (int)belong_domain[i];
3056  }
3057 
3058  HECMW_free(belong_domain);
3059 
3060  return n_edgecut;
3061 
3062 error:
3063  HECMW_free(belong_domain);
3064 
3065  return -1;
3066 }
3067 
3068 /*------------------------------------------------------------------------------------------------*/
3069 
3070 #define LINEBUF_SIZE 1023
3071 
3072 static int read_part_file(
3073  const char *part_file_name,
3074  int n,
3075  int n_domain,
3076  int *wnum) {
3077  FILE *fpart;
3078  char linebuf[LINEBUF_SIZE + 1];
3079  int rtc, n_in, n_domain_in;
3080  int i, part;
3081  int *count_dom;
3082 
3083  fpart = fopen(part_file_name, "r");
3084  if (fpart == NULL) {
3085  HECMW_set_error(HECMW_PART_E_NO_SUCH_FILE, "%s", part_file_name);
3086  goto error;
3087  }
3088 
3089  /* read n and n_domain */
3090  if (fgets(linebuf, LINEBUF_SIZE, fpart) == NULL) {
3091  HECMW_set_error(HECMW_PART_E_PART_EOF, "read_part_file");
3092  goto error;
3093  }
3094  rtc = sscanf(linebuf, "%d %d", &n_in, &n_domain_in);
3095  if (rtc != 2) {
3097  goto error;
3098  }
3099 
3100  if (n_in != n) {
3102  goto error;
3103  }
3104  if (n_domain_in != n_domain) {
3106  goto error;
3107  }
3108 
3109  count_dom = (int *) HECMW_calloc(n_domain, sizeof(int));
3110  if (count_dom == NULL) {
3111  HECMW_set_error(errno, "");
3112  goto error;
3113  }
3114 
3115  /* read part array and count members in each domain */
3116  for (i = 0; i < n; i++) {
3117  if (fgets(linebuf, LINEBUF_SIZE, fpart) == NULL) {
3119  goto error;
3120  }
3121  rtc = sscanf(linebuf, "%d", &part);
3122  if (rtc != 1) {
3124  goto error;
3125  }
3126 
3127  if (part < 0 || n_domain <= part) {
3129  goto error;
3130  }
3131 
3132  count_dom[part]++;
3133 
3134  wnum[2*i+1] = part;
3135  }
3136 
3137  /* check for empty domain */
3138  for (i = 0; i < n_domain; i++) {
3139  if (count_dom[i] == 0) {
3141  goto error;
3142  }
3143  }
3144 
3145  fclose(fpart);
3146 
3147  return RTC_NORMAL;
3148 
3149 error:
3150  return RTC_ERROR;
3151 }
3152 
3153 static int write_part_file(
3154  const char *part_file_name,
3155  int n,
3156  int n_domain,
3157  const int *wnum) {
3158  FILE *fpart;
3159  int i;
3160 
3161  fpart = fopen(part_file_name, "w");
3162  if (fpart == NULL) {
3163  HECMW_set_error(HECMW_PART_E_NO_SUCH_FILE, "%s", part_file_name);
3164  goto error;
3165  }
3166 
3167  fprintf(fpart, "%d %d\n", n, n_domain);
3168 
3169  for (i = 0; i < n; i++) {
3170  fprintf(fpart, "%d\n", wnum[2*i+1]);
3171  }
3172 
3173  fclose(fpart);
3174 
3175  return RTC_NORMAL;
3176 
3177 error:
3178  return RTC_ERROR;
3179 }
3180 
3181 /*------------------------------------------------------------------------------------------------*/
3182 
3183 static int user_partition(
3184  int n,
3185  int n_domain,
3186  int *wnum,
3187  const char *part_file_name) {
3188  int rtc;
3189 
3190  rtc = read_part_file(part_file_name, n, n_domain, wnum);
3191  if (rtc != RTC_NORMAL) goto error;
3192 
3193  return RTC_NORMAL;
3194 
3195 error:
3196  return RTC_ERROR;
3197 }
3198 
3199 static int user_partition_nb(
3200  struct hecmwST_local_mesh *global_mesh,
3201  const struct hecmw_part_cont_data *cont_data) {
3202  return user_partition(global_mesh->n_node, global_mesh->n_subdomain,
3203  global_mesh->node_ID, cont_data->part_file_name);
3204 }
3205 
3206 static int user_partition_eb(
3207  struct hecmwST_local_mesh *global_mesh,
3208  const struct hecmw_part_cont_data *cont_data) {
3209  return user_partition(global_mesh->n_elem, global_mesh->n_subdomain,
3210  global_mesh->elem_ID, cont_data->part_file_name);
3211 }
3212 
3213 /*------------------------------------------------------------------------------------------------*/
3214 
3215 static int print_part(
3216  struct hecmwST_local_mesh *global_mesh,
3217  const char *part_file_name) {
3218  int rtc;
3219 
3220  switch (global_mesh->hecmw_flag_parttype) {
3222  rtc = write_part_file(part_file_name, global_mesh->n_node,
3223  global_mesh->n_subdomain, global_mesh->node_ID);
3224  if (rtc != RTC_NORMAL) goto error;
3225 
3226  break;
3227 
3229  rtc = write_part_file(part_file_name, global_mesh->n_elem,
3230  global_mesh->n_subdomain, global_mesh->elem_ID);
3231  if (rtc != RTC_NORMAL) goto error;
3232 
3233  break;
3234 
3235  default:
3237  goto error;
3238  }
3239 
3240  return RTC_NORMAL;
3241 
3242 error:
3243  return RTC_ERROR;
3244 }
3245 
3246 /*------------------------------------------------------------------------------------------------*/
3247 
3248 static int count_edgecut(
3249  const struct hecmw_part_edge_data *edge_data,
3250  const int *wnum) {
3251  int i;
3252  int n_edgecut = 0;
3253 
3254  for (i = 0; i < edge_data->n_edge; i++) {
3255  if (wnum[2 * (edge_data->edge_node_item[2 * i] - 1) + 1] !=
3256  wnum[2 * (edge_data->edge_node_item[2 * i + 1] - 1) + 1]) {
3257  n_edgecut++;
3258  }
3259  }
3260 
3261  return n_edgecut;
3262 }
3263 
3264 /*------------------------------------------------------------------------------------------------*/
3265 
3266 static int set_node_belong_domain_nb(
3267  struct hecmwST_local_mesh *global_mesh,
3268  const struct hecmw_part_cont_data *cont_data) {
3269  struct hecmw_part_edge_data *edge_data = NULL;
3270  int n_edgecut;
3271  int rtc;
3272 
3273  edge_data = (struct hecmw_part_edge_data *)HECMW_malloc(
3274  sizeof(struct hecmw_part_edge_data));
3275  if (edge_data == NULL) {
3276  HECMW_set_error(errno, "");
3277  goto error;
3278  } else {
3279  edge_data->n_edge = 0;
3280  edge_data->edge_node_item = NULL;
3281  }
3282 
3283  HECMW_log(HECMW_LOG_DEBUG, "Starting creation of mesh edge info...\n");
3284 
3285 #ifdef HECMW_ARCH_FX64
3286  rtc = HECMW_mesh_edge_info(global_mesh, edge_data, 1);
3287 #else
3288  rtc = HECMW_mesh_edge_info(global_mesh, edge_data);
3289 #endif
3290  if (rtc != 0) goto error;
3291 
3292  HECMW_log(HECMW_LOG_DEBUG, "Creation of mesh edge info done\n");
3293 
3294  switch (cont_data->method) {
3295  case HECMW_PART_METHOD_RCB: /* RCB */
3296  rtc = rcb_partition(global_mesh->n_node, global_mesh->node,
3297  global_mesh->node_ID, cont_data);
3298  if (rtc != RTC_NORMAL) goto error;
3299 
3300  n_edgecut = count_edgecut(edge_data, global_mesh->node_ID);
3301 
3302  break;
3303 
3304  case HECMW_PART_METHOD_KMETIS: /* kMETIS */
3305  case HECMW_PART_METHOD_PMETIS: /* pMETIS */
3306  n_edgecut = metis_partition_nb(global_mesh, cont_data, edge_data);
3307  if (n_edgecut < 0) goto error;
3308 
3309  break;
3310 
3311  case HECMW_PART_METHOD_USER: /* USER */
3312  rtc = user_partition_nb(global_mesh, cont_data);
3313  if (rtc != RTC_NORMAL) goto error;
3314 
3315  n_edgecut = count_edgecut(edge_data, global_mesh->node_ID);
3316 
3317  break;
3318 
3319  default:
3321  goto error;
3322  }
3323 
3324  rtc = HECMW_part_set_log_n_edgecut(edge_data->n_edge, n_edgecut);
3325  if (rtc != RTC_NORMAL) goto error;
3326 
3327  /* commented out by K.Goto; begin */
3328  /* rtc = eqn_block( global_mesh ); */
3329  /* if( rtc != RTC_NORMAL ) goto error; */
3330  /* commented out by K.Goto; end */
3331 
3332  HECMW_free(edge_data->edge_node_item);
3333  HECMW_free(edge_data);
3334 
3335  return RTC_NORMAL;
3336 
3337 error:
3338  if (edge_data) {
3339  HECMW_free(edge_data->edge_node_item);
3340  }
3341  HECMW_free(edge_data);
3342 
3343  return RTC_ERROR;
3344 }
3345 
3346 static int set_node_belong_domain_eb(struct hecmwST_local_mesh *global_mesh) {
3347  int node;
3348  int i;
3349  long long j;
3350 
3351  for (i = 0; i < global_mesh->n_node; i++) {
3352  global_mesh->node_ID[2 * i + 1] = global_mesh->n_subdomain;
3353  }
3354 
3355  for (i = 0; i < global_mesh->n_elem; i++) {
3356  for (j = global_mesh->elem_node_index[i];
3357  j < global_mesh->elem_node_index[i + 1]; j++) {
3358  node = global_mesh->elem_node_item[j];
3359  if (global_mesh->elem_ID[2 * i + 1] <
3360  global_mesh->node_ID[2 * (node - 1) + 1]) {
3361  global_mesh->node_ID[2 * (node - 1) + 1] =
3362  global_mesh->elem_ID[2 * i + 1];
3363  }
3364  }
3365  }
3366 
3367  return RTC_NORMAL;
3368 }
3369 
3370 static int set_local_node_id(struct hecmwST_local_mesh *global_mesh) {
3371  int *counter;
3372  int j, domain;
3373 
3374  counter = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
3375  if (counter == NULL) {
3376  HECMW_set_error(errno, "");
3377  goto error;
3378  }
3379 
3380  for (j = 0; j < global_mesh->n_node; j++) {
3381  domain = global_mesh->node_ID[2 * j + 1];
3382  global_mesh->node_ID[2 * j] = ++counter[domain];
3383  }
3384 
3385  HECMW_free(counter);
3386 
3387  return RTC_NORMAL;
3388 
3389 error:
3390  return RTC_ERROR;
3391 }
3392 
3393 static int wnumbering_node(struct hecmwST_local_mesh *global_mesh,
3394  const struct hecmw_part_cont_data *cont_data) {
3395  int rtc;
3396  int i;
3397 
3398  HECMW_free(global_mesh->node_ID);
3399  global_mesh->node_ID =
3400  (int *)HECMW_malloc(sizeof(int) * (size_t)global_mesh->n_node * 2);
3401  if (global_mesh->node_ID == NULL) {
3402  HECMW_set_error(errno, "");
3403  goto error;
3404  } else {
3405  for (i = 0; i < global_mesh->n_node; i++) {
3406  global_mesh->node_ID[2 * i] = i + 1;
3407  global_mesh->node_ID[2 * i + 1] = 0;
3408  }
3409  }
3410 
3411  if (global_mesh->n_subdomain == 1) return RTC_NORMAL;
3412 
3413  switch (global_mesh->hecmw_flag_parttype) {
3414  case HECMW_FLAG_PARTTYPE_NODEBASED: /* for node-based partitioning */
3415  rtc = set_node_belong_domain_nb(global_mesh, cont_data);
3416  if (rtc != RTC_NORMAL) goto error;
3417  break;
3418 
3419  case HECMW_FLAG_PARTTYPE_ELEMBASED: /* for element-based partitioning */
3420  rtc = set_node_belong_domain_eb(global_mesh);
3421  if (rtc != RTC_NORMAL) goto error;
3422  break;
3423 
3424  default:
3426  goto error;
3427  }
3428 
3429  rtc = set_local_node_id(global_mesh);
3430  if (rtc != RTC_NORMAL) goto error;
3431 
3432  return RTC_NORMAL;
3433 
3434 error:
3435  return RTC_ERROR;
3436 }
3437 
3438 /*------------------------------------------------------------------------------------------------*/
3439 
3440 static int set_elem_belong_domain_nb(struct hecmwST_local_mesh *global_mesh) {
3441  int node, node_domain, min_domain;
3442  int i;
3443  long long j;
3444 
3445  for (i = 0; i < global_mesh->n_elem; i++) {
3446  min_domain = global_mesh->n_subdomain;
3447  for (j = global_mesh->elem_node_index[i];
3448  j < global_mesh->elem_node_index[i + 1]; j++) {
3449  node = global_mesh->elem_node_item[j];
3450  node_domain = global_mesh->node_ID[2 * (node - 1) + 1];
3451  if (node_domain < min_domain) {
3452  min_domain = node_domain;
3453  }
3454  }
3455  global_mesh->elem_ID[2 * i + 1] = min_domain;
3456  }
3457 
3458  return RTC_NORMAL;
3459 }
3460 
3461 static int count_edge_for_eb(const struct hecmwST_local_mesh *global_mesh,
3462  struct hecmw_part_edge_data *elem_data,
3463  idx_t *elem_graph_index, idx_t *elem_graph_item) {
3464  int rtc;
3465  long long int eid;
3466  int i;
3467  idx_t j;
3468 
3469  rtc = HECMW_mesh_hsort_edge_init(global_mesh->n_node, global_mesh->n_elem);
3470  if (rtc != RTC_NORMAL) goto error;
3471 
3472  for (i = 0; i < global_mesh->n_elem; i++) {
3473  for (j = elem_graph_index[i]; j < elem_graph_index[i + 1]; j++) {
3474  eid = HECMW_mesh_hsort_edge(i + 1, elem_graph_item[j] + 1);
3475  if (eid < 0) goto error;
3476  }
3477  }
3478 
3479  elem_data->n_edge = HECMW_mesh_hsort_edge_get_n();
3480  if (elem_data->n_edge < 0) goto error;
3481 
3483  if (elem_data->edge_node_item == NULL) goto error;
3484 
3486 
3487  return RTC_NORMAL;
3488 
3489 error:
3491 
3492  return RTC_ERROR;
3493 }
3494 
3495 static int set_elem_belong_domain_eb(
3496  struct hecmwST_local_mesh *global_mesh,
3497  const struct hecmw_part_cont_data *cont_data) {
3498  int n_edgecut = 0;
3499  idx_t *elem_graph_index = NULL;
3500  idx_t *elem_graph_item = NULL;
3501  struct hecmw_part_edge_data *elem_data = NULL;
3502  int rtc;
3503 
3504  elem_graph_index =
3505  (idx_t *)HECMW_calloc(global_mesh->n_elem + 1, sizeof(idx_t));
3506  if (elem_graph_index == NULL) {
3507  HECMW_set_error(errno, "");
3508  goto error;
3509  }
3510  elem_data = (struct hecmw_part_edge_data *)HECMW_malloc(
3511  sizeof(struct hecmw_part_edge_data));
3512  if (elem_data == NULL) {
3513  HECMW_set_error(errno, "");
3514  goto error;
3515  } else {
3516  elem_data->n_edge = 0;
3517  elem_data->edge_node_item = NULL;
3518  }
3519 
3520  HECMW_log(HECMW_LOG_DEBUG, "Starting creation of elem graph...\n");
3521 
3522  elem_graph_item = create_elem_graph(global_mesh, elem_graph_index);
3523  if (elem_graph_item == NULL) goto error;
3524 
3525  HECMW_log(HECMW_LOG_DEBUG, "Creation of elem graph done\n");
3526 
3527  rtc = count_edge_for_eb(global_mesh, elem_data, elem_graph_index,
3528  elem_graph_item);
3529  if (rtc != RTC_NORMAL) goto error;
3530 
3531  switch (cont_data->method) {
3532  case HECMW_PART_METHOD_RCB: /* RCB */
3533  rtc = rcb_partition_eb(global_mesh, cont_data);
3534  if (rtc != RTC_NORMAL) goto error;
3535 
3536  n_edgecut = count_edgecut(elem_data, global_mesh->elem_ID);
3537 
3538  break;
3539 
3540  case HECMW_PART_METHOD_PMETIS: /* pMETIS */
3541  case HECMW_PART_METHOD_KMETIS: /* kMETIS */
3542  n_edgecut = metis_partition_eb(global_mesh, cont_data, elem_graph_index,
3543  elem_graph_item);
3544  if (n_edgecut < 0) goto error;
3545 
3546  break;
3547 
3548  case HECMW_PART_METHOD_USER: /* USER */
3549  rtc = user_partition_eb(global_mesh, cont_data);
3550  if (rtc != RTC_NORMAL) goto error;
3551 
3552  n_edgecut = count_edgecut(elem_data, global_mesh->elem_ID);
3553 
3554  break;
3555 
3556  default:
3558  goto error;
3559  }
3560 
3561  rtc = HECMW_part_set_log_n_edgecut(elem_data->n_edge, n_edgecut);
3562  if (rtc != RTC_NORMAL) goto error;
3563 
3564  HECMW_free(elem_graph_index);
3565  HECMW_free(elem_graph_item);
3566  HECMW_free(elem_data->edge_node_item);
3567  HECMW_free(elem_data);
3568 
3569  return RTC_NORMAL;
3570 
3571 error:
3572  HECMW_free(elem_graph_index);
3573  HECMW_free(elem_graph_item);
3574  if (elem_data) {
3575  HECMW_free(elem_data->edge_node_item);
3576  }
3577  HECMW_free(elem_data);
3578 
3579  return RTC_ERROR;
3580 }
3581 
3582 static int set_local_elem_id(struct hecmwST_local_mesh *global_mesh) {
3583  int *counter;
3584  int j, domain;
3585 
3586  counter = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
3587  if (counter == NULL) {
3588  HECMW_set_error(errno, "");
3589  goto error;
3590  }
3591 
3592  for (j = 0; j < global_mesh->n_elem; j++) {
3593  domain = global_mesh->elem_ID[2 * j + 1];
3594  global_mesh->elem_ID[2 * j] = ++counter[domain];
3595  }
3596 
3597  HECMW_free(counter);
3598 
3599  return RTC_NORMAL;
3600 
3601 error:
3602  return RTC_ERROR;
3603 }
3604 
3605 static int wnumbering_elem(struct hecmwST_local_mesh *global_mesh,
3606  const struct hecmw_part_cont_data *cont_data) {
3607  int rtc;
3608  int i;
3609 
3610  HECMW_free(global_mesh->elem_ID);
3611  global_mesh->elem_ID =
3612  (int *)HECMW_malloc(sizeof(int) * (size_t)global_mesh->n_elem * 2);
3613  if (global_mesh->elem_ID == NULL) {
3614  HECMW_set_error(errno, "");
3615  goto error;
3616  } else {
3617  for (i = 0; i < global_mesh->n_elem; i++) {
3618  global_mesh->elem_ID[2 * i] = i + 1;
3619  global_mesh->elem_ID[2 * i + 1] = 0;
3620  }
3621  }
3622 
3623  if (global_mesh->n_subdomain == 1) return RTC_NORMAL;
3624 
3625  switch (global_mesh->hecmw_flag_parttype) {
3626  case HECMW_FLAG_PARTTYPE_NODEBASED: /* for node-based partitioning */
3627  rtc = set_elem_belong_domain_nb(global_mesh);
3628  if (rtc != RTC_NORMAL) goto error;
3629 
3630  break;
3631 
3632  case HECMW_FLAG_PARTTYPE_ELEMBASED: /* for element-based partitioning */
3633  rtc = set_elem_belong_domain_eb(global_mesh, cont_data);
3634  if (rtc != RTC_NORMAL) goto error;
3635 
3636  break;
3637 
3638  default:
3640  goto error;
3641  }
3642 
3643  rtc = set_local_elem_id(global_mesh);
3644  if (rtc != RTC_NORMAL) goto error;
3645 
3646  return RTC_NORMAL;
3647 
3648 error:
3649  return RTC_ERROR;
3650 }
3651 
3652 static int wnumbering(struct hecmwST_local_mesh *global_mesh,
3653  const struct hecmw_part_cont_data *cont_data) {
3654  int rtc;
3655 
3656  HECMW_assert(global_mesh);
3658 
3659  HECMW_log(HECMW_LOG_DEBUG, "Starting double numbering...");
3660 
3661  switch (global_mesh->hecmw_flag_parttype) {
3662  case HECMW_FLAG_PARTTYPE_NODEBASED: /* for node-based partitioning */
3663  rtc = wnumbering_node(global_mesh, cont_data);
3664  if (rtc != RTC_NORMAL) goto error;
3665 
3666  rtc = wnumbering_elem(global_mesh, cont_data);
3667  if (rtc != RTC_NORMAL) goto error;
3668 
3669  break;
3670 
3671  case HECMW_FLAG_PARTTYPE_ELEMBASED: /* for element-based partitioning */
3672 
3673  rtc = wnumbering_elem(global_mesh, cont_data);
3674  if (rtc != RTC_NORMAL) goto error;
3675 
3676  rtc = wnumbering_node(global_mesh, cont_data);
3677  if (rtc != RTC_NORMAL) goto error;
3678 
3679  break;
3680 
3681  default:
3683  goto error;
3684  }
3685 
3686  HECMW_log(HECMW_LOG_DEBUG, "Double numbering done");
3687 
3688  return RTC_NORMAL;
3689 
3690 error:
3691  return RTC_ERROR;
3692 }
3693 
3694 /*==================================================================================================
3695 
3696 
3697  create neighboring domain & communication information
3698 
3699 
3700 ==================================================================================================*/
3701 
3702 static int mask_node_by_domain(const struct hecmwST_local_mesh *global_mesh,
3703  char *node_flag, int current_domain) {
3704  int i, node;
3705 
3706  for (i = 0; i < n_int_nlist[current_domain]; i++) {
3707  node = int_nlist[current_domain][i];
3708  MASK_BIT(node_flag[node - 1], INTERNAL);
3709  }
3710 
3711  return RTC_NORMAL;
3712 }
3713 
3714 static int mask_elem_by_domain(const struct hecmwST_local_mesh *global_mesh,
3715  char *elem_flag, int current_domain) {
3716  int i;
3717 
3718  for (i = 0; i < global_mesh->n_elem; i++) {
3719  (global_mesh->elem_ID[2 * i + 1] == current_domain)
3720  ? MASK_BIT(elem_flag[i], INTERNAL)
3721  : MASK_BIT(elem_flag[i], EXTERNAL);
3722  }
3723 
3724  return RTC_NORMAL;
3725 }
3726 
3727 static int mask_elem_by_domain_mod(char *elem_flag, int current_domain) {
3728  int i, elem;
3729 
3730  for (i = 0; i < n_int_elist[current_domain]; i++) {
3731  elem = int_elist[current_domain][i];
3732  MASK_BIT(elem_flag[elem - 1], INTERNAL);
3733  }
3734 
3735  return RTC_NORMAL;
3736 }
3737 
3738 #if 0
3739 /* For Additional overlap for explicit DOF elimination for MPC */
3740 /* NO LONGER NEEDED because node-migration implemented */
3741 static int mask_slave_node(const struct hecmwST_local_mesh *global_mesh,
3742  char *node_flag, int current_domain) {
3743  int i;
3744 
3745  for (i = 0; i < global_mesh->mpc->n_mpc; i++) {
3746  int j0, je, slave, master, j, evalsum;
3747  j0 = global_mesh->mpc->mpc_index[i];
3748  je = global_mesh->mpc->mpc_index[i + 1];
3749  slave = global_mesh->mpc->mpc_item[j0];
3750 
3751  /* mask all slave nodes */
3752  MASK_BIT(node_flag[slave - 1], MASK);
3753 
3754  /* mark slave nodes that have mpc-link across the boundary */
3755  evalsum = 0;
3756  for (j = j0 + 1; j < je; j++) {
3757  master = global_mesh->mpc->mpc_item[j];
3758  if (EVAL_BIT(node_flag[slave - 1], INTERNAL) ^ /* exclusive or */
3759  EVAL_BIT(node_flag[master - 1], INTERNAL)) {
3760  evalsum++;
3761  }
3762  }
3763  if (evalsum) {
3764  MASK_BIT(node_flag[slave - 1], MARK);
3765  }
3766  }
3767  return RTC_NORMAL;
3768 }
3769 #endif
3770 
3771 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3772  * - - - - - - - - - */
3773 
3774 static int mask_overlap_elem(char *elem_flag, int domain) {
3775  int i, elem;
3776 
3777  for (i = 0; i < n_bnd_elist[2 * domain + 1]; i++) {
3778  elem = bnd_elist[domain][i];
3779  MASK_BIT(elem_flag[elem - 1], OVERLAP);
3780  MASK_BIT(elem_flag[elem - 1], BOUNDARY);
3781  }
3782 
3783  return RTC_NORMAL;
3784 }
3785 
3786 static int mask_boundary_node(const struct hecmwST_local_mesh *global_mesh,
3787  char *node_flag, const char *elem_flag) {
3788  int node;
3789  int i;
3790  long long j;
3791 
3792  for (i = 0; i < global_mesh->n_elem; i++) {
3793  if (EVAL_BIT(elem_flag[i], BOUNDARY)) {
3794  for (j = global_mesh->elem_node_index[i];
3795  j < global_mesh->elem_node_index[i + 1]; j++) {
3796  node = global_mesh->elem_node_item[j];
3797  MASK_BIT(node_flag[node - 1], OVERLAP);
3798  MASK_BIT(node_flag[node - 1], BOUNDARY);
3799  }
3800  }
3801  }
3802 
3803  return RTC_NORMAL;
3804 }
3805 
3806 static int mask_boundary_node_mod(const struct hecmwST_local_mesh *global_mesh,
3807  char *node_flag, char *elem_flag,
3808  int domain) {
3809  int i, node;
3810 
3811  for (i = 0; i < n_bnd_nlist[2 * domain + 1]; i++) {
3812  node = bnd_nlist[domain][i];
3813  MASK_BIT(node_flag[node - 1], OVERLAP);
3814  MASK_BIT(node_flag[node - 1], BOUNDARY);
3815  }
3816 
3817  return RTC_NORMAL;
3818 }
3819 
3820 #if 0
3821 /* For Additional overlap for explicit DOF elimination for MPC */
3822 /* NO LONGER NEEDED because node-migration implemented */
3823 static int mask_boundary_elem_with_slave(
3824  const struct hecmwST_local_mesh *global_mesh, const char *node_flag,
3825  char *elem_flag, int *added) {
3826  int node, evalsum;
3827  int i, j;
3828 
3829  *added = 0;
3830 
3831  for (i = 0; i < global_mesh->n_elem; i++) {
3832  if (EVAL_BIT(elem_flag[i], BOUNDARY)) continue;
3833  if (HECMW_is_etype_link(global_mesh->elem_type[i]))
3834  continue; /* skip link elements */
3835 
3836  evalsum = 0;
3837  for (j = global_mesh->elem_node_index[i];
3838  j < global_mesh->elem_node_index[i + 1]; j++) {
3839  node = global_mesh->elem_node_item[j];
3840  /* check if the node is on boundary and a slave having mpc-link across the
3841  * boundary */
3842  if (EVAL_BIT(node_flag[node - 1], BOUNDARY) &&
3843  EVAL_BIT(node_flag[node - 1], MASK) &&
3844  EVAL_BIT(node_flag[node - 1], MARK)) {
3845  evalsum++;
3846  }
3847  }
3848 
3849  if (evalsum) {
3850  MASK_BIT(elem_flag[i], OVERLAP);
3851  MASK_BIT(elem_flag[i], BOUNDARY);
3852  (*added)++;
3853  }
3854  }
3855 
3856  return RTC_NORMAL;
3857 }
3858 
3859 static int mask_boundary_link_elem_with_slave(
3860  const struct hecmwST_local_mesh *global_mesh, const char *node_flag,
3861  char *elem_flag, int *added) {
3862  int node, evalsum;
3863  int i, j;
3864 
3865  *added = 0;
3866 
3867  for (i = 0; i < global_mesh->n_elem; i++) {
3868  if (EVAL_BIT(elem_flag[i], BOUNDARY)) continue;
3869  if (!HECMW_is_etype_link(global_mesh->elem_type[i]))
3870  continue; /* check only link elements */
3871 
3872  evalsum = 0;
3873  for (j = global_mesh->elem_node_index[i];
3874  j < global_mesh->elem_node_index[i + 1]; j++) {
3875  node = global_mesh->elem_node_item[j];
3876  /* check if the node is on boundary and a slave */
3877  if (EVAL_BIT(node_flag[node - 1], BOUNDARY) &&
3878  EVAL_BIT(node_flag[node - 1], MASK)) {
3879  evalsum++;
3880  }
3881  }
3882 
3883  if (evalsum) {
3884  MASK_BIT(elem_flag[i], OVERLAP);
3885  MASK_BIT(elem_flag[i], BOUNDARY);
3886  (*added)++;
3887  }
3888  }
3889 
3890  return RTC_NORMAL;
3891 }
3892 #endif
3893 
3894 static int mask_additional_overlap_elem(
3895  const struct hecmwST_local_mesh *global_mesh, const char *node_flag,
3896  char *elem_flag) {
3897  int node, evalsum;
3898  int i;
3899  long long j;
3900 
3901  for (i = 0; i < global_mesh->n_elem; i++) {
3902  evalsum = 0;
3903  for (j = global_mesh->elem_node_index[i];
3904  j < global_mesh->elem_node_index[i + 1]; j++) {
3905  node = global_mesh->elem_node_item[j];
3906  evalsum += (EVAL_BIT(node_flag[node - 1], BOUNDARY));
3907  }
3908 
3909  if (evalsum) {
3910  MASK_BIT(elem_flag[i], OVERLAP);
3911  MASK_BIT(elem_flag[i], BOUNDARY);
3912  }
3913  }
3914 
3915  return RTC_NORMAL;
3916 }
3917 
3918 static int mask_contact_replicate_slave_to_master_owner(
3919  const struct hecmwST_local_mesh *global_mesh, char *elem_flag,
3920  char *node_flag) {
3921  int i, j;
3922  long long k;
3923  int elem, node, selem;
3924  int evalsum, evalsum2;
3925  int master_gid, slave_gid;
3926  int jstart, jend;
3927  struct hecmwST_contact_pair *cp;
3928  struct hecmwST_surf_grp *sgrp;
3929  struct hecmwST_node_grp *ngrp;
3930  struct hecmwST_elem_grp *egrp;
3931 
3932  cp = global_mesh->contact_pair;
3933  sgrp = global_mesh->surf_group;
3934  ngrp = global_mesh->node_group;
3935  egrp = global_mesh->elem_group;
3936 
3937  for (i = 0; i < cp->n_pair; i++) {
3938  switch (cp->type[i]) {
3940  /* if any elem of master surf is internal */
3941  evalsum = 0;
3942  master_gid = cp->master_grp_id[i];
3943  jstart = sgrp->grp_index[master_gid - 1];
3944  jend = sgrp->grp_index[master_gid];
3945  for (j = jstart; j < jend; j++) {
3946  elem = sgrp->grp_item[j * 2];
3947  if (EVAL_BIT(elem_flag[elem - 1], INTERNAL)) {
3948  evalsum++;
3949  break;
3950  }
3951  }
3952  if (evalsum) {
3953  /* mask all external slave nodes as BOUNDARY (but not OVERLAP) */
3954  slave_gid = cp->slave_grp_id[i];
3955  jstart = ngrp->grp_index[slave_gid - 1];
3956  jend = ngrp->grp_index[slave_gid];
3957  for (j = jstart; j < jend; j++) {
3958  node = ngrp->grp_item[j];
3959  if (!EVAL_BIT(node_flag[node - 1], INTERNAL)) {
3960  MASK_BIT(node_flag[node - 1], BOUNDARY);
3961  }
3962  }
3963  }
3964  /* if any elem of master surf is external */
3965  evalsum = 0;
3966  master_gid = cp->master_grp_id[i];
3967  jstart = sgrp->grp_index[master_gid - 1];
3968  jend = sgrp->grp_index[master_gid];
3969  for (j = jstart; j < jend; j++) {
3970  elem = sgrp->grp_item[j * 2];
3971  if (!EVAL_BIT(elem_flag[elem - 1], INTERNAL)) {
3972  evalsum++;
3973  break;
3974  }
3975  }
3976  if (evalsum) {
3977  /* mask all internal slave nodes as BOUNDARY (but not OVERLAP) */
3978  slave_gid = cp->slave_grp_id[i];
3979  jstart = ngrp->grp_index[slave_gid - 1];
3980  jend = ngrp->grp_index[slave_gid];
3981  for (j = jstart; j < jend; j++) {
3982  node = ngrp->grp_item[j];
3983  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
3984  MASK_BIT(node_flag[node - 1], BOUNDARY);
3985  }
3986  }
3987  }
3988  break;
3989 
3991  /* if any elem of master surf is internal or boundary */
3992  evalsum = 0;
3993  master_gid = cp->master_grp_id[i];
3994  jstart = sgrp->grp_index[master_gid - 1];
3995  jend = sgrp->grp_index[master_gid];
3996  for (j = jstart; j < jend; j++) {
3997  elem = sgrp->grp_item[j * 2];
3998  if (EVAL_BIT(elem_flag[elem - 1], INTERNAL)
3999  || EVAL_BIT(elem_flag[elem - 1], BOUNDARY)) {
4000  evalsum++;
4001  break;
4002  }
4003  }
4004  if (evalsum) {
4005  /* mask all external slave elems/nodes as BOUNDARY (but not OVERLAP) */
4006  slave_gid = cp->slave_grp_id[i];
4007  jstart = sgrp->grp_index[slave_gid - 1];
4008  jend = sgrp->grp_index[slave_gid];
4009  for (j = jstart; j < jend; j++) {
4010  selem = sgrp->grp_item[j * 2];
4011  if (!EVAL_BIT(elem_flag[selem - 1], INTERNAL)) {
4012  MASK_BIT(elem_flag[selem - 1], BOUNDARY);
4013  for (k = global_mesh->elem_node_index[selem - 1];
4014  k < global_mesh->elem_node_index[selem]; k++) {
4015  node = global_mesh->elem_node_item[k];
4016  MASK_BIT(node_flag[node - 1], BOUNDARY);
4017  }
4018  }
4019  }
4020  }
4021  /* if any elem of master surf is external or boundary */
4022  evalsum = 0;
4023  master_gid = cp->master_grp_id[i];
4024  jstart = sgrp->grp_index[master_gid - 1];
4025  jend = sgrp->grp_index[master_gid];
4026  for (j = jstart; j < jend; j++) {
4027  elem = sgrp->grp_item[j * 2];
4028  if (!EVAL_BIT(elem_flag[elem - 1], INTERNAL)
4029  || EVAL_BIT(elem_flag[elem - 1], BOUNDARY)) {
4030  evalsum++;
4031  break;
4032  }
4033  }
4034  if (evalsum) {
4035  /* mask all internal slave nodes as BOUNDARY (but not OVERLAP) */
4036  slave_gid = cp->slave_grp_id[i];
4037  jstart = sgrp->grp_index[slave_gid - 1];
4038  jend = sgrp->grp_index[slave_gid];
4039  for (j = jstart; j < jend; j++) {
4040  evalsum2 = 0;
4041  selem = sgrp->grp_item[j * 2];
4042  for (k = global_mesh->elem_node_index[selem - 1];
4043  k < global_mesh->elem_node_index[selem]; k++) {
4044  node = global_mesh->elem_node_item[k];
4045  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4046  evalsum2++;
4047  break;
4048  }
4049  }
4050  if (evalsum2) {
4051  MASK_BIT(elem_flag[selem - 1], BOUNDARY);
4052  for (k = global_mesh->elem_node_index[selem - 1];
4053  k < global_mesh->elem_node_index[selem]; k++) {
4054  node = global_mesh->elem_node_item[k];
4055  MASK_BIT(node_flag[node - 1], BOUNDARY);
4056  }
4057  }
4058  }
4059  }
4060  break;
4061 
4063  /* if any elem of master surf is internal */
4064  evalsum = 0;
4065  master_gid = cp->master_grp_id[i];
4066  jstart = egrp->grp_index[master_gid - 1];
4067  jend = egrp->grp_index[master_gid];
4068  for (j = jstart; j < jend; j++) {
4069  elem = egrp->grp_item[j];
4070  if (EVAL_BIT(elem_flag[elem - 1], INTERNAL)) {
4071  evalsum++;
4072  break;
4073  }
4074  }
4075  if (evalsum) {
4076  /* mask all external slave nodes as BOUNDARY (but not OVERLAP) */
4077  slave_gid = cp->slave_grp_id[i];
4078  jstart = ngrp->grp_index[slave_gid - 1];
4079  jend = ngrp->grp_index[slave_gid];
4080  for (j = jstart; j < jend; j++) {
4081  node = ngrp->grp_item[j];
4082  if (!EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4083  MASK_BIT(node_flag[node - 1], BOUNDARY);
4084  }
4085  }
4086  }
4087  /* if any elem of master surf is external */
4088  evalsum = 0;
4089  master_gid = cp->master_grp_id[i];
4090  jstart = egrp->grp_index[master_gid - 1];
4091  jend = egrp->grp_index[master_gid];
4092  for (j = jstart; j < jend; j++) {
4093  elem = egrp->grp_item[j];
4094  if (!EVAL_BIT(elem_flag[elem - 1], INTERNAL)) {
4095  evalsum++;
4096  break;
4097  }
4098  }
4099  if (evalsum) {
4100  /* mask all internal slave nodes as BOUNDARY (but not OVERLAP) */
4101  slave_gid = cp->slave_grp_id[i];
4102  jstart = ngrp->grp_index[slave_gid - 1];
4103  jend = ngrp->grp_index[slave_gid];
4104  for (j = jstart; j < jend; j++) {
4105  node = ngrp->grp_item[j];
4106  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4107  MASK_BIT(node_flag[node - 1], BOUNDARY);
4108  }
4109  }
4110  }
4111  break;
4112 
4113  default:
4114  return RTC_ERROR;
4115  }
4116  }
4117 
4118  return RTC_NORMAL;
4119 }
4120 
4121 /* SURF_SURF is judged on the nodes of the slave elements, not on element
4122  * ownership: fistr1 searches per slave node, and this node set is a superset of
4123  * the sub-face nodes it registers, so no slave owner is missed. */
4124 static int classify_contact_slave_ownership(
4125  const struct hecmwST_local_mesh *global_mesh, const char *node_flag,
4126  int pair_idx, int *has_internal_slave, int *has_external_slave) {
4127  int j, node, selem, slave_gid, jstart, jend;
4128  long long k;
4129  struct hecmwST_contact_pair *cp;
4130  struct hecmwST_surf_grp *sgrp;
4131  struct hecmwST_node_grp *ngrp;
4132 
4133  cp = global_mesh->contact_pair;
4134  sgrp = global_mesh->surf_group;
4135  ngrp = global_mesh->node_group;
4136 
4137  *has_internal_slave = 0;
4138  *has_external_slave = 0;
4139 
4140  slave_gid = cp->slave_grp_id[pair_idx];
4141 
4142  switch (cp->type[pair_idx]) {
4145  jstart = ngrp->grp_index[slave_gid - 1];
4146  jend = ngrp->grp_index[slave_gid];
4147  for (j = jstart; j < jend; j++) {
4148  node = ngrp->grp_item[j];
4149  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4150  *has_internal_slave = 1;
4151  } else {
4152  *has_external_slave = 1;
4153  }
4154  }
4155  break;
4156 
4158  jstart = sgrp->grp_index[slave_gid - 1];
4159  jend = sgrp->grp_index[slave_gid];
4160  for (j = jstart; j < jend; j++) {
4161  selem = sgrp->grp_item[j * 2];
4162  for (k = global_mesh->elem_node_index[selem - 1];
4163  k < global_mesh->elem_node_index[selem]; k++) {
4164  node = global_mesh->elem_node_item[k];
4165  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4166  *has_internal_slave = 1;
4167  } else {
4168  *has_external_slave = 1;
4169  }
4170  }
4171  }
4172  break;
4173 
4174  default:
4175  return RTC_ERROR;
4176  }
4177 
4178  return RTC_NORMAL;
4179 }
4180 
4181 static void mask_contact_master_elem(
4182  const struct hecmwST_local_mesh *global_mesh, int elem, char *elem_flag,
4183  char *node_flag) {
4184  long long k;
4185  int node;
4186 
4187  if (!EVAL_BIT(elem_flag[elem - 1], INTERNAL)) {
4188  MASK_BIT(elem_flag[elem - 1], BOUNDARY);
4189  }
4190  for (k = global_mesh->elem_node_index[elem - 1];
4191  k < global_mesh->elem_node_index[elem]; k++) {
4192  node = global_mesh->elem_node_item[k];
4193  MASK_BIT(node_flag[node - 1], BOUNDARY);
4194  }
4195 }
4196 
4197 /*
4198  * A slave owner must get the master surface whole: find_surface_neighbor builds
4199  * the master adjacency graph from the local surfaces alone, so a partial master
4200  * surface leaves that graph cut at the domain boundary.
4201  * Master-node owners keep their master elements BOUNDARY as well, because
4202  * mask_comm_node intersects the BOUNDARY sets of the two domains and the
4203  * intersection would otherwise be empty.
4204  */
4205 static int mask_contact_replicate_master_to_slave_owner(
4206  const struct hecmwST_local_mesh *global_mesh, char *elem_flag,
4207  char *node_flag) {
4208  int i, j, rtc;
4209  long long k;
4210  int elem, node, master_gid, jstart, jend;
4211  int has_internal_slave, has_external_slave, owns_master_node;
4212  struct hecmwST_contact_pair *cp;
4213  struct hecmwST_surf_grp *sgrp;
4214  struct hecmwST_elem_grp *egrp;
4215 
4216  cp = global_mesh->contact_pair;
4217  sgrp = global_mesh->surf_group;
4218  egrp = global_mesh->elem_group;
4219 
4220  for (i = 0; i < cp->n_pair; i++) {
4221  rtc = classify_contact_slave_ownership(global_mesh, node_flag, i,
4222  &has_internal_slave,
4223  &has_external_slave);
4224  if (rtc != RTC_NORMAL) return RTC_ERROR;
4225 
4226  if (!has_internal_slave && !has_external_slave) continue;
4227 
4228  master_gid = cp->master_grp_id[i];
4229 
4230  if (cp->type[i] == HECMW_CONTACT_TYPE_NODE_ELEM) {
4231  jstart = egrp->grp_index[master_gid - 1];
4232  jend = egrp->grp_index[master_gid];
4233  } else {
4234  jstart = sgrp->grp_index[master_gid - 1];
4235  jend = sgrp->grp_index[master_gid];
4236  }
4237 
4238  for (j = jstart; j < jend; j++) {
4239  if (cp->type[i] == HECMW_CONTACT_TYPE_NODE_ELEM) {
4240  elem = egrp->grp_item[j];
4241  } else {
4242  elem = sgrp->grp_item[j * 2];
4243  }
4244 
4245  if (has_internal_slave) {
4246  mask_contact_master_elem(global_mesh, elem, elem_flag, node_flag);
4247  continue;
4248  }
4249 
4250  owns_master_node = 0;
4251  for (k = global_mesh->elem_node_index[elem - 1];
4252  k < global_mesh->elem_node_index[elem]; k++) {
4253  node = global_mesh->elem_node_item[k];
4254  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4255  owns_master_node = 1;
4256  break;
4257  }
4258  }
4259  if (owns_master_node) {
4260  mask_contact_master_elem(global_mesh, elem, elem_flag, node_flag);
4261  }
4262  }
4263  }
4264 
4265  return RTC_NORMAL;
4266 }
4267 
4268 static int mask_contact_replicate_by_owner(
4269  const struct hecmwST_local_mesh *global_mesh, char *elem_flag,
4270  char *node_flag) {
4271  switch (HECMW_partcontact_get_owner(global_mesh->hecmw_flag_partcontact)) {
4273  return mask_contact_replicate_slave_to_master_owner(global_mesh, elem_flag,
4274  node_flag);
4275 
4277  return mask_contact_replicate_master_to_slave_owner(global_mesh, elem_flag,
4278  node_flag);
4279 
4280  default:
4282  "unknown CONTACT_OWNER in hecmw_flag_partcontact");
4283  return RTC_ERROR;
4284  }
4285 }
4286 
4287 static int mask_mesh_status_nb(const struct hecmwST_local_mesh *global_mesh,
4288  char *node_flag, char *elem_flag,
4289  int current_domain) {
4290  int rtc;
4291  int i;
4292 
4293  rtc = mask_node_by_domain(global_mesh, node_flag, current_domain);
4294  if (rtc != RTC_NORMAL) goto error;
4295 
4296  rtc = mask_elem_by_domain_mod(elem_flag, current_domain);
4297  if (rtc != RTC_NORMAL) goto error;
4298 
4299  rtc = mask_overlap_elem(elem_flag, current_domain);
4300  if (rtc != RTC_NORMAL) goto error;
4301 
4302  rtc =
4303  mask_boundary_node_mod(global_mesh, node_flag, elem_flag, current_domain);
4304  if (rtc != RTC_NORMAL) goto error;
4305 
4306 #if 0
4307  /* Additional overlap for explicit DOF elimination for MPC */
4308  /* NO LONGER NEEDED because node-migration implemented */
4309  if (global_mesh->mpc->n_mpc > 0) {
4310  int added = 0;
4311 
4312  rtc = mask_slave_node(global_mesh, node_flag, current_domain);
4313  if (rtc != RTC_NORMAL) goto error;
4314 
4315  rtc = mask_boundary_elem_with_slave(global_mesh, node_flag, elem_flag,
4316  &added);
4317  if (rtc != RTC_NORMAL) goto error;
4318 
4319  if (added > 0) {
4320  rtc = mask_boundary_node(global_mesh, node_flag, elem_flag);
4321  if (rtc != RTC_NORMAL) goto error;
4322  }
4323 
4324  added = 0;
4325  rtc = mask_boundary_link_elem_with_slave(global_mesh, node_flag, elem_flag,
4326  &added);
4327  if (rtc != RTC_NORMAL) goto error;
4328 
4329  if (added > 0) {
4330  rtc = mask_boundary_node(global_mesh, node_flag, elem_flag);
4331  if (rtc != RTC_NORMAL) goto error;
4332  }
4333 
4334  for (i = 0; i < global_mesh->n_node; i++) {
4335  CLEAR_BIT(node_flag[i], MASK);
4336  CLEAR_BIT(node_flag[i], MARK);
4337  }
4338  }
4339 #endif
4340 
4341  for (i = 1; i < global_mesh->hecmw_flag_partdepth; i++) {
4342  rtc = mask_additional_overlap_elem(global_mesh, node_flag, elem_flag);
4343  if (rtc != RTC_NORMAL) goto error;
4344 
4345  rtc = mask_boundary_node(global_mesh, node_flag, elem_flag);
4346  if (rtc != RTC_NORMAL) goto error;
4347  }
4348 
4349  if (global_mesh->contact_pair->n_pair > 0) {
4350  rtc = mask_contact_replicate_by_owner(global_mesh, elem_flag, node_flag);
4351  if (rtc != RTC_NORMAL) goto error;
4352  }
4353 
4354  return RTC_NORMAL;
4355 
4356 error:
4357  return RTC_ERROR;
4358 }
4359 
4360 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4361  * - - - - - - - - - */
4362 
4363 static int mask_overlap_node_mark(const struct hecmwST_local_mesh *global_mesh,
4364  char *node_flag, const char *elem_flag) {
4365  int node;
4366  int i;
4367  long long j;
4368 
4369  for (i = 0; i < global_mesh->n_elem; i++) {
4370  if (EVAL_BIT(elem_flag[i], INTERNAL)) {
4371  for (j = global_mesh->elem_node_index[i];
4372  j < global_mesh->elem_node_index[i + 1]; j++) {
4373  node = global_mesh->elem_node_item[j];
4374  MASK_BIT(node_flag[node - 1], MARK);
4375  }
4376 
4377  } else {
4378  for (j = global_mesh->elem_node_index[i];
4379  j < global_mesh->elem_node_index[i + 1]; j++) {
4380  node = global_mesh->elem_node_item[j];
4381  MASK_BIT(node_flag[node - 1], MASK);
4382  }
4383  }
4384  }
4385 
4386  return RTC_NORMAL;
4387 }
4388 
4389 static int mask_overlap_node_inner(const struct hecmwST_local_mesh *global_mesh,
4390  char *node_flag) {
4391  int i;
4392 
4393  for (i = 0; i < global_mesh->n_node; i++) {
4394  if (EVAL_BIT(node_flag[i], MARK) && EVAL_BIT(node_flag[i], MASK)) {
4395  MASK_BIT(node_flag[i], OVERLAP);
4396  MASK_BIT(node_flag[i], BOUNDARY);
4397  }
4398  }
4399 
4400  return RTC_NORMAL;
4401 }
4402 
4403 static int mask_overlap_node(const struct hecmwST_local_mesh *global_mesh,
4404  char *node_flag, const char *elem_flag) {
4405  int rtc;
4406  int i;
4407 
4408  rtc = mask_overlap_node_mark(global_mesh, node_flag, elem_flag);
4409  if (rtc != RTC_NORMAL) goto error;
4410 
4411  rtc = mask_overlap_node_inner(global_mesh, node_flag);
4412  if (rtc != RTC_NORMAL) goto error;
4413 
4414  for (i = 0; i < global_mesh->n_node; i++) {
4415  CLEAR_BIT(node_flag[i], MASK);
4416  CLEAR_BIT(node_flag[i], MARK);
4417  }
4418 
4419  return RTC_NORMAL;
4420 
4421 error:
4422  return RTC_ERROR;
4423 }
4424 
4425 static int mask_boundary_elem(const struct hecmwST_local_mesh *global_mesh,
4426  const char *node_flag, char *elem_flag) {
4427  int node, evalsum;
4428  int i;
4429  long long j;
4430 
4431  for (i = 0; i < global_mesh->n_elem; i++) {
4432  evalsum = 0;
4433  for (j = global_mesh->elem_node_index[i];
4434  j < global_mesh->elem_node_index[i + 1]; j++) {
4435  node = global_mesh->elem_node_item[j];
4436  if (EVAL_BIT(node_flag[node - 1], BOUNDARY)) evalsum++;
4437  }
4438 
4439  if (evalsum) {
4440  MASK_BIT(elem_flag[i], OVERLAP);
4441  MASK_BIT(elem_flag[i], BOUNDARY);
4442  }
4443  }
4444 
4445  return RTC_NORMAL;
4446 }
4447 
4448 static int mask_mesh_status_eb(const struct hecmwST_local_mesh *global_mesh,
4449  char *node_flag, char *elem_flag,
4450  int current_domain) {
4451  int rtc;
4452  int i;
4453 
4454  for (i = 0; i < global_mesh->n_node; i++) {
4455  CLEAR_BIT(node_flag[i], INTERNAL);
4456  CLEAR_BIT(node_flag[i], EXTERNAL);
4457  CLEAR_BIT(node_flag[i], BOUNDARY);
4458  }
4459  for (i = 0; i < global_mesh->n_elem; i++) {
4460  CLEAR_BIT(elem_flag[i], INTERNAL);
4461  CLEAR_BIT(elem_flag[i], EXTERNAL);
4462  CLEAR_BIT(elem_flag[i], BOUNDARY);
4463  }
4464 
4465  rtc = mask_node_by_domain(global_mesh, node_flag, current_domain);
4466  if (rtc != RTC_NORMAL) goto error;
4467 
4468  rtc = mask_elem_by_domain(global_mesh, elem_flag, current_domain);
4469  if (rtc != RTC_NORMAL) goto error;
4470 
4471  rtc = mask_overlap_node(global_mesh, node_flag, elem_flag);
4472  if (rtc != RTC_NORMAL) goto error;
4473 
4474  rtc = mask_boundary_elem(global_mesh, node_flag, elem_flag);
4475  if (rtc != RTC_NORMAL) goto error;
4476 
4477  return RTC_NORMAL;
4478 
4479 error:
4480  return RTC_ERROR;
4481 }
4482 
4483 /*------------------------------------------------------------------------------------------------*/
4484 
4485 static int mask_neighbor_domain_nb(const struct hecmwST_local_mesh *global_mesh,
4486  const char *node_flag, char *domain_flag) {
4487  int i;
4488 
4489  for (i = 0; i < global_mesh->n_node; i++) {
4490  if (!EVAL_BIT(node_flag[i], INTERNAL) && EVAL_BIT(node_flag[i], BOUNDARY)) {
4491  MASK_BIT(domain_flag[global_mesh->node_ID[2 * i + 1]], MASK);
4492  }
4493  }
4494 
4495  return RTC_NORMAL;
4496 }
4497 
4498 static int mask_neighbor_domain_nb_mod(
4499  const struct hecmwST_local_mesh *global_mesh, const char *node_flag,
4500  char *domain_flag, int domain) {
4501  int i, node;
4502 
4503  for (i = n_bnd_nlist[2 * domain]; i < n_bnd_nlist[2 * domain + 1]; i++) {
4504  node = bnd_nlist[domain][i];
4505  MASK_BIT(domain_flag[global_mesh->node_ID[2 * node - 1]], MASK);
4506  }
4507 
4508  return RTC_NORMAL;
4509 }
4510 
4511 static int mask_neighbor_domain_nb_contact_master_owner(
4512  const struct hecmwST_local_mesh *global_mesh, const char *node_flag,
4513  const char *elem_flag, char *domain_flag) {
4514  int i, j;
4515  long long k;
4516  int elem, node, selem;
4517  int evalsum;
4518  int master_gid, slave_gid;
4519  int jstart, jend;
4520  struct hecmwST_contact_pair *cp;
4521  struct hecmwST_surf_grp *sgrp;
4522  struct hecmwST_node_grp *ngrp;
4523  struct hecmwST_elem_grp *egrp;
4524 
4525  cp = global_mesh->contact_pair;
4526  sgrp = global_mesh->surf_group;
4527  ngrp = global_mesh->node_group;
4528  egrp = global_mesh->elem_group;
4529 
4530  for (i = 0; i < cp->n_pair; i++) {
4531  /* if any slave node is internal */
4532  evalsum = 0;
4533  switch (cp->type[i]) {
4535  slave_gid = cp->slave_grp_id[i];
4536  jstart = ngrp->grp_index[slave_gid - 1];
4537  jend = ngrp->grp_index[slave_gid];
4538  for (j = jstart; j < jend; j++) {
4539  node = ngrp->grp_item[j];
4540  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4541  evalsum++;
4542  break;
4543  }
4544  }
4545  break;
4547  slave_gid = cp->slave_grp_id[i];
4548  jstart = sgrp->grp_index[slave_gid - 1];
4549  jend = sgrp->grp_index[slave_gid];
4550  for (j = jstart; j < jend; j++) {
4551  selem = sgrp->grp_item[j * 2];
4552  for (k = global_mesh->elem_node_index[selem - 1];
4553  k < global_mesh->elem_node_index[selem]; k++) {
4554  node = global_mesh->elem_node_item[k];
4555  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4556  evalsum++;
4557  break;
4558  }
4559  }
4560  if (evalsum) break;
4561  }
4562  break;
4564  slave_gid = cp->slave_grp_id[i];
4565  jstart = ngrp->grp_index[slave_gid - 1];
4566  jend = ngrp->grp_index[slave_gid];
4567  for (j = jstart; j < jend; j++) {
4568  node = ngrp->grp_item[j];
4569  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4570  evalsum++;
4571  break;
4572  }
4573  }
4574  break;
4575  default:
4576  return RTC_ERROR;
4577  }
4578  /* the domain to which elems of the master surf belong is neighbor */
4579  if (evalsum) {
4580  master_gid = cp->master_grp_id[i];
4581  if( cp->type[i] == HECMW_CONTACT_TYPE_NODE_ELEM ) {
4582  jstart = egrp->grp_index[master_gid - 1];
4583  jend = egrp->grp_index[master_gid];
4584  for (j = jstart; j < jend; j++) {
4585  elem = egrp->grp_item[j];
4586  if (!EVAL_BIT(elem_flag[elem - 1], INTERNAL)) {
4587  MASK_BIT(domain_flag[global_mesh->elem_ID[2 * (elem - 1) + 1]], MASK);
4588  }
4589  }
4590  } else {
4591  jstart = sgrp->grp_index[master_gid - 1];
4592  jend = sgrp->grp_index[master_gid];
4593  for (j = jstart; j < jend; j++) {
4594  elem = sgrp->grp_item[j * 2];
4595  if (!EVAL_BIT(elem_flag[elem - 1], INTERNAL)) {
4596  MASK_BIT(domain_flag[global_mesh->elem_ID[2 * (elem - 1) + 1]], MASK);
4597  }
4598  }
4599  }
4600  }
4601  }
4602 
4603  return RTC_NORMAL;
4604 }
4605 
4606 /* The opposite direction is invisible to mask_neighbor_domain_nb: on a
4607  * master-node owner those nodes are internal, and it may share no mesh entity
4608  * with the slave owner at all. Both directions must be keyed on node
4609  * ownership, so that the set of domains registered here matches the set that
4610  * receives the replicated master surface. */
4611 static int mask_neighbor_domain_nb_contact_slave_owner(
4612  const struct hecmwST_local_mesh *global_mesh, const char *node_flag,
4613  const char *elem_flag, char *domain_flag) {
4614  int i, j, rtc;
4615  long long k;
4616  int elem, node, selem, master_gid, slave_gid, jstart, jend;
4617  int has_internal_slave, has_external_slave, owns_master_node;
4618  struct hecmwST_contact_pair *cp;
4619  struct hecmwST_surf_grp *sgrp;
4620  struct hecmwST_node_grp *ngrp;
4621  struct hecmwST_elem_grp *egrp;
4622 
4623  cp = global_mesh->contact_pair;
4624  sgrp = global_mesh->surf_group;
4625  ngrp = global_mesh->node_group;
4626  egrp = global_mesh->elem_group;
4627 
4628  for (i = 0; i < cp->n_pair; i++) {
4629  rtc = classify_contact_slave_ownership(global_mesh, node_flag, i,
4630  &has_internal_slave,
4631  &has_external_slave);
4632  if (rtc != RTC_NORMAL) return RTC_ERROR;
4633 
4634  if (!has_external_slave) continue;
4635 
4636  owns_master_node = 0;
4637  master_gid = cp->master_grp_id[i];
4638  if (cp->type[i] == HECMW_CONTACT_TYPE_NODE_ELEM) {
4639  jstart = egrp->grp_index[master_gid - 1];
4640  jend = egrp->grp_index[master_gid];
4641  } else {
4642  jstart = sgrp->grp_index[master_gid - 1];
4643  jend = sgrp->grp_index[master_gid];
4644  }
4645  for (j = jstart; j < jend && !owns_master_node; j++) {
4646  if (cp->type[i] == HECMW_CONTACT_TYPE_NODE_ELEM) {
4647  elem = egrp->grp_item[j];
4648  } else {
4649  elem = sgrp->grp_item[j * 2];
4650  }
4651  for (k = global_mesh->elem_node_index[elem - 1];
4652  k < global_mesh->elem_node_index[elem]; k++) {
4653  node = global_mesh->elem_node_item[k];
4654  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4655  owns_master_node = 1;
4656  break;
4657  }
4658  }
4659  }
4660  if (!owns_master_node) continue;
4661 
4662  slave_gid = cp->slave_grp_id[i];
4663  switch (cp->type[i]) {
4666  jstart = ngrp->grp_index[slave_gid - 1];
4667  jend = ngrp->grp_index[slave_gid];
4668  for (j = jstart; j < jend; j++) {
4669  node = ngrp->grp_item[j];
4670  if (!EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4671  MASK_BIT(domain_flag[global_mesh->node_ID[2 * (node - 1) + 1]],
4672  MASK);
4673  }
4674  }
4675  break;
4676 
4678  jstart = sgrp->grp_index[slave_gid - 1];
4679  jend = sgrp->grp_index[slave_gid];
4680  for (j = jstart; j < jend; j++) {
4681  selem = sgrp->grp_item[j * 2];
4682  for (k = global_mesh->elem_node_index[selem - 1];
4683  k < global_mesh->elem_node_index[selem]; k++) {
4684  node = global_mesh->elem_node_item[k];
4685  if (!EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4686  MASK_BIT(domain_flag[global_mesh->node_ID[2 * (node - 1) + 1]],
4687  MASK);
4688  }
4689  }
4690  }
4691  break;
4692 
4693  default:
4694  return RTC_ERROR;
4695  }
4696  }
4697 
4698  return RTC_NORMAL;
4699 }
4700 
4701 static int mask_neighbor_domain_nb_contact_by_owner(
4702  const struct hecmwST_local_mesh *global_mesh, const char *node_flag,
4703  const char *elem_flag, char *domain_flag) {
4704  switch (HECMW_partcontact_get_owner(global_mesh->hecmw_flag_partcontact)) {
4706  return mask_neighbor_domain_nb_contact_master_owner(
4707  global_mesh, node_flag, elem_flag, domain_flag);
4708 
4710  return mask_neighbor_domain_nb_contact_slave_owner(
4711  global_mesh, node_flag, elem_flag, domain_flag);
4712 
4713  default:
4715  "unknown CONTACT_OWNER in hecmw_flag_partcontact");
4716  return RTC_ERROR;
4717  }
4718 }
4719 
4720 static int mask_neighbor_domain_eb(const struct hecmwST_local_mesh *global_mesh,
4721  const char *elem_flag, char *domain_flag) {
4722  int i;
4723 
4724  for (i = 0; i < global_mesh->n_elem; i++) {
4725  if (EVAL_BIT(elem_flag[i], EXTERNAL) && EVAL_BIT(elem_flag[i], BOUNDARY)) {
4726  MASK_BIT(domain_flag[global_mesh->elem_ID[2 * i + 1]], MASK);
4727  }
4728  }
4729 
4730  return RTC_NORMAL;
4731 }
4732 
4733 static int count_neighbor_domain(const struct hecmwST_local_mesh *global_mesh,
4734  const char *domain_flag) {
4735  int counter;
4736  int i;
4737 
4738  for (counter = 0, i = 0; i < global_mesh->n_subdomain; i++) {
4739  if (EVAL_BIT(domain_flag[i], MASK)) counter++;
4740  }
4741 
4742  return counter;
4743 }
4744 
4745 static int set_neighbor_domain(const struct hecmwST_local_mesh *global_mesh,
4746  struct hecmwST_local_mesh *local_mesh,
4747  const char *domain_flag) {
4748  int counter;
4749  int i;
4750 
4751  for (counter = 0, i = 0; i < global_mesh->n_subdomain; i++) {
4752  if (EVAL_BIT(domain_flag[i], MASK)) {
4753  local_mesh->neighbor_pe[counter++] = i;
4754  }
4755  }
4756 
4757  return counter;
4758 }
4759 
4760 static int create_neighbor_info(const struct hecmwST_local_mesh *global_mesh,
4761  struct hecmwST_local_mesh *local_mesh,
4762  char *node_flag, char *elem_flag,
4763  int current_domain) {
4764  int rtc;
4765  char *domain_flag = NULL;
4766 
4767  HECMW_assert(global_mesh);
4768  HECMW_assert(local_mesh);
4769  HECMW_assert(node_flag);
4770  HECMW_assert(elem_flag);
4771 
4773  "Starting creation of neighboring domain information...");
4774 
4775  local_mesh->n_neighbor_pe = 0;
4776  local_mesh->neighbor_pe = NULL;
4777 
4778  domain_flag = (char *)HECMW_calloc(global_mesh->n_subdomain, sizeof(char));
4779  if (domain_flag == NULL) {
4780  HECMW_set_error(errno, "");
4781  goto error;
4782  }
4783 
4784  switch (global_mesh->hecmw_flag_parttype) {
4785  case HECMW_FLAG_PARTTYPE_NODEBASED: /* for node-based partitioning */
4786  rtc = mask_mesh_status_nb(global_mesh, node_flag, elem_flag,
4787  current_domain);
4788  if (rtc != RTC_NORMAL) goto error;
4789 
4790  if (is_spdup_available(global_mesh)) {
4791  rtc = mask_neighbor_domain_nb_mod(global_mesh, node_flag, domain_flag,
4792  current_domain);
4793  } else {
4794  rtc = mask_neighbor_domain_nb(global_mesh, node_flag, domain_flag);
4795  }
4796  if (rtc != RTC_NORMAL) goto error;
4797 
4798  if (global_mesh->contact_pair->n_pair > 0) {
4799  rtc = mask_neighbor_domain_nb_contact_by_owner(
4800  global_mesh, node_flag, elem_flag, domain_flag);
4801  if (rtc != RTC_NORMAL) goto error;
4802  }
4803 
4804  break;
4805 
4806  case HECMW_FLAG_PARTTYPE_ELEMBASED: /* for element-based partitioning */
4807  rtc = mask_mesh_status_eb(global_mesh, node_flag, elem_flag,
4808  current_domain);
4809  if (rtc != RTC_NORMAL) goto error;
4810 
4811  rtc = mask_neighbor_domain_eb(global_mesh, elem_flag, domain_flag);
4812  if (rtc != RTC_NORMAL) goto error;
4813 
4814  break;
4815 
4816  default:
4818  goto error;
4819  }
4820 
4821  local_mesh->n_neighbor_pe = count_neighbor_domain(global_mesh, domain_flag);
4822  if (local_mesh->n_neighbor_pe < 0) {
4824  goto error;
4825  }
4826 
4827  if (local_mesh->n_neighbor_pe == 0) {
4828  local_mesh->neighbor_pe = NULL;
4829  HECMW_free(domain_flag);
4830  return RTC_NORMAL;
4831  }
4832 
4833  local_mesh->neighbor_pe =
4834  (int *)HECMW_malloc(sizeof(int) * local_mesh->n_neighbor_pe);
4835  if (local_mesh->neighbor_pe == NULL) {
4836  HECMW_set_error(errno, "");
4837  goto error;
4838  }
4839  rtc = set_neighbor_domain(global_mesh, local_mesh, domain_flag);
4840  HECMW_assert(rtc == local_mesh->n_neighbor_pe);
4841 
4842  HECMW_free(domain_flag);
4843 
4844  HECMW_log(HECMW_LOG_DEBUG, "Creation of neighboring domain information done");
4845 
4846  return RTC_NORMAL;
4847 
4848 error:
4849  HECMW_free(domain_flag);
4850  HECMW_free(local_mesh->neighbor_pe);
4851  local_mesh->n_neighbor_pe = 0;
4852  local_mesh->neighbor_pe = NULL;
4853 
4854  return RTC_ERROR;
4855 }
4856 
4857 /*================================================================================================*/
4858 
4859 static int mask_comm_node(const struct hecmwST_local_mesh *global_mesh,
4860  char *node_flag_current, char *node_flag_neighbor) {
4861  int i;
4862 
4863  for (i = 0; i < global_mesh->n_node; i++) {
4864  if (EVAL_BIT(node_flag_current[i], BOUNDARY) &&
4865  EVAL_BIT(node_flag_neighbor[i], BOUNDARY)) {
4866  MASK_BIT(node_flag_current[i], MASK);
4867  }
4868  }
4869 
4870  return RTC_NORMAL;
4871 }
4872 
4873 static int mask_comm_node_mod(const struct hecmwST_local_mesh *global_mesh,
4874  char *node_flag_current, char *node_flag_neighbor,
4875  int current_domain) {
4876  int i, node;
4877 
4878  for (i = 0; i < n_bnd_nlist[2 * current_domain + 1]; i++) {
4879  node = bnd_nlist[current_domain][i];
4880  if (EVAL_BIT(node_flag_neighbor[node - 1], BOUNDARY)) {
4881  MASK_BIT(node_flag_current[node - 1], MASK);
4882  }
4883  }
4884 
4885  return RTC_NORMAL;
4886 }
4887 
4888 static int mask_comm_elem(const struct hecmwST_local_mesh *global_mesh,
4889  char *elem_flag_current, char *elem_flag_neighbor) {
4890  int i;
4891 
4892  for (i = 0; i < global_mesh->n_elem; i++) {
4893  if (EVAL_BIT(elem_flag_current[i], BOUNDARY) &&
4894  EVAL_BIT(elem_flag_neighbor[i], BOUNDARY)) {
4895  MASK_BIT(elem_flag_current[i], MASK);
4896  }
4897  }
4898 
4899  return RTC_NORMAL;
4900 }
4901 
4902 static int mask_comm_elem_mod(const struct hecmwST_local_mesh *global_mesh,
4903  char *elem_flag_current, char *elem_flag_neighbor,
4904  int current_domain) {
4905  int i, elem;
4906 
4907  for (i = 0; i < n_bnd_elist[2 * current_domain + 1]; i++) {
4908  elem = bnd_elist[current_domain][i];
4909  if (EVAL_BIT(elem_flag_neighbor[elem - 1], BOUNDARY)) {
4910  MASK_BIT(elem_flag_current[elem - 1], MASK);
4911  }
4912  }
4913 
4914  return RTC_NORMAL;
4915 }
4916 
4917 static int count_masked_comm_node(const struct hecmwST_local_mesh *global_mesh,
4918  const char *node_flag, int domain) {
4919  int counter;
4920  int i, node;
4921 
4922  for (counter = 0, i = 0; i < n_int_nlist[domain]; i++) {
4923  node = int_nlist[domain][i];
4924  if (EVAL_BIT(node_flag[node - 1], MASK)) counter++;
4925  }
4926 
4927  return counter;
4928 }
4929 
4930 static int count_masked_comm_elem(const struct hecmwST_local_mesh *global_mesh,
4931  const char *elem_flag, int domain) {
4932  int counter;
4933  int i;
4934 
4935  for (counter = 0, i = 0; i < global_mesh->n_elem; i++) {
4936  if (EVAL_BIT(elem_flag[i], MASK) &&
4937  global_mesh->elem_ID[2 * i + 1] == domain)
4938  counter++;
4939  }
4940 
4941  return counter;
4942 }
4943 
4944 static int count_masked_shared_node(
4945  const struct hecmwST_local_mesh *global_mesh, const char *node_flag) {
4946  int counter;
4947  int i;
4948 
4949  for (counter = 0, i = 0; i < global_mesh->n_node; i++) {
4950  if (EVAL_BIT(node_flag[i], MASK)) counter++;
4951  }
4952 
4953  return counter;
4954 }
4955 
4956 static int count_masked_shared_elem(
4957  const struct hecmwST_local_mesh *global_mesh, const char *elem_flag) {
4958  int counter;
4959  int i;
4960 
4961  for (counter = 0, i = 0; i < global_mesh->n_elem; i++) {
4962  if (EVAL_BIT(elem_flag[i], MASK)) counter++;
4963  }
4964 
4965  return counter;
4966 }
4967 
4968 static int count_masked_shared_elem_mod(
4969  const struct hecmwST_local_mesh *global_mesh, const char *elem_flag,
4970  int domain) {
4971  int counter;
4972  int i, elem;
4973 
4974  for (counter = 0, i = 0; i < n_bnd_elist[2 * domain + 1]; i++) {
4975  elem = bnd_elist[domain][i];
4976  if (EVAL_BIT(elem_flag[elem - 1], MASK)) counter++;
4977  }
4978 
4979  return counter;
4980 }
4981 
4982 static int create_comm_node_pre(const struct hecmwST_local_mesh *global_mesh,
4983  const char *node_flag, int **comm_node,
4984  int neighbor_idx, int domain) {
4985  int counter;
4986  int i, node;
4987 
4988  for (counter = 0, i = 0; i < n_int_nlist[domain]; i++) {
4989  node = int_nlist[domain][i];
4990  if (EVAL_BIT(node_flag[node - 1], MASK)) {
4991  comm_node[neighbor_idx][counter++] = node;
4992  }
4993  }
4994 
4995  return counter;
4996 }
4997 
4998 static int create_comm_elem_pre(const struct hecmwST_local_mesh *global_mesh,
4999  const char *elem_flag, int **comm_elem,
5000  int neighbor_idx, int domain) {
5001  int counter;
5002  int i;
5003 
5004  for (counter = 0, i = 0; i < global_mesh->n_elem; i++) {
5005  if (EVAL_BIT(elem_flag[i], MASK) &&
5006  global_mesh->elem_ID[2 * i + 1] == domain) {
5007  comm_elem[neighbor_idx][counter++] = i + 1;
5008  }
5009  }
5010 
5011  return counter;
5012 }
5013 
5014 static int create_shared_node_pre(const struct hecmwST_local_mesh *global_mesh,
5015  const char *node_flag, int **shared_node,
5016  int neighbor_idx) {
5017  int counter;
5018  int i;
5019 
5020  for (counter = 0, i = 0; i < global_mesh->n_node; i++) {
5021  if (EVAL_BIT(node_flag[i], MASK)) {
5022  shared_node[neighbor_idx][counter++] = i + 1;
5023  }
5024  }
5025 
5026  return counter;
5027 }
5028 
5029 static int create_shared_elem_pre(const struct hecmwST_local_mesh *global_mesh,
5030  const char *elem_flag, int **shared_elem,
5031  int neighbor_idx) {
5032  int counter;
5033  int i;
5034 
5035  for (counter = 0, i = 0; i < global_mesh->n_elem; i++) {
5036  if (EVAL_BIT(elem_flag[i], MASK)) {
5037  shared_elem[neighbor_idx][counter++] = i + 1;
5038  }
5039  }
5040 
5041  return counter;
5042 }
5043 
5044 static int create_shared_elem_pre_mod(
5045  const struct hecmwST_local_mesh *global_mesh, const char *elem_flag,
5046  int **shared_elem, int neighbor_idx, int neighbor_domain) {
5047  int counter;
5048  int i, idx1, idx2, elem1, elem2, n_bnd, n_out, maxe;
5049 
5050  n_bnd = n_bnd_elist[2 * neighbor_domain];
5051  n_out =
5052  n_bnd_elist[2 * neighbor_domain + 1] - n_bnd_elist[2 * neighbor_domain];
5053  maxe = global_mesh->n_elem + 1;
5054 
5055  elem1 = (n_bnd == 0) ? maxe : bnd_elist[neighbor_domain][0];
5056  elem2 = (n_out == 0) ? maxe : bnd_elist[neighbor_domain][n_bnd];
5057  for (counter = 0, idx1 = 0, idx2 = 0, i = 0; i < n_bnd + n_out; i++) {
5058  if (elem1 < elem2) {
5059  if (EVAL_BIT(elem_flag[elem1 - 1], MASK)) {
5060  shared_elem[neighbor_idx][counter++] = elem1;
5061  }
5062  idx1++;
5063  elem1 = (idx1 == n_bnd) ? maxe : bnd_elist[neighbor_domain][idx1];
5064  } else {
5065  if (EVAL_BIT(elem_flag[elem2 - 1], MASK)) {
5066  shared_elem[neighbor_idx][counter++] = elem2;
5067  }
5068  idx2++;
5069  elem2 = (idx2 == n_out) ? maxe : bnd_elist[neighbor_domain][idx2 + n_bnd];
5070  }
5071  }
5072 
5073  return counter;
5074 }
5075 
5076 static int create_comm_item(int n_neighbor_pe, int **comm_item_pre,
5077  int *comm_index, int *comm_item) {
5078  int i, j, js, je;
5079 
5080  for (i = 0; i < n_neighbor_pe; i++) {
5081  js = comm_index[i];
5082  je = comm_index[i + 1];
5083 
5084  for (j = 0; j < je - js; j++) {
5085  comm_item[js + j] = comm_item_pre[i][j];
5086  }
5087  }
5088 
5089  return RTC_NORMAL;
5090 }
5091 
5092 /*------------------------------------------------------------------------------------------------*/
5093 
5094 static int create_import_info_nb(const struct hecmwST_local_mesh *global_mesh,
5095  struct hecmwST_local_mesh *local_mesh,
5096  const char *node_flag, int **import_node,
5097  int neighbor_idx, int neighbor_domain) {
5098  int n_import_node, rtc;
5099 
5100  n_import_node =
5101  count_masked_comm_node(global_mesh, node_flag, neighbor_domain);
5102  HECMW_assert(n_import_node >= 0);
5103 
5104  local_mesh->import_index[neighbor_idx + 1] =
5105  local_mesh->import_index[neighbor_idx] + n_import_node;
5106 
5107  import_node[neighbor_idx] = (int *)HECMW_malloc(sizeof(int) * n_import_node);
5108  if (import_node[neighbor_idx] == NULL) {
5109  HECMW_set_error(errno, "");
5110  goto error;
5111  }
5112 
5113  rtc = create_comm_node_pre(global_mesh, node_flag, import_node, neighbor_idx,
5114  neighbor_domain);
5115  HECMW_assert(rtc == n_import_node);
5116 
5117  return RTC_NORMAL;
5118 
5119 error:
5120  return RTC_ERROR;
5121 }
5122 
5123 static int create_export_info_nb(const struct hecmwST_local_mesh *global_mesh,
5124  struct hecmwST_local_mesh *local_mesh,
5125  const char *node_flag, int **export_node,
5126  int neighbor_idx, int current_domain,
5127  int neighbor_domain) {
5128  int n_export_node, rtc;
5129 
5130  n_export_node =
5131  count_masked_comm_node(global_mesh, node_flag, current_domain);
5132  HECMW_assert(n_export_node >= 0);
5133 
5134  local_mesh->export_index[neighbor_idx + 1] =
5135  local_mesh->export_index[neighbor_idx] + n_export_node;
5136 
5137  export_node[neighbor_idx] = (int *)HECMW_malloc(sizeof(int) * n_export_node);
5138  if (export_node[neighbor_idx] == NULL) {
5139  HECMW_set_error(errno, "");
5140  goto error;
5141  }
5142 
5143  rtc = create_comm_node_pre(global_mesh, node_flag, export_node, neighbor_idx,
5144  current_domain);
5145  HECMW_assert(rtc == n_export_node);
5146 
5147  return RTC_NORMAL;
5148 
5149 error:
5150  return RTC_ERROR;
5151 }
5152 
5153 static int create_shared_info_nb(const struct hecmwST_local_mesh *global_mesh,
5154  struct hecmwST_local_mesh *local_mesh,
5155  const char *elem_flag, int **shared_elem,
5156  int neighbor_idx, int neighbor_domain) {
5157  int n_shared_elem, rtc;
5158 
5159  if (is_spdup_available(global_mesh)) {
5160  n_shared_elem =
5161  count_masked_shared_elem_mod(global_mesh, elem_flag, neighbor_domain);
5162  } else {
5163  n_shared_elem = count_masked_shared_elem(global_mesh, elem_flag);
5164  }
5165 
5166  HECMW_assert(n_shared_elem >= 0);
5167 
5168  local_mesh->shared_index[neighbor_idx + 1] =
5169  local_mesh->shared_index[neighbor_idx] + n_shared_elem;
5170 
5171  shared_elem[neighbor_idx] = (int *)HECMW_malloc(sizeof(int) * n_shared_elem);
5172  if (shared_elem[neighbor_idx] == NULL) {
5173  HECMW_set_error(errno, "");
5174  goto error;
5175  }
5176 
5177  if (is_spdup_available(global_mesh)) {
5178  rtc = create_shared_elem_pre_mod(global_mesh, elem_flag, shared_elem,
5179  neighbor_idx, neighbor_domain);
5180  } else {
5181  rtc = create_shared_elem_pre(global_mesh, elem_flag, shared_elem,
5182  neighbor_idx);
5183  }
5184 
5185  HECMW_assert(rtc == n_shared_elem);
5186 
5187  return RTC_NORMAL;
5188 
5189 error:
5190  return RTC_ERROR;
5191 }
5192 
5193 static int create_comm_info_nb(const struct hecmwST_local_mesh *global_mesh,
5194  struct hecmwST_local_mesh *local_mesh,
5195  char *node_flag, char *elem_flag,
5196  char *node_flag_neighbor,
5197  char *elem_flag_neighbor, int current_domain) {
5198  int **import_node = NULL;
5199  int **export_node = NULL;
5200  int **shared_elem = NULL;
5201  int neighbor_domain;
5202  int size;
5203  int rtc;
5204  int i, j;
5205 
5206  local_mesh->import_index = NULL;
5207  local_mesh->export_index = NULL;
5208  local_mesh->shared_index = NULL;
5209  local_mesh->import_item = NULL;
5210  local_mesh->export_item = NULL;
5211  local_mesh->shared_item = NULL;
5212 
5213  import_node = (int **)HECMW_malloc(sizeof(int *) * (size_t)local_mesh->n_neighbor_pe);
5214  if (import_node == NULL) {
5215  HECMW_set_error(errno, "");
5216  goto error;
5217  } else {
5218  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5219  import_node[i] = NULL;
5220  }
5221  }
5222  export_node = (int **)HECMW_malloc(sizeof(int *) * (size_t)local_mesh->n_neighbor_pe);
5223  if (export_node == NULL) {
5224  HECMW_set_error(errno, "");
5225  goto error;
5226  } else {
5227  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5228  export_node[i] = NULL;
5229  }
5230  }
5231  shared_elem = (int **)HECMW_malloc(sizeof(int *) * local_mesh->n_neighbor_pe);
5232  if (shared_elem == NULL) {
5233  HECMW_set_error(errno, "");
5234  goto error;
5235  } else {
5236  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5237  shared_elem[i] = NULL;
5238  }
5239  }
5240 
5241  local_mesh->import_index =
5242  (int *)HECMW_calloc(local_mesh->n_neighbor_pe + 1, sizeof(int));
5243  if (local_mesh->import_index == NULL) {
5244  HECMW_set_error(errno, "");
5245  goto error;
5246  }
5247  local_mesh->export_index =
5248  (int *)HECMW_calloc(local_mesh->n_neighbor_pe + 1, sizeof(int));
5249  if (local_mesh->export_index == NULL) {
5250  HECMW_set_error(errno, "");
5251  goto error;
5252  }
5253  local_mesh->shared_index =
5254  (int *)HECMW_calloc(local_mesh->n_neighbor_pe + 1, sizeof(int));
5255  if (local_mesh->shared_index == NULL) {
5256  HECMW_set_error(errno, "");
5257  goto error;
5258  }
5259 
5260  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5261  neighbor_domain = local_mesh->neighbor_pe[i];
5262 
5263  rtc = mask_mesh_status_nb(global_mesh, node_flag_neighbor,
5264  elem_flag_neighbor, neighbor_domain);
5265  if (rtc != RTC_NORMAL) goto error;
5266 
5267  if (is_spdup_available(global_mesh)) {
5268  rtc = mask_comm_node_mod(global_mesh, node_flag, node_flag_neighbor,
5269  current_domain);
5270  } else {
5271  rtc = mask_comm_node(global_mesh, node_flag, node_flag_neighbor);
5272  }
5273 
5274  if (rtc != RTC_NORMAL) goto error;
5275 
5276  if (is_spdup_available(global_mesh)) {
5277  rtc = mask_comm_elem_mod(global_mesh, elem_flag, elem_flag_neighbor,
5278  current_domain);
5279  } else {
5280  rtc = mask_comm_elem(global_mesh, elem_flag, elem_flag_neighbor);
5281  }
5282 
5283  if (rtc != RTC_NORMAL) goto error;
5284 
5285  rtc = create_import_info_nb(global_mesh, local_mesh, node_flag, import_node,
5286  i, neighbor_domain);
5287  if (rtc != RTC_NORMAL) goto error;
5288 
5289  rtc = create_export_info_nb(global_mesh, local_mesh, node_flag, export_node,
5290  i, current_domain, neighbor_domain);
5291  if (rtc != RTC_NORMAL) goto error;
5292 
5293  rtc = create_shared_info_nb(global_mesh, local_mesh, elem_flag, shared_elem,
5294  i, neighbor_domain);
5295  if (rtc != RTC_NORMAL) goto error;
5296 
5297  if (is_spdup_available(global_mesh)) {
5298  rtc = spdup_clear_IEB(node_flag_neighbor, elem_flag_neighbor,
5299  neighbor_domain);
5300  if (rtc != RTC_NORMAL) goto error;
5301 
5302  rtc = spdup_clear_MMbnd(node_flag_neighbor, elem_flag_neighbor,
5303  neighbor_domain);
5304  if (rtc != RTC_NORMAL) goto error;
5305 
5306  rtc = spdup_clear_MMbnd(node_flag, elem_flag, current_domain);
5307  if (rtc != RTC_NORMAL) goto error;
5308  } else {
5309  for (j = 0; j < global_mesh->n_node; j++) {
5310  CLEAR_MM(node_flag[j]);
5311  }
5312  for (j = 0; j < global_mesh->n_elem; j++) {
5313  CLEAR_MM(elem_flag[j]);
5314  }
5315 
5316  memset(node_flag_neighbor, 0, sizeof(char) * global_mesh->n_node);
5317  memset(elem_flag_neighbor, 0, sizeof(char) * global_mesh->n_elem);
5318  }
5319  }
5320 
5321  size = sizeof(int) * local_mesh->import_index[local_mesh->n_neighbor_pe];
5322  local_mesh->import_item = (int *)HECMW_malloc(size);
5323  if (local_mesh->import_item == NULL) {
5324  HECMW_set_error(errno, "");
5325  goto error;
5326  }
5327 
5328  rtc = create_comm_item(local_mesh->n_neighbor_pe, import_node,
5329  local_mesh->import_index, local_mesh->import_item);
5330  if (rtc != RTC_NORMAL) goto error;
5331 
5332  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5333  HECMW_free(import_node[i]);
5334  }
5335  HECMW_free(import_node);
5336  import_node = NULL;
5337 
5338  size = sizeof(int) * local_mesh->export_index[local_mesh->n_neighbor_pe];
5339  local_mesh->export_item = (int *)HECMW_malloc(size);
5340  if (local_mesh->export_item == NULL) {
5341  HECMW_set_error(errno, "");
5342  goto error;
5343  }
5344 
5345  rtc = create_comm_item(local_mesh->n_neighbor_pe, export_node,
5346  local_mesh->export_index, local_mesh->export_item);
5347  if (rtc != RTC_NORMAL) goto error;
5348 
5349  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5350  HECMW_free(export_node[i]);
5351  }
5352  HECMW_free(export_node);
5353  export_node = NULL;
5354 
5355  size = sizeof(int) * local_mesh->shared_index[local_mesh->n_neighbor_pe];
5356  local_mesh->shared_item = (int *)HECMW_malloc(size);
5357  if (local_mesh->shared_item == NULL) {
5358  HECMW_set_error(errno, "");
5359  goto error;
5360  }
5361 
5362  rtc = create_comm_item(local_mesh->n_neighbor_pe, shared_elem,
5363  local_mesh->shared_index, local_mesh->shared_item);
5364  if (rtc != RTC_NORMAL) goto error;
5365 
5366  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5367  HECMW_free(shared_elem[i]);
5368  }
5369  HECMW_free(shared_elem);
5370  shared_elem = NULL;
5371 
5372  return RTC_NORMAL;
5373 
5374 error:
5375  if (import_node) {
5376  int i;
5377  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5378  HECMW_free(import_node[i]);
5379  }
5380  HECMW_free(import_node);
5381  }
5382  if (export_node) {
5383  int i;
5384  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5385  HECMW_free(export_node[i]);
5386  }
5387  HECMW_free(export_node);
5388  }
5389  if (shared_elem) {
5390  int i;
5391  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5392  HECMW_free(shared_elem[i]);
5393  }
5394  HECMW_free(shared_elem);
5395  }
5396 
5397  HECMW_free(local_mesh->import_index);
5398  HECMW_free(local_mesh->export_index);
5399  HECMW_free(local_mesh->shared_index);
5400  HECMW_free(local_mesh->import_item);
5401  HECMW_free(local_mesh->export_item);
5402  HECMW_free(local_mesh->shared_item);
5403 
5404  local_mesh->import_index = NULL;
5405  local_mesh->export_index = NULL;
5406  local_mesh->shared_index = NULL;
5407  local_mesh->import_item = NULL;
5408  local_mesh->export_item = NULL;
5409  local_mesh->shared_item = NULL;
5410 
5411  return RTC_ERROR;
5412 }
5413 
5414 /*------------------------------------------------------------------------------------------------*/
5415 
5416 static int create_import_info_eb(const struct hecmwST_local_mesh *global_mesh,
5417  struct hecmwST_local_mesh *local_mesh,
5418  const char *elem_flag, int **import_elem,
5419  int neighbor_idx, int neighbor_domain) {
5420  int n_import_elem, rtc;
5421 
5422  n_import_elem =
5423  count_masked_comm_elem(global_mesh, elem_flag, neighbor_domain);
5424  HECMW_assert(n_import_elem >= 0);
5425 
5426  local_mesh->import_index[neighbor_idx + 1] =
5427  local_mesh->import_index[neighbor_idx] + n_import_elem;
5428 
5429  import_elem[neighbor_idx] = (int *)HECMW_malloc(sizeof(int) * n_import_elem);
5430  if (import_elem[neighbor_idx] == NULL) {
5431  HECMW_set_error(errno, "");
5432  goto error;
5433  }
5434 
5435  rtc = create_comm_elem_pre(global_mesh, elem_flag, import_elem, neighbor_idx,
5436  neighbor_domain);
5437  HECMW_assert(rtc == n_import_elem);
5438 
5439  return RTC_NORMAL;
5440 
5441 error:
5442  return RTC_ERROR;
5443 }
5444 
5445 static int create_export_info_eb(const struct hecmwST_local_mesh *global_mesh,
5446  struct hecmwST_local_mesh *local_mesh,
5447  const char *elem_flag, int **export_elem,
5448  int neighbor_idx, int current_domain,
5449  int neighbor_domain) {
5450  int n_export_elem, rtc;
5451 
5452  n_export_elem =
5453  count_masked_comm_elem(global_mesh, elem_flag, current_domain);
5454  HECMW_assert(n_export_elem >= 0);
5455 
5456  local_mesh->export_index[neighbor_idx + 1] =
5457  local_mesh->export_index[neighbor_idx] + n_export_elem;
5458 
5459  export_elem[neighbor_idx] = (int *)HECMW_malloc(sizeof(int) * n_export_elem);
5460  if (export_elem[neighbor_idx] == NULL) {
5461  HECMW_set_error(errno, "");
5462  goto error;
5463  }
5464 
5465  rtc = create_comm_elem_pre(global_mesh, elem_flag, export_elem, neighbor_idx,
5466  current_domain);
5467  HECMW_assert(rtc == n_export_elem);
5468 
5469  return RTC_NORMAL;
5470 
5471 error:
5472  return RTC_ERROR;
5473 }
5474 
5475 static int create_shared_info_eb(const struct hecmwST_local_mesh *global_mesh,
5476  struct hecmwST_local_mesh *local_mesh,
5477  const char *node_flag, int **shared_node,
5478  int neighbor_idx, int neighbor_domain) {
5479  int n_shared_node, rtc;
5480 
5481  n_shared_node = count_masked_shared_node(global_mesh, node_flag);
5482  HECMW_assert(n_shared_node >= 0);
5483 
5484  local_mesh->shared_index[neighbor_idx + 1] =
5485  local_mesh->shared_index[neighbor_idx] + n_shared_node;
5486 
5487  shared_node[neighbor_idx] = (int *)HECMW_malloc(sizeof(int) * n_shared_node);
5488  if (shared_node[neighbor_idx] == NULL) {
5489  HECMW_set_error(errno, "");
5490  goto error;
5491  }
5492 
5493  rtc =
5494  create_shared_node_pre(global_mesh, node_flag, shared_node, neighbor_idx);
5495  HECMW_assert(rtc == n_shared_node);
5496 
5497  return RTC_NORMAL;
5498 
5499 error:
5500  return RTC_ERROR;
5501 }
5502 
5503 /*------------------------------------------------------------------------------------------------*/
5504 
5505 static int create_comm_info_eb(const struct hecmwST_local_mesh *global_mesh,
5506  struct hecmwST_local_mesh *local_mesh,
5507  char *node_flag, char *elem_flag,
5508  char *node_flag_neighbor,
5509  char *elem_flag_neighbor, int current_domain) {
5510  int **import_elem = NULL;
5511  int **export_elem = NULL;
5512  int **shared_node = NULL;
5513  int neighbor_domain;
5514  int size;
5515  int rtc;
5516  int i, j;
5517 
5518  /* allocation */
5519  local_mesh->import_index = NULL;
5520  local_mesh->export_index = NULL;
5521  local_mesh->shared_index = NULL;
5522  local_mesh->import_item = NULL;
5523  local_mesh->export_item = NULL;
5524  local_mesh->shared_item = NULL;
5525 
5526  import_elem = (int **)HECMW_malloc(sizeof(int *) * local_mesh->n_neighbor_pe);
5527  if (import_elem == NULL) {
5528  HECMW_set_error(errno, "");
5529  goto error;
5530  } else {
5531  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5532  import_elem[i] = NULL;
5533  }
5534  }
5535  export_elem = (int **)HECMW_malloc(sizeof(int *) * local_mesh->n_neighbor_pe);
5536  if (export_elem == NULL) {
5537  HECMW_set_error(errno, "");
5538  goto error;
5539  } else {
5540  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5541  export_elem[i] = NULL;
5542  }
5543  }
5544  shared_node = (int **)HECMW_malloc(sizeof(int *) * local_mesh->n_neighbor_pe);
5545  if (shared_node == NULL) {
5546  HECMW_set_error(errno, "");
5547  goto error;
5548  } else {
5549  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5550  shared_node[i] = NULL;
5551  }
5552  }
5553 
5554  local_mesh->import_index =
5555  (int *)HECMW_calloc(local_mesh->n_neighbor_pe + 1, sizeof(int));
5556  if (local_mesh->import_index == NULL) {
5557  HECMW_set_error(errno, "");
5558  goto error;
5559  }
5560  local_mesh->export_index =
5561  (int *)HECMW_calloc(local_mesh->n_neighbor_pe + 1, sizeof(int));
5562  if (local_mesh->export_index == NULL) {
5563  HECMW_set_error(errno, "");
5564  goto error;
5565  }
5566  local_mesh->shared_index =
5567  (int *)HECMW_calloc(local_mesh->n_neighbor_pe + 1, sizeof(int));
5568  if (local_mesh->shared_index == NULL) {
5569  HECMW_set_error(errno, "");
5570  goto error;
5571  }
5572 
5573  /* create communication table */
5574  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5575  neighbor_domain = local_mesh->neighbor_pe[i];
5576 
5577  for (j = 0; j < global_mesh->n_node; j++) {
5578  CLEAR_BIT(node_flag[j], MASK);
5579  CLEAR_BIT(node_flag[j], MARK);
5580  }
5581  for (j = 0; j < global_mesh->n_elem; j++) {
5582  CLEAR_BIT(elem_flag[j], MASK);
5583  CLEAR_BIT(elem_flag[j], MARK);
5584  }
5585 
5586  memset(node_flag_neighbor, 0, sizeof(char) * global_mesh->n_node);
5587  memset(elem_flag_neighbor, 0, sizeof(char) * global_mesh->n_elem);
5588 
5589  /* mask boundary node & element */
5590  rtc = mask_mesh_status_eb(global_mesh, node_flag_neighbor,
5591  elem_flag_neighbor, neighbor_domain);
5592  if (rtc != RTC_NORMAL) goto error;
5593 
5594  rtc = mask_comm_node(global_mesh, node_flag, node_flag_neighbor);
5595  if (rtc != RTC_NORMAL) goto error;
5596 
5597  rtc = mask_comm_elem(global_mesh, elem_flag, elem_flag_neighbor);
5598  if (rtc != RTC_NORMAL) goto error;
5599 
5600  /* create import element information (preliminary) */
5601  rtc = create_import_info_eb(global_mesh, local_mesh, elem_flag, import_elem,
5602  i, neighbor_domain);
5603  if (rtc != RTC_NORMAL) goto error;
5604 
5605  /* create export element information (preliminary) */
5606  rtc = create_export_info_eb(global_mesh, local_mesh, elem_flag, export_elem,
5607  i, current_domain, neighbor_domain);
5608  if (rtc != RTC_NORMAL) goto error;
5609 
5610  /* create shared node information (preliminary) */
5611  rtc = create_shared_info_eb(global_mesh, local_mesh, node_flag, shared_node,
5612  i, neighbor_domain);
5613  if (rtc != RTC_NORMAL) goto error;
5614  }
5615 
5616  /* create import element information */
5617  size = sizeof(int) * local_mesh->import_index[local_mesh->n_neighbor_pe];
5618  local_mesh->import_item = (int *)HECMW_malloc(size);
5619  if (local_mesh->import_item == NULL) {
5620  HECMW_set_error(errno, "");
5621  goto error;
5622  }
5623 
5624  rtc = create_comm_item(local_mesh->n_neighbor_pe, import_elem,
5625  local_mesh->import_index, local_mesh->import_item);
5626  if (rtc != RTC_NORMAL) goto error;
5627 
5628  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5629  HECMW_free(import_elem[i]);
5630  }
5631  HECMW_free(import_elem);
5632  import_elem = NULL;
5633 
5634  /* create export node information */
5635  size = sizeof(int) * local_mesh->export_index[local_mesh->n_neighbor_pe];
5636  local_mesh->export_item = (int *)HECMW_malloc(size);
5637  if (local_mesh->export_item == NULL) {
5638  HECMW_set_error(errno, "");
5639  goto error;
5640  }
5641 
5642  rtc = create_comm_item(local_mesh->n_neighbor_pe, export_elem,
5643  local_mesh->export_index, local_mesh->export_item);
5644  if (rtc != RTC_NORMAL) goto error;
5645 
5646  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5647  HECMW_free(export_elem[i]);
5648  }
5649  HECMW_free(export_elem);
5650  export_elem = NULL;
5651 
5652  /* create shared element information */
5653  size = sizeof(int) * local_mesh->shared_index[local_mesh->n_neighbor_pe];
5654  local_mesh->shared_item = (int *)HECMW_malloc(size);
5655  if (local_mesh->shared_item == NULL) {
5656  HECMW_set_error(errno, "");
5657  goto error;
5658  }
5659 
5660  rtc = create_comm_item(local_mesh->n_neighbor_pe, shared_node,
5661  local_mesh->shared_index, local_mesh->shared_item);
5662  if (rtc != RTC_NORMAL) goto error;
5663 
5664  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5665  HECMW_free(shared_node[i]);
5666  }
5667  HECMW_free(shared_node);
5668  shared_node = NULL;
5669 
5670  return RTC_NORMAL;
5671 
5672 error:
5673  if (import_elem) {
5674  int i;
5675  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5676  HECMW_free(import_elem[i]);
5677  }
5678  HECMW_free(import_elem);
5679  }
5680  if (export_elem) {
5681  int i;
5682  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5683  HECMW_free(export_elem[i]);
5684  }
5685  HECMW_free(export_elem);
5686  }
5687  if (shared_node) {
5688  int i;
5689  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5690  HECMW_free(shared_node[i]);
5691  }
5692  HECMW_free(shared_node);
5693  }
5694  HECMW_free(local_mesh->import_index);
5695  HECMW_free(local_mesh->export_index);
5696  HECMW_free(local_mesh->shared_index);
5697  HECMW_free(local_mesh->import_item);
5698  HECMW_free(local_mesh->export_item);
5699  HECMW_free(local_mesh->shared_item);
5700 
5701  local_mesh->import_index = NULL;
5702  local_mesh->export_index = NULL;
5703  local_mesh->shared_index = NULL;
5704  local_mesh->import_item = NULL;
5705  local_mesh->export_item = NULL;
5706  local_mesh->shared_item = NULL;
5707 
5708  return RTC_ERROR;
5709 }
5710 
5711 /*================================================================================================*/
5712 
5713 static int create_comm_info(const struct hecmwST_local_mesh *global_mesh,
5714  struct hecmwST_local_mesh *local_mesh,
5715  char *node_flag, char *elem_flag,
5716  char *node_flag_neighbor, char *elem_flag_neighbor,
5717  int current_domain) {
5718  int rtc;
5719 
5720  HECMW_assert(global_mesh);
5721  HECMW_assert(local_mesh);
5722  HECMW_assert(node_flag);
5723  HECMW_assert(elem_flag);
5724 
5725  HECMW_log(HECMW_LOG_DEBUG, "Starting creation of interface table...");
5726 
5727  switch (global_mesh->hecmw_flag_parttype) {
5728  case HECMW_FLAG_PARTTYPE_NODEBASED: /* for node-based partitioning */
5729  rtc = create_comm_info_nb(global_mesh, local_mesh, node_flag, elem_flag,
5730  node_flag_neighbor, elem_flag_neighbor,
5731  current_domain);
5732  if (rtc != RTC_NORMAL) goto error;
5733 
5734  break;
5735 
5736  case HECMW_FLAG_PARTTYPE_ELEMBASED: /* for element-based partitioning */
5737  rtc = create_comm_info_eb(global_mesh, local_mesh, node_flag, elem_flag,
5738  node_flag_neighbor, elem_flag_neighbor,
5739  current_domain);
5740  if (rtc != RTC_NORMAL) goto error;
5741 
5742  break;
5743 
5744  default:
5746  goto error;
5747  }
5748 
5749  HECMW_log(HECMW_LOG_DEBUG, "Creation of interface table done");
5750 
5751  return RTC_NORMAL;
5752 
5753 error:
5754  return RTC_ERROR;
5755 }
5756 
5757 /*==================================================================================================
5758 
5759  create distributed mesh information
5760 
5761 ==================================================================================================*/
5762 
5763 static int set_node_global2local_internal(
5764  const struct hecmwST_local_mesh *global_mesh,
5765  struct hecmwST_local_mesh *local_mesh, int *node_global2local,
5766  const char *node_flag, int domain) {
5767  int counter;
5768  int i, node;
5769 
5770  HECMW_assert(global_mesh);
5771  HECMW_assert(local_mesh);
5772  HECMW_assert(node_global2local);
5773  HECMW_assert(node_flag);
5774  HECMW_assert(global_mesh->n_node > 0);
5775 
5776  for (counter = 0, i = 0; i < n_int_nlist[domain]; i++) {
5777  node = int_nlist[domain][i];
5778  node_global2local[node - 1] = ++counter;
5779  }
5780  local_mesh->nn_internal = counter;
5781 
5782  return RTC_NORMAL;
5783 }
5784 
5785 static int set_node_global2local_external(
5786  const struct hecmwST_local_mesh *global_mesh,
5787  struct hecmwST_local_mesh *local_mesh, int *node_global2local,
5788  const char *node_flag) {
5789  int counter;
5790  int i;
5791 
5792  HECMW_assert(global_mesh);
5793  HECMW_assert(local_mesh);
5794  HECMW_assert(node_global2local);
5795  HECMW_assert(node_flag);
5796  HECMW_assert(global_mesh->n_node > 0);
5797 
5798  /* ordinary external nodes are marked as BOUNDARY && OVERLAP */
5799  for (counter = local_mesh->nn_internal, i = 0; i < global_mesh->n_node; i++) {
5800  if (!EVAL_BIT(node_flag[i], INTERNAL) && EVAL_BIT(node_flag[i], BOUNDARY) &&
5801  EVAL_BIT(node_flag[i], OVERLAP)) {
5802  node_global2local[i] = ++counter;
5803  }
5804  }
5805  local_mesh->nn_middle = counter;
5806 
5807  /* added external contact slave nodes are marked as BOUNDARY but not OVERLAP
5808  */
5809  for (i = 0; i < global_mesh->n_node; i++) {
5810  if (!EVAL_BIT(node_flag[i], INTERNAL) && EVAL_BIT(node_flag[i], BOUNDARY) &&
5811  !EVAL_BIT(node_flag[i], OVERLAP)) {
5812  node_global2local[i] = ++counter;
5813  }
5814  }
5815  local_mesh->n_node = counter;
5816  local_mesh->n_node_gross = counter;
5817 
5818  HECMW_assert(local_mesh->n_node > 0);
5819 
5820  return RTC_NORMAL;
5821 }
5822 
5823 static int set_node_global2local_external_mod(
5824  const struct hecmwST_local_mesh *global_mesh,
5825  struct hecmwST_local_mesh *local_mesh, int *node_global2local,
5826  const char *node_flag, int domain) {
5827  int counter;
5828  int i, node;
5829 
5830  HECMW_assert(global_mesh);
5831  HECMW_assert(local_mesh);
5832  HECMW_assert(node_global2local);
5833  HECMW_assert(node_flag);
5834  HECMW_assert(global_mesh->n_node > 0);
5835 
5836  for (counter = local_mesh->nn_internal, i = n_bnd_nlist[2 * domain];
5837  i < n_bnd_nlist[2 * domain + 1]; i++) {
5838  node = bnd_nlist[domain][i];
5839  node_global2local[node - 1] = ++counter;
5840  }
5841  local_mesh->n_node = counter;
5842  local_mesh->n_node_gross = counter;
5843 
5844  HECMW_assert(local_mesh->n_node > 0);
5845 
5846  return RTC_NORMAL;
5847 }
5848 
5849 static int set_node_global2local_all(
5850  const struct hecmwST_local_mesh *global_mesh,
5851  struct hecmwST_local_mesh *local_mesh, int *node_global2local,
5852  const char *node_flag) {
5853  int counter;
5854  int i;
5855 
5856  HECMW_assert(global_mesh);
5857  HECMW_assert(local_mesh);
5858  HECMW_assert(node_global2local);
5859  HECMW_assert(node_flag);
5860  HECMW_assert(global_mesh->n_node > 0);
5861 
5862  for (counter = 0, i = 0; i < global_mesh->n_node; i++) {
5863  if (EVAL_BIT(node_flag[i], INTERNAL) || EVAL_BIT(node_flag[i], BOUNDARY)) {
5864  node_global2local[i] = ++counter;
5865  }
5866  }
5867  local_mesh->n_node = counter;
5868  local_mesh->n_node_gross = counter;
5869 
5870  HECMW_assert(local_mesh->n_node > 0);
5871 
5872  return RTC_NORMAL;
5873 }
5874 
5875 static int const_nn_internal(const struct hecmwST_local_mesh *global_mesh,
5876  struct hecmwST_local_mesh *local_mesh,
5877  const char *node_flag) {
5878  int counter;
5879  int i;
5880 
5881  HECMW_assert(global_mesh);
5882  HECMW_assert(local_mesh);
5883  HECMW_assert(node_flag);
5884  HECMW_assert(global_mesh->n_node > 0);
5885 
5886  for (counter = 0, i = 0; i < global_mesh->n_node; i++) {
5887  if (EVAL_BIT(node_flag[i], INTERNAL)) counter++;
5888  }
5889  local_mesh->nn_internal = counter;
5890 
5891  return 0;
5892 }
5893 
5894 static int const_node_internal_list(
5895  const struct hecmwST_local_mesh *global_mesh,
5896  struct hecmwST_local_mesh *local_mesh, int *node_global2local,
5897  const char *node_flag) {
5898  int counter;
5899  int i;
5900 
5901  HECMW_assert(global_mesh);
5902  HECMW_assert(local_mesh);
5903  HECMW_assert(node_global2local);
5904  HECMW_assert(node_flag);
5905  HECMW_assert(global_mesh->n_node > 0);
5906 
5907  if (local_mesh->nn_internal == 0) {
5908  local_mesh->node_internal_list = NULL;
5909  return RTC_NORMAL;
5910  }
5911 
5912  local_mesh->node_internal_list =
5913  (int *)HECMW_malloc(sizeof(int) * local_mesh->nn_internal);
5914  if (local_mesh->node_internal_list == NULL) {
5915  HECMW_set_error(errno, "");
5916  goto error;
5917  }
5918 
5919  for (counter = 0, i = 0; i < global_mesh->n_node; i++) {
5920  if (EVAL_BIT(node_flag[i], INTERNAL)) {
5921  local_mesh->node_internal_list[counter++] = node_global2local[i];
5922  }
5923  }
5924  HECMW_assert(counter == local_mesh->nn_internal);
5925 
5926  return RTC_NORMAL;
5927 
5928 error:
5929  return RTC_ERROR;
5930 }
5931 
5932 static int set_node_global2local(const struct hecmwST_local_mesh *global_mesh,
5933  struct hecmwST_local_mesh *local_mesh,
5934  int *node_global2local, const char *node_flag,
5935  int current_domain) {
5936  int rtc;
5937 
5938  HECMW_assert(global_mesh);
5939  HECMW_assert(local_mesh);
5940  HECMW_assert(node_global2local);
5941  HECMW_assert(node_flag);
5942 
5943  switch (global_mesh->hecmw_flag_parttype) {
5945 
5946  rtc = set_node_global2local_internal(global_mesh, local_mesh,
5947  node_global2local, node_flag,
5948  current_domain);
5949  if (rtc != RTC_NORMAL) goto error;
5950 
5951  if (is_spdup_available(global_mesh)) {
5952  rtc = set_node_global2local_external_mod(global_mesh, local_mesh,
5953  node_global2local, node_flag,
5954  current_domain);
5955  } else {
5956  rtc = set_node_global2local_external(global_mesh, local_mesh,
5957  node_global2local, node_flag);
5958  }
5959 
5960  if (rtc != RTC_NORMAL) goto error;
5961 
5962  local_mesh->node_internal_list = NULL;
5963 
5964  break;
5965 
5967 
5968  rtc = const_nn_internal(global_mesh, local_mesh, node_flag);
5969  if (rtc != RTC_NORMAL) goto error;
5970 
5971  rtc = set_node_global2local_all(global_mesh, local_mesh,
5972  node_global2local, node_flag);
5973  if (rtc != RTC_NORMAL) goto error;
5974 
5975  rtc = const_node_internal_list(global_mesh, local_mesh, node_global2local,
5976  node_flag);
5977  if (rtc != RTC_NORMAL) goto error;
5978 
5979  break;
5980 
5981  default:
5983  global_mesh->hecmw_flag_parttype);
5984  goto error;
5985  }
5986 
5987  return RTC_NORMAL;
5988 
5989 error:
5990  return RTC_ERROR;
5991 }
5992 
5993 static int clear_node_global2local(const struct hecmwST_local_mesh *global_mesh,
5994  struct hecmwST_local_mesh *local_mesh,
5995  int *node_global2local, int domain) {
5996  int i, node;
5997 
5998  HECMW_assert(global_mesh);
5999  HECMW_assert(local_mesh);
6000  HECMW_assert(node_global2local);
6001 
6002  if (is_spdup_available(global_mesh)) {
6003  for (i = 0; i < n_int_nlist[domain]; i++) {
6004  node = int_nlist[domain][i];
6005  node_global2local[node - 1] = 0;
6006  }
6007  for (i = n_bnd_nlist[2 * domain]; i < n_bnd_nlist[2 * domain + 1]; i++) {
6008  node = bnd_nlist[domain][i];
6009  node_global2local[node - 1] = 0;
6010  }
6011  } else {
6012  for (i = 0; i < global_mesh->n_node; i++) {
6013  node_global2local[i] = 0;
6014  }
6015  }
6016 
6017  return RTC_NORMAL;
6018 }
6019 
6020 /*------------------------------------------------------------------------------------------------*/
6021 
6022 static int set_node_local2global(const struct hecmwST_local_mesh *global_mesh,
6023  struct hecmwST_local_mesh *local_mesh,
6024  const int *node_global2local,
6025  int *node_local2global) {
6026  int counter;
6027  int i;
6028 
6029  HECMW_assert(global_mesh);
6030  HECMW_assert(local_mesh);
6031  HECMW_assert(node_global2local);
6032  HECMW_assert(node_local2global);
6033  HECMW_assert(global_mesh->n_node > 0);
6034 
6035  for (counter = 0, i = 0; i < global_mesh->n_node; i++) {
6036  if (node_global2local[i]) {
6037  node_local2global[node_global2local[i] - 1] = i + 1;
6038  counter++;
6039  }
6040  }
6041  HECMW_assert(counter == local_mesh->n_node);
6042 
6043  return RTC_NORMAL;
6044 }
6045 
6046 static int set_node_local2global_mod(
6047  const struct hecmwST_local_mesh *global_mesh,
6048  struct hecmwST_local_mesh *local_mesh, const int *node_global2local,
6049  int *node_local2global, int domain) {
6050  int counter;
6051  int i, idx1, idx2, node1, node2, n_int, n_bnd, n_out, maxn;
6052 
6053  HECMW_assert(global_mesh);
6054  HECMW_assert(local_mesh);
6055  HECMW_assert(node_global2local);
6056  HECMW_assert(node_local2global);
6057  HECMW_assert(global_mesh->n_node > 0);
6058 
6059  n_int = n_int_nlist[domain];
6060  n_bnd = n_bnd_nlist[2 * domain];
6061  n_out = n_bnd_nlist[2 * domain + 1] - n_bnd_nlist[2 * domain];
6062  maxn = global_mesh->n_node + 1;
6063 
6064  node1 = (n_int == 0) ? maxn : int_nlist[domain][0];
6065  node2 = (n_out == 0) ? maxn : bnd_nlist[domain][n_bnd];
6066  for (counter = 0, idx1 = 0, idx2 = 0, i = 0; i < n_int + n_out; i++) {
6067  if (node1 < node2) {
6068  node_local2global[node_global2local[node1 - 1] - 1] = node1;
6069  idx1++;
6070  node1 = (idx1 == n_int) ? maxn : int_nlist[domain][idx1];
6071  } else {
6072  node_local2global[node_global2local[node2 - 1] - 1] = node2;
6073  idx2++;
6074  node2 = (idx2 == n_out) ? maxn : bnd_nlist[domain][idx2 + n_bnd];
6075  }
6076  counter++;
6077  }
6078 
6079  HECMW_assert(counter == local_mesh->n_node);
6080 
6081  return RTC_NORMAL;
6082 }
6083 
6084 /*------------------------------------------------------------------------------------------------*/
6085 
6086 static int set_elem_global2local_internal(
6087  const struct hecmwST_local_mesh *global_mesh,
6088  struct hecmwST_local_mesh *local_mesh, int *elem_global2local,
6089  const char *elem_flag) {
6090  int counter;
6091  int i;
6092 
6093  HECMW_assert(global_mesh);
6094  HECMW_assert(local_mesh);
6095  HECMW_assert(elem_global2local);
6096  HECMW_assert(elem_flag);
6097  HECMW_assert(global_mesh->n_elem);
6098 
6099  for (counter = 0, i = 0; i < global_mesh->n_elem; i++) {
6100  if (EVAL_BIT(elem_flag[i], INTERNAL)) {
6101  elem_global2local[i] = ++counter;
6102  }
6103  }
6104  local_mesh->ne_internal = counter;
6105 
6106  return RTC_NORMAL;
6107 }
6108 
6109 static int set_elem_global2local_external(
6110  const struct hecmwST_local_mesh *global_mesh,
6111  struct hecmwST_local_mesh *local_mesh, int *elem_global2local,
6112  const char *elem_flag) {
6113  int counter;
6114  int i;
6115 
6116  HECMW_assert(global_mesh);
6117  HECMW_assert(local_mesh);
6118  HECMW_assert(elem_global2local);
6119  HECMW_assert(elem_flag);
6120  HECMW_assert(global_mesh->n_elem);
6121 
6122  for (counter = local_mesh->ne_internal, i = 0; i < global_mesh->n_elem; i++) {
6123  if (!EVAL_BIT(elem_flag[i], INTERNAL) && EVAL_BIT(elem_flag[i], BOUNDARY)) {
6124  elem_global2local[i] = ++counter;
6125  }
6126  }
6127  local_mesh->n_elem = counter;
6128  local_mesh->n_elem_gross = counter;
6129 
6130  HECMW_assert(local_mesh->n_elem > 0);
6131 
6132  return RTC_NORMAL;
6133 }
6134 
6135 static int set_elem_global2local_all(
6136  const struct hecmwST_local_mesh *global_mesh,
6137  struct hecmwST_local_mesh *local_mesh, int *elem_global2local,
6138  const char *elem_flag) {
6139  int counter;
6140  int i;
6141 
6142  HECMW_assert(global_mesh);
6143  HECMW_assert(local_mesh);
6144  HECMW_assert(elem_global2local);
6145  HECMW_assert(elem_flag);
6146  HECMW_assert(global_mesh->n_elem > 0);
6147 
6148  for (counter = 0, i = 0; i < global_mesh->n_elem; i++) {
6149  if (EVAL_BIT(elem_flag[i], INTERNAL) || EVAL_BIT(elem_flag[i], BOUNDARY)) {
6150  elem_global2local[i] = ++counter;
6151  }
6152  }
6153  local_mesh->n_elem = counter;
6154  local_mesh->n_elem_gross = counter;
6155 
6156  HECMW_assert(local_mesh->n_elem > 0);
6157 
6158  return RTC_NORMAL;
6159 }
6160 
6161 static int set_elem_global2local_all_mod(
6162  const struct hecmwST_local_mesh *global_mesh,
6163  struct hecmwST_local_mesh *local_mesh, int *elem_global2local,
6164  const char *elem_flag, int domain) {
6165  int counter;
6166  int i, idx1, idx2, elem1, elem2, n_int, n_bnd, n_out, maxe;
6167 
6168  HECMW_assert(global_mesh);
6169  HECMW_assert(local_mesh);
6170  HECMW_assert(elem_global2local);
6171  HECMW_assert(elem_flag);
6172  HECMW_assert(global_mesh->n_elem > 0);
6173 
6174  n_int = n_int_elist[domain];
6175  n_bnd = n_bnd_elist[2 * domain];
6176  n_out = n_bnd_elist[2 * domain + 1] - n_bnd_elist[2 * domain];
6177  maxe = global_mesh->n_elem + 1;
6178 
6179  elem1 = (n_int == 0) ? maxe : int_elist[domain][0];
6180  elem2 = (n_out == 0) ? maxe : bnd_elist[domain][n_bnd];
6181  for (counter = 0, idx1 = 0, idx2 = 0, i = 0; i < n_int + n_out; i++) {
6182  if (elem1 < elem2) {
6183  elem_global2local[elem1 - 1] = ++counter;
6184  idx1++;
6185  elem1 = (idx1 == n_int) ? maxe : int_elist[domain][idx1];
6186  } else {
6187  elem_global2local[elem2 - 1] = ++counter;
6188  idx2++;
6189  elem2 = (idx2 == n_out) ? maxe : bnd_elist[domain][idx2 + n_bnd];
6190  }
6191  }
6192 
6193  local_mesh->n_elem = counter;
6194  local_mesh->n_elem_gross = counter;
6195 
6196  HECMW_assert(local_mesh->n_elem > 0);
6197 
6198  return RTC_NORMAL;
6199 }
6200 
6201 static int const_ne_internal(const struct hecmwST_local_mesh *global_mesh,
6202  struct hecmwST_local_mesh *local_mesh,
6203  const char *elem_flag) {
6204  int counter;
6205  int i;
6206 
6207  HECMW_assert(global_mesh->n_elem > 0);
6208 
6209  for (counter = 0, i = 0; i < global_mesh->n_elem; i++) {
6210  if (EVAL_BIT(elem_flag[i], INTERNAL)) counter++;
6211  }
6212  local_mesh->ne_internal = counter;
6213 
6214  return RTC_NORMAL;
6215 }
6216 
6217 static int const_elem_internal_list(
6218  const struct hecmwST_local_mesh *global_mesh,
6219  struct hecmwST_local_mesh *local_mesh, int *elem_global2local,
6220  const char *elem_flag, int domain) {
6221  int counter;
6222  int i, elem;
6223 
6224  HECMW_assert(global_mesh);
6225  HECMW_assert(local_mesh);
6226  HECMW_assert(elem_global2local);
6227  HECMW_assert(elem_flag);
6228  HECMW_assert(global_mesh->n_elem > 0);
6229 
6230  if (local_mesh->ne_internal == 0) {
6231  local_mesh->elem_internal_list = NULL;
6232  return RTC_NORMAL;
6233  }
6234 
6235  local_mesh->elem_internal_list =
6236  (int *)HECMW_malloc(sizeof(int) * local_mesh->ne_internal);
6237  if (local_mesh->elem_internal_list == NULL) {
6238  HECMW_set_error(errno, "");
6239  goto error;
6240  }
6241 
6242  for (counter = 0, i = 0; i < n_int_elist[domain]; i++) {
6243  elem = int_elist[domain][i];
6244  local_mesh->elem_internal_list[counter++] = elem_global2local[elem - 1];
6245  }
6246 
6247  HECMW_assert(counter == local_mesh->ne_internal);
6248 
6249  return RTC_NORMAL;
6250 
6251 error:
6252  return RTC_ERROR;
6253 }
6254 
6255 static int set_elem_global2local(const struct hecmwST_local_mesh *global_mesh,
6256  struct hecmwST_local_mesh *local_mesh,
6257  int *elem_global2local, const char *elem_flag,
6258  int current_domain) {
6259  int rtc;
6260 
6261  HECMW_assert(global_mesh);
6262  HECMW_assert(local_mesh);
6263  HECMW_assert(elem_global2local);
6264  HECMW_assert(elem_flag);
6265 
6266  switch (global_mesh->hecmw_flag_parttype) {
6267  case HECMW_FLAG_PARTTYPE_NODEBASED: /* for node-based partitioning */
6268 
6269  local_mesh->ne_internal = n_int_elist[current_domain];
6270 
6271  if (is_spdup_available(global_mesh)) {
6272  rtc = set_elem_global2local_all_mod(global_mesh, local_mesh,
6273  elem_global2local, elem_flag,
6274  current_domain);
6275  } else {
6276  rtc = set_elem_global2local_all(global_mesh, local_mesh,
6277  elem_global2local, elem_flag);
6278  }
6279 
6280  if (rtc != RTC_NORMAL) goto error;
6281 
6282  rtc = const_elem_internal_list(global_mesh, local_mesh, elem_global2local,
6283  elem_flag, current_domain);
6284 
6285  if (rtc != RTC_NORMAL) goto error;
6286 
6287  break;
6288 
6289  case HECMW_FLAG_PARTTYPE_ELEMBASED: /* for element-based partitioning */
6290 
6291  rtc = set_elem_global2local_internal(global_mesh, local_mesh,
6292  elem_global2local, elem_flag);
6293  if (rtc != RTC_NORMAL) goto error;
6294 
6295  rtc = set_elem_global2local_external(global_mesh, local_mesh,
6296  elem_global2local, elem_flag);
6297  if (rtc != RTC_NORMAL) goto error;
6298 
6299  local_mesh->elem_internal_list = NULL;
6300 
6301  break;
6302 
6303  default:
6305  global_mesh->hecmw_flag_parttype);
6306  goto error;
6307  }
6308 
6309  return RTC_NORMAL;
6310 
6311 error:
6312  return RTC_ERROR;
6313 }
6314 
6315 static int clear_elem_global2local(const struct hecmwST_local_mesh *global_mesh,
6316  struct hecmwST_local_mesh *local_mesh,
6317  int *elem_global2local, int domain) {
6318  int i, elem;
6319 
6320  HECMW_assert(global_mesh);
6321  HECMW_assert(local_mesh);
6322  HECMW_assert(elem_global2local);
6323 
6324  if (is_spdup_available(global_mesh)) {
6325  for (i = 0; i < n_int_elist[domain]; i++) {
6326  elem = int_elist[domain][i];
6327  elem_global2local[elem - 1] = 0;
6328  }
6329  for (i = n_bnd_elist[2 * domain]; i < n_bnd_elist[2 * domain + 1]; i++) {
6330  elem = bnd_elist[domain][i];
6331  elem_global2local[elem - 1] = 0;
6332  }
6333 
6334  } else {
6335  for (i = 0; i < global_mesh->n_elem; i++) {
6336  elem_global2local[i] = 0;
6337  }
6338  }
6339 
6340  return RTC_NORMAL;
6341 }
6342 
6343 /*------------------------------------------------------------------------------------------------*/
6344 
6345 static int set_elem_local2global(const struct hecmwST_local_mesh *global_mesh,
6346  struct hecmwST_local_mesh *local_mesh,
6347  const int *elem_global2local,
6348  int *elem_local2global) {
6349  int counter;
6350  int i;
6351 
6352  HECMW_assert(global_mesh);
6353  HECMW_assert(local_mesh);
6354  HECMW_assert(elem_global2local);
6355  HECMW_assert(elem_local2global);
6356  HECMW_assert(global_mesh->n_elem > 0);
6357 
6358  for (counter = 0, i = 0; i < global_mesh->n_elem; i++) {
6359  if (elem_global2local[i]) {
6360  elem_local2global[elem_global2local[i] - 1] = i + 1;
6361  counter++;
6362  }
6363  }
6364  HECMW_assert(counter == local_mesh->n_elem);
6365 
6366  return RTC_NORMAL;
6367 }
6368 
6369 static int set_elem_local2global_mod(
6370  const struct hecmwST_local_mesh *global_mesh,
6371  struct hecmwST_local_mesh *local_mesh, const int *elem_global2local,
6372  int *elem_local2global, int domain) {
6373  int counter;
6374  int i, idx1, idx2, elem1, elem2, n_int, n_bnd, n_out, maxe;
6375 
6376  HECMW_assert(global_mesh);
6377  HECMW_assert(local_mesh);
6378  HECMW_assert(elem_global2local);
6379  HECMW_assert(elem_local2global);
6380  HECMW_assert(global_mesh->n_elem > 0);
6381 
6382  n_int = n_int_elist[domain];
6383  n_bnd = n_bnd_elist[2 * domain];
6384  n_out = n_bnd_elist[2 * domain + 1] - n_bnd_elist[2 * domain];
6385  maxe = global_mesh->n_elem + 1;
6386 
6387  elem1 = (n_int == 0) ? maxe : int_elist[domain][0];
6388  elem2 = (n_out == 0) ? maxe : bnd_elist[domain][n_bnd];
6389  for (counter = 0, idx1 = 0, idx2 = 0, i = 0; i < n_int + n_out; i++) {
6390  if (elem1 < elem2) {
6391  elem_local2global[elem_global2local[elem1 - 1] - 1] = elem1;
6392  idx1++;
6393  elem1 = (idx1 == n_int) ? maxe : int_elist[domain][idx1];
6394  } else {
6395  elem_local2global[elem_global2local[elem2 - 1] - 1] = elem2;
6396  idx2++;
6397  elem2 = (idx2 == n_out) ? maxe : bnd_elist[domain][idx2 + n_bnd];
6398  }
6399  counter++;
6400  }
6401 
6402  HECMW_assert(counter == local_mesh->n_elem);
6403 
6404  return RTC_NORMAL;
6405 }
6406 
6407 /*================================================================================================*/
6408 
6409 static int const_gridfile(const struct hecmwST_local_mesh *global_mesh,
6410  struct hecmwST_local_mesh *local_mesh) {
6411  snprintf(local_mesh->gridfile, sizeof(local_mesh->gridfile), "%s",
6412  global_mesh->gridfile);
6413 
6414  return RTC_NORMAL;
6415 }
6416 
6417 static int const_hecmw_n_file(const struct hecmwST_local_mesh *global_mesh,
6418  struct hecmwST_local_mesh *local_mesh) {
6419  local_mesh->hecmw_n_file = global_mesh->hecmw_n_file;
6420 
6421  return RTC_NORMAL;
6422 }
6423 
6424 static int const_files(const struct hecmwST_local_mesh *global_mesh,
6425  struct hecmwST_local_mesh *local_mesh) {
6426  local_mesh->files = global_mesh->files;
6427 
6428  return RTC_NORMAL;
6429 }
6430 
6431 static int const_header(const struct hecmwST_local_mesh *global_mesh,
6432  struct hecmwST_local_mesh *local_mesh) {
6433  snprintf(local_mesh->header, sizeof(local_mesh->header), "%s",
6434  global_mesh->header);
6435 
6436  return RTC_NORMAL;
6437 }
6438 
6439 static int const_hecmw_flag_adapt(const struct hecmwST_local_mesh *global_mesh,
6440  struct hecmwST_local_mesh *local_mesh) {
6441  local_mesh->hecmw_flag_adapt = global_mesh->hecmw_flag_adapt;
6442 
6443  return RTC_NORMAL;
6444 }
6445 
6446 static int const_hecmw_flag_initcon(
6447  const struct hecmwST_local_mesh *global_mesh,
6448  struct hecmwST_local_mesh *local_mesh) {
6449  local_mesh->hecmw_flag_initcon = global_mesh->hecmw_flag_initcon;
6450 
6451  return RTC_NORMAL;
6452 }
6453 
6454 static int const_hecmw_flag_parttype(
6455  const struct hecmwST_local_mesh *global_mesh,
6456  struct hecmwST_local_mesh *local_mesh) {
6457  local_mesh->hecmw_flag_parttype = global_mesh->hecmw_flag_parttype;
6458 
6459  return RTC_NORMAL;
6460 }
6461 
6462 static int const_hecmw_flag_partdepth(
6463  const struct hecmwST_local_mesh *global_mesh,
6464  struct hecmwST_local_mesh *local_mesh) {
6465  local_mesh->hecmw_flag_partdepth = global_mesh->hecmw_flag_partdepth;
6466 
6467  return RTC_NORMAL;
6468 }
6469 
6470 static int const_hecmw_flag_version(
6471  const struct hecmwST_local_mesh *global_mesh,
6472  struct hecmwST_local_mesh *local_mesh) {
6473  local_mesh->hecmw_flag_version = global_mesh->hecmw_flag_version;
6474 
6475  return RTC_NORMAL;
6476 }
6477 
6478 static int const_hecmw_flag_partcontact(
6479  const struct hecmwST_local_mesh *global_mesh,
6480  struct hecmwST_local_mesh *local_mesh) {
6481  local_mesh->hecmw_flag_partcontact = global_mesh->hecmw_flag_partcontact;
6482 
6483  return RTC_NORMAL;
6484 }
6485 
6486 static int const_zero_temp(const struct hecmwST_local_mesh *global_mesh,
6487  struct hecmwST_local_mesh *local_mesh) {
6488  local_mesh->zero_temp = global_mesh->zero_temp;
6489 
6490  return RTC_NORMAL;
6491 }
6492 
6493 static int const_global_info(const struct hecmwST_local_mesh *global_mesh,
6494  struct hecmwST_local_mesh *local_mesh) {
6495  int rtc;
6496 
6497  HECMW_assert(global_mesh);
6498  HECMW_assert(local_mesh);
6499 
6500  rtc = const_gridfile(global_mesh, local_mesh);
6501  if (rtc != RTC_NORMAL) goto error;
6502 
6503  rtc = const_hecmw_n_file(global_mesh, local_mesh);
6504  if (rtc != RTC_NORMAL) goto error;
6505 
6506  rtc = const_files(global_mesh, local_mesh);
6507  if (rtc != RTC_NORMAL) goto error;
6508 
6509  rtc = const_header(global_mesh, local_mesh);
6510  if (rtc != RTC_NORMAL) goto error;
6511 
6512  rtc = const_hecmw_flag_adapt(global_mesh, local_mesh);
6513  if (rtc != RTC_NORMAL) goto error;
6514 
6515  rtc = const_hecmw_flag_initcon(global_mesh, local_mesh);
6516  if (rtc != RTC_NORMAL) goto error;
6517 
6518  rtc = const_hecmw_flag_parttype(global_mesh, local_mesh);
6519  if (rtc != RTC_NORMAL) goto error;
6520 
6521  rtc = const_hecmw_flag_partdepth(global_mesh, local_mesh);
6522  if (rtc != RTC_NORMAL) goto error;
6523 
6524  rtc = const_hecmw_flag_version(global_mesh, local_mesh);
6525  if (rtc != RTC_NORMAL) goto error;
6526 
6527  rtc = const_hecmw_flag_partcontact(global_mesh, local_mesh);
6528  if (rtc != RTC_NORMAL) goto error;
6529 
6530  rtc = const_zero_temp(global_mesh, local_mesh);
6531  if (rtc != RTC_NORMAL) goto error;
6532 
6533  return RTC_NORMAL;
6534 
6535 error:
6536  return RTC_ERROR;
6537 }
6538 
6539 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6540  * - - - - - - - - - */
6541 
6542 static int const_n_dof(const struct hecmwST_local_mesh *global_mesh,
6543  struct hecmwST_local_mesh *local_mesh) {
6544  HECMW_assert(global_mesh->n_dof > 0);
6545 
6546  local_mesh->n_dof = global_mesh->n_dof;
6547 
6548  HECMW_assert(local_mesh->n_dof > 0);
6549 
6550  return RTC_NORMAL;
6551 }
6552 
6553 static int const_n_dof_grp(const struct hecmwST_local_mesh *global_mesh,
6554  struct hecmwST_local_mesh *local_mesh) {
6555  HECMW_assert(global_mesh->n_dof_grp);
6556 
6557  local_mesh->n_dof_grp = global_mesh->n_dof_grp;
6558 
6559  HECMW_assert(global_mesh->n_dof_grp);
6560 
6561  return RTC_NORMAL;
6562 }
6563 
6564 static int const_node_dof_index(const struct hecmwST_local_mesh *global_mesh,
6565  struct hecmwST_local_mesh *local_mesh,
6566  const char *node_flag) {
6567  int counter;
6568  int i, j;
6569 
6570  HECMW_assert(local_mesh->n_dof_grp > 0);
6571  HECMW_assert(global_mesh->node_dof_index);
6572 
6573  local_mesh->node_dof_index =
6574  (int *)HECMW_calloc(local_mesh->n_dof_grp + 1, sizeof(int));
6575  if (local_mesh->node_dof_index == NULL) {
6576  HECMW_set_error(errno, "");
6577  goto error;
6578  }
6579 
6580  for (counter = 0, i = 0; i < global_mesh->n_dof_grp; i++) {
6581  for (j = global_mesh->node_dof_index[i];
6582  j < global_mesh->node_dof_index[i + 1]; j++) {
6583  if (EVAL_BIT(node_flag[j], INTERNAL)) counter++;
6584  }
6585  local_mesh->node_dof_index[i + 1] = counter;
6586  }
6587  HECMW_assert(local_mesh->node_dof_index[local_mesh->n_dof_grp] ==
6588  local_mesh->nn_internal);
6589 
6590  return RTC_NORMAL;
6591 
6592 error:
6593  return RTC_ERROR;
6594 }
6595 
6596 static int const_node_dof_index_mod(
6597  const struct hecmwST_local_mesh *global_mesh,
6598  struct hecmwST_local_mesh *local_mesh, const char *node_flag, int domain) {
6599  int counter;
6600  int i, j, node;
6601 
6602  HECMW_assert(local_mesh->n_dof_grp > 0);
6603  HECMW_assert(global_mesh->node_dof_index);
6604 
6605  local_mesh->node_dof_index =
6606  (int *)HECMW_calloc(local_mesh->n_dof_grp + 1, sizeof(int));
6607  if (local_mesh->node_dof_index == NULL) {
6608  HECMW_set_error(errno, "");
6609  goto error;
6610  }
6611 
6612  for (counter = 0, i = 0; i < global_mesh->n_dof_grp; i++) {
6613  for (j = 0; j < n_int_nlist[domain]; j++) {
6614  node = int_nlist[domain][j];
6615  if (node <= global_mesh->node_dof_index[i]) continue;
6616  if (node > global_mesh->node_dof_index[i + 1]) continue;
6617  counter++;
6618  }
6619  local_mesh->node_dof_index[i + 1] = counter;
6620  }
6621 
6622  return RTC_NORMAL;
6623 
6624 error:
6625  return RTC_ERROR;
6626 }
6627 
6628 static int const_node_dof_item(const struct hecmwST_local_mesh *global_mesh,
6629  struct hecmwST_local_mesh *local_mesh) {
6630  HECMW_assert(global_mesh->node_dof_item);
6631 
6632  local_mesh->node_dof_item = global_mesh->node_dof_item;
6633 
6634  return 0;
6635 }
6636 
6637 static int const_node(const struct hecmwST_local_mesh *global_mesh,
6638  struct hecmwST_local_mesh *local_mesh,
6639  const int *node_local2global) {
6640  int i;
6641 
6642  HECMW_assert(local_mesh->n_node > 0);
6643  HECMW_assert(global_mesh->node);
6644 
6645  local_mesh->node =
6646  (double *)HECMW_malloc(sizeof(double) * local_mesh->n_node * 3);
6647  if (local_mesh->node == NULL) {
6648  HECMW_set_error(errno, "");
6649  goto error;
6650  }
6651 
6652  for (i = 0; i < local_mesh->n_node; i++) {
6653  local_mesh->node[3 * i] = global_mesh->node[3 * (node_local2global[i] - 1)];
6654  local_mesh->node[3 * i + 1] =
6655  global_mesh->node[3 * (node_local2global[i] - 1) + 1];
6656  local_mesh->node[3 * i + 2] =
6657  global_mesh->node[3 * (node_local2global[i] - 1) + 2];
6658  }
6659 
6660  return RTC_NORMAL;
6661 
6662 error:
6663  return RTC_ERROR;
6664 }
6665 
6666 static int const_node_id(const struct hecmwST_local_mesh *global_mesh,
6667  struct hecmwST_local_mesh *local_mesh,
6668  const int *node_local2global) {
6669  int i;
6670 
6671  HECMW_assert(local_mesh->n_node > 0);
6672  HECMW_assert(global_mesh->node_ID);
6673 
6674  local_mesh->node_ID =
6675  (int *)HECMW_malloc(sizeof(int) * (size_t)local_mesh->n_node * 2);
6676  if (local_mesh->node_ID == NULL) {
6677  HECMW_set_error(errno, "");
6678  goto error;
6679  }
6680 
6681  for (i = 0; i < local_mesh->n_node; i++) {
6682  local_mesh->node_ID[2 * i] =
6683  global_mesh->node_ID[2 * (node_local2global[i] - 1)];
6684  local_mesh->node_ID[2 * i + 1] =
6685  global_mesh->node_ID[2 * (node_local2global[i] - 1) + 1];
6686  }
6687 
6688  return RTC_NORMAL;
6689 
6690 error:
6691  return RTC_ERROR;
6692 }
6693 
6694 static int const_global_node_id(const struct hecmwST_local_mesh *global_mesh,
6695  struct hecmwST_local_mesh *local_mesh,
6696  const int *node_local2global) {
6697  int i;
6698 
6699  HECMW_assert(local_mesh->n_node > 0);
6700  HECMW_assert(global_mesh->global_node_ID);
6701 
6702  local_mesh->global_node_ID =
6703  (int *)HECMW_malloc(sizeof(int) * local_mesh->n_node);
6704  if (local_mesh->global_node_ID == NULL) {
6705  HECMW_set_error(errno, "");
6706  goto error;
6707  }
6708 
6709  for (i = 0; i < local_mesh->n_node; i++) {
6710  local_mesh->global_node_ID[i] =
6711  global_mesh->global_node_ID[node_local2global[i] - 1];
6712  }
6713 
6714  return RTC_NORMAL;
6715 
6716 error:
6717  return RTC_ERROR;
6718 }
6719 
6720 static int const_node_init_val_index(
6721  const struct hecmwST_local_mesh *global_mesh,
6722  struct hecmwST_local_mesh *local_mesh, const int *node_local2global) {
6723  int old_idx;
6724  int i;
6725 
6726  HECMW_assert(local_mesh->hecmw_flag_initcon);
6727  HECMW_assert(local_mesh->n_node > 0);
6728  HECMW_assert(global_mesh->node_init_val_index);
6729 
6730  local_mesh->node_init_val_index =
6731  (int *)HECMW_calloc(local_mesh->n_node + 1, sizeof(int));
6732  if (local_mesh->node_init_val_index == NULL) {
6733  HECMW_set_error(errno, "");
6734  goto error;
6735  }
6736 
6737  for (i = 0; i < local_mesh->n_node; i++) {
6738  old_idx = node_local2global[i] - 1;
6739 
6740  local_mesh->node_init_val_index[i + 1] =
6741  local_mesh->node_init_val_index[i] +
6742  global_mesh->node_init_val_index[old_idx + 1] -
6743  global_mesh->node_init_val_index[old_idx];
6744  }
6745 
6746  return RTC_NORMAL;
6747 
6748 error:
6749  return RTC_ERROR;
6750 }
6751 
6752 static int const_node_init_val_item(
6753  const struct hecmwST_local_mesh *global_mesh,
6754  struct hecmwST_local_mesh *local_mesh, const int *node_local2global) {
6755  int size;
6756  int counter;
6757  int i, j, gstart, gend, lstart, lend;
6758 
6759  HECMW_assert(local_mesh->hecmw_flag_initcon);
6760  HECMW_assert(local_mesh->n_node > 0);
6761  HECMW_assert(local_mesh->node_init_val_index);
6762  HECMW_assert(global_mesh->node_init_val_item);
6763 
6764  if (local_mesh->node_init_val_index[local_mesh->n_node] == 0) {
6765  local_mesh->node_init_val_item = NULL;
6766  return 0;
6767  }
6768 
6769  size = sizeof(double) * local_mesh->node_init_val_index[local_mesh->n_node];
6770  local_mesh->node_init_val_item = (double *)HECMW_malloc(size);
6771  if (local_mesh->node_init_val_item == NULL) {
6772  HECMW_set_error(errno, "");
6773  goto error;
6774  }
6775 
6776  for (counter = 0, i = 0; i < local_mesh->n_node; i++) {
6777  gstart = global_mesh->node_init_val_index[node_local2global[i] - 1];
6778  gend = global_mesh->node_init_val_index[node_local2global[i]];
6779  lstart = local_mesh->node_init_val_index[i];
6780  lend = local_mesh->node_init_val_index[i + 1];
6781 
6782  HECMW_assert(gend - gstart == lend - lstart);
6783 
6784  for (j = 0; j < lend - lstart; j++) {
6785  local_mesh->node_init_val_item[lstart + j] =
6786  global_mesh->node_init_val_item[gstart + j];
6787  counter++;
6788  }
6789  HECMW_assert(counter == local_mesh->node_init_val_index[i + 1]);
6790  }
6791 
6792  return RTC_NORMAL;
6793 
6794 error:
6795  return RTC_ERROR;
6796 }
6797 
6798 static int const_node_info(const struct hecmwST_local_mesh *global_mesh,
6799  struct hecmwST_local_mesh *local_mesh,
6800  const int *node_local2global, const char *node_flag,
6801  int current_domain) {
6802  int rtc;
6803 
6804  HECMW_assert(global_mesh);
6805  HECMW_assert(local_mesh);
6806  HECMW_assert(node_local2global);
6807  HECMW_assert(node_flag);
6808 
6809  rtc = const_n_dof(global_mesh, local_mesh);
6810  if (rtc != RTC_NORMAL) goto error;
6811 
6812  rtc = const_n_dof_grp(global_mesh, local_mesh);
6813  if (rtc != RTC_NORMAL) goto error;
6814 
6815  switch (global_mesh->hecmw_flag_parttype) {
6817  rtc = const_node_dof_index_mod(global_mesh, local_mesh, node_flag,
6818  current_domain);
6819  break;
6821  rtc = const_node_dof_index(global_mesh, local_mesh, node_flag);
6822  break;
6823  default:
6824  HECMW_set_error(errno, "");
6825  goto error;
6826  }
6827 
6828  if (rtc != RTC_NORMAL) goto error;
6829 
6830  rtc = const_node_dof_item(global_mesh, local_mesh);
6831  if (rtc != RTC_NORMAL) goto error;
6832 
6833  rtc = const_node(global_mesh, local_mesh, node_local2global);
6834  if (rtc != RTC_NORMAL) goto error;
6835 
6836  rtc = const_node_id(global_mesh, local_mesh, node_local2global);
6837  if (rtc != RTC_NORMAL) goto error;
6838 
6839  rtc = const_global_node_id(global_mesh, local_mesh, node_local2global);
6840  if (rtc != RTC_NORMAL) goto error;
6841 
6842  if (local_mesh->hecmw_flag_initcon) {
6843  rtc = const_node_init_val_index(global_mesh, local_mesh, node_local2global);
6844  if (rtc != RTC_NORMAL) goto error;
6845 
6846  rtc = const_node_init_val_item(global_mesh, local_mesh, node_local2global);
6847  if (rtc != RTC_NORMAL) goto error;
6848  }
6849 
6850  return RTC_NORMAL;
6851 
6852 error:
6853  return RTC_ERROR;
6854 }
6855 
6856 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6857  * - - - - - - - - - */
6858 
6859 static int const_n_elem_type(const struct hecmwST_local_mesh *global_mesh,
6860  struct hecmwST_local_mesh *local_mesh) {
6861  HECMW_assert(global_mesh->n_elem_type > 0);
6862 
6863  local_mesh->n_elem_type = global_mesh->n_elem_type;
6864 
6865  HECMW_assert(local_mesh->n_elem_type > 0);
6866 
6867  return RTC_NORMAL;
6868 }
6869 
6870 static int const_elem_type(const struct hecmwST_local_mesh *global_mesh,
6871  struct hecmwST_local_mesh *local_mesh,
6872  const int *elem_local2global) {
6873  int i;
6874 
6875  HECMW_assert(local_mesh->n_elem > 0);
6876  HECMW_assert(global_mesh->elem_type);
6877 
6878  local_mesh->elem_type = (int *)HECMW_malloc(sizeof(int) * local_mesh->n_elem);
6879  if (local_mesh->elem_type == NULL) {
6880  HECMW_set_error(errno, "");
6881  goto error;
6882  }
6883 
6884  for (i = 0; i < local_mesh->n_elem; i++) {
6885  local_mesh->elem_type[i] = global_mesh->elem_type[elem_local2global[i] - 1];
6886  }
6887 
6888  return RTC_NORMAL;
6889 
6890 error:
6891  return RTC_ERROR;
6892 }
6893 
6894 static int const_elem_type_index(const struct hecmwST_local_mesh *global_mesh,
6895  struct hecmwST_local_mesh *local_mesh,
6896  const int *elem_global2local) {
6897  int counter;
6898  int i, j;
6899 
6900  HECMW_assert(local_mesh->n_elem_type > 0);
6901  HECMW_assert(global_mesh->n_elem_type > 0);
6902  HECMW_assert(global_mesh->elem_type_index);
6903 
6904  local_mesh->elem_type_index =
6905  (int *)HECMW_calloc(local_mesh->n_elem_type + 1, sizeof(int));
6906  if (local_mesh->elem_type_index == NULL) {
6907  HECMW_set_error(errno, "");
6908  goto error;
6909  }
6910 
6911  for (counter = 0, i = 0; i < global_mesh->n_elem_type; i++) {
6912  for (j = global_mesh->elem_type_index[i];
6913  j < global_mesh->elem_type_index[i + 1]; j++) {
6914  if (elem_global2local[j]) counter++;
6915  }
6916  local_mesh->elem_type_index[i + 1] = counter;
6917  }
6918  HECMW_assert(local_mesh->elem_type_index[local_mesh->n_elem_type] ==
6919  local_mesh->n_elem);
6920 
6921  return RTC_NORMAL;
6922 
6923 error:
6924  return RTC_ERROR;
6925 }
6926 
6927 static int const_elem_type_index_mod(
6928  const struct hecmwST_local_mesh *global_mesh,
6929  struct hecmwST_local_mesh *local_mesh, const int *elem_global2local,
6930  int domain) {
6931  int counter;
6932  int i, j, idx1, idx2, elem_tmp, elem1, elem2, n_int, n_bnd, n_out, maxe;
6933 
6934  HECMW_assert(local_mesh->n_elem_type > 0);
6935  HECMW_assert(global_mesh->n_elem_type > 0);
6936  HECMW_assert(global_mesh->elem_type_index);
6937 
6938  local_mesh->elem_type_index =
6939  (int *)HECMW_calloc(local_mesh->n_elem_type + 1, sizeof(int));
6940  if (local_mesh->elem_type_index == NULL) {
6941  HECMW_set_error(errno, "");
6942  goto error;
6943  }
6944 
6945  n_int = n_int_elist[domain];
6946  n_bnd = n_bnd_elist[2 * domain];
6947  n_out = n_bnd_elist[2 * domain + 1] - n_bnd_elist[2 * domain];
6948  maxe = global_mesh->n_elem + 1;
6949 
6950  for (counter = 0, i = 0; i < global_mesh->n_elem_type; i++) {
6951  elem1 = (n_int == 0) ? maxe : int_elist[domain][0];
6952  elem2 = (n_out == 0) ? maxe : bnd_elist[domain][n_bnd];
6953  for (idx1 = 0, idx2 = 0, j = 0; j < n_int + n_out; j++) {
6954  if (elem1 < elem2) {
6955  elem_tmp = elem1 - 1;
6956  idx1++;
6957  elem1 = (idx1 == n_int) ? maxe : int_elist[domain][idx1];
6958  } else {
6959  elem_tmp = elem2 - 1;
6960  idx2++;
6961  elem2 = (idx2 == n_out) ? maxe : bnd_elist[domain][idx2 + n_bnd];
6962  }
6963  if (elem_tmp >= global_mesh->elem_type_index[i] &&
6964  elem_tmp < global_mesh->elem_type_index[i + 1]) {
6965  counter++;
6966  }
6967  }
6968  local_mesh->elem_type_index[i + 1] = counter;
6969  }
6970 
6971  HECMW_assert(local_mesh->elem_type_index[local_mesh->n_elem_type] ==
6972  local_mesh->n_elem);
6973 
6974  return RTC_NORMAL;
6975 
6976 error:
6977  return RTC_ERROR;
6978 }
6979 
6980 static int const_elem_type_item(const struct hecmwST_local_mesh *global_mesh,
6981  struct hecmwST_local_mesh *local_mesh) {
6982  HECMW_assert(global_mesh->elem_type_item);
6983 
6984  local_mesh->elem_type_item = global_mesh->elem_type_item;
6985 
6986  return RTC_NORMAL;
6987 }
6988 
6989 static int const_elem_node_index(const struct hecmwST_local_mesh *global_mesh,
6990  struct hecmwST_local_mesh *local_mesh,
6991  const int *elem_local2global) {
6992  int old_idx;
6993  int i;
6994 
6995  HECMW_assert(local_mesh->n_elem > 0);
6996  HECMW_assert(global_mesh->elem_node_index);
6997 
6998  local_mesh->elem_node_index =
6999  (long long *)HECMW_calloc(local_mesh->n_elem + 1, sizeof(long long));
7000  if (local_mesh->elem_node_index == NULL) {
7001  HECMW_set_error(errno, "");
7002  goto error;
7003  }
7004 
7005  for (i = 0; i < local_mesh->n_elem; i++) {
7006  old_idx = elem_local2global[i] - 1;
7007 
7008  local_mesh->elem_node_index[i + 1] =
7009  local_mesh->elem_node_index[i] +
7010  global_mesh->elem_node_index[old_idx + 1] -
7011  global_mesh->elem_node_index[old_idx];
7012  }
7013 
7014  return RTC_NORMAL;
7015 
7016 error:
7017  return RTC_ERROR;
7018 }
7019 
7020 static int const_elem_node_item(const struct hecmwST_local_mesh *global_mesh,
7021  struct hecmwST_local_mesh *local_mesh,
7022  const int *node_global2local,
7023  const int *elem_local2global) {
7024  int node;
7025  size_t size;
7026  long long counter;
7027  int i, j;
7028  long long gstart, lstart, lend;
7029 
7030  HECMW_assert(local_mesh->n_elem > 0);
7031  HECMW_assert(local_mesh->elem_node_index);
7032  HECMW_assert(local_mesh->elem_node_index[local_mesh->n_elem] > 0);
7033  HECMW_assert(global_mesh->elem_node_item);
7034 
7035  size = sizeof(int) * (size_t)local_mesh->elem_node_index[local_mesh->n_elem];
7036  local_mesh->elem_node_item = (int *)HECMW_malloc(size);
7037  if (local_mesh->elem_node_item == NULL) {
7038  HECMW_set_error(errno, "");
7039  goto error;
7040  }
7041 
7042  for (counter = 0, i = 0; i < local_mesh->n_elem; i++) {
7043  gstart = global_mesh->elem_node_index[elem_local2global[i] - 1];
7044  lstart = local_mesh->elem_node_index[i];
7045  lend = local_mesh->elem_node_index[i + 1];
7046 
7047  for (j = 0; j < lend - lstart; j++) {
7048  node = global_mesh->elem_node_item[gstart + j];
7049  local_mesh->elem_node_item[lstart + j] = node_global2local[node - 1];
7050  counter++;
7051  }
7052  HECMW_assert(counter == local_mesh->elem_node_index[i + 1]);
7053  }
7054 
7055  return RTC_NORMAL;
7056 
7057 error:
7058  return RTC_ERROR;
7059 }
7060 
7061 static int const_elem_id(const struct hecmwST_local_mesh *global_mesh,
7062  struct hecmwST_local_mesh *local_mesh,
7063  const int *elem_local2global) {
7064  int i;
7065 
7066  HECMW_assert(local_mesh->n_elem > 0);
7067  HECMW_assert(global_mesh->elem_ID);
7068 
7069  local_mesh->elem_ID =
7070  (int *)HECMW_malloc(sizeof(int) * (size_t)local_mesh->n_elem * 2);
7071  if (local_mesh->elem_ID == NULL) {
7072  HECMW_set_error(errno, "");
7073  goto error;
7074  }
7075 
7076  for (i = 0; i < local_mesh->n_elem; i++) {
7077  local_mesh->elem_ID[2 * i] =
7078  global_mesh->elem_ID[2 * (elem_local2global[i] - 1)];
7079  local_mesh->elem_ID[2 * i + 1] =
7080  global_mesh->elem_ID[2 * (elem_local2global[i] - 1) + 1];
7081  }
7082 
7083  return RTC_NORMAL;
7084 
7085 error:
7086  return RTC_ERROR;
7087 }
7088 
7089 static int const_global_elem_id(const struct hecmwST_local_mesh *global_mesh,
7090  struct hecmwST_local_mesh *local_mesh,
7091  const int *elem_local2global) {
7092  int i;
7093 
7094  HECMW_assert(local_mesh->n_elem);
7095  HECMW_assert(global_mesh->global_elem_ID);
7096 
7097  local_mesh->global_elem_ID =
7098  (int *)HECMW_malloc(sizeof(int) * local_mesh->n_elem);
7099  if (local_mesh->global_elem_ID == NULL) {
7100  HECMW_set_error(errno, "");
7101  goto error;
7102  }
7103 
7104  for (i = 0; i < local_mesh->n_elem; i++) {
7105  local_mesh->global_elem_ID[i] =
7106  global_mesh->global_elem_ID[elem_local2global[i] - 1];
7107  }
7108 
7109  return RTC_NORMAL;
7110 
7111 error:
7112  return RTC_ERROR;
7113 }
7114 
7115 static int const_section_id(const struct hecmwST_local_mesh *global_mesh,
7116  struct hecmwST_local_mesh *local_mesh,
7117  const int *elem_local2global) {
7118  int i;
7119 
7120  HECMW_assert(local_mesh->n_elem);
7121  HECMW_assert(global_mesh->section_ID);
7122 
7123  local_mesh->section_ID =
7124  (int *)HECMW_malloc(sizeof(int) * local_mesh->n_elem);
7125  if (local_mesh->section_ID == NULL) {
7126  HECMW_set_error(errno, "");
7127  goto error;
7128  }
7129 
7130  for (i = 0; i < local_mesh->n_elem; i++) {
7131  local_mesh->section_ID[i] =
7132  global_mesh->section_ID[elem_local2global[i] - 1];
7133  }
7134 
7135  return RTC_NORMAL;
7136 
7137 error:
7138  return RTC_ERROR;
7139 }
7140 
7141 static int const_elem_mat_id_index(const struct hecmwST_local_mesh *global_mesh,
7142  struct hecmwST_local_mesh *local_mesh,
7143  const int *elem_local2global) {
7144  int old_idx;
7145  int i;
7146 
7147  HECMW_assert(local_mesh->n_elem > 0);
7148  HECMW_assert(global_mesh->elem_mat_ID_index);
7149 
7150  local_mesh->elem_mat_ID_index =
7151  (int *)HECMW_calloc(local_mesh->n_elem + 1, sizeof(int));
7152  if (local_mesh->elem_mat_ID_index == NULL) {
7153  HECMW_set_error(errno, "");
7154  goto error;
7155  }
7156 
7157  for (i = 0; i < local_mesh->n_elem; i++) {
7158  old_idx = elem_local2global[i] - 1;
7159 
7160  local_mesh->elem_mat_ID_index[i + 1] =
7161  local_mesh->elem_mat_ID_index[i] +
7162  global_mesh->elem_mat_ID_index[old_idx + 1] -
7163  global_mesh->elem_mat_ID_index[old_idx];
7164  }
7165 
7166  return RTC_NORMAL;
7167 
7168 error:
7169  return RTC_ERROR;
7170 }
7171 
7172 static int const_n_elem_mat_id(struct hecmwST_local_mesh *local_mesh) {
7173  HECMW_assert(local_mesh->n_elem > 0);
7174  HECMW_assert(local_mesh->elem_mat_ID_index);
7175 
7176  local_mesh->n_elem_mat_ID = local_mesh->elem_mat_ID_index[local_mesh->n_elem];
7177 
7178  return RTC_NORMAL;
7179 }
7180 
7181 static int const_elem_mat_id_item(const struct hecmwST_local_mesh *global_mesh,
7182  struct hecmwST_local_mesh *local_mesh,
7183  const int *elem_local2global) {
7184  int size;
7185  int counter;
7186  int i, j, gstart, gend, lstart, lend;
7187 
7188  HECMW_assert(local_mesh->n_elem > 0);
7189  HECMW_assert(local_mesh->elem_mat_ID_index[local_mesh->n_elem] >= 0);
7190 
7191  if (local_mesh->elem_mat_ID_index[local_mesh->n_elem] == 0) {
7192  local_mesh->elem_mat_ID_item = NULL;
7193  return RTC_NORMAL;
7194  }
7195 
7196  size = sizeof(int) * local_mesh->elem_mat_ID_index[local_mesh->n_elem];
7197  local_mesh->elem_mat_ID_item = (int *)HECMW_malloc(size);
7198  if (local_mesh->elem_mat_ID_item == NULL) {
7199  HECMW_set_error(errno, "");
7200  goto error;
7201  }
7202 
7203  for (counter = 0, i = 0; i < local_mesh->n_elem; i++) {
7204  gstart = global_mesh->elem_mat_ID_index[elem_local2global[i] - 1];
7205  gend = global_mesh->elem_mat_ID_index[elem_local2global[i]];
7206  lstart = local_mesh->elem_mat_ID_index[i];
7207  lend = local_mesh->elem_mat_ID_index[i + 1];
7208 
7209  HECMW_assert(lend - lstart == gend - gstart);
7210 
7211  for (j = 0; j < lend - lstart; j++) {
7212  local_mesh->elem_mat_ID_item[lstart + j] =
7213  global_mesh->elem_mat_ID_item[gstart + j];
7214  counter++;
7215  }
7216  HECMW_assert(counter == local_mesh->elem_mat_ID_index[i + 1]);
7217  }
7218  HECMW_assert(counter == local_mesh->n_elem_mat_ID);
7219 
7220  return RTC_NORMAL;
7221 
7222 error:
7223  return RTC_ERROR;
7224 }
7225 
7226 static int const_elem_info(const struct hecmwST_local_mesh *global_mesh,
7227  struct hecmwST_local_mesh *local_mesh,
7228  const int *node_global2local,
7229  const int *elem_global2local,
7230  const int *elem_local2global, int current_domain) {
7231  int rtc;
7232 
7233  HECMW_assert(global_mesh);
7234  HECMW_assert(local_mesh);
7235  HECMW_assert(node_global2local);
7236  HECMW_assert(elem_global2local);
7237  HECMW_assert(elem_local2global);
7238 
7239  rtc = const_n_elem_type(global_mesh, local_mesh);
7240  if (rtc != RTC_NORMAL) goto error;
7241 
7242  rtc = const_elem_type(global_mesh, local_mesh, elem_local2global);
7243  if (rtc != RTC_NORMAL) goto error;
7244 
7245  if (is_spdup_available(global_mesh)) {
7246  rtc = const_elem_type_index_mod(global_mesh, local_mesh, elem_global2local,
7247  current_domain);
7248  } else {
7249  rtc = const_elem_type_index(global_mesh, local_mesh, elem_global2local);
7250  }
7251 
7252  if (rtc != RTC_NORMAL) goto error;
7253 
7254  rtc = const_elem_type_item(global_mesh, local_mesh);
7255  if (rtc != RTC_NORMAL) goto error;
7256 
7257  rtc = const_elem_node_index(global_mesh, local_mesh, elem_local2global);
7258  if (rtc != RTC_NORMAL) goto error;
7259 
7260  rtc = const_elem_node_item(global_mesh, local_mesh, node_global2local,
7261  elem_local2global);
7262  if (rtc != RTC_NORMAL) goto error;
7263 
7264  rtc = const_elem_id(global_mesh, local_mesh, elem_local2global);
7265  if (rtc != RTC_NORMAL) goto error;
7266 
7267  rtc = const_global_elem_id(global_mesh, local_mesh, elem_local2global);
7268  if (rtc != RTC_NORMAL) goto error;
7269 
7270  rtc = const_section_id(global_mesh, local_mesh, elem_local2global);
7271  if (rtc != RTC_NORMAL) goto error;
7272 
7273  rtc = const_elem_mat_id_index(global_mesh, local_mesh, elem_local2global);
7274  if (rtc != RTC_NORMAL) goto error;
7275 
7276  rtc = const_n_elem_mat_id(local_mesh);
7277  if (rtc != RTC_NORMAL) goto error;
7278 
7279  rtc = const_elem_mat_id_item(global_mesh, local_mesh, elem_local2global);
7280  if (rtc != RTC_NORMAL) goto error;
7281 
7282  return RTC_NORMAL;
7283 
7284 error:
7285  return RTC_ERROR;
7286 }
7287 
7288 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7289  * - - - - - - - - - */
7290 
7291 static int const_hecmw_comm(const struct hecmwST_local_mesh *global_mesh,
7292  struct hecmwST_local_mesh *local_mesh) {
7293  local_mesh->HECMW_COMM = global_mesh->HECMW_COMM;
7294 
7295  return RTC_NORMAL;
7296 }
7297 
7298 static int const_zero(struct hecmwST_local_mesh *local_mesh,
7299  int current_domain) {
7300  local_mesh->zero = (current_domain == 0) ? 1 : 0;
7301 
7302  return RTC_NORMAL;
7303 }
7304 
7305 static int const_petot(const struct hecmwST_local_mesh *global_mesh,
7306  struct hecmwST_local_mesh *local_mesh) {
7307  local_mesh->PETOT = global_mesh->n_subdomain;
7308 
7309  return RTC_NORMAL;
7310 }
7311 
7312 static int const_pesmptot(const struct hecmwST_local_mesh *global_mesh,
7313  struct hecmwST_local_mesh *local_mesh) {
7314  local_mesh->PEsmpTOT = global_mesh->PEsmpTOT;
7315 
7316  return RTC_NORMAL;
7317 }
7318 
7319 static int const_my_rank(struct hecmwST_local_mesh *local_mesh,
7320  int current_domain) {
7321  local_mesh->my_rank = current_domain;
7322 
7323  return RTC_NORMAL;
7324 }
7325 
7326 static int const_errnof(const struct hecmwST_local_mesh *global_mesh,
7327  struct hecmwST_local_mesh *local_mesh) {
7328  local_mesh->errnof = global_mesh->errnof;
7329 
7330  return RTC_NORMAL;
7331 }
7332 
7333 static int const_n_subdomain(const struct hecmwST_local_mesh *global_mesh,
7334  struct hecmwST_local_mesh *local_mesh) {
7335  local_mesh->n_subdomain = global_mesh->n_subdomain;
7336 
7337  return RTC_NORMAL;
7338 }
7339 
7340 static int const_import_item(struct hecmwST_local_mesh *local_mesh,
7341  const int *global2local) {
7342  int new_id;
7343  int i;
7344 
7345  if (local_mesh->n_neighbor_pe == 0) {
7346  local_mesh->import_item = NULL;
7347  return RTC_NORMAL;
7348  }
7349 
7350  HECMW_assert(local_mesh->n_neighbor_pe > 0);
7351  HECMW_assert(local_mesh->import_index);
7352  HECMW_assert(local_mesh->import_index[local_mesh->n_neighbor_pe] >= 0);
7353  HECMW_assert(local_mesh->import_item);
7354 
7355  for (i = 0; i < local_mesh->import_index[local_mesh->n_neighbor_pe]; i++) {
7356  new_id = global2local[local_mesh->import_item[i] - 1];
7357  local_mesh->import_item[i] = new_id;
7358  }
7359 
7360  return RTC_NORMAL;
7361 }
7362 
7363 static int const_export_item(struct hecmwST_local_mesh *local_mesh,
7364  const int *global2local) {
7365  int new_id;
7366  int i;
7367 
7368  if (local_mesh->n_neighbor_pe == 0) {
7369  local_mesh->export_item = NULL;
7370  return RTC_NORMAL;
7371  }
7372 
7373  HECMW_assert(local_mesh->n_neighbor_pe > 0);
7374  HECMW_assert(local_mesh->export_index);
7375  HECMW_assert(local_mesh->export_index[local_mesh->n_neighbor_pe] >= 0);
7376  HECMW_assert(local_mesh->export_item);
7377 
7378  for (i = 0; i < local_mesh->export_index[local_mesh->n_neighbor_pe]; i++) {
7379  new_id = global2local[local_mesh->export_item[i] - 1];
7380  local_mesh->export_item[i] = new_id;
7381  }
7382 
7383  return RTC_NORMAL;
7384 }
7385 
7386 static int const_shared_item(struct hecmwST_local_mesh *local_mesh,
7387  const int *global2local) {
7388  int new_id;
7389  int i;
7390 
7391  if (local_mesh->n_neighbor_pe == 0) {
7392  local_mesh->shared_item = NULL;
7393  return RTC_NORMAL;
7394  }
7395 
7396  HECMW_assert(local_mesh->n_neighbor_pe > 0);
7397  HECMW_assert(local_mesh->shared_index);
7398  HECMW_assert(local_mesh->shared_index[local_mesh->n_neighbor_pe] >= 0);
7399  HECMW_assert(local_mesh->shared_item);
7400 
7401  for (i = 0; i < local_mesh->shared_index[local_mesh->n_neighbor_pe]; i++) {
7402  new_id = global2local[local_mesh->shared_item[i] - 1];
7403  local_mesh->shared_item[i] = new_id;
7404  }
7405 
7406  return RTC_NORMAL;
7407 }
7408 
7409 static int const_comm_info(const struct hecmwST_local_mesh *global_mesh,
7410  struct hecmwST_local_mesh *local_mesh,
7411  const int *node_global2local,
7412  const int *elem_global2local, int current_domain) {
7413  int rtc;
7414 
7415  HECMW_assert(global_mesh);
7416  HECMW_assert(local_mesh);
7417  HECMW_assert(node_global2local);
7418  HECMW_assert(elem_global2local);
7419 
7420  rtc = const_hecmw_comm(global_mesh, local_mesh);
7421  if (rtc != RTC_NORMAL) goto error;
7422 
7423  rtc = const_zero(local_mesh, current_domain);
7424  if (rtc != RTC_NORMAL) goto error;
7425 
7426  rtc = const_petot(global_mesh, local_mesh);
7427  if (rtc != RTC_NORMAL) goto error;
7428 
7429  rtc = const_pesmptot(global_mesh, local_mesh);
7430  if (rtc != RTC_NORMAL) goto error;
7431 
7432  rtc = const_my_rank(local_mesh, current_domain);
7433  if (rtc != RTC_NORMAL) goto error;
7434 
7435  rtc = const_errnof(global_mesh, local_mesh);
7436  if (rtc != RTC_NORMAL) goto error;
7437 
7438  rtc = const_n_subdomain(global_mesh, local_mesh);
7439  if (rtc != RTC_NORMAL) goto error;
7440 
7441  switch (global_mesh->hecmw_flag_parttype) {
7443  rtc = const_import_item(local_mesh, node_global2local);
7444  if (rtc != RTC_NORMAL) goto error;
7445 
7446  rtc = const_export_item(local_mesh, node_global2local);
7447  if (rtc != RTC_NORMAL) goto error;
7448 
7449  rtc = const_shared_item(local_mesh, elem_global2local);
7450  if (rtc != RTC_NORMAL) goto error;
7451 
7452  break;
7453 
7455  rtc = const_import_item(local_mesh, elem_global2local);
7456  if (rtc != RTC_NORMAL) goto error;
7457 
7458  rtc = const_export_item(local_mesh, elem_global2local);
7459  if (rtc != RTC_NORMAL) goto error;
7460 
7461  rtc = const_shared_item(local_mesh, node_global2local);
7462  if (rtc != RTC_NORMAL) goto error;
7463 
7464  break;
7465 
7466  default:
7468  global_mesh->hecmw_flag_parttype);
7469  goto error;
7470  }
7471 
7472  return RTC_NORMAL;
7473 
7474 error:
7475  return RTC_ERROR;
7476 }
7477 
7478 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7479  * - - - - - - - - - */
7480 
7481 static int const_n_adapt(const struct hecmwST_local_mesh *global_mesh,
7482  struct hecmwST_local_mesh *local_mesh) {
7483  local_mesh->n_adapt = global_mesh->n_adapt;
7484 
7485  return RTC_NORMAL;
7486 }
7487 
7488 static int const_coarse_grid_level(const struct hecmwST_local_mesh *global_mesh,
7489  struct hecmwST_local_mesh *local_mesh) {
7490  local_mesh->coarse_grid_level = global_mesh->coarse_grid_level;
7491 
7492  return RTC_NORMAL;
7493 }
7494 
7495 static int const_when_i_was_refined_node(
7496  const struct hecmwST_local_mesh *global_mesh,
7497  struct hecmwST_local_mesh *local_mesh) {
7498  local_mesh->when_i_was_refined_node = global_mesh->when_i_was_refined_node;
7499 
7500  return RTC_NORMAL;
7501 }
7502 
7503 static int const_when_i_was_refined_elem(
7504  const struct hecmwST_local_mesh *global_mesh,
7505  struct hecmwST_local_mesh *local_mesh) {
7506  local_mesh->when_i_was_refined_elem = global_mesh->when_i_was_refined_elem;
7507 
7508  return RTC_NORMAL;
7509 }
7510 
7511 static int const_adapt_parent_type(const struct hecmwST_local_mesh *global_mesh,
7512  struct hecmwST_local_mesh *local_mesh) {
7513  local_mesh->adapt_parent_type = global_mesh->adapt_parent_type;
7514 
7515  return RTC_NORMAL;
7516 }
7517 
7518 static int const_adapt_type(const struct hecmwST_local_mesh *global_mesh,
7519  struct hecmwST_local_mesh *local_mesh) {
7520  local_mesh->adapt_type = global_mesh->adapt_type;
7521 
7522  return RTC_NORMAL;
7523 }
7524 
7525 static int const_adapt_level(const struct hecmwST_local_mesh *global_mesh,
7526  struct hecmwST_local_mesh *local_mesh) {
7527  local_mesh->adapt_level = global_mesh->adapt_level;
7528 
7529  return RTC_NORMAL;
7530 }
7531 
7532 static int const_adapt_parent(const struct hecmwST_local_mesh *global_mesh,
7533  struct hecmwST_local_mesh *local_mesh) {
7534  local_mesh->adapt_parent = global_mesh->adapt_parent;
7535 
7536  return RTC_NORMAL;
7537 }
7538 
7539 static int const_adapt_children_index(
7540  const struct hecmwST_local_mesh *global_mesh,
7541  struct hecmwST_local_mesh *local_mesh) {
7542  local_mesh->adapt_children_index = global_mesh->adapt_children_index;
7543 
7544  return RTC_NORMAL;
7545 }
7546 
7547 static int const_adapt_children_item(
7548  const struct hecmwST_local_mesh *global_mesh,
7549  struct hecmwST_local_mesh *local_mesh) {
7550  local_mesh->adapt_children_item = global_mesh->adapt_children_item;
7551 
7552  return RTC_NORMAL;
7553 }
7554 
7555 static int const_adapt_info(const struct hecmwST_local_mesh *global_mesh,
7556  struct hecmwST_local_mesh *local_mesh) {
7557  int rtc;
7558 
7559  HECMW_assert(global_mesh);
7560  HECMW_assert(local_mesh);
7561 
7562  rtc = const_n_adapt(global_mesh, local_mesh);
7563  if (rtc != RTC_NORMAL) goto error;
7564 
7565  rtc = const_coarse_grid_level(global_mesh, local_mesh);
7566  if (rtc != RTC_NORMAL) goto error;
7567 
7568  rtc = const_when_i_was_refined_node(global_mesh, local_mesh);
7569  if (rtc != RTC_NORMAL) goto error;
7570 
7571  rtc = const_when_i_was_refined_elem(global_mesh, local_mesh);
7572  if (rtc != RTC_NORMAL) goto error;
7573 
7574  rtc = const_adapt_parent_type(global_mesh, local_mesh);
7575  if (rtc != RTC_NORMAL) goto error;
7576 
7577  rtc = const_adapt_type(global_mesh, local_mesh);
7578  if (rtc != RTC_NORMAL) goto error;
7579 
7580  rtc = const_adapt_level(global_mesh, local_mesh);
7581  if (rtc != RTC_NORMAL) goto error;
7582 
7583  rtc = const_adapt_parent(global_mesh, local_mesh);
7584  if (rtc != RTC_NORMAL) goto error;
7585 
7586  rtc = const_adapt_children_index(global_mesh, local_mesh);
7587  if (rtc != RTC_NORMAL) goto error;
7588 
7589  rtc = const_adapt_children_item(global_mesh, local_mesh);
7590  if (rtc != RTC_NORMAL) goto error;
7591 
7592  return RTC_NORMAL;
7593 
7594 error:
7595  return RTC_ERROR;
7596 }
7597 
7598 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7599  * - - - - - - - - - */
7600 
7601 static int const_n_sect(const struct hecmwST_local_mesh *global_mesh,
7602  struct hecmwST_local_mesh *local_mesh) {
7603  local_mesh->section->n_sect = global_mesh->section->n_sect;
7604 
7605  return RTC_NORMAL;
7606 }
7607 
7608 static int const_sect_type(const struct hecmwST_local_mesh *global_mesh,
7609  struct hecmwST_local_mesh *local_mesh) {
7610  local_mesh->section->sect_type = global_mesh->section->sect_type;
7611 
7612  return RTC_NORMAL;
7613 }
7614 
7615 static int const_sect_opt(const struct hecmwST_local_mesh *global_mesh,
7616  struct hecmwST_local_mesh *local_mesh) {
7617  local_mesh->section->sect_opt = global_mesh->section->sect_opt;
7618 
7619  return RTC_NORMAL;
7620 }
7621 
7622 static int const_sect_mat_id_index(const struct hecmwST_local_mesh *global_mesh,
7623  struct hecmwST_local_mesh *local_mesh) {
7624  local_mesh->section->sect_mat_ID_index =
7625  global_mesh->section->sect_mat_ID_index;
7626 
7627  return RTC_NORMAL;
7628 }
7629 
7630 static int const_sect_mat_id_item(const struct hecmwST_local_mesh *global_mesh,
7631  struct hecmwST_local_mesh *local_mesh) {
7632  local_mesh->section->sect_mat_ID_item =
7633  global_mesh->section->sect_mat_ID_item;
7634 
7635  return RTC_NORMAL;
7636 }
7637 
7638 static int const_sect_i_index(const struct hecmwST_local_mesh *global_mesh,
7639  struct hecmwST_local_mesh *local_mesh) {
7640  local_mesh->section->sect_I_index = global_mesh->section->sect_I_index;
7641 
7642  return RTC_NORMAL;
7643 }
7644 
7645 static int const_sect_i_item(const struct hecmwST_local_mesh *global_mesh,
7646  struct hecmwST_local_mesh *local_mesh) {
7647  local_mesh->section->sect_I_item = global_mesh->section->sect_I_item;
7648 
7649  return RTC_NORMAL;
7650 }
7651 
7652 static int const_sect_r_index(const struct hecmwST_local_mesh *global_mesh,
7653  struct hecmwST_local_mesh *local_mesh) {
7654  local_mesh->section->sect_R_index = global_mesh->section->sect_R_index;
7655 
7656  return RTC_NORMAL;
7657 }
7658 
7659 static int const_sect_r_item(const struct hecmwST_local_mesh *global_mesh,
7660  struct hecmwST_local_mesh *local_mesh) {
7661  local_mesh->section->sect_R_item = global_mesh->section->sect_R_item;
7662 
7663  return RTC_NORMAL;
7664 }
7665 
7666 static int const_sect_info(const struct hecmwST_local_mesh *global_mesh,
7667  struct hecmwST_local_mesh *local_mesh) {
7668  int rtc;
7669 
7670  HECMW_assert(global_mesh);
7671  HECMW_assert(local_mesh);
7672  HECMW_assert(global_mesh->section);
7673  HECMW_assert(local_mesh->section);
7674 
7675  rtc = const_n_sect(global_mesh, local_mesh);
7676  if (rtc != RTC_NORMAL) goto error;
7677 
7678  rtc = const_sect_type(global_mesh, local_mesh);
7679  if (rtc != RTC_NORMAL) goto error;
7680 
7681  rtc = const_sect_opt(global_mesh, local_mesh);
7682  if (rtc != RTC_NORMAL) goto error;
7683 
7684  rtc = const_sect_mat_id_index(global_mesh, local_mesh);
7685  if (rtc != RTC_NORMAL) goto error;
7686 
7687  rtc = const_sect_mat_id_item(global_mesh, local_mesh);
7688  if (rtc != RTC_NORMAL) goto error;
7689 
7690  rtc = const_sect_i_index(global_mesh, local_mesh);
7691  if (rtc != RTC_NORMAL) goto error;
7692 
7693  rtc = const_sect_i_item(global_mesh, local_mesh);
7694  if (rtc != RTC_NORMAL) goto error;
7695 
7696  rtc = const_sect_r_index(global_mesh, local_mesh);
7697  if (rtc != RTC_NORMAL) goto error;
7698 
7699  rtc = const_sect_r_item(global_mesh, local_mesh);
7700  if (rtc != RTC_NORMAL) goto error;
7701 
7702  return RTC_NORMAL;
7703 
7704 error:
7705  return RTC_ERROR;
7706 }
7707 
7708 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7709  * - - - - - - - - - */
7710 
7711 static int const_n_mat(const struct hecmwST_local_mesh *global_mesh,
7712  struct hecmwST_local_mesh *local_mesh) {
7713  local_mesh->material->n_mat = global_mesh->material->n_mat;
7714 
7715  return RTC_NORMAL;
7716 }
7717 
7718 static int const_n_mat_item(const struct hecmwST_local_mesh *global_mesh,
7719  struct hecmwST_local_mesh *local_mesh) {
7720  local_mesh->material->n_mat_item = global_mesh->material->n_mat_item;
7721 
7722  return RTC_NORMAL;
7723 }
7724 
7725 static int const_n_mat_subitem(const struct hecmwST_local_mesh *global_mesh,
7726  struct hecmwST_local_mesh *local_mesh) {
7727  local_mesh->material->n_mat_subitem = global_mesh->material->n_mat_subitem;
7728 
7729  return RTC_NORMAL;
7730 }
7731 
7732 static int const_n_mat_table(const struct hecmwST_local_mesh *global_mesh,
7733  struct hecmwST_local_mesh *local_mesh) {
7734  local_mesh->material->n_mat_table = global_mesh->material->n_mat_table;
7735 
7736  return RTC_NORMAL;
7737 }
7738 
7739 static int const_mat_name(const struct hecmwST_local_mesh *global_mesh,
7740  struct hecmwST_local_mesh *local_mesh) {
7741  local_mesh->material->mat_name = global_mesh->material->mat_name;
7742 
7743  return RTC_NORMAL;
7744 }
7745 
7746 static int const_mat_item_index(const struct hecmwST_local_mesh *global_mesh,
7747  struct hecmwST_local_mesh *local_mesh) {
7748  local_mesh->material->mat_item_index = global_mesh->material->mat_item_index;
7749 
7750  return RTC_NORMAL;
7751 }
7752 
7753 static int const_mat_subitem_index(const struct hecmwST_local_mesh *global_mesh,
7754  struct hecmwST_local_mesh *local_mesh) {
7755  local_mesh->material->mat_subitem_index =
7756  global_mesh->material->mat_subitem_index;
7757 
7758  return RTC_NORMAL;
7759 }
7760 
7761 static int const_mat_table_index(const struct hecmwST_local_mesh *global_mesh,
7762  struct hecmwST_local_mesh *local_mesh) {
7763  local_mesh->material->mat_table_index =
7764  global_mesh->material->mat_table_index;
7765 
7766  return RTC_NORMAL;
7767 }
7768 
7769 static int const_mat_val(const struct hecmwST_local_mesh *global_mesh,
7770  struct hecmwST_local_mesh *local_mesh) {
7771  local_mesh->material->mat_val = global_mesh->material->mat_val;
7772 
7773  return RTC_NORMAL;
7774 }
7775 
7776 static int const_mat_temp(const struct hecmwST_local_mesh *global_mesh,
7777  struct hecmwST_local_mesh *local_mesh) {
7778  local_mesh->material->mat_temp = global_mesh->material->mat_temp;
7779 
7780  return RTC_NORMAL;
7781 }
7782 
7783 static int const_mat_info(const struct hecmwST_local_mesh *global_mesh,
7784  struct hecmwST_local_mesh *local_mesh) {
7785  int rtc;
7786 
7787  HECMW_assert(global_mesh);
7788  HECMW_assert(global_mesh->material);
7789  HECMW_assert(local_mesh);
7790  HECMW_assert(local_mesh->material);
7791 
7792  rtc = const_n_mat(global_mesh, local_mesh);
7793  if (rtc != RTC_NORMAL) goto error;
7794 
7795  rtc = const_n_mat_item(global_mesh, local_mesh);
7796  if (rtc != RTC_NORMAL) goto error;
7797 
7798  rtc = const_n_mat_subitem(global_mesh, local_mesh);
7799  if (rtc != RTC_NORMAL) goto error;
7800 
7801  rtc = const_n_mat_table(global_mesh, local_mesh);
7802  if (rtc != RTC_NORMAL) goto error;
7803 
7804  rtc = const_mat_name(global_mesh, local_mesh);
7805  if (rtc != RTC_NORMAL) goto error;
7806 
7807  rtc = const_mat_item_index(global_mesh, local_mesh);
7808  if (rtc != RTC_NORMAL) goto error;
7809 
7810  rtc = const_mat_subitem_index(global_mesh, local_mesh);
7811  if (rtc != RTC_NORMAL) goto error;
7812 
7813  rtc = const_mat_table_index(global_mesh, local_mesh);
7814  if (rtc != RTC_NORMAL) goto error;
7815 
7816  rtc = const_mat_val(global_mesh, local_mesh);
7817  if (rtc != RTC_NORMAL) goto error;
7818 
7819  rtc = const_mat_temp(global_mesh, local_mesh);
7820  if (rtc != RTC_NORMAL) goto error;
7821 
7822  return RTC_NORMAL;
7823 
7824 error:
7825  return RTC_ERROR;
7826 }
7827 
7828 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7829  * - - - - - - - - - */
7830 
7831 static int const_n_mpc(const struct hecmwST_local_mesh *global_mesh,
7832  struct hecmwST_local_mesh *local_mesh,
7833  const int *node_global2local, char *mpc_flag) {
7834  struct hecmwST_mpc *mpc_global = global_mesh->mpc;
7835  struct hecmwST_mpc *mpc_local = local_mesh->mpc;
7836  int node, diff, evalsum, counter;
7837  int i, j;
7838 
7839  for (counter = 0, i = 0; i < mpc_global->n_mpc; i++) {
7840  diff = mpc_global->mpc_index[i + 1] - mpc_global->mpc_index[i];
7841 
7842  evalsum = 0;
7843 
7844  for (j = mpc_global->mpc_index[i]; j < mpc_global->mpc_index[i + 1]; j++) {
7845  node = mpc_global->mpc_item[j];
7846  if (node_global2local[node - 1] > 0) evalsum++;
7847  }
7848 
7849  if (evalsum == diff) {
7850  MASK_BIT(mpc_flag[i], MASK);
7851  counter++;
7852  }
7853  }
7854  mpc_local->n_mpc = counter;
7855 
7856  return RTC_NORMAL;
7857 }
7858 
7859 static int const_mpc_index(const struct hecmwST_local_mesh *global_mesh,
7860  struct hecmwST_local_mesh *local_mesh,
7861  const char *mpc_flag) {
7862  struct hecmwST_mpc *mpc_global = global_mesh->mpc;
7863  struct hecmwST_mpc *mpc_local = local_mesh->mpc;
7864  int counter;
7865  int i;
7866 
7867  mpc_local->mpc_index = (int *)HECMW_calloc(mpc_local->n_mpc + 1, sizeof(int));
7868  if (local_mesh->mpc->mpc_index == NULL) {
7869  HECMW_set_error(errno, "");
7870  goto error;
7871  }
7872 
7873  for (counter = 0, i = 0; i < mpc_global->n_mpc; i++) {
7874  if (EVAL_BIT(mpc_flag[i], MASK)) {
7875  mpc_local->mpc_index[counter + 1] = mpc_local->mpc_index[counter] +
7876  mpc_global->mpc_index[i + 1] -
7877  mpc_global->mpc_index[i];
7878  counter++;
7879  }
7880  }
7881  HECMW_assert(counter == mpc_local->n_mpc);
7882 
7883  return RTC_NORMAL;
7884 
7885 error:
7886  return RTC_ERROR;
7887 }
7888 
7889 static int const_mpc_item(const struct hecmwST_local_mesh *global_mesh,
7890  struct hecmwST_local_mesh *local_mesh,
7891  const int *node_global2local, const char *mpc_flag) {
7892  struct hecmwST_mpc *mpc_global = global_mesh->mpc;
7893  struct hecmwST_mpc *mpc_local = local_mesh->mpc;
7894  int mcounter, icounter;
7895  int i, j;
7896 
7897  mpc_local->mpc_item =
7898  (int *)HECMW_malloc(sizeof(int) * mpc_local->mpc_index[mpc_local->n_mpc]);
7899  if (mpc_local->mpc_item == NULL) {
7900  HECMW_set_error(errno, "");
7901  goto error;
7902  }
7903 
7904  for (mcounter = 0, icounter = 0, i = 0; i < mpc_global->n_mpc; i++) {
7905  if (EVAL_BIT(mpc_flag[i], MASK)) {
7906  for (j = mpc_global->mpc_index[i]; j < mpc_global->mpc_index[i + 1];
7907  j++) {
7908  mpc_local->mpc_item[mcounter++] =
7909  node_global2local[mpc_global->mpc_item[j] - 1];
7910  }
7911  HECMW_assert(mcounter == mpc_local->mpc_index[++icounter]);
7912  }
7913  }
7914  HECMW_assert(icounter == mpc_local->n_mpc);
7915  HECMW_assert(mcounter == mpc_local->mpc_index[mpc_local->n_mpc]);
7916 
7917  return RTC_NORMAL;
7918 
7919 error:
7920  return RTC_ERROR;
7921 }
7922 
7923 static int const_mpc_dof(const struct hecmwST_local_mesh *global_mesh,
7924  struct hecmwST_local_mesh *local_mesh,
7925  const char *mpc_flag) {
7926  struct hecmwST_mpc *mpc_global = global_mesh->mpc;
7927  struct hecmwST_mpc *mpc_local = local_mesh->mpc;
7928  int mcounter, icounter;
7929  int i, j;
7930 
7931  mpc_local->mpc_dof =
7932  (int *)HECMW_malloc(sizeof(int) * mpc_local->mpc_index[mpc_local->n_mpc]);
7933  if (local_mesh->mpc->mpc_dof == NULL) {
7934  HECMW_set_error(errno, "");
7935  goto error;
7936  }
7937 
7938  for (mcounter = 0, icounter = 0, i = 0; i < mpc_global->n_mpc; i++) {
7939  if (EVAL_BIT(mpc_flag[i], MASK)) {
7940  for (j = mpc_global->mpc_index[i]; j < mpc_global->mpc_index[i + 1];
7941  j++) {
7942  mpc_local->mpc_dof[mcounter++] = mpc_global->mpc_dof[j];
7943  }
7944  HECMW_assert(mcounter == mpc_local->mpc_index[++icounter]);
7945  }
7946  }
7947  HECMW_assert(icounter == mpc_local->n_mpc);
7948  HECMW_assert(mcounter == mpc_local->mpc_index[mpc_local->n_mpc]);
7949 
7950  return RTC_NORMAL;
7951 
7952 error:
7953  return RTC_ERROR;
7954 }
7955 
7956 static int const_mpc_val(const struct hecmwST_local_mesh *global_mesh,
7957  struct hecmwST_local_mesh *local_mesh,
7958  const char *mpc_flag) {
7959  struct hecmwST_mpc *mpc_global = global_mesh->mpc;
7960  struct hecmwST_mpc *mpc_local = local_mesh->mpc;
7961  int size;
7962  int mcounter, icounter;
7963  int i, j;
7964 
7965  size = sizeof(double) * mpc_local->mpc_index[mpc_local->n_mpc];
7966  mpc_local->mpc_val = (double *)HECMW_malloc(size);
7967  if (local_mesh->mpc->mpc_val == NULL) {
7968  HECMW_set_error(errno, "");
7969  goto error;
7970  }
7971 
7972  for (mcounter = 0, icounter = 0, i = 0; i < mpc_global->n_mpc; i++) {
7973  if (EVAL_BIT(mpc_flag[i], MASK)) {
7974  for (j = mpc_global->mpc_index[i]; j < mpc_global->mpc_index[i + 1];
7975  j++) {
7976  mpc_local->mpc_val[mcounter++] = mpc_global->mpc_val[j];
7977  }
7978  HECMW_assert(mcounter == mpc_local->mpc_index[++icounter]);
7979  }
7980  }
7981  HECMW_assert(icounter == local_mesh->mpc->n_mpc);
7982  HECMW_assert(mcounter == local_mesh->mpc->mpc_index[local_mesh->mpc->n_mpc]);
7983 
7984  return RTC_NORMAL;
7985 
7986 error:
7987  return RTC_ERROR;
7988 }
7989 
7990 static int const_mpc_const(const struct hecmwST_local_mesh *global_mesh,
7991  struct hecmwST_local_mesh *local_mesh,
7992  const char *mpc_flag) {
7993  struct hecmwST_mpc *mpc_global = global_mesh->mpc;
7994  struct hecmwST_mpc *mpc_local = local_mesh->mpc;
7995  int size;
7996  int icounter;
7997  int i;
7998 
7999  size = sizeof(double) * mpc_local->n_mpc;
8000  mpc_local->mpc_const = (double *)HECMW_malloc(size);
8001  if (local_mesh->mpc->mpc_const == NULL) {
8002  HECMW_set_error(errno, "");
8003  goto error;
8004  }
8005 
8006  for (icounter = 0, i = 0; i < mpc_global->n_mpc; i++) {
8007  if (EVAL_BIT(mpc_flag[i], MASK)) {
8008  mpc_local->mpc_const[icounter] = mpc_global->mpc_const[i];
8009  icounter++;
8010  }
8011  }
8012  HECMW_assert(icounter == local_mesh->mpc->n_mpc);
8013 
8014  return RTC_NORMAL;
8015 
8016 error:
8017  return RTC_ERROR;
8018 }
8019 
8020 static int const_mpc_info(const struct hecmwST_local_mesh *global_mesh,
8021  struct hecmwST_local_mesh *local_mesh,
8022  const int *node_global2local) {
8023  char *mpc_flag = NULL;
8024  int rtc;
8025 
8026  HECMW_assert(global_mesh);
8027  HECMW_assert(global_mesh->mpc);
8028  HECMW_assert(local_mesh);
8029  HECMW_assert(local_mesh->mpc);
8030  HECMW_assert(node_global2local);
8031 
8032  if (global_mesh->mpc->n_mpc == 0) {
8033  init_struct_mpc(local_mesh);
8034  return RTC_NORMAL;
8035  }
8036 
8037  mpc_flag = (char *)HECMW_calloc(global_mesh->mpc->n_mpc, sizeof(char));
8038  if (mpc_flag == NULL) {
8039  HECMW_set_error(errno, "");
8040  goto error;
8041  }
8042 
8043  rtc = const_n_mpc(global_mesh, local_mesh, node_global2local, mpc_flag);
8044  if (rtc != RTC_NORMAL) goto error;
8045 
8046  if (local_mesh->mpc->n_mpc == 0) {
8047  init_struct_mpc(local_mesh);
8048  HECMW_free(mpc_flag);
8049  return RTC_NORMAL;
8050  }
8051 
8052  rtc = const_mpc_index(global_mesh, local_mesh, mpc_flag);
8053  if (rtc != RTC_NORMAL) goto error;
8054 
8055  rtc = const_mpc_item(global_mesh, local_mesh, node_global2local, mpc_flag);
8056  if (rtc != RTC_NORMAL) goto error;
8057 
8058  rtc = const_mpc_dof(global_mesh, local_mesh, mpc_flag);
8059  if (rtc != RTC_NORMAL) goto error;
8060 
8061  rtc = const_mpc_val(global_mesh, local_mesh, mpc_flag);
8062  if (rtc != RTC_NORMAL) goto error;
8063 
8064  rtc = const_mpc_const(global_mesh, local_mesh, mpc_flag);
8065  if (rtc != RTC_NORMAL) goto error;
8066 
8067  HECMW_free(mpc_flag);
8068 
8069  return RTC_NORMAL;
8070 
8071 error:
8072  HECMW_free(mpc_flag);
8073 
8074  return RTC_ERROR;
8075 }
8076 
8077 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8078  * - - - - - - - - - */
8079 
8080 static int const_n_amp(const struct hecmwST_local_mesh *global_mesh,
8081  struct hecmwST_local_mesh *local_mesh) {
8082  local_mesh->amp->n_amp = global_mesh->amp->n_amp;
8083 
8084  return RTC_NORMAL;
8085 }
8086 
8087 static int const_amp_name(const struct hecmwST_local_mesh *global_mesh,
8088  struct hecmwST_local_mesh *local_mesh) {
8089  local_mesh->amp->amp_name = global_mesh->amp->amp_name;
8090 
8091  return RTC_NORMAL;
8092 }
8093 
8094 static int const_amp_type_definition(
8095  const struct hecmwST_local_mesh *global_mesh,
8096  struct hecmwST_local_mesh *local_mesh) {
8097  local_mesh->amp->amp_type_definition = global_mesh->amp->amp_type_definition;
8098 
8099  return RTC_NORMAL;
8100 }
8101 
8102 static int const_amp_type_time(const struct hecmwST_local_mesh *global_mesh,
8103  struct hecmwST_local_mesh *local_mesh) {
8104  local_mesh->amp->amp_type_time = global_mesh->amp->amp_type_time;
8105 
8106  return RTC_NORMAL;
8107 }
8108 
8109 static int const_amp_type_value(const struct hecmwST_local_mesh *global_mesh,
8110  struct hecmwST_local_mesh *local_mesh) {
8111  local_mesh->amp->amp_type_value = global_mesh->amp->amp_type_value;
8112 
8113  return RTC_NORMAL;
8114 }
8115 
8116 static int const_amp_index(const struct hecmwST_local_mesh *global_mesh,
8117  struct hecmwST_local_mesh *local_mesh) {
8118  local_mesh->amp->amp_index = global_mesh->amp->amp_index;
8119 
8120  return RTC_NORMAL;
8121 }
8122 
8123 static int const_amp_val(const struct hecmwST_local_mesh *global_mesh,
8124  struct hecmwST_local_mesh *local_mesh) {
8125  local_mesh->amp->amp_val = global_mesh->amp->amp_val;
8126 
8127  return RTC_NORMAL;
8128 }
8129 
8130 static int const_amp_table(const struct hecmwST_local_mesh *global_mesh,
8131  struct hecmwST_local_mesh *local_mesh) {
8132  local_mesh->amp->amp_table = global_mesh->amp->amp_table;
8133 
8134  return RTC_NORMAL;
8135 }
8136 
8137 static int const_amp_info(const struct hecmwST_local_mesh *global_mesh,
8138  struct hecmwST_local_mesh *local_mesh) {
8139  int rtc;
8140 
8141  HECMW_assert(global_mesh);
8142  HECMW_assert(global_mesh->amp);
8143  HECMW_assert(local_mesh);
8144  HECMW_assert(local_mesh->amp);
8145 
8146  if (global_mesh->amp->n_amp == 0) {
8147  init_struct_amp(local_mesh);
8148  return RTC_NORMAL;
8149  }
8150 
8151  rtc = const_n_amp(global_mesh, local_mesh);
8152  if (rtc != RTC_NORMAL) goto error;
8153 
8154  rtc = const_amp_name(global_mesh, local_mesh);
8155  if (rtc != RTC_NORMAL) goto error;
8156 
8157  rtc = const_amp_type_definition(global_mesh, local_mesh);
8158  if (rtc != RTC_NORMAL) goto error;
8159 
8160  rtc = const_amp_type_time(global_mesh, local_mesh);
8161  if (rtc != RTC_NORMAL) goto error;
8162 
8163  rtc = const_amp_type_value(global_mesh, local_mesh);
8164  if (rtc != RTC_NORMAL) goto error;
8165 
8166  rtc = const_amp_index(global_mesh, local_mesh);
8167  if (rtc != RTC_NORMAL) goto error;
8168 
8169  rtc = const_amp_val(global_mesh, local_mesh);
8170  if (rtc != RTC_NORMAL) goto error;
8171 
8172  rtc = const_amp_table(global_mesh, local_mesh);
8173  if (rtc != RTC_NORMAL) goto error;
8174 
8175  return RTC_NORMAL;
8176 
8177 error:
8178  return RTC_ERROR;
8179 }
8180 
8181 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8182  * - - - - - - - - - */
8183 
8184 static int *const_node_grp_mask_eqn(
8185  const struct hecmwST_local_mesh *global_mesh,
8186  struct hecmwST_local_mesh *local_mesh, const int *node_global2local,
8187  int eqn_block_idx) {
8188  struct hecmwST_node_grp *node_group_global = global_mesh->node_group;
8189  int *n_eqn_item = NULL;
8190  int diff, evalsum;
8191  int i, j, is, ie, js;
8192 
8193  is = node_group_global->grp_index[eqn_block_idx];
8194  ie = node_group_global->grp_index[eqn_block_idx + 1];
8195 
8196  n_eqn_item = (int *)HECMW_malloc(sizeof(int) * (ie - is));
8197  if (n_eqn_item == NULL) {
8198  HECMW_set_error(errno, "");
8199  goto error;
8200  }
8201 
8202  for (js = 0, i = 0; i < ie - is; i++) {
8203  diff = node_group_global->grp_item[is + i] - js;
8204  for (evalsum = 0, j = js; j < node_group_global->grp_item[is + i]; j++) {
8205  if (node_global2local[j] > 0 &&
8206  node_global2local[j] <= local_mesh->nn_internal)
8207  evalsum++;
8208  }
8209 
8210  if (evalsum) {
8211  HECMW_assert(evalsum == diff);
8212  n_eqn_item[i] = diff;
8213  } else {
8214  n_eqn_item[i] = 0;
8215  }
8216 
8217  js = node_group_global->grp_item[is + i];
8218  }
8219 
8220  return n_eqn_item;
8221 
8222 error:
8223  return NULL;
8224 }
8225 
8226 static int const_node_n_grp(const struct hecmwST_local_mesh *global_mesh,
8227  struct hecmwST_local_mesh *local_mesh) {
8228  local_mesh->node_group->n_grp = global_mesh->node_group->n_grp;
8229 
8230  return RTC_NORMAL;
8231 }
8232 
8233 static int const_node_grp_name(const struct hecmwST_local_mesh *global_mesh,
8234  struct hecmwST_local_mesh *local_mesh) {
8235  local_mesh->node_group->grp_name = global_mesh->node_group->grp_name;
8236 
8237  return RTC_NORMAL;
8238 }
8239 
8240 static int const_node_grp_index(const struct hecmwST_local_mesh *global_mesh,
8241  struct hecmwST_local_mesh *local_mesh,
8242  const int *node_global2local,
8243  const int *n_eqn_item, int eqn_block_idx) {
8244  struct hecmwST_node_grp *node_group_global = global_mesh->node_group;
8245  struct hecmwST_node_grp *node_group_local = local_mesh->node_group;
8246  int node;
8247  int counter, diff;
8248  int i, j;
8249 
8250  node_group_local->grp_index =
8251  (int *)HECMW_calloc(node_group_local->n_grp + 1, sizeof(int));
8252  if (node_group_local->grp_index == NULL) {
8253  HECMW_set_error(errno, "");
8254  goto error;
8255  }
8256 
8257  for (counter = 0, i = 0; i < node_group_global->n_grp; i++) {
8258  if (i != eqn_block_idx) {
8259  for (j = node_group_global->grp_index[i];
8260  j < node_group_global->grp_index[i + 1]; j++) {
8261  node = node_group_global->grp_item[j];
8262  if (node_global2local[node - 1]) counter++;
8263  }
8264 
8265  } else {
8266  diff =
8267  node_group_global->grp_index[i + 1] - node_group_global->grp_index[i];
8268  for (j = 0; j < diff; j++) {
8269  if (n_eqn_item[j] > 0) counter++;
8270  }
8271  }
8272 
8273  node_group_local->grp_index[i + 1] = counter;
8274  }
8275 
8276  return RTC_NORMAL;
8277 
8278 error:
8279  return RTC_ERROR;
8280 }
8281 
8282 static int const_node_grp_index_mod(
8283  const struct hecmwST_local_mesh *global_mesh,
8284  struct hecmwST_local_mesh *local_mesh, const int *node_global2local,
8285  const int *n_eqn_item, int eqn_block_idx, int domain) {
8286  struct hecmwST_node_grp *node_group_global = global_mesh->node_group;
8287  struct hecmwST_node_grp *node_group_local = local_mesh->node_group;
8288  int counter, diff;
8289  int i, j;
8290 
8291  node_group_local->grp_index =
8292  (int *)HECMW_calloc(node_group_local->n_grp + 1, sizeof(int));
8293  if (node_group_local->grp_index == NULL) {
8294  HECMW_set_error(errno, "");
8295  goto error;
8296  }
8297 
8298  for (counter = 0, i = 0; i < node_group_global->n_grp; i++) {
8299  if (i != eqn_block_idx) {
8300  if (node_group_global->grp_index[i + 1] -
8301  node_group_global->grp_index[i] ==
8302  global_mesh->n_node) {
8303  counter += n_int_nlist[domain];
8304  counter += n_bnd_nlist[2 * domain + 1] - n_bnd_nlist[2 * domain];
8305  } else {
8306  counter += ngrp_idx[domain][i + 1] - ngrp_idx[domain][i];
8307  }
8308 
8309  } else {
8310  diff =
8311  node_group_global->grp_index[i + 1] - node_group_global->grp_index[i];
8312  for (j = 0; j < diff; j++) {
8313  if (n_eqn_item[j] > 0) counter++;
8314  }
8315  }
8316 
8317  node_group_local->grp_index[i + 1] = counter;
8318  }
8319 
8320  return RTC_NORMAL;
8321 
8322 error:
8323  return RTC_ERROR;
8324 }
8325 
8326 static int const_node_grp_item(const struct hecmwST_local_mesh *global_mesh,
8327  struct hecmwST_local_mesh *local_mesh,
8328  const int *node_global2local,
8329  const int *n_eqn_item, int eqn_block_idx) {
8330  struct hecmwST_node_grp *node_group_global = global_mesh->node_group;
8331  struct hecmwST_node_grp *node_group_local = local_mesh->node_group;
8332  int node;
8333  int size;
8334  int counter;
8335  int i, j, k, js, je, ks, ls;
8336 
8337  size = sizeof(int) * node_group_local->grp_index[node_group_local->n_grp];
8338  node_group_local->grp_item = (int *)HECMW_malloc(size);
8339  if (node_group_local->grp_item == NULL) {
8340  HECMW_set_error(errno, "");
8341  goto error;
8342  }
8343 
8344  for (counter = 0, i = 0; i < node_group_global->n_grp; i++) {
8345  if (i != eqn_block_idx) {
8346  for (j = node_group_global->grp_index[i];
8347  j < node_group_global->grp_index[i + 1]; j++) {
8348  node = node_group_global->grp_item[j];
8349  if (node_global2local[node - 1]) {
8350  node_group_local->grp_item[counter++] = node_global2local[node - 1];
8351  }
8352  }
8353 
8354  } else {
8355  js = node_group_global->grp_index[i];
8356  je = node_group_global->grp_index[i + 1];
8357  for (ks = 0, ls = 0, j = js; j < je; j++) {
8358  if (n_eqn_item[j - js]) {
8359  HECMW_assert(n_eqn_item[j - js] ==
8360  node_group_global->grp_item[j] - ks);
8361  node_group_local->grp_item[counter] = ls + n_eqn_item[j - js];
8362 
8363  for (k = ks; k < node_group_global->grp_item[j]; k++) {
8364  HECMW_assert(ls < node_global2local[k] &&
8365  node_global2local[k] <=
8366  node_group_local->grp_item[counter]);
8367  }
8368  ls = node_group_local->grp_item[counter];
8369  counter++;
8370  }
8371  ks = node_group_global->grp_item[j];
8372  }
8373  }
8374  HECMW_assert(counter == node_group_local->grp_index[i + 1]);
8375  }
8376 
8377  return RTC_NORMAL;
8378 
8379 error:
8380  return RTC_ERROR;
8381 }
8382 
8383 static int const_node_grp_item_mod(const struct hecmwST_local_mesh *global_mesh,
8384  struct hecmwST_local_mesh *local_mesh,
8385  const int *node_global2local,
8386  const int *n_eqn_item, int eqn_block_idx,
8387  int domain) {
8388  struct hecmwST_node_grp *node_group_global = global_mesh->node_group;
8389  struct hecmwST_node_grp *node_group_local = local_mesh->node_group;
8390  int node;
8391  int size;
8392  int counter;
8393  int i, j, k, js, je, ks, ls;
8394  int idx1, idx2, node1, node2, n_int, n_bnd, n_out, maxn;
8395 
8396  size = sizeof(int) * node_group_local->grp_index[node_group_local->n_grp];
8397  node_group_local->grp_item = (int *)HECMW_malloc(size);
8398  if (node_group_local->grp_item == NULL) {
8399  HECMW_set_error(errno, "");
8400  goto error;
8401  }
8402 
8403  n_int = n_int_nlist[domain];
8404  n_bnd = n_bnd_nlist[2 * domain];
8405  n_out = n_bnd_nlist[2 * domain + 1] - n_bnd_nlist[2 * domain];
8406  maxn = global_mesh->n_node + 1;
8407 
8408  for (counter = 0, i = 0; i < node_group_global->n_grp; i++) {
8409  if (i != eqn_block_idx) {
8410  if (node_group_global->grp_index[i + 1] -
8411  node_group_global->grp_index[i] ==
8412  global_mesh->n_node) {
8413  idx1 = 0;
8414  idx2 = 0;
8415  node1 = (n_int == 0) ? maxn : int_nlist[domain][0];
8416  node2 = (n_out == 0) ? maxn : bnd_nlist[domain][n_bnd];
8417  for (j = 0; j < n_int + n_out; j++) {
8418  if (node1 < node2) {
8419  node_group_local->grp_item[counter++] =
8420  node_global2local[node1 - 1];
8421  idx1++;
8422  node1 = (idx1 == n_int) ? maxn : int_nlist[domain][idx1];
8423  } else {
8424  node_group_local->grp_item[counter++] =
8425  node_global2local[node2 - 1];
8426  idx2++;
8427  node2 = (idx2 == n_out) ? maxn : bnd_nlist[domain][idx2 + n_bnd];
8428  }
8429  }
8430  } else {
8431  if (ngrp_idx[domain][i + 1] - ngrp_idx[domain][i] == 0) continue;
8432  for (j = ngrp_idx[domain][i]; j < ngrp_idx[domain][i + 1]; j++) {
8433  node = ngrp_item[domain][j];
8434  node_group_local->grp_item[counter++] = node_global2local[node - 1];
8435  }
8436  }
8437  } else {
8438  js = node_group_global->grp_index[i];
8439  je = node_group_global->grp_index[i + 1];
8440  for (ks = 0, ls = 0, j = js; j < je; j++) {
8441  if (n_eqn_item[j - js]) {
8442  HECMW_assert(n_eqn_item[j - js] ==
8443  node_group_global->grp_item[j] - ks);
8444  node_group_local->grp_item[counter] = ls + n_eqn_item[j - js];
8445 
8446  for (k = ks; k < node_group_global->grp_item[j]; k++) {
8447  HECMW_assert(ls < node_global2local[k] &&
8448  node_global2local[k] <=
8449  node_group_local->grp_item[counter]);
8450  }
8451  ls = node_group_local->grp_item[counter];
8452  counter++;
8453  }
8454  ks = node_group_global->grp_item[j];
8455  }
8456  }
8457  HECMW_assert(counter == node_group_local->grp_index[i + 1]);
8458  }
8459 
8460  return RTC_NORMAL;
8461 
8462 error:
8463  return RTC_ERROR;
8464 }
8465 
8466 static int const_node_grp_info(const struct hecmwST_local_mesh *global_mesh,
8467  struct hecmwST_local_mesh *local_mesh,
8468  const int *node_global2local,
8469  int current_domain) {
8470  int *n_eqn_item = NULL;
8471  int eqn_block_idx;
8472  int rtc;
8473 
8474  HECMW_assert(global_mesh);
8475  HECMW_assert(global_mesh->node_group);
8476  HECMW_assert(local_mesh);
8477  HECMW_assert(local_mesh->node_group);
8478  HECMW_assert(node_global2local);
8479 
8480  if (global_mesh->node_group->n_grp == 0) {
8481  init_struct_node_grp(local_mesh);
8482  return RTC_NORMAL;
8483  }
8484 
8485  eqn_block_idx = search_eqn_block_idx(global_mesh);
8486 
8487  if (eqn_block_idx >= 0) {
8488  n_eqn_item = const_node_grp_mask_eqn(global_mesh, local_mesh,
8489  node_global2local, eqn_block_idx);
8490  if (n_eqn_item == NULL) goto error;
8491  }
8492 
8493  rtc = const_node_n_grp(global_mesh, local_mesh);
8494  if (rtc != RTC_NORMAL) goto error;
8495 
8496  rtc = const_node_grp_name(global_mesh, local_mesh);
8497  if (rtc != RTC_NORMAL) goto error;
8498 
8499  if (is_spdup_available(global_mesh)) {
8500  rtc = const_node_grp_index_mod(global_mesh, local_mesh, node_global2local,
8501  n_eqn_item, eqn_block_idx, current_domain);
8502  if (rtc != RTC_NORMAL) goto error;
8503  rtc = const_node_grp_item_mod(global_mesh, local_mesh, node_global2local,
8504  n_eqn_item, eqn_block_idx, current_domain);
8505  if (rtc != RTC_NORMAL) goto error;
8506 
8507  } else {
8508  rtc = const_node_grp_index(global_mesh, local_mesh, node_global2local,
8509  n_eqn_item, eqn_block_idx);
8510  if (rtc != RTC_NORMAL) goto error;
8511  rtc = const_node_grp_item(global_mesh, local_mesh, node_global2local,
8512  n_eqn_item, eqn_block_idx);
8513  if (rtc != RTC_NORMAL) goto error;
8514  }
8515 
8516  HECMW_free(n_eqn_item);
8517 
8518  return RTC_NORMAL;
8519 
8520 error:
8521  HECMW_free(n_eqn_item);
8522 
8523  return RTC_ERROR;
8524 }
8525 
8526 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8527  * - - - - - - - - - */
8528 
8529 static int const_elem_n_grp(const struct hecmwST_local_mesh *global_mesh,
8530  struct hecmwST_local_mesh *local_mesh) {
8531  local_mesh->elem_group->n_grp = global_mesh->elem_group->n_grp;
8532 
8533  return RTC_NORMAL;
8534 }
8535 
8536 static int const_elem_grp_name(const struct hecmwST_local_mesh *global_mesh,
8537  struct hecmwST_local_mesh *local_mesh) {
8538  local_mesh->elem_group->grp_name = global_mesh->elem_group->grp_name;
8539 
8540  return RTC_NORMAL;
8541 }
8542 
8543 static int const_elem_grp_index(const struct hecmwST_local_mesh *global_mesh,
8544  struct hecmwST_local_mesh *local_mesh,
8545  const int *elem_global2local) {
8546  struct hecmwST_elem_grp *elem_group_global = global_mesh->elem_group;
8547  struct hecmwST_elem_grp *elem_group_local = local_mesh->elem_group;
8548  int elem;
8549  int counter;
8550  int i, j;
8551 
8552  elem_group_local->grp_index =
8553  (int *)HECMW_calloc(elem_group_local->n_grp + 1, sizeof(int));
8554  if (elem_group_local->grp_index == NULL) {
8555  HECMW_set_error(errno, "");
8556  goto error;
8557  }
8558 
8559  for (counter = 0, i = 0; i < elem_group_global->n_grp; i++) {
8560  for (j = elem_group_global->grp_index[i];
8561  j < elem_group_global->grp_index[i + 1]; j++) {
8562  elem = elem_group_global->grp_item[j];
8563  if (elem_global2local[elem - 1]) counter++;
8564  }
8565  elem_group_local->grp_index[i + 1] = counter;
8566  }
8567 
8568  return RTC_NORMAL;
8569 
8570 error:
8571  return RTC_ERROR;
8572 }
8573 
8574 static int const_elem_grp_index_mod(
8575  const struct hecmwST_local_mesh *global_mesh,
8576  struct hecmwST_local_mesh *local_mesh, const int *elem_global2local,
8577  int domain) {
8578  struct hecmwST_elem_grp *elem_group_global = global_mesh->elem_group;
8579  struct hecmwST_elem_grp *elem_group_local = local_mesh->elem_group;
8580  int counter;
8581  int i;
8582 
8583  elem_group_local->grp_index =
8584  (int *)HECMW_calloc(elem_group_local->n_grp + 1, sizeof(int));
8585  if (elem_group_local->grp_index == NULL) {
8586  HECMW_set_error(errno, "");
8587  goto error;
8588  }
8589 
8590  for (counter = 0, i = 0; i < elem_group_global->n_grp; i++) {
8591  if (elem_group_global->grp_index[i + 1] - elem_group_global->grp_index[i] ==
8592  global_mesh->n_elem) {
8593  counter += n_int_elist[domain];
8594  counter += n_bnd_elist[2 * domain + 1] - n_bnd_elist[2 * domain];
8595  } else {
8596  counter += egrp_idx[domain][i + 1] - egrp_idx[domain][i];
8597  }
8598  elem_group_local->grp_index[i + 1] = counter;
8599  }
8600 
8601  return RTC_NORMAL;
8602 
8603 error:
8604  return RTC_ERROR;
8605 }
8606 
8607 static int const_elem_grp_item(const struct hecmwST_local_mesh *global_mesh,
8608  struct hecmwST_local_mesh *local_mesh,
8609  const int *elem_global2local) {
8610  struct hecmwST_elem_grp *elem_group_global = global_mesh->elem_group;
8611  struct hecmwST_elem_grp *elem_group_local = local_mesh->elem_group;
8612  int elem;
8613  int size;
8614  int counter;
8615  int i, j;
8616 
8617  size = sizeof(int) * elem_group_local->grp_index[elem_group_local->n_grp];
8618  elem_group_local->grp_item = (int *)HECMW_malloc(size);
8619  if (local_mesh->elem_group->grp_item == NULL) {
8620  HECMW_set_error(errno, "");
8621  goto error;
8622  }
8623 
8624  for (counter = 0, i = 0; i < elem_group_global->n_grp; i++) {
8625  for (j = elem_group_global->grp_index[i];
8626  j < elem_group_global->grp_index[i + 1]; j++) {
8627  elem = elem_group_global->grp_item[j];
8628  if (elem_global2local[elem - 1]) {
8629  elem_group_local->grp_item[counter++] = elem_global2local[elem - 1];
8630  }
8631  }
8632  HECMW_assert(counter == elem_group_local->grp_index[i + 1]);
8633  }
8634 
8635  return RTC_NORMAL;
8636 
8637 error:
8638  return RTC_ERROR;
8639 }
8640 
8641 static int const_elem_grp_item_mod(const struct hecmwST_local_mesh *global_mesh,
8642  struct hecmwST_local_mesh *local_mesh,
8643  const int *elem_global2local, int domain) {
8644  struct hecmwST_elem_grp *elem_group_global = global_mesh->elem_group;
8645  struct hecmwST_elem_grp *elem_group_local = local_mesh->elem_group;
8646  int elem;
8647  int size;
8648  int counter;
8649  int i, j, idx1, idx2, elem1, elem2, n_int, n_bnd, n_out, maxe;
8650 
8651  size = sizeof(int) * elem_group_local->grp_index[elem_group_local->n_grp];
8652  elem_group_local->grp_item = (int *)HECMW_malloc(size);
8653  if (local_mesh->elem_group->grp_item == NULL) {
8654  HECMW_set_error(errno, "");
8655  goto error;
8656  }
8657 
8658  n_int = n_int_elist[domain];
8659  n_bnd = n_bnd_elist[2 * domain];
8660  n_out = n_bnd_elist[2 * domain + 1] - n_bnd_elist[2 * domain];
8661  maxe = global_mesh->n_elem + 1;
8662 
8663  for (counter = 0, i = 0; i < elem_group_global->n_grp; i++) {
8664  if (elem_group_global->grp_index[i + 1] - elem_group_global->grp_index[i] ==
8665  global_mesh->n_elem) {
8666  elem1 = (n_int == 0) ? maxe : int_elist[domain][0];
8667  elem2 = (n_out == 0) ? maxe : bnd_elist[domain][n_bnd];
8668  for (idx1 = 0, idx2 = 0, j = 0; j < n_int + n_out; j++) {
8669  if (elem1 < elem2) {
8670  elem_group_local->grp_item[counter++] = elem_global2local[elem1 - 1];
8671  idx1++;
8672  elem1 = (idx1 == n_int) ? maxe : int_elist[domain][idx1];
8673  } else {
8674  elem_group_local->grp_item[counter++] = elem_global2local[elem2 - 1];
8675  idx2++;
8676  elem2 = (idx2 == n_out) ? maxe : bnd_elist[domain][idx2 + n_bnd];
8677  }
8678  }
8679  } else {
8680  if (egrp_idx[domain][i + 1] - egrp_idx[domain][i] == 0) continue;
8681  for (j = egrp_idx[domain][i]; j < egrp_idx[domain][i + 1]; j++) {
8682  elem = egrp_item[domain][j];
8683  elem_group_local->grp_item[counter++] = elem_global2local[elem - 1];
8684  }
8685  }
8686  HECMW_assert(counter == elem_group_local->grp_index[i + 1]);
8687  }
8688 
8689  return RTC_NORMAL;
8690 
8691 error:
8692  return RTC_ERROR;
8693 }
8694 
8695 static int const_elem_grp_info(const struct hecmwST_local_mesh *global_mesh,
8696  struct hecmwST_local_mesh *local_mesh,
8697  const int *elem_global2local,
8698  int current_domain) {
8699  int rtc;
8700 
8701  HECMW_assert(global_mesh);
8702  HECMW_assert(global_mesh->elem_group);
8703  HECMW_assert(local_mesh);
8704  HECMW_assert(local_mesh->elem_group);
8705  HECMW_assert(elem_global2local);
8706 
8707  if (global_mesh->elem_group->n_grp == 0) {
8708  init_struct_elem_grp(local_mesh);
8709  return RTC_NORMAL;
8710  }
8711 
8712  rtc = const_elem_n_grp(global_mesh, local_mesh);
8713  if (rtc != RTC_NORMAL) goto error;
8714 
8715  rtc = const_elem_grp_name(global_mesh, local_mesh);
8716  if (rtc != RTC_NORMAL) goto error;
8717 
8718  if (is_spdup_available(global_mesh)) {
8719  rtc = const_elem_grp_index_mod(global_mesh, local_mesh, elem_global2local,
8720  current_domain);
8721  if (rtc != RTC_NORMAL) goto error;
8722  rtc = const_elem_grp_item_mod(global_mesh, local_mesh, elem_global2local,
8723  current_domain);
8724  if (rtc != RTC_NORMAL) goto error;
8725 
8726  } else {
8727  rtc = const_elem_grp_index(global_mesh, local_mesh, elem_global2local);
8728  if (rtc != RTC_NORMAL) goto error;
8729  rtc = const_elem_grp_item(global_mesh, local_mesh, elem_global2local);
8730  if (rtc != RTC_NORMAL) goto error;
8731  }
8732 
8733  return RTC_NORMAL;
8734 
8735 error:
8736  return RTC_ERROR;
8737 }
8738 
8739 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8740  * - - - - - - - - - */
8741 
8742 static int const_surf_n_grp(const struct hecmwST_local_mesh *global_mesh,
8743  struct hecmwST_local_mesh *local_mesh) {
8744  local_mesh->surf_group->n_grp = global_mesh->surf_group->n_grp;
8745 
8746  return RTC_NORMAL;
8747 }
8748 
8749 static int const_surf_grp_name(const struct hecmwST_local_mesh *global_mesh,
8750  struct hecmwST_local_mesh *local_mesh) {
8751  local_mesh->surf_group->grp_name = global_mesh->surf_group->grp_name;
8752 
8753  return RTC_NORMAL;
8754 }
8755 
8756 static int const_surf_grp_index(const struct hecmwST_local_mesh *global_mesh,
8757  struct hecmwST_local_mesh *local_mesh,
8758  const int *elem_global2local) {
8759  struct hecmwST_surf_grp *surf_group_global = global_mesh->surf_group;
8760  struct hecmwST_surf_grp *surf_group_local = local_mesh->surf_group;
8761  int elem;
8762  int counter;
8763  int i, j;
8764 
8765  surf_group_local->grp_index =
8766  (int *)HECMW_calloc(surf_group_local->n_grp + 1, sizeof(int));
8767  if (surf_group_local->grp_index == NULL) {
8768  HECMW_set_error(errno, "");
8769  goto error;
8770  }
8771 
8772  for (counter = 0, i = 0; i < surf_group_global->n_grp; i++) {
8773  for (j = surf_group_global->grp_index[i];
8774  j < surf_group_global->grp_index[i + 1]; j++) {
8775  elem = surf_group_global->grp_item[2 * j];
8776  if (elem_global2local[elem - 1]) counter++;
8777  }
8778  surf_group_local->grp_index[i + 1] = counter;
8779  }
8780 
8781  return RTC_NORMAL;
8782 
8783 error:
8784  return RTC_ERROR;
8785 }
8786 
8787 static int const_surf_grp_item(const struct hecmwST_local_mesh *global_mesh,
8788  struct hecmwST_local_mesh *local_mesh,
8789  const int *elem_global2local) {
8790  struct hecmwST_surf_grp *surf_group_global = global_mesh->surf_group;
8791  struct hecmwST_surf_grp *surf_group_local = local_mesh->surf_group;
8792  int elem, surf;
8793  int size;
8794  int counter;
8795  int i, j;
8796 
8797  size = sizeof(int) * (size_t)surf_group_local->grp_index[surf_group_local->n_grp] * 2;
8798  surf_group_local->grp_item = (int *)HECMW_malloc(size);
8799  if (surf_group_local->grp_item == NULL) {
8800  HECMW_set_error(errno, "");
8801  goto error;
8802  }
8803 
8804  for (counter = 0, i = 0; i < surf_group_global->n_grp; i++) {
8805  for (j = surf_group_global->grp_index[i];
8806  j < surf_group_global->grp_index[i + 1]; j++) {
8807  elem = surf_group_global->grp_item[2 * j];
8808  surf = surf_group_global->grp_item[2 * j + 1];
8809  if (elem_global2local[elem - 1]) {
8810  surf_group_local->grp_item[2 * counter] = elem_global2local[elem - 1];
8811  surf_group_local->grp_item[2 * counter + 1] = surf;
8812  counter++;
8813  }
8814  }
8815  HECMW_assert(counter == surf_group_local->grp_index[i + 1]);
8816  }
8817 
8818  return RTC_NORMAL;
8819 
8820 error:
8821  return RTC_ERROR;
8822 }
8823 
8824 static int const_surf_grp_info(const struct hecmwST_local_mesh *global_mesh,
8825  struct hecmwST_local_mesh *local_mesh,
8826  const int *elem_global2local) {
8827  int rtc;
8828 
8829  HECMW_assert(global_mesh);
8830  HECMW_assert(global_mesh->surf_group);
8831  HECMW_assert(local_mesh);
8832  HECMW_assert(local_mesh->surf_group);
8833  HECMW_assert(elem_global2local);
8834 
8835  if (global_mesh->surf_group->n_grp == 0) {
8836  init_struct_surf_grp(local_mesh);
8837  return RTC_NORMAL;
8838  }
8839 
8840  rtc = const_surf_n_grp(global_mesh, local_mesh);
8841  if (rtc != RTC_NORMAL) goto error;
8842 
8843  rtc = const_surf_grp_name(global_mesh, local_mesh);
8844  if (rtc != RTC_NORMAL) goto error;
8845 
8846  rtc = const_surf_grp_index(global_mesh, local_mesh, elem_global2local);
8847  if (rtc != RTC_NORMAL) goto error;
8848 
8849  rtc = const_surf_grp_item(global_mesh, local_mesh, elem_global2local);
8850  if (rtc != RTC_NORMAL) goto error;
8851 
8852  return RTC_NORMAL;
8853 
8854 error:
8855  return RTC_ERROR;
8856 }
8857 
8858 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8859  * - - - - - - - - - */
8860 
8861 static int const_contact_pair_n_pair(
8862  const struct hecmwST_local_mesh *global_mesh,
8863  struct hecmwST_local_mesh *local_mesh) {
8864  local_mesh->contact_pair->n_pair = global_mesh->contact_pair->n_pair;
8865 
8866  return RTC_NORMAL;
8867 }
8868 
8869 static int const_contact_pair_name(const struct hecmwST_local_mesh *global_mesh,
8870  struct hecmwST_local_mesh *local_mesh) {
8871  local_mesh->contact_pair->name = global_mesh->contact_pair->name;
8872 
8873  return RTC_NORMAL;
8874 }
8875 
8876 static int const_contact_pair_type(const struct hecmwST_local_mesh *global_mesh,
8877  struct hecmwST_local_mesh *local_mesh) {
8878  struct hecmwST_contact_pair *cpair_global = global_mesh->contact_pair;
8879  struct hecmwST_contact_pair *cpair_local = local_mesh->contact_pair;
8880  int i;
8881 
8882  cpair_local->type = (int *)HECMW_calloc(cpair_local->n_pair, sizeof(int));
8883  if (cpair_local->type == NULL) {
8884  HECMW_set_error(errno, "");
8885  goto error;
8886  }
8887 
8888  for (i = 0; i < cpair_global->n_pair; i++) {
8889  cpair_local->type[i] = cpair_global->type[i];
8890  }
8891 
8892  return RTC_NORMAL;
8893 
8894 error:
8895  return RTC_ERROR;
8896 }
8897 
8898 static int const_contact_pair_slave_grp_id(
8899  const struct hecmwST_local_mesh *global_mesh,
8900  struct hecmwST_local_mesh *local_mesh) {
8901  struct hecmwST_contact_pair *cpair_global = global_mesh->contact_pair;
8902  struct hecmwST_contact_pair *cpair_local = local_mesh->contact_pair;
8903  int i;
8904 
8905  cpair_local->slave_grp_id =
8906  (int *)HECMW_calloc(cpair_local->n_pair, sizeof(int));
8907  if (cpair_local->slave_grp_id == NULL) {
8908  HECMW_set_error(errno, "");
8909  goto error;
8910  }
8911 
8912  for (i = 0; i < cpair_global->n_pair; i++) {
8913  cpair_local->slave_grp_id[i] = cpair_global->slave_grp_id[i];
8914  }
8915 
8916  return RTC_NORMAL;
8917 
8918 error:
8919  return RTC_ERROR;
8920 }
8921 
8922 static int const_contact_pair_slave_orisgrp_id(
8923  const struct hecmwST_local_mesh *global_mesh,
8924  struct hecmwST_local_mesh *local_mesh) {
8925  struct hecmwST_contact_pair *cpair_global = global_mesh->contact_pair;
8926  struct hecmwST_contact_pair *cpair_local = local_mesh->contact_pair;
8927  int i;
8928 
8929  cpair_local->slave_orisgrp_id =
8930  (int *)HECMW_calloc(cpair_local->n_pair, sizeof(int));
8931  if (cpair_local->slave_orisgrp_id == NULL) {
8932  HECMW_set_error(errno, "");
8933  goto error;
8934  }
8935 
8936  for (i = 0; i < cpair_global->n_pair; i++) {
8937  cpair_local->slave_orisgrp_id[i] = cpair_global->slave_orisgrp_id[i];
8938  }
8939 
8940  return RTC_NORMAL;
8941 
8942 error:
8943  return RTC_ERROR;
8944 }
8945 
8946 static int const_contact_pair_master_grp_id(
8947  const struct hecmwST_local_mesh *global_mesh,
8948  struct hecmwST_local_mesh *local_mesh) {
8949  struct hecmwST_contact_pair *cpair_global = global_mesh->contact_pair;
8950  struct hecmwST_contact_pair *cpair_local = local_mesh->contact_pair;
8951  int i;
8952 
8953  cpair_local->master_grp_id =
8954  (int *)HECMW_calloc(cpair_local->n_pair, sizeof(int));
8955  if (cpair_local->master_grp_id == NULL) {
8956  HECMW_set_error(errno, "");
8957  goto error;
8958  }
8959 
8960  for (i = 0; i < cpair_global->n_pair; i++) {
8961  cpair_local->master_grp_id[i] = cpair_global->master_grp_id[i];
8962  }
8963 
8964  return RTC_NORMAL;
8965 
8966 error:
8967  return RTC_ERROR;
8968 }
8969 
8970 static int const_contact_pair_info(const struct hecmwST_local_mesh *global_mesh,
8971  struct hecmwST_local_mesh *local_mesh) {
8972  int rtc;
8973 
8974  HECMW_assert(global_mesh);
8975  HECMW_assert(global_mesh->contact_pair);
8976  HECMW_assert(local_mesh);
8977  HECMW_assert(local_mesh->contact_pair);
8978 
8979  if (global_mesh->contact_pair->n_pair == 0) {
8980  init_struct_contact_pair(local_mesh);
8981  return RTC_NORMAL;
8982  }
8983 
8984  rtc = const_contact_pair_n_pair(global_mesh, local_mesh);
8985  if (rtc != RTC_NORMAL) goto error;
8986 
8987  rtc = const_contact_pair_name(global_mesh, local_mesh);
8988  if (rtc != RTC_NORMAL) goto error;
8989 
8990  rtc = const_contact_pair_type(global_mesh, local_mesh);
8991  if (rtc != RTC_NORMAL) goto error;
8992 
8993  rtc = const_contact_pair_slave_grp_id(global_mesh, local_mesh);
8994  if (rtc != RTC_NORMAL) goto error;
8995 
8996  rtc = const_contact_pair_slave_orisgrp_id(global_mesh, local_mesh);
8997  if (rtc != RTC_NORMAL) goto error;
8998 
8999  rtc = const_contact_pair_master_grp_id(global_mesh, local_mesh);
9000  if (rtc != RTC_NORMAL) goto error;
9001 
9002  return RTC_NORMAL;
9003 
9004 error:
9005  return RTC_ERROR;
9006 }
9007 
9008 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9009  * - - - - - - - - - */
9010 
9011 static int const_local_data(const struct hecmwST_local_mesh *global_mesh,
9012  struct hecmwST_local_mesh *local_mesh,
9013  const struct hecmw_part_cont_data *cont_data,
9014  const char *node_flag, const char *elem_flag,
9015  int *node_global2local, int *elem_global2local,
9016  int current_domain) {
9017  int *node_local2global = NULL;
9018  int *elem_local2global = NULL;
9019  int rtc;
9020 
9021  HECMW_log(HECMW_LOG_DEBUG, "Starting creation of local mesh data...\n");
9022 
9023  rtc = set_node_global2local(global_mesh, local_mesh, node_global2local,
9024  node_flag, current_domain);
9025  if (rtc != RTC_NORMAL) goto error;
9026 
9027  node_local2global = (int *)HECMW_calloc(local_mesh->n_node, sizeof(int));
9028  if (node_local2global == NULL) {
9029  HECMW_set_error(errno, "");
9030  goto error;
9031  }
9032 
9033  if (is_spdup_available(global_mesh)) {
9034  rtc = set_node_local2global_mod(global_mesh, local_mesh, node_global2local,
9035  node_local2global, current_domain);
9036  } else {
9037  rtc = set_node_local2global(global_mesh, local_mesh, node_global2local,
9038  node_local2global);
9039  }
9040 
9041  if (rtc != RTC_NORMAL) goto error;
9042 
9043  rtc = set_elem_global2local(global_mesh, local_mesh, elem_global2local,
9044  elem_flag, current_domain);
9045 
9046  if (rtc != RTC_NORMAL) goto error;
9047 
9048  elem_local2global = (int *)HECMW_calloc(local_mesh->n_elem, sizeof(int));
9049  if (elem_local2global == NULL) {
9050  HECMW_set_error(errno, "");
9051  goto error;
9052  }
9053 
9054  if (is_spdup_available(global_mesh)) {
9055  rtc = set_elem_local2global_mod(global_mesh, local_mesh, elem_global2local,
9056  elem_local2global, current_domain);
9057  } else {
9058  rtc = set_elem_local2global(global_mesh, local_mesh, elem_global2local,
9059  elem_local2global);
9060  }
9061 
9062  if (rtc != RTC_NORMAL) goto error;
9063 
9064  rtc = const_global_info(global_mesh, local_mesh);
9065  if (rtc != RTC_NORMAL) goto error;
9066 
9067  rtc = const_node_info(global_mesh, local_mesh, node_local2global, node_flag,
9068  current_domain);
9069  if (rtc != RTC_NORMAL) goto error;
9070 
9071  rtc = const_elem_info(global_mesh, local_mesh, node_global2local,
9072  elem_global2local, elem_local2global, current_domain);
9073 
9074  if (rtc != RTC_NORMAL) goto error;
9075  rtc = const_comm_info(global_mesh, local_mesh, node_global2local,
9076  elem_global2local, current_domain);
9077  if (rtc != RTC_NORMAL) goto error;
9078 
9079  rtc = const_adapt_info(global_mesh, local_mesh);
9080  if (rtc != RTC_NORMAL) goto error;
9081 
9082  rtc = const_sect_info(global_mesh, local_mesh);
9083  if (rtc != RTC_NORMAL) goto error;
9084 
9085  rtc = const_mat_info(global_mesh, local_mesh);
9086  if (rtc != RTC_NORMAL) goto error;
9087 
9088  rtc = const_mpc_info(global_mesh, local_mesh, node_global2local);
9089  if (rtc != RTC_NORMAL) goto error;
9090 
9091  rtc = const_amp_info(global_mesh, local_mesh);
9092  if (rtc != RTC_NORMAL) goto error;
9093 
9094  rtc = const_node_grp_info(global_mesh, local_mesh, node_global2local,
9095  current_domain);
9096  if (rtc != RTC_NORMAL) goto error;
9097 
9098  rtc = const_elem_grp_info(global_mesh, local_mesh, elem_global2local,
9099  current_domain);
9100  if (rtc != RTC_NORMAL) goto error;
9101 
9102  rtc = const_surf_grp_info(global_mesh, local_mesh, elem_global2local);
9103  if (rtc != RTC_NORMAL) goto error;
9104 
9105  rtc = const_contact_pair_info(global_mesh, local_mesh);
9106  if (rtc != RTC_NORMAL) goto error;
9107 
9108  rtc = clear_node_global2local(global_mesh, local_mesh, node_global2local,
9109  current_domain);
9110  rtc = clear_elem_global2local(global_mesh, local_mesh, elem_global2local,
9111  current_domain);
9112 
9113  HECMW_free(node_local2global);
9114  HECMW_free(elem_local2global);
9115 
9116  HECMW_log(HECMW_LOG_DEBUG, "Creation of local mesh data done\n");
9117 
9118  return RTC_NORMAL;
9119 
9120 error:
9121  HECMW_free(node_local2global);
9122  HECMW_free(elem_local2global);
9123  clean_struct_local_mesh(local_mesh);
9124 
9125  return RTC_ERROR;
9126 }
9127 
9128 /*==================================================================================================
9129 
9130  print UCD format data
9131 
9132 ==================================================================================================*/
9133 
9134 static int print_ucd_entire_set_node_data(
9135  const struct hecmwST_local_mesh *global_mesh,
9136  struct hecmwST_result_data *result_data, const char *node_flag) {
9137  int size;
9138  int nn_item;
9139  int i;
9140  const size_t label_len = HECMW_NAME_LEN + 1;
9141 
9142  result_data->nn_component = 1;
9143 
9144  result_data->nn_dof =
9145  (int *)HECMW_malloc(sizeof(int) * result_data->nn_component);
9146  if (result_data->nn_dof == NULL) {
9147  HECMW_set_error(errno, "");
9148  goto error;
9149  }
9150  result_data->nn_dof[0] = 1;
9151 
9152  result_data->node_label =
9153  (char **)HECMW_malloc(sizeof(char *) * result_data->nn_component);
9154  if (result_data->node_label == NULL) {
9155  HECMW_set_error(errno, "");
9156  goto error;
9157  } else {
9158  for (i = 0; i < result_data->nn_component; i++) {
9159  result_data->node_label[i] = NULL;
9160  }
9161  }
9162  for (i = 0; i < result_data->nn_component; i++) {
9163  result_data->node_label[i] =
9164  (char *)HECMW_malloc(sizeof(char) * label_len);
9165  if (result_data->node_label[i] == NULL) {
9166  HECMW_set_error(errno, "");
9167  goto error;
9168  }
9169  }
9170  snprintf(result_data->node_label[0], label_len, "rank_of_node");
9171 
9172  for (nn_item = 0, i = 0; i < result_data->nn_component; i++) {
9173  nn_item += result_data->nn_dof[i];
9174  }
9175 
9176  size = sizeof(double) * nn_item * global_mesh->n_node;
9177  result_data->node_val_item = (double *)HECMW_malloc(size);
9178  if (result_data->node_val_item == NULL) {
9179  HECMW_set_error(errno, "");
9180  goto error;
9181  }
9182 
9183  switch (global_mesh->hecmw_flag_parttype) {
9185  for (i = 0; i < global_mesh->n_node; i++) {
9186  result_data->node_val_item[i] = (double)global_mesh->node_ID[2 * i + 1];
9187  }
9188  break;
9189 
9191  for (i = 0; i < global_mesh->n_node; i++) {
9192  if (EVAL_BIT(node_flag[i], OVERLAP)) {
9193  result_data->node_val_item[i] =
9194  (double)global_mesh->n_subdomain + 2.0;
9195  } else {
9196  result_data->node_val_item[i] =
9197  (double)global_mesh->node_ID[2 * i + 1];
9198  }
9199  }
9200  break;
9201 
9202  default:
9204  global_mesh->hecmw_flag_parttype);
9205  goto error;
9206  }
9207 
9208  return RTC_NORMAL;
9209 
9210 error:
9211  free_struct_result_data(result_data);
9212 
9213  return RTC_ERROR;
9214 }
9215 
9216 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9217  * - - - - - - - - - */
9218 
9219 static int print_ucd_entire_set_elem_data(
9220  const struct hecmwST_local_mesh *global_mesh,
9221  struct hecmwST_result_data *result_data, const char *elem_flag) {
9222  int size;
9223  int ne_item;
9224  int i;
9225  const size_t label_len = HECMW_NAME_LEN + 1;
9226 
9227  result_data->ne_component = 1;
9228 
9229  result_data->ne_dof =
9230  (int *)HECMW_malloc(sizeof(int) * result_data->ne_component);
9231  if (result_data->ne_dof == NULL) {
9232  HECMW_set_error(errno, "");
9233  goto error;
9234  }
9235  result_data->ne_dof[0] = 1;
9236 
9237  result_data->elem_label =
9238  (char **)HECMW_malloc(sizeof(char *) * result_data->ne_component);
9239  if (result_data->elem_label == NULL) {
9240  HECMW_set_error(errno, "");
9241  goto error;
9242  } else {
9243  for (i = 0; i < result_data->ne_component; i++) {
9244  result_data->elem_label[i] = NULL;
9245  }
9246  }
9247  for (i = 0; i < result_data->ne_component; i++) {
9248  result_data->elem_label[i] =
9249  (char *)HECMW_malloc(sizeof(char) * label_len);
9250  if (result_data->elem_label[i] == NULL) {
9251  HECMW_set_error(errno, "");
9252  goto error;
9253  }
9254  }
9255  snprintf(result_data->elem_label[0], label_len, "partitioning_image");
9256 
9257  /* modify element information*/
9258  for (i = 0; i < global_mesh->n_elem; i++) {
9259  switch (global_mesh->elem_type[i]) {
9260  case HECMW_ETYPE_SHT6:
9261  global_mesh->elem_type[i] = HECMW_ETYPE_SHT1;
9262  break;
9263 
9264  case HECMW_ETYPE_SHQ8:
9265  global_mesh->elem_type[i] = HECMW_ETYPE_SHQ1;
9266  break;
9267 
9268  case HECMW_ETYPE_BEM3:
9269  global_mesh->elem_type[i] = HECMW_ETYPE_ROD1;
9270  break;
9271 
9272  case HECMW_ETYPE_ROD31:
9273  case HECMW_ETYPE_SPGDPT1:
9274  global_mesh->elem_type[i] = HECMW_ETYPE_ROD1;
9275  break;
9276  }
9277  }
9278 
9279  for (ne_item = 0, i = 0; i < result_data->ne_component; i++) {
9280  ne_item += result_data->ne_dof[i];
9281  }
9282 
9283  size = sizeof(double) * ne_item * global_mesh->n_elem;
9284  result_data->elem_val_item = (double *)HECMW_malloc(size);
9285  if (result_data->elem_val_item == NULL) {
9286  HECMW_set_error(errno, "");
9287  goto error;
9288  }
9289 
9290  switch (global_mesh->hecmw_flag_parttype) {
9292  for (i = 0; i < global_mesh->n_elem; i++) {
9293  if (EVAL_BIT(elem_flag[i], OVERLAP)) {
9294  result_data->elem_val_item[i] =
9295  (double)global_mesh->n_subdomain + 2.0;
9296  } else {
9297  result_data->elem_val_item[i] =
9298  (double)global_mesh->elem_ID[2 * i + 1];
9299  }
9300  }
9301  break;
9302 
9304  for (i = 0; i < global_mesh->n_elem; i++) {
9305  result_data->elem_val_item[i] = (double)global_mesh->elem_ID[2 * i + 1];
9306  }
9307  break;
9308 
9309  default:
9311  global_mesh->hecmw_flag_parttype);
9312  goto error;
9313  }
9314 
9315  return RTC_NORMAL;
9316 
9317 error:
9318  free_struct_result_data(result_data);
9319 
9320  return RTC_ERROR;
9321 }
9322 
9323 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
9324 
9325 static int print_ucd_entire(const struct hecmwST_local_mesh *global_mesh,
9326  const char *node_flag, const char *elem_flag,
9327  const char *ofname) {
9328  struct hecmwST_result_data *result_data;
9329 
9330  result_data = (struct hecmwST_result_data *)HECMW_malloc(
9331  sizeof(struct hecmwST_result_data));
9332  if (result_data == NULL) {
9333  HECMW_set_error(errno, "");
9334  goto error;
9335  } else {
9336  init_struct_result_data(result_data);
9337  }
9338 
9339  if (print_ucd_entire_set_node_data(global_mesh, result_data, node_flag)) {
9340  goto error;
9341  }
9342 
9343  if (print_ucd_entire_set_elem_data(global_mesh, result_data, elem_flag)) {
9344  goto error;
9345  }
9346 
9347  if (HECMW_ucd_legacy_print(global_mesh, result_data, ofname)) {
9348  goto error;
9349  }
9350 
9351  free_struct_result_data(result_data);
9352 
9353  return RTC_NORMAL;
9354 
9355 error:
9356  free_struct_result_data(result_data);
9357 
9358  return RTC_ERROR;
9359 }
9360 
9361 static int init_partition(struct hecmwST_local_mesh *global_mesh,
9362  struct hecmw_part_cont_data *cont_data) {
9363  HECMW_log(HECMW_LOG_DEBUG, "Starting initialization for partitioner...");
9364 
9365  /* global_mesh->n_subdomain */
9366  global_mesh->n_subdomain = cont_data->n_domain;
9367 
9368  /* global_mesh->hecmw_flag_parttype */
9369  switch (cont_data->type) {
9370  case HECMW_PART_TYPE_NODE_BASED: /* for node-based partitioning */
9372  break;
9373 
9374  case HECMW_PART_TYPE_ELEMENT_BASED: /* for element-based partitioning */
9376  break;
9377 
9378  default:
9380  goto error;
9381  }
9382 
9383  /* global_mesh->hecmw_flag_partdepth */
9384  global_mesh->hecmw_flag_partdepth = cont_data->depth;
9385 
9386  /* global_mesh->hecmw_flag_partcontact */
9387  if (global_mesh->contact_pair->n_pair > 0) {
9388  switch (cont_data->contact) {
9391  break;
9392 
9395  break;
9396 
9399  break;
9400 
9402  default:
9405  break;
9406  }
9407 
9408  switch (cont_data->contact_owner) {
9410  global_mesh->hecmw_flag_partcontact |=
9412  break;
9413 
9415  default:
9416  global_mesh->hecmw_flag_partcontact |=
9418  break;
9419  }
9420  }
9421 
9422  /* ELEMENT-BASED partitioning has no contact masking, so a mesh with contact
9423  * pairs would be split with zero contact overlap (silently broken = false
9424  * completion). Stop loudly instead. */
9425  if (global_mesh->contact_pair->n_pair > 0 &&
9428  "ELEMENT-BASED partitioning is not supported with contact "
9429  "pairs; use TYPE=NODE-BASED");
9430  goto error;
9431  }
9432 
9433  HECMW_log(HECMW_LOG_DEBUG, "Initialization for partitioner done");
9434 
9435  return RTC_NORMAL;
9436 
9437 error:
9438  return RTC_ERROR;
9439  ;
9440 }
9441 
9442 /*==================================================================================================
9443 
9444  main function
9445 
9446 ==================================================================================================*/
9447 
9449  struct hecmwST_local_mesh *global_mesh,
9450  struct hecmw_part_cont_data *cont_data) {
9451  struct hecmwST_local_mesh *local_mesh = NULL;
9452  struct hecmw_ctrl_meshfiles *ofheader = NULL;
9453  char *node_flag = NULL;
9454  char *elem_flag = NULL;
9455  char *node_flag_neighbor = NULL;
9456  char *elem_flag_neighbor = NULL;
9457  int *node_global2local = NULL;
9458  int *elem_global2local = NULL;
9459  char ofname[HECMW_FILENAME_LEN + 1];
9460  int *num_elem = NULL, *num_node = NULL, *num_ielem = NULL, *num_inode = NULL,
9461  *num_nbpe = NULL;
9462  int *sum_elem = NULL, *sum_node = NULL, *sum_ielem = NULL, *sum_inode = NULL,
9463  *sum_nbpe = NULL;
9464  int current_domain, nrank, iS, iE;
9465  int rtc;
9466  int i;
9467  int error_in_ompsection = 0;
9468 
9469  if (global_mesh == NULL) {
9470  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'global_mesh\' is NULL");
9471  goto error;
9472  }
9473  if (cont_data == NULL) {
9474  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'cont_data\' is NULL");
9475  goto error;
9476  }
9477 
9478  rtc = init_partition(global_mesh, cont_data);
9479  if (rtc != RTC_NORMAL) goto error;
9480 
9481  rtc = HECMW_part_init_log(global_mesh->n_subdomain);
9482  if (rtc != RTC_NORMAL) goto error;
9483 
9484  if (global_mesh->my_rank == 0) {
9486  if (rtc != RTC_NORMAL) goto error;
9488  if (rtc != RTC_NORMAL) goto error;
9490  if (rtc != RTC_NORMAL) goto error;
9492  if (rtc != RTC_NORMAL) goto error;
9493 
9494  rtc = HECMW_part_set_log_n_node_g(global_mesh->n_node);
9495  if (rtc != RTC_NORMAL) goto error;
9496  rtc = HECMW_part_set_log_n_elem_g(global_mesh->n_elem);
9497  if (rtc != RTC_NORMAL) goto error;
9498  }
9499 
9500  if (global_mesh->n_subdomain == 1) {
9501  current_domain = 0;
9502 
9503  if (global_mesh->my_rank == 0) {
9504  HECMW_log(HECMW_LOG_INFO, "Creating local mesh for domain #%d ...",
9505  current_domain);
9506 
9508  "part_out", global_mesh->n_subdomain, current_domain);
9509  if (ofheader == NULL) {
9510  HECMW_log(HECMW_LOG_ERROR, "not set output file header");
9511  error_in_ompsection = 1;
9512  goto error;
9513  }
9514  if (ofheader->n_mesh == 0) {
9515  HECMW_log(HECMW_LOG_ERROR, "output file name is not set");
9516  error_in_ompsection = 1;
9517  goto error;
9518  }
9519 
9520  get_dist_file_name(ofheader->meshfiles[0].filename, current_domain,
9521  ofname, sizeof(ofname));
9522  HECMW_assert(ofname != NULL);
9523 
9525  "Starting writing local mesh for domain #%d...",
9526  current_domain);
9527 
9528  rtc = HECMW_put_dist_mesh(global_mesh, ofname);
9529  if (rtc != 0) {
9530  HECMW_log(HECMW_LOG_ERROR, "Failed to write local mesh for domain #%d",
9531  current_domain);
9532  goto error;
9533  }
9534 
9535  HECMW_log(HECMW_LOG_DEBUG, "Writing local mesh for domain #%d done",
9536  current_domain);
9537 
9538  rtc = HECMW_part_set_log_n_elem(0, global_mesh->n_elem);
9539  if (rtc != 0) goto error;
9540  rtc = HECMW_part_set_log_n_node(0, global_mesh->n_node);
9541  if (rtc != 0) goto error;
9542  rtc = HECMW_part_set_log_ne_internal(0, global_mesh->ne_internal);
9543  if (rtc != 0) goto error;
9544  rtc = HECMW_part_set_log_nn_internal(0, global_mesh->nn_internal);
9545  if (rtc != 0) goto error;
9546 
9547  rtc = HECMW_part_print_log();
9548  if (rtc) goto error;
9549  }
9551 
9552  return global_mesh;
9553  }
9554 
9555  num_elem = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9556  if (num_elem == NULL) {
9557  HECMW_set_error(errno, "");
9558  goto error;
9559  }
9560  num_node = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9561  if (num_node == NULL) {
9562  HECMW_set_error(errno, "");
9563  goto error;
9564  }
9565  num_ielem = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9566  if (num_ielem == NULL) {
9567  HECMW_set_error(errno, "");
9568  goto error;
9569  }
9570  num_inode = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9571  if (num_inode == NULL) {
9572  HECMW_set_error(errno, "");
9573  goto error;
9574  }
9575  num_nbpe = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9576  if (num_nbpe == NULL) {
9577  HECMW_set_error(errno, "");
9578  goto error;
9579  }
9580  sum_elem = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9581  if (sum_elem == NULL) {
9582  HECMW_set_error(errno, "");
9583  goto error;
9584  }
9585  sum_node = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9586  if (sum_node == NULL) {
9587  HECMW_set_error(errno, "");
9588  goto error;
9589  }
9590  sum_ielem = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9591  if (sum_ielem == NULL) {
9592  HECMW_set_error(errno, "");
9593  goto error;
9594  }
9595  sum_inode = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9596  if (sum_inode == NULL) {
9597  HECMW_set_error(errno, "");
9598  goto error;
9599  }
9600  sum_nbpe = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9601  if (sum_nbpe == NULL) {
9602  HECMW_set_error(errno, "");
9603  goto error;
9604  }
9605 
9606  rtc = wnumbering(global_mesh, cont_data);
9607  if (rtc != RTC_NORMAL) goto error;
9608 
9609  if (cont_data->is_print_part == 1) {
9610  if (global_mesh->my_rank == 0) {
9611  print_part(global_mesh, cont_data->part_file_name);
9612  }
9613  }
9614 
9615  rtc = spdup_makelist_main(global_mesh);
9616  if (rtc != RTC_NORMAL) goto error;
9617 
9618 #ifdef _OPENMP
9619 #pragma omp parallel default(none), \
9620  private(node_flag, elem_flag, local_mesh, nrank, iS, iE, i, \
9621  current_domain, rtc, ofheader, ofname), \
9622  private(node_global2local, elem_global2local, \
9623  node_flag_neighbor, elem_flag_neighbor), \
9624  shared(global_mesh, cont_data, num_elem, num_node, \
9625  num_ielem, num_inode, num_nbpe, error_in_ompsection)
9626  {
9627 #endif /* _OPENMP */
9628 
9629  node_flag = (char *)HECMW_calloc(global_mesh->n_node, sizeof(char));
9630  if (node_flag == NULL) {
9631  HECMW_set_error(errno, "");
9632  error_in_ompsection = 1;
9633  goto error_omp;
9634  }
9635  elem_flag = (char *)HECMW_calloc(global_mesh->n_elem, sizeof(char));
9636  if (elem_flag == NULL) {
9637  HECMW_set_error(errno, "");
9638  error_in_ompsection = 1;
9639  goto error_omp;
9640  }
9641 
9642  node_global2local = (int *)HECMW_calloc(global_mesh->n_node, sizeof(int));
9643  if (node_global2local == NULL) {
9644  HECMW_set_error(errno, "");
9645  error_in_ompsection = 1;
9646  goto error_omp;
9647  }
9648  elem_global2local = (int *)HECMW_calloc(global_mesh->n_elem, sizeof(int));
9649  if (elem_global2local == NULL) {
9650  HECMW_set_error(errno, "");
9651  error_in_ompsection = 1;
9652  goto error_omp;
9653  }
9654  node_flag_neighbor =
9655  (char *)HECMW_malloc(sizeof(char) * global_mesh->n_node);
9656  if (node_flag_neighbor == NULL) {
9657  HECMW_set_error(errno, "");
9658  error_in_ompsection = 1;
9659  goto error_omp;
9660  }
9661  elem_flag_neighbor =
9662  (char *)HECMW_malloc(sizeof(char) * global_mesh->n_elem);
9663  if (elem_flag_neighbor == NULL) {
9664  HECMW_set_error(errno, "");
9665  error_in_ompsection = 1;
9666  goto error_omp;
9667  }
9668  memset(node_flag_neighbor, 0, sizeof(char) * global_mesh->n_node);
9669  memset(elem_flag_neighbor, 0, sizeof(char) * global_mesh->n_elem);
9670 
9671  local_mesh = HECMW_dist_alloc();
9672  if (local_mesh == NULL) {
9673  error_in_ompsection = 1;
9674  goto error_omp;
9675  }
9676 
9677  nrank = global_mesh->n_subdomain / HECMW_comm_get_size();
9678  iS = HECMW_comm_get_rank() * nrank;
9679  iE = iS + nrank;
9681  iE = global_mesh->n_subdomain;
9682 
9683 #ifdef _OPENMP
9684 #pragma omp for schedule(dynamic, 1), reduction(+ : error_in_ompsection)
9685 #endif
9686  for (i = iS; i < iE; i++) {
9687  if (error_in_ompsection) continue;
9688 
9689  current_domain = i;
9690 
9691  HECMW_log(HECMW_LOG_INFO, "Creating local mesh for domain #%d ...",
9692  current_domain);
9693 
9694  rtc = create_neighbor_info(global_mesh, local_mesh, node_flag, elem_flag,
9695  current_domain);
9696  if (rtc != RTC_NORMAL) {
9697  error_in_ompsection = 1;
9698  continue;
9699  }
9700 
9701  if (global_mesh->n_subdomain > 1) {
9702  rtc = create_comm_info(global_mesh, local_mesh, node_flag, elem_flag,
9703  node_flag_neighbor, elem_flag_neighbor,
9704  current_domain);
9705  if (rtc != RTC_NORMAL) {
9706  error_in_ompsection = 1;
9707  continue;
9708  }
9709  }
9710 
9711  rtc = const_local_data(global_mesh, local_mesh, cont_data, node_flag,
9712  elem_flag, node_global2local, elem_global2local,
9713  current_domain);
9714  if (rtc != RTC_NORMAL) {
9715  error_in_ompsection = 1;
9716  continue;
9717  }
9718 
9719  num_elem[i] = local_mesh->n_elem;
9720  num_node[i] = local_mesh->n_node;
9721  num_ielem[i] = local_mesh->ne_internal;
9722  num_inode[i] = local_mesh->nn_internal;
9723  num_nbpe[i] = local_mesh->n_neighbor_pe;
9724 
9726  "part_out", global_mesh->n_subdomain, current_domain);
9727  if (ofheader == NULL) {
9728  HECMW_log(HECMW_LOG_ERROR, "not set output file header");
9729  error_in_ompsection = 1;
9730  continue;
9731  }
9732  if (ofheader->n_mesh == 0) {
9733  HECMW_log(HECMW_LOG_ERROR, "output file name is not set");
9734  error_in_ompsection = 1;
9735  continue;
9736  }
9737 
9738  get_dist_file_name(ofheader->meshfiles[0].filename, current_domain,
9739  ofname, sizeof(ofname));
9740  HECMW_assert(ofname != NULL);
9741 
9743  "Starting writing local mesh for domain #%d...",
9744  current_domain);
9745 
9746  rtc = HECMW_put_dist_mesh(local_mesh, ofname);
9747  if (rtc != 0) {
9748  HECMW_log(HECMW_LOG_ERROR, "Failed to write local mesh for domain #%d",
9749  current_domain);
9750  error_in_ompsection = 1;
9751  } else {
9752  HECMW_log(HECMW_LOG_DEBUG, "Writing local mesh for domain #%d done",
9753  current_domain);
9754  }
9755 
9756  clean_struct_local_mesh(local_mesh);
9757 
9758  HECMW_ctrl_free_meshfiles(ofheader);
9759  ofheader = NULL;
9760 
9761  if (is_spdup_available(global_mesh)) {
9762  spdup_clear_IEB(node_flag, elem_flag, current_domain);
9763  } else {
9764  int j;
9765  for (j = 0; j < global_mesh->n_node; j++) {
9766  CLEAR_IEB(node_flag[j]);
9767  }
9768  for (j = 0; j < global_mesh->n_elem; j++) {
9769  CLEAR_IEB(elem_flag[j]);
9770  }
9771  }
9772  }
9773 #ifdef _OPENMP
9774  if (error_in_ompsection) goto error_omp;
9775 
9776 #pragma omp single
9777 #endif
9778  if (cont_data->is_print_ucd == 1) {
9779  if (global_mesh->my_rank == 0) {
9780  print_ucd_entire(global_mesh, node_flag, elem_flag,
9781  cont_data->ucd_file_name);
9782  }
9783  }
9784 
9785  error_omp:
9786  HECMW_dist_free(local_mesh);
9787  HECMW_free(node_flag);
9788  HECMW_free(elem_flag);
9789  HECMW_free(node_global2local);
9790  HECMW_free(elem_global2local);
9791  HECMW_free(node_flag_neighbor);
9792  HECMW_free(elem_flag_neighbor);
9793 
9794 #ifdef _OPENMP
9795  } /* omp end parallel */
9796  if (error_in_ompsection) goto error;
9797 #endif
9798 
9799  rtc = HECMW_Allreduce(num_elem, sum_elem, global_mesh->n_subdomain, HECMW_INT,
9801  if (rtc != 0) goto error;
9802  rtc = HECMW_Allreduce(num_node, sum_node, global_mesh->n_subdomain, HECMW_INT,
9804  if (rtc != 0) goto error;
9805  rtc = HECMW_Allreduce(num_ielem, sum_ielem, global_mesh->n_subdomain,
9807  if (rtc != 0) goto error;
9808  rtc = HECMW_Allreduce(num_inode, sum_inode, global_mesh->n_subdomain,
9810  if (rtc != 0) goto error;
9811  rtc = HECMW_Allreduce(num_nbpe, sum_nbpe, global_mesh->n_subdomain,
9813  if (rtc != 0) goto error;
9814 
9815  if (global_mesh->my_rank == 0) {
9816  for (i = 0; i < global_mesh->n_subdomain; i++) {
9817  rtc = HECMW_part_set_log_n_elem(i, sum_elem[i]);
9818  if (rtc != 0) goto error;
9819  rtc = HECMW_part_set_log_n_node(i, sum_node[i]);
9820  if (rtc != 0) goto error;
9821  rtc = HECMW_part_set_log_ne_internal(i, sum_ielem[i]);
9822  if (rtc != 0) goto error;
9823  rtc = HECMW_part_set_log_nn_internal(i, sum_inode[i]);
9824  if (rtc != 0) goto error;
9825  rtc = HECMW_part_set_log_n_neighbor_pe(i, sum_nbpe[i]);
9826  if (rtc != 0) goto error;
9827  }
9828  rtc = HECMW_part_print_log();
9829  if (rtc) goto error;
9830  }
9832 
9833  HECMW_free(num_elem);
9834  HECMW_free(num_node);
9835  HECMW_free(num_ielem);
9836  HECMW_free(num_inode);
9837  HECMW_free(num_nbpe);
9838  HECMW_free(sum_elem);
9839  HECMW_free(sum_node);
9840  HECMW_free(sum_ielem);
9841  HECMW_free(sum_inode);
9842  HECMW_free(sum_nbpe);
9843 
9844  spdup_freelist(global_mesh);
9845 
9846  return global_mesh;
9847 
9848 error:
9849  HECMW_free(node_flag);
9850  HECMW_free(elem_flag);
9851  HECMW_free(num_elem);
9852  HECMW_free(num_node);
9853  HECMW_free(num_ielem);
9854  HECMW_free(num_inode);
9855  HECMW_free(num_nbpe);
9856  HECMW_free(sum_elem);
9857  HECMW_free(sum_node);
9858  HECMW_free(sum_ielem);
9859  HECMW_free(sum_inode);
9860  HECMW_free(sum_nbpe);
9861  HECMW_dist_free(local_mesh);
9862  if (ofheader) {
9863  HECMW_ctrl_free_meshfiles(ofheader);
9864  }
9866 
9867  return NULL;
9868 }
9869 
9871  struct hecmwST_local_mesh *global_mesh) {
9872  struct hecmwST_local_mesh *local_mesh;
9874 
9875  HECMW_log(HECMW_LOG_INFO, "Starting domain decomposition...\n");
9876 
9877  if (global_mesh == NULL) {
9878  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'global_mesh\' is NULL");
9879  goto error;
9880  }
9881 
9883  if (cont_data == NULL) goto error;
9884 
9885  local_mesh = HECMW_partition_inner(global_mesh, cont_data);
9886  if (local_mesh == NULL) goto error;
9887 
9889 
9890  HECMW_log(HECMW_LOG_INFO, "Domain decomposition done\n");
9891 
9892  return local_mesh;
9893 
9894 error:
9895  return NULL;
9896 }
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_comm_get_size(void)
Definition: hecmw_comm.c:755
#define HECMW_ETYPE_PRI1
#define HECMW_ETYPE_PRI2
#define HECMW_ETYPE_BEM3
#define HECMW_ETYPE_SHQ1
#define HECMW_ETYPE_SHT1
#define HECMW_ETYPE_TET2
#define HECMW_ETYPE_PTQ1
#define HECMW_ETYPE_PTT1
#define HECMW_ETYPE_SPGDPT1
#define HECMW_ETYPE_SHT6
#define HECMW_ETYPE_ROD31
#define HECMW_ETYPE_HEX1
#define HECMW_ETYPE_ROD1
#define HECMW_ETYPE_SHQ8
#define HECMW_ETYPE_TET1
#define HECMW_ETYPE_HEX2
#define HECMW_ETYPE_PTT2
#define HECMW_ETYPE_PTQ2
#define HECMW_INT
Definition: hecmw_config.h:48
#define HECMW_FILENAME_LEN
Definition: hecmw_config.h:87
#define HECMW_SUM
Definition: hecmw_config.h:60
#define HECMW_HEADER_LEN
Definition: hecmw_config.h:83
#define HECMW_NAME_LEN
Definition: hecmw_config.h:85
void HECMW_ctrl_free_meshfiles(struct hecmw_ctrl_meshfiles *meshfiles)
struct hecmw_ctrl_meshfiles * HECMW_ctrl_get_meshfiles_header_sub(char *name_ID, int n_rank, int i_rank)
if(!(yy_init))
int HECMW_partcontact_get_mode(int flag_partcontact)
Definition: hecmw_dist.c:157
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)
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_is_etype_link(int etype)
Definition: hecmw_etype.c:1987
int HECMW_graph_degeneGraph(struct hecmw_graph *graph, const struct hecmw_graph *refgraph, int num_part, const int *parttab)
Definition: hecmw_graph.c:161
const idx_t * HECMW_graph_getEdgeItem(const struct hecmw_graph *graph)
Definition: hecmw_graph.c:157
const idx_t * HECMW_graph_getEdgeIndex(const struct hecmw_graph *graph)
Definition: hecmw_graph.c:153
int HECMW_graph_init_with_arrays(struct hecmw_graph *graph, int num_vertex, idx_t *edge_index, idx_t *edge_item)
Definition: hecmw_graph.c:73
void HECMW_graph_finalize(struct hecmw_graph *graph)
Definition: hecmw_graph.c:97
int HECMW_graph_init(struct hecmw_graph *graph)
Definition: hecmw_graph.c:55
Graph utility.
int HECMW_put_dist_mesh(const struct hecmwST_local_mesh *mesh, char *fname)
#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_DEBUG
Definition: hecmw_log.h:21
#define HECMW_LOG_INFO
Definition: hecmw_log.h:19
#define HECMW_calloc(nmemb, size)
Definition: hecmw_malloc.h:21
#define HECMW_free(ptr)
Definition: hecmw_malloc.h:24
#define HECMW_malloc(size)
Definition: hecmw_malloc.h:20
int HECMW_mesh_edge_info(struct hecmwST_local_mesh *local_mesh, struct hecmw_part_edge_data *edge_data)
long long int HECMW_mesh_hsort_edge(int node1, int node2)
long long int HECMW_mesh_hsort_edge_get_n(void)
void HECMW_mesh_hsort_edge_final(void)
int HECMW_mesh_hsort_edge_init(int n_node, int n_elem)
int * HECMW_mesh_hsort_edge_get_v(void)
#define HECMW_PART_METHOD_PMETIS
#define HECMW_PART_RCB_Z_AXIS
#define HECMW_PART_E_STACK_OVERFLOW
#define HECMW_PART_E_INVALID_RCB_DIR
#define HECMW_PART_RCB_Y_AXIS
#define HECMW_PART_CONTACT_OWNER_MASTER
#define HECMW_PART_E_PART_N
#define HECMW_PART_E_INVALID_PMETHOD
#define HECMW_PART_E_INVALID_PTYPE
#define HECMW_PART_RCB_X_AXIS
#define HECMW_PART_E_PART_NDOMAIN
#define HECMW_PART_E_NO_SUCH_FILE
#define HECMW_PART_E_PART_EOF
#define HECMW_PART_METHOD_RCB
#define HECMW_PART_CONTACT_DEFAULT
#define HECMW_PART_E_INV_ARG
#define HECMW_PART_E_PART_EMPTY_DOMAIN
#define HECMW_PART_EQUATION_BLOCK_NAME
#define HECMW_PART_TYPE_NODE_BASED
#define HECMW_PART_METHOD_KMETIS
#define HECMW_PART_CONTACT_DISTRIBUTE
#define HECMW_PART_CONTACT_SIMPLE
#define HECMW_PART_CONTACT_AGGREGATE
#define HECMW_PART_E_NNEIGHBORPE_LOWER
#define HECMW_PART_E_PART_INVALID_FORMAT
#define HECMW_PART_METHOD_USER
#define HECMW_PART_E_PART_INVALID_PART
#define HECMW_PART_CONTACT_OWNER_SLAVE
#define HECMW_PART_TYPE_ELEMENT_BASED
void HECMW_part_free_control(struct hecmw_part_cont_data *cont_data)
struct hecmw_part_cont_data * HECMW_part_get_control(void)
int HECMW_part_set_log_n_neighbor_pe(int domain, int _n_neighbor_pe)
int HECMW_part_set_log_part_contact(int _part_contact)
int HECMW_part_set_log_part_type(int _part_type)
void HECMW_part_finalize_log(void)
int HECMW_part_set_log_n_node_g(int _n_node_g)
int HECMW_part_set_log_part_depth(int _depth)
int HECMW_part_set_log_n_node(int domain, int _n_node)
int HECMW_part_set_log_n_elem(int domain, int _n_elem)
int HECMW_part_init_log(int _n_domain)
int HECMW_part_print_log(void)
int HECMW_part_set_log_n_edgecut(long long int _n_edge, int _n_edgecut)
int HECMW_part_set_log_nn_internal(int domain, int _nn_internal)
int HECMW_part_set_log_n_elem_g(int _n_elem_g)
int HECMW_part_set_log_part_method(int _part_method)
int HECMW_part_set_log_ne_internal(int domain, int _ne_internal)
#define INTERNAL
struct hecmwST_local_mesh * HECMW_partition(struct hecmwST_local_mesh *global_mesh)
#define CLEAR_BIT(map, bit)
#define RTC_NORMAL
#define LINEBUF_SIZE
#define F_1_2
#define ISWAP(b, bb)
#define DSWAP(a, aa)
#define QSORT_LOWER
#define OVERLAP
#define CLEAR_MM(map)
#define BOUNDARY
#define EVAL_BIT(map, bit)
#define MARK
#define RTC_ERROR
#define MASK_BIT(map, bit)
#define MASK
#define CLEAR_IEB(map)
struct hecmwST_local_mesh * HECMW_partition_inner(struct hecmwST_local_mesh *global_mesh, struct hecmw_part_cont_data *cont_data)
#define EXTERNAL
#define HECMW_FLAG_PARTCONTACT_SIMPLE
Definition: hecmw_struct.h:153
#define HECMW_CONTACT_TYPE_NODE_SURF
Definition: hecmw_struct.h:126
#define HECMW_FLAG_PARTCONTACT_AGGREGATE
Definition: hecmw_struct.h:151
#define HECMW_CONTACT_TYPE_NODE_ELEM
Definition: hecmw_struct.h:128
#define HECMW_FLAG_PARTCONTACT_OWNER_SLAVE
Definition: hecmw_struct.h:161
#define HECMW_FLAG_PARTCONTACT_DISTRIBUTE
Definition: hecmw_struct.h:152
#define HECMW_FLAG_PARTCONTACT_OWNER_MASTER
Definition: hecmw_struct.h:160
#define HECMW_CONTACT_TYPE_SURF_SURF
Definition: hecmw_struct.h:127
#define HECMW_FLAG_PARTTYPE_NODEBASED
Definition: hecmw_struct.h:145
#define HECMW_FLAG_PARTTYPE_ELEMBASED
Definition: hecmw_struct.h:146
int HECMW_ucd_legacy_print(const struct hecmwST_local_mesh *mesh, const struct hecmwST_result_data *result, const char *ofname)
void HECMW_abort(HECMW_Comm comm)
Definition: hecmw_util.c:88
#define HECMW_assert(cond)
Definition: hecmw_util.h:40
long long idx_t
struct option_rec options[]
specify command line option name and executing function name.
Definition: main.c:283
struct hecmw_ctrl_meshfile * meshfiles
Definition: hecmw_control.h:42
int * amp_type_definition
Definition: hecmw_struct.h:61
double * amp_table
Definition: hecmw_struct.h:73
double * bc_grp_val
Definition: hecmw_struct.h:104
struct hecmwST_section * section
Definition: hecmw_struct.h:254
double * elem_val_item
Definition: hecmw_struct.h:214
double * elem_mat_int_val
Definition: hecmw_struct.h:212
struct hecmwST_amplitude * amp
Definition: hecmw_struct.h:257
struct hecmwST_material * material
Definition: hecmw_struct.h:255
double * node_val_item
Definition: hecmw_struct.h:187
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 * bc_grp_val
Definition: hecmw_struct.h:90
double * elem_val_item
Definition: hecmw_result.h:23
double * node_val_item
Definition: hecmw_result.h:22
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
double * bc_grp_val
Definition: hecmw_struct.h:119