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