FrontISTR 5.2.0
Large-scale structural analysis program with finit element method
Loading...
Searching...
No Matches
hecmw_couple_info.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#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <assert.h>
10#include <errno.h>
11
12#include "hecmw_msgno.h"
13#include "hecmw_struct.h"
14#include "hecmw_malloc.h"
15#include "hecmw_error.h"
16#include "hecmw_comm.h"
17
18#include "hecmw_couple_define.h"
19#include "hecmw_couple_struct.h"
21#include "hecmw_couple_info.h"
22
23static struct intracomm_info {
24 char unit_id[HECMW_NAME_LEN + 1];
25 struct hecmw_couple_comm *comm;
26 struct intracomm_info *next;
27} intracomm_root = {
28 "", /* unit_id */
29 NULL, /* comm */
30 NULL, /* next */
31};
32
33static struct intercomm_info {
34 char couple_id[HECMW_NAME_LEN + 1];
35 char unit1_id[HECMW_NAME_LEN + 1];
36 char unit2_id[HECMW_NAME_LEN + 1];
37 struct hecmw_couple_comm *comm;
38 struct intercomm_info *next;
39} intercomm_root = {
40 "", /* couple_id */
41 "", /* unit1_id */
42 "", /* unit2_id */
43 NULL, /* comm */
44 NULL, /* next */
45};
46
47static struct couple_info {
48 char boundary_id[HECMW_NAME_LEN + 1];
49 char couple_id[HECMW_NAME_LEN + 1];
50 char unit1_id[HECMW_NAME_LEN + 1];
51 char unit2_id[HECMW_NAME_LEN + 1];
52 int couple_type;
53 int direction;
54 double tolerance;
55 double bbcoef;
56 double bgcoef;
57 struct hecmw_couple_group *unit1_grp;
58 struct hecmw_couple_group *unit2_grp;
59 struct couple_info *next;
60} couple_root = {
61 "", /* boundary_id */
62 "", /* couple_id */
63 "", /* unit1_id */
64 "", /* unit2_id */
65 HECMW_COUPLE_TYPE_UNDEF, /* couple_type */
66 HECMW_COUPLE_DIRECTION_UNDEF, /* direction */
67 -1.0, /* tolerance */
68 -1.0, /* bbcoef */
69 -1.0, /* bgcoef */
70 NULL, /* unit1_grp */
71 NULL, /* unit2_grp */
72 NULL, /* next */
73};
74
75static int is_initialized = 0;
76
77/*================================================================================================*/
78
79extern void HECMW_couple_free_comm(struct hecmw_couple_comm *comm) {
80 if (comm == NULL) return;
81
82 HECMW_free(comm->ranks);
83 HECMW_free(comm);
84 comm = NULL;
85}
86
87static struct hecmw_couple_comm *alloc_struct_comm(void) {
88 struct hecmw_couple_comm *comm;
89
91 sizeof(struct hecmw_couple_comm));
92 if (comm == NULL) {
93 HECMW_set_error(errno, "");
94 return NULL;
95 }
96
97 comm->psize = 0;
98 comm->rank = -1;
99 comm->ranks = NULL;
100 comm->comm = (HECMW_Comm)(-1);
101 comm->group = (HECMW_Group)(-1);
102 comm->root = -1;
103 comm->is_member = 0;
104 comm->is_root = 0;
105
106 return comm;
107}
108
109static void free_intracomm_info(void) {
110 struct intracomm_info *p, *q;
111
112 for (p = intracomm_root.next; p; p = q) {
113 q = p->next;
114 HECMW_couple_free_comm(p->comm);
115 HECMW_free(p);
116 }
117}
118
119static void free_intercomm_info(void) {
120 struct intercomm_info *p, *q;
121
122 for (p = intercomm_root.next; p; p = q) {
123 q = p->next;
124 HECMW_couple_free_comm(p->comm);
125 HECMW_free(p);
126 }
127}
128
129static void free_couple_info(void) {
130 struct couple_info *p, *q;
131
132 for (p = couple_root.next; p; p = q) {
133 q = p->next;
134 HECMW_couple_ctrl_free_group(p->unit1_grp);
135 HECMW_couple_ctrl_free_group(p->unit2_grp);
136 HECMW_free(p);
137 }
138}
139
141 free_intracomm_info();
142 free_intercomm_info();
143 free_couple_info();
144}
145
146/*------------------------------------------------------------------------------------------------*/
147
148static struct intracomm_info *get_intracomm_info(const char *unit_id) {
149 struct intracomm_info *p;
150
151 for (p = intracomm_root.next; p; p = p->next) {
152 if (strcmp(unit_id, p->unit_id) == 0) return p;
153 }
154
155 return NULL;
156}
157
158static struct intercomm_info *get_intercomm_info(const char *couple_id) {
159 struct intercomm_info *p;
160
161 for (p = intercomm_root.next; p; p = p->next) {
162 if (strcmp(couple_id, p->couple_id) == 0) return p;
163 }
164
165 return NULL;
166}
167
168static struct couple_info *get_couple_info(const char *boundary_id) {
169 struct couple_info *p;
170
171 for (p = couple_root.next; p; p = p->next) {
172 if (strcmp(boundary_id, p->boundary_id) == 0) return p;
173 }
174
175 return NULL;
176}
177
178/*------------------------------------------------------------------------------------------------*/
179
180static int init_intracomm_info(void) {
181 struct hecmw_couple_ctrl_unit_ids *unit_ids;
182 struct hecmw_couple_ctrl_boundary_ids *boundary_ids;
183 struct intracomm_info *p;
184 int *mask = NULL;
185 char *couple_id, *unit1_id, *unit2_id;
186 int i, j;
187
188 if ((unit_ids = HECMW_couple_get_unit_ids()) == NULL) return HECMW_ERROR;
189 if ((boundary_ids = HECMW_couple_get_boundary_ids()) == NULL)
190 return HECMW_ERROR;
191
192 /* masking */
193 mask = (int *)HECMW_malloc(sizeof(int) * unit_ids->n_unit);
194 if (mask == NULL) {
195 HECMW_set_error(errno, "");
196 goto error;
197 }
198 for (i = 0; i < unit_ids->n_unit; i++) {
199 mask[i] = HECMW_COUPLE_FALSE;
200 }
201 for (i = 0; i < boundary_ids->n_boundary; i++) {
202 couple_id = HECMW_couple_ctrl_get_couple_id(boundary_ids->ids[i], NULL, 0);
203 if (couple_id == NULL) goto error;
204 unit1_id =
206 if (unit1_id == NULL) goto error;
207 unit2_id =
209 if (unit2_id == NULL) goto error;
210
211 for (j = 0; j < unit_ids->n_unit; j++) {
212 if (strcmp(unit1_id, unit_ids->ids[j]) == 0) {
213 mask[j] = HECMW_COUPLE_TRUE;
214 }
215 if (strcmp(unit2_id, unit_ids->ids[j]) == 0) {
216 mask[j] = HECMW_COUPLE_TRUE;
217 }
218 }
219 }
220
221 /* setting */
222 p = &intracomm_root;
223 for (i = 0; i < unit_ids->n_unit; i++) {
224 if (mask[i] == HECMW_COUPLE_TRUE) {
225 p->next =
226 (struct intracomm_info *)HECMW_malloc(sizeof(struct intracomm_info));
227 if (p->next == NULL) {
228 HECMW_set_error(errno, "");
229 goto error;
230 }
231 p = p->next;
232
233 strcpy(p->unit_id, unit_ids->ids[i]);
234 p->comm = alloc_struct_comm();
235 if (p->comm == NULL) goto error;
236
237 p->next = NULL;
238 }
239 }
240
241 HECMW_free(mask);
242 return HECMW_SUCCESS;
243
244error:
245 HECMW_free(mask);
246 free_intracomm_info();
247 return HECMW_ERROR;
248}
249
250static int init_intercomm_info(void) {
251 struct hecmw_couple_ctrl_couple_ids *couple_ids;
252 struct hecmw_couple_ctrl_boundary_ids *boundary_ids;
253 struct intercomm_info *p;
254 int *mask = NULL;
255 char *couple_id, unit1_id[HECMW_NAME_LEN + 1], unit2_id[HECMW_NAME_LEN + 1];
256 int i, j;
257
258 if ((couple_ids = HECMW_couple_get_couple_ids()) == NULL) return HECMW_ERROR;
259 if ((boundary_ids = HECMW_couple_get_boundary_ids()) == NULL)
260 return HECMW_ERROR;
261
262 /* masking */
263 mask = (int *)HECMW_malloc(sizeof(int) * couple_ids->n_couple);
264 if (mask == NULL) {
265 HECMW_set_error(errno, "");
266 goto error;
267 }
268 for (i = 0; i < couple_ids->n_couple; i++) {
269 mask[i] = HECMW_COUPLE_FALSE;
270 }
271 for (i = 0; i < boundary_ids->n_boundary; i++) {
272 couple_id = HECMW_couple_ctrl_get_couple_id(boundary_ids->ids[i], NULL, 0);
273 if (couple_id == NULL) goto error;
274
275 for (j = 0; j < couple_ids->n_couple; j++) {
276 if (strcmp(couple_id, couple_ids->ids[j]) == 0) {
277 mask[j] = HECMW_COUPLE_TRUE;
278 }
279 }
280 }
281
282 /* setting */
283 p = &intercomm_root;
284 for (i = 0; i < couple_ids->n_couple; i++) {
285 if (mask[i] == HECMW_COUPLE_TRUE) {
286 p->next =
287 (struct intercomm_info *)HECMW_malloc(sizeof(struct intercomm_info));
288 if (p->next == NULL) {
289 HECMW_set_error(errno, "");
290 goto error;
291 }
292 p = p->next;
293
295 unit1_id, HECMW_NAME_LEN + 1) == NULL)
296 goto error;
298 unit2_id, HECMW_NAME_LEN + 1) == NULL)
299 goto error;
300
301 strcpy(p->couple_id, couple_ids->ids[i]);
302 strcpy(p->unit1_id, unit1_id);
303 strcpy(p->unit2_id, unit2_id);
304 if ((p->comm = alloc_struct_comm()) == NULL) goto error;
305
306 p->next = NULL;
307 }
308 }
309
310 HECMW_free(mask);
311 return HECMW_SUCCESS;
312
313error:
314 HECMW_free(mask);
315 free_intercomm_info();
316 return HECMW_ERROR;
317}
318
319static int init_couple_info(void) {
320 struct hecmw_couple_ctrl_boundary_ids *boundary_ids;
321 struct couple_info *p;
322 char *boundary_id, *unit1_id, *unit2_id;
323 int i;
324
325 if ((boundary_ids = HECMW_couple_get_boundary_ids()) == NULL)
326 return HECMW_ERROR;
327
328 p = &couple_root;
329 for (i = 0; i < boundary_ids->n_boundary; i++) {
330 boundary_id = boundary_ids->ids[i];
331
332 p->next = (struct couple_info *)HECMW_malloc(sizeof(struct couple_info));
333 if (p->next == NULL) {
334 HECMW_set_error(errno, "");
335 goto error;
336 }
337 p = p->next;
338 p->unit1_grp = NULL;
339 p->unit2_grp = NULL;
340 p->next = NULL;
341
342 strcpy(p->boundary_id, boundary_id);
343 if (HECMW_couple_ctrl_get_couple_id(boundary_id, p->couple_id,
344 HECMW_NAME_LEN + 1) == NULL)
345 goto error;
346 ;
348 p->unit1_id, HECMW_NAME_LEN + 1) == NULL)
349 goto error;
351 p->unit2_id, HECMW_NAME_LEN + 1) == NULL)
352 goto error;
353
354 if (HECMW_couple_ctrl_get_type(p->couple_id, &p->couple_type) !=
356 goto error;
357 if (HECMW_couple_ctrl_get_direction(boundary_id, &p->direction) !=
359 goto error;
360 if (HECMW_couple_ctrl_get_tolerance(boundary_id, &p->tolerance) !=
362 goto error;
363 if (HECMW_couple_ctrl_get_bbcoef(boundary_id, &p->bbcoef) != HECMW_SUCCESS)
364 goto error;
365 if (HECMW_couple_ctrl_get_bgcoef(boundary_id, &p->bgcoef) != HECMW_SUCCESS)
366 goto error;
367
368 p->unit1_grp = HECMW_couple_ctrl_get_group(boundary_id, HECMW_COUPLE_UNIT1);
369 if (p->unit1_grp == NULL) goto error;
370 p->unit2_grp = HECMW_couple_ctrl_get_group(boundary_id, HECMW_COUPLE_UNIT2);
371 if (p->unit2_grp == NULL) goto error;
372 }
373
374 return HECMW_SUCCESS;
375
376error:
377 free_couple_info();
378 return HECMW_ERROR;
379}
380
381/*------------------------------------------------------------------------------------------------*/
382
383static int set_couple_type(int *couple_type) {
384 struct couple_info *p;
385 int is_specified_mxn = 0;
386 int is_specified_maxmn = 0;
387 int is_specified_manual = 0;
388
389 for (p = couple_root.next; p; p = p->next) {
390 if (p->couple_type == HECMW_COUPLE_TYPE_MXN) {
391 is_specified_mxn = 1;
392 } else if (p->couple_type == HECMW_COUPLE_TYPE_MAXMN) {
393 is_specified_maxmn = 1;
394 } else if (p->couple_type == HECMW_COUPLE_TYPE_MANUAL) {
395 is_specified_manual = 1;
396 } else {
398 return HECMW_ERROR;
399 }
400 }
401
402 if (is_specified_mxn + is_specified_maxmn + is_specified_manual != 1) {
404 return HECMW_ERROR;
405 }
406
407 if (is_specified_mxn) {
408 *couple_type = HECMW_COUPLE_TYPE_MXN;
409 } else if (is_specified_maxmn) {
410 *couple_type = HECMW_COUPLE_TYPE_MAXMN;
411 } else if (is_specified_manual) {
412 *couple_type = HECMW_COUPLE_TYPE_MANUAL;
413 } else {
414 HECMW_assert(0);
415 }
416
417 return HECMW_SUCCESS;
418}
419
420static int check_intracomm_psize_mxn(void) {
421 struct hecmw_couple_ctrl_proc *proc;
422 struct intracomm_info *p;
423 int psize_sum = 0;
424
425 for (p = intracomm_root.next; p; p = p->next) {
426 proc = HECMW_couple_ctrl_get_proc(p->unit_id);
427 if (proc == NULL) return HECMW_ERROR;
428
429 psize_sum += proc->n_proc;
430
432 }
433
434 if (psize_sum != HECMW_comm_get_size()) {
435 HECMW_set_error(HECMWCPL_E_UNMATCH_PSIZE, "Total number of processes is %d",
436 psize_sum);
437 return HECMW_ERROR;
438 }
439
440 return HECMW_SUCCESS;
441}
442
443static int check_intracomm_psize_maxmn(void) {
444 struct hecmw_couple_ctrl_proc *proc;
445 struct intracomm_info *p;
446 int psize_max = 0;
447
448 for (p = intracomm_root.next; p; p = p->next) {
449 proc = HECMW_couple_ctrl_get_proc(p->unit_id);
450 if (proc == NULL) return HECMW_ERROR;
451
452 if (proc->n_proc > psize_max) psize_max = proc->n_proc;
453
455 }
456
457 if (psize_max != HECMW_comm_get_size()) {
458 HECMW_set_error(HECMWCPL_E_UNMATCH_PSIZE, "Total number of processes is %d",
459 psize_max);
460 return HECMW_ERROR;
461 }
462
463 return HECMW_SUCCESS;
464}
465
466static int check_intracomm_psize_manual(void) {
467 struct hecmw_couple_ctrl_proc *proc;
468 struct intracomm_info *p;
469 int *mask = NULL;
470 int psize_sum = 0, psize_max = 0;
471 int rank, n, i;
472
473 for (p = intracomm_root.next; p; p = p->next) {
474 proc = HECMW_couple_ctrl_get_proc(p->unit_id);
475 if (proc == NULL) return HECMW_ERROR;
476
477 psize_sum += proc->n_proc;
478
480 }
481
482 /* masking */
483 mask = (int *)HECMW_malloc(sizeof(int) * psize_sum);
484 if (mask == NULL) {
485 HECMW_set_error(errno, "");
486 return HECMW_ERROR;
487 }
488 for (i = 0; i < psize_sum; i++) {
489 mask[i] = HECMW_COUPLE_FALSE;
490 }
491 for (p = intracomm_root.next; p; p = p->next) {
492 proc = HECMW_couple_ctrl_get_proc(p->unit_id);
493 if (proc == NULL) return HECMW_ERROR;
494
495 for (i = 0; i < proc->n_proc; i++) {
496 rank = proc->ranks[i];
497 if (rank < 0) {
499 "specified rank number is too small (%d)", rank);
501 goto error;
502 }
503 if (rank >= psize_sum) {
505 "specified rank number is too large (%d)", rank);
507 goto error;
508 }
509 mask[rank]++;
510 }
512 }
513
514 for (i = 0; i < psize_sum; i++) {
515 if (mask[i]) psize_max = i;
516 }
517 for (n = 0, i = 0; i <= psize_max; i++) {
518 if (!mask[i]) {
520 "Process No. %d is not used");
521 goto error;
522 }
523 n++;
524 }
525 if (n != HECMW_comm_get_size()) {
526 HECMW_set_error(HECMWCPL_E_UNMATCH_PSIZE, "Total number of processes is %d",
527 n);
528 }
529
530 HECMW_free(mask);
531 return HECMW_SUCCESS;
532
533error:
534 HECMW_free(mask);
535 return HECMW_ERROR;
536}
537
538static int check_intracomm_psize(int couple_type) {
539 if (couple_type == HECMW_COUPLE_TYPE_MXN) {
540 if (check_intracomm_psize_mxn() != HECMW_SUCCESS) return HECMW_ERROR;
541 } else if (couple_type == HECMW_COUPLE_TYPE_MAXMN) {
542 if (check_intracomm_psize_maxmn() != HECMW_SUCCESS) return HECMW_ERROR;
543 } else if (couple_type == HECMW_COUPLE_TYPE_MANUAL) {
544 if (check_intracomm_psize_manual() != HECMW_SUCCESS) return HECMW_ERROR;
545 } else {
546 HECMW_assert(0);
547 }
548
549 return HECMW_SUCCESS;
550}
551
552static int set_intracomm_psize(void) {
553 struct hecmw_couple_ctrl_proc *proc;
554 struct intracomm_info *p;
555
556 for (p = intracomm_root.next; p; p = p->next) {
557 proc = HECMW_couple_ctrl_get_proc(p->unit_id);
558 if (proc == NULL) return HECMW_ERROR;
559
560 HECMW_assert(p->comm);
561 p->comm->psize = proc->n_proc;
562
564 }
565
566 return HECMW_SUCCESS;
567}
568
569static int set_intracomm_ranks_mxn(void) {
570 struct intracomm_info *p;
571 int n = 0;
572 int i;
573
574 for (p = intracomm_root.next; p; p = p->next) {
575 p->comm->ranks = (int *)HECMW_calloc(p->comm->psize, sizeof(int));
576 if (p->comm->ranks == NULL) {
577 HECMW_set_error(errno, "");
578 free_intracomm_info();
579 return HECMW_ERROR;
580 }
581 for (i = 0; i < p->comm->psize; i++) {
582 p->comm->ranks[i] = n;
583 n++;
584 }
585 }
586
587 return HECMW_SUCCESS;
588}
589
590static int set_intracomm_ranks_maxmn(void) {
591 struct intracomm_info *p;
592 int i;
593
594 for (p = intracomm_root.next; p; p = p->next) {
595 p->comm->ranks = (int *)HECMW_calloc(p->comm->psize, sizeof(int));
596 if (p->comm->ranks == NULL) {
597 HECMW_set_error(errno, "");
598 free_intracomm_info();
599 return HECMW_ERROR;
600 }
601 for (i = 0; i < p->comm->psize; i++) {
602 p->comm->ranks[i] = i;
603 }
604 }
605
606 return HECMW_SUCCESS;
607}
608
609static int set_intracomm_ranks_manual(void) {
610 struct hecmw_couple_ctrl_proc *proc;
611 struct intracomm_info *p;
612 int i;
613
614 for (p = intracomm_root.next; p; p = p->next) {
615 proc = HECMW_couple_ctrl_get_proc(p->unit_id);
616 if (proc == NULL) return HECMW_ERROR;
617
618 p->comm->ranks = (int *)HECMW_calloc(p->comm->psize, sizeof(int));
619 if (p->comm->ranks == NULL) {
620 HECMW_set_error(errno, "");
622 free_intracomm_info();
623 return HECMW_ERROR;
624 }
625 for (i = 0; i < p->comm->psize; i++) {
626 p->comm->ranks[i] = proc->ranks[i];
627 }
628
630 }
631
632 return HECMW_SUCCESS;
633}
634
635static int set_intracomm_ranks(int couple_type) {
636 if (couple_type == HECMW_COUPLE_TYPE_MXN) {
637 if (set_intracomm_ranks_mxn() != HECMW_SUCCESS) return HECMW_ERROR;
638 } else if (couple_type == HECMW_COUPLE_TYPE_MAXMN) {
639 if (set_intracomm_ranks_maxmn() != HECMW_SUCCESS) return HECMW_ERROR;
640 } else if (couple_type == HECMW_COUPLE_TYPE_MANUAL) {
641 if (set_intracomm_ranks_manual() != HECMW_SUCCESS) return HECMW_ERROR;
642 } else {
643 HECMW_assert(0);
644 }
645
646 return HECMW_SUCCESS;
647}
648
649/*------------------------------------------------------------------------------------------------*/
650
651static int set_intercomm_psize_mxn(void) {
652 struct intercomm_info *p;
653 struct intracomm_info *q1, *q2;
654
655 for (p = intercomm_root.next; p; p = p->next) {
656 q1 = get_intracomm_info(p->unit1_id);
657 if (q1 == NULL) return HECMW_ERROR;
658 q2 = get_intracomm_info(p->unit2_id);
659 if (q2 == NULL) return HECMW_ERROR;
660
661 p->comm->psize = q1->comm->psize + q2->comm->psize;
662 }
663
664 return HECMW_SUCCESS;
665}
666
667static int set_intercomm_psize_maxmn(void) {
668 struct intercomm_info *p;
669 struct intracomm_info *q1, *q2;
670
671 for (p = intercomm_root.next; p; p = p->next) {
672 q1 = get_intracomm_info(p->unit1_id);
673 if (q1 == NULL) return HECMW_ERROR;
674 q2 = get_intracomm_info(p->unit2_id);
675 if (q2 == NULL) return HECMW_ERROR;
676
677 if (q1->comm->psize >= q2->comm->psize) {
678 p->comm->psize = q1->comm->psize;
679 } else {
680 p->comm->psize = q2->comm->psize;
681 }
682 }
683
684 return HECMW_SUCCESS;
685}
686
687static int set_intercomm_psize_manual(void) {
688 struct intercomm_info *p;
689 struct intracomm_info *q1, *q2;
690 int *mask = NULL;
691 int global_psize, n, i;
692
693 global_psize = HECMW_comm_get_size();
694
695 mask = (int *)HECMW_malloc(sizeof(int) * global_psize);
696 if (mask == NULL) {
697 HECMW_set_error(errno, "");
698 return HECMW_ERROR;
699 }
700
701 for (p = intercomm_root.next; p; p = p->next) {
702 q1 = get_intracomm_info(p->unit1_id);
703 if (q1 == NULL) goto error;
704 q2 = get_intracomm_info(p->unit2_id);
705 if (q2 == NULL) goto error;
706
707 for (i = 0; i < global_psize; i++) {
708 mask[i] = HECMW_COUPLE_FALSE;
709 }
710 for (i = 0; i < q1->comm->psize; i++) {
711 mask[q1->comm->ranks[i]] = HECMW_COUPLE_TRUE;
712 }
713 for (i = 0; i < q2->comm->psize; i++) {
714 mask[q2->comm->ranks[i]] = HECMW_COUPLE_TRUE;
715 }
716 for (n = 0, i = 0; i < global_psize; i++) {
717 if (mask[i] == HECMW_COUPLE_TRUE) n++;
718 }
719
720 p->comm->psize = n;
721 }
722
723 HECMW_free(mask);
724 return HECMW_SUCCESS;
725
726error:
727 HECMW_free(mask);
728 return HECMW_ERROR;
729}
730
731static int set_intercomm_psize(int couple_type) {
732 if (couple_type == HECMW_COUPLE_TYPE_MXN) {
733 if (set_intercomm_psize_mxn() != HECMW_SUCCESS) return HECMW_ERROR;
734 } else if (couple_type == HECMW_COUPLE_TYPE_MAXMN) {
735 if (set_intercomm_psize_maxmn() != HECMW_SUCCESS) return HECMW_ERROR;
736 } else if (couple_type == HECMW_COUPLE_TYPE_MANUAL) {
737 if (set_intercomm_psize_manual() != HECMW_SUCCESS) return HECMW_ERROR;
738 } else {
740 return HECMW_ERROR;
741 }
742
743 return HECMW_SUCCESS;
744}
745
746/*------------------------------------------------------------------------------------------------*/
747
748static int set_intercomm_ranks_mxn(void) {
749 struct intercomm_info *p;
750 struct intracomm_info *q1, *q2;
751 int n, i;
752
753 for (p = intercomm_root.next; p; p = p->next) {
754 q1 = get_intracomm_info(p->unit1_id);
755 if (q1 == NULL) goto error;
756 q2 = get_intracomm_info(p->unit2_id);
757 if (q2 == NULL) goto error;
758
759 p->comm->ranks = (int *)HECMW_calloc(p->comm->psize, sizeof(int));
760 if (p->comm->ranks == NULL) {
761 HECMW_set_error(errno, "");
762 goto error;
763 }
764 HECMW_assert(p->comm->psize == q1->comm->psize + q2->comm->psize);
765 for (n = 0, i = 0; i < q1->comm->psize; i++, n++) {
766 p->comm->ranks[n] = q1->comm->ranks[i];
767 }
768 for (i = 0; i < q2->comm->psize; i++, n++) {
769 p->comm->ranks[n] = q2->comm->ranks[i];
770 }
771 }
772
773 return HECMW_SUCCESS;
774
775error:
776 free_couple_info();
777 return HECMW_ERROR;
778}
779
780static int set_intercomm_ranks_maxmn(void) {
781 struct intercomm_info *p;
782 struct intracomm_info *q1, *q2;
783 int i;
784
785 for (p = intercomm_root.next; p; p = p->next) {
786 q1 = get_intracomm_info(p->unit1_id);
787 if (q1 == NULL) goto error;
788 q2 = get_intracomm_info(p->unit2_id);
789 if (q2 == NULL) goto error;
790
791 p->comm->ranks = (int *)HECMW_calloc(p->comm->psize, sizeof(int));
792 if (p->comm->ranks == NULL) {
793 HECMW_set_error(errno, "");
794 goto error;
795 }
796 if (q1->comm->psize >= q2->comm->psize) {
797 HECMW_assert(p->comm->psize == q1->comm->psize);
798 for (i = 0; i < q1->comm->psize; i++) {
799 p->comm->ranks[i] = q1->comm->ranks[i];
800 }
801 } else {
802 HECMW_assert(p->comm->psize == q2->comm->psize);
803 for (i = 0; i < q2->comm->psize; i++) {
804 p->comm->ranks[i] = q2->comm->ranks[i];
805 }
806 }
807 }
808
809 return HECMW_SUCCESS;
810
811error:
812 free_couple_info();
813 return HECMW_ERROR;
814}
815
816static int set_intercomm_ranks_manual(void) {
817 struct intercomm_info *p;
818 struct intracomm_info *q1, *q2;
819 int *mask = NULL;
820 int global_psize, n, i;
821
822 global_psize = HECMW_comm_get_size();
823
824 mask = (int *)HECMW_malloc(sizeof(int) * global_psize);
825 if (mask == NULL) {
826 HECMW_set_error(errno, "");
827 goto error;
828 }
829
830 for (p = intercomm_root.next; p; p = p->next) {
831 q1 = get_intracomm_info(p->unit1_id);
832 if (q1 == NULL) goto error;
833 q2 = get_intracomm_info(p->unit2_id);
834 if (q2 == NULL) goto error;
835
836 p->comm->ranks = (int *)HECMW_calloc(p->comm->psize, sizeof(int));
837 if (p->comm->ranks == NULL) {
838 HECMW_set_error(errno, "");
839 goto error;
840 }
841
842 for (i = 0; i < global_psize; i++) {
843 mask[i] = HECMW_COUPLE_FALSE;
844 }
845 for (i = 0; i < q1->comm->psize; i++) {
846 mask[q1->comm->ranks[i]] = HECMW_COUPLE_TRUE;
847 }
848 for (i = 0; i < q2->comm->psize; i++) {
849 mask[q2->comm->ranks[i]] = HECMW_COUPLE_TRUE;
850 }
851 for (n = 0, i = 0; i < global_psize; i++) {
852 if (mask[i] == HECMW_COUPLE_TRUE) {
853 HECMW_assert(n <= p->comm->psize);
854 p->comm->ranks[n] = i;
855 n++;
856 }
857 }
858 }
859
860 HECMW_free(mask);
861 return HECMW_SUCCESS;
862
863error:
864 HECMW_free(mask);
865 free_couple_info();
866 return HECMW_ERROR;
867}
868
869static int set_intercomm_ranks(int couple_type) {
870 if (couple_type == HECMW_COUPLE_TYPE_MXN) {
871 if (set_intercomm_ranks_mxn() != HECMW_SUCCESS) return HECMW_ERROR;
872 } else if (couple_type == HECMW_COUPLE_TYPE_MAXMN) {
873 if (set_intercomm_ranks_maxmn() != HECMW_SUCCESS) return HECMW_ERROR;
874 } else if (couple_type == HECMW_COUPLE_TYPE_MANUAL) {
875 if (set_intercomm_ranks_manual() != HECMW_SUCCESS) return HECMW_ERROR;
876 } else {
878 return HECMW_ERROR;
879 }
880
881 return HECMW_SUCCESS;
882}
883
884/*================================================================================================*/
885
886static int set_is_member(struct hecmw_couple_comm *comm) {
887 int global_rank, i;
888
889 global_rank = HECMW_comm_get_rank();
890 if (global_rank < 0) return HECMW_ERROR;
891
892 comm->is_member = 0;
893 for (i = 0; i < comm->psize; i++) {
894 if (comm->ranks[i] == global_rank) {
895 comm->is_member = 1;
896 break;
897 }
898 }
899
900 return HECMW_SUCCESS;
901}
902
903static int allgather_root(int *root) {
904 int *send_buf = NULL, *recv_buf = NULL;
905 HECMW_Comm global_comm;
906 int rtc, i;
907
908 global_comm = HECMW_comm_get_comm();
909
910 send_buf = (int *)HECMW_calloc(1, sizeof(int));
911 if (send_buf == NULL) {
912 HECMW_set_error(errno, "");
913 goto error;
914 }
915 recv_buf = (int *)HECMW_calloc(HECMW_comm_get_size(), sizeof(int));
916 if (recv_buf == NULL) {
917 HECMW_set_error(errno, "");
918 goto error;
919 }
920
921 send_buf[0] = *root;
922
923 rtc = HECMW_Allgather(send_buf, 1, HECMW_INT, recv_buf, 1, HECMW_INT,
924 global_comm);
925 if (rtc != HECMW_SUCCESS) goto error;
926
927 for (i = 0; i < HECMW_comm_get_size(); i++) {
928 if (recv_buf[i] >= 0) {
929 *root = i;
930 }
931 }
932
933 HECMW_free(send_buf);
934 HECMW_free(recv_buf);
935 return HECMW_SUCCESS;
936
937error:
938 HECMW_free(send_buf);
939 HECMW_free(recv_buf);
940 return HECMW_ERROR;
941}
942
943static int set_root(struct hecmw_couple_comm *comm) {
944 if (comm->is_member == 1) {
945 if (comm->rank == 0) {
946 comm->root = HECMW_comm_get_rank();
947 comm->is_root = 1;
948 }
949 }
950
951 if (allgather_root(&comm->root) != HECMW_SUCCESS) return HECMW_ERROR;
952
953 return HECMW_SUCCESS;
954}
955
956static int init_comm(struct hecmw_couple_comm *comm) {
957 int rtc, _psize;
958
959 rtc = HECMW_Group_incl(HECMW_comm_get_group(), comm->psize, comm->ranks,
960 &comm->group);
961 if (rtc != HECMW_SUCCESS) return HECMW_ERROR;
962
963 rtc = HECMW_Comm_create(HECMW_comm_get_comm(), comm->group, &comm->comm);
964 if (rtc != HECMW_SUCCESS) return HECMW_ERROR;
965
966 rtc = HECMW_Group_rank(comm->group, &comm->rank);
967 if (rtc != HECMW_SUCCESS) return HECMW_ERROR;
968
969 rtc = HECMW_Group_size(comm->group, &_psize);
970 if (rtc != HECMW_SUCCESS) return HECMW_ERROR;
971 HECMW_assert(_psize == comm->psize);
972
973 if (set_is_member(comm) != HECMW_SUCCESS) return HECMW_ERROR;
974 if (set_root(comm) != HECMW_SUCCESS) return HECMW_ERROR;
975
976 return HECMW_SUCCESS;
977}
978
979/*================================================================================================*/
980
981extern int HECMW_couple_comm_init(void) {
982 struct intracomm_info *p;
983 struct intercomm_info *q;
984 int couple_type;
985
987
988 if (init_intracomm_info() != HECMW_SUCCESS) goto error;
989 if (init_intercomm_info() != HECMW_SUCCESS) goto error;
990 if (init_couple_info() != HECMW_SUCCESS) goto error;
991
992 if (set_couple_type(&couple_type) != HECMW_SUCCESS) goto error;
993 if (check_intracomm_psize(couple_type) != HECMW_SUCCESS) goto error;
994
995 /* set intra-communication info. */
996 if (set_intracomm_psize() != HECMW_SUCCESS) goto error;
997 if (set_intracomm_ranks(couple_type) != HECMW_SUCCESS) goto error;
998
999 for (p = intracomm_root.next; p; p = p->next) {
1000 if (init_comm(p->comm) != HECMW_SUCCESS) goto error;
1001 }
1002
1003 /* set inter-communication info. */
1004 if (set_intercomm_psize(couple_type) != HECMW_SUCCESS) goto error;
1005 if (set_intercomm_ranks(couple_type) != HECMW_SUCCESS) goto error;
1006
1007 for (q = intercomm_root.next; q; q = q->next) {
1008 if (init_comm(q->comm) != HECMW_SUCCESS) goto error;
1009 }
1010
1011 return HECMW_SUCCESS;
1012
1013error:
1015 return HECMW_ERROR;
1016}
1017
1018/*================================================================================================*/
1019
1020extern char *HECMW_couple_get_unit_id(const char *boundary_id,
1021 int unit_specifier, char *buf,
1022 int bufsize) {
1023 struct couple_info *couple;
1024 struct hecmw_couple_info *couple_info;
1025 char *unit_id, *ret_buf;
1026 int len;
1027
1028 if (boundary_id == NULL) {
1030 "Invalid NULL pointer is found (boundary_id)");
1031 return NULL;
1032 }
1033
1034 if ((couple = get_couple_info(boundary_id)) == NULL) return NULL;
1035
1036 if (unit_specifier == HECMW_COUPLE_UNIT1) {
1037 unit_id = couple->unit1_id;
1038 } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1039 unit_id = couple->unit2_id;
1040 } else {
1042 return NULL;
1043 }
1044
1045 if (buf == NULL) {
1046 ret_buf = HECMW_strdup(unit_id);
1047 if (ret_buf == NULL) {
1048 HECMW_set_error(errno, "");
1049 return NULL;
1050 }
1051 } else {
1052 len = strlen(unit_id);
1053 if (bufsize <= len) {
1054 len = bufsize - 1;
1055 }
1056 strncpy(buf, unit_id, len);
1057 buf[len] = '\0';
1058 ret_buf = buf;
1059 }
1060
1061 return ret_buf;
1062}
1063
1064extern int HECMW_couple_is_member(const char *boundary_id) {
1065 struct couple_info *couple;
1066 struct intercomm_info *intercomm;
1067
1068 if (boundary_id == NULL) {
1070 "Invalid NULL pointer is found (boundary_id)");
1071 return -1;
1072 }
1073
1074 if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1075 if ((intercomm = get_intercomm_info(couple->couple_id)) == NULL) return -1;
1076
1077 if (intercomm->comm->is_member) return 1;
1078 return 0;
1079}
1080
1081extern int HECMW_couple_is_unit_member(const char *boundary_id,
1082 int unit_specifier) {
1083 struct couple_info *couple;
1084 struct intracomm_info *intracomm;
1085
1086 if (boundary_id == NULL) {
1088 "Invalid NULL pointer is found (boundary_id)");
1089 return -1;
1090 }
1091
1092 if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1093
1094 if (unit_specifier == HECMW_COUPLE_UNIT1) {
1095 if ((intracomm = get_intracomm_info(couple->unit1_id)) == NULL) return -1;
1096 } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1097 if ((intracomm = get_intracomm_info(couple->unit2_id)) == NULL) return -1;
1098 } else {
1100 return -1;
1101 }
1102
1103 if (intracomm->comm->is_member) return 1;
1104 return 0;
1105}
1106
1107extern int HECMW_couple_is_unit_member_u(const char *unit_id) {
1108 struct intracomm_info *intracomm;
1109
1110 if (unit_id == NULL) {
1112 "Invalid NULL pointer is found (unit_id)");
1113 return -1;
1114 }
1115
1116 if ((intracomm = get_intracomm_info(unit_id)) == NULL) return -1;
1117
1118 if (intracomm->comm->is_member) return 1;
1119 return 0;
1120}
1121
1122extern int HECMW_couple_is_root(const char *boundary_id) {
1123 struct couple_info *couple;
1124 struct intercomm_info *intercomm;
1125
1126 if (boundary_id == NULL) {
1128 "Invalid NULL pointer is found (boundary_id)");
1129 return -1;
1130 }
1131
1132 if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1133 if ((intercomm = get_intercomm_info(couple->couple_id)) == NULL) return -1;
1134
1135 if (intercomm->comm->is_root) return 1;
1136 return 0;
1137}
1138
1139extern int HECMW_couple_is_unit_root(const char *boundary_id,
1140 int unit_specifier) {
1141 struct couple_info *couple;
1142 struct intracomm_info *intracomm;
1143
1144 if (boundary_id == NULL) {
1146 "Invalid NULL pointer is found (boundary_id)");
1147 return -1;
1148 }
1149
1150 if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1151
1152 if (unit_specifier == HECMW_COUPLE_UNIT1) {
1153 if ((intracomm = get_intracomm_info(couple->unit1_id)) == NULL) return -1;
1154 } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1155 if ((intracomm = get_intracomm_info(couple->unit2_id)) == NULL) return -1;
1156 } else {
1158 return -1;
1159 }
1160
1161 if (intracomm->comm->is_root) return 1;
1162 return 0;
1163}
1164
1165extern int HECMW_couple_is_unit_root_u(const char *unit_id) {
1166 struct intracomm_info *intracomm;
1167
1168 if (unit_id == NULL) {
1170 "Invalid NULL pointer is found (unit_id)");
1171 return -1;
1172 }
1173
1174 if ((intracomm = get_intracomm_info(unit_id)) == NULL) return -1;
1175
1176 if (intracomm->comm->is_root) return 1;
1177 return 0;
1178}
1179
1180extern int HECMW_intercomm_get_size(const char *boundary_id) {
1181 struct couple_info *couple;
1182 struct intercomm_info *intercomm;
1183
1184 if (boundary_id == NULL) {
1186 "Invalid NULL pointer is found (boundary_id)");
1187 return -1;
1188 }
1189
1190 if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1191 if ((intercomm = get_intercomm_info(couple->couple_id)) == NULL) return -1;
1192
1193 return intercomm->comm->psize;
1194}
1195
1196extern int HECMW_intracomm_get_size(const char *boundary_id,
1197 int unit_specifier) {
1198 struct couple_info *couple;
1199 struct intracomm_info *intracomm;
1200
1201 if (boundary_id == NULL) {
1203 "Invalid NULL pointer is found (boundary_id)");
1204 return -1;
1205 }
1206
1207 if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1208
1209 if (unit_specifier == HECMW_COUPLE_UNIT1) {
1210 if ((intracomm = get_intracomm_info(couple->unit1_id)) == NULL) return -1;
1211 } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1212 if ((intracomm = get_intracomm_info(couple->unit2_id)) == NULL) return -1;
1213 } else {
1215 return -1;
1216 }
1217
1218 return intracomm->comm->psize;
1219}
1220
1221extern int HECMW_intracomm_get_size_u(const char *unit_id) {
1222 struct intracomm_info *intracomm;
1223
1224 if (unit_id == NULL) {
1226 "Invalid NULL pointer is found (unit_id)");
1227 return -1;
1228 }
1229
1230 if ((intracomm = get_intracomm_info(unit_id)) == NULL) return -1;
1231
1232 return intracomm->comm->psize;
1233}
1234
1235extern int HECMW_intercomm_get_rank(const char *boundary_id) {
1236 struct couple_info *couple;
1237 struct intercomm_info *intercomm;
1238
1239 if (boundary_id == NULL) {
1241 "Invalid NULL pointer is found (boundary_id)");
1242 return -1;
1243 }
1244
1245 if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1246 if ((intercomm = get_intercomm_info(couple->couple_id)) == NULL) return -1;
1247
1248 return intercomm->comm->rank;
1249}
1250
1251extern int HECMW_intracomm_get_rank(const char *boundary_id,
1252 int unit_specifier) {
1253 struct couple_info *couple;
1254 struct intracomm_info *intracomm;
1255
1256 if (boundary_id == NULL) {
1258 "Invalid NULL pointer is found (boundary_id)");
1259 return -1;
1260 }
1261
1262 if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1263
1264 if (unit_specifier == HECMW_COUPLE_UNIT1) {
1265 if ((intracomm = get_intracomm_info(couple->unit1_id)) == NULL) return -1;
1266 } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1267 if ((intracomm = get_intracomm_info(couple->unit2_id)) == NULL) return -1;
1268 } else {
1270 return -1;
1271 }
1272
1273 return intracomm->comm->rank;
1274}
1275
1276extern int HECMW_intracomm_get_rank_u(const char *unit_id) {
1277 struct intracomm_info *intracomm;
1278
1279 if (unit_id == NULL) {
1281 "Invalid NULL pointer is found (unit_id)");
1282 return -1;
1283 }
1284
1285 if ((intracomm = get_intracomm_info(unit_id)) == NULL) return -1;
1286
1287 return intracomm->comm->rank;
1288}
1289
1290extern HECMW_Comm HECMW_intercomm_get_comm(const char *boundary_id) {
1291 struct couple_info *couple;
1292 struct intercomm_info *intercomm;
1293
1294 if (boundary_id == NULL) {
1296 "Invalid NULL pointer is found (boundary_id)");
1297 return -1;
1298 }
1299
1300 if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1301 if ((intercomm = get_intercomm_info(couple->couple_id)) == NULL) return -1;
1302
1303 return intercomm->comm->comm;
1304}
1305
1306extern HECMW_Comm HECMW_intracomm_get_comm(const char *boundary_id,
1307 int unit_specifier) {
1308 struct couple_info *couple;
1309 struct intracomm_info *intracomm;
1310
1311 if (boundary_id == NULL) {
1313 "Invalid NULL pointer is found (boundary_id)");
1314 return -1;
1315 }
1316
1317 if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1318
1319 if (unit_specifier == HECMW_COUPLE_UNIT1) {
1320 if ((intracomm = get_intracomm_info(couple->unit1_id)) == NULL) return -1;
1321 } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1322 if ((intracomm = get_intracomm_info(couple->unit2_id)) == NULL) return -1;
1323 } else {
1325 return -1;
1326 }
1327
1328 return intracomm->comm->comm;
1329}
1330
1331extern HECMW_Comm HECMW_intracomm_get_comm_u(const char *unit_id) {
1332 struct intracomm_info *intracomm;
1333
1334 if (unit_id == NULL) {
1336 "Invalid NULL pointer is found (unit_id)");
1337 return -1;
1338 }
1339
1340 if ((intracomm = get_intracomm_info(unit_id)) == NULL) return -1;
1341
1342 return intracomm->comm->comm;
1343}
1344
1345extern HECMW_Group HECMW_intercomm_get_group(const char *boundary_id) {
1346 struct couple_info *couple;
1347 struct intercomm_info *intercomm;
1348
1349 if (boundary_id == NULL) {
1351 "Invalid NULL pointer is found (boundary_id)");
1352 return -1;
1353 }
1354
1355 if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1356 if ((intercomm = get_intercomm_info(couple->couple_id)) == NULL) return -1;
1357
1358 return intercomm->comm->group;
1359}
1360
1361extern HECMW_Group HECMW_intracomm_get_group(const char *boundary_id,
1362 int unit_specifier) {
1363 struct couple_info *couple;
1364 struct intracomm_info *intracomm;
1365
1366 if (boundary_id == NULL) {
1368 "Invalid NULL pointer is found (boundary_id)");
1369 return -1;
1370 }
1371
1372 if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1373
1374 if (unit_specifier == HECMW_COUPLE_UNIT1) {
1375 if ((intracomm = get_intracomm_info(couple->unit1_id)) == NULL) return -1;
1376 } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1377 if ((intracomm = get_intracomm_info(couple->unit2_id)) == NULL) return -1;
1378 } else {
1380 return -1;
1381 }
1382
1383 return intracomm->comm->group;
1384}
1385
1386extern HECMW_Group HECMW_intracomm_get_group_u(const char *unit_id) {
1387 struct intracomm_info *intracomm;
1388
1389 if (unit_id == NULL) {
1391 "Invalid NULL pointer is found (unit_id)");
1392 return -1;
1393 }
1394
1395 if ((intracomm = get_intracomm_info(unit_id)) == NULL) return -1;
1396
1397 return intracomm->comm->group;
1398}
1399
1401 const char *boundary_id, int unit_specifier) {
1402 struct couple_info *couple = NULL;
1403 struct intracomm_info *intracomm = NULL;
1404 struct hecmw_couple_comm *comm;
1405 char *unit_id;
1406 int i;
1407
1408 if (boundary_id == NULL) {
1410 "Invalid NULL pointer is found (boundary_id)");
1411 return NULL;
1412 }
1413
1414 couple = get_couple_info(boundary_id);
1415 if (couple == NULL) return NULL;
1416
1417 if (unit_specifier == HECMW_COUPLE_UNIT1) {
1418 unit_id = couple->unit1_id;
1419 } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1420 unit_id = couple->unit2_id;
1421 } else {
1423 return NULL;
1424 }
1425
1426 intracomm = get_intracomm_info(unit_id);
1427 if (intracomm == NULL) return NULL;
1428
1429 comm = alloc_struct_comm();
1430 if (comm == NULL) return NULL;
1431
1432 comm->psize = intracomm->comm->psize;
1433 comm->rank = intracomm->comm->rank;
1434 comm->ranks = (int *)HECMW_calloc(comm->psize, sizeof(int));
1435 if (comm->ranks == NULL) {
1436 HECMW_set_error(errno, "");
1438 return NULL;
1439 }
1440 for (i = 0; i < comm->psize; i++) {
1441 comm->ranks[i] = intracomm->comm->ranks[i];
1442 }
1443 comm->comm = intracomm->comm->comm;
1444 comm->group = intracomm->comm->group;
1445 comm->root = intracomm->comm->root;
1446 comm->is_member = intracomm->comm->is_member;
1447 comm->is_root = intracomm->comm->is_root;
1448
1449 return comm;
1450}
1451
1453 const char *unit_id) {
1454 struct intracomm_info *intracomm = NULL;
1455 struct hecmw_couple_comm *comm;
1456 int i;
1457
1458 if (unit_id == NULL) {
1460 "Invalid NULL pointer is found (boundary_id)");
1461 return NULL;
1462 }
1463
1464 intracomm = get_intracomm_info(unit_id);
1465 if (intracomm == NULL) return NULL;
1466
1467 comm = alloc_struct_comm();
1468 if (comm == NULL) return NULL;
1469
1470 comm->psize = intracomm->comm->psize;
1471 comm->rank = intracomm->comm->rank;
1472 comm->ranks = (int *)HECMW_calloc(comm->psize, sizeof(int));
1473 if (comm->ranks == NULL) {
1474 HECMW_set_error(errno, "");
1476 return NULL;
1477 }
1478 for (i = 0; i < comm->psize; i++) {
1479 comm->ranks[i] = intracomm->comm->ranks[i];
1480 }
1481 comm->comm = intracomm->comm->comm;
1482 comm->group = intracomm->comm->group;
1483 comm->root = intracomm->comm->root;
1484 comm->is_member = intracomm->comm->is_member;
1485 comm->is_root = intracomm->comm->is_root;
1486
1487 return comm;
1488}
1489
1491 const char *boundary_id) {
1492 struct couple_info *couple;
1493 struct intercomm_info *intercomm;
1494 struct hecmw_couple_comm *comm;
1495 int i;
1496
1497 if (boundary_id == NULL) {
1499 "Invalid NULL pointer is found (boundary_id)");
1500 return NULL;
1501 }
1502
1503 couple = get_couple_info(boundary_id);
1504 if (couple == NULL) return NULL;
1505
1506 intercomm = get_intercomm_info(couple->couple_id);
1507 if (intercomm == NULL) return NULL;
1508
1509 comm = alloc_struct_comm();
1510 if (comm == NULL) return NULL;
1511
1512 comm->psize = intercomm->comm->psize;
1513 comm->rank = intercomm->comm->rank;
1514 comm->ranks = (int *)HECMW_calloc(comm->psize, sizeof(int));
1515 if (comm->ranks == NULL) {
1516 HECMW_set_error(errno, "");
1518 return NULL;
1519 }
1520 for (i = 0; i < comm->psize; i++) {
1521 comm->ranks[i] = intercomm->comm->ranks[i];
1522 }
1523 comm->comm = intercomm->comm->comm;
1524 comm->group = intercomm->comm->group;
1525 comm->root = intercomm->comm->root;
1526 comm->is_member = intercomm->comm->is_member;
1527 comm->is_root = intercomm->comm->is_root;
1528
1529 return comm;
1530}
int HECMW_Comm_create(HECMW_Comm comm, HECMW_Group group, HECMW_Comm *comm_out)
Definition: hecmw_comm.c:522
HECMW_Comm HECMW_comm_get_comm(void)
Definition: hecmw_comm.c:699
int HECMW_Group_size(HECMW_Group group, int *size)
Definition: hecmw_comm.c:560
int HECMW_comm_get_rank(void)
Definition: hecmw_comm.c:707
int HECMW_comm_get_size(void)
Definition: hecmw_comm.c:703
HECMW_Group HECMW_comm_get_group(void)
Definition: hecmw_comm.c:711
int HECMW_Group_rank(HECMW_Group group, int *rank)
Definition: hecmw_comm.c:541
int HECMW_Group_incl(HECMW_Group group, int n, int *ranks, HECMW_Group *newgroup)
Definition: hecmw_comm.c:484
int HECMW_Allgather(void *sendbuf, int sendcount, HECMW_Datatype sendtype, void *recvbuf, int recvcount, HECMW_Datatype recvtype, HECMW_Comm comm)
Definition: hecmw_comm.c:432
MPI_Group HECMW_Group
Definition: hecmw_config.h:32
#define HECMW_INT
Definition: hecmw_config.h:48
MPI_Comm HECMW_Comm
Definition: hecmw_config.h:30
#define HECMW_ERROR
Definition: hecmw_config.h:66
#define HECMW_SUCCESS
Definition: hecmw_config.h:64
#define HECMW_NAME_LEN
Definition: hecmw_config.h:70
int HECMW_couple_ctrl_get_type(const char *couple_id, int *couple_type)
struct hecmw_couple_ctrl_unit_ids * HECMW_couple_get_unit_ids(void)
void HECMW_couple_ctrl_free_proc(struct hecmw_couple_ctrl_proc *proc_info)
int HECMW_couple_ctrl_get_direction(const char *boundary_id, int *direction)
int HECMW_couple_ctrl_get_tolerance(const char *boundary_id, double *tolerance)
struct hecmw_couple_group * HECMW_couple_ctrl_get_group(const char *boundary_id, int unit_specifier)
struct hecmw_couple_ctrl_couple_ids * HECMW_couple_get_couple_ids(void)
int HECMW_couple_ctrl_get_bgcoef(const char *boundary_id, double *bgcoef)
void HECMW_couple_ctrl_free_group(struct hecmw_couple_group *grp_info)
struct hecmw_couple_ctrl_proc * HECMW_couple_ctrl_get_proc(const char *unit_id)
struct hecmw_couple_ctrl_boundary_ids * HECMW_couple_get_boundary_ids(void)
int HECMW_couple_ctrl_get_bbcoef(const char *boundary_id, double *bbcoef)
char * HECMW_couple_ctrl_get_couple_id(const char *boundary_id, char *buf, int bufsize)
int HECMW_couple_ctrl_get_n_boundary(void)
char * HECMW_couple_ctrl_get_unit_id(const char *couple_id, int unit_specifier, char *buf, int bufsize)
#define HECMWCPL_E_INVALID_UNITTYPE
#define HECMW_COUPLE_TRUE
#define HECMW_COUPLE_TYPE_UNDEF
#define HECMW_COUPLE_UNIT1
#define HECMWCPL_E_INVALID_CPLTYPE
#define HECMWCPL_E_MULTIPLE_CPLTYPE
#define HECMW_COUPLE_DIRECTION_UNDEF
#define HECMWCPL_E_INVALID_RANKS
#define HECMW_COUPLE_FALSE
#define HECMWCPL_E_DISCONTINUOUS_RANKS
#define HECMW_COUPLE_TYPE_MAXMN
#define HECMWCPL_E_INVALID_ARG
#define HECMW_COUPLE_TYPE_MXN
#define HECMWCPL_E_UNMATCH_PSIZE
#define HECMW_COUPLE_UNIT2
#define HECMW_COUPLE_TYPE_MANUAL
int HECMW_couple_is_member(const char *boundary_id)
void HECMW_couple_free_couple_info(void)
struct hecmw_couple_comm * HECMW_couple_get_intracomm_u(const char *unit_id)
int HECMW_intracomm_get_size(const char *boundary_id, int unit_specifier)
int HECMW_couple_is_unit_member(const char *boundary_id, int unit_specifier)
HECMW_Group HECMW_intercomm_get_group(const char *boundary_id)
int HECMW_intracomm_get_size_u(const char *unit_id)
int HECMW_couple_is_unit_root_u(const char *unit_id)
int HECMW_couple_is_unit_root(const char *boundary_id, int unit_specifier)
HECMW_Group HECMW_intracomm_get_group_u(const char *unit_id)
HECMW_Comm HECMW_intercomm_get_comm(const char *boundary_id)
HECMW_Comm HECMW_intracomm_get_comm_u(const char *unit_id)
struct hecmw_couple_comm * HECMW_couple_get_intercomm(const char *boundary_id)
int HECMW_intracomm_get_rank_u(const char *unit_id)
int HECMW_couple_is_root(const char *boundary_id)
int HECMW_couple_comm_init(void)
int HECMW_intercomm_get_size(const char *boundary_id)
int HECMW_intracomm_get_rank(const char *boundary_id, int unit_specifier)
int HECMW_intercomm_get_rank(const char *boundary_id)
struct hecmw_couple_comm * HECMW_couple_get_intracomm(const char *boundary_id, int unit_specifier)
HECMW_Group HECMW_intracomm_get_group(const char *boundary_id, int unit_specifier)
void HECMW_couple_free_comm(struct hecmw_couple_comm *comm)
int HECMW_couple_is_unit_member_u(const char *unit_id)
HECMW_Comm HECMW_intracomm_get_comm(const char *boundary_id, int unit_specifier)
char * HECMW_couple_get_unit_id(const char *boundary_id, int unit_specifier, char *buf, int bufsize)
int HECMW_set_error(int errorno, const char *fmt,...)
Definition: hecmw_error.c:37
#define NULL
#define HECMW_calloc(nmemb, size)
Definition: hecmw_malloc.h:21
#define HECMW_free(ptr)
Definition: hecmw_malloc.h:24
#define HECMW_strdup(s)
Definition: hecmw_malloc.h:23
#define HECMW_malloc(size)
Definition: hecmw_malloc.h:20
#define HECMW_assert(cond)
Definition: hecmw_util.h:40