FrontISTR  5.9.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, elem, 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(struct hecmwST_local_mesh *global_mesh,
2896  const struct hecmw_part_cont_data *cont_data,
2897  const struct hecmw_part_edge_data *edge_data) {
2898  if (global_mesh->contact_pair->n_pair > 0) {
2899  switch (HECMW_partcontact_get_mode(global_mesh->hecmw_flag_partcontact)) {
2901  return metis_partition_nb_contact_agg(global_mesh, cont_data,
2902  edge_data);
2903 
2906  return metis_partition_nb_contact_dist(global_mesh, cont_data,
2907  edge_data);
2908 
2909  default:
2910  return -1;
2911  }
2912  } else {
2913  return metis_partition_nb_default(global_mesh, cont_data, edge_data);
2914  }
2915 }
2916 
2917 static int metis_partition_eb(struct hecmwST_local_mesh *global_mesh,
2918  const struct hecmw_part_cont_data *cont_data,
2919  idx_t *elem_graph_index, idx_t *elem_graph_item) {
2920  int n_edgecut;
2921  idx_t *belong_domain = NULL;
2922  int i;
2923 
2924  belong_domain = (idx_t *)HECMW_calloc(global_mesh->n_elem, sizeof(idx_t));
2925  if (belong_domain == NULL) {
2926  HECMW_set_error(errno, "");
2927  goto error;
2928  }
2929 
2930  switch (cont_data->method) {
2931  case HECMW_PART_METHOD_PMETIS: /* pMETIS */
2932  n_edgecut =
2933  pmetis_interface(global_mesh->n_elem, global_mesh->n_subdomain,
2934  elem_graph_index, elem_graph_item, belong_domain);
2935  if (n_edgecut < 0) goto error;
2936  break;
2937 
2938  case HECMW_PART_METHOD_KMETIS: /* kMETIS */
2939  n_edgecut =
2940  kmetis_interface(global_mesh->n_elem, global_mesh->n_subdomain,
2941  elem_graph_index, elem_graph_item, belong_domain);
2942  if (n_edgecut < 0) goto error;
2943  break;
2944 
2945  default:
2947  goto error;
2948  }
2949 
2950  for (i = 0; i < global_mesh->n_elem; i++) {
2951  global_mesh->elem_ID[2 * i + 1] = (int)belong_domain[i];
2952  }
2953 
2954  HECMW_free(belong_domain);
2955 
2956  return n_edgecut;
2957 
2958 error:
2959  HECMW_free(belong_domain);
2960 
2961  return -1;
2962 }
2963 
2964 /*------------------------------------------------------------------------------------------------*/
2965 
2966 #define LINEBUF_SIZE 1023
2967 
2968 static int read_part_file(
2969  const char *part_file_name,
2970  int n,
2971  int n_domain,
2972  int *wnum) {
2973  FILE *fpart;
2974  char linebuf[LINEBUF_SIZE + 1];
2975  int rtc, n_in, n_domain_in;
2976  int i, part;
2977  int *count_dom;
2978 
2979  fpart = fopen(part_file_name, "r");
2980  if (fpart == NULL) {
2981  HECMW_set_error(HECMW_PART_E_NO_SUCH_FILE, "%s", part_file_name);
2982  goto error;
2983  }
2984 
2985  /* read n and n_domain */
2986  if (fgets(linebuf, LINEBUF_SIZE, fpart) == NULL) {
2987  HECMW_set_error(HECMW_PART_E_PART_EOF, "read_part_file");
2988  goto error;
2989  }
2990  rtc = sscanf(linebuf, "%d %d", &n_in, &n_domain_in);
2991  if (rtc != 2) {
2993  goto error;
2994  }
2995 
2996  if (n_in != n) {
2998  goto error;
2999  }
3000  if (n_domain_in != n_domain) {
3002  goto error;
3003  }
3004 
3005  count_dom = (int *) HECMW_calloc(n_domain, sizeof(int));
3006  if (count_dom == NULL) {
3007  HECMW_set_error(errno, "");
3008  goto error;
3009  }
3010 
3011  /* read part array and count members in each domain */
3012  for (i = 0; i < n; i++) {
3013  if (fgets(linebuf, LINEBUF_SIZE, fpart) == NULL) {
3015  goto error;
3016  }
3017  rtc = sscanf(linebuf, "%d", &part);
3018  if (rtc != 1) {
3020  goto error;
3021  }
3022 
3023  if (part < 0 || n_domain <= part) {
3025  goto error;
3026  }
3027 
3028  count_dom[part]++;
3029 
3030  wnum[2*i+1] = part;
3031  }
3032 
3033  /* check for empty domain */
3034  for (i = 0; i < n_domain; i++) {
3035  if (count_dom[i] == 0) {
3037  goto error;
3038  }
3039  }
3040 
3041  fclose(fpart);
3042 
3043  return RTC_NORMAL;
3044 
3045 error:
3046  return RTC_ERROR;
3047 }
3048 
3049 static int write_part_file(
3050  const char *part_file_name,
3051  int n,
3052  int n_domain,
3053  const int *wnum) {
3054  FILE *fpart;
3055  int i;
3056 
3057  fpart = fopen(part_file_name, "w");
3058  if (fpart == NULL) {
3059  HECMW_set_error(HECMW_PART_E_NO_SUCH_FILE, "%s", part_file_name);
3060  goto error;
3061  }
3062 
3063  fprintf(fpart, "%d %d\n", n, n_domain);
3064 
3065  for (i = 0; i < n; i++) {
3066  fprintf(fpart, "%d\n", wnum[2*i+1]);
3067  }
3068 
3069  fclose(fpart);
3070 
3071  return RTC_NORMAL;
3072 
3073 error:
3074  return RTC_ERROR;
3075 }
3076 
3077 /*------------------------------------------------------------------------------------------------*/
3078 
3079 static int user_partition(
3080  int n,
3081  int n_domain,
3082  int *wnum,
3083  const char *part_file_name) {
3084  int rtc;
3085 
3086  rtc = read_part_file(part_file_name, n, n_domain, wnum);
3087  if (rtc != RTC_NORMAL) goto error;
3088 
3089  return RTC_NORMAL;
3090 
3091 error:
3092  return RTC_ERROR;
3093 }
3094 
3095 static int user_partition_nb(
3096  struct hecmwST_local_mesh *global_mesh,
3097  const struct hecmw_part_cont_data *cont_data) {
3098  return user_partition(global_mesh->n_node, global_mesh->n_subdomain,
3099  global_mesh->node_ID, cont_data->part_file_name);
3100 }
3101 
3102 static int user_partition_eb(
3103  struct hecmwST_local_mesh *global_mesh,
3104  const struct hecmw_part_cont_data *cont_data) {
3105  return user_partition(global_mesh->n_elem, global_mesh->n_subdomain,
3106  global_mesh->elem_ID, cont_data->part_file_name);
3107 }
3108 
3109 /*------------------------------------------------------------------------------------------------*/
3110 
3111 static int print_part(
3112  struct hecmwST_local_mesh *global_mesh,
3113  const char *part_file_name) {
3114  int rtc;
3115 
3116  switch (global_mesh->hecmw_flag_parttype) {
3118  rtc = write_part_file(part_file_name, global_mesh->n_node,
3119  global_mesh->n_subdomain, global_mesh->node_ID);
3120  if (rtc != RTC_NORMAL) goto error;
3121 
3122  break;
3123 
3125  rtc = write_part_file(part_file_name, global_mesh->n_elem,
3126  global_mesh->n_subdomain, global_mesh->elem_ID);
3127  if (rtc != RTC_NORMAL) goto error;
3128 
3129  break;
3130 
3131  default:
3133  goto error;
3134  }
3135 
3136  return RTC_NORMAL;
3137 
3138 error:
3139  return RTC_ERROR;
3140 }
3141 
3142 /*------------------------------------------------------------------------------------------------*/
3143 
3144 static int count_edgecut(
3145  const struct hecmw_part_edge_data *edge_data,
3146  const int *wnum) {
3147  int i;
3148  int n_edgecut = 0;
3149 
3150  for (i = 0; i < edge_data->n_edge; i++) {
3151  if (wnum[2 * (edge_data->edge_node_item[2 * i] - 1) + 1] !=
3152  wnum[2 * (edge_data->edge_node_item[2 * i + 1] - 1) + 1]) {
3153  n_edgecut++;
3154  }
3155  }
3156 
3157  return n_edgecut;
3158 }
3159 
3160 /*------------------------------------------------------------------------------------------------*/
3161 
3162 static int set_node_belong_domain_nb(
3163  struct hecmwST_local_mesh *global_mesh,
3164  const struct hecmw_part_cont_data *cont_data) {
3165  struct hecmw_part_edge_data *edge_data = NULL;
3166  int n_edgecut;
3167  int rtc;
3168  long long int i;
3169 
3170  edge_data = (struct hecmw_part_edge_data *)HECMW_malloc(
3171  sizeof(struct hecmw_part_edge_data));
3172  if (edge_data == NULL) {
3173  HECMW_set_error(errno, "");
3174  goto error;
3175  } else {
3176  edge_data->n_edge = 0;
3177  edge_data->edge_node_item = NULL;
3178  }
3179 
3180  HECMW_log(HECMW_LOG_DEBUG, "Starting creation of mesh edge info...\n");
3181 
3182  rtc = HECMW_mesh_edge_info(global_mesh, edge_data);
3183  if (rtc != 0) goto error;
3184 
3185  HECMW_log(HECMW_LOG_DEBUG, "Creation of mesh edge info done\n");
3186 
3187  switch (cont_data->method) {
3188  case HECMW_PART_METHOD_RCB: /* RCB */
3189  rtc = rcb_partition(global_mesh->n_node, global_mesh->node,
3190  global_mesh->node_ID, cont_data);
3191  if (rtc != RTC_NORMAL) goto error;
3192 
3193  n_edgecut = count_edgecut(edge_data, global_mesh->node_ID);
3194 
3195  break;
3196 
3197  case HECMW_PART_METHOD_KMETIS: /* kMETIS */
3198  case HECMW_PART_METHOD_PMETIS: /* pMETIS */
3199  n_edgecut = metis_partition_nb(global_mesh, cont_data, edge_data);
3200  if (n_edgecut < 0) goto error;
3201 
3202  break;
3203 
3204  case HECMW_PART_METHOD_USER: /* USER */
3205  rtc = user_partition_nb(global_mesh, cont_data);
3206  if (rtc != RTC_NORMAL) goto error;
3207 
3208  n_edgecut = count_edgecut(edge_data, global_mesh->node_ID);
3209 
3210  break;
3211 
3212  default:
3214  goto error;
3215  }
3216 
3217  rtc = HECMW_part_set_log_n_edgecut(edge_data->n_edge, n_edgecut);
3218  if (rtc != RTC_NORMAL) goto error;
3219 
3220  /* commented out by K.Goto; begin */
3221  /* rtc = eqn_block( global_mesh ); */
3222  /* if( rtc != RTC_NORMAL ) goto error; */
3223  /* commented out by K.Goto; end */
3224 
3225  HECMW_free(edge_data->edge_node_item);
3226  HECMW_free(edge_data);
3227 
3228  return RTC_NORMAL;
3229 
3230 error:
3231  if (edge_data) {
3232  HECMW_free(edge_data->edge_node_item);
3233  }
3234  HECMW_free(edge_data);
3235 
3236  return RTC_ERROR;
3237 }
3238 
3239 static int set_node_belong_domain_eb(struct hecmwST_local_mesh *global_mesh) {
3240  int node;
3241  int i;
3242  long long j;
3243 
3244  for (i = 0; i < global_mesh->n_node; i++) {
3245  global_mesh->node_ID[2 * i + 1] = global_mesh->n_subdomain;
3246  }
3247 
3248  for (i = 0; i < global_mesh->n_elem; i++) {
3249  for (j = global_mesh->elem_node_index[i];
3250  j < global_mesh->elem_node_index[i + 1]; j++) {
3251  node = global_mesh->elem_node_item[j];
3252  if (global_mesh->elem_ID[2 * i + 1] <
3253  global_mesh->node_ID[2 * (node - 1) + 1]) {
3254  global_mesh->node_ID[2 * (node - 1) + 1] =
3255  global_mesh->elem_ID[2 * i + 1];
3256  }
3257  }
3258  }
3259 
3260  return RTC_NORMAL;
3261 }
3262 
3263 static int set_local_node_id(struct hecmwST_local_mesh *global_mesh) {
3264  int *counter;
3265  int j, domain;
3266 
3267  counter = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
3268  if (counter == NULL) {
3269  HECMW_set_error(errno, "");
3270  goto error;
3271  }
3272 
3273  for (j = 0; j < global_mesh->n_node; j++) {
3274  domain = global_mesh->node_ID[2 * j + 1];
3275  global_mesh->node_ID[2 * j] = ++counter[domain];
3276  }
3277 
3278  HECMW_free(counter);
3279 
3280  return RTC_NORMAL;
3281 
3282 error:
3283  return RTC_ERROR;
3284 }
3285 
3286 static int wnumbering_node(struct hecmwST_local_mesh *global_mesh,
3287  const struct hecmw_part_cont_data *cont_data) {
3288  int rtc;
3289  int i;
3290 
3291  HECMW_free(global_mesh->node_ID);
3292  global_mesh->node_ID =
3293  (int *)HECMW_malloc(sizeof(int) * (size_t)global_mesh->n_node * 2);
3294  if (global_mesh->node_ID == NULL) {
3295  HECMW_set_error(errno, "");
3296  goto error;
3297  } else {
3298  for (i = 0; i < global_mesh->n_node; i++) {
3299  global_mesh->node_ID[2 * i] = i + 1;
3300  global_mesh->node_ID[2 * i + 1] = 0;
3301  }
3302  }
3303 
3304  if (global_mesh->n_subdomain == 1) return RTC_NORMAL;
3305 
3306  switch (global_mesh->hecmw_flag_parttype) {
3307  case HECMW_FLAG_PARTTYPE_NODEBASED: /* for node-based partitioning */
3308  rtc = set_node_belong_domain_nb(global_mesh, cont_data);
3309  if (rtc != RTC_NORMAL) goto error;
3310  break;
3311 
3312  case HECMW_FLAG_PARTTYPE_ELEMBASED: /* for element-based partitioning */
3313  rtc = set_node_belong_domain_eb(global_mesh);
3314  if (rtc != RTC_NORMAL) goto error;
3315  break;
3316 
3317  default:
3319  goto error;
3320  }
3321 
3322  rtc = set_local_node_id(global_mesh);
3323  if (rtc != RTC_NORMAL) goto error;
3324 
3325  return RTC_NORMAL;
3326 
3327 error:
3328  return RTC_ERROR;
3329 }
3330 
3331 /*------------------------------------------------------------------------------------------------*/
3332 
3333 static int set_elem_belong_domain_nb(struct hecmwST_local_mesh *global_mesh) {
3334  int node, node_domain, min_domain;
3335  int i;
3336  long long j;
3337 
3338  for (i = 0; i < global_mesh->n_elem; i++) {
3339  min_domain = global_mesh->n_subdomain;
3340  for (j = global_mesh->elem_node_index[i];
3341  j < global_mesh->elem_node_index[i + 1]; j++) {
3342  node = global_mesh->elem_node_item[j];
3343  node_domain = global_mesh->node_ID[2 * (node - 1) + 1];
3344  if (node_domain < min_domain) {
3345  min_domain = node_domain;
3346  }
3347  }
3348  global_mesh->elem_ID[2 * i + 1] = min_domain;
3349  }
3350 
3351  return RTC_NORMAL;
3352 }
3353 
3354 static int count_edge_for_eb(const struct hecmwST_local_mesh *global_mesh,
3355  struct hecmw_part_edge_data *elem_data,
3356  idx_t *elem_graph_index, idx_t *elem_graph_item) {
3357  int rtc;
3358  long long int eid;
3359  int i;
3360  idx_t j;
3361 
3362  rtc = HECMW_mesh_hsort_edge_init(global_mesh->n_node, global_mesh->n_elem);
3363  if (rtc != RTC_NORMAL) goto error;
3364 
3365  for (i = 0; i < global_mesh->n_elem; i++) {
3366  for (j = elem_graph_index[i]; j < elem_graph_index[i + 1]; j++) {
3367  eid = HECMW_mesh_hsort_edge(i + 1, elem_graph_item[j] + 1);
3368  if (eid < 0) goto error;
3369  }
3370  }
3371 
3372  elem_data->n_edge = HECMW_mesh_hsort_edge_get_n();
3373  if (elem_data->n_edge < 0) goto error;
3374 
3376  if (elem_data->edge_node_item == NULL) goto error;
3377 
3379 
3380  return RTC_NORMAL;
3381 
3382 error:
3384 
3385  return RTC_ERROR;
3386 }
3387 
3388 static int set_elem_belong_domain_eb(
3389  struct hecmwST_local_mesh *global_mesh,
3390  const struct hecmw_part_cont_data *cont_data) {
3391  int n_edgecut = 0;
3392  idx_t *elem_graph_index = NULL;
3393  idx_t *elem_graph_item = NULL;
3394  struct hecmw_part_edge_data *elem_data = NULL;
3395  int rtc;
3396  long long int i;
3397 
3398  elem_graph_index =
3399  (idx_t *)HECMW_calloc(global_mesh->n_elem + 1, sizeof(idx_t));
3400  if (elem_graph_index == NULL) {
3401  HECMW_set_error(errno, "");
3402  goto error;
3403  }
3404  elem_data = (struct hecmw_part_edge_data *)HECMW_malloc(
3405  sizeof(struct hecmw_part_edge_data));
3406  if (elem_data == NULL) {
3407  HECMW_set_error(errno, "");
3408  goto error;
3409  } else {
3410  elem_data->n_edge = 0;
3411  elem_data->edge_node_item = NULL;
3412  }
3413 
3414  HECMW_log(HECMW_LOG_DEBUG, "Starting creation of elem graph...\n");
3415 
3416  elem_graph_item = create_elem_graph(global_mesh, elem_graph_index);
3417  if (elem_graph_item == NULL) goto error;
3418 
3419  HECMW_log(HECMW_LOG_DEBUG, "Creation of elem graph done\n");
3420 
3421  rtc = count_edge_for_eb(global_mesh, elem_data, elem_graph_index,
3422  elem_graph_item);
3423  if (rtc != RTC_NORMAL) goto error;
3424 
3425  switch (cont_data->method) {
3426  case HECMW_PART_METHOD_RCB: /* RCB */
3427  rtc = rcb_partition_eb(global_mesh, cont_data);
3428  if (rtc != RTC_NORMAL) goto error;
3429 
3430  n_edgecut = count_edgecut(elem_data, global_mesh->elem_ID);
3431 
3432  break;
3433 
3434  case HECMW_PART_METHOD_PMETIS: /* pMETIS */
3435  case HECMW_PART_METHOD_KMETIS: /* kMETIS */
3436  n_edgecut = metis_partition_eb(global_mesh, cont_data, elem_graph_index,
3437  elem_graph_item);
3438  if (n_edgecut < 0) goto error;
3439 
3440  break;
3441 
3442  case HECMW_PART_METHOD_USER: /* USER */
3443  rtc = user_partition_eb(global_mesh, cont_data);
3444  if (rtc != RTC_NORMAL) goto error;
3445 
3446  n_edgecut = count_edgecut(elem_data, global_mesh->elem_ID);
3447 
3448  break;
3449 
3450  default:
3452  goto error;
3453  }
3454 
3455  rtc = HECMW_part_set_log_n_edgecut(elem_data->n_edge, n_edgecut);
3456  if (rtc != RTC_NORMAL) goto error;
3457 
3458  HECMW_free(elem_graph_index);
3459  HECMW_free(elem_graph_item);
3460  HECMW_free(elem_data->edge_node_item);
3461  HECMW_free(elem_data);
3462 
3463  return RTC_NORMAL;
3464 
3465 error:
3466  HECMW_free(elem_graph_index);
3467  HECMW_free(elem_graph_item);
3468  if (elem_data) {
3469  HECMW_free(elem_data->edge_node_item);
3470  }
3471  HECMW_free(elem_data);
3472 
3473  return RTC_ERROR;
3474 }
3475 
3476 static int set_local_elem_id(struct hecmwST_local_mesh *global_mesh) {
3477  int *counter;
3478  int j, domain;
3479 
3480  counter = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
3481  if (counter == NULL) {
3482  HECMW_set_error(errno, "");
3483  goto error;
3484  }
3485 
3486  for (j = 0; j < global_mesh->n_elem; j++) {
3487  domain = global_mesh->elem_ID[2 * j + 1];
3488  global_mesh->elem_ID[2 * j] = ++counter[domain];
3489  }
3490 
3491  HECMW_free(counter);
3492 
3493  return RTC_NORMAL;
3494 
3495 error:
3496  return RTC_ERROR;
3497 }
3498 
3499 static int wnumbering_elem(struct hecmwST_local_mesh *global_mesh,
3500  const struct hecmw_part_cont_data *cont_data) {
3501  int rtc;
3502  int i;
3503 
3504  HECMW_free(global_mesh->elem_ID);
3505  global_mesh->elem_ID =
3506  (int *)HECMW_malloc(sizeof(int) * (size_t)global_mesh->n_elem * 2);
3507  if (global_mesh->elem_ID == NULL) {
3508  HECMW_set_error(errno, "");
3509  goto error;
3510  } else {
3511  for (i = 0; i < global_mesh->n_elem; i++) {
3512  global_mesh->elem_ID[2 * i] = i + 1;
3513  global_mesh->elem_ID[2 * i + 1] = 0;
3514  }
3515  }
3516 
3517  if (global_mesh->n_subdomain == 1) return RTC_NORMAL;
3518 
3519  switch (global_mesh->hecmw_flag_parttype) {
3520  case HECMW_FLAG_PARTTYPE_NODEBASED: /* for node-based partitioning */
3521  rtc = set_elem_belong_domain_nb(global_mesh);
3522  if (rtc != RTC_NORMAL) goto error;
3523 
3524  break;
3525 
3526  case HECMW_FLAG_PARTTYPE_ELEMBASED: /* for element-based partitioning */
3527  rtc = set_elem_belong_domain_eb(global_mesh, cont_data);
3528  if (rtc != RTC_NORMAL) goto error;
3529 
3530  break;
3531 
3532  default:
3534  goto error;
3535  }
3536 
3537  rtc = set_local_elem_id(global_mesh);
3538  if (rtc != RTC_NORMAL) goto error;
3539 
3540  return RTC_NORMAL;
3541 
3542 error:
3543  return RTC_ERROR;
3544 }
3545 
3546 static int wnumbering(struct hecmwST_local_mesh *global_mesh,
3547  const struct hecmw_part_cont_data *cont_data) {
3548  int rtc;
3549 
3550  HECMW_assert(global_mesh);
3552 
3553  HECMW_log(HECMW_LOG_DEBUG, "Starting double numbering...");
3554 
3555  switch (global_mesh->hecmw_flag_parttype) {
3556  case HECMW_FLAG_PARTTYPE_NODEBASED: /* for node-based partitioning */
3557  rtc = wnumbering_node(global_mesh, cont_data);
3558  if (rtc != RTC_NORMAL) goto error;
3559 
3560  rtc = wnumbering_elem(global_mesh, cont_data);
3561  if (rtc != RTC_NORMAL) goto error;
3562 
3563  break;
3564 
3565  case HECMW_FLAG_PARTTYPE_ELEMBASED: /* for element-based partitioning */
3566 
3567  rtc = wnumbering_elem(global_mesh, cont_data);
3568  if (rtc != RTC_NORMAL) goto error;
3569 
3570  rtc = wnumbering_node(global_mesh, cont_data);
3571  if (rtc != RTC_NORMAL) goto error;
3572 
3573  break;
3574 
3575  default:
3577  goto error;
3578  }
3579 
3580  HECMW_log(HECMW_LOG_DEBUG, "Double numbering done");
3581 
3582  return RTC_NORMAL;
3583 
3584 error:
3585  return RTC_ERROR;
3586 }
3587 
3588 /*==================================================================================================
3589 
3590 
3591  create neighboring domain & communication information
3592 
3593 
3594 ==================================================================================================*/
3595 
3596 static int mask_node_by_domain(const struct hecmwST_local_mesh *global_mesh,
3597  char *node_flag, int current_domain) {
3598  int i, node;
3599 
3600  for (i = 0; i < n_int_nlist[current_domain]; i++) {
3601  node = int_nlist[current_domain][i];
3602  MASK_BIT(node_flag[node - 1], INTERNAL);
3603  }
3604 
3605  return RTC_NORMAL;
3606 }
3607 
3608 static int mask_elem_by_domain(const struct hecmwST_local_mesh *global_mesh,
3609  char *elem_flag, int current_domain) {
3610  int i;
3611 
3612  for (i = 0; i < global_mesh->n_elem; i++) {
3613  (global_mesh->elem_ID[2 * i + 1] == current_domain)
3614  ? MASK_BIT(elem_flag[i], INTERNAL)
3615  : MASK_BIT(elem_flag[i], EXTERNAL);
3616  }
3617 
3618  return RTC_NORMAL;
3619 }
3620 
3621 static int mask_elem_by_domain_mod(char *elem_flag, int current_domain) {
3622  int i, elem;
3623 
3624  for (i = 0; i < n_int_elist[current_domain]; i++) {
3625  elem = int_elist[current_domain][i];
3626  MASK_BIT(elem_flag[elem - 1], INTERNAL);
3627  }
3628 
3629  return RTC_NORMAL;
3630 }
3631 
3632 #if 0
3633 /* For Additional overlap for explicit DOF elimination for MPC */
3634 /* NO LONGER NEEDED because node-migration implemented */
3635 static int mask_slave_node(const struct hecmwST_local_mesh *global_mesh,
3636  char *node_flag, int current_domain) {
3637  int i;
3638 
3639  for (i = 0; i < global_mesh->mpc->n_mpc; i++) {
3640  int j0, je, slave, master, j, evalsum;
3641  j0 = global_mesh->mpc->mpc_index[i];
3642  je = global_mesh->mpc->mpc_index[i + 1];
3643  slave = global_mesh->mpc->mpc_item[j0];
3644 
3645  /* mask all slave nodes */
3646  MASK_BIT(node_flag[slave - 1], MASK);
3647 
3648  /* mark slave nodes that have mpc-link across the boundary */
3649  evalsum = 0;
3650  for (j = j0 + 1; j < je; j++) {
3651  master = global_mesh->mpc->mpc_item[j];
3652  if (EVAL_BIT(node_flag[slave - 1], INTERNAL) ^ /* exclusive or */
3653  EVAL_BIT(node_flag[master - 1], INTERNAL)) {
3654  evalsum++;
3655  }
3656  }
3657  if (evalsum) {
3658  MASK_BIT(node_flag[slave - 1], MARK);
3659  }
3660  }
3661  return RTC_NORMAL;
3662 }
3663 #endif
3664 
3665 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3666  * - - - - - - - - - */
3667 
3668 static int mask_overlap_elem(char *elem_flag, int domain) {
3669  int i, elem;
3670 
3671  for (i = 0; i < n_bnd_elist[2 * domain + 1]; i++) {
3672  elem = bnd_elist[domain][i];
3673  MASK_BIT(elem_flag[elem - 1], OVERLAP);
3674  MASK_BIT(elem_flag[elem - 1], BOUNDARY);
3675  }
3676 
3677  return RTC_NORMAL;
3678 }
3679 
3680 static int mask_boundary_node(const struct hecmwST_local_mesh *global_mesh,
3681  char *node_flag, const char *elem_flag) {
3682  int node;
3683  int i;
3684  long long j;
3685 
3686  for (i = 0; i < global_mesh->n_elem; i++) {
3687  if (EVAL_BIT(elem_flag[i], BOUNDARY)) {
3688  for (j = global_mesh->elem_node_index[i];
3689  j < global_mesh->elem_node_index[i + 1]; j++) {
3690  node = global_mesh->elem_node_item[j];
3691  MASK_BIT(node_flag[node - 1], OVERLAP);
3692  MASK_BIT(node_flag[node - 1], BOUNDARY);
3693  }
3694  }
3695  }
3696 
3697  return RTC_NORMAL;
3698 }
3699 
3700 static int mask_boundary_node_mod(const struct hecmwST_local_mesh *global_mesh,
3701  char *node_flag, char *elem_flag,
3702  int domain) {
3703  int i, node;
3704 
3705  for (i = 0; i < n_bnd_nlist[2 * domain + 1]; i++) {
3706  node = bnd_nlist[domain][i];
3707  MASK_BIT(node_flag[node - 1], OVERLAP);
3708  MASK_BIT(node_flag[node - 1], BOUNDARY);
3709  }
3710 
3711  return RTC_NORMAL;
3712 }
3713 
3714 #if 0
3715 /* For Additional overlap for explicit DOF elimination for MPC */
3716 /* NO LONGER NEEDED because node-migration implemented */
3717 static int mask_boundary_elem_with_slave(
3718  const struct hecmwST_local_mesh *global_mesh, const char *node_flag,
3719  char *elem_flag, int *added) {
3720  int node, evalsum;
3721  int i, j;
3722 
3723  *added = 0;
3724 
3725  for (i = 0; i < global_mesh->n_elem; i++) {
3726  if (EVAL_BIT(elem_flag[i], BOUNDARY)) continue;
3727  if (HECMW_is_etype_link(global_mesh->elem_type[i]))
3728  continue; /* skip link elements */
3729 
3730  evalsum = 0;
3731  for (j = global_mesh->elem_node_index[i];
3732  j < global_mesh->elem_node_index[i + 1]; j++) {
3733  node = global_mesh->elem_node_item[j];
3734  /* check if the node is on boundary and a slave having mpc-link across the
3735  * boundary */
3736  if (EVAL_BIT(node_flag[node - 1], BOUNDARY) &&
3737  EVAL_BIT(node_flag[node - 1], MASK) &&
3738  EVAL_BIT(node_flag[node - 1], MARK)) {
3739  evalsum++;
3740  }
3741  }
3742 
3743  if (evalsum) {
3744  MASK_BIT(elem_flag[i], OVERLAP);
3745  MASK_BIT(elem_flag[i], BOUNDARY);
3746  (*added)++;
3747  }
3748  }
3749 
3750  return RTC_NORMAL;
3751 }
3752 
3753 static int mask_boundary_link_elem_with_slave(
3754  const struct hecmwST_local_mesh *global_mesh, const char *node_flag,
3755  char *elem_flag, int *added) {
3756  int node, evalsum;
3757  int i, j;
3758 
3759  *added = 0;
3760 
3761  for (i = 0; i < global_mesh->n_elem; i++) {
3762  if (EVAL_BIT(elem_flag[i], BOUNDARY)) continue;
3763  if (!HECMW_is_etype_link(global_mesh->elem_type[i]))
3764  continue; /* check only link elements */
3765 
3766  evalsum = 0;
3767  for (j = global_mesh->elem_node_index[i];
3768  j < global_mesh->elem_node_index[i + 1]; j++) {
3769  node = global_mesh->elem_node_item[j];
3770  /* check if the node is on boundary and a slave */
3771  if (EVAL_BIT(node_flag[node - 1], BOUNDARY) &&
3772  EVAL_BIT(node_flag[node - 1], MASK)) {
3773  evalsum++;
3774  }
3775  }
3776 
3777  if (evalsum) {
3778  MASK_BIT(elem_flag[i], OVERLAP);
3779  MASK_BIT(elem_flag[i], BOUNDARY);
3780  (*added)++;
3781  }
3782  }
3783 
3784  return RTC_NORMAL;
3785 }
3786 #endif
3787 
3788 static int mask_additional_overlap_elem(
3789  const struct hecmwST_local_mesh *global_mesh, const char *node_flag,
3790  char *elem_flag) {
3791  int node, evalsum;
3792  int i;
3793  long long j;
3794 
3795  for (i = 0; i < global_mesh->n_elem; i++) {
3796  evalsum = 0;
3797  for (j = global_mesh->elem_node_index[i];
3798  j < global_mesh->elem_node_index[i + 1]; j++) {
3799  node = global_mesh->elem_node_item[j];
3800  evalsum += (EVAL_BIT(node_flag[node - 1], BOUNDARY));
3801  }
3802 
3803  if (evalsum) {
3804  MASK_BIT(elem_flag[i], OVERLAP);
3805  MASK_BIT(elem_flag[i], BOUNDARY);
3806  }
3807  }
3808 
3809  return RTC_NORMAL;
3810 }
3811 
3812 static int mask_contact_replicate_slave_to_master_owner(
3813  const struct hecmwST_local_mesh *global_mesh, char *elem_flag,
3814  char *node_flag) {
3815  int i, j;
3816  long long k;
3817  int elem, node, selem;
3818  int evalsum, evalsum2;
3819  int master_gid, slave_gid;
3820  int jstart, jend;
3821  struct hecmwST_contact_pair *cp;
3822  struct hecmwST_surf_grp *sgrp;
3823  struct hecmwST_node_grp *ngrp;
3824  struct hecmwST_elem_grp *egrp;
3825 
3826  cp = global_mesh->contact_pair;
3827  sgrp = global_mesh->surf_group;
3828  ngrp = global_mesh->node_group;
3829  egrp = global_mesh->elem_group;
3830 
3831  for (i = 0; i < cp->n_pair; i++) {
3832  switch (cp->type[i]) {
3834  /* if any elem of master surf is internal */
3835  evalsum = 0;
3836  master_gid = cp->master_grp_id[i];
3837  jstart = sgrp->grp_index[master_gid - 1];
3838  jend = sgrp->grp_index[master_gid];
3839  for (j = jstart; j < jend; j++) {
3840  elem = sgrp->grp_item[j * 2];
3841  if (EVAL_BIT(elem_flag[elem - 1], INTERNAL)) {
3842  evalsum++;
3843  break;
3844  }
3845  }
3846  if (evalsum) {
3847  /* mask all external slave nodes as BOUNDARY (but not OVERLAP) */
3848  slave_gid = cp->slave_grp_id[i];
3849  jstart = ngrp->grp_index[slave_gid - 1];
3850  jend = ngrp->grp_index[slave_gid];
3851  for (j = jstart; j < jend; j++) {
3852  node = ngrp->grp_item[j];
3853  if (!EVAL_BIT(node_flag[node - 1], INTERNAL)) {
3854  MASK_BIT(node_flag[node - 1], BOUNDARY);
3855  }
3856  }
3857  }
3858  /* if any elem of master surf is external */
3859  evalsum = 0;
3860  master_gid = cp->master_grp_id[i];
3861  jstart = sgrp->grp_index[master_gid - 1];
3862  jend = sgrp->grp_index[master_gid];
3863  for (j = jstart; j < jend; j++) {
3864  elem = sgrp->grp_item[j * 2];
3865  if (!EVAL_BIT(elem_flag[elem - 1], INTERNAL)) {
3866  evalsum++;
3867  break;
3868  }
3869  }
3870  if (evalsum) {
3871  /* mask all internal slave nodes as BOUNDARY (but not OVERLAP) */
3872  slave_gid = cp->slave_grp_id[i];
3873  jstart = ngrp->grp_index[slave_gid - 1];
3874  jend = ngrp->grp_index[slave_gid];
3875  for (j = jstart; j < jend; j++) {
3876  node = ngrp->grp_item[j];
3877  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
3878  MASK_BIT(node_flag[node - 1], BOUNDARY);
3879  }
3880  }
3881  }
3882  break;
3883 
3885  /* if any elem of master surf is internal or boundary */
3886  evalsum = 0;
3887  master_gid = cp->master_grp_id[i];
3888  jstart = sgrp->grp_index[master_gid - 1];
3889  jend = sgrp->grp_index[master_gid];
3890  for (j = jstart; j < jend; j++) {
3891  elem = sgrp->grp_item[j * 2];
3892  if (EVAL_BIT(elem_flag[elem - 1], INTERNAL)
3893  || EVAL_BIT(elem_flag[elem - 1], BOUNDARY)) {
3894  evalsum++;
3895  break;
3896  }
3897  }
3898  if (evalsum) {
3899  /* mask all external slave elems/nodes as BOUNDARY (but not OVERLAP) */
3900  slave_gid = cp->slave_grp_id[i];
3901  jstart = sgrp->grp_index[slave_gid - 1];
3902  jend = sgrp->grp_index[slave_gid];
3903  for (j = jstart; j < jend; j++) {
3904  selem = sgrp->grp_item[j * 2];
3905  if (!EVAL_BIT(elem_flag[selem - 1], INTERNAL)) {
3906  MASK_BIT(elem_flag[selem - 1], BOUNDARY);
3907  for (k = global_mesh->elem_node_index[selem - 1];
3908  k < global_mesh->elem_node_index[selem]; k++) {
3909  node = global_mesh->elem_node_item[k];
3910  MASK_BIT(node_flag[node - 1], BOUNDARY);
3911  }
3912  }
3913  }
3914  }
3915  /* if any elem of master surf is external or boundary */
3916  evalsum = 0;
3917  master_gid = cp->master_grp_id[i];
3918  jstart = sgrp->grp_index[master_gid - 1];
3919  jend = sgrp->grp_index[master_gid];
3920  for (j = jstart; j < jend; j++) {
3921  elem = sgrp->grp_item[j * 2];
3922  if (!EVAL_BIT(elem_flag[elem - 1], INTERNAL)
3923  || EVAL_BIT(elem_flag[elem - 1], BOUNDARY)) {
3924  evalsum++;
3925  break;
3926  }
3927  }
3928  if (evalsum) {
3929  /* mask all internal slave nodes as BOUNDARY (but not OVERLAP) */
3930  slave_gid = cp->slave_grp_id[i];
3931  jstart = sgrp->grp_index[slave_gid - 1];
3932  jend = sgrp->grp_index[slave_gid];
3933  for (j = jstart; j < jend; j++) {
3934  evalsum2 = 0;
3935  selem = sgrp->grp_item[j * 2];
3936  for (k = global_mesh->elem_node_index[selem - 1];
3937  k < global_mesh->elem_node_index[selem]; k++) {
3938  node = global_mesh->elem_node_item[k];
3939  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
3940  evalsum2++;
3941  break;
3942  }
3943  }
3944  if (evalsum2) {
3945  MASK_BIT(elem_flag[selem - 1], BOUNDARY);
3946  for (k = global_mesh->elem_node_index[selem - 1];
3947  k < global_mesh->elem_node_index[selem]; k++) {
3948  node = global_mesh->elem_node_item[k];
3949  MASK_BIT(node_flag[node - 1], BOUNDARY);
3950  }
3951  }
3952  }
3953  }
3954  break;
3955 
3957  /* if any elem of master surf is internal */
3958  evalsum = 0;
3959  master_gid = cp->master_grp_id[i];
3960  jstart = egrp->grp_index[master_gid - 1];
3961  jend = egrp->grp_index[master_gid];
3962  for (j = jstart; j < jend; j++) {
3963  elem = egrp->grp_item[j];
3964  if (EVAL_BIT(elem_flag[elem - 1], INTERNAL)) {
3965  evalsum++;
3966  break;
3967  }
3968  }
3969  if (evalsum) {
3970  /* mask all external slave nodes as BOUNDARY (but not OVERLAP) */
3971  slave_gid = cp->slave_grp_id[i];
3972  jstart = ngrp->grp_index[slave_gid - 1];
3973  jend = ngrp->grp_index[slave_gid];
3974  for (j = jstart; j < jend; j++) {
3975  node = ngrp->grp_item[j];
3976  if (!EVAL_BIT(node_flag[node - 1], INTERNAL)) {
3977  MASK_BIT(node_flag[node - 1], BOUNDARY);
3978  }
3979  }
3980  }
3981  /* if any elem of master surf is external */
3982  evalsum = 0;
3983  master_gid = cp->master_grp_id[i];
3984  jstart = egrp->grp_index[master_gid - 1];
3985  jend = egrp->grp_index[master_gid];
3986  for (j = jstart; j < jend; j++) {
3987  elem = egrp->grp_item[j];
3988  if (!EVAL_BIT(elem_flag[elem - 1], INTERNAL)) {
3989  evalsum++;
3990  break;
3991  }
3992  }
3993  if (evalsum) {
3994  /* mask all internal slave nodes as BOUNDARY (but not OVERLAP) */
3995  slave_gid = cp->slave_grp_id[i];
3996  jstart = ngrp->grp_index[slave_gid - 1];
3997  jend = ngrp->grp_index[slave_gid];
3998  for (j = jstart; j < jend; j++) {
3999  node = ngrp->grp_item[j];
4000  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4001  MASK_BIT(node_flag[node - 1], BOUNDARY);
4002  }
4003  }
4004  }
4005  break;
4006 
4007  default:
4008  return RTC_ERROR;
4009  }
4010  }
4011 
4012  return RTC_NORMAL;
4013 }
4014 
4015 /* SURF_SURF is judged on the nodes of the slave elements, not on element
4016  * ownership: fistr1 searches per slave node, and this node set is a superset of
4017  * the sub-face nodes it registers, so no slave owner is missed. */
4018 static int classify_contact_slave_ownership(
4019  const struct hecmwST_local_mesh *global_mesh, const char *node_flag,
4020  int pair_idx, int *has_internal_slave, int *has_external_slave) {
4021  int j, node, selem, slave_gid, jstart, jend;
4022  long long k;
4023  struct hecmwST_contact_pair *cp;
4024  struct hecmwST_surf_grp *sgrp;
4025  struct hecmwST_node_grp *ngrp;
4026 
4027  cp = global_mesh->contact_pair;
4028  sgrp = global_mesh->surf_group;
4029  ngrp = global_mesh->node_group;
4030 
4031  *has_internal_slave = 0;
4032  *has_external_slave = 0;
4033 
4034  slave_gid = cp->slave_grp_id[pair_idx];
4035 
4036  switch (cp->type[pair_idx]) {
4039  jstart = ngrp->grp_index[slave_gid - 1];
4040  jend = ngrp->grp_index[slave_gid];
4041  for (j = jstart; j < jend; j++) {
4042  node = ngrp->grp_item[j];
4043  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4044  *has_internal_slave = 1;
4045  } else {
4046  *has_external_slave = 1;
4047  }
4048  }
4049  break;
4050 
4052  jstart = sgrp->grp_index[slave_gid - 1];
4053  jend = sgrp->grp_index[slave_gid];
4054  for (j = jstart; j < jend; j++) {
4055  selem = sgrp->grp_item[j * 2];
4056  for (k = global_mesh->elem_node_index[selem - 1];
4057  k < global_mesh->elem_node_index[selem]; k++) {
4058  node = global_mesh->elem_node_item[k];
4059  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4060  *has_internal_slave = 1;
4061  } else {
4062  *has_external_slave = 1;
4063  }
4064  }
4065  }
4066  break;
4067 
4068  default:
4069  return RTC_ERROR;
4070  }
4071 
4072  return RTC_NORMAL;
4073 }
4074 
4075 static void mask_contact_master_elem(
4076  const struct hecmwST_local_mesh *global_mesh, int elem, char *elem_flag,
4077  char *node_flag) {
4078  long long k;
4079  int node;
4080 
4081  if (!EVAL_BIT(elem_flag[elem - 1], INTERNAL)) {
4082  MASK_BIT(elem_flag[elem - 1], BOUNDARY);
4083  }
4084  for (k = global_mesh->elem_node_index[elem - 1];
4085  k < global_mesh->elem_node_index[elem]; k++) {
4086  node = global_mesh->elem_node_item[k];
4087  MASK_BIT(node_flag[node - 1], BOUNDARY);
4088  }
4089 }
4090 
4091 /*
4092  * A slave owner must get the master surface whole: find_surface_neighbor builds
4093  * the master adjacency graph from the local surfaces alone, so a partial master
4094  * surface leaves that graph cut at the domain boundary.
4095  * Master-node owners keep their master elements BOUNDARY as well, because
4096  * mask_comm_node intersects the BOUNDARY sets of the two domains and the
4097  * intersection would otherwise be empty.
4098  */
4099 static int mask_contact_replicate_master_to_slave_owner(
4100  const struct hecmwST_local_mesh *global_mesh, char *elem_flag,
4101  char *node_flag) {
4102  int i, j, rtc;
4103  long long k;
4104  int elem, node, master_gid, jstart, jend;
4105  int has_internal_slave, has_external_slave, owns_master_node;
4106  struct hecmwST_contact_pair *cp;
4107  struct hecmwST_surf_grp *sgrp;
4108  struct hecmwST_elem_grp *egrp;
4109 
4110  cp = global_mesh->contact_pair;
4111  sgrp = global_mesh->surf_group;
4112  egrp = global_mesh->elem_group;
4113 
4114  for (i = 0; i < cp->n_pair; i++) {
4115  rtc = classify_contact_slave_ownership(global_mesh, node_flag, i,
4116  &has_internal_slave,
4117  &has_external_slave);
4118  if (rtc != RTC_NORMAL) return RTC_ERROR;
4119 
4120  if (!has_internal_slave && !has_external_slave) continue;
4121 
4122  master_gid = cp->master_grp_id[i];
4123 
4124  if (cp->type[i] == HECMW_CONTACT_TYPE_NODE_ELEM) {
4125  jstart = egrp->grp_index[master_gid - 1];
4126  jend = egrp->grp_index[master_gid];
4127  } else {
4128  jstart = sgrp->grp_index[master_gid - 1];
4129  jend = sgrp->grp_index[master_gid];
4130  }
4131 
4132  for (j = jstart; j < jend; j++) {
4133  if (cp->type[i] == HECMW_CONTACT_TYPE_NODE_ELEM) {
4134  elem = egrp->grp_item[j];
4135  } else {
4136  elem = sgrp->grp_item[j * 2];
4137  }
4138 
4139  if (has_internal_slave) {
4140  mask_contact_master_elem(global_mesh, elem, elem_flag, node_flag);
4141  continue;
4142  }
4143 
4144  owns_master_node = 0;
4145  for (k = global_mesh->elem_node_index[elem - 1];
4146  k < global_mesh->elem_node_index[elem]; k++) {
4147  node = global_mesh->elem_node_item[k];
4148  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4149  owns_master_node = 1;
4150  break;
4151  }
4152  }
4153  if (owns_master_node) {
4154  mask_contact_master_elem(global_mesh, elem, elem_flag, node_flag);
4155  }
4156  }
4157  }
4158 
4159  return RTC_NORMAL;
4160 }
4161 
4162 static int mask_contact_replicate_by_owner(
4163  const struct hecmwST_local_mesh *global_mesh, char *elem_flag,
4164  char *node_flag) {
4165  switch (HECMW_partcontact_get_owner(global_mesh->hecmw_flag_partcontact)) {
4167  return mask_contact_replicate_slave_to_master_owner(global_mesh, elem_flag,
4168  node_flag);
4169 
4171  return mask_contact_replicate_master_to_slave_owner(global_mesh, elem_flag,
4172  node_flag);
4173 
4174  default:
4176  "unknown CONTACT_OWNER in hecmw_flag_partcontact");
4177  return RTC_ERROR;
4178  }
4179 }
4180 
4181 static int mask_mesh_status_nb(const struct hecmwST_local_mesh *global_mesh,
4182  char *node_flag, char *elem_flag,
4183  int current_domain) {
4184  int rtc;
4185  int i;
4186 
4187  rtc = mask_node_by_domain(global_mesh, node_flag, current_domain);
4188  if (rtc != RTC_NORMAL) goto error;
4189 
4190  rtc = mask_elem_by_domain_mod(elem_flag, current_domain);
4191  if (rtc != RTC_NORMAL) goto error;
4192 
4193  rtc = mask_overlap_elem(elem_flag, current_domain);
4194  if (rtc != RTC_NORMAL) goto error;
4195 
4196  rtc =
4197  mask_boundary_node_mod(global_mesh, node_flag, elem_flag, current_domain);
4198  if (rtc != RTC_NORMAL) goto error;
4199 
4200 #if 0
4201  /* Additional overlap for explicit DOF elimination for MPC */
4202  /* NO LONGER NEEDED because node-migration implemented */
4203  if (global_mesh->mpc->n_mpc > 0) {
4204  int added = 0;
4205 
4206  rtc = mask_slave_node(global_mesh, node_flag, current_domain);
4207  if (rtc != RTC_NORMAL) goto error;
4208 
4209  rtc = mask_boundary_elem_with_slave(global_mesh, node_flag, elem_flag,
4210  &added);
4211  if (rtc != RTC_NORMAL) goto error;
4212 
4213  if (added > 0) {
4214  rtc = mask_boundary_node(global_mesh, node_flag, elem_flag);
4215  if (rtc != RTC_NORMAL) goto error;
4216  }
4217 
4218  added = 0;
4219  rtc = mask_boundary_link_elem_with_slave(global_mesh, node_flag, elem_flag,
4220  &added);
4221  if (rtc != RTC_NORMAL) goto error;
4222 
4223  if (added > 0) {
4224  rtc = mask_boundary_node(global_mesh, node_flag, elem_flag);
4225  if (rtc != RTC_NORMAL) goto error;
4226  }
4227 
4228  for (i = 0; i < global_mesh->n_node; i++) {
4229  CLEAR_BIT(node_flag[i], MASK);
4230  CLEAR_BIT(node_flag[i], MARK);
4231  }
4232  }
4233 #endif
4234 
4235  for (i = 1; i < global_mesh->hecmw_flag_partdepth; i++) {
4236  rtc = mask_additional_overlap_elem(global_mesh, node_flag, elem_flag);
4237  if (rtc != RTC_NORMAL) goto error;
4238 
4239  rtc = mask_boundary_node(global_mesh, node_flag, elem_flag);
4240  if (rtc != RTC_NORMAL) goto error;
4241  }
4242 
4243  if (global_mesh->contact_pair->n_pair > 0) {
4244  rtc = mask_contact_replicate_by_owner(global_mesh, elem_flag, node_flag);
4245  if (rtc != RTC_NORMAL) goto error;
4246  }
4247 
4248  return RTC_NORMAL;
4249 
4250 error:
4251  return RTC_ERROR;
4252 }
4253 
4254 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4255  * - - - - - - - - - */
4256 
4257 static int mask_overlap_node_mark(const struct hecmwST_local_mesh *global_mesh,
4258  char *node_flag, const char *elem_flag) {
4259  int node;
4260  int i;
4261  long long j;
4262 
4263  for (i = 0; i < global_mesh->n_elem; i++) {
4264  if (EVAL_BIT(elem_flag[i], INTERNAL)) {
4265  for (j = global_mesh->elem_node_index[i];
4266  j < global_mesh->elem_node_index[i + 1]; j++) {
4267  node = global_mesh->elem_node_item[j];
4268  MASK_BIT(node_flag[node - 1], MARK);
4269  }
4270 
4271  } else {
4272  for (j = global_mesh->elem_node_index[i];
4273  j < global_mesh->elem_node_index[i + 1]; j++) {
4274  node = global_mesh->elem_node_item[j];
4275  MASK_BIT(node_flag[node - 1], MASK);
4276  }
4277  }
4278  }
4279 
4280  return RTC_NORMAL;
4281 }
4282 
4283 static int mask_overlap_node_inner(const struct hecmwST_local_mesh *global_mesh,
4284  char *node_flag) {
4285  int i;
4286 
4287  for (i = 0; i < global_mesh->n_node; i++) {
4288  if (EVAL_BIT(node_flag[i], MARK) && EVAL_BIT(node_flag[i], MASK)) {
4289  MASK_BIT(node_flag[i], OVERLAP);
4290  MASK_BIT(node_flag[i], BOUNDARY);
4291  }
4292  }
4293 
4294  return RTC_NORMAL;
4295 }
4296 
4297 static int mask_overlap_node(const struct hecmwST_local_mesh *global_mesh,
4298  char *node_flag, const char *elem_flag) {
4299  int rtc;
4300  int i;
4301 
4302  rtc = mask_overlap_node_mark(global_mesh, node_flag, elem_flag);
4303  if (rtc != RTC_NORMAL) goto error;
4304 
4305  rtc = mask_overlap_node_inner(global_mesh, node_flag);
4306  if (rtc != RTC_NORMAL) goto error;
4307 
4308  for (i = 0; i < global_mesh->n_node; i++) {
4309  CLEAR_BIT(node_flag[i], MASK);
4310  CLEAR_BIT(node_flag[i], MARK);
4311  }
4312 
4313  return RTC_NORMAL;
4314 
4315 error:
4316  return RTC_ERROR;
4317 }
4318 
4319 static int mask_boundary_elem(const struct hecmwST_local_mesh *global_mesh,
4320  const char *node_flag, char *elem_flag) {
4321  int node, evalsum;
4322  int i;
4323  long long j;
4324 
4325  for (i = 0; i < global_mesh->n_elem; i++) {
4326  evalsum = 0;
4327  for (j = global_mesh->elem_node_index[i];
4328  j < global_mesh->elem_node_index[i + 1]; j++) {
4329  node = global_mesh->elem_node_item[j];
4330  if (EVAL_BIT(node_flag[node - 1], BOUNDARY)) evalsum++;
4331  }
4332 
4333  if (evalsum) {
4334  MASK_BIT(elem_flag[i], OVERLAP);
4335  MASK_BIT(elem_flag[i], BOUNDARY);
4336  }
4337  }
4338 
4339  return RTC_NORMAL;
4340 }
4341 
4342 static int mask_mesh_status_eb(const struct hecmwST_local_mesh *global_mesh,
4343  char *node_flag, char *elem_flag,
4344  int current_domain) {
4345  int rtc;
4346  int i;
4347 
4348  for (i = 0; i < global_mesh->n_node; i++) {
4349  CLEAR_BIT(node_flag[i], INTERNAL);
4350  CLEAR_BIT(node_flag[i], EXTERNAL);
4351  CLEAR_BIT(node_flag[i], BOUNDARY);
4352  }
4353  for (i = 0; i < global_mesh->n_elem; i++) {
4354  CLEAR_BIT(elem_flag[i], INTERNAL);
4355  CLEAR_BIT(elem_flag[i], EXTERNAL);
4356  CLEAR_BIT(elem_flag[i], BOUNDARY);
4357  }
4358 
4359  rtc = mask_node_by_domain(global_mesh, node_flag, current_domain);
4360  if (rtc != RTC_NORMAL) goto error;
4361 
4362  rtc = mask_elem_by_domain(global_mesh, elem_flag, current_domain);
4363  if (rtc != RTC_NORMAL) goto error;
4364 
4365  rtc = mask_overlap_node(global_mesh, node_flag, elem_flag);
4366  if (rtc != RTC_NORMAL) goto error;
4367 
4368  rtc = mask_boundary_elem(global_mesh, node_flag, elem_flag);
4369  if (rtc != RTC_NORMAL) goto error;
4370 
4371  return RTC_NORMAL;
4372 
4373 error:
4374  return RTC_ERROR;
4375 }
4376 
4377 /*------------------------------------------------------------------------------------------------*/
4378 
4379 static int mask_neighbor_domain_nb(const struct hecmwST_local_mesh *global_mesh,
4380  const char *node_flag, char *domain_flag) {
4381  int i;
4382 
4383  for (i = 0; i < global_mesh->n_node; i++) {
4384  if (!EVAL_BIT(node_flag[i], INTERNAL) && EVAL_BIT(node_flag[i], BOUNDARY)) {
4385  MASK_BIT(domain_flag[global_mesh->node_ID[2 * i + 1]], MASK);
4386  }
4387  }
4388 
4389  return RTC_NORMAL;
4390 }
4391 
4392 static int mask_neighbor_domain_nb_mod(
4393  const struct hecmwST_local_mesh *global_mesh, const char *node_flag,
4394  char *domain_flag, int domain) {
4395  int i, node;
4396 
4397  for (i = n_bnd_nlist[2 * domain]; i < n_bnd_nlist[2 * domain + 1]; i++) {
4398  node = bnd_nlist[domain][i];
4399  MASK_BIT(domain_flag[global_mesh->node_ID[2 * node - 1]], MASK);
4400  }
4401 
4402  return RTC_NORMAL;
4403 }
4404 
4405 static int mask_neighbor_domain_nb_contact_master_owner(
4406  const struct hecmwST_local_mesh *global_mesh, const char *node_flag,
4407  const char *elem_flag, char *domain_flag) {
4408  int i, j;
4409  long long k;
4410  int elem, node, selem;
4411  int evalsum;
4412  int master_gid, slave_gid;
4413  int jstart, jend;
4414  struct hecmwST_contact_pair *cp;
4415  struct hecmwST_surf_grp *sgrp;
4416  struct hecmwST_node_grp *ngrp;
4417  struct hecmwST_elem_grp *egrp;
4418 
4419  cp = global_mesh->contact_pair;
4420  sgrp = global_mesh->surf_group;
4421  ngrp = global_mesh->node_group;
4422  egrp = global_mesh->elem_group;
4423 
4424  for (i = 0; i < cp->n_pair; i++) {
4425  /* if any slave node is internal */
4426  evalsum = 0;
4427  switch (cp->type[i]) {
4429  slave_gid = cp->slave_grp_id[i];
4430  jstart = ngrp->grp_index[slave_gid - 1];
4431  jend = ngrp->grp_index[slave_gid];
4432  for (j = jstart; j < jend; j++) {
4433  node = ngrp->grp_item[j];
4434  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4435  evalsum++;
4436  break;
4437  }
4438  }
4439  break;
4441  slave_gid = cp->slave_grp_id[i];
4442  jstart = sgrp->grp_index[slave_gid - 1];
4443  jend = sgrp->grp_index[slave_gid];
4444  for (j = jstart; j < jend; j++) {
4445  selem = sgrp->grp_item[j * 2];
4446  for (k = global_mesh->elem_node_index[selem - 1];
4447  k < global_mesh->elem_node_index[selem]; k++) {
4448  node = global_mesh->elem_node_item[k];
4449  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4450  evalsum++;
4451  break;
4452  }
4453  }
4454  if (evalsum) break;
4455  }
4456  break;
4458  slave_gid = cp->slave_grp_id[i];
4459  jstart = ngrp->grp_index[slave_gid - 1];
4460  jend = ngrp->grp_index[slave_gid];
4461  for (j = jstart; j < jend; j++) {
4462  node = ngrp->grp_item[j];
4463  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4464  evalsum++;
4465  break;
4466  }
4467  }
4468  break;
4469  default:
4470  return RTC_ERROR;
4471  }
4472  /* the domain to which elems of the master surf belong is neighbor */
4473  if (evalsum) {
4474  master_gid = cp->master_grp_id[i];
4475  if( cp->type[i] == HECMW_CONTACT_TYPE_NODE_ELEM ) {
4476  jstart = egrp->grp_index[master_gid - 1];
4477  jend = egrp->grp_index[master_gid];
4478  for (j = jstart; j < jend; j++) {
4479  elem = egrp->grp_item[j];
4480  if (!EVAL_BIT(elem_flag[elem - 1], INTERNAL)) {
4481  MASK_BIT(domain_flag[global_mesh->elem_ID[2 * (elem - 1) + 1]], MASK);
4482  }
4483  }
4484  } else {
4485  jstart = sgrp->grp_index[master_gid - 1];
4486  jend = sgrp->grp_index[master_gid];
4487  for (j = jstart; j < jend; j++) {
4488  elem = sgrp->grp_item[j * 2];
4489  if (!EVAL_BIT(elem_flag[elem - 1], INTERNAL)) {
4490  MASK_BIT(domain_flag[global_mesh->elem_ID[2 * (elem - 1) + 1]], MASK);
4491  }
4492  }
4493  }
4494  }
4495  }
4496 
4497  return RTC_NORMAL;
4498 }
4499 
4500 /* The opposite direction is invisible to mask_neighbor_domain_nb: on a
4501  * master-node owner those nodes are internal, and it may share no mesh entity
4502  * with the slave owner at all. Both directions must be keyed on node
4503  * ownership, so that the set of domains registered here matches the set that
4504  * receives the replicated master surface. */
4505 static int mask_neighbor_domain_nb_contact_slave_owner(
4506  const struct hecmwST_local_mesh *global_mesh, const char *node_flag,
4507  const char *elem_flag, char *domain_flag) {
4508  int i, j, rtc;
4509  long long k;
4510  int elem, node, selem, master_gid, slave_gid, jstart, jend;
4511  int has_internal_slave, has_external_slave, owns_master_node;
4512  struct hecmwST_contact_pair *cp;
4513  struct hecmwST_surf_grp *sgrp;
4514  struct hecmwST_node_grp *ngrp;
4515  struct hecmwST_elem_grp *egrp;
4516 
4517  cp = global_mesh->contact_pair;
4518  sgrp = global_mesh->surf_group;
4519  ngrp = global_mesh->node_group;
4520  egrp = global_mesh->elem_group;
4521 
4522  for (i = 0; i < cp->n_pair; i++) {
4523  rtc = classify_contact_slave_ownership(global_mesh, node_flag, i,
4524  &has_internal_slave,
4525  &has_external_slave);
4526  if (rtc != RTC_NORMAL) return RTC_ERROR;
4527 
4528  if (!has_external_slave) continue;
4529 
4530  owns_master_node = 0;
4531  master_gid = cp->master_grp_id[i];
4532  if (cp->type[i] == HECMW_CONTACT_TYPE_NODE_ELEM) {
4533  jstart = egrp->grp_index[master_gid - 1];
4534  jend = egrp->grp_index[master_gid];
4535  } else {
4536  jstart = sgrp->grp_index[master_gid - 1];
4537  jend = sgrp->grp_index[master_gid];
4538  }
4539  for (j = jstart; j < jend && !owns_master_node; j++) {
4540  if (cp->type[i] == HECMW_CONTACT_TYPE_NODE_ELEM) {
4541  elem = egrp->grp_item[j];
4542  } else {
4543  elem = sgrp->grp_item[j * 2];
4544  }
4545  for (k = global_mesh->elem_node_index[elem - 1];
4546  k < global_mesh->elem_node_index[elem]; k++) {
4547  node = global_mesh->elem_node_item[k];
4548  if (EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4549  owns_master_node = 1;
4550  break;
4551  }
4552  }
4553  }
4554  if (!owns_master_node) continue;
4555 
4556  slave_gid = cp->slave_grp_id[i];
4557  switch (cp->type[i]) {
4560  jstart = ngrp->grp_index[slave_gid - 1];
4561  jend = ngrp->grp_index[slave_gid];
4562  for (j = jstart; j < jend; j++) {
4563  node = ngrp->grp_item[j];
4564  if (!EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4565  MASK_BIT(domain_flag[global_mesh->node_ID[2 * (node - 1) + 1]],
4566  MASK);
4567  }
4568  }
4569  break;
4570 
4572  jstart = sgrp->grp_index[slave_gid - 1];
4573  jend = sgrp->grp_index[slave_gid];
4574  for (j = jstart; j < jend; j++) {
4575  selem = sgrp->grp_item[j * 2];
4576  for (k = global_mesh->elem_node_index[selem - 1];
4577  k < global_mesh->elem_node_index[selem]; k++) {
4578  node = global_mesh->elem_node_item[k];
4579  if (!EVAL_BIT(node_flag[node - 1], INTERNAL)) {
4580  MASK_BIT(domain_flag[global_mesh->node_ID[2 * (node - 1) + 1]],
4581  MASK);
4582  }
4583  }
4584  }
4585  break;
4586 
4587  default:
4588  return RTC_ERROR;
4589  }
4590  }
4591 
4592  return RTC_NORMAL;
4593 }
4594 
4595 static int mask_neighbor_domain_nb_contact_by_owner(
4596  const struct hecmwST_local_mesh *global_mesh, const char *node_flag,
4597  const char *elem_flag, char *domain_flag) {
4598  switch (HECMW_partcontact_get_owner(global_mesh->hecmw_flag_partcontact)) {
4600  return mask_neighbor_domain_nb_contact_master_owner(
4601  global_mesh, node_flag, elem_flag, domain_flag);
4602 
4604  return mask_neighbor_domain_nb_contact_slave_owner(
4605  global_mesh, node_flag, elem_flag, domain_flag);
4606 
4607  default:
4609  "unknown CONTACT_OWNER in hecmw_flag_partcontact");
4610  return RTC_ERROR;
4611  }
4612 }
4613 
4614 static int mask_neighbor_domain_eb(const struct hecmwST_local_mesh *global_mesh,
4615  const char *elem_flag, char *domain_flag) {
4616  int i;
4617 
4618  for (i = 0; i < global_mesh->n_elem; i++) {
4619  if (EVAL_BIT(elem_flag[i], EXTERNAL) && EVAL_BIT(elem_flag[i], BOUNDARY)) {
4620  MASK_BIT(domain_flag[global_mesh->elem_ID[2 * i + 1]], MASK);
4621  }
4622  }
4623 
4624  return RTC_NORMAL;
4625 }
4626 
4627 static int count_neighbor_domain(const struct hecmwST_local_mesh *global_mesh,
4628  const char *domain_flag) {
4629  int counter;
4630  int i;
4631 
4632  for (counter = 0, i = 0; i < global_mesh->n_subdomain; i++) {
4633  if (EVAL_BIT(domain_flag[i], MASK)) counter++;
4634  }
4635 
4636  return counter;
4637 }
4638 
4639 static int set_neighbor_domain(const struct hecmwST_local_mesh *global_mesh,
4640  struct hecmwST_local_mesh *local_mesh,
4641  const char *domain_flag) {
4642  int counter;
4643  int i;
4644 
4645  for (counter = 0, i = 0; i < global_mesh->n_subdomain; i++) {
4646  if (EVAL_BIT(domain_flag[i], MASK)) {
4647  local_mesh->neighbor_pe[counter++] = i;
4648  }
4649  }
4650 
4651  return counter;
4652 }
4653 
4654 static int create_neighbor_info(const struct hecmwST_local_mesh *global_mesh,
4655  struct hecmwST_local_mesh *local_mesh,
4656  char *node_flag, char *elem_flag,
4657  int current_domain) {
4658  int rtc;
4659  char *domain_flag = NULL;
4660 
4661  HECMW_assert(global_mesh);
4662  HECMW_assert(local_mesh);
4663  HECMW_assert(node_flag);
4664  HECMW_assert(elem_flag);
4665 
4667  "Starting creation of neighboring domain information...");
4668 
4669  local_mesh->n_neighbor_pe = 0;
4670  local_mesh->neighbor_pe = NULL;
4671 
4672  domain_flag = (char *)HECMW_calloc(global_mesh->n_subdomain, sizeof(char));
4673  if (domain_flag == NULL) {
4674  HECMW_set_error(errno, "");
4675  goto error;
4676  }
4677 
4678  switch (global_mesh->hecmw_flag_parttype) {
4679  case HECMW_FLAG_PARTTYPE_NODEBASED: /* for node-based partitioning */
4680  rtc = mask_mesh_status_nb(global_mesh, node_flag, elem_flag,
4681  current_domain);
4682  if (rtc != RTC_NORMAL) goto error;
4683 
4684  if (is_spdup_available(global_mesh)) {
4685  rtc = mask_neighbor_domain_nb_mod(global_mesh, node_flag, domain_flag,
4686  current_domain);
4687  } else {
4688  rtc = mask_neighbor_domain_nb(global_mesh, node_flag, domain_flag);
4689  }
4690  if (rtc != RTC_NORMAL) goto error;
4691 
4692  if (global_mesh->contact_pair->n_pair > 0) {
4693  rtc = mask_neighbor_domain_nb_contact_by_owner(
4694  global_mesh, node_flag, elem_flag, domain_flag);
4695  if (rtc != RTC_NORMAL) goto error;
4696  }
4697 
4698  break;
4699 
4700  case HECMW_FLAG_PARTTYPE_ELEMBASED: /* for element-based partitioning */
4701  rtc = mask_mesh_status_eb(global_mesh, node_flag, elem_flag,
4702  current_domain);
4703  if (rtc != RTC_NORMAL) goto error;
4704 
4705  rtc = mask_neighbor_domain_eb(global_mesh, elem_flag, domain_flag);
4706  if (rtc != RTC_NORMAL) goto error;
4707 
4708  break;
4709 
4710  default:
4712  goto error;
4713  }
4714 
4715  local_mesh->n_neighbor_pe = count_neighbor_domain(global_mesh, domain_flag);
4716  if (local_mesh->n_neighbor_pe < 0) {
4718  goto error;
4719  }
4720 
4721  if (local_mesh->n_neighbor_pe == 0) {
4722  local_mesh->neighbor_pe = NULL;
4723  HECMW_free(domain_flag);
4724  return RTC_NORMAL;
4725  }
4726 
4727  local_mesh->neighbor_pe =
4728  (int *)HECMW_malloc(sizeof(int) * local_mesh->n_neighbor_pe);
4729  if (local_mesh->neighbor_pe == NULL) {
4730  HECMW_set_error(errno, "");
4731  goto error;
4732  }
4733  rtc = set_neighbor_domain(global_mesh, local_mesh, domain_flag);
4734  HECMW_assert(rtc == local_mesh->n_neighbor_pe);
4735 
4736  HECMW_free(domain_flag);
4737 
4738  HECMW_log(HECMW_LOG_DEBUG, "Creation of neighboring domain information done");
4739 
4740  return RTC_NORMAL;
4741 
4742 error:
4743  HECMW_free(domain_flag);
4744  HECMW_free(local_mesh->neighbor_pe);
4745  local_mesh->n_neighbor_pe = 0;
4746  local_mesh->neighbor_pe = NULL;
4747 
4748  return RTC_ERROR;
4749 }
4750 
4751 /*================================================================================================*/
4752 
4753 static int mask_comm_node(const struct hecmwST_local_mesh *global_mesh,
4754  char *node_flag_current, char *node_flag_neighbor) {
4755  int i;
4756 
4757  for (i = 0; i < global_mesh->n_node; i++) {
4758  if (EVAL_BIT(node_flag_current[i], BOUNDARY) &&
4759  EVAL_BIT(node_flag_neighbor[i], BOUNDARY)) {
4760  MASK_BIT(node_flag_current[i], MASK);
4761  }
4762  }
4763 
4764  return RTC_NORMAL;
4765 }
4766 
4767 static int mask_comm_node_mod(const struct hecmwST_local_mesh *global_mesh,
4768  char *node_flag_current, char *node_flag_neighbor,
4769  int current_domain) {
4770  int i, node;
4771 
4772  for (i = 0; i < n_bnd_nlist[2 * current_domain + 1]; i++) {
4773  node = bnd_nlist[current_domain][i];
4774  if (EVAL_BIT(node_flag_neighbor[node - 1], BOUNDARY)) {
4775  MASK_BIT(node_flag_current[node - 1], MASK);
4776  }
4777  }
4778 
4779  return RTC_NORMAL;
4780 }
4781 
4782 static int mask_comm_elem(const struct hecmwST_local_mesh *global_mesh,
4783  char *elem_flag_current, char *elem_flag_neighbor) {
4784  int i;
4785 
4786  for (i = 0; i < global_mesh->n_elem; i++) {
4787  if (EVAL_BIT(elem_flag_current[i], BOUNDARY) &&
4788  EVAL_BIT(elem_flag_neighbor[i], BOUNDARY)) {
4789  MASK_BIT(elem_flag_current[i], MASK);
4790  }
4791  }
4792 
4793  return RTC_NORMAL;
4794 }
4795 
4796 static int mask_comm_elem_mod(const struct hecmwST_local_mesh *global_mesh,
4797  char *elem_flag_current, char *elem_flag_neighbor,
4798  int current_domain) {
4799  int i, elem;
4800 
4801  for (i = 0; i < n_bnd_elist[2 * current_domain + 1]; i++) {
4802  elem = bnd_elist[current_domain][i];
4803  if (EVAL_BIT(elem_flag_neighbor[elem - 1], BOUNDARY)) {
4804  MASK_BIT(elem_flag_current[elem - 1], MASK);
4805  }
4806  }
4807 
4808  return RTC_NORMAL;
4809 }
4810 
4811 static int count_masked_comm_node(const struct hecmwST_local_mesh *global_mesh,
4812  const char *node_flag, int domain) {
4813  int counter;
4814  int i, node;
4815 
4816  for (counter = 0, i = 0; i < n_int_nlist[domain]; i++) {
4817  node = int_nlist[domain][i];
4818  if (EVAL_BIT(node_flag[node - 1], MASK)) counter++;
4819  }
4820 
4821  return counter;
4822 }
4823 
4824 static int count_masked_comm_elem(const struct hecmwST_local_mesh *global_mesh,
4825  const char *elem_flag, int domain) {
4826  int counter;
4827  int i;
4828 
4829  for (counter = 0, i = 0; i < global_mesh->n_elem; i++) {
4830  if (EVAL_BIT(elem_flag[i], MASK) &&
4831  global_mesh->elem_ID[2 * i + 1] == domain)
4832  counter++;
4833  }
4834 
4835  return counter;
4836 }
4837 
4838 static int count_masked_shared_node(
4839  const struct hecmwST_local_mesh *global_mesh, const char *node_flag) {
4840  int counter;
4841  int i;
4842 
4843  for (counter = 0, i = 0; i < global_mesh->n_node; i++) {
4844  if (EVAL_BIT(node_flag[i], MASK)) counter++;
4845  }
4846 
4847  return counter;
4848 }
4849 
4850 static int count_masked_shared_elem(
4851  const struct hecmwST_local_mesh *global_mesh, const char *elem_flag) {
4852  int counter;
4853  int i;
4854 
4855  for (counter = 0, i = 0; i < global_mesh->n_elem; i++) {
4856  if (EVAL_BIT(elem_flag[i], MASK)) counter++;
4857  }
4858 
4859  return counter;
4860 }
4861 
4862 static int count_masked_shared_elem_mod(
4863  const struct hecmwST_local_mesh *global_mesh, const char *elem_flag,
4864  int domain) {
4865  int counter;
4866  int i, elem;
4867 
4868  for (counter = 0, i = 0; i < n_bnd_elist[2 * domain + 1]; i++) {
4869  elem = bnd_elist[domain][i];
4870  if (EVAL_BIT(elem_flag[elem - 1], MASK)) counter++;
4871  }
4872 
4873  return counter;
4874 }
4875 
4876 static int create_comm_node_pre(const struct hecmwST_local_mesh *global_mesh,
4877  const char *node_flag, int **comm_node,
4878  int neighbor_idx, int domain) {
4879  int counter;
4880  int i, node;
4881 
4882  for (counter = 0, i = 0; i < n_int_nlist[domain]; i++) {
4883  node = int_nlist[domain][i];
4884  if (EVAL_BIT(node_flag[node - 1], MASK)) {
4885  comm_node[neighbor_idx][counter++] = node;
4886  }
4887  }
4888 
4889  return counter;
4890 }
4891 
4892 static int create_comm_elem_pre(const struct hecmwST_local_mesh *global_mesh,
4893  const char *elem_flag, int **comm_elem,
4894  int neighbor_idx, int domain) {
4895  int counter;
4896  int i;
4897 
4898  for (counter = 0, i = 0; i < global_mesh->n_elem; i++) {
4899  if (EVAL_BIT(elem_flag[i], MASK) &&
4900  global_mesh->elem_ID[2 * i + 1] == domain) {
4901  comm_elem[neighbor_idx][counter++] = i + 1;
4902  }
4903  }
4904 
4905  return counter;
4906 }
4907 
4908 static int create_shared_node_pre(const struct hecmwST_local_mesh *global_mesh,
4909  const char *node_flag, int **shared_node,
4910  int neighbor_idx) {
4911  int counter;
4912  int i;
4913 
4914  for (counter = 0, i = 0; i < global_mesh->n_node; i++) {
4915  if (EVAL_BIT(node_flag[i], MASK)) {
4916  shared_node[neighbor_idx][counter++] = i + 1;
4917  }
4918  }
4919 
4920  return counter;
4921 }
4922 
4923 static int create_shared_elem_pre(const struct hecmwST_local_mesh *global_mesh,
4924  const char *elem_flag, int **shared_elem,
4925  int neighbor_idx) {
4926  int counter;
4927  int i;
4928 
4929  for (counter = 0, i = 0; i < global_mesh->n_elem; i++) {
4930  if (EVAL_BIT(elem_flag[i], MASK)) {
4931  shared_elem[neighbor_idx][counter++] = i + 1;
4932  }
4933  }
4934 
4935  return counter;
4936 }
4937 
4938 static int create_shared_elem_pre_mod(
4939  const struct hecmwST_local_mesh *global_mesh, const char *elem_flag,
4940  int **shared_elem, int neighbor_idx, int neighbor_domain) {
4941  int counter;
4942  int i, idx1, idx2, elem1, elem2, n_bnd, n_out, maxe;
4943 
4944  n_bnd = n_bnd_elist[2 * neighbor_domain];
4945  n_out =
4946  n_bnd_elist[2 * neighbor_domain + 1] - n_bnd_elist[2 * neighbor_domain];
4947  maxe = global_mesh->n_elem + 1;
4948 
4949  elem1 = (n_bnd == 0) ? maxe : bnd_elist[neighbor_domain][0];
4950  elem2 = (n_out == 0) ? maxe : bnd_elist[neighbor_domain][n_bnd];
4951  for (counter = 0, idx1 = 0, idx2 = 0, i = 0; i < n_bnd + n_out; i++) {
4952  if (elem1 < elem2) {
4953  if (EVAL_BIT(elem_flag[elem1 - 1], MASK)) {
4954  shared_elem[neighbor_idx][counter++] = elem1;
4955  }
4956  idx1++;
4957  elem1 = (idx1 == n_bnd) ? maxe : bnd_elist[neighbor_domain][idx1];
4958  } else {
4959  if (EVAL_BIT(elem_flag[elem2 - 1], MASK)) {
4960  shared_elem[neighbor_idx][counter++] = elem2;
4961  }
4962  idx2++;
4963  elem2 = (idx2 == n_out) ? maxe : bnd_elist[neighbor_domain][idx2 + n_bnd];
4964  }
4965  }
4966 
4967  return counter;
4968 }
4969 
4970 static int create_comm_item(int n_neighbor_pe, int **comm_item_pre,
4971  int *comm_index, int *comm_item) {
4972  int i, j, js, je;
4973 
4974  for (i = 0; i < n_neighbor_pe; i++) {
4975  js = comm_index[i];
4976  je = comm_index[i + 1];
4977 
4978  for (j = 0; j < je - js; j++) {
4979  comm_item[js + j] = comm_item_pre[i][j];
4980  }
4981  }
4982 
4983  return RTC_NORMAL;
4984 }
4985 
4986 /*------------------------------------------------------------------------------------------------*/
4987 
4988 static int create_import_info_nb(const struct hecmwST_local_mesh *global_mesh,
4989  struct hecmwST_local_mesh *local_mesh,
4990  const char *node_flag, int **import_node,
4991  int neighbor_idx, int neighbor_domain) {
4992  int n_import_node, rtc;
4993 
4994  n_import_node =
4995  count_masked_comm_node(global_mesh, node_flag, neighbor_domain);
4996  HECMW_assert(n_import_node >= 0);
4997 
4998  local_mesh->import_index[neighbor_idx + 1] =
4999  local_mesh->import_index[neighbor_idx] + n_import_node;
5000 
5001  import_node[neighbor_idx] = (int *)HECMW_malloc(sizeof(int) * n_import_node);
5002  if (import_node[neighbor_idx] == NULL) {
5003  HECMW_set_error(errno, "");
5004  goto error;
5005  }
5006 
5007  rtc = create_comm_node_pre(global_mesh, node_flag, import_node, neighbor_idx,
5008  neighbor_domain);
5009  HECMW_assert(rtc == n_import_node);
5010 
5011  return RTC_NORMAL;
5012 
5013 error:
5014  return RTC_ERROR;
5015 }
5016 
5017 static int create_export_info_nb(const struct hecmwST_local_mesh *global_mesh,
5018  struct hecmwST_local_mesh *local_mesh,
5019  const char *node_flag, int **export_node,
5020  int neighbor_idx, int current_domain,
5021  int neighbor_domain) {
5022  int n_export_node, rtc;
5023 
5024  n_export_node =
5025  count_masked_comm_node(global_mesh, node_flag, current_domain);
5026  HECMW_assert(n_export_node >= 0);
5027 
5028  local_mesh->export_index[neighbor_idx + 1] =
5029  local_mesh->export_index[neighbor_idx] + n_export_node;
5030 
5031  export_node[neighbor_idx] = (int *)HECMW_malloc(sizeof(int) * n_export_node);
5032  if (export_node[neighbor_idx] == NULL) {
5033  HECMW_set_error(errno, "");
5034  goto error;
5035  }
5036 
5037  rtc = create_comm_node_pre(global_mesh, node_flag, export_node, neighbor_idx,
5038  current_domain);
5039  HECMW_assert(rtc == n_export_node);
5040 
5041  return RTC_NORMAL;
5042 
5043 error:
5044  return RTC_ERROR;
5045 }
5046 
5047 static int create_shared_info_nb(const struct hecmwST_local_mesh *global_mesh,
5048  struct hecmwST_local_mesh *local_mesh,
5049  const char *elem_flag, int **shared_elem,
5050  int neighbor_idx, int neighbor_domain) {
5051  int n_shared_elem, rtc;
5052 
5053  if (is_spdup_available(global_mesh)) {
5054  n_shared_elem =
5055  count_masked_shared_elem_mod(global_mesh, elem_flag, neighbor_domain);
5056  } else {
5057  n_shared_elem = count_masked_shared_elem(global_mesh, elem_flag);
5058  }
5059 
5060  HECMW_assert(n_shared_elem >= 0);
5061 
5062  local_mesh->shared_index[neighbor_idx + 1] =
5063  local_mesh->shared_index[neighbor_idx] + n_shared_elem;
5064 
5065  shared_elem[neighbor_idx] = (int *)HECMW_malloc(sizeof(int) * n_shared_elem);
5066  if (shared_elem[neighbor_idx] == NULL) {
5067  HECMW_set_error(errno, "");
5068  goto error;
5069  }
5070 
5071  if (is_spdup_available(global_mesh)) {
5072  rtc = create_shared_elem_pre_mod(global_mesh, elem_flag, shared_elem,
5073  neighbor_idx, neighbor_domain);
5074  } else {
5075  rtc = create_shared_elem_pre(global_mesh, elem_flag, shared_elem,
5076  neighbor_idx);
5077  }
5078 
5079  HECMW_assert(rtc == n_shared_elem);
5080 
5081  return RTC_NORMAL;
5082 
5083 error:
5084  return RTC_ERROR;
5085 }
5086 
5087 static int create_comm_info_nb(const struct hecmwST_local_mesh *global_mesh,
5088  struct hecmwST_local_mesh *local_mesh,
5089  char *node_flag, char *elem_flag,
5090  char *node_flag_neighbor,
5091  char *elem_flag_neighbor, int current_domain) {
5092  int **import_node = NULL;
5093  int **export_node = NULL;
5094  int **shared_elem = NULL;
5095  int neighbor_domain;
5096  int size;
5097  int rtc;
5098  int i, j;
5099 
5100  local_mesh->import_index = NULL;
5101  local_mesh->export_index = NULL;
5102  local_mesh->shared_index = NULL;
5103  local_mesh->import_item = NULL;
5104  local_mesh->export_item = NULL;
5105  local_mesh->shared_item = NULL;
5106 
5107  import_node = (int **)HECMW_malloc(sizeof(int *) * (size_t)local_mesh->n_neighbor_pe);
5108  if (import_node == NULL) {
5109  HECMW_set_error(errno, "");
5110  goto error;
5111  } else {
5112  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5113  import_node[i] = NULL;
5114  }
5115  }
5116  export_node = (int **)HECMW_malloc(sizeof(int *) * (size_t)local_mesh->n_neighbor_pe);
5117  if (export_node == NULL) {
5118  HECMW_set_error(errno, "");
5119  goto error;
5120  } else {
5121  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5122  export_node[i] = NULL;
5123  }
5124  }
5125  shared_elem = (int **)HECMW_malloc(sizeof(int *) * local_mesh->n_neighbor_pe);
5126  if (shared_elem == NULL) {
5127  HECMW_set_error(errno, "");
5128  goto error;
5129  } else {
5130  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5131  shared_elem[i] = NULL;
5132  }
5133  }
5134 
5135  local_mesh->import_index =
5136  (int *)HECMW_calloc(local_mesh->n_neighbor_pe + 1, sizeof(int));
5137  if (local_mesh->import_index == NULL) {
5138  HECMW_set_error(errno, "");
5139  goto error;
5140  }
5141  local_mesh->export_index =
5142  (int *)HECMW_calloc(local_mesh->n_neighbor_pe + 1, sizeof(int));
5143  if (local_mesh->export_index == NULL) {
5144  HECMW_set_error(errno, "");
5145  goto error;
5146  }
5147  local_mesh->shared_index =
5148  (int *)HECMW_calloc(local_mesh->n_neighbor_pe + 1, sizeof(int));
5149  if (local_mesh->shared_index == NULL) {
5150  HECMW_set_error(errno, "");
5151  goto error;
5152  }
5153 
5154  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5155  neighbor_domain = local_mesh->neighbor_pe[i];
5156 
5157  rtc = mask_mesh_status_nb(global_mesh, node_flag_neighbor,
5158  elem_flag_neighbor, neighbor_domain);
5159  if (rtc != RTC_NORMAL) goto error;
5160 
5161  if (is_spdup_available(global_mesh)) {
5162  rtc = mask_comm_node_mod(global_mesh, node_flag, node_flag_neighbor,
5163  current_domain);
5164  } else {
5165  rtc = mask_comm_node(global_mesh, node_flag, node_flag_neighbor);
5166  }
5167 
5168  if (rtc != RTC_NORMAL) goto error;
5169 
5170  if (is_spdup_available(global_mesh)) {
5171  rtc = mask_comm_elem_mod(global_mesh, elem_flag, elem_flag_neighbor,
5172  current_domain);
5173  } else {
5174  rtc = mask_comm_elem(global_mesh, elem_flag, elem_flag_neighbor);
5175  }
5176 
5177  if (rtc != RTC_NORMAL) goto error;
5178 
5179  rtc = create_import_info_nb(global_mesh, local_mesh, node_flag, import_node,
5180  i, neighbor_domain);
5181  if (rtc != RTC_NORMAL) goto error;
5182 
5183  rtc = create_export_info_nb(global_mesh, local_mesh, node_flag, export_node,
5184  i, current_domain, neighbor_domain);
5185  if (rtc != RTC_NORMAL) goto error;
5186 
5187  rtc = create_shared_info_nb(global_mesh, local_mesh, elem_flag, shared_elem,
5188  i, neighbor_domain);
5189  if (rtc != RTC_NORMAL) goto error;
5190 
5191  if (is_spdup_available(global_mesh)) {
5192  rtc = spdup_clear_IEB(node_flag_neighbor, elem_flag_neighbor,
5193  neighbor_domain);
5194  if (rtc != RTC_NORMAL) goto error;
5195 
5196  rtc = spdup_clear_MMbnd(node_flag_neighbor, elem_flag_neighbor,
5197  neighbor_domain);
5198  if (rtc != RTC_NORMAL) goto error;
5199 
5200  rtc = spdup_clear_MMbnd(node_flag, elem_flag, current_domain);
5201  if (rtc != RTC_NORMAL) goto error;
5202  } else {
5203  for (j = 0; j < global_mesh->n_node; j++) {
5204  CLEAR_MM(node_flag[j]);
5205  }
5206  for (j = 0; j < global_mesh->n_elem; j++) {
5207  CLEAR_MM(elem_flag[j]);
5208  }
5209 
5210  memset(node_flag_neighbor, 0, sizeof(char) * global_mesh->n_node);
5211  memset(elem_flag_neighbor, 0, sizeof(char) * global_mesh->n_elem);
5212  }
5213  }
5214 
5215  size = sizeof(int) * local_mesh->import_index[local_mesh->n_neighbor_pe];
5216  local_mesh->import_item = (int *)HECMW_malloc(size);
5217  if (local_mesh->import_item == NULL) {
5218  HECMW_set_error(errno, "");
5219  goto error;
5220  }
5221 
5222  rtc = create_comm_item(local_mesh->n_neighbor_pe, import_node,
5223  local_mesh->import_index, local_mesh->import_item);
5224  if (rtc != RTC_NORMAL) goto error;
5225 
5226  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5227  HECMW_free(import_node[i]);
5228  }
5229  HECMW_free(import_node);
5230  import_node = NULL;
5231 
5232  size = sizeof(int) * local_mesh->export_index[local_mesh->n_neighbor_pe];
5233  local_mesh->export_item = (int *)HECMW_malloc(size);
5234  if (local_mesh->export_item == NULL) {
5235  HECMW_set_error(errno, "");
5236  goto error;
5237  }
5238 
5239  rtc = create_comm_item(local_mesh->n_neighbor_pe, export_node,
5240  local_mesh->export_index, local_mesh->export_item);
5241  if (rtc != RTC_NORMAL) goto error;
5242 
5243  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5244  HECMW_free(export_node[i]);
5245  }
5246  HECMW_free(export_node);
5247  export_node = NULL;
5248 
5249  size = sizeof(int) * local_mesh->shared_index[local_mesh->n_neighbor_pe];
5250  local_mesh->shared_item = (int *)HECMW_malloc(size);
5251  if (local_mesh->shared_item == NULL) {
5252  HECMW_set_error(errno, "");
5253  goto error;
5254  }
5255 
5256  rtc = create_comm_item(local_mesh->n_neighbor_pe, shared_elem,
5257  local_mesh->shared_index, local_mesh->shared_item);
5258  if (rtc != RTC_NORMAL) goto error;
5259 
5260  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5261  HECMW_free(shared_elem[i]);
5262  }
5263  HECMW_free(shared_elem);
5264  shared_elem = NULL;
5265 
5266  return RTC_NORMAL;
5267 
5268 error:
5269  if (import_node) {
5270  int i;
5271  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5272  HECMW_free(import_node[i]);
5273  }
5274  HECMW_free(import_node);
5275  }
5276  if (export_node) {
5277  int i;
5278  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5279  HECMW_free(export_node[i]);
5280  }
5281  HECMW_free(export_node);
5282  }
5283  if (shared_elem) {
5284  int i;
5285  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5286  HECMW_free(shared_elem[i]);
5287  }
5288  HECMW_free(shared_elem);
5289  }
5290 
5291  HECMW_free(local_mesh->import_index);
5292  HECMW_free(local_mesh->export_index);
5293  HECMW_free(local_mesh->shared_index);
5294  HECMW_free(local_mesh->import_item);
5295  HECMW_free(local_mesh->export_item);
5296  HECMW_free(local_mesh->shared_item);
5297 
5298  local_mesh->import_index = NULL;
5299  local_mesh->export_index = NULL;
5300  local_mesh->shared_index = NULL;
5301  local_mesh->import_item = NULL;
5302  local_mesh->export_item = NULL;
5303  local_mesh->shared_item = NULL;
5304 
5305  return RTC_ERROR;
5306 }
5307 
5308 /*------------------------------------------------------------------------------------------------*/
5309 
5310 static int create_import_info_eb(const struct hecmwST_local_mesh *global_mesh,
5311  struct hecmwST_local_mesh *local_mesh,
5312  const char *elem_flag, int **import_elem,
5313  int neighbor_idx, int neighbor_domain) {
5314  int n_import_elem, rtc;
5315 
5316  n_import_elem =
5317  count_masked_comm_elem(global_mesh, elem_flag, neighbor_domain);
5318  HECMW_assert(n_import_elem >= 0);
5319 
5320  local_mesh->import_index[neighbor_idx + 1] =
5321  local_mesh->import_index[neighbor_idx] + n_import_elem;
5322 
5323  import_elem[neighbor_idx] = (int *)HECMW_malloc(sizeof(int) * n_import_elem);
5324  if (import_elem[neighbor_idx] == NULL) {
5325  HECMW_set_error(errno, "");
5326  goto error;
5327  }
5328 
5329  rtc = create_comm_elem_pre(global_mesh, elem_flag, import_elem, neighbor_idx,
5330  neighbor_domain);
5331  HECMW_assert(rtc == n_import_elem);
5332 
5333  return RTC_NORMAL;
5334 
5335 error:
5336  return RTC_ERROR;
5337 }
5338 
5339 static int create_export_info_eb(const struct hecmwST_local_mesh *global_mesh,
5340  struct hecmwST_local_mesh *local_mesh,
5341  const char *elem_flag, int **export_elem,
5342  int neighbor_idx, int current_domain,
5343  int neighbor_domain) {
5344  int n_export_elem, rtc;
5345 
5346  n_export_elem =
5347  count_masked_comm_elem(global_mesh, elem_flag, current_domain);
5348  HECMW_assert(n_export_elem >= 0);
5349 
5350  local_mesh->export_index[neighbor_idx + 1] =
5351  local_mesh->export_index[neighbor_idx] + n_export_elem;
5352 
5353  export_elem[neighbor_idx] = (int *)HECMW_malloc(sizeof(int) * n_export_elem);
5354  if (export_elem[neighbor_idx] == NULL) {
5355  HECMW_set_error(errno, "");
5356  goto error;
5357  }
5358 
5359  rtc = create_comm_elem_pre(global_mesh, elem_flag, export_elem, neighbor_idx,
5360  current_domain);
5361  HECMW_assert(rtc == n_export_elem);
5362 
5363  return RTC_NORMAL;
5364 
5365 error:
5366  return RTC_ERROR;
5367 }
5368 
5369 static int create_shared_info_eb(const struct hecmwST_local_mesh *global_mesh,
5370  struct hecmwST_local_mesh *local_mesh,
5371  const char *node_flag, int **shared_node,
5372  int neighbor_idx, int neighbor_domain) {
5373  int n_shared_node, rtc;
5374 
5375  n_shared_node = count_masked_shared_node(global_mesh, node_flag);
5376  HECMW_assert(n_shared_node >= 0);
5377 
5378  local_mesh->shared_index[neighbor_idx + 1] =
5379  local_mesh->shared_index[neighbor_idx] + n_shared_node;
5380 
5381  shared_node[neighbor_idx] = (int *)HECMW_malloc(sizeof(int) * n_shared_node);
5382  if (shared_node[neighbor_idx] == NULL) {
5383  HECMW_set_error(errno, "");
5384  goto error;
5385  }
5386 
5387  rtc =
5388  create_shared_node_pre(global_mesh, node_flag, shared_node, neighbor_idx);
5389  HECMW_assert(rtc == n_shared_node);
5390 
5391  return RTC_NORMAL;
5392 
5393 error:
5394  return RTC_ERROR;
5395 }
5396 
5397 /*------------------------------------------------------------------------------------------------*/
5398 
5399 static int create_comm_info_eb(const struct hecmwST_local_mesh *global_mesh,
5400  struct hecmwST_local_mesh *local_mesh,
5401  char *node_flag, char *elem_flag,
5402  char *node_flag_neighbor,
5403  char *elem_flag_neighbor, int current_domain) {
5404  int **import_elem = NULL;
5405  int **export_elem = NULL;
5406  int **shared_node = NULL;
5407  int neighbor_domain;
5408  int size;
5409  int rtc;
5410  int i, j;
5411 
5412  /* allocation */
5413  local_mesh->import_index = NULL;
5414  local_mesh->export_index = NULL;
5415  local_mesh->shared_index = NULL;
5416  local_mesh->import_item = NULL;
5417  local_mesh->export_item = NULL;
5418  local_mesh->shared_item = NULL;
5419 
5420  import_elem = (int **)HECMW_malloc(sizeof(int *) * local_mesh->n_neighbor_pe);
5421  if (import_elem == NULL) {
5422  HECMW_set_error(errno, "");
5423  goto error;
5424  } else {
5425  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5426  import_elem[i] = NULL;
5427  }
5428  }
5429  export_elem = (int **)HECMW_malloc(sizeof(int *) * local_mesh->n_neighbor_pe);
5430  if (export_elem == NULL) {
5431  HECMW_set_error(errno, "");
5432  goto error;
5433  } else {
5434  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5435  export_elem[i] = NULL;
5436  }
5437  }
5438  shared_node = (int **)HECMW_malloc(sizeof(int *) * local_mesh->n_neighbor_pe);
5439  if (shared_node == NULL) {
5440  HECMW_set_error(errno, "");
5441  goto error;
5442  } else {
5443  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5444  shared_node[i] = NULL;
5445  }
5446  }
5447 
5448  local_mesh->import_index =
5449  (int *)HECMW_calloc(local_mesh->n_neighbor_pe + 1, sizeof(int));
5450  if (local_mesh->import_index == NULL) {
5451  HECMW_set_error(errno, "");
5452  goto error;
5453  }
5454  local_mesh->export_index =
5455  (int *)HECMW_calloc(local_mesh->n_neighbor_pe + 1, sizeof(int));
5456  if (local_mesh->export_index == NULL) {
5457  HECMW_set_error(errno, "");
5458  goto error;
5459  }
5460  local_mesh->shared_index =
5461  (int *)HECMW_calloc(local_mesh->n_neighbor_pe + 1, sizeof(int));
5462  if (local_mesh->shared_index == NULL) {
5463  HECMW_set_error(errno, "");
5464  goto error;
5465  }
5466 
5467  /* create communication table */
5468  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5469  neighbor_domain = local_mesh->neighbor_pe[i];
5470 
5471  for (j = 0; j < global_mesh->n_node; j++) {
5472  CLEAR_BIT(node_flag[j], MASK);
5473  CLEAR_BIT(node_flag[j], MARK);
5474  }
5475  for (j = 0; j < global_mesh->n_elem; j++) {
5476  CLEAR_BIT(elem_flag[j], MASK);
5477  CLEAR_BIT(elem_flag[j], MARK);
5478  }
5479 
5480  memset(node_flag_neighbor, 0, sizeof(char) * global_mesh->n_node);
5481  memset(elem_flag_neighbor, 0, sizeof(char) * global_mesh->n_elem);
5482 
5483  /* mask boundary node & element */
5484  rtc = mask_mesh_status_eb(global_mesh, node_flag_neighbor,
5485  elem_flag_neighbor, neighbor_domain);
5486  if (rtc != RTC_NORMAL) goto error;
5487 
5488  rtc = mask_comm_node(global_mesh, node_flag, node_flag_neighbor);
5489  if (rtc != RTC_NORMAL) goto error;
5490 
5491  rtc = mask_comm_elem(global_mesh, elem_flag, elem_flag_neighbor);
5492  if (rtc != RTC_NORMAL) goto error;
5493 
5494  /* create import element information (preliminary) */
5495  rtc = create_import_info_eb(global_mesh, local_mesh, elem_flag, import_elem,
5496  i, neighbor_domain);
5497  if (rtc != RTC_NORMAL) goto error;
5498 
5499  /* create export element information (preliminary) */
5500  rtc = create_export_info_eb(global_mesh, local_mesh, elem_flag, export_elem,
5501  i, current_domain, neighbor_domain);
5502  if (rtc != RTC_NORMAL) goto error;
5503 
5504  /* create shared node information (preliminary) */
5505  rtc = create_shared_info_eb(global_mesh, local_mesh, node_flag, shared_node,
5506  i, neighbor_domain);
5507  if (rtc != RTC_NORMAL) goto error;
5508  }
5509 
5510  /* create import element information */
5511  size = sizeof(int) * local_mesh->import_index[local_mesh->n_neighbor_pe];
5512  local_mesh->import_item = (int *)HECMW_malloc(size);
5513  if (local_mesh->import_item == NULL) {
5514  HECMW_set_error(errno, "");
5515  goto error;
5516  }
5517 
5518  rtc = create_comm_item(local_mesh->n_neighbor_pe, import_elem,
5519  local_mesh->import_index, local_mesh->import_item);
5520  if (rtc != RTC_NORMAL) goto error;
5521 
5522  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5523  HECMW_free(import_elem[i]);
5524  }
5525  HECMW_free(import_elem);
5526  import_elem = NULL;
5527 
5528  /* create export node information */
5529  size = sizeof(int) * local_mesh->export_index[local_mesh->n_neighbor_pe];
5530  local_mesh->export_item = (int *)HECMW_malloc(size);
5531  if (local_mesh->export_item == NULL) {
5532  HECMW_set_error(errno, "");
5533  goto error;
5534  }
5535 
5536  rtc = create_comm_item(local_mesh->n_neighbor_pe, export_elem,
5537  local_mesh->export_index, local_mesh->export_item);
5538  if (rtc != RTC_NORMAL) goto error;
5539 
5540  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5541  HECMW_free(export_elem[i]);
5542  }
5543  HECMW_free(export_elem);
5544  export_elem = NULL;
5545 
5546  /* create shared element information */
5547  size = sizeof(int) * local_mesh->shared_index[local_mesh->n_neighbor_pe];
5548  local_mesh->shared_item = (int *)HECMW_malloc(size);
5549  if (local_mesh->shared_item == NULL) {
5550  HECMW_set_error(errno, "");
5551  goto error;
5552  }
5553 
5554  rtc = create_comm_item(local_mesh->n_neighbor_pe, shared_node,
5555  local_mesh->shared_index, local_mesh->shared_item);
5556  if (rtc != RTC_NORMAL) goto error;
5557 
5558  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5559  HECMW_free(shared_node[i]);
5560  }
5561  HECMW_free(shared_node);
5562  shared_node = NULL;
5563 
5564  return RTC_NORMAL;
5565 
5566 error:
5567  if (import_elem) {
5568  int i;
5569  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5570  HECMW_free(import_elem[i]);
5571  }
5572  HECMW_free(import_elem);
5573  }
5574  if (export_elem) {
5575  int i;
5576  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5577  HECMW_free(export_elem[i]);
5578  }
5579  HECMW_free(export_elem);
5580  }
5581  if (shared_node) {
5582  int i;
5583  for (i = 0; i < local_mesh->n_neighbor_pe; i++) {
5584  HECMW_free(shared_node[i]);
5585  }
5586  HECMW_free(shared_node);
5587  }
5588  HECMW_free(local_mesh->import_index);
5589  HECMW_free(local_mesh->export_index);
5590  HECMW_free(local_mesh->shared_index);
5591  HECMW_free(local_mesh->import_item);
5592  HECMW_free(local_mesh->export_item);
5593  HECMW_free(local_mesh->shared_item);
5594 
5595  local_mesh->import_index = NULL;
5596  local_mesh->export_index = NULL;
5597  local_mesh->shared_index = NULL;
5598  local_mesh->import_item = NULL;
5599  local_mesh->export_item = NULL;
5600  local_mesh->shared_item = NULL;
5601 
5602  return RTC_ERROR;
5603 }
5604 
5605 /*================================================================================================*/
5606 
5607 static int create_comm_info(const struct hecmwST_local_mesh *global_mesh,
5608  struct hecmwST_local_mesh *local_mesh,
5609  char *node_flag, char *elem_flag,
5610  char *node_flag_neighbor, char *elem_flag_neighbor,
5611  int current_domain) {
5612  int rtc;
5613 
5614  HECMW_assert(global_mesh);
5615  HECMW_assert(local_mesh);
5616  HECMW_assert(node_flag);
5617  HECMW_assert(elem_flag);
5618 
5619  HECMW_log(HECMW_LOG_DEBUG, "Starting creation of interface table...");
5620 
5621  switch (global_mesh->hecmw_flag_parttype) {
5622  case HECMW_FLAG_PARTTYPE_NODEBASED: /* for node-based partitioning */
5623  rtc = create_comm_info_nb(global_mesh, local_mesh, node_flag, elem_flag,
5624  node_flag_neighbor, elem_flag_neighbor,
5625  current_domain);
5626  if (rtc != RTC_NORMAL) goto error;
5627 
5628  break;
5629 
5630  case HECMW_FLAG_PARTTYPE_ELEMBASED: /* for element-based partitioning */
5631  rtc = create_comm_info_eb(global_mesh, local_mesh, node_flag, elem_flag,
5632  node_flag_neighbor, elem_flag_neighbor,
5633  current_domain);
5634  if (rtc != RTC_NORMAL) goto error;
5635 
5636  break;
5637 
5638  default:
5640  goto error;
5641  }
5642 
5643  HECMW_log(HECMW_LOG_DEBUG, "Creation of interface table done");
5644 
5645  return RTC_NORMAL;
5646 
5647 error:
5648  return RTC_ERROR;
5649 }
5650 
5651 /*==================================================================================================
5652 
5653  create distributed mesh information
5654 
5655 ==================================================================================================*/
5656 
5657 static int set_node_global2local_internal(
5658  const struct hecmwST_local_mesh *global_mesh,
5659  struct hecmwST_local_mesh *local_mesh, int *node_global2local,
5660  const char *node_flag, int domain) {
5661  int counter;
5662  int i, node;
5663 
5664  HECMW_assert(global_mesh);
5665  HECMW_assert(local_mesh);
5666  HECMW_assert(node_global2local);
5667  HECMW_assert(node_flag);
5668  HECMW_assert(global_mesh->n_node > 0);
5669 
5670  for (counter = 0, i = 0; i < n_int_nlist[domain]; i++) {
5671  node = int_nlist[domain][i];
5672  node_global2local[node - 1] = ++counter;
5673  }
5674  local_mesh->nn_internal = counter;
5675 
5676  return RTC_NORMAL;
5677 }
5678 
5679 static int set_node_global2local_external(
5680  const struct hecmwST_local_mesh *global_mesh,
5681  struct hecmwST_local_mesh *local_mesh, int *node_global2local,
5682  const char *node_flag) {
5683  int counter;
5684  int i;
5685 
5686  HECMW_assert(global_mesh);
5687  HECMW_assert(local_mesh);
5688  HECMW_assert(node_global2local);
5689  HECMW_assert(node_flag);
5690  HECMW_assert(global_mesh->n_node > 0);
5691 
5692  /* ordinary external nodes are marked as BOUNDARY && OVERLAP */
5693  for (counter = local_mesh->nn_internal, i = 0; i < global_mesh->n_node; i++) {
5694  if (!EVAL_BIT(node_flag[i], INTERNAL) && EVAL_BIT(node_flag[i], BOUNDARY) &&
5695  EVAL_BIT(node_flag[i], OVERLAP)) {
5696  node_global2local[i] = ++counter;
5697  }
5698  }
5699  local_mesh->nn_middle = counter;
5700 
5701  /* added external contact slave nodes are marked as BOUNDARY but not OVERLAP
5702  */
5703  for (i = 0; i < global_mesh->n_node; i++) {
5704  if (!EVAL_BIT(node_flag[i], INTERNAL) && EVAL_BIT(node_flag[i], BOUNDARY) &&
5705  !EVAL_BIT(node_flag[i], OVERLAP)) {
5706  node_global2local[i] = ++counter;
5707  }
5708  }
5709  local_mesh->n_node = counter;
5710  local_mesh->n_node_gross = counter;
5711 
5712  HECMW_assert(local_mesh->n_node > 0);
5713 
5714  return RTC_NORMAL;
5715 }
5716 
5717 static int set_node_global2local_external_mod(
5718  const struct hecmwST_local_mesh *global_mesh,
5719  struct hecmwST_local_mesh *local_mesh, int *node_global2local,
5720  const char *node_flag, int domain) {
5721  int counter;
5722  int i, node;
5723 
5724  HECMW_assert(global_mesh);
5725  HECMW_assert(local_mesh);
5726  HECMW_assert(node_global2local);
5727  HECMW_assert(node_flag);
5728  HECMW_assert(global_mesh->n_node > 0);
5729 
5730  for (counter = local_mesh->nn_internal, i = n_bnd_nlist[2 * domain];
5731  i < n_bnd_nlist[2 * domain + 1]; i++) {
5732  node = bnd_nlist[domain][i];
5733  node_global2local[node - 1] = ++counter;
5734  }
5735  local_mesh->n_node = counter;
5736  local_mesh->n_node_gross = counter;
5737 
5738  HECMW_assert(local_mesh->n_node > 0);
5739 
5740  return RTC_NORMAL;
5741 }
5742 
5743 static int set_node_global2local_all(
5744  const struct hecmwST_local_mesh *global_mesh,
5745  struct hecmwST_local_mesh *local_mesh, int *node_global2local,
5746  const char *node_flag) {
5747  int counter;
5748  int i;
5749 
5750  HECMW_assert(global_mesh);
5751  HECMW_assert(local_mesh);
5752  HECMW_assert(node_global2local);
5753  HECMW_assert(node_flag);
5754  HECMW_assert(global_mesh->n_node > 0);
5755 
5756  for (counter = 0, i = 0; i < global_mesh->n_node; i++) {
5757  if (EVAL_BIT(node_flag[i], INTERNAL) || EVAL_BIT(node_flag[i], BOUNDARY)) {
5758  node_global2local[i] = ++counter;
5759  }
5760  }
5761  local_mesh->n_node = counter;
5762  local_mesh->n_node_gross = counter;
5763 
5764  HECMW_assert(local_mesh->n_node > 0);
5765 
5766  return RTC_NORMAL;
5767 }
5768 
5769 static int const_nn_internal(const struct hecmwST_local_mesh *global_mesh,
5770  struct hecmwST_local_mesh *local_mesh,
5771  const char *node_flag) {
5772  int counter;
5773  int i;
5774 
5775  HECMW_assert(global_mesh);
5776  HECMW_assert(local_mesh);
5777  HECMW_assert(node_flag);
5778  HECMW_assert(global_mesh->n_node > 0);
5779 
5780  for (counter = 0, i = 0; i < global_mesh->n_node; i++) {
5781  if (EVAL_BIT(node_flag[i], INTERNAL)) counter++;
5782  }
5783  local_mesh->nn_internal = counter;
5784 
5785  return 0;
5786 }
5787 
5788 static int const_node_internal_list(
5789  const struct hecmwST_local_mesh *global_mesh,
5790  struct hecmwST_local_mesh *local_mesh, int *node_global2local,
5791  const char *node_flag) {
5792  int counter;
5793  int i;
5794 
5795  HECMW_assert(global_mesh);
5796  HECMW_assert(local_mesh);
5797  HECMW_assert(node_global2local);
5798  HECMW_assert(node_flag);
5799  HECMW_assert(global_mesh->n_node > 0);
5800 
5801  if (local_mesh->nn_internal == 0) {
5802  local_mesh->node_internal_list = NULL;
5803  return RTC_NORMAL;
5804  }
5805 
5806  local_mesh->node_internal_list =
5807  (int *)HECMW_malloc(sizeof(int) * local_mesh->nn_internal);
5808  if (local_mesh->node_internal_list == NULL) {
5809  HECMW_set_error(errno, "");
5810  goto error;
5811  }
5812 
5813  for (counter = 0, i = 0; i < global_mesh->n_node; i++) {
5814  if (EVAL_BIT(node_flag[i], INTERNAL)) {
5815  local_mesh->node_internal_list[counter++] = node_global2local[i];
5816  }
5817  }
5818  HECMW_assert(counter == local_mesh->nn_internal);
5819 
5820  return RTC_NORMAL;
5821 
5822 error:
5823  return RTC_ERROR;
5824 }
5825 
5826 static int set_node_global2local(const struct hecmwST_local_mesh *global_mesh,
5827  struct hecmwST_local_mesh *local_mesh,
5828  int *node_global2local, const char *node_flag,
5829  int current_domain) {
5830  int rtc;
5831 
5832  HECMW_assert(global_mesh);
5833  HECMW_assert(local_mesh);
5834  HECMW_assert(node_global2local);
5835  HECMW_assert(node_flag);
5836 
5837  switch (global_mesh->hecmw_flag_parttype) {
5839 
5840  rtc = set_node_global2local_internal(global_mesh, local_mesh,
5841  node_global2local, node_flag,
5842  current_domain);
5843  if (rtc != RTC_NORMAL) goto error;
5844 
5845  if (is_spdup_available(global_mesh)) {
5846  rtc = set_node_global2local_external_mod(global_mesh, local_mesh,
5847  node_global2local, node_flag,
5848  current_domain);
5849  } else {
5850  rtc = set_node_global2local_external(global_mesh, local_mesh,
5851  node_global2local, node_flag);
5852  }
5853 
5854  if (rtc != RTC_NORMAL) goto error;
5855 
5856  local_mesh->node_internal_list = NULL;
5857 
5858  break;
5859 
5861 
5862  rtc = const_nn_internal(global_mesh, local_mesh, node_flag);
5863  if (rtc != RTC_NORMAL) goto error;
5864 
5865  rtc = set_node_global2local_all(global_mesh, local_mesh,
5866  node_global2local, node_flag);
5867  if (rtc != RTC_NORMAL) goto error;
5868 
5869  rtc = const_node_internal_list(global_mesh, local_mesh, node_global2local,
5870  node_flag);
5871  if (rtc != RTC_NORMAL) goto error;
5872 
5873  break;
5874 
5875  default:
5877  global_mesh->hecmw_flag_parttype);
5878  goto error;
5879  }
5880 
5881  return RTC_NORMAL;
5882 
5883 error:
5884  return RTC_ERROR;
5885 }
5886 
5887 static int clear_node_global2local(const struct hecmwST_local_mesh *global_mesh,
5888  struct hecmwST_local_mesh *local_mesh,
5889  int *node_global2local, int domain) {
5890  int rtc;
5891  int i, node;
5892 
5893  HECMW_assert(global_mesh);
5894  HECMW_assert(local_mesh);
5895  HECMW_assert(node_global2local);
5896 
5897  if (is_spdup_available(global_mesh)) {
5898  for (i = 0; i < n_int_nlist[domain]; i++) {
5899  node = int_nlist[domain][i];
5900  node_global2local[node - 1] = 0;
5901  }
5902  for (i = n_bnd_nlist[2 * domain]; i < n_bnd_nlist[2 * domain + 1]; i++) {
5903  node = bnd_nlist[domain][i];
5904  node_global2local[node - 1] = 0;
5905  }
5906  } else {
5907  for (i = 0; i < global_mesh->n_node; i++) {
5908  node_global2local[i] = 0;
5909  }
5910  }
5911 
5912  return RTC_NORMAL;
5913 }
5914 
5915 /*------------------------------------------------------------------------------------------------*/
5916 
5917 static int set_node_local2global(const struct hecmwST_local_mesh *global_mesh,
5918  struct hecmwST_local_mesh *local_mesh,
5919  const int *node_global2local,
5920  int *node_local2global) {
5921  int counter;
5922  int i;
5923 
5924  HECMW_assert(global_mesh);
5925  HECMW_assert(local_mesh);
5926  HECMW_assert(node_global2local);
5927  HECMW_assert(node_local2global);
5928  HECMW_assert(global_mesh->n_node > 0);
5929 
5930  for (counter = 0, i = 0; i < global_mesh->n_node; i++) {
5931  if (node_global2local[i]) {
5932  node_local2global[node_global2local[i] - 1] = i + 1;
5933  counter++;
5934  }
5935  }
5936  HECMW_assert(counter == local_mesh->n_node);
5937 
5938  return RTC_NORMAL;
5939 }
5940 
5941 static int set_node_local2global_mod(
5942  const struct hecmwST_local_mesh *global_mesh,
5943  struct hecmwST_local_mesh *local_mesh, const int *node_global2local,
5944  int *node_local2global, int domain) {
5945  int counter;
5946  int i, idx1, idx2, node1, node2, n_int, n_bnd, n_out, maxn;
5947 
5948  HECMW_assert(global_mesh);
5949  HECMW_assert(local_mesh);
5950  HECMW_assert(node_global2local);
5951  HECMW_assert(node_local2global);
5952  HECMW_assert(global_mesh->n_node > 0);
5953 
5954  n_int = n_int_nlist[domain];
5955  n_bnd = n_bnd_nlist[2 * domain];
5956  n_out = n_bnd_nlist[2 * domain + 1] - n_bnd_nlist[2 * domain];
5957  maxn = global_mesh->n_node + 1;
5958 
5959  node1 = (n_int == 0) ? maxn : int_nlist[domain][0];
5960  node2 = (n_out == 0) ? maxn : bnd_nlist[domain][n_bnd];
5961  for (counter = 0, idx1 = 0, idx2 = 0, i = 0; i < n_int + n_out; i++) {
5962  if (node1 < node2) {
5963  node_local2global[node_global2local[node1 - 1] - 1] = node1;
5964  idx1++;
5965  node1 = (idx1 == n_int) ? maxn : int_nlist[domain][idx1];
5966  } else {
5967  node_local2global[node_global2local[node2 - 1] - 1] = node2;
5968  idx2++;
5969  node2 = (idx2 == n_out) ? maxn : bnd_nlist[domain][idx2 + n_bnd];
5970  }
5971  counter++;
5972  }
5973 
5974  HECMW_assert(counter == local_mesh->n_node);
5975 
5976  return RTC_NORMAL;
5977 }
5978 
5979 /*------------------------------------------------------------------------------------------------*/
5980 
5981 static int set_elem_global2local_internal(
5982  const struct hecmwST_local_mesh *global_mesh,
5983  struct hecmwST_local_mesh *local_mesh, int *elem_global2local,
5984  const char *elem_flag) {
5985  int counter;
5986  int i;
5987 
5988  HECMW_assert(global_mesh);
5989  HECMW_assert(local_mesh);
5990  HECMW_assert(elem_global2local);
5991  HECMW_assert(elem_flag);
5992  HECMW_assert(global_mesh->n_elem);
5993 
5994  for (counter = 0, i = 0; i < global_mesh->n_elem; i++) {
5995  if (EVAL_BIT(elem_flag[i], INTERNAL)) {
5996  elem_global2local[i] = ++counter;
5997  }
5998  }
5999  local_mesh->ne_internal = counter;
6000 
6001  return RTC_NORMAL;
6002 }
6003 
6004 static int set_elem_global2local_external(
6005  const struct hecmwST_local_mesh *global_mesh,
6006  struct hecmwST_local_mesh *local_mesh, int *elem_global2local,
6007  const char *elem_flag) {
6008  int counter;
6009  int i;
6010 
6011  HECMW_assert(global_mesh);
6012  HECMW_assert(local_mesh);
6013  HECMW_assert(elem_global2local);
6014  HECMW_assert(elem_flag);
6015  HECMW_assert(global_mesh->n_elem);
6016 
6017  for (counter = local_mesh->ne_internal, i = 0; i < global_mesh->n_elem; i++) {
6018  if (!EVAL_BIT(elem_flag[i], INTERNAL) && EVAL_BIT(elem_flag[i], BOUNDARY)) {
6019  elem_global2local[i] = ++counter;
6020  }
6021  }
6022  local_mesh->n_elem = counter;
6023  local_mesh->n_elem_gross = counter;
6024 
6025  HECMW_assert(local_mesh->n_elem > 0);
6026 
6027  return RTC_NORMAL;
6028 }
6029 
6030 static int set_elem_global2local_all(
6031  const struct hecmwST_local_mesh *global_mesh,
6032  struct hecmwST_local_mesh *local_mesh, int *elem_global2local,
6033  const char *elem_flag) {
6034  int counter;
6035  int i;
6036 
6037  HECMW_assert(global_mesh);
6038  HECMW_assert(local_mesh);
6039  HECMW_assert(elem_global2local);
6040  HECMW_assert(elem_flag);
6041  HECMW_assert(global_mesh->n_elem > 0);
6042 
6043  for (counter = 0, i = 0; i < global_mesh->n_elem; i++) {
6044  if (EVAL_BIT(elem_flag[i], INTERNAL) || EVAL_BIT(elem_flag[i], BOUNDARY)) {
6045  elem_global2local[i] = ++counter;
6046  }
6047  }
6048  local_mesh->n_elem = counter;
6049  local_mesh->n_elem_gross = counter;
6050 
6051  HECMW_assert(local_mesh->n_elem > 0);
6052 
6053  return RTC_NORMAL;
6054 }
6055 
6056 static int set_elem_global2local_all_mod(
6057  const struct hecmwST_local_mesh *global_mesh,
6058  struct hecmwST_local_mesh *local_mesh, int *elem_global2local,
6059  const char *elem_flag, int domain) {
6060  int counter;
6061  int i, idx1, idx2, elem1, elem2, n_int, n_bnd, n_out, maxe;
6062 
6063  HECMW_assert(global_mesh);
6064  HECMW_assert(local_mesh);
6065  HECMW_assert(elem_global2local);
6066  HECMW_assert(elem_flag);
6067  HECMW_assert(global_mesh->n_elem > 0);
6068 
6069  n_int = n_int_elist[domain];
6070  n_bnd = n_bnd_elist[2 * domain];
6071  n_out = n_bnd_elist[2 * domain + 1] - n_bnd_elist[2 * domain];
6072  maxe = global_mesh->n_elem + 1;
6073 
6074  elem1 = (n_int == 0) ? maxe : int_elist[domain][0];
6075  elem2 = (n_out == 0) ? maxe : bnd_elist[domain][n_bnd];
6076  for (counter = 0, idx1 = 0, idx2 = 0, i = 0; i < n_int + n_out; i++) {
6077  if (elem1 < elem2) {
6078  elem_global2local[elem1 - 1] = ++counter;
6079  idx1++;
6080  elem1 = (idx1 == n_int) ? maxe : int_elist[domain][idx1];
6081  } else {
6082  elem_global2local[elem2 - 1] = ++counter;
6083  idx2++;
6084  elem2 = (idx2 == n_out) ? maxe : bnd_elist[domain][idx2 + n_bnd];
6085  }
6086  }
6087 
6088  local_mesh->n_elem = counter;
6089  local_mesh->n_elem_gross = counter;
6090 
6091  HECMW_assert(local_mesh->n_elem > 0);
6092 
6093  return RTC_NORMAL;
6094 }
6095 
6096 static int const_ne_internal(const struct hecmwST_local_mesh *global_mesh,
6097  struct hecmwST_local_mesh *local_mesh,
6098  const char *elem_flag) {
6099  int counter;
6100  int i;
6101 
6102  HECMW_assert(global_mesh->n_elem > 0);
6103 
6104  for (counter = 0, i = 0; i < global_mesh->n_elem; i++) {
6105  if (EVAL_BIT(elem_flag[i], INTERNAL)) counter++;
6106  }
6107  local_mesh->ne_internal = counter;
6108 
6109  return RTC_NORMAL;
6110 }
6111 
6112 static int const_elem_internal_list(
6113  const struct hecmwST_local_mesh *global_mesh,
6114  struct hecmwST_local_mesh *local_mesh, int *elem_global2local,
6115  const char *elem_flag, int domain) {
6116  int counter;
6117  int i, elem;
6118 
6119  HECMW_assert(global_mesh);
6120  HECMW_assert(local_mesh);
6121  HECMW_assert(elem_global2local);
6122  HECMW_assert(elem_flag);
6123  HECMW_assert(global_mesh->n_elem > 0);
6124 
6125  if (local_mesh->ne_internal == 0) {
6126  local_mesh->elem_internal_list = NULL;
6127  return RTC_NORMAL;
6128  }
6129 
6130  local_mesh->elem_internal_list =
6131  (int *)HECMW_malloc(sizeof(int) * local_mesh->ne_internal);
6132  if (local_mesh->elem_internal_list == NULL) {
6133  HECMW_set_error(errno, "");
6134  goto error;
6135  }
6136 
6137  for (counter = 0, i = 0; i < n_int_elist[domain]; i++) {
6138  elem = int_elist[domain][i];
6139  local_mesh->elem_internal_list[counter++] = elem_global2local[elem - 1];
6140  }
6141 
6142  HECMW_assert(counter == local_mesh->ne_internal);
6143 
6144  return RTC_NORMAL;
6145 
6146 error:
6147  return RTC_ERROR;
6148 }
6149 
6150 static int set_elem_global2local(const struct hecmwST_local_mesh *global_mesh,
6151  struct hecmwST_local_mesh *local_mesh,
6152  int *elem_global2local, const char *elem_flag,
6153  int current_domain) {
6154  int rtc;
6155 
6156  HECMW_assert(global_mesh);
6157  HECMW_assert(local_mesh);
6158  HECMW_assert(elem_global2local);
6159  HECMW_assert(elem_flag);
6160 
6161  switch (global_mesh->hecmw_flag_parttype) {
6162  case HECMW_FLAG_PARTTYPE_NODEBASED: /* for node-based partitioning */
6163 
6164  local_mesh->ne_internal = n_int_elist[current_domain];
6165 
6166  if (is_spdup_available(global_mesh)) {
6167  rtc = set_elem_global2local_all_mod(global_mesh, local_mesh,
6168  elem_global2local, elem_flag,
6169  current_domain);
6170  } else {
6171  rtc = set_elem_global2local_all(global_mesh, local_mesh,
6172  elem_global2local, elem_flag);
6173  }
6174 
6175  if (rtc != RTC_NORMAL) goto error;
6176 
6177  rtc = const_elem_internal_list(global_mesh, local_mesh, elem_global2local,
6178  elem_flag, current_domain);
6179 
6180  if (rtc != RTC_NORMAL) goto error;
6181 
6182  break;
6183 
6184  case HECMW_FLAG_PARTTYPE_ELEMBASED: /* for element-based partitioning */
6185 
6186  rtc = set_elem_global2local_internal(global_mesh, local_mesh,
6187  elem_global2local, elem_flag);
6188  if (rtc != RTC_NORMAL) goto error;
6189 
6190  rtc = set_elem_global2local_external(global_mesh, local_mesh,
6191  elem_global2local, elem_flag);
6192  if (rtc != RTC_NORMAL) goto error;
6193 
6194  local_mesh->elem_internal_list = NULL;
6195 
6196  break;
6197 
6198  default:
6200  global_mesh->hecmw_flag_parttype);
6201  goto error;
6202  }
6203 
6204  return RTC_NORMAL;
6205 
6206 error:
6207  return RTC_ERROR;
6208 }
6209 
6210 static int clear_elem_global2local(const struct hecmwST_local_mesh *global_mesh,
6211  struct hecmwST_local_mesh *local_mesh,
6212  int *elem_global2local, int domain) {
6213  int rtc;
6214  int i, elem;
6215 
6216  HECMW_assert(global_mesh);
6217  HECMW_assert(local_mesh);
6218  HECMW_assert(elem_global2local);
6219 
6220  if (is_spdup_available(global_mesh)) {
6221  for (i = 0; i < n_int_elist[domain]; i++) {
6222  elem = int_elist[domain][i];
6223  elem_global2local[elem - 1] = 0;
6224  }
6225  for (i = n_bnd_elist[2 * domain]; i < n_bnd_elist[2 * domain + 1]; i++) {
6226  elem = bnd_elist[domain][i];
6227  elem_global2local[elem - 1] = 0;
6228  }
6229 
6230  } else {
6231  for (i = 0; i < global_mesh->n_elem; i++) {
6232  elem_global2local[i] = 0;
6233  }
6234  }
6235 
6236  return RTC_NORMAL;
6237 }
6238 
6239 /*------------------------------------------------------------------------------------------------*/
6240 
6241 static int set_elem_local2global(const struct hecmwST_local_mesh *global_mesh,
6242  struct hecmwST_local_mesh *local_mesh,
6243  const int *elem_global2local,
6244  int *elem_local2global) {
6245  int counter;
6246  int i;
6247 
6248  HECMW_assert(global_mesh);
6249  HECMW_assert(local_mesh);
6250  HECMW_assert(elem_global2local);
6251  HECMW_assert(elem_local2global);
6252  HECMW_assert(global_mesh->n_elem > 0);
6253 
6254  for (counter = 0, i = 0; i < global_mesh->n_elem; i++) {
6255  if (elem_global2local[i]) {
6256  elem_local2global[elem_global2local[i] - 1] = i + 1;
6257  counter++;
6258  }
6259  }
6260  HECMW_assert(counter == local_mesh->n_elem);
6261 
6262  return RTC_NORMAL;
6263 }
6264 
6265 static int set_elem_local2global_mod(
6266  const struct hecmwST_local_mesh *global_mesh,
6267  struct hecmwST_local_mesh *local_mesh, const int *elem_global2local,
6268  int *elem_local2global, int domain) {
6269  int counter;
6270  int i, idx1, idx2, elem1, elem2, n_int, n_bnd, n_out, maxe;
6271 
6272  HECMW_assert(global_mesh);
6273  HECMW_assert(local_mesh);
6274  HECMW_assert(elem_global2local);
6275  HECMW_assert(elem_local2global);
6276  HECMW_assert(global_mesh->n_elem > 0);
6277 
6278  n_int = n_int_elist[domain];
6279  n_bnd = n_bnd_elist[2 * domain];
6280  n_out = n_bnd_elist[2 * domain + 1] - n_bnd_elist[2 * domain];
6281  maxe = global_mesh->n_elem + 1;
6282 
6283  elem1 = (n_int == 0) ? maxe : int_elist[domain][0];
6284  elem2 = (n_out == 0) ? maxe : bnd_elist[domain][n_bnd];
6285  for (counter = 0, idx1 = 0, idx2 = 0, i = 0; i < n_int + n_out; i++) {
6286  if (elem1 < elem2) {
6287  elem_local2global[elem_global2local[elem1 - 1] - 1] = elem1;
6288  idx1++;
6289  elem1 = (idx1 == n_int) ? maxe : int_elist[domain][idx1];
6290  } else {
6291  elem_local2global[elem_global2local[elem2 - 1] - 1] = elem2;
6292  idx2++;
6293  elem2 = (idx2 == n_out) ? maxe : bnd_elist[domain][idx2 + n_bnd];
6294  }
6295  counter++;
6296  }
6297 
6298  HECMW_assert(counter == local_mesh->n_elem);
6299 
6300  return RTC_NORMAL;
6301 }
6302 
6303 /*================================================================================================*/
6304 
6305 static int const_gridfile(const struct hecmwST_local_mesh *global_mesh,
6306  struct hecmwST_local_mesh *local_mesh) {
6307  snprintf(local_mesh->gridfile, sizeof(local_mesh->gridfile), "%s",
6308  global_mesh->gridfile);
6309 
6310  return RTC_NORMAL;
6311 }
6312 
6313 static int const_hecmw_n_file(const struct hecmwST_local_mesh *global_mesh,
6314  struct hecmwST_local_mesh *local_mesh) {
6315  local_mesh->hecmw_n_file = global_mesh->hecmw_n_file;
6316 
6317  return RTC_NORMAL;
6318 }
6319 
6320 static int const_files(const struct hecmwST_local_mesh *global_mesh,
6321  struct hecmwST_local_mesh *local_mesh) {
6322  local_mesh->files = global_mesh->files;
6323 
6324  return RTC_NORMAL;
6325 }
6326 
6327 static int const_header(const struct hecmwST_local_mesh *global_mesh,
6328  struct hecmwST_local_mesh *local_mesh) {
6329  snprintf(local_mesh->header, sizeof(local_mesh->header), "%s",
6330  global_mesh->header);
6331 
6332  return RTC_NORMAL;
6333 }
6334 
6335 static int const_hecmw_flag_adapt(const struct hecmwST_local_mesh *global_mesh,
6336  struct hecmwST_local_mesh *local_mesh) {
6337  local_mesh->hecmw_flag_adapt = global_mesh->hecmw_flag_adapt;
6338 
6339  return RTC_NORMAL;
6340 }
6341 
6342 static int const_hecmw_flag_initcon(
6343  const struct hecmwST_local_mesh *global_mesh,
6344  struct hecmwST_local_mesh *local_mesh) {
6345  local_mesh->hecmw_flag_initcon = global_mesh->hecmw_flag_initcon;
6346 
6347  return RTC_NORMAL;
6348 }
6349 
6350 static int const_hecmw_flag_parttype(
6351  const struct hecmwST_local_mesh *global_mesh,
6352  struct hecmwST_local_mesh *local_mesh) {
6353  local_mesh->hecmw_flag_parttype = global_mesh->hecmw_flag_parttype;
6354 
6355  return RTC_NORMAL;
6356 }
6357 
6358 static int const_hecmw_flag_partdepth(
6359  const struct hecmwST_local_mesh *global_mesh,
6360  struct hecmwST_local_mesh *local_mesh) {
6361  local_mesh->hecmw_flag_partdepth = global_mesh->hecmw_flag_partdepth;
6362 
6363  return RTC_NORMAL;
6364 }
6365 
6366 static int const_hecmw_flag_version(
6367  const struct hecmwST_local_mesh *global_mesh,
6368  struct hecmwST_local_mesh *local_mesh) {
6369  local_mesh->hecmw_flag_version = global_mesh->hecmw_flag_version;
6370 
6371  return RTC_NORMAL;
6372 }
6373 
6374 static int const_hecmw_flag_partcontact(
6375  const struct hecmwST_local_mesh *global_mesh,
6376  struct hecmwST_local_mesh *local_mesh) {
6377  local_mesh->hecmw_flag_partcontact = global_mesh->hecmw_flag_partcontact;
6378 
6379  return RTC_NORMAL;
6380 }
6381 
6382 static int const_zero_temp(const struct hecmwST_local_mesh *global_mesh,
6383  struct hecmwST_local_mesh *local_mesh) {
6384  local_mesh->zero_temp = global_mesh->zero_temp;
6385 
6386  return RTC_NORMAL;
6387 }
6388 
6389 static int const_global_info(const struct hecmwST_local_mesh *global_mesh,
6390  struct hecmwST_local_mesh *local_mesh) {
6391  int rtc;
6392 
6393  HECMW_assert(global_mesh);
6394  HECMW_assert(local_mesh);
6395 
6396  rtc = const_gridfile(global_mesh, local_mesh);
6397  if (rtc != RTC_NORMAL) goto error;
6398 
6399  rtc = const_hecmw_n_file(global_mesh, local_mesh);
6400  if (rtc != RTC_NORMAL) goto error;
6401 
6402  rtc = const_files(global_mesh, local_mesh);
6403  if (rtc != RTC_NORMAL) goto error;
6404 
6405  rtc = const_header(global_mesh, local_mesh);
6406  if (rtc != RTC_NORMAL) goto error;
6407 
6408  rtc = const_hecmw_flag_adapt(global_mesh, local_mesh);
6409  if (rtc != RTC_NORMAL) goto error;
6410 
6411  rtc = const_hecmw_flag_initcon(global_mesh, local_mesh);
6412  if (rtc != RTC_NORMAL) goto error;
6413 
6414  rtc = const_hecmw_flag_parttype(global_mesh, local_mesh);
6415  if (rtc != RTC_NORMAL) goto error;
6416 
6417  rtc = const_hecmw_flag_partdepth(global_mesh, local_mesh);
6418  if (rtc != RTC_NORMAL) goto error;
6419 
6420  rtc = const_hecmw_flag_version(global_mesh, local_mesh);
6421  if (rtc != RTC_NORMAL) goto error;
6422 
6423  rtc = const_hecmw_flag_partcontact(global_mesh, local_mesh);
6424  if (rtc != RTC_NORMAL) goto error;
6425 
6426  rtc = const_zero_temp(global_mesh, local_mesh);
6427  if (rtc != RTC_NORMAL) goto error;
6428 
6429  return RTC_NORMAL;
6430 
6431 error:
6432  return RTC_ERROR;
6433 }
6434 
6435 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6436  * - - - - - - - - - */
6437 
6438 static int const_n_dof(const struct hecmwST_local_mesh *global_mesh,
6439  struct hecmwST_local_mesh *local_mesh) {
6440  HECMW_assert(global_mesh->n_dof > 0);
6441 
6442  local_mesh->n_dof = global_mesh->n_dof;
6443 
6444  HECMW_assert(local_mesh->n_dof > 0);
6445 
6446  return RTC_NORMAL;
6447 }
6448 
6449 static int const_n_dof_grp(const struct hecmwST_local_mesh *global_mesh,
6450  struct hecmwST_local_mesh *local_mesh) {
6451  HECMW_assert(global_mesh->n_dof_grp);
6452 
6453  local_mesh->n_dof_grp = global_mesh->n_dof_grp;
6454 
6455  HECMW_assert(global_mesh->n_dof_grp);
6456 
6457  return RTC_NORMAL;
6458 }
6459 
6460 static int const_node_dof_index(const struct hecmwST_local_mesh *global_mesh,
6461  struct hecmwST_local_mesh *local_mesh,
6462  const char *node_flag) {
6463  int counter;
6464  int i, j;
6465 
6466  HECMW_assert(local_mesh->n_dof_grp > 0);
6467  HECMW_assert(global_mesh->node_dof_index);
6468 
6469  local_mesh->node_dof_index =
6470  (int *)HECMW_calloc(local_mesh->n_dof_grp + 1, sizeof(int));
6471  if (local_mesh->node_dof_index == NULL) {
6472  HECMW_set_error(errno, "");
6473  goto error;
6474  }
6475 
6476  for (counter = 0, i = 0; i < global_mesh->n_dof_grp; i++) {
6477  for (j = global_mesh->node_dof_index[i];
6478  j < global_mesh->node_dof_index[i + 1]; j++) {
6479  if (EVAL_BIT(node_flag[j], INTERNAL)) counter++;
6480  }
6481  local_mesh->node_dof_index[i + 1] = counter;
6482  }
6483  HECMW_assert(local_mesh->node_dof_index[local_mesh->n_dof_grp] ==
6484  local_mesh->nn_internal);
6485 
6486  return RTC_NORMAL;
6487 
6488 error:
6489  return RTC_ERROR;
6490 }
6491 
6492 static int const_node_dof_index_mod(
6493  const struct hecmwST_local_mesh *global_mesh,
6494  struct hecmwST_local_mesh *local_mesh, const char *node_flag, int domain) {
6495  int counter;
6496  int i, j, node;
6497 
6498  HECMW_assert(local_mesh->n_dof_grp > 0);
6499  HECMW_assert(global_mesh->node_dof_index);
6500 
6501  local_mesh->node_dof_index =
6502  (int *)HECMW_calloc(local_mesh->n_dof_grp + 1, sizeof(int));
6503  if (local_mesh->node_dof_index == NULL) {
6504  HECMW_set_error(errno, "");
6505  goto error;
6506  }
6507 
6508  for (counter = 0, i = 0; i < global_mesh->n_dof_grp; i++) {
6509  for (j = 0; j < n_int_nlist[domain]; j++) {
6510  node = int_nlist[domain][j];
6511  if (node <= global_mesh->node_dof_index[i]) continue;
6512  if (node > global_mesh->node_dof_index[i + 1]) continue;
6513  counter++;
6514  }
6515  local_mesh->node_dof_index[i + 1] = counter;
6516  }
6517 
6518  return RTC_NORMAL;
6519 
6520 error:
6521  return RTC_ERROR;
6522 }
6523 
6524 static int const_node_dof_item(const struct hecmwST_local_mesh *global_mesh,
6525  struct hecmwST_local_mesh *local_mesh) {
6526  HECMW_assert(global_mesh->node_dof_item);
6527 
6528  local_mesh->node_dof_item = global_mesh->node_dof_item;
6529 
6530  return 0;
6531 }
6532 
6533 static int const_node(const struct hecmwST_local_mesh *global_mesh,
6534  struct hecmwST_local_mesh *local_mesh,
6535  const int *node_local2global) {
6536  int i;
6537 
6538  HECMW_assert(local_mesh->n_node > 0);
6539  HECMW_assert(global_mesh->node);
6540 
6541  local_mesh->node =
6542  (double *)HECMW_malloc(sizeof(double) * local_mesh->n_node * 3);
6543  if (local_mesh->node == NULL) {
6544  HECMW_set_error(errno, "");
6545  goto error;
6546  }
6547 
6548  for (i = 0; i < local_mesh->n_node; i++) {
6549  local_mesh->node[3 * i] = global_mesh->node[3 * (node_local2global[i] - 1)];
6550  local_mesh->node[3 * i + 1] =
6551  global_mesh->node[3 * (node_local2global[i] - 1) + 1];
6552  local_mesh->node[3 * i + 2] =
6553  global_mesh->node[3 * (node_local2global[i] - 1) + 2];
6554  }
6555 
6556  return RTC_NORMAL;
6557 
6558 error:
6559  return RTC_ERROR;
6560 }
6561 
6562 static int const_node_id(const struct hecmwST_local_mesh *global_mesh,
6563  struct hecmwST_local_mesh *local_mesh,
6564  const int *node_local2global) {
6565  int i;
6566 
6567  HECMW_assert(local_mesh->n_node > 0);
6568  HECMW_assert(global_mesh->node_ID);
6569 
6570  local_mesh->node_ID =
6571  (int *)HECMW_malloc(sizeof(int) * (size_t)local_mesh->n_node * 2);
6572  if (local_mesh->node_ID == NULL) {
6573  HECMW_set_error(errno, "");
6574  goto error;
6575  }
6576 
6577  for (i = 0; i < local_mesh->n_node; i++) {
6578  local_mesh->node_ID[2 * i] =
6579  global_mesh->node_ID[2 * (node_local2global[i] - 1)];
6580  local_mesh->node_ID[2 * i + 1] =
6581  global_mesh->node_ID[2 * (node_local2global[i] - 1) + 1];
6582  }
6583 
6584  return RTC_NORMAL;
6585 
6586 error:
6587  return RTC_ERROR;
6588 }
6589 
6590 static int const_global_node_id(const struct hecmwST_local_mesh *global_mesh,
6591  struct hecmwST_local_mesh *local_mesh,
6592  const int *node_local2global) {
6593  int i;
6594 
6595  HECMW_assert(local_mesh->n_node > 0);
6596  HECMW_assert(global_mesh->global_node_ID);
6597 
6598  local_mesh->global_node_ID =
6599  (int *)HECMW_malloc(sizeof(int) * local_mesh->n_node);
6600  if (local_mesh->global_node_ID == NULL) {
6601  HECMW_set_error(errno, "");
6602  goto error;
6603  }
6604 
6605  for (i = 0; i < local_mesh->n_node; i++) {
6606  local_mesh->global_node_ID[i] =
6607  global_mesh->global_node_ID[node_local2global[i] - 1];
6608  }
6609 
6610  return RTC_NORMAL;
6611 
6612 error:
6613  return RTC_ERROR;
6614 }
6615 
6616 static int const_node_init_val_index(
6617  const struct hecmwST_local_mesh *global_mesh,
6618  struct hecmwST_local_mesh *local_mesh, const int *node_local2global) {
6619  int old_idx;
6620  int i;
6621 
6622  HECMW_assert(local_mesh->hecmw_flag_initcon);
6623  HECMW_assert(local_mesh->n_node > 0);
6624  HECMW_assert(global_mesh->node_init_val_index);
6625 
6626  local_mesh->node_init_val_index =
6627  (int *)HECMW_calloc(local_mesh->n_node + 1, sizeof(int));
6628  if (local_mesh->node_init_val_index == NULL) {
6629  HECMW_set_error(errno, "");
6630  goto error;
6631  }
6632 
6633  for (i = 0; i < local_mesh->n_node; i++) {
6634  old_idx = node_local2global[i] - 1;
6635 
6636  local_mesh->node_init_val_index[i + 1] =
6637  local_mesh->node_init_val_index[i] +
6638  global_mesh->node_init_val_index[old_idx + 1] -
6639  global_mesh->node_init_val_index[old_idx];
6640  }
6641 
6642  return RTC_NORMAL;
6643 
6644 error:
6645  return RTC_ERROR;
6646 }
6647 
6648 static int const_node_init_val_item(
6649  const struct hecmwST_local_mesh *global_mesh,
6650  struct hecmwST_local_mesh *local_mesh, const int *node_local2global) {
6651  int size;
6652  int counter;
6653  int i, j, gstart, gend, lstart, lend;
6654 
6655  HECMW_assert(local_mesh->hecmw_flag_initcon);
6656  HECMW_assert(local_mesh->n_node > 0);
6657  HECMW_assert(local_mesh->node_init_val_index);
6658  HECMW_assert(global_mesh->node_init_val_item);
6659 
6660  if (local_mesh->node_init_val_index[local_mesh->n_node] == 0) {
6661  local_mesh->node_init_val_item = NULL;
6662  return 0;
6663  }
6664 
6665  size = sizeof(double) * local_mesh->node_init_val_index[local_mesh->n_node];
6666  local_mesh->node_init_val_item = (double *)HECMW_malloc(size);
6667  if (local_mesh->node_init_val_item == NULL) {
6668  HECMW_set_error(errno, "");
6669  goto error;
6670  }
6671 
6672  for (counter = 0, i = 0; i < local_mesh->n_node; i++) {
6673  gstart = global_mesh->node_init_val_index[node_local2global[i] - 1];
6674  gend = global_mesh->node_init_val_index[node_local2global[i]];
6675  lstart = local_mesh->node_init_val_index[i];
6676  lend = local_mesh->node_init_val_index[i + 1];
6677 
6678  HECMW_assert(gend - gstart == lend - lstart);
6679 
6680  for (j = 0; j < lend - lstart; j++) {
6681  local_mesh->node_init_val_item[lstart + j] =
6682  global_mesh->node_init_val_item[gstart + j];
6683  counter++;
6684  }
6685  HECMW_assert(counter == local_mesh->node_init_val_index[i + 1]);
6686  }
6687 
6688  return RTC_NORMAL;
6689 
6690 error:
6691  return RTC_ERROR;
6692 }
6693 
6694 static int const_node_info(const struct hecmwST_local_mesh *global_mesh,
6695  struct hecmwST_local_mesh *local_mesh,
6696  const int *node_local2global, const char *node_flag,
6697  int current_domain) {
6698  int rtc;
6699 
6700  HECMW_assert(global_mesh);
6701  HECMW_assert(local_mesh);
6702  HECMW_assert(node_local2global);
6703  HECMW_assert(node_flag);
6704 
6705  rtc = const_n_dof(global_mesh, local_mesh);
6706  if (rtc != RTC_NORMAL) goto error;
6707 
6708  rtc = const_n_dof_grp(global_mesh, local_mesh);
6709  if (rtc != RTC_NORMAL) goto error;
6710 
6711  switch (global_mesh->hecmw_flag_parttype) {
6713  rtc = const_node_dof_index_mod(global_mesh, local_mesh, node_flag,
6714  current_domain);
6715  break;
6717  rtc = const_node_dof_index(global_mesh, local_mesh, node_flag);
6718  break;
6719  default:
6720  HECMW_set_error(errno, "");
6721  goto error;
6722  }
6723 
6724  if (rtc != RTC_NORMAL) goto error;
6725 
6726  rtc = const_node_dof_item(global_mesh, local_mesh);
6727  if (rtc != RTC_NORMAL) goto error;
6728 
6729  rtc = const_node(global_mesh, local_mesh, node_local2global);
6730  if (rtc != RTC_NORMAL) goto error;
6731 
6732  rtc = const_node_id(global_mesh, local_mesh, node_local2global);
6733  if (rtc != RTC_NORMAL) goto error;
6734 
6735  rtc = const_global_node_id(global_mesh, local_mesh, node_local2global);
6736  if (rtc != RTC_NORMAL) goto error;
6737 
6738  if (local_mesh->hecmw_flag_initcon) {
6739  rtc = const_node_init_val_index(global_mesh, local_mesh, node_local2global);
6740  if (rtc != RTC_NORMAL) goto error;
6741 
6742  rtc = const_node_init_val_item(global_mesh, local_mesh, node_local2global);
6743  if (rtc != RTC_NORMAL) goto error;
6744  }
6745 
6746  return RTC_NORMAL;
6747 
6748 error:
6749  return RTC_ERROR;
6750 }
6751 
6752 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6753  * - - - - - - - - - */
6754 
6755 static int const_n_elem_type(const struct hecmwST_local_mesh *global_mesh,
6756  struct hecmwST_local_mesh *local_mesh) {
6757  HECMW_assert(global_mesh->n_elem_type > 0);
6758 
6759  local_mesh->n_elem_type = global_mesh->n_elem_type;
6760 
6761  HECMW_assert(local_mesh->n_elem_type > 0);
6762 
6763  return RTC_NORMAL;
6764 }
6765 
6766 static int const_elem_type(const struct hecmwST_local_mesh *global_mesh,
6767  struct hecmwST_local_mesh *local_mesh,
6768  const int *elem_local2global) {
6769  int i;
6770 
6771  HECMW_assert(local_mesh->n_elem > 0);
6772  HECMW_assert(global_mesh->elem_type);
6773 
6774  local_mesh->elem_type = (int *)HECMW_malloc(sizeof(int) * local_mesh->n_elem);
6775  if (local_mesh->elem_type == NULL) {
6776  HECMW_set_error(errno, "");
6777  goto error;
6778  }
6779 
6780  for (i = 0; i < local_mesh->n_elem; i++) {
6781  local_mesh->elem_type[i] = global_mesh->elem_type[elem_local2global[i] - 1];
6782  }
6783 
6784  return RTC_NORMAL;
6785 
6786 error:
6787  return RTC_ERROR;
6788 }
6789 
6790 static int const_elem_type_index(const struct hecmwST_local_mesh *global_mesh,
6791  struct hecmwST_local_mesh *local_mesh,
6792  const int *elem_global2local) {
6793  int counter;
6794  int i, j;
6795 
6796  HECMW_assert(local_mesh->n_elem_type > 0);
6797  HECMW_assert(global_mesh->n_elem_type > 0);
6798  HECMW_assert(global_mesh->elem_type_index);
6799 
6800  local_mesh->elem_type_index =
6801  (int *)HECMW_calloc(local_mesh->n_elem_type + 1, sizeof(int));
6802  if (local_mesh->elem_type_index == NULL) {
6803  HECMW_set_error(errno, "");
6804  goto error;
6805  }
6806 
6807  for (counter = 0, i = 0; i < global_mesh->n_elem_type; i++) {
6808  for (j = global_mesh->elem_type_index[i];
6809  j < global_mesh->elem_type_index[i + 1]; j++) {
6810  if (elem_global2local[j]) counter++;
6811  }
6812  local_mesh->elem_type_index[i + 1] = counter;
6813  }
6814  HECMW_assert(local_mesh->elem_type_index[local_mesh->n_elem_type] ==
6815  local_mesh->n_elem);
6816 
6817  return RTC_NORMAL;
6818 
6819 error:
6820  return RTC_ERROR;
6821 }
6822 
6823 static int const_elem_type_index_mod(
6824  const struct hecmwST_local_mesh *global_mesh,
6825  struct hecmwST_local_mesh *local_mesh, const int *elem_global2local,
6826  int domain) {
6827  int counter;
6828  int i, j, idx1, idx2, elem_tmp, elem1, elem2, n_int, n_bnd, n_out, maxe;
6829 
6830  HECMW_assert(local_mesh->n_elem_type > 0);
6831  HECMW_assert(global_mesh->n_elem_type > 0);
6832  HECMW_assert(global_mesh->elem_type_index);
6833 
6834  local_mesh->elem_type_index =
6835  (int *)HECMW_calloc(local_mesh->n_elem_type + 1, sizeof(int));
6836  if (local_mesh->elem_type_index == NULL) {
6837  HECMW_set_error(errno, "");
6838  goto error;
6839  }
6840 
6841  n_int = n_int_elist[domain];
6842  n_bnd = n_bnd_elist[2 * domain];
6843  n_out = n_bnd_elist[2 * domain + 1] - n_bnd_elist[2 * domain];
6844  maxe = global_mesh->n_elem + 1;
6845 
6846  for (counter = 0, i = 0; i < global_mesh->n_elem_type; i++) {
6847  elem1 = (n_int == 0) ? maxe : int_elist[domain][0];
6848  elem2 = (n_out == 0) ? maxe : bnd_elist[domain][n_bnd];
6849  for (idx1 = 0, idx2 = 0, j = 0; j < n_int + n_out; j++) {
6850  if (elem1 < elem2) {
6851  elem_tmp = elem1 - 1;
6852  idx1++;
6853  elem1 = (idx1 == n_int) ? maxe : int_elist[domain][idx1];
6854  } else {
6855  elem_tmp = elem2 - 1;
6856  idx2++;
6857  elem2 = (idx2 == n_out) ? maxe : bnd_elist[domain][idx2 + n_bnd];
6858  }
6859  if (elem_tmp >= global_mesh->elem_type_index[i] &&
6860  elem_tmp < global_mesh->elem_type_index[i + 1]) {
6861  counter++;
6862  }
6863  }
6864  local_mesh->elem_type_index[i + 1] = counter;
6865  }
6866 
6867  HECMW_assert(local_mesh->elem_type_index[local_mesh->n_elem_type] ==
6868  local_mesh->n_elem);
6869 
6870  return RTC_NORMAL;
6871 
6872 error:
6873  return RTC_ERROR;
6874 }
6875 
6876 static int const_elem_type_item(const struct hecmwST_local_mesh *global_mesh,
6877  struct hecmwST_local_mesh *local_mesh) {
6878  HECMW_assert(global_mesh->elem_type_item);
6879 
6880  local_mesh->elem_type_item = global_mesh->elem_type_item;
6881 
6882  return RTC_NORMAL;
6883 }
6884 
6885 static int const_elem_node_index(const struct hecmwST_local_mesh *global_mesh,
6886  struct hecmwST_local_mesh *local_mesh,
6887  const int *elem_local2global) {
6888  int old_idx;
6889  int i;
6890 
6891  HECMW_assert(local_mesh->n_elem > 0);
6892  HECMW_assert(global_mesh->elem_node_index);
6893 
6894  local_mesh->elem_node_index =
6895  (long long *)HECMW_calloc(local_mesh->n_elem + 1, sizeof(long long));
6896  if (local_mesh->elem_node_index == NULL) {
6897  HECMW_set_error(errno, "");
6898  goto error;
6899  }
6900 
6901  for (i = 0; i < local_mesh->n_elem; i++) {
6902  old_idx = elem_local2global[i] - 1;
6903 
6904  local_mesh->elem_node_index[i + 1] =
6905  local_mesh->elem_node_index[i] +
6906  global_mesh->elem_node_index[old_idx + 1] -
6907  global_mesh->elem_node_index[old_idx];
6908  }
6909 
6910  return RTC_NORMAL;
6911 
6912 error:
6913  return RTC_ERROR;
6914 }
6915 
6916 static int const_elem_node_item(const struct hecmwST_local_mesh *global_mesh,
6917  struct hecmwST_local_mesh *local_mesh,
6918  const int *node_global2local,
6919  const int *elem_local2global) {
6920  int node;
6921  size_t size;
6922  long long counter;
6923  int i, j;
6924  long long gstart, gend, lstart, lend;
6925 
6926  HECMW_assert(local_mesh->n_elem > 0);
6927  HECMW_assert(local_mesh->elem_node_index);
6928  HECMW_assert(local_mesh->elem_node_index[local_mesh->n_elem] > 0);
6929  HECMW_assert(global_mesh->elem_node_item);
6930 
6931  size = sizeof(int) * (size_t)local_mesh->elem_node_index[local_mesh->n_elem];
6932  local_mesh->elem_node_item = (int *)HECMW_malloc(size);
6933  if (local_mesh->elem_node_item == NULL) {
6934  HECMW_set_error(errno, "");
6935  goto error;
6936  }
6937 
6938  for (counter = 0, i = 0; i < local_mesh->n_elem; i++) {
6939  gstart = global_mesh->elem_node_index[elem_local2global[i] - 1];
6940  gend = global_mesh->elem_node_index[elem_local2global[i]];
6941  lstart = local_mesh->elem_node_index[i];
6942  lend = local_mesh->elem_node_index[i + 1];
6943 
6944  for (j = 0; j < lend - lstart; j++) {
6945  node = global_mesh->elem_node_item[gstart + j];
6946  local_mesh->elem_node_item[lstart + j] = node_global2local[node - 1];
6947  counter++;
6948  }
6949  HECMW_assert(counter == local_mesh->elem_node_index[i + 1]);
6950  }
6951 
6952  return RTC_NORMAL;
6953 
6954 error:
6955  return RTC_ERROR;
6956 }
6957 
6958 static int const_elem_id(const struct hecmwST_local_mesh *global_mesh,
6959  struct hecmwST_local_mesh *local_mesh,
6960  const int *elem_local2global) {
6961  int i;
6962 
6963  HECMW_assert(local_mesh->n_elem > 0);
6964  HECMW_assert(global_mesh->elem_ID);
6965 
6966  local_mesh->elem_ID =
6967  (int *)HECMW_malloc(sizeof(int) * (size_t)local_mesh->n_elem * 2);
6968  if (local_mesh->elem_ID == NULL) {
6969  HECMW_set_error(errno, "");
6970  goto error;
6971  }
6972 
6973  for (i = 0; i < local_mesh->n_elem; i++) {
6974  local_mesh->elem_ID[2 * i] =
6975  global_mesh->elem_ID[2 * (elem_local2global[i] - 1)];
6976  local_mesh->elem_ID[2 * i + 1] =
6977  global_mesh->elem_ID[2 * (elem_local2global[i] - 1) + 1];
6978  }
6979 
6980  return RTC_NORMAL;
6981 
6982 error:
6983  return RTC_ERROR;
6984 }
6985 
6986 static int const_global_elem_id(const struct hecmwST_local_mesh *global_mesh,
6987  struct hecmwST_local_mesh *local_mesh,
6988  const int *elem_local2global) {
6989  int i;
6990 
6991  HECMW_assert(local_mesh->n_elem);
6992  HECMW_assert(global_mesh->global_elem_ID);
6993 
6994  local_mesh->global_elem_ID =
6995  (int *)HECMW_malloc(sizeof(int) * local_mesh->n_elem);
6996  if (local_mesh->global_elem_ID == NULL) {
6997  HECMW_set_error(errno, "");
6998  goto error;
6999  }
7000 
7001  for (i = 0; i < local_mesh->n_elem; i++) {
7002  local_mesh->global_elem_ID[i] =
7003  global_mesh->global_elem_ID[elem_local2global[i] - 1];
7004  }
7005 
7006  return RTC_NORMAL;
7007 
7008 error:
7009  return RTC_ERROR;
7010 }
7011 
7012 static int const_section_id(const struct hecmwST_local_mesh *global_mesh,
7013  struct hecmwST_local_mesh *local_mesh,
7014  const int *elem_local2global) {
7015  int i;
7016 
7017  HECMW_assert(local_mesh->n_elem);
7018  HECMW_assert(global_mesh->section_ID);
7019 
7020  local_mesh->section_ID =
7021  (int *)HECMW_malloc(sizeof(int) * local_mesh->n_elem);
7022  if (local_mesh->section_ID == NULL) {
7023  HECMW_set_error(errno, "");
7024  goto error;
7025  }
7026 
7027  for (i = 0; i < local_mesh->n_elem; i++) {
7028  local_mesh->section_ID[i] =
7029  global_mesh->section_ID[elem_local2global[i] - 1];
7030  }
7031 
7032  return RTC_NORMAL;
7033 
7034 error:
7035  return RTC_ERROR;
7036 }
7037 
7038 static int const_elem_mat_id_index(const struct hecmwST_local_mesh *global_mesh,
7039  struct hecmwST_local_mesh *local_mesh,
7040  const int *elem_local2global) {
7041  int old_idx;
7042  int i;
7043 
7044  HECMW_assert(local_mesh->n_elem > 0);
7045  HECMW_assert(global_mesh->elem_mat_ID_index);
7046 
7047  local_mesh->elem_mat_ID_index =
7048  (int *)HECMW_calloc(local_mesh->n_elem + 1, sizeof(int));
7049  if (local_mesh->elem_mat_ID_index == NULL) {
7050  HECMW_set_error(errno, "");
7051  goto error;
7052  }
7053 
7054  for (i = 0; i < local_mesh->n_elem; i++) {
7055  old_idx = elem_local2global[i] - 1;
7056 
7057  local_mesh->elem_mat_ID_index[i + 1] =
7058  local_mesh->elem_mat_ID_index[i] +
7059  global_mesh->elem_mat_ID_index[old_idx + 1] -
7060  global_mesh->elem_mat_ID_index[old_idx];
7061  }
7062 
7063  return RTC_NORMAL;
7064 
7065 error:
7066  return RTC_ERROR;
7067 }
7068 
7069 static int const_n_elem_mat_id(struct hecmwST_local_mesh *local_mesh) {
7070  HECMW_assert(local_mesh->n_elem > 0);
7071  HECMW_assert(local_mesh->elem_mat_ID_index);
7072 
7073  local_mesh->n_elem_mat_ID = local_mesh->elem_mat_ID_index[local_mesh->n_elem];
7074 
7075  return RTC_NORMAL;
7076 }
7077 
7078 static int const_elem_mat_id_item(const struct hecmwST_local_mesh *global_mesh,
7079  struct hecmwST_local_mesh *local_mesh,
7080  const int *elem_local2global) {
7081  int size;
7082  int counter;
7083  int i, j, gstart, gend, lstart, lend;
7084 
7085  HECMW_assert(local_mesh->n_elem > 0);
7086  HECMW_assert(local_mesh->elem_mat_ID_index[local_mesh->n_elem] >= 0);
7087 
7088  if (local_mesh->elem_mat_ID_index[local_mesh->n_elem] == 0) {
7089  local_mesh->elem_mat_ID_item = NULL;
7090  return RTC_NORMAL;
7091  }
7092 
7093  size = sizeof(int) * local_mesh->elem_mat_ID_index[local_mesh->n_elem];
7094  local_mesh->elem_mat_ID_item = (int *)HECMW_malloc(size);
7095  if (local_mesh->elem_mat_ID_item == NULL) {
7096  HECMW_set_error(errno, "");
7097  goto error;
7098  }
7099 
7100  for (counter = 0, i = 0; i < local_mesh->n_elem; i++) {
7101  gstart = global_mesh->elem_mat_ID_index[elem_local2global[i] - 1];
7102  gend = global_mesh->elem_mat_ID_index[elem_local2global[i]];
7103  lstart = local_mesh->elem_mat_ID_index[i];
7104  lend = local_mesh->elem_mat_ID_index[i + 1];
7105 
7106  HECMW_assert(lend - lstart == gend - gstart);
7107 
7108  for (j = 0; j < lend - lstart; j++) {
7109  local_mesh->elem_mat_ID_item[lstart + j] =
7110  global_mesh->elem_mat_ID_item[gstart + j];
7111  counter++;
7112  }
7113  HECMW_assert(counter == local_mesh->elem_mat_ID_index[i + 1]);
7114  }
7115  HECMW_assert(counter == local_mesh->n_elem_mat_ID);
7116 
7117  return RTC_NORMAL;
7118 
7119 error:
7120  return RTC_ERROR;
7121 }
7122 
7123 static int const_elem_info(const struct hecmwST_local_mesh *global_mesh,
7124  struct hecmwST_local_mesh *local_mesh,
7125  const int *node_global2local,
7126  const int *elem_global2local,
7127  const int *elem_local2global, int current_domain) {
7128  int rtc;
7129 
7130  HECMW_assert(global_mesh);
7131  HECMW_assert(local_mesh);
7132  HECMW_assert(node_global2local);
7133  HECMW_assert(elem_global2local);
7134  HECMW_assert(elem_local2global);
7135 
7136  rtc = const_n_elem_type(global_mesh, local_mesh);
7137  if (rtc != RTC_NORMAL) goto error;
7138 
7139  rtc = const_elem_type(global_mesh, local_mesh, elem_local2global);
7140  if (rtc != RTC_NORMAL) goto error;
7141 
7142  if (is_spdup_available(global_mesh)) {
7143  rtc = const_elem_type_index_mod(global_mesh, local_mesh, elem_global2local,
7144  current_domain);
7145  } else {
7146  rtc = const_elem_type_index(global_mesh, local_mesh, elem_global2local);
7147  }
7148 
7149  if (rtc != RTC_NORMAL) goto error;
7150 
7151  rtc = const_elem_type_item(global_mesh, local_mesh);
7152  if (rtc != RTC_NORMAL) goto error;
7153 
7154  rtc = const_elem_node_index(global_mesh, local_mesh, elem_local2global);
7155  if (rtc != RTC_NORMAL) goto error;
7156 
7157  rtc = const_elem_node_item(global_mesh, local_mesh, node_global2local,
7158  elem_local2global);
7159  if (rtc != RTC_NORMAL) goto error;
7160 
7161  rtc = const_elem_id(global_mesh, local_mesh, elem_local2global);
7162  if (rtc != RTC_NORMAL) goto error;
7163 
7164  rtc = const_global_elem_id(global_mesh, local_mesh, elem_local2global);
7165  if (rtc != RTC_NORMAL) goto error;
7166 
7167  rtc = const_section_id(global_mesh, local_mesh, elem_local2global);
7168  if (rtc != RTC_NORMAL) goto error;
7169 
7170  rtc = const_elem_mat_id_index(global_mesh, local_mesh, elem_local2global);
7171  if (rtc != RTC_NORMAL) goto error;
7172 
7173  rtc = const_n_elem_mat_id(local_mesh);
7174  if (rtc != RTC_NORMAL) goto error;
7175 
7176  rtc = const_elem_mat_id_item(global_mesh, local_mesh, elem_local2global);
7177  if (rtc != RTC_NORMAL) goto error;
7178 
7179  return RTC_NORMAL;
7180 
7181 error:
7182  return RTC_ERROR;
7183 }
7184 
7185 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7186  * - - - - - - - - - */
7187 
7188 static int const_hecmw_comm(const struct hecmwST_local_mesh *global_mesh,
7189  struct hecmwST_local_mesh *local_mesh) {
7190  local_mesh->HECMW_COMM = global_mesh->HECMW_COMM;
7191 
7192  return RTC_NORMAL;
7193 }
7194 
7195 static int const_zero(struct hecmwST_local_mesh *local_mesh,
7196  int current_domain) {
7197  local_mesh->zero = (current_domain == 0) ? 1 : 0;
7198 
7199  return RTC_NORMAL;
7200 }
7201 
7202 static int const_petot(const struct hecmwST_local_mesh *global_mesh,
7203  struct hecmwST_local_mesh *local_mesh) {
7204  local_mesh->PETOT = global_mesh->n_subdomain;
7205 
7206  return RTC_NORMAL;
7207 }
7208 
7209 static int const_pesmptot(const struct hecmwST_local_mesh *global_mesh,
7210  struct hecmwST_local_mesh *local_mesh) {
7211  local_mesh->PEsmpTOT = global_mesh->PEsmpTOT;
7212 
7213  return RTC_NORMAL;
7214 }
7215 
7216 static int const_my_rank(struct hecmwST_local_mesh *local_mesh,
7217  int current_domain) {
7218  local_mesh->my_rank = current_domain;
7219 
7220  return RTC_NORMAL;
7221 }
7222 
7223 static int const_errnof(const struct hecmwST_local_mesh *global_mesh,
7224  struct hecmwST_local_mesh *local_mesh) {
7225  local_mesh->errnof = global_mesh->errnof;
7226 
7227  return RTC_NORMAL;
7228 }
7229 
7230 static int const_n_subdomain(const struct hecmwST_local_mesh *global_mesh,
7231  struct hecmwST_local_mesh *local_mesh) {
7232  local_mesh->n_subdomain = global_mesh->n_subdomain;
7233 
7234  return RTC_NORMAL;
7235 }
7236 
7237 static int const_import_item(struct hecmwST_local_mesh *local_mesh,
7238  const int *global2local) {
7239  int new_id;
7240  int i;
7241 
7242  if (local_mesh->n_neighbor_pe == 0) {
7243  local_mesh->import_item = NULL;
7244  return RTC_NORMAL;
7245  }
7246 
7247  HECMW_assert(local_mesh->n_neighbor_pe > 0);
7248  HECMW_assert(local_mesh->import_index);
7249  HECMW_assert(local_mesh->import_index[local_mesh->n_neighbor_pe] >= 0);
7250  HECMW_assert(local_mesh->import_item);
7251 
7252  for (i = 0; i < local_mesh->import_index[local_mesh->n_neighbor_pe]; i++) {
7253  new_id = global2local[local_mesh->import_item[i] - 1];
7254  local_mesh->import_item[i] = new_id;
7255  }
7256 
7257  return RTC_NORMAL;
7258 }
7259 
7260 static int const_export_item(struct hecmwST_local_mesh *local_mesh,
7261  const int *global2local) {
7262  int new_id;
7263  int i;
7264 
7265  if (local_mesh->n_neighbor_pe == 0) {
7266  local_mesh->export_item = NULL;
7267  return RTC_NORMAL;
7268  }
7269 
7270  HECMW_assert(local_mesh->n_neighbor_pe > 0);
7271  HECMW_assert(local_mesh->export_index);
7272  HECMW_assert(local_mesh->export_index[local_mesh->n_neighbor_pe] >= 0);
7273  HECMW_assert(local_mesh->export_item);
7274 
7275  for (i = 0; i < local_mesh->export_index[local_mesh->n_neighbor_pe]; i++) {
7276  new_id = global2local[local_mesh->export_item[i] - 1];
7277  local_mesh->export_item[i] = new_id;
7278  }
7279 
7280  return RTC_NORMAL;
7281 }
7282 
7283 static int const_shared_item(struct hecmwST_local_mesh *local_mesh,
7284  const int *global2local) {
7285  int new_id;
7286  int i;
7287 
7288  if (local_mesh->n_neighbor_pe == 0) {
7289  local_mesh->shared_item = NULL;
7290  return RTC_NORMAL;
7291  }
7292 
7293  HECMW_assert(local_mesh->n_neighbor_pe > 0);
7294  HECMW_assert(local_mesh->shared_index);
7295  HECMW_assert(local_mesh->shared_index[local_mesh->n_neighbor_pe] >= 0);
7296  HECMW_assert(local_mesh->shared_item);
7297 
7298  for (i = 0; i < local_mesh->shared_index[local_mesh->n_neighbor_pe]; i++) {
7299  new_id = global2local[local_mesh->shared_item[i] - 1];
7300  local_mesh->shared_item[i] = new_id;
7301  }
7302 
7303  return RTC_NORMAL;
7304 }
7305 
7306 static int const_comm_info(const struct hecmwST_local_mesh *global_mesh,
7307  struct hecmwST_local_mesh *local_mesh,
7308  const int *node_global2local,
7309  const int *elem_global2local, int current_domain) {
7310  int rtc;
7311 
7312  HECMW_assert(global_mesh);
7313  HECMW_assert(local_mesh);
7314  HECMW_assert(node_global2local);
7315  HECMW_assert(elem_global2local);
7316 
7317  rtc = const_hecmw_comm(global_mesh, local_mesh);
7318  if (rtc != RTC_NORMAL) goto error;
7319 
7320  rtc = const_zero(local_mesh, current_domain);
7321  if (rtc != RTC_NORMAL) goto error;
7322 
7323  rtc = const_petot(global_mesh, local_mesh);
7324  if (rtc != RTC_NORMAL) goto error;
7325 
7326  rtc = const_pesmptot(global_mesh, local_mesh);
7327  if (rtc != RTC_NORMAL) goto error;
7328 
7329  rtc = const_my_rank(local_mesh, current_domain);
7330  if (rtc != RTC_NORMAL) goto error;
7331 
7332  rtc = const_errnof(global_mesh, local_mesh);
7333  if (rtc != RTC_NORMAL) goto error;
7334 
7335  rtc = const_n_subdomain(global_mesh, local_mesh);
7336  if (rtc != RTC_NORMAL) goto error;
7337 
7338  switch (global_mesh->hecmw_flag_parttype) {
7340  rtc = const_import_item(local_mesh, node_global2local);
7341  if (rtc != RTC_NORMAL) goto error;
7342 
7343  rtc = const_export_item(local_mesh, node_global2local);
7344  if (rtc != RTC_NORMAL) goto error;
7345 
7346  rtc = const_shared_item(local_mesh, elem_global2local);
7347  if (rtc != RTC_NORMAL) goto error;
7348 
7349  break;
7350 
7352  rtc = const_import_item(local_mesh, elem_global2local);
7353  if (rtc != RTC_NORMAL) goto error;
7354 
7355  rtc = const_export_item(local_mesh, elem_global2local);
7356  if (rtc != RTC_NORMAL) goto error;
7357 
7358  rtc = const_shared_item(local_mesh, node_global2local);
7359  if (rtc != RTC_NORMAL) goto error;
7360 
7361  break;
7362 
7363  default:
7365  global_mesh->hecmw_flag_parttype);
7366  goto error;
7367  }
7368 
7369  return RTC_NORMAL;
7370 
7371 error:
7372  return RTC_ERROR;
7373 }
7374 
7375 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7376  * - - - - - - - - - */
7377 
7378 static int const_n_adapt(const struct hecmwST_local_mesh *global_mesh,
7379  struct hecmwST_local_mesh *local_mesh) {
7380  local_mesh->n_adapt = global_mesh->n_adapt;
7381 
7382  return RTC_NORMAL;
7383 }
7384 
7385 static int const_coarse_grid_level(const struct hecmwST_local_mesh *global_mesh,
7386  struct hecmwST_local_mesh *local_mesh) {
7387  local_mesh->coarse_grid_level = global_mesh->coarse_grid_level;
7388 
7389  return RTC_NORMAL;
7390 }
7391 
7392 static int const_when_i_was_refined_node(
7393  const struct hecmwST_local_mesh *global_mesh,
7394  struct hecmwST_local_mesh *local_mesh) {
7395  local_mesh->when_i_was_refined_node = global_mesh->when_i_was_refined_node;
7396 
7397  return RTC_NORMAL;
7398 }
7399 
7400 static int const_when_i_was_refined_elem(
7401  const struct hecmwST_local_mesh *global_mesh,
7402  struct hecmwST_local_mesh *local_mesh) {
7403  local_mesh->when_i_was_refined_elem = global_mesh->when_i_was_refined_elem;
7404 
7405  return RTC_NORMAL;
7406 }
7407 
7408 static int const_adapt_parent_type(const struct hecmwST_local_mesh *global_mesh,
7409  struct hecmwST_local_mesh *local_mesh) {
7410  local_mesh->adapt_parent_type = global_mesh->adapt_parent_type;
7411 
7412  return RTC_NORMAL;
7413 }
7414 
7415 static int const_adapt_type(const struct hecmwST_local_mesh *global_mesh,
7416  struct hecmwST_local_mesh *local_mesh) {
7417  local_mesh->adapt_type = global_mesh->adapt_type;
7418 
7419  return RTC_NORMAL;
7420 }
7421 
7422 static int const_adapt_level(const struct hecmwST_local_mesh *global_mesh,
7423  struct hecmwST_local_mesh *local_mesh) {
7424  local_mesh->adapt_level = global_mesh->adapt_level;
7425 
7426  return RTC_NORMAL;
7427 }
7428 
7429 static int const_adapt_parent(const struct hecmwST_local_mesh *global_mesh,
7430  struct hecmwST_local_mesh *local_mesh) {
7431  local_mesh->adapt_parent = global_mesh->adapt_parent;
7432 
7433  return RTC_NORMAL;
7434 }
7435 
7436 static int const_adapt_children_index(
7437  const struct hecmwST_local_mesh *global_mesh,
7438  struct hecmwST_local_mesh *local_mesh) {
7439  local_mesh->adapt_children_index = global_mesh->adapt_children_index;
7440 
7441  return RTC_NORMAL;
7442 }
7443 
7444 static int const_adapt_children_item(
7445  const struct hecmwST_local_mesh *global_mesh,
7446  struct hecmwST_local_mesh *local_mesh) {
7447  local_mesh->adapt_children_item = global_mesh->adapt_children_item;
7448 
7449  return RTC_NORMAL;
7450 }
7451 
7452 static int const_adapt_info(const struct hecmwST_local_mesh *global_mesh,
7453  struct hecmwST_local_mesh *local_mesh) {
7454  int rtc;
7455 
7456  HECMW_assert(global_mesh);
7457  HECMW_assert(local_mesh);
7458 
7459  rtc = const_n_adapt(global_mesh, local_mesh);
7460  if (rtc != RTC_NORMAL) goto error;
7461 
7462  rtc = const_coarse_grid_level(global_mesh, local_mesh);
7463  if (rtc != RTC_NORMAL) goto error;
7464 
7465  rtc = const_when_i_was_refined_node(global_mesh, local_mesh);
7466  if (rtc != RTC_NORMAL) goto error;
7467 
7468  rtc = const_when_i_was_refined_elem(global_mesh, local_mesh);
7469  if (rtc != RTC_NORMAL) goto error;
7470 
7471  rtc = const_adapt_parent_type(global_mesh, local_mesh);
7472  if (rtc != RTC_NORMAL) goto error;
7473 
7474  rtc = const_adapt_type(global_mesh, local_mesh);
7475  if (rtc != RTC_NORMAL) goto error;
7476 
7477  rtc = const_adapt_level(global_mesh, local_mesh);
7478  if (rtc != RTC_NORMAL) goto error;
7479 
7480  rtc = const_adapt_parent(global_mesh, local_mesh);
7481  if (rtc != RTC_NORMAL) goto error;
7482 
7483  rtc = const_adapt_children_index(global_mesh, local_mesh);
7484  if (rtc != RTC_NORMAL) goto error;
7485 
7486  rtc = const_adapt_children_item(global_mesh, local_mesh);
7487  if (rtc != RTC_NORMAL) goto error;
7488 
7489  return RTC_NORMAL;
7490 
7491 error:
7492  return RTC_ERROR;
7493 }
7494 
7495 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7496  * - - - - - - - - - */
7497 
7498 static int const_n_sect(const struct hecmwST_local_mesh *global_mesh,
7499  struct hecmwST_local_mesh *local_mesh) {
7500  local_mesh->section->n_sect = global_mesh->section->n_sect;
7501 
7502  return RTC_NORMAL;
7503 }
7504 
7505 static int const_sect_type(const struct hecmwST_local_mesh *global_mesh,
7506  struct hecmwST_local_mesh *local_mesh) {
7507  local_mesh->section->sect_type = global_mesh->section->sect_type;
7508 
7509  return RTC_NORMAL;
7510 }
7511 
7512 static int const_sect_opt(const struct hecmwST_local_mesh *global_mesh,
7513  struct hecmwST_local_mesh *local_mesh) {
7514  local_mesh->section->sect_opt = global_mesh->section->sect_opt;
7515 
7516  return RTC_NORMAL;
7517 }
7518 
7519 static int const_sect_mat_id_index(const struct hecmwST_local_mesh *global_mesh,
7520  struct hecmwST_local_mesh *local_mesh) {
7521  local_mesh->section->sect_mat_ID_index =
7522  global_mesh->section->sect_mat_ID_index;
7523 
7524  return RTC_NORMAL;
7525 }
7526 
7527 static int const_sect_mat_id_item(const struct hecmwST_local_mesh *global_mesh,
7528  struct hecmwST_local_mesh *local_mesh) {
7529  local_mesh->section->sect_mat_ID_item =
7530  global_mesh->section->sect_mat_ID_item;
7531 
7532  return RTC_NORMAL;
7533 }
7534 
7535 static int const_sect_i_index(const struct hecmwST_local_mesh *global_mesh,
7536  struct hecmwST_local_mesh *local_mesh) {
7537  local_mesh->section->sect_I_index = global_mesh->section->sect_I_index;
7538 
7539  return RTC_NORMAL;
7540 }
7541 
7542 static int const_sect_i_item(const struct hecmwST_local_mesh *global_mesh,
7543  struct hecmwST_local_mesh *local_mesh) {
7544  local_mesh->section->sect_I_item = global_mesh->section->sect_I_item;
7545 
7546  return RTC_NORMAL;
7547 }
7548 
7549 static int const_sect_r_index(const struct hecmwST_local_mesh *global_mesh,
7550  struct hecmwST_local_mesh *local_mesh) {
7551  local_mesh->section->sect_R_index = global_mesh->section->sect_R_index;
7552 
7553  return RTC_NORMAL;
7554 }
7555 
7556 static int const_sect_r_item(const struct hecmwST_local_mesh *global_mesh,
7557  struct hecmwST_local_mesh *local_mesh) {
7558  local_mesh->section->sect_R_item = global_mesh->section->sect_R_item;
7559 
7560  return RTC_NORMAL;
7561 }
7562 
7563 static int const_sect_info(const struct hecmwST_local_mesh *global_mesh,
7564  struct hecmwST_local_mesh *local_mesh) {
7565  int rtc;
7566 
7567  HECMW_assert(global_mesh);
7568  HECMW_assert(local_mesh);
7569  HECMW_assert(global_mesh->section);
7570  HECMW_assert(local_mesh->section);
7571 
7572  rtc = const_n_sect(global_mesh, local_mesh);
7573  if (rtc != RTC_NORMAL) goto error;
7574 
7575  rtc = const_sect_type(global_mesh, local_mesh);
7576  if (rtc != RTC_NORMAL) goto error;
7577 
7578  rtc = const_sect_opt(global_mesh, local_mesh);
7579  if (rtc != RTC_NORMAL) goto error;
7580 
7581  rtc = const_sect_mat_id_index(global_mesh, local_mesh);
7582  if (rtc != RTC_NORMAL) goto error;
7583 
7584  rtc = const_sect_mat_id_item(global_mesh, local_mesh);
7585  if (rtc != RTC_NORMAL) goto error;
7586 
7587  rtc = const_sect_i_index(global_mesh, local_mesh);
7588  if (rtc != RTC_NORMAL) goto error;
7589 
7590  rtc = const_sect_i_item(global_mesh, local_mesh);
7591  if (rtc != RTC_NORMAL) goto error;
7592 
7593  rtc = const_sect_r_index(global_mesh, local_mesh);
7594  if (rtc != RTC_NORMAL) goto error;
7595 
7596  rtc = const_sect_r_item(global_mesh, local_mesh);
7597  if (rtc != RTC_NORMAL) goto error;
7598 
7599  return RTC_NORMAL;
7600 
7601 error:
7602  return RTC_ERROR;
7603 }
7604 
7605 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7606  * - - - - - - - - - */
7607 
7608 static int const_n_mat(const struct hecmwST_local_mesh *global_mesh,
7609  struct hecmwST_local_mesh *local_mesh) {
7610  local_mesh->material->n_mat = global_mesh->material->n_mat;
7611 
7612  return RTC_NORMAL;
7613 }
7614 
7615 static int const_n_mat_item(const struct hecmwST_local_mesh *global_mesh,
7616  struct hecmwST_local_mesh *local_mesh) {
7617  local_mesh->material->n_mat_item = global_mesh->material->n_mat_item;
7618 
7619  return RTC_NORMAL;
7620 }
7621 
7622 static int const_n_mat_subitem(const struct hecmwST_local_mesh *global_mesh,
7623  struct hecmwST_local_mesh *local_mesh) {
7624  local_mesh->material->n_mat_subitem = global_mesh->material->n_mat_subitem;
7625 
7626  return RTC_NORMAL;
7627 }
7628 
7629 static int const_n_mat_table(const struct hecmwST_local_mesh *global_mesh,
7630  struct hecmwST_local_mesh *local_mesh) {
7631  local_mesh->material->n_mat_table = global_mesh->material->n_mat_table;
7632 
7633  return RTC_NORMAL;
7634 }
7635 
7636 static int const_mat_name(const struct hecmwST_local_mesh *global_mesh,
7637  struct hecmwST_local_mesh *local_mesh) {
7638  local_mesh->material->mat_name = global_mesh->material->mat_name;
7639 
7640  return RTC_NORMAL;
7641 }
7642 
7643 static int const_mat_item_index(const struct hecmwST_local_mesh *global_mesh,
7644  struct hecmwST_local_mesh *local_mesh) {
7645  local_mesh->material->mat_item_index = global_mesh->material->mat_item_index;
7646 
7647  return RTC_NORMAL;
7648 }
7649 
7650 static int const_mat_subitem_index(const struct hecmwST_local_mesh *global_mesh,
7651  struct hecmwST_local_mesh *local_mesh) {
7652  local_mesh->material->mat_subitem_index =
7653  global_mesh->material->mat_subitem_index;
7654 
7655  return RTC_NORMAL;
7656 }
7657 
7658 static int const_mat_table_index(const struct hecmwST_local_mesh *global_mesh,
7659  struct hecmwST_local_mesh *local_mesh) {
7660  local_mesh->material->mat_table_index =
7661  global_mesh->material->mat_table_index;
7662 
7663  return RTC_NORMAL;
7664 }
7665 
7666 static int const_mat_val(const struct hecmwST_local_mesh *global_mesh,
7667  struct hecmwST_local_mesh *local_mesh) {
7668  local_mesh->material->mat_val = global_mesh->material->mat_val;
7669 
7670  return RTC_NORMAL;
7671 }
7672 
7673 static int const_mat_temp(const struct hecmwST_local_mesh *global_mesh,
7674  struct hecmwST_local_mesh *local_mesh) {
7675  local_mesh->material->mat_temp = global_mesh->material->mat_temp;
7676 
7677  return RTC_NORMAL;
7678 }
7679 
7680 static int const_mat_info(const struct hecmwST_local_mesh *global_mesh,
7681  struct hecmwST_local_mesh *local_mesh) {
7682  int rtc;
7683 
7684  HECMW_assert(global_mesh);
7685  HECMW_assert(global_mesh->material);
7686  HECMW_assert(local_mesh);
7687  HECMW_assert(local_mesh->material);
7688 
7689  rtc = const_n_mat(global_mesh, local_mesh);
7690  if (rtc != RTC_NORMAL) goto error;
7691 
7692  rtc = const_n_mat_item(global_mesh, local_mesh);
7693  if (rtc != RTC_NORMAL) goto error;
7694 
7695  rtc = const_n_mat_subitem(global_mesh, local_mesh);
7696  if (rtc != RTC_NORMAL) goto error;
7697 
7698  rtc = const_n_mat_table(global_mesh, local_mesh);
7699  if (rtc != RTC_NORMAL) goto error;
7700 
7701  rtc = const_mat_name(global_mesh, local_mesh);
7702  if (rtc != RTC_NORMAL) goto error;
7703 
7704  rtc = const_mat_item_index(global_mesh, local_mesh);
7705  if (rtc != RTC_NORMAL) goto error;
7706 
7707  rtc = const_mat_subitem_index(global_mesh, local_mesh);
7708  if (rtc != RTC_NORMAL) goto error;
7709 
7710  rtc = const_mat_table_index(global_mesh, local_mesh);
7711  if (rtc != RTC_NORMAL) goto error;
7712 
7713  rtc = const_mat_val(global_mesh, local_mesh);
7714  if (rtc != RTC_NORMAL) goto error;
7715 
7716  rtc = const_mat_temp(global_mesh, local_mesh);
7717  if (rtc != RTC_NORMAL) goto error;
7718 
7719  return RTC_NORMAL;
7720 
7721 error:
7722  return RTC_ERROR;
7723 }
7724 
7725 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7726  * - - - - - - - - - */
7727 
7728 static int const_n_mpc(const struct hecmwST_local_mesh *global_mesh,
7729  struct hecmwST_local_mesh *local_mesh,
7730  const int *node_global2local, char *mpc_flag) {
7731  struct hecmwST_mpc *mpc_global = global_mesh->mpc;
7732  struct hecmwST_mpc *mpc_local = local_mesh->mpc;
7733  int node, diff, evalsum, counter;
7734  int i, j;
7735 
7736  for (counter = 0, i = 0; i < mpc_global->n_mpc; i++) {
7737  diff = mpc_global->mpc_index[i + 1] - mpc_global->mpc_index[i];
7738 
7739  evalsum = 0;
7740 
7741  for (j = mpc_global->mpc_index[i]; j < mpc_global->mpc_index[i + 1]; j++) {
7742  node = mpc_global->mpc_item[j];
7743  if (node_global2local[node - 1] > 0) evalsum++;
7744  }
7745 
7746  if (evalsum == diff) {
7747  MASK_BIT(mpc_flag[i], MASK);
7748  counter++;
7749  }
7750  }
7751  mpc_local->n_mpc = counter;
7752 
7753  return RTC_NORMAL;
7754 }
7755 
7756 static int const_mpc_index(const struct hecmwST_local_mesh *global_mesh,
7757  struct hecmwST_local_mesh *local_mesh,
7758  const char *mpc_flag) {
7759  struct hecmwST_mpc *mpc_global = global_mesh->mpc;
7760  struct hecmwST_mpc *mpc_local = local_mesh->mpc;
7761  int counter;
7762  int i;
7763 
7764  mpc_local->mpc_index = (int *)HECMW_calloc(mpc_local->n_mpc + 1, sizeof(int));
7765  if (local_mesh->mpc->mpc_index == NULL) {
7766  HECMW_set_error(errno, "");
7767  goto error;
7768  }
7769 
7770  for (counter = 0, i = 0; i < mpc_global->n_mpc; i++) {
7771  if (EVAL_BIT(mpc_flag[i], MASK)) {
7772  mpc_local->mpc_index[counter + 1] = mpc_local->mpc_index[counter] +
7773  mpc_global->mpc_index[i + 1] -
7774  mpc_global->mpc_index[i];
7775  counter++;
7776  }
7777  }
7778  HECMW_assert(counter == mpc_local->n_mpc);
7779 
7780  return RTC_NORMAL;
7781 
7782 error:
7783  return RTC_ERROR;
7784 }
7785 
7786 static int const_mpc_item(const struct hecmwST_local_mesh *global_mesh,
7787  struct hecmwST_local_mesh *local_mesh,
7788  const int *node_global2local, const char *mpc_flag) {
7789  struct hecmwST_mpc *mpc_global = global_mesh->mpc;
7790  struct hecmwST_mpc *mpc_local = local_mesh->mpc;
7791  int mcounter, icounter;
7792  int i, j;
7793 
7794  mpc_local->mpc_item =
7795  (int *)HECMW_malloc(sizeof(int) * mpc_local->mpc_index[mpc_local->n_mpc]);
7796  if (mpc_local->mpc_item == NULL) {
7797  HECMW_set_error(errno, "");
7798  goto error;
7799  }
7800 
7801  for (mcounter = 0, icounter = 0, i = 0; i < mpc_global->n_mpc; i++) {
7802  if (EVAL_BIT(mpc_flag[i], MASK)) {
7803  for (j = mpc_global->mpc_index[i]; j < mpc_global->mpc_index[i + 1];
7804  j++) {
7805  mpc_local->mpc_item[mcounter++] =
7806  node_global2local[mpc_global->mpc_item[j] - 1];
7807  }
7808  HECMW_assert(mcounter == mpc_local->mpc_index[++icounter]);
7809  }
7810  }
7811  HECMW_assert(icounter == mpc_local->n_mpc);
7812  HECMW_assert(mcounter == mpc_local->mpc_index[mpc_local->n_mpc]);
7813 
7814  return RTC_NORMAL;
7815 
7816 error:
7817  return RTC_ERROR;
7818 }
7819 
7820 static int const_mpc_dof(const struct hecmwST_local_mesh *global_mesh,
7821  struct hecmwST_local_mesh *local_mesh,
7822  const char *mpc_flag) {
7823  struct hecmwST_mpc *mpc_global = global_mesh->mpc;
7824  struct hecmwST_mpc *mpc_local = local_mesh->mpc;
7825  int mcounter, icounter;
7826  int i, j;
7827 
7828  mpc_local->mpc_dof =
7829  (int *)HECMW_malloc(sizeof(int) * mpc_local->mpc_index[mpc_local->n_mpc]);
7830  if (local_mesh->mpc->mpc_dof == NULL) {
7831  HECMW_set_error(errno, "");
7832  goto error;
7833  }
7834 
7835  for (mcounter = 0, icounter = 0, i = 0; i < mpc_global->n_mpc; i++) {
7836  if (EVAL_BIT(mpc_flag[i], MASK)) {
7837  for (j = mpc_global->mpc_index[i]; j < mpc_global->mpc_index[i + 1];
7838  j++) {
7839  mpc_local->mpc_dof[mcounter++] = mpc_global->mpc_dof[j];
7840  }
7841  HECMW_assert(mcounter == mpc_local->mpc_index[++icounter]);
7842  }
7843  }
7844  HECMW_assert(icounter == mpc_local->n_mpc);
7845  HECMW_assert(mcounter == mpc_local->mpc_index[mpc_local->n_mpc]);
7846 
7847  return RTC_NORMAL;
7848 
7849 error:
7850  return RTC_ERROR;
7851 }
7852 
7853 static int const_mpc_val(const struct hecmwST_local_mesh *global_mesh,
7854  struct hecmwST_local_mesh *local_mesh,
7855  const char *mpc_flag) {
7856  struct hecmwST_mpc *mpc_global = global_mesh->mpc;
7857  struct hecmwST_mpc *mpc_local = local_mesh->mpc;
7858  int size;
7859  int mcounter, icounter;
7860  int i, j;
7861 
7862  size = sizeof(double) * mpc_local->mpc_index[mpc_local->n_mpc];
7863  mpc_local->mpc_val = (double *)HECMW_malloc(size);
7864  if (local_mesh->mpc->mpc_val == NULL) {
7865  HECMW_set_error(errno, "");
7866  goto error;
7867  }
7868 
7869  for (mcounter = 0, icounter = 0, i = 0; i < mpc_global->n_mpc; i++) {
7870  if (EVAL_BIT(mpc_flag[i], MASK)) {
7871  for (j = mpc_global->mpc_index[i]; j < mpc_global->mpc_index[i + 1];
7872  j++) {
7873  mpc_local->mpc_val[mcounter++] = mpc_global->mpc_val[j];
7874  }
7875  HECMW_assert(mcounter == mpc_local->mpc_index[++icounter]);
7876  }
7877  }
7878  HECMW_assert(icounter == local_mesh->mpc->n_mpc);
7879  HECMW_assert(mcounter == local_mesh->mpc->mpc_index[local_mesh->mpc->n_mpc]);
7880 
7881  return RTC_NORMAL;
7882 
7883 error:
7884  return RTC_ERROR;
7885 }
7886 
7887 static int const_mpc_const(const struct hecmwST_local_mesh *global_mesh,
7888  struct hecmwST_local_mesh *local_mesh,
7889  const char *mpc_flag) {
7890  struct hecmwST_mpc *mpc_global = global_mesh->mpc;
7891  struct hecmwST_mpc *mpc_local = local_mesh->mpc;
7892  int size;
7893  int icounter;
7894  int i;
7895 
7896  size = sizeof(double) * mpc_local->n_mpc;
7897  mpc_local->mpc_const = (double *)HECMW_malloc(size);
7898  if (local_mesh->mpc->mpc_const == NULL) {
7899  HECMW_set_error(errno, "");
7900  goto error;
7901  }
7902 
7903  for (icounter = 0, i = 0; i < mpc_global->n_mpc; i++) {
7904  if (EVAL_BIT(mpc_flag[i], MASK)) {
7905  mpc_local->mpc_const[icounter] = mpc_global->mpc_const[i];
7906  icounter++;
7907  }
7908  }
7909  HECMW_assert(icounter == local_mesh->mpc->n_mpc);
7910 
7911  return RTC_NORMAL;
7912 
7913 error:
7914  return RTC_ERROR;
7915 }
7916 
7917 static int const_mpc_info(const struct hecmwST_local_mesh *global_mesh,
7918  struct hecmwST_local_mesh *local_mesh,
7919  const int *node_global2local) {
7920  char *mpc_flag = NULL;
7921  int rtc;
7922 
7923  HECMW_assert(global_mesh);
7924  HECMW_assert(global_mesh->mpc);
7925  HECMW_assert(local_mesh);
7926  HECMW_assert(local_mesh->mpc);
7927  HECMW_assert(node_global2local);
7928 
7929  if (global_mesh->mpc->n_mpc == 0) {
7930  init_struct_mpc(local_mesh);
7931  return RTC_NORMAL;
7932  }
7933 
7934  mpc_flag = (char *)HECMW_calloc(global_mesh->mpc->n_mpc, sizeof(char));
7935  if (mpc_flag == NULL) {
7936  HECMW_set_error(errno, "");
7937  goto error;
7938  }
7939 
7940  rtc = const_n_mpc(global_mesh, local_mesh, node_global2local, mpc_flag);
7941  if (rtc != RTC_NORMAL) goto error;
7942 
7943  if (local_mesh->mpc->n_mpc == 0) {
7944  init_struct_mpc(local_mesh);
7945  HECMW_free(mpc_flag);
7946  return RTC_NORMAL;
7947  }
7948 
7949  rtc = const_mpc_index(global_mesh, local_mesh, mpc_flag);
7950  if (rtc != RTC_NORMAL) goto error;
7951 
7952  rtc = const_mpc_item(global_mesh, local_mesh, node_global2local, mpc_flag);
7953  if (rtc != RTC_NORMAL) goto error;
7954 
7955  rtc = const_mpc_dof(global_mesh, local_mesh, mpc_flag);
7956  if (rtc != RTC_NORMAL) goto error;
7957 
7958  rtc = const_mpc_val(global_mesh, local_mesh, mpc_flag);
7959  if (rtc != RTC_NORMAL) goto error;
7960 
7961  rtc = const_mpc_const(global_mesh, local_mesh, mpc_flag);
7962  if (rtc != RTC_NORMAL) goto error;
7963 
7964  HECMW_free(mpc_flag);
7965 
7966  return RTC_NORMAL;
7967 
7968 error:
7969  HECMW_free(mpc_flag);
7970 
7971  return RTC_ERROR;
7972 }
7973 
7974 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7975  * - - - - - - - - - */
7976 
7977 static int const_n_amp(const struct hecmwST_local_mesh *global_mesh,
7978  struct hecmwST_local_mesh *local_mesh) {
7979  local_mesh->amp->n_amp = global_mesh->amp->n_amp;
7980 
7981  return RTC_NORMAL;
7982 }
7983 
7984 static int const_amp_name(const struct hecmwST_local_mesh *global_mesh,
7985  struct hecmwST_local_mesh *local_mesh) {
7986  local_mesh->amp->amp_name = global_mesh->amp->amp_name;
7987 
7988  return RTC_NORMAL;
7989 }
7990 
7991 static int const_amp_type_definition(
7992  const struct hecmwST_local_mesh *global_mesh,
7993  struct hecmwST_local_mesh *local_mesh) {
7994  local_mesh->amp->amp_type_definition = global_mesh->amp->amp_type_definition;
7995 
7996  return RTC_NORMAL;
7997 }
7998 
7999 static int const_amp_type_time(const struct hecmwST_local_mesh *global_mesh,
8000  struct hecmwST_local_mesh *local_mesh) {
8001  local_mesh->amp->amp_type_time = global_mesh->amp->amp_type_time;
8002 
8003  return RTC_NORMAL;
8004 }
8005 
8006 static int const_amp_type_value(const struct hecmwST_local_mesh *global_mesh,
8007  struct hecmwST_local_mesh *local_mesh) {
8008  local_mesh->amp->amp_type_value = global_mesh->amp->amp_type_value;
8009 
8010  return RTC_NORMAL;
8011 }
8012 
8013 static int const_amp_index(const struct hecmwST_local_mesh *global_mesh,
8014  struct hecmwST_local_mesh *local_mesh) {
8015  local_mesh->amp->amp_index = global_mesh->amp->amp_index;
8016 
8017  return RTC_NORMAL;
8018 }
8019 
8020 static int const_amp_val(const struct hecmwST_local_mesh *global_mesh,
8021  struct hecmwST_local_mesh *local_mesh) {
8022  local_mesh->amp->amp_val = global_mesh->amp->amp_val;
8023 
8024  return RTC_NORMAL;
8025 }
8026 
8027 static int const_amp_table(const struct hecmwST_local_mesh *global_mesh,
8028  struct hecmwST_local_mesh *local_mesh) {
8029  local_mesh->amp->amp_table = global_mesh->amp->amp_table;
8030 
8031  return RTC_NORMAL;
8032 }
8033 
8034 static int const_amp_info(const struct hecmwST_local_mesh *global_mesh,
8035  struct hecmwST_local_mesh *local_mesh) {
8036  int rtc;
8037 
8038  HECMW_assert(global_mesh);
8039  HECMW_assert(global_mesh->amp);
8040  HECMW_assert(local_mesh);
8041  HECMW_assert(local_mesh->amp);
8042 
8043  if (global_mesh->amp->n_amp == 0) {
8044  init_struct_amp(local_mesh);
8045  return RTC_NORMAL;
8046  }
8047 
8048  rtc = const_n_amp(global_mesh, local_mesh);
8049  if (rtc != RTC_NORMAL) goto error;
8050 
8051  rtc = const_amp_name(global_mesh, local_mesh);
8052  if (rtc != RTC_NORMAL) goto error;
8053 
8054  rtc = const_amp_type_definition(global_mesh, local_mesh);
8055  if (rtc != RTC_NORMAL) goto error;
8056 
8057  rtc = const_amp_type_time(global_mesh, local_mesh);
8058  if (rtc != RTC_NORMAL) goto error;
8059 
8060  rtc = const_amp_type_value(global_mesh, local_mesh);
8061  if (rtc != RTC_NORMAL) goto error;
8062 
8063  rtc = const_amp_index(global_mesh, local_mesh);
8064  if (rtc != RTC_NORMAL) goto error;
8065 
8066  rtc = const_amp_val(global_mesh, local_mesh);
8067  if (rtc != RTC_NORMAL) goto error;
8068 
8069  rtc = const_amp_table(global_mesh, local_mesh);
8070  if (rtc != RTC_NORMAL) goto error;
8071 
8072  return RTC_NORMAL;
8073 
8074 error:
8075  return RTC_ERROR;
8076 }
8077 
8078 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8079  * - - - - - - - - - */
8080 
8081 static int *const_node_grp_mask_eqn(
8082  const struct hecmwST_local_mesh *global_mesh,
8083  struct hecmwST_local_mesh *local_mesh, const int *node_global2local,
8084  int eqn_block_idx) {
8085  struct hecmwST_node_grp *node_group_global = global_mesh->node_group;
8086  int *n_eqn_item = NULL;
8087  int diff, evalsum;
8088  int i, j, is, ie, js;
8089 
8090  is = node_group_global->grp_index[eqn_block_idx];
8091  ie = node_group_global->grp_index[eqn_block_idx + 1];
8092 
8093  n_eqn_item = (int *)HECMW_malloc(sizeof(int) * (ie - is));
8094  if (n_eqn_item == NULL) {
8095  HECMW_set_error(errno, "");
8096  goto error;
8097  }
8098 
8099  for (js = 0, i = 0; i < ie - is; i++) {
8100  diff = node_group_global->grp_item[is + i] - js;
8101  for (evalsum = 0, j = js; j < node_group_global->grp_item[is + i]; j++) {
8102  if (node_global2local[j] > 0 &&
8103  node_global2local[j] <= local_mesh->nn_internal)
8104  evalsum++;
8105  }
8106 
8107  if (evalsum) {
8108  HECMW_assert(evalsum == diff);
8109  n_eqn_item[i] = diff;
8110  } else {
8111  n_eqn_item[i] = 0;
8112  }
8113 
8114  js = node_group_global->grp_item[is + i];
8115  }
8116 
8117  return n_eqn_item;
8118 
8119 error:
8120  return NULL;
8121 }
8122 
8123 static int const_node_n_grp(const struct hecmwST_local_mesh *global_mesh,
8124  struct hecmwST_local_mesh *local_mesh) {
8125  local_mesh->node_group->n_grp = global_mesh->node_group->n_grp;
8126 
8127  return RTC_NORMAL;
8128 }
8129 
8130 static int const_node_grp_name(const struct hecmwST_local_mesh *global_mesh,
8131  struct hecmwST_local_mesh *local_mesh) {
8132  local_mesh->node_group->grp_name = global_mesh->node_group->grp_name;
8133 
8134  return RTC_NORMAL;
8135 }
8136 
8137 static int const_node_grp_index(const struct hecmwST_local_mesh *global_mesh,
8138  struct hecmwST_local_mesh *local_mesh,
8139  const int *node_global2local,
8140  const int *n_eqn_item, int eqn_block_idx) {
8141  struct hecmwST_node_grp *node_group_global = global_mesh->node_group;
8142  struct hecmwST_node_grp *node_group_local = local_mesh->node_group;
8143  int node;
8144  int counter, diff;
8145  int i, j;
8146 
8147  node_group_local->grp_index =
8148  (int *)HECMW_calloc(node_group_local->n_grp + 1, sizeof(int));
8149  if (node_group_local->grp_index == NULL) {
8150  HECMW_set_error(errno, "");
8151  goto error;
8152  }
8153 
8154  for (counter = 0, i = 0; i < node_group_global->n_grp; i++) {
8155  if (i != eqn_block_idx) {
8156  for (j = node_group_global->grp_index[i];
8157  j < node_group_global->grp_index[i + 1]; j++) {
8158  node = node_group_global->grp_item[j];
8159  if (node_global2local[node - 1]) counter++;
8160  }
8161 
8162  } else {
8163  diff =
8164  node_group_global->grp_index[i + 1] - node_group_global->grp_index[i];
8165  for (j = 0; j < diff; j++) {
8166  if (n_eqn_item[j] > 0) counter++;
8167  }
8168  }
8169 
8170  node_group_local->grp_index[i + 1] = counter;
8171  }
8172 
8173  return RTC_NORMAL;
8174 
8175 error:
8176  return RTC_ERROR;
8177 }
8178 
8179 static int const_node_grp_index_mod(
8180  const struct hecmwST_local_mesh *global_mesh,
8181  struct hecmwST_local_mesh *local_mesh, const int *node_global2local,
8182  const int *n_eqn_item, int eqn_block_idx, int domain) {
8183  struct hecmwST_node_grp *node_group_global = global_mesh->node_group;
8184  struct hecmwST_node_grp *node_group_local = local_mesh->node_group;
8185  int node;
8186  int counter, diff;
8187  int i, j;
8188 
8189  node_group_local->grp_index =
8190  (int *)HECMW_calloc(node_group_local->n_grp + 1, sizeof(int));
8191  if (node_group_local->grp_index == NULL) {
8192  HECMW_set_error(errno, "");
8193  goto error;
8194  }
8195 
8196  for (counter = 0, i = 0; i < node_group_global->n_grp; i++) {
8197  if (i != eqn_block_idx) {
8198  if (node_group_global->grp_index[i + 1] -
8199  node_group_global->grp_index[i] ==
8200  global_mesh->n_node) {
8201  counter += n_int_nlist[domain];
8202  counter += n_bnd_nlist[2 * domain + 1] - n_bnd_nlist[2 * domain];
8203  } else {
8204  counter += ngrp_idx[domain][i + 1] - ngrp_idx[domain][i];
8205  /*
8206  for( j=node_group_global->grp_index[i];
8207  j<node_group_global->grp_index[i+1]; j++ ) {
8208  node = node_group_global->grp_item[j];
8209  if( node_global2local[node-1] ) counter++;
8210  }
8211  */
8212  }
8213 
8214  } else {
8215  diff =
8216  node_group_global->grp_index[i + 1] - node_group_global->grp_index[i];
8217  for (j = 0; j < diff; j++) {
8218  if (n_eqn_item[j] > 0) counter++;
8219  }
8220  }
8221 
8222  node_group_local->grp_index[i + 1] = counter;
8223  }
8224 
8225  return RTC_NORMAL;
8226 
8227 error:
8228  return RTC_ERROR;
8229 }
8230 
8231 static int const_node_grp_item(const struct hecmwST_local_mesh *global_mesh,
8232  struct hecmwST_local_mesh *local_mesh,
8233  const int *node_global2local,
8234  const int *n_eqn_item, int eqn_block_idx) {
8235  struct hecmwST_node_grp *node_group_global = global_mesh->node_group;
8236  struct hecmwST_node_grp *node_group_local = local_mesh->node_group;
8237  int node;
8238  int size;
8239  int counter;
8240  int i, j, k, js, je, ks, ls;
8241 
8242  size = sizeof(int) * node_group_local->grp_index[node_group_local->n_grp];
8243  node_group_local->grp_item = (int *)HECMW_malloc(size);
8244  if (node_group_local->grp_item == NULL) {
8245  HECMW_set_error(errno, "");
8246  goto error;
8247  }
8248 
8249  for (counter = 0, i = 0; i < node_group_global->n_grp; i++) {
8250  if (i != eqn_block_idx) {
8251  for (j = node_group_global->grp_index[i];
8252  j < node_group_global->grp_index[i + 1]; j++) {
8253  node = node_group_global->grp_item[j];
8254  if (node_global2local[node - 1]) {
8255  node_group_local->grp_item[counter++] = node_global2local[node - 1];
8256  }
8257  }
8258 
8259  } else {
8260  js = node_group_global->grp_index[i];
8261  je = node_group_global->grp_index[i + 1];
8262  for (ks = 0, ls = 0, j = js; j < je; j++) {
8263  if (n_eqn_item[j - js]) {
8264  HECMW_assert(n_eqn_item[j - js] ==
8265  node_group_global->grp_item[j] - ks);
8266  node_group_local->grp_item[counter] = ls + n_eqn_item[j - js];
8267 
8268  for (k = ks; k < node_group_global->grp_item[j]; k++) {
8269  HECMW_assert(ls < node_global2local[k] &&
8270  node_global2local[k] <=
8271  node_group_local->grp_item[counter]);
8272  }
8273  ls = node_group_local->grp_item[counter];
8274  counter++;
8275  }
8276  ks = node_group_global->grp_item[j];
8277  }
8278  }
8279  HECMW_assert(counter == node_group_local->grp_index[i + 1]);
8280  }
8281 
8282  return RTC_NORMAL;
8283 
8284 error:
8285  return RTC_ERROR;
8286 }
8287 
8288 static int const_node_grp_item_mod(const struct hecmwST_local_mesh *global_mesh,
8289  struct hecmwST_local_mesh *local_mesh,
8290  const int *node_global2local,
8291  const int *n_eqn_item, int eqn_block_idx,
8292  int domain) {
8293  struct hecmwST_node_grp *node_group_global = global_mesh->node_group;
8294  struct hecmwST_node_grp *node_group_local = local_mesh->node_group;
8295  int node;
8296  int size;
8297  int counter;
8298  int i, j, k, js, je, ks, ls;
8299  int idx1, idx2, node1, node2, n_int, n_bnd, n_out, maxn;
8300 
8301  size = sizeof(int) * node_group_local->grp_index[node_group_local->n_grp];
8302  node_group_local->grp_item = (int *)HECMW_malloc(size);
8303  if (node_group_local->grp_item == NULL) {
8304  HECMW_set_error(errno, "");
8305  goto error;
8306  }
8307 
8308  n_int = n_int_nlist[domain];
8309  n_bnd = n_bnd_nlist[2 * domain];
8310  n_out = n_bnd_nlist[2 * domain + 1] - n_bnd_nlist[2 * domain];
8311  maxn = global_mesh->n_node + 1;
8312 
8313  for (counter = 0, i = 0; i < node_group_global->n_grp; i++) {
8314  if (i != eqn_block_idx) {
8315  if (node_group_global->grp_index[i + 1] -
8316  node_group_global->grp_index[i] ==
8317  global_mesh->n_node) {
8318  idx1 = 0;
8319  idx2 = 0;
8320  node1 = (n_int == 0) ? maxn : int_nlist[domain][0];
8321  node2 = (n_out == 0) ? maxn : bnd_nlist[domain][n_bnd];
8322  for (j = 0; j < n_int + n_out; j++) {
8323  if (node1 < node2) {
8324  node_group_local->grp_item[counter++] =
8325  node_global2local[node1 - 1];
8326  idx1++;
8327  node1 = (idx1 == n_int) ? maxn : int_nlist[domain][idx1];
8328  } else {
8329  node_group_local->grp_item[counter++] =
8330  node_global2local[node2 - 1];
8331  idx2++;
8332  node2 = (idx2 == n_out) ? maxn : bnd_nlist[domain][idx2 + n_bnd];
8333  }
8334  }
8335  } else {
8336  if (ngrp_idx[domain][i + 1] - ngrp_idx[domain][i] == 0) continue;
8337  for (j = ngrp_idx[domain][i]; j < ngrp_idx[domain][i + 1]; j++) {
8338  node = ngrp_item[domain][j];
8339  node_group_local->grp_item[counter++] = node_global2local[node - 1];
8340  }
8341  }
8342  } else {
8343  js = node_group_global->grp_index[i];
8344  je = node_group_global->grp_index[i + 1];
8345  for (ks = 0, ls = 0, j = js; j < je; j++) {
8346  if (n_eqn_item[j - js]) {
8347  HECMW_assert(n_eqn_item[j - js] ==
8348  node_group_global->grp_item[j] - ks);
8349  node_group_local->grp_item[counter] = ls + n_eqn_item[j - js];
8350 
8351  for (k = ks; k < node_group_global->grp_item[j]; k++) {
8352  HECMW_assert(ls < node_global2local[k] &&
8353  node_global2local[k] <=
8354  node_group_local->grp_item[counter]);
8355  }
8356  ls = node_group_local->grp_item[counter];
8357  counter++;
8358  }
8359  ks = node_group_global->grp_item[j];
8360  }
8361  }
8362  HECMW_assert(counter == node_group_local->grp_index[i + 1]);
8363  }
8364 
8365  return RTC_NORMAL;
8366 
8367 error:
8368  return RTC_ERROR;
8369 }
8370 
8371 static int const_node_grp_info(const struct hecmwST_local_mesh *global_mesh,
8372  struct hecmwST_local_mesh *local_mesh,
8373  const int *node_global2local,
8374  int current_domain) {
8375  int *n_eqn_item = NULL;
8376  int eqn_block_idx;
8377  int rtc;
8378 
8379  HECMW_assert(global_mesh);
8380  HECMW_assert(global_mesh->node_group);
8381  HECMW_assert(local_mesh);
8382  HECMW_assert(local_mesh->node_group);
8383  HECMW_assert(node_global2local);
8384 
8385  if (global_mesh->node_group->n_grp == 0) {
8386  init_struct_node_grp(local_mesh);
8387  return RTC_NORMAL;
8388  }
8389 
8390  eqn_block_idx = search_eqn_block_idx(global_mesh);
8391 
8392  if (eqn_block_idx >= 0) {
8393  n_eqn_item = const_node_grp_mask_eqn(global_mesh, local_mesh,
8394  node_global2local, eqn_block_idx);
8395  if (n_eqn_item == NULL) goto error;
8396  }
8397 
8398  rtc = const_node_n_grp(global_mesh, local_mesh);
8399  if (rtc != RTC_NORMAL) goto error;
8400 
8401  rtc = const_node_grp_name(global_mesh, local_mesh);
8402  if (rtc != RTC_NORMAL) goto error;
8403 
8404  if (is_spdup_available(global_mesh)) {
8405  rtc = const_node_grp_index_mod(global_mesh, local_mesh, node_global2local,
8406  n_eqn_item, eqn_block_idx, current_domain);
8407  if (rtc != RTC_NORMAL) goto error;
8408  rtc = const_node_grp_item_mod(global_mesh, local_mesh, node_global2local,
8409  n_eqn_item, eqn_block_idx, current_domain);
8410  if (rtc != RTC_NORMAL) goto error;
8411 
8412  } else {
8413  rtc = const_node_grp_index(global_mesh, local_mesh, node_global2local,
8414  n_eqn_item, eqn_block_idx);
8415  if (rtc != RTC_NORMAL) goto error;
8416  rtc = const_node_grp_item(global_mesh, local_mesh, node_global2local,
8417  n_eqn_item, eqn_block_idx);
8418  if (rtc != RTC_NORMAL) goto error;
8419  }
8420 
8421  HECMW_free(n_eqn_item);
8422 
8423  return RTC_NORMAL;
8424 
8425 error:
8426  HECMW_free(n_eqn_item);
8427 
8428  return RTC_ERROR;
8429 }
8430 
8431 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8432  * - - - - - - - - - */
8433 
8434 static int const_elem_n_grp(const struct hecmwST_local_mesh *global_mesh,
8435  struct hecmwST_local_mesh *local_mesh) {
8436  local_mesh->elem_group->n_grp = global_mesh->elem_group->n_grp;
8437 
8438  return RTC_NORMAL;
8439 }
8440 
8441 static int const_elem_grp_name(const struct hecmwST_local_mesh *global_mesh,
8442  struct hecmwST_local_mesh *local_mesh) {
8443  local_mesh->elem_group->grp_name = global_mesh->elem_group->grp_name;
8444 
8445  return RTC_NORMAL;
8446 }
8447 
8448 static int const_elem_grp_index(const struct hecmwST_local_mesh *global_mesh,
8449  struct hecmwST_local_mesh *local_mesh,
8450  const int *elem_global2local) {
8451  struct hecmwST_elem_grp *elem_group_global = global_mesh->elem_group;
8452  struct hecmwST_elem_grp *elem_group_local = local_mesh->elem_group;
8453  int elem;
8454  int counter;
8455  int i, j;
8456 
8457  elem_group_local->grp_index =
8458  (int *)HECMW_calloc(elem_group_local->n_grp + 1, sizeof(int));
8459  if (elem_group_local->grp_index == NULL) {
8460  HECMW_set_error(errno, "");
8461  goto error;
8462  }
8463 
8464  for (counter = 0, i = 0; i < elem_group_global->n_grp; i++) {
8465  for (j = elem_group_global->grp_index[i];
8466  j < elem_group_global->grp_index[i + 1]; j++) {
8467  elem = elem_group_global->grp_item[j];
8468  if (elem_global2local[elem - 1]) counter++;
8469  }
8470  elem_group_local->grp_index[i + 1] = counter;
8471  }
8472 
8473  return RTC_NORMAL;
8474 
8475 error:
8476  return RTC_ERROR;
8477 }
8478 
8479 static int const_elem_grp_index_mod(
8480  const struct hecmwST_local_mesh *global_mesh,
8481  struct hecmwST_local_mesh *local_mesh, const int *elem_global2local,
8482  int domain) {
8483  struct hecmwST_elem_grp *elem_group_global = global_mesh->elem_group;
8484  struct hecmwST_elem_grp *elem_group_local = local_mesh->elem_group;
8485  int elem;
8486  int counter;
8487  int i, j, idx1, idx2, elem1, elem2;
8488 
8489  elem_group_local->grp_index =
8490  (int *)HECMW_calloc(elem_group_local->n_grp + 1, sizeof(int));
8491  if (elem_group_local->grp_index == NULL) {
8492  HECMW_set_error(errno, "");
8493  goto error;
8494  }
8495 
8496  for (counter = 0, i = 0; i < elem_group_global->n_grp; i++) {
8497  if (elem_group_global->grp_index[i + 1] - elem_group_global->grp_index[i] ==
8498  global_mesh->n_elem) {
8499  counter += n_int_elist[domain];
8500  counter += n_bnd_elist[2 * domain + 1] - n_bnd_elist[2 * domain];
8501  } else {
8502  counter += egrp_idx[domain][i + 1] - egrp_idx[domain][i];
8503  }
8504  elem_group_local->grp_index[i + 1] = counter;
8505  }
8506 
8507  return RTC_NORMAL;
8508 
8509 error:
8510  return RTC_ERROR;
8511 }
8512 
8513 static int const_elem_grp_item(const struct hecmwST_local_mesh *global_mesh,
8514  struct hecmwST_local_mesh *local_mesh,
8515  const int *elem_global2local) {
8516  struct hecmwST_elem_grp *elem_group_global = global_mesh->elem_group;
8517  struct hecmwST_elem_grp *elem_group_local = local_mesh->elem_group;
8518  int elem;
8519  int size;
8520  int counter;
8521  int i, j;
8522 
8523  size = sizeof(int) * elem_group_local->grp_index[elem_group_local->n_grp];
8524  elem_group_local->grp_item = (int *)HECMW_malloc(size);
8525  if (local_mesh->elem_group->grp_item == NULL) {
8526  HECMW_set_error(errno, "");
8527  goto error;
8528  }
8529 
8530  for (counter = 0, i = 0; i < elem_group_global->n_grp; i++) {
8531  for (j = elem_group_global->grp_index[i];
8532  j < elem_group_global->grp_index[i + 1]; j++) {
8533  elem = elem_group_global->grp_item[j];
8534  if (elem_global2local[elem - 1]) {
8535  elem_group_local->grp_item[counter++] = elem_global2local[elem - 1];
8536  }
8537  }
8538  HECMW_assert(counter == elem_group_local->grp_index[i + 1]);
8539  }
8540 
8541  return RTC_NORMAL;
8542 
8543 error:
8544  return RTC_ERROR;
8545 }
8546 
8547 static int const_elem_grp_item_mod(const struct hecmwST_local_mesh *global_mesh,
8548  struct hecmwST_local_mesh *local_mesh,
8549  const int *elem_global2local, int domain) {
8550  struct hecmwST_elem_grp *elem_group_global = global_mesh->elem_group;
8551  struct hecmwST_elem_grp *elem_group_local = local_mesh->elem_group;
8552  int elem;
8553  int size;
8554  int counter;
8555  int i, j, idx1, idx2, elem1, elem2, n_int, n_bnd, n_out, maxe;
8556 
8557  size = sizeof(int) * elem_group_local->grp_index[elem_group_local->n_grp];
8558  elem_group_local->grp_item = (int *)HECMW_malloc(size);
8559  if (local_mesh->elem_group->grp_item == NULL) {
8560  HECMW_set_error(errno, "");
8561  goto error;
8562  }
8563 
8564  n_int = n_int_elist[domain];
8565  n_bnd = n_bnd_elist[2 * domain];
8566  n_out = n_bnd_elist[2 * domain + 1] - n_bnd_elist[2 * domain];
8567  maxe = global_mesh->n_elem + 1;
8568 
8569  for (counter = 0, i = 0; i < elem_group_global->n_grp; i++) {
8570  if (elem_group_global->grp_index[i + 1] - elem_group_global->grp_index[i] ==
8571  global_mesh->n_elem) {
8572  elem1 = (n_int == 0) ? maxe : int_elist[domain][0];
8573  elem2 = (n_out == 0) ? maxe : bnd_elist[domain][n_bnd];
8574  for (idx1 = 0, idx2 = 0, j = 0; j < n_int + n_out; j++) {
8575  if (elem1 < elem2) {
8576  elem_group_local->grp_item[counter++] = elem_global2local[elem1 - 1];
8577  idx1++;
8578  elem1 = (idx1 == n_int) ? maxe : int_elist[domain][idx1];
8579  } else {
8580  elem_group_local->grp_item[counter++] = elem_global2local[elem2 - 1];
8581  idx2++;
8582  elem2 = (idx2 == n_out) ? maxe : bnd_elist[domain][idx2 + n_bnd];
8583  }
8584  }
8585  } else {
8586  if (egrp_idx[domain][i + 1] - egrp_idx[domain][i] == 0) continue;
8587  for (j = egrp_idx[domain][i]; j < egrp_idx[domain][i + 1]; j++) {
8588  elem = egrp_item[domain][j];
8589  elem_group_local->grp_item[counter++] = elem_global2local[elem - 1];
8590  }
8591  }
8592  HECMW_assert(counter == elem_group_local->grp_index[i + 1]);
8593  }
8594 
8595  return RTC_NORMAL;
8596 
8597 error:
8598  return RTC_ERROR;
8599 }
8600 
8601 static int const_elem_grp_info(const struct hecmwST_local_mesh *global_mesh,
8602  struct hecmwST_local_mesh *local_mesh,
8603  const int *elem_global2local,
8604  int current_domain) {
8605  int rtc;
8606 
8607  HECMW_assert(global_mesh);
8608  HECMW_assert(global_mesh->elem_group);
8609  HECMW_assert(local_mesh);
8610  HECMW_assert(local_mesh->elem_group);
8611  HECMW_assert(elem_global2local);
8612 
8613  if (global_mesh->elem_group->n_grp == 0) {
8614  init_struct_elem_grp(local_mesh);
8615  return RTC_NORMAL;
8616  }
8617 
8618  rtc = const_elem_n_grp(global_mesh, local_mesh);
8619  if (rtc != RTC_NORMAL) goto error;
8620 
8621  rtc = const_elem_grp_name(global_mesh, local_mesh);
8622  if (rtc != RTC_NORMAL) goto error;
8623 
8624  if (is_spdup_available(global_mesh)) {
8625  rtc = const_elem_grp_index_mod(global_mesh, local_mesh, elem_global2local,
8626  current_domain);
8627  if (rtc != RTC_NORMAL) goto error;
8628  rtc = const_elem_grp_item_mod(global_mesh, local_mesh, elem_global2local,
8629  current_domain);
8630  if (rtc != RTC_NORMAL) goto error;
8631 
8632  } else {
8633  rtc = const_elem_grp_index(global_mesh, local_mesh, elem_global2local);
8634  if (rtc != RTC_NORMAL) goto error;
8635  rtc = const_elem_grp_item(global_mesh, local_mesh, elem_global2local);
8636  if (rtc != RTC_NORMAL) goto error;
8637  }
8638 
8639  return RTC_NORMAL;
8640 
8641 error:
8642  return RTC_ERROR;
8643 }
8644 
8645 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8646  * - - - - - - - - - */
8647 
8648 static int const_surf_n_grp(const struct hecmwST_local_mesh *global_mesh,
8649  struct hecmwST_local_mesh *local_mesh) {
8650  local_mesh->surf_group->n_grp = global_mesh->surf_group->n_grp;
8651 
8652  return RTC_NORMAL;
8653 }
8654 
8655 static int const_surf_grp_name(const struct hecmwST_local_mesh *global_mesh,
8656  struct hecmwST_local_mesh *local_mesh) {
8657  local_mesh->surf_group->grp_name = global_mesh->surf_group->grp_name;
8658 
8659  return RTC_NORMAL;
8660 }
8661 
8662 static int const_surf_grp_index(const struct hecmwST_local_mesh *global_mesh,
8663  struct hecmwST_local_mesh *local_mesh,
8664  const int *elem_global2local) {
8665  struct hecmwST_surf_grp *surf_group_global = global_mesh->surf_group;
8666  struct hecmwST_surf_grp *surf_group_local = local_mesh->surf_group;
8667  int elem;
8668  int counter;
8669  int i, j;
8670 
8671  surf_group_local->grp_index =
8672  (int *)HECMW_calloc(surf_group_local->n_grp + 1, sizeof(int));
8673  if (surf_group_local->grp_index == NULL) {
8674  HECMW_set_error(errno, "");
8675  goto error;
8676  }
8677 
8678  for (counter = 0, i = 0; i < surf_group_global->n_grp; i++) {
8679  for (j = surf_group_global->grp_index[i];
8680  j < surf_group_global->grp_index[i + 1]; j++) {
8681  elem = surf_group_global->grp_item[2 * j];
8682  if (elem_global2local[elem - 1]) counter++;
8683  }
8684  surf_group_local->grp_index[i + 1] = counter;
8685  }
8686 
8687  return RTC_NORMAL;
8688 
8689 error:
8690  return RTC_ERROR;
8691 }
8692 
8693 static int const_surf_grp_item(const struct hecmwST_local_mesh *global_mesh,
8694  struct hecmwST_local_mesh *local_mesh,
8695  const int *elem_global2local) {
8696  struct hecmwST_surf_grp *surf_group_global = global_mesh->surf_group;
8697  struct hecmwST_surf_grp *surf_group_local = local_mesh->surf_group;
8698  int elem, surf;
8699  int size;
8700  int counter;
8701  int i, j;
8702 
8703  size = sizeof(int) * (size_t)surf_group_local->grp_index[surf_group_local->n_grp] * 2;
8704  surf_group_local->grp_item = (int *)HECMW_malloc(size);
8705  if (surf_group_local->grp_item == NULL) {
8706  HECMW_set_error(errno, "");
8707  goto error;
8708  }
8709 
8710  for (counter = 0, i = 0; i < surf_group_global->n_grp; i++) {
8711  for (j = surf_group_global->grp_index[i];
8712  j < surf_group_global->grp_index[i + 1]; j++) {
8713  elem = surf_group_global->grp_item[2 * j];
8714  surf = surf_group_global->grp_item[2 * j + 1];
8715  if (elem_global2local[elem - 1]) {
8716  surf_group_local->grp_item[2 * counter] = elem_global2local[elem - 1];
8717  surf_group_local->grp_item[2 * counter + 1] = surf;
8718  counter++;
8719  }
8720  }
8721  HECMW_assert(counter == surf_group_local->grp_index[i + 1]);
8722  }
8723 
8724  return RTC_NORMAL;
8725 
8726 error:
8727  return RTC_ERROR;
8728 }
8729 
8730 static int const_surf_grp_info(const struct hecmwST_local_mesh *global_mesh,
8731  struct hecmwST_local_mesh *local_mesh,
8732  const int *elem_global2local) {
8733  int rtc;
8734 
8735  HECMW_assert(global_mesh);
8736  HECMW_assert(global_mesh->surf_group);
8737  HECMW_assert(local_mesh);
8738  HECMW_assert(local_mesh->surf_group);
8739  HECMW_assert(elem_global2local);
8740 
8741  if (global_mesh->surf_group->n_grp == 0) {
8742  init_struct_surf_grp(local_mesh);
8743  return RTC_NORMAL;
8744  }
8745 
8746  rtc = const_surf_n_grp(global_mesh, local_mesh);
8747  if (rtc != RTC_NORMAL) goto error;
8748 
8749  rtc = const_surf_grp_name(global_mesh, local_mesh);
8750  if (rtc != RTC_NORMAL) goto error;
8751 
8752  rtc = const_surf_grp_index(global_mesh, local_mesh, elem_global2local);
8753  if (rtc != RTC_NORMAL) goto error;
8754 
8755  rtc = const_surf_grp_item(global_mesh, local_mesh, elem_global2local);
8756  if (rtc != RTC_NORMAL) goto error;
8757 
8758  return RTC_NORMAL;
8759 
8760 error:
8761  return RTC_ERROR;
8762 }
8763 
8764 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8765  * - - - - - - - - - */
8766 
8767 static int const_contact_pair_n_pair(
8768  const struct hecmwST_local_mesh *global_mesh,
8769  struct hecmwST_local_mesh *local_mesh) {
8770  local_mesh->contact_pair->n_pair = global_mesh->contact_pair->n_pair;
8771 
8772  return RTC_NORMAL;
8773 }
8774 
8775 static int const_contact_pair_name(const struct hecmwST_local_mesh *global_mesh,
8776  struct hecmwST_local_mesh *local_mesh) {
8777  local_mesh->contact_pair->name = global_mesh->contact_pair->name;
8778 
8779  return RTC_NORMAL;
8780 }
8781 
8782 static int const_contact_pair_type(const struct hecmwST_local_mesh *global_mesh,
8783  struct hecmwST_local_mesh *local_mesh) {
8784  struct hecmwST_contact_pair *cpair_global = global_mesh->contact_pair;
8785  struct hecmwST_contact_pair *cpair_local = local_mesh->contact_pair;
8786  int i;
8787 
8788  cpair_local->type = (int *)HECMW_calloc(cpair_local->n_pair, sizeof(int));
8789  if (cpair_local->type == NULL) {
8790  HECMW_set_error(errno, "");
8791  goto error;
8792  }
8793 
8794  for (i = 0; i < cpair_global->n_pair; i++) {
8795  cpair_local->type[i] = cpair_global->type[i];
8796  }
8797 
8798  return RTC_NORMAL;
8799 
8800 error:
8801  return RTC_ERROR;
8802 }
8803 
8804 static int const_contact_pair_slave_grp_id(
8805  const struct hecmwST_local_mesh *global_mesh,
8806  struct hecmwST_local_mesh *local_mesh) {
8807  struct hecmwST_contact_pair *cpair_global = global_mesh->contact_pair;
8808  struct hecmwST_contact_pair *cpair_local = local_mesh->contact_pair;
8809  int i;
8810 
8811  cpair_local->slave_grp_id =
8812  (int *)HECMW_calloc(cpair_local->n_pair, sizeof(int));
8813  if (cpair_local->slave_grp_id == NULL) {
8814  HECMW_set_error(errno, "");
8815  goto error;
8816  }
8817 
8818  for (i = 0; i < cpair_global->n_pair; i++) {
8819  cpair_local->slave_grp_id[i] = cpair_global->slave_grp_id[i];
8820  }
8821 
8822  return RTC_NORMAL;
8823 
8824 error:
8825  return RTC_ERROR;
8826 }
8827 
8828 static int const_contact_pair_slave_orisgrp_id(
8829  const struct hecmwST_local_mesh *global_mesh,
8830  struct hecmwST_local_mesh *local_mesh) {
8831  struct hecmwST_contact_pair *cpair_global = global_mesh->contact_pair;
8832  struct hecmwST_contact_pair *cpair_local = local_mesh->contact_pair;
8833  int i;
8834 
8835  cpair_local->slave_orisgrp_id =
8836  (int *)HECMW_calloc(cpair_local->n_pair, sizeof(int));
8837  if (cpair_local->slave_orisgrp_id == NULL) {
8838  HECMW_set_error(errno, "");
8839  goto error;
8840  }
8841 
8842  for (i = 0; i < cpair_global->n_pair; i++) {
8843  cpair_local->slave_orisgrp_id[i] = cpair_global->slave_orisgrp_id[i];
8844  }
8845 
8846  return RTC_NORMAL;
8847 
8848 error:
8849  return RTC_ERROR;
8850 }
8851 
8852 static int const_contact_pair_master_grp_id(
8853  const struct hecmwST_local_mesh *global_mesh,
8854  struct hecmwST_local_mesh *local_mesh) {
8855  struct hecmwST_contact_pair *cpair_global = global_mesh->contact_pair;
8856  struct hecmwST_contact_pair *cpair_local = local_mesh->contact_pair;
8857  int i;
8858 
8859  cpair_local->master_grp_id =
8860  (int *)HECMW_calloc(cpair_local->n_pair, sizeof(int));
8861  if (cpair_local->master_grp_id == NULL) {
8862  HECMW_set_error(errno, "");
8863  goto error;
8864  }
8865 
8866  for (i = 0; i < cpair_global->n_pair; i++) {
8867  cpair_local->master_grp_id[i] = cpair_global->master_grp_id[i];
8868  }
8869 
8870  return RTC_NORMAL;
8871 
8872 error:
8873  return RTC_ERROR;
8874 }
8875 
8876 static int const_contact_pair_info(const struct hecmwST_local_mesh *global_mesh,
8877  struct hecmwST_local_mesh *local_mesh) {
8878  int rtc;
8879 
8880  HECMW_assert(global_mesh);
8881  HECMW_assert(global_mesh->contact_pair);
8882  HECMW_assert(local_mesh);
8883  HECMW_assert(local_mesh->contact_pair);
8884 
8885  if (global_mesh->contact_pair->n_pair == 0) {
8886  init_struct_contact_pair(local_mesh);
8887  return RTC_NORMAL;
8888  }
8889 
8890  rtc = const_contact_pair_n_pair(global_mesh, local_mesh);
8891  if (rtc != RTC_NORMAL) goto error;
8892 
8893  rtc = const_contact_pair_name(global_mesh, local_mesh);
8894  if (rtc != RTC_NORMAL) goto error;
8895 
8896  rtc = const_contact_pair_type(global_mesh, local_mesh);
8897  if (rtc != RTC_NORMAL) goto error;
8898 
8899  rtc = const_contact_pair_slave_grp_id(global_mesh, local_mesh);
8900  if (rtc != RTC_NORMAL) goto error;
8901 
8902  rtc = const_contact_pair_slave_orisgrp_id(global_mesh, local_mesh);
8903  if (rtc != RTC_NORMAL) goto error;
8904 
8905  rtc = const_contact_pair_master_grp_id(global_mesh, local_mesh);
8906  if (rtc != RTC_NORMAL) goto error;
8907 
8908  return RTC_NORMAL;
8909 
8910 error:
8911  return RTC_ERROR;
8912 }
8913 
8914 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8915  * - - - - - - - - - */
8916 
8917 static int const_local_data(const struct hecmwST_local_mesh *global_mesh,
8918  struct hecmwST_local_mesh *local_mesh,
8919  const struct hecmw_part_cont_data *cont_data,
8920  const char *node_flag, const char *elem_flag,
8921  int *node_global2local, int *elem_global2local,
8922  int current_domain) {
8923  int *node_local2global = NULL;
8924  int *elem_local2global = NULL;
8925  int rtc, i;
8926 
8927  HECMW_log(HECMW_LOG_DEBUG, "Starting creation of local mesh data...\n");
8928 
8929  rtc = set_node_global2local(global_mesh, local_mesh, node_global2local,
8930  node_flag, current_domain);
8931  if (rtc != RTC_NORMAL) goto error;
8932 
8933  node_local2global = (int *)HECMW_calloc(local_mesh->n_node, sizeof(int));
8934  if (node_local2global == NULL) {
8935  HECMW_set_error(errno, "");
8936  goto error;
8937  }
8938 
8939  if (is_spdup_available(global_mesh)) {
8940  rtc = set_node_local2global_mod(global_mesh, local_mesh, node_global2local,
8941  node_local2global, current_domain);
8942  } else {
8943  rtc = set_node_local2global(global_mesh, local_mesh, node_global2local,
8944  node_local2global);
8945  }
8946 
8947  if (rtc != RTC_NORMAL) goto error;
8948 
8949  rtc = set_elem_global2local(global_mesh, local_mesh, elem_global2local,
8950  elem_flag, current_domain);
8951 
8952  if (rtc != RTC_NORMAL) goto error;
8953 
8954  elem_local2global = (int *)HECMW_calloc(local_mesh->n_elem, sizeof(int));
8955  if (elem_local2global == NULL) {
8956  HECMW_set_error(errno, "");
8957  goto error;
8958  }
8959 
8960  if (is_spdup_available(global_mesh)) {
8961  rtc = set_elem_local2global_mod(global_mesh, local_mesh, elem_global2local,
8962  elem_local2global, current_domain);
8963  } else {
8964  rtc = set_elem_local2global(global_mesh, local_mesh, elem_global2local,
8965  elem_local2global);
8966  }
8967 
8968  if (rtc != RTC_NORMAL) goto error;
8969 
8970  rtc = const_global_info(global_mesh, local_mesh);
8971  if (rtc != RTC_NORMAL) goto error;
8972 
8973  rtc = const_node_info(global_mesh, local_mesh, node_local2global, node_flag,
8974  current_domain);
8975  if (rtc != RTC_NORMAL) goto error;
8976 
8977  rtc = const_elem_info(global_mesh, local_mesh, node_global2local,
8978  elem_global2local, elem_local2global, current_domain);
8979 
8980  if (rtc != RTC_NORMAL) goto error;
8981  rtc = const_comm_info(global_mesh, local_mesh, node_global2local,
8982  elem_global2local, current_domain);
8983  if (rtc != RTC_NORMAL) goto error;
8984 
8985  rtc = const_adapt_info(global_mesh, local_mesh);
8986  if (rtc != RTC_NORMAL) goto error;
8987 
8988  rtc = const_sect_info(global_mesh, local_mesh);
8989  if (rtc != RTC_NORMAL) goto error;
8990 
8991  rtc = const_mat_info(global_mesh, local_mesh);
8992  if (rtc != RTC_NORMAL) goto error;
8993 
8994  rtc = const_mpc_info(global_mesh, local_mesh, node_global2local);
8995  if (rtc != RTC_NORMAL) goto error;
8996 
8997  rtc = const_amp_info(global_mesh, local_mesh);
8998  if (rtc != RTC_NORMAL) goto error;
8999 
9000  rtc = const_node_grp_info(global_mesh, local_mesh, node_global2local,
9001  current_domain);
9002  if (rtc != RTC_NORMAL) goto error;
9003 
9004  rtc = const_elem_grp_info(global_mesh, local_mesh, elem_global2local,
9005  current_domain);
9006  if (rtc != RTC_NORMAL) goto error;
9007 
9008  rtc = const_surf_grp_info(global_mesh, local_mesh, elem_global2local);
9009  if (rtc != RTC_NORMAL) goto error;
9010 
9011  rtc = const_contact_pair_info(global_mesh, local_mesh);
9012  if (rtc != RTC_NORMAL) goto error;
9013 
9014  rtc = clear_node_global2local(global_mesh, local_mesh, node_global2local,
9015  current_domain);
9016  rtc = clear_elem_global2local(global_mesh, local_mesh, elem_global2local,
9017  current_domain);
9018 
9019  HECMW_free(node_local2global);
9020  HECMW_free(elem_local2global);
9021 
9022  HECMW_log(HECMW_LOG_DEBUG, "Creation of local mesh data done\n");
9023 
9024  return RTC_NORMAL;
9025 
9026 error:
9027  HECMW_free(node_local2global);
9028  HECMW_free(elem_local2global);
9029  clean_struct_local_mesh(local_mesh);
9030 
9031  return RTC_ERROR;
9032 }
9033 
9034 /*==================================================================================================
9035 
9036  print UCD format data
9037 
9038 ==================================================================================================*/
9039 
9040 static int print_ucd_entire_set_node_data(
9041  const struct hecmwST_local_mesh *global_mesh,
9042  struct hecmwST_result_data *result_data, const char *node_flag) {
9043  int size;
9044  int nn_item;
9045  int i;
9046  const size_t label_len = HECMW_NAME_LEN + 1;
9047 
9048  result_data->nn_component = 1;
9049 
9050  result_data->nn_dof =
9051  (int *)HECMW_malloc(sizeof(int) * result_data->nn_component);
9052  if (result_data->nn_dof == NULL) {
9053  HECMW_set_error(errno, "");
9054  goto error;
9055  }
9056  result_data->nn_dof[0] = 1;
9057 
9058  result_data->node_label =
9059  (char **)HECMW_malloc(sizeof(char *) * result_data->nn_component);
9060  if (result_data->node_label == NULL) {
9061  HECMW_set_error(errno, "");
9062  goto error;
9063  } else {
9064  for (i = 0; i < result_data->nn_component; i++) {
9065  result_data->node_label[i] = NULL;
9066  }
9067  }
9068  for (i = 0; i < result_data->nn_component; i++) {
9069  result_data->node_label[i] =
9070  (char *)HECMW_malloc(sizeof(char) * label_len);
9071  if (result_data->node_label[i] == NULL) {
9072  HECMW_set_error(errno, "");
9073  goto error;
9074  }
9075  }
9076  snprintf(result_data->node_label[0], label_len, "rank_of_node");
9077 
9078  for (nn_item = 0, i = 0; i < result_data->nn_component; i++) {
9079  nn_item += result_data->nn_dof[i];
9080  }
9081 
9082  size = sizeof(double) * nn_item * global_mesh->n_node;
9083  result_data->node_val_item = (double *)HECMW_malloc(size);
9084  if (result_data->node_val_item == NULL) {
9085  HECMW_set_error(errno, "");
9086  goto error;
9087  }
9088 
9089  switch (global_mesh->hecmw_flag_parttype) {
9091  for (i = 0; i < global_mesh->n_node; i++) {
9092  result_data->node_val_item[i] = (double)global_mesh->node_ID[2 * i + 1];
9093  }
9094  break;
9095 
9097  for (i = 0; i < global_mesh->n_node; i++) {
9098  if (EVAL_BIT(node_flag[i], OVERLAP)) {
9099  result_data->node_val_item[i] =
9100  (double)global_mesh->n_subdomain + 2.0;
9101  } else {
9102  result_data->node_val_item[i] =
9103  (double)global_mesh->node_ID[2 * i + 1];
9104  }
9105  }
9106  break;
9107 
9108  default:
9110  global_mesh->hecmw_flag_parttype);
9111  goto error;
9112  }
9113 
9114  return RTC_NORMAL;
9115 
9116 error:
9117  free_struct_result_data(result_data);
9118 
9119  return RTC_ERROR;
9120 }
9121 
9122 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9123  * - - - - - - - - - */
9124 
9125 static int print_ucd_entire_set_elem_data(
9126  const struct hecmwST_local_mesh *global_mesh,
9127  struct hecmwST_result_data *result_data, const char *elem_flag) {
9128  int size;
9129  int ne_item;
9130  int i;
9131  const size_t label_len = HECMW_NAME_LEN + 1;
9132 
9133  result_data->ne_component = 1;
9134 
9135  result_data->ne_dof =
9136  (int *)HECMW_malloc(sizeof(int) * result_data->ne_component);
9137  if (result_data->ne_dof == NULL) {
9138  HECMW_set_error(errno, "");
9139  goto error;
9140  }
9141  result_data->ne_dof[0] = 1;
9142 
9143  result_data->elem_label =
9144  (char **)HECMW_malloc(sizeof(char *) * result_data->ne_component);
9145  if (result_data->elem_label == NULL) {
9146  HECMW_set_error(errno, "");
9147  goto error;
9148  } else {
9149  for (i = 0; i < result_data->ne_component; i++) {
9150  result_data->elem_label[i] = NULL;
9151  }
9152  }
9153  for (i = 0; i < result_data->ne_component; i++) {
9154  result_data->elem_label[i] =
9155  (char *)HECMW_malloc(sizeof(char) * label_len);
9156  if (result_data->elem_label[i] == NULL) {
9157  HECMW_set_error(errno, "");
9158  goto error;
9159  }
9160  }
9161  snprintf(result_data->elem_label[0], label_len, "partitioning_image");
9162 
9163  /* modify element information*/
9164  for (i = 0; i < global_mesh->n_elem; i++) {
9165  switch (global_mesh->elem_type[i]) {
9166  case HECMW_ETYPE_SHT6:
9167  global_mesh->elem_type[i] = HECMW_ETYPE_SHT1;
9168  break;
9169 
9170  case HECMW_ETYPE_SHQ8:
9171  global_mesh->elem_type[i] = HECMW_ETYPE_SHQ1;
9172  break;
9173 
9174  case HECMW_ETYPE_BEM3:
9175  global_mesh->elem_type[i] = HECMW_ETYPE_ROD1;
9176  break;
9177 
9178  case HECMW_ETYPE_ROD31:
9179  case HECMW_ETYPE_SPGDPT1:
9180  global_mesh->elem_type[i] = HECMW_ETYPE_ROD1;
9181  break;
9182  }
9183  }
9184 
9185  for (ne_item = 0, i = 0; i < result_data->ne_component; i++) {
9186  ne_item += result_data->ne_dof[i];
9187  }
9188 
9189  size = sizeof(double) * ne_item * global_mesh->n_elem;
9190  result_data->elem_val_item = (double *)HECMW_malloc(size);
9191  if (result_data->elem_val_item == NULL) {
9192  HECMW_set_error(errno, "");
9193  goto error;
9194  }
9195 
9196  switch (global_mesh->hecmw_flag_parttype) {
9198  for (i = 0; i < global_mesh->n_elem; i++) {
9199  if (EVAL_BIT(elem_flag[i], OVERLAP)) {
9200  result_data->elem_val_item[i] =
9201  (double)global_mesh->n_subdomain + 2.0;
9202  } else {
9203  result_data->elem_val_item[i] =
9204  (double)global_mesh->elem_ID[2 * i + 1];
9205  }
9206  }
9207  break;
9208 
9210  for (i = 0; i < global_mesh->n_elem; i++) {
9211  result_data->elem_val_item[i] = (double)global_mesh->elem_ID[2 * i + 1];
9212  }
9213  break;
9214 
9215  default:
9217  global_mesh->hecmw_flag_parttype);
9218  goto error;
9219  }
9220 
9221  return RTC_NORMAL;
9222 
9223 error:
9224  free_struct_result_data(result_data);
9225 
9226  return RTC_ERROR;
9227 }
9228 
9229 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
9230 
9231 static int print_ucd_entire(const struct hecmwST_local_mesh *global_mesh,
9232  const char *node_flag, const char *elem_flag,
9233  const char *ofname) {
9234  struct hecmwST_result_data *result_data;
9235 
9236  result_data = (struct hecmwST_result_data *)HECMW_malloc(
9237  sizeof(struct hecmwST_result_data));
9238  if (result_data == NULL) {
9239  HECMW_set_error(errno, "");
9240  goto error;
9241  } else {
9242  init_struct_result_data(result_data);
9243  }
9244 
9245  if (print_ucd_entire_set_node_data(global_mesh, result_data, node_flag)) {
9246  goto error;
9247  }
9248 
9249  if (print_ucd_entire_set_elem_data(global_mesh, result_data, elem_flag)) {
9250  goto error;
9251  }
9252 
9253  if (HECMW_ucd_legacy_print(global_mesh, result_data, ofname)) {
9254  goto error;
9255  }
9256 
9257  free_struct_result_data(result_data);
9258 
9259  return RTC_NORMAL;
9260 
9261 error:
9262  free_struct_result_data(result_data);
9263 
9264  return RTC_ERROR;
9265 }
9266 
9267 static int init_partition(struct hecmwST_local_mesh *global_mesh,
9268  struct hecmw_part_cont_data *cont_data) {
9269  HECMW_log(HECMW_LOG_DEBUG, "Starting initialization for partitioner...");
9270 
9271  /* global_mesh->n_subdomain */
9272  global_mesh->n_subdomain = cont_data->n_domain;
9273 
9274  /* global_mesh->hecmw_flag_parttype */
9275  switch (cont_data->type) {
9276  case HECMW_PART_TYPE_NODE_BASED: /* for node-based partitioning */
9278  break;
9279 
9280  case HECMW_PART_TYPE_ELEMENT_BASED: /* for element-based partitioning */
9282  break;
9283 
9284  default:
9286  goto error;
9287  }
9288 
9289  /* global_mesh->hecmw_flag_partdepth */
9290  global_mesh->hecmw_flag_partdepth = cont_data->depth;
9291 
9292  /* global_mesh->hecmw_flag_partcontact */
9293  if (global_mesh->contact_pair->n_pair > 0) {
9294  switch (cont_data->contact) {
9297  break;
9298 
9301  break;
9302 
9305  break;
9306 
9308  default:
9311  break;
9312  }
9313 
9314  switch (cont_data->contact_owner) {
9316  global_mesh->hecmw_flag_partcontact |=
9318  break;
9319 
9321  default:
9322  global_mesh->hecmw_flag_partcontact |=
9324  break;
9325  }
9326  }
9327 
9328  HECMW_log(HECMW_LOG_DEBUG, "Initialization for partitioner done");
9329 
9330  return RTC_NORMAL;
9331 
9332 error:
9333  return RTC_ERROR;
9334  ;
9335 }
9336 
9337 /*==================================================================================================
9338 
9339  main function
9340 
9341 ==================================================================================================*/
9342 
9344  struct hecmwST_local_mesh *global_mesh,
9345  struct hecmw_part_cont_data *cont_data) {
9346  struct hecmwST_local_mesh *local_mesh = NULL;
9347  struct hecmw_ctrl_meshfiles *ofheader = NULL;
9348  char *node_flag = NULL;
9349  char *elem_flag = NULL;
9350  char *node_flag_neighbor = NULL;
9351  char *elem_flag_neighbor = NULL;
9352  int *node_global2local = NULL;
9353  int *elem_global2local = NULL;
9354  char ofname[HECMW_FILENAME_LEN + 1];
9355  int *num_elem, *num_node, *num_ielem, *num_inode, *num_nbpe;
9356  int *sum_elem, *sum_node, *sum_ielem, *sum_inode, *sum_nbpe;
9357  int current_domain, nrank, iS, iE;
9358  int rtc;
9359  int i;
9360  int error_in_ompsection = 0;
9361 
9362  if (global_mesh == NULL) {
9363  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'global_mesh\' is NULL");
9364  goto error;
9365  }
9366  if (cont_data == NULL) {
9367  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'cont_data\' is NULL");
9368  goto error;
9369  }
9370 
9371  rtc = init_partition(global_mesh, cont_data);
9372  if (rtc != RTC_NORMAL) goto error;
9373 
9374  rtc = HECMW_part_init_log(global_mesh->n_subdomain);
9375  if (rtc != RTC_NORMAL) goto error;
9376 
9377  if (global_mesh->my_rank == 0) {
9379  if (rtc != RTC_NORMAL) goto error;
9381  if (rtc != RTC_NORMAL) goto error;
9383  if (rtc != RTC_NORMAL) goto error;
9385  if (rtc != RTC_NORMAL) goto error;
9386 
9387  rtc = HECMW_part_set_log_n_node_g(global_mesh->n_node);
9388  if (rtc != RTC_NORMAL) goto error;
9389  rtc = HECMW_part_set_log_n_elem_g(global_mesh->n_elem);
9390  if (rtc != RTC_NORMAL) goto error;
9391  }
9392 
9393  if (global_mesh->n_subdomain == 1) {
9394  current_domain = 0;
9395 
9396  if (global_mesh->my_rank == 0) {
9397  HECMW_log(HECMW_LOG_INFO, "Creating local mesh for domain #%d ...",
9398  current_domain);
9399 
9401  "part_out", global_mesh->n_subdomain, current_domain);
9402  if (ofheader == NULL) {
9403  HECMW_log(HECMW_LOG_ERROR, "not set output file header");
9404  error_in_ompsection = 1;
9405  goto error;
9406  }
9407  if (ofheader->n_mesh == 0) {
9408  HECMW_log(HECMW_LOG_ERROR, "output file name is not set");
9409  error_in_ompsection = 1;
9410  goto error;
9411  }
9412 
9413  get_dist_file_name(ofheader->meshfiles[0].filename, current_domain,
9414  ofname, sizeof(ofname));
9415  HECMW_assert(ofname != NULL);
9416 
9418  "Starting writing local mesh for domain #%d...",
9419  current_domain);
9420 
9421  rtc = HECMW_put_dist_mesh(global_mesh, ofname);
9422  if (rtc != 0) {
9423  HECMW_log(HECMW_LOG_ERROR, "Failed to write local mesh for domain #%d",
9424  current_domain);
9425  goto error;
9426  }
9427 
9428  HECMW_log(HECMW_LOG_DEBUG, "Writing local mesh for domain #%d done",
9429  current_domain);
9430 
9431  rtc = HECMW_part_set_log_n_elem(0, global_mesh->n_elem);
9432  if (rtc != 0) goto error;
9433  rtc = HECMW_part_set_log_n_node(0, global_mesh->n_node);
9434  if (rtc != 0) goto error;
9435  rtc = HECMW_part_set_log_ne_internal(0, global_mesh->ne_internal);
9436  if (rtc != 0) goto error;
9437  rtc = HECMW_part_set_log_nn_internal(0, global_mesh->nn_internal);
9438  if (rtc != 0) goto error;
9439 
9440  rtc = HECMW_part_print_log();
9441  if (rtc) goto error;
9442  }
9444 
9445  return global_mesh;
9446  }
9447 
9448  num_elem = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9449  if (num_elem == NULL) {
9450  HECMW_set_error(errno, "");
9451  goto error;
9452  }
9453  num_node = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9454  if (num_node == NULL) {
9455  HECMW_set_error(errno, "");
9456  goto error;
9457  }
9458  num_ielem = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9459  if (num_ielem == NULL) {
9460  HECMW_set_error(errno, "");
9461  goto error;
9462  }
9463  num_inode = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9464  if (num_inode == NULL) {
9465  HECMW_set_error(errno, "");
9466  goto error;
9467  }
9468  num_nbpe = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9469  if (num_nbpe == NULL) {
9470  HECMW_set_error(errno, "");
9471  goto error;
9472  }
9473  sum_elem = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9474  if (sum_elem == NULL) {
9475  HECMW_set_error(errno, "");
9476  goto error;
9477  }
9478  sum_node = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9479  if (sum_node == NULL) {
9480  HECMW_set_error(errno, "");
9481  goto error;
9482  }
9483  sum_ielem = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9484  if (sum_ielem == NULL) {
9485  HECMW_set_error(errno, "");
9486  goto error;
9487  }
9488  sum_inode = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9489  if (sum_inode == NULL) {
9490  HECMW_set_error(errno, "");
9491  goto error;
9492  }
9493  sum_nbpe = (int *)HECMW_calloc(global_mesh->n_subdomain, sizeof(int));
9494  if (sum_nbpe == NULL) {
9495  HECMW_set_error(errno, "");
9496  goto error;
9497  }
9498 
9499  rtc = wnumbering(global_mesh, cont_data);
9500  if (rtc != RTC_NORMAL) goto error;
9501 
9502  if (cont_data->is_print_part == 1) {
9503  if (global_mesh->my_rank == 0) {
9504  print_part(global_mesh, cont_data->part_file_name);
9505  }
9506  }
9507 
9508  rtc = spdup_makelist_main(global_mesh);
9509  if (rtc != RTC_NORMAL) goto error;
9510 
9511 #ifdef _OPENMP
9512 #pragma omp parallel default(none), \
9513  private(node_flag, elem_flag, local_mesh, nrank, iS, iE, i, \
9514  current_domain, rtc, ofheader, ofname), \
9515  private(node_global2local, elem_global2local, \
9516  node_flag_neighbor, elem_flag_neighbor), \
9517  shared(global_mesh, cont_data, num_elem, num_node, \
9518  num_ielem, num_inode, num_nbpe, error_in_ompsection)
9519  {
9520 #endif /* _OPENMP */
9521 
9522  node_flag = (char *)HECMW_calloc(global_mesh->n_node, sizeof(char));
9523  if (node_flag == NULL) {
9524  HECMW_set_error(errno, "");
9525  error_in_ompsection = 1;
9526  goto error_omp;
9527  }
9528  elem_flag = (char *)HECMW_calloc(global_mesh->n_elem, sizeof(char));
9529  if (elem_flag == NULL) {
9530  HECMW_set_error(errno, "");
9531  error_in_ompsection = 1;
9532  goto error_omp;
9533  }
9534 
9535  node_global2local = (int *)HECMW_calloc(global_mesh->n_node, sizeof(int));
9536  if (node_global2local == NULL) {
9537  HECMW_set_error(errno, "");
9538  error_in_ompsection = 1;
9539  goto error_omp;
9540  }
9541  elem_global2local = (int *)HECMW_calloc(global_mesh->n_elem, sizeof(int));
9542  if (elem_global2local == NULL) {
9543  HECMW_set_error(errno, "");
9544  error_in_ompsection = 1;
9545  goto error_omp;
9546  }
9547  node_flag_neighbor =
9548  (char *)HECMW_malloc(sizeof(char) * global_mesh->n_node);
9549  if (node_flag_neighbor == NULL) {
9550  HECMW_set_error(errno, "");
9551  error_in_ompsection = 1;
9552  goto error_omp;
9553  }
9554  elem_flag_neighbor =
9555  (char *)HECMW_malloc(sizeof(char) * global_mesh->n_elem);
9556  if (elem_flag_neighbor == NULL) {
9557  HECMW_set_error(errno, "");
9558  error_in_ompsection = 1;
9559  goto error_omp;
9560  }
9561  memset(node_flag_neighbor, 0, sizeof(char) * global_mesh->n_node);
9562  memset(elem_flag_neighbor, 0, sizeof(char) * global_mesh->n_elem);
9563 
9564  local_mesh = HECMW_dist_alloc();
9565  if (local_mesh == NULL) {
9566  error_in_ompsection = 1;
9567  goto error_omp;
9568  }
9569 
9570  nrank = global_mesh->n_subdomain / HECMW_comm_get_size();
9571  iS = HECMW_comm_get_rank() * nrank;
9572  iE = iS + nrank;
9574  iE = global_mesh->n_subdomain;
9575 
9576 #ifdef _OPENMP
9577 #pragma omp for schedule(dynamic, 1), reduction(+ : error_in_ompsection)
9578 #endif
9579  for (i = iS; i < iE; i++) {
9580  if (error_in_ompsection) continue;
9581 
9582  current_domain = i;
9583 
9584  HECMW_log(HECMW_LOG_INFO, "Creating local mesh for domain #%d ...",
9585  current_domain);
9586 
9587  rtc = create_neighbor_info(global_mesh, local_mesh, node_flag, elem_flag,
9588  current_domain);
9589  if (rtc != RTC_NORMAL) {
9590  error_in_ompsection = 1;
9591  continue;
9592  }
9593 
9594  if (global_mesh->n_subdomain > 1) {
9595  rtc = create_comm_info(global_mesh, local_mesh, node_flag, elem_flag,
9596  node_flag_neighbor, elem_flag_neighbor,
9597  current_domain);
9598  if (rtc != RTC_NORMAL) {
9599  error_in_ompsection = 1;
9600  continue;
9601  }
9602  }
9603 
9604  rtc = const_local_data(global_mesh, local_mesh, cont_data, node_flag,
9605  elem_flag, node_global2local, elem_global2local,
9606  current_domain);
9607  if (rtc != RTC_NORMAL) {
9608  error_in_ompsection = 1;
9609  continue;
9610  }
9611 
9612  num_elem[i] = local_mesh->n_elem;
9613  num_node[i] = local_mesh->n_node;
9614  num_ielem[i] = local_mesh->ne_internal;
9615  num_inode[i] = local_mesh->nn_internal;
9616  num_nbpe[i] = local_mesh->n_neighbor_pe;
9617 
9619  "part_out", global_mesh->n_subdomain, current_domain);
9620  if (ofheader == NULL) {
9621  HECMW_log(HECMW_LOG_ERROR, "not set output file header");
9622  error_in_ompsection = 1;
9623  continue;
9624  }
9625  if (ofheader->n_mesh == 0) {
9626  HECMW_log(HECMW_LOG_ERROR, "output file name is not set");
9627  error_in_ompsection = 1;
9628  continue;
9629  }
9630 
9631  get_dist_file_name(ofheader->meshfiles[0].filename, current_domain,
9632  ofname, sizeof(ofname));
9633  HECMW_assert(ofname != NULL);
9634 
9636  "Starting writing local mesh for domain #%d...",
9637  current_domain);
9638 
9639  rtc = HECMW_put_dist_mesh(local_mesh, ofname);
9640  if (rtc != 0) {
9641  HECMW_log(HECMW_LOG_ERROR, "Failed to write local mesh for domain #%d",
9642  current_domain);
9643  error_in_ompsection = 1;
9644  } else {
9645  HECMW_log(HECMW_LOG_DEBUG, "Writing local mesh for domain #%d done",
9646  current_domain);
9647  }
9648 
9649  clean_struct_local_mesh(local_mesh);
9650 
9651  HECMW_ctrl_free_meshfiles(ofheader);
9652  ofheader = NULL;
9653 
9654  if (is_spdup_available(global_mesh)) {
9655  spdup_clear_IEB(node_flag, elem_flag, current_domain);
9656  } else {
9657  int j;
9658  for (j = 0; j < global_mesh->n_node; j++) {
9659  CLEAR_IEB(node_flag[j]);
9660  }
9661  for (j = 0; j < global_mesh->n_elem; j++) {
9662  CLEAR_IEB(elem_flag[j]);
9663  }
9664  }
9665  }
9666 #ifdef _OPENMP
9667  if (error_in_ompsection) goto error_omp;
9668 
9669 #pragma omp single
9670 #endif
9671  if (cont_data->is_print_ucd == 1) {
9672  if (global_mesh->my_rank == 0) {
9673  print_ucd_entire(global_mesh, node_flag, elem_flag,
9674  cont_data->ucd_file_name);
9675  }
9676  }
9677 
9678  error_omp:
9679  HECMW_dist_free(local_mesh);
9680  HECMW_free(node_flag);
9681  HECMW_free(elem_flag);
9682  HECMW_free(node_global2local);
9683  HECMW_free(elem_global2local);
9684  HECMW_free(node_flag_neighbor);
9685  HECMW_free(elem_flag_neighbor);
9686 
9687 #ifdef _OPENMP
9688  } /* omp end parallel */
9689  if (error_in_ompsection) goto error;
9690 #endif
9691 
9692  rtc = HECMW_Allreduce(num_elem, sum_elem, global_mesh->n_subdomain, HECMW_INT,
9694  if (rtc != 0) goto error;
9695  rtc = HECMW_Allreduce(num_node, sum_node, global_mesh->n_subdomain, HECMW_INT,
9697  if (rtc != 0) goto error;
9698  rtc = HECMW_Allreduce(num_ielem, sum_ielem, global_mesh->n_subdomain,
9700  if (rtc != 0) goto error;
9701  rtc = HECMW_Allreduce(num_inode, sum_inode, global_mesh->n_subdomain,
9703  if (rtc != 0) goto error;
9704  rtc = HECMW_Allreduce(num_nbpe, sum_nbpe, global_mesh->n_subdomain,
9706  if (rtc != 0) goto error;
9707 
9708  if (global_mesh->my_rank == 0) {
9709  for (i = 0; i < global_mesh->n_subdomain; i++) {
9710  rtc = HECMW_part_set_log_n_elem(i, sum_elem[i]);
9711  if (rtc != 0) goto error;
9712  rtc = HECMW_part_set_log_n_node(i, sum_node[i]);
9713  if (rtc != 0) goto error;
9714  rtc = HECMW_part_set_log_ne_internal(i, sum_ielem[i]);
9715  if (rtc != 0) goto error;
9716  rtc = HECMW_part_set_log_nn_internal(i, sum_inode[i]);
9717  if (rtc != 0) goto error;
9718  rtc = HECMW_part_set_log_n_neighbor_pe(i, sum_nbpe[i]);
9719  if (rtc != 0) goto error;
9720  }
9721  rtc = HECMW_part_print_log();
9722  if (rtc) goto error;
9723  }
9725 
9726  HECMW_free(num_elem);
9727  HECMW_free(num_node);
9728  HECMW_free(num_ielem);
9729  HECMW_free(num_inode);
9730  HECMW_free(num_nbpe);
9731  HECMW_free(sum_elem);
9732  HECMW_free(sum_node);
9733  HECMW_free(sum_ielem);
9734  HECMW_free(sum_inode);
9735  HECMW_free(sum_nbpe);
9736 
9737  spdup_freelist(global_mesh);
9738 
9739  return global_mesh;
9740 
9741 error:
9742  HECMW_free(node_flag);
9743  HECMW_free(elem_flag);
9744  HECMW_free(num_elem);
9745  HECMW_free(num_node);
9746  HECMW_free(num_ielem);
9747  HECMW_free(num_inode);
9748  HECMW_free(num_nbpe);
9749  HECMW_free(sum_elem);
9750  HECMW_free(sum_node);
9751  HECMW_free(sum_ielem);
9752  HECMW_free(sum_inode);
9753  HECMW_free(sum_nbpe);
9754  HECMW_dist_free(local_mesh);
9755  if (ofheader) {
9756  HECMW_ctrl_free_meshfiles(ofheader);
9757  }
9759 
9760  return NULL;
9761 }
9762 
9764  struct hecmwST_local_mesh *global_mesh) {
9765  struct hecmwST_local_mesh *local_mesh;
9767 
9768  HECMW_log(HECMW_LOG_INFO, "Starting domain decomposition...\n");
9769 
9770  if (global_mesh == NULL) {
9771  HECMW_set_error(HECMW_PART_E_INV_ARG, "\'global_mesh\' is NULL");
9772  goto error;
9773  }
9774 
9776  if (cont_data == NULL) goto error;
9777 
9778  local_mesh = HECMW_partition_inner(global_mesh, cont_data);
9779  if (local_mesh == NULL) goto error;
9780 
9782 
9783  HECMW_log(HECMW_LOG_INFO, "Domain decomposition done\n");
9784 
9785  return local_mesh;
9786 
9787 error:
9788  return NULL;
9789 }
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