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