FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
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"
20 #include "hecmw_couple_control.h"
21 #include "hecmw_couple_info.h"
22 
23 static 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 
33 static 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 
47 static 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 
75 static int is_initialized = 0;
76 
77 /*================================================================================================*/
78 
79 extern 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 
87 static 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 
109 static 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 
119 static 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 
129 static 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 
140 extern void HECMW_couple_free_couple_info(void) {
141  free_intracomm_info();
142  free_intercomm_info();
143  free_couple_info();
144 }
145 
146 /*------------------------------------------------------------------------------------------------*/
147 
148 static 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 
158 static 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 
168 static 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 
180 static 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  snprintf(p->unit_id, sizeof(p->unit_id), "%s", 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 
244 error:
245  HECMW_free(mask);
246  free_intracomm_info();
247  return HECMW_ERROR;
248 }
249 
250 static 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  snprintf(p->couple_id, sizeof(p->couple_id), "%s", couple_ids->ids[i]);
302  snprintf(p->unit1_id, sizeof(p->unit1_id), "%s", unit1_id);
303  snprintf(p->unit2_id, sizeof(p->unit2_id), "%s", 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 
313 error:
314  HECMW_free(mask);
315  free_intercomm_info();
316  return HECMW_ERROR;
317 }
318 
319 static 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  snprintf(p->boundary_id, sizeof(p->boundary_id), "%s", 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 
376 error:
377  free_couple_info();
378  return HECMW_ERROR;
379 }
380 
381 /*------------------------------------------------------------------------------------------------*/
382 
383 static 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 
420 static 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 
443 static 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 
466 static 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 
533 error:
534  HECMW_free(mask);
535  return HECMW_ERROR;
536 }
537 
538 static 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 
552 static 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 
569 static 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 
590 static 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 
609 static 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 
635 static 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 
651 static 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 
667 static 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 
687 static 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 
726 error:
727  HECMW_free(mask);
728  return HECMW_ERROR;
729 }
730 
731 static 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 
748 static 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 
775 error:
776  free_couple_info();
777  return HECMW_ERROR;
778 }
779 
780 static 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 
811 error:
812  free_couple_info();
813  return HECMW_ERROR;
814 }
815 
816 static 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 
863 error:
864  HECMW_free(mask);
865  free_couple_info();
866  return HECMW_ERROR;
867 }
868 
869 static 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 
886 static 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 
903 static 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 
937 error:
938  HECMW_free(send_buf);
939  HECMW_free(recv_buf);
940  return HECMW_ERROR;
941 }
942 
943 static 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 
956 static 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 
981 extern 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 
1013 error:
1015  return HECMW_ERROR;
1016 }
1017 
1018 /*================================================================================================*/
1019 
1020 extern 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 
1027  if (boundary_id == NULL) {
1029  "Invalid NULL pointer is found (boundary_id)");
1030  return NULL;
1031  }
1032 
1033  if ((couple = get_couple_info(boundary_id)) == NULL) return NULL;
1034 
1035  if (unit_specifier == HECMW_COUPLE_UNIT1) {
1036  unit_id = couple->unit1_id;
1037  } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1038  unit_id = couple->unit2_id;
1039  } else {
1041  return NULL;
1042  }
1043 
1044  if (buf == NULL) {
1045  ret_buf = HECMW_strdup(unit_id);
1046  if (ret_buf == NULL) {
1047  HECMW_set_error(errno, "");
1048  return NULL;
1049  }
1050  } else {
1051  snprintf(buf, bufsize, "%s", unit_id);
1052  ret_buf = buf;
1053  }
1054 
1055  return ret_buf;
1056 }
1057 
1058 extern int HECMW_couple_is_member(const char *boundary_id) {
1059  struct couple_info *couple;
1060  struct intercomm_info *intercomm;
1061 
1062  if (boundary_id == NULL) {
1064  "Invalid NULL pointer is found (boundary_id)");
1065  return -1;
1066  }
1067 
1068  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1069  if ((intercomm = get_intercomm_info(couple->couple_id)) == NULL) return -1;
1070 
1071  if (intercomm->comm->is_member) return 1;
1072  return 0;
1073 }
1074 
1075 extern int HECMW_couple_is_unit_member(const char *boundary_id,
1076  int unit_specifier) {
1077  struct couple_info *couple;
1078  struct intracomm_info *intracomm;
1079 
1080  if (boundary_id == NULL) {
1082  "Invalid NULL pointer is found (boundary_id)");
1083  return -1;
1084  }
1085 
1086  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1087 
1088  if (unit_specifier == HECMW_COUPLE_UNIT1) {
1089  if ((intracomm = get_intracomm_info(couple->unit1_id)) == NULL) return -1;
1090  } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1091  if ((intracomm = get_intracomm_info(couple->unit2_id)) == NULL) return -1;
1092  } else {
1094  return -1;
1095  }
1096 
1097  if (intracomm->comm->is_member) return 1;
1098  return 0;
1099 }
1100 
1101 extern int HECMW_couple_is_unit_member_u(const char *unit_id) {
1102  struct intracomm_info *intracomm;
1103 
1104  if (unit_id == NULL) {
1106  "Invalid NULL pointer is found (unit_id)");
1107  return -1;
1108  }
1109 
1110  if ((intracomm = get_intracomm_info(unit_id)) == NULL) return -1;
1111 
1112  if (intracomm->comm->is_member) return 1;
1113  return 0;
1114 }
1115 
1116 extern int HECMW_couple_is_root(const char *boundary_id) {
1117  struct couple_info *couple;
1118  struct intercomm_info *intercomm;
1119 
1120  if (boundary_id == NULL) {
1122  "Invalid NULL pointer is found (boundary_id)");
1123  return -1;
1124  }
1125 
1126  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1127  if ((intercomm = get_intercomm_info(couple->couple_id)) == NULL) return -1;
1128 
1129  if (intercomm->comm->is_root) return 1;
1130  return 0;
1131 }
1132 
1133 extern int HECMW_couple_is_unit_root(const char *boundary_id,
1134  int unit_specifier) {
1135  struct couple_info *couple;
1136  struct intracomm_info *intracomm;
1137 
1138  if (boundary_id == NULL) {
1140  "Invalid NULL pointer is found (boundary_id)");
1141  return -1;
1142  }
1143 
1144  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1145 
1146  if (unit_specifier == HECMW_COUPLE_UNIT1) {
1147  if ((intracomm = get_intracomm_info(couple->unit1_id)) == NULL) return -1;
1148  } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1149  if ((intracomm = get_intracomm_info(couple->unit2_id)) == NULL) return -1;
1150  } else {
1152  return -1;
1153  }
1154 
1155  if (intracomm->comm->is_root) return 1;
1156  return 0;
1157 }
1158 
1159 extern int HECMW_couple_is_unit_root_u(const char *unit_id) {
1160  struct intracomm_info *intracomm;
1161 
1162  if (unit_id == NULL) {
1164  "Invalid NULL pointer is found (unit_id)");
1165  return -1;
1166  }
1167 
1168  if ((intracomm = get_intracomm_info(unit_id)) == NULL) return -1;
1169 
1170  if (intracomm->comm->is_root) return 1;
1171  return 0;
1172 }
1173 
1174 extern int HECMW_intercomm_get_size(const char *boundary_id) {
1175  struct couple_info *couple;
1176  struct intercomm_info *intercomm;
1177 
1178  if (boundary_id == NULL) {
1180  "Invalid NULL pointer is found (boundary_id)");
1181  return -1;
1182  }
1183 
1184  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1185  if ((intercomm = get_intercomm_info(couple->couple_id)) == NULL) return -1;
1186 
1187  return intercomm->comm->psize;
1188 }
1189 
1190 extern int HECMW_intracomm_get_size(const char *boundary_id,
1191  int unit_specifier) {
1192  struct couple_info *couple;
1193  struct intracomm_info *intracomm;
1194 
1195  if (boundary_id == NULL) {
1197  "Invalid NULL pointer is found (boundary_id)");
1198  return -1;
1199  }
1200 
1201  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1202 
1203  if (unit_specifier == HECMW_COUPLE_UNIT1) {
1204  if ((intracomm = get_intracomm_info(couple->unit1_id)) == NULL) return -1;
1205  } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1206  if ((intracomm = get_intracomm_info(couple->unit2_id)) == NULL) return -1;
1207  } else {
1209  return -1;
1210  }
1211 
1212  return intracomm->comm->psize;
1213 }
1214 
1215 extern int HECMW_intracomm_get_size_u(const char *unit_id) {
1216  struct intracomm_info *intracomm;
1217 
1218  if (unit_id == NULL) {
1220  "Invalid NULL pointer is found (unit_id)");
1221  return -1;
1222  }
1223 
1224  if ((intracomm = get_intracomm_info(unit_id)) == NULL) return -1;
1225 
1226  return intracomm->comm->psize;
1227 }
1228 
1229 extern int HECMW_intercomm_get_rank(const char *boundary_id) {
1230  struct couple_info *couple;
1231  struct intercomm_info *intercomm;
1232 
1233  if (boundary_id == NULL) {
1235  "Invalid NULL pointer is found (boundary_id)");
1236  return -1;
1237  }
1238 
1239  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1240  if ((intercomm = get_intercomm_info(couple->couple_id)) == NULL) return -1;
1241 
1242  return intercomm->comm->rank;
1243 }
1244 
1245 extern int HECMW_intracomm_get_rank(const char *boundary_id,
1246  int unit_specifier) {
1247  struct couple_info *couple;
1248  struct intracomm_info *intracomm;
1249 
1250  if (boundary_id == NULL) {
1252  "Invalid NULL pointer is found (boundary_id)");
1253  return -1;
1254  }
1255 
1256  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1257 
1258  if (unit_specifier == HECMW_COUPLE_UNIT1) {
1259  if ((intracomm = get_intracomm_info(couple->unit1_id)) == NULL) return -1;
1260  } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1261  if ((intracomm = get_intracomm_info(couple->unit2_id)) == NULL) return -1;
1262  } else {
1264  return -1;
1265  }
1266 
1267  return intracomm->comm->rank;
1268 }
1269 
1270 extern int HECMW_intracomm_get_rank_u(const char *unit_id) {
1271  struct intracomm_info *intracomm;
1272 
1273  if (unit_id == NULL) {
1275  "Invalid NULL pointer is found (unit_id)");
1276  return -1;
1277  }
1278 
1279  if ((intracomm = get_intracomm_info(unit_id)) == NULL) return -1;
1280 
1281  return intracomm->comm->rank;
1282 }
1283 
1284 extern HECMW_Comm HECMW_intercomm_get_comm(const char *boundary_id) {
1285  struct couple_info *couple;
1286  struct intercomm_info *intercomm;
1287 
1288  if (boundary_id == NULL) {
1290  "Invalid NULL pointer is found (boundary_id)");
1291  return -1;
1292  }
1293 
1294  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1295  if ((intercomm = get_intercomm_info(couple->couple_id)) == NULL) return -1;
1296 
1297  return intercomm->comm->comm;
1298 }
1299 
1300 extern HECMW_Comm HECMW_intracomm_get_comm(const char *boundary_id,
1301  int unit_specifier) {
1302  struct couple_info *couple;
1303  struct intracomm_info *intracomm;
1304 
1305  if (boundary_id == NULL) {
1307  "Invalid NULL pointer is found (boundary_id)");
1308  return -1;
1309  }
1310 
1311  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1312 
1313  if (unit_specifier == HECMW_COUPLE_UNIT1) {
1314  if ((intracomm = get_intracomm_info(couple->unit1_id)) == NULL) return -1;
1315  } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1316  if ((intracomm = get_intracomm_info(couple->unit2_id)) == NULL) return -1;
1317  } else {
1319  return -1;
1320  }
1321 
1322  return intracomm->comm->comm;
1323 }
1324 
1325 extern HECMW_Comm HECMW_intracomm_get_comm_u(const char *unit_id) {
1326  struct intracomm_info *intracomm;
1327 
1328  if (unit_id == NULL) {
1330  "Invalid NULL pointer is found (unit_id)");
1331  return -1;
1332  }
1333 
1334  if ((intracomm = get_intracomm_info(unit_id)) == NULL) return -1;
1335 
1336  return intracomm->comm->comm;
1337 }
1338 
1339 extern HECMW_Group HECMW_intercomm_get_group(const char *boundary_id) {
1340  struct couple_info *couple;
1341  struct intercomm_info *intercomm;
1342 
1343  if (boundary_id == NULL) {
1345  "Invalid NULL pointer is found (boundary_id)");
1346  return -1;
1347  }
1348 
1349  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1350  if ((intercomm = get_intercomm_info(couple->couple_id)) == NULL) return -1;
1351 
1352  return intercomm->comm->group;
1353 }
1354 
1355 extern HECMW_Group HECMW_intracomm_get_group(const char *boundary_id,
1356  int unit_specifier) {
1357  struct couple_info *couple;
1358  struct intracomm_info *intracomm;
1359 
1360  if (boundary_id == NULL) {
1362  "Invalid NULL pointer is found (boundary_id)");
1363  return -1;
1364  }
1365 
1366  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1367 
1368  if (unit_specifier == HECMW_COUPLE_UNIT1) {
1369  if ((intracomm = get_intracomm_info(couple->unit1_id)) == NULL) return -1;
1370  } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1371  if ((intracomm = get_intracomm_info(couple->unit2_id)) == NULL) return -1;
1372  } else {
1374  return -1;
1375  }
1376 
1377  return intracomm->comm->group;
1378 }
1379 
1380 extern HECMW_Group HECMW_intracomm_get_group_u(const char *unit_id) {
1381  struct intracomm_info *intracomm;
1382 
1383  if (unit_id == NULL) {
1385  "Invalid NULL pointer is found (unit_id)");
1386  return -1;
1387  }
1388 
1389  if ((intracomm = get_intracomm_info(unit_id)) == NULL) return -1;
1390 
1391  return intracomm->comm->group;
1392 }
1393 
1395  const char *boundary_id, int unit_specifier) {
1396  struct couple_info *couple = NULL;
1397  struct intracomm_info *intracomm = NULL;
1398  struct hecmw_couple_comm *comm;
1399  char *unit_id;
1400  int i;
1401 
1402  if (boundary_id == NULL) {
1404  "Invalid NULL pointer is found (boundary_id)");
1405  return NULL;
1406  }
1407 
1408  couple = get_couple_info(boundary_id);
1409  if (couple == NULL) return NULL;
1410 
1411  if (unit_specifier == HECMW_COUPLE_UNIT1) {
1412  unit_id = couple->unit1_id;
1413  } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1414  unit_id = couple->unit2_id;
1415  } else {
1417  return NULL;
1418  }
1419 
1420  intracomm = get_intracomm_info(unit_id);
1421  if (intracomm == NULL) return NULL;
1422 
1423  comm = alloc_struct_comm();
1424  if (comm == NULL) return NULL;
1425 
1426  comm->psize = intracomm->comm->psize;
1427  comm->rank = intracomm->comm->rank;
1428  comm->ranks = (int *)HECMW_calloc(comm->psize, sizeof(int));
1429  if (comm->ranks == NULL) {
1430  HECMW_set_error(errno, "");
1432  return NULL;
1433  }
1434  for (i = 0; i < comm->psize; i++) {
1435  comm->ranks[i] = intracomm->comm->ranks[i];
1436  }
1437  comm->comm = intracomm->comm->comm;
1438  comm->group = intracomm->comm->group;
1439  comm->root = intracomm->comm->root;
1440  comm->is_member = intracomm->comm->is_member;
1441  comm->is_root = intracomm->comm->is_root;
1442 
1443  return comm;
1444 }
1445 
1447  const char *unit_id) {
1448  struct intracomm_info *intracomm = NULL;
1449  struct hecmw_couple_comm *comm;
1450  int i;
1451 
1452  if (unit_id == NULL) {
1454  "Invalid NULL pointer is found (boundary_id)");
1455  return NULL;
1456  }
1457 
1458  intracomm = get_intracomm_info(unit_id);
1459  if (intracomm == NULL) return NULL;
1460 
1461  comm = alloc_struct_comm();
1462  if (comm == NULL) return NULL;
1463 
1464  comm->psize = intracomm->comm->psize;
1465  comm->rank = intracomm->comm->rank;
1466  comm->ranks = (int *)HECMW_calloc(comm->psize, sizeof(int));
1467  if (comm->ranks == NULL) {
1468  HECMW_set_error(errno, "");
1470  return NULL;
1471  }
1472  for (i = 0; i < comm->psize; i++) {
1473  comm->ranks[i] = intracomm->comm->ranks[i];
1474  }
1475  comm->comm = intracomm->comm->comm;
1476  comm->group = intracomm->comm->group;
1477  comm->root = intracomm->comm->root;
1478  comm->is_member = intracomm->comm->is_member;
1479  comm->is_root = intracomm->comm->is_root;
1480 
1481  return comm;
1482 }
1483 
1485  const char *boundary_id) {
1486  struct couple_info *couple;
1487  struct intercomm_info *intercomm;
1488  struct hecmw_couple_comm *comm;
1489  int i;
1490 
1491  if (boundary_id == NULL) {
1493  "Invalid NULL pointer is found (boundary_id)");
1494  return NULL;
1495  }
1496 
1497  couple = get_couple_info(boundary_id);
1498  if (couple == NULL) return NULL;
1499 
1500  intercomm = get_intercomm_info(couple->couple_id);
1501  if (intercomm == NULL) return NULL;
1502 
1503  comm = alloc_struct_comm();
1504  if (comm == NULL) return NULL;
1505 
1506  comm->psize = intercomm->comm->psize;
1507  comm->rank = intercomm->comm->rank;
1508  comm->ranks = (int *)HECMW_calloc(comm->psize, sizeof(int));
1509  if (comm->ranks == NULL) {
1510  HECMW_set_error(errno, "");
1512  return NULL;
1513  }
1514  for (i = 0; i < comm->psize; i++) {
1515  comm->ranks[i] = intercomm->comm->ranks[i];
1516  }
1517  comm->comm = intercomm->comm->comm;
1518  comm->group = intercomm->comm->group;
1519  comm->root = intercomm->comm->root;
1520  comm->is_member = intercomm->comm->is_member;
1521  comm->is_root = intercomm->comm->is_root;
1522 
1523  return comm;
1524 }
int HECMW_Comm_create(HECMW_Comm comm, HECMW_Group group, HECMW_Comm *comm_out)
Definition: hecmw_comm.c:574
HECMW_Comm HECMW_comm_get_comm(void)
Definition: hecmw_comm.c:751
int HECMW_Group_size(HECMW_Group group, int *size)
Definition: hecmw_comm.c:612
int HECMW_comm_get_rank(void)
Definition: hecmw_comm.c:759
int HECMW_comm_get_size(void)
Definition: hecmw_comm.c:755
HECMW_Group HECMW_comm_get_group(void)
Definition: hecmw_comm.c:763
int HECMW_Group_rank(HECMW_Group group, int *rank)
Definition: hecmw_comm.c:593
int HECMW_Group_incl(HECMW_Group group, int n, int *ranks, HECMW_Group *newgroup)
Definition: hecmw_comm.c:536
int HECMW_Allgather(void *sendbuf, int sendcount, HECMW_Datatype sendtype, void *recvbuf, int recvcount, HECMW_Datatype recvtype, HECMW_Comm comm)
Definition: hecmw_comm.c:478
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:68
#define HECMW_SUCCESS
Definition: hecmw_config.h:66
#define HECMW_NAME_LEN
Definition: hecmw_config.h:72
int HECMW_couple_ctrl_get_type(const char *couple_id, int *couple_type)
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)
int HECMW_couple_ctrl_get_bgcoef(const char *boundary_id, double *bgcoef)
char * HECMW_couple_ctrl_get_couple_id(const char *boundary_id, char *buf, int bufsize)
char * HECMW_couple_ctrl_get_unit_id(const char *couple_id, int unit_specifier, char *buf, int bufsize)
void HECMW_couple_ctrl_free_group(struct hecmw_couple_group *grp_info)
struct hecmw_couple_ctrl_boundary_ids * HECMW_couple_get_boundary_ids(void)
struct hecmw_couple_ctrl_unit_ids * HECMW_couple_get_unit_ids(void)
struct hecmw_couple_ctrl_proc * HECMW_couple_ctrl_get_proc(const char *unit_id)
int HECMW_couple_ctrl_get_bbcoef(const char *boundary_id, double *bbcoef)
int HECMW_couple_ctrl_get_n_boundary(void)
struct hecmw_couple_ctrl_couple_ids * HECMW_couple_get_couple_ids(void)
#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
struct hecmw_couple_comm * HECMW_couple_get_intracomm_u(const char *unit_id)
int HECMW_couple_is_member(const char *boundary_id)
void HECMW_couple_free_couple_info(void)
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)
char * HECMW_couple_get_unit_id(const char *boundary_id, int unit_specifier, char *buf, int bufsize)
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)
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)
struct hecmw_couple_comm * HECMW_couple_get_intracomm(const char *boundary_id, int unit_specifier)
HECMW_Comm HECMW_intracomm_get_comm(const char *boundary_id, int unit_specifier)
struct hecmw_couple_comm * HECMW_couple_get_intercomm(const char *boundary_id)
int HECMW_set_error(int errorno, const char *fmt,...)
Definition: hecmw_error.c:33
#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