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