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