FrontISTR 5.2.0
Large-scale structural analysis program with finit element method
Loading...
Searching...
No Matches
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"
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
102struct link_unit {
103 int id;
104
106};
107
108struct link_list {
109 int n;
110
112
114};
115
116/*===== internal/boundary node/element list of each domain =======*/
117static int *n_int_nlist = NULL;
118static int *n_bnd_nlist = NULL;
119static int *n_int_elist = NULL;
120static int *n_bnd_elist = NULL;
121static int **int_nlist = NULL;
122static int **bnd_nlist = NULL;
123static int **int_elist = NULL;
124static int **bnd_elist = NULL;
125static int **ngrp_idx = NULL;
126static int **ngrp_item = NULL;
127static int **egrp_idx = NULL;
128static int **egrp_item = NULL;
129
130/*===== speed up (K. Inagaki )=======*/
131static 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
146static 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
170static 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
282error:
283 return RTC_ERROR;
284}
285
286static 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
297static 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
328static 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
411error:
412 return RTC_ERROR;
413}
414
415static 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
488error:
489 return RTC_ERROR;
490}
491
492static 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
614error:
615 return RTC_ERROR;
616}
617
618static 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
740error:
741 return RTC_ERROR;
742}
743
744static 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
761error:
762 return RTC_ERROR;
763}
764
765static 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
794static 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
802static 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
814static 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
826static 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
848error:
849 return RTC_ERROR;
850}
851
852static 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
880error:
881 return RTC_ERROR;
882}
883
884static 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
920error:
921 return RTC_ERROR;
922}
923
924static 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
949error:
950 return RTC_ERROR;
951}
952
953static 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
972error:
973 return RTC_ERROR;
974}
975
976static 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
998error:
999 return RTC_ERROR;
1000}
1001
1002static 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
1025error:
1026 return RTC_ERROR;
1027}
1028
1029static 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
1048error:
1049 return RTC_ERROR;
1050}
1051
1052static 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
1074error:
1075 return RTC_ERROR;
1076}
1077
1078static 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
1103error:
1104 return RTC_ERROR;
1105}
1106
1107static 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
1131error:
1132 return RTC_ERROR;
1133}
1134
1135static 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
1159error:
1160 return RTC_ERROR;
1161}
1162
1163static 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
1184error:
1185 return RTC_ERROR;
1186}
1187
1188/*================================================================================================*/
1189
1190static 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
1196static 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
1224static 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
1261static 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
1289static 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
1295static 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
1302static 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
1309static 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
1322static 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
1329static 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
1343static 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
1357static 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
1371static 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) {
1386 }
1387
1388 init_struct_contact_pair(local_mesh);
1389}
1390
1391static 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
1412static 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
1428error:
1429 return RTC_ERROR;
1430}
1431
1432static 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
1462static 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
1475static 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
1574static 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
1655error:
1656 HECMW_free(id);
1657 HECMW_free(stack);
1658 HECMW_free(value);
1659
1660 return RTC_ERROR;
1661}
1662
1663/*------------------------------------------------------------------------------------------------*/
1664
1665static 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
1692static 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
1714error:
1715 HECMW_free(coord);
1716
1717 return RTC_ERROR;
1718}
1719
1720/*================================================================================================*/
1721
1722static 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
1761error:
1762 return RTC_ERROR;
1763}
1764
1765static 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
1784static 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
1837error:
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
1853static 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);
1943 }
1945
1946 return RTC_NORMAL;
1947
1948error:
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);
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
1967static 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
2018error:
2019 HECMW_free(elem_flag);
2020
2021 return -1;
2022}
2023
2024static 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
2044static 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
2121error:
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
2144static 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
2179static 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
2214static 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
2258static 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
2311static 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
2341static 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
2371static 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
2426static 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
2456static 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
2511static 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
2551static 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
2596static 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
2753error:
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
2763static 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
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
2873error:
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
2883static 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
2951error:
2952 HECMW_free(node_graph_index);
2953 HECMW_free(node_graph_item);
2954 HECMW_free(belong_domain);
2955
2956 return -1;
2957}
2958
2959static 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
2981static 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
3022error:
3023 HECMW_free(belong_domain);
3024
3025 return -1;
3026}
3027
3028/*------------------------------------------------------------------------------------------------*/
3029
3030static 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
3097error:
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
3106static 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
3129static 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
3148error:
3149 return RTC_ERROR;
3150}
3151
3152static 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
3193error:
3194 return RTC_ERROR;
3195}
3196
3197/*------------------------------------------------------------------------------------------------*/
3198
3199static 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
3219static 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
3246error:
3248
3249 return RTC_ERROR;
3250}
3251
3252static 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
3327error:
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
3338static 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
3357error:
3358 return RTC_ERROR;
3359}
3360
3361static 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
3404error:
3405 return RTC_ERROR;
3406}
3407
3408static 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
3446error:
3447 return RTC_ERROR;
3448}
3449
3450/*==================================================================================================
3451
3452
3453 create neighboring domain & communication information
3454
3455
3456==================================================================================================*/
3457
3458/*K. Inagaki */
3459static 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
3471static 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 */
3485static 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 */
3499static 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 */
3533static 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
3545static 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 */
3565static 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 */
3582static 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
3618static 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
3653static 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
3676static 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
3823static 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
3892error:
3893 return RTC_ERROR;
3894}
3895
3896/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3897 * - - - - - - - - - */
3898
3899static 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
3924static 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
3938static 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
3956error:
3957 return RTC_ERROR;
3958}
3959
3960static 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
3982static 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
4013error:
4014 return RTC_ERROR;
4015}
4016
4017/*------------------------------------------------------------------------------------------------*/
4018
4019static 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 */
4033static 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
4046static 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
4115static 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
4128static 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
4140static 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
4155static 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
4241error:
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
4252static 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 */
4267static 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
4282static 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 */
4297static 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 */
4313static 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
4326static 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
4340static 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
4352static 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 */
4365static 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 */
4380static 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
4396static 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
4412static 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
4427static 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 */
4443static 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
4475static 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
4493static 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
4518error:
4519 return RTC_ERROR;
4520}
4521
4522static 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
4548error:
4549 return RTC_ERROR;
4550}
4551
4552static 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
4588error:
4589 return RTC_ERROR;
4590}
4591
4592static 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
4774error:
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
4816static 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
4841error:
4842 return RTC_ERROR;
4843}
4844
4845static 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
4871error:
4872 return RTC_ERROR;
4873}
4874
4875static 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
4899error:
4900 return RTC_ERROR;
4901}
4902
4903/*------------------------------------------------------------------------------------------------*/
4904
4905static 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
5072error:
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
5113static 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
5153error:
5154 return RTC_ERROR;
5155}
5156
5157/*==================================================================================================
5158
5159 create distributed mesh information
5160
5161==================================================================================================*/
5162
5163/*K. Inagaki */
5164static 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
5186static 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 */
5225static 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
5251static 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
5277static 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
5296static 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
5330error:
5331 return RTC_ERROR;
5332}
5333
5334/*K. Inagaki */
5335static 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
5392error:
5393 return RTC_ERROR;
5394}
5395
5396/*K. Inagaki */
5397static 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
5427static 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 */
5452static 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
5492static 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
5515static 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
5541static 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 */
5568static 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
5608static 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 */
5625static 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
5659error:
5660 return RTC_ERROR;
5661}
5662
5663static 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
5719error:
5720 return RTC_ERROR;
5721}
5722
5723static 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
5754static 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 */
5779static 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
5819static 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
5826static 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
5833static 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
5840static 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
5847static 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
5854static 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
5862static 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
5870static 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
5878static 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
5886static 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
5894static 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
5901static 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
5943error:
5944 return RTC_ERROR;
5945}
5946
5947/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5948 * - - - - - - - - - */
5949
5950static 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
5961static 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
5972static 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
6000error:
6001 return RTC_ERROR;
6002}
6003
6004/*K. Inagaki */
6005static 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
6033error:
6034 return RTC_ERROR;
6035}
6036
6037static 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
6046static 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
6071error:
6072 return RTC_ERROR;
6073}
6074
6075static 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
6099error:
6100 return RTC_ERROR;
6101}
6102
6103static 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
6125error:
6126 return RTC_ERROR;
6127}
6128
6129static 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
6157error:
6158 return RTC_ERROR;
6159}
6160
6161static 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
6203error:
6204 return RTC_ERROR;
6205}
6206
6207static 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
6261error:
6262 return RTC_ERROR;
6263}
6264
6265/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6266 * - - - - - - - - - */
6267
6268static 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
6279static 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
6299error:
6300 return RTC_ERROR;
6301}
6302
6303static 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
6332error:
6333 return RTC_ERROR;
6334}
6335
6336/*K. Inagaki */
6337static 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
6386error:
6387 return RTC_ERROR;
6388}
6389
6390static 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
6399static 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
6426error:
6427 return RTC_ERROR;
6428}
6429
6430static 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
6467error:
6468 return RTC_ERROR;
6469}
6470
6471static 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
6495error:
6496 return RTC_ERROR;
6497}
6498
6499static 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
6521error:
6522 return RTC_ERROR;
6523}
6524
6525static 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
6547error:
6548 return RTC_ERROR;
6549}
6550
6551static 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
6578error:
6579 return RTC_ERROR;
6580}
6581
6582static 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
6591static 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
6632error:
6633 return RTC_ERROR;
6634}
6635
6636static 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
6694error:
6695 return RTC_ERROR;
6696}
6697
6698/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6699 * - - - - - - - - - */
6700
6701static 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
6708static 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
6715static 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
6722static 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
6729static 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
6736static 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
6743static 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
6750static 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
6773static 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
6796static 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
6819static 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
6884error:
6885 return RTC_ERROR;
6886}
6887
6888/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6889 * - - - - - - - - - */
6890
6891static 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
6898static 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
6905static 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
6913static 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
6921static 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
6928static 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
6935static 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
6942static 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
6949static 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
6957static 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
6965static 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
7004error:
7005 return RTC_ERROR;
7006}
7007
7008/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7009 * - - - - - - - - - */
7010
7011static 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
7018static 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
7025static 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
7032static 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
7040static 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
7048static 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
7055static 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
7062static 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
7069static 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
7076static 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
7114error:
7115 return RTC_ERROR;
7116}
7117
7118/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7119 * - - - - - - - - - */
7120
7121static 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
7128static 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
7135static 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
7142static 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
7149static 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
7156static 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
7163static 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
7171static 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
7179static 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
7186static 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
7193static 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
7234error:
7235 return RTC_ERROR;
7236}
7237
7238/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7239 * - - - - - - - - - */
7240
7241static 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
7269static 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
7295error:
7296 return RTC_ERROR;
7297}
7298
7299static 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
7329error:
7330 return RTC_ERROR;
7331}
7332
7333static 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
7362error:
7363 return RTC_ERROR;
7364}
7365
7366static 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
7396error:
7397 return RTC_ERROR;
7398}
7399
7400static 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
7426error:
7427 return RTC_ERROR;
7428}
7429
7430static 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
7481error:
7482 HECMW_free(mpc_flag);
7483
7484 return RTC_ERROR;
7485}
7486
7487/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7488 * - - - - - - - - - */
7489
7490static 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
7497static 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
7504static 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
7512static 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
7519static 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
7526static 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
7533static 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
7540static 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
7547static 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
7587error:
7588 return RTC_ERROR;
7589}
7590
7591/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7592 * - - - - - - - - - */
7593
7594static 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
7632error:
7633 return NULL;
7634}
7635
7636static 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
7643static 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
7650static 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
7688error:
7689 return RTC_ERROR;
7690}
7691
7692/*K. Inagaki */
7693static 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
7741error:
7742 return RTC_ERROR;
7743}
7744
7745static 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
7798error:
7799 return RTC_ERROR;
7800}
7801
7802/*K. Inagaki */
7803static 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
7882error:
7883 return RTC_ERROR;
7884}
7885
7886static 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
7940error:
7941 HECMW_free(n_eqn_item);
7942
7943 return RTC_ERROR;
7944}
7945
7946/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7947 * - - - - - - - - - */
7948
7949static 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
7956static 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
7963static 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
7990error:
7991 return RTC_ERROR;
7992}
7993
7994/*K. Inagaki */
7995static 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
8025error:
8026 return RTC_ERROR;
8027}
8028
8029static 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
8059error:
8060 return RTC_ERROR;
8061}
8062
8063/*K. Inagaki */
8064static 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
8114error:
8115 return RTC_ERROR;
8116}
8117
8118static 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
8158error:
8159 return RTC_ERROR;
8160}
8161
8162/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8163 * - - - - - - - - - */
8164
8165static 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
8172static 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
8179static 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
8206error:
8207 return RTC_ERROR;
8208}
8209
8210static 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
8243error:
8244 return RTC_ERROR;
8245}
8246
8247static 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
8277error:
8278 return RTC_ERROR;
8279}
8280
8281/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8282 * - - - - - - - - - */
8283
8284static 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
8292static 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
8299static 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
8317error:
8318 return RTC_ERROR;
8319}
8320
8321static 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
8341error:
8342 return RTC_ERROR;
8343}
8344
8345static 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
8365error:
8366 return RTC_ERROR;
8367}
8368
8369static 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
8389error:
8390 return RTC_ERROR;
8391}
8392
8393static 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
8427error:
8428 return RTC_ERROR;
8429}
8430
8431/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8432 * - - - - - - - - - */
8433
8434static 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
8543error:
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
8557static 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
8632error:
8633 free_struct_result_data(result_data);
8634
8635 return RTC_ERROR;
8636}
8637
8638/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8639 * - - - - - - - - - */
8640
8641static 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
8737error:
8738 free_struct_result_data(result_data);
8739
8740 return RTC_ERROR;
8741}
8742
8743/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
8744
8745static 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
8775error:
8776 free_struct_result_data(result_data);
8777
8778 return RTC_ERROR;
8779}
8780
8781static int init_partition(struct hecmwST_local_mesh *global_mesh,
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
8833error:
8834 return RTC_ERROR;
8835 ;
8836}
8837
8838/*==================================================================================================
8839
8840 main function
8841
8842==================================================================================================*/
8843
8845 struct hecmwST_local_mesh *global_mesh,
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
9241error:
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
9287error:
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)
int * HECMW_mesh_hsort_edge_get_v(void)
void HECMW_mesh_hsort_edge_final(void)
int HECMW_mesh_hsort_edge_init(int n_node, int n_elem)
#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
struct hecmw_part_cont_data * HECMW_part_get_control(void)
void HECMW_part_free_control(struct hecmw_part_cont_data *cont_data)
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
#define CLEAR_BIT(map, bit)
#define RTC_NORMAL
#define F_1_2
struct hecmwST_local_mesh * HECMW_partition(struct hecmwST_local_mesh *global_mesh)
#define ISWAP(b, bb)
#define DSWAP(a, aa)
#define QSORT_LOWER
#define OVERLAP
#define CLEAR_MM(map)
#define BOUNDARY
struct hecmwST_local_mesh * HECMW_partition_inner(struct hecmwST_local_mesh *global_mesh, struct hecmw_part_cont_data *cont_data)
#define EVAL_BIT(map, bit)
#define MARK
#define RTC_ERROR
#define MASK_BIT(map, bit)
#define MASK
#define CLEAR_IEB(map)
#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