FrontISTR  5.7.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  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 
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  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 
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  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 
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  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 
1064 extern 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 
1081 extern 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 
1107 extern 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 
1122 extern 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 
1139 extern 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 
1165 extern 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 
1180 extern 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 
1196 extern 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 
1221 extern 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 
1235 extern 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 
1251 extern 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 
1276 extern 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 
1290 extern 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 
1306 extern 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 
1331 extern 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 
1345 extern 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 
1361 extern 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 
1386 extern 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 }
HECMW_couple_ctrl_get_group
struct hecmw_couple_group * HECMW_couple_ctrl_get_group(const char *boundary_id, int unit_specifier)
Definition: hecmw_couple_control.c:1894
hecmw_malloc.h
HECMW_couple_get_intracomm_u
struct hecmw_couple_comm * HECMW_couple_get_intracomm_u(const char *unit_id)
Definition: hecmw_couple_info.c:1452
HECMW_intracomm_get_group_u
HECMW_Group HECMW_intracomm_get_group_u(const char *unit_id)
Definition: hecmw_couple_info.c:1386
hecmw_couple_ctrl_unit_ids::n_unit
int n_unit
Definition: hecmw_couple_control.h:15
HECMW_Allgather
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
HECMW_couple_free_comm
void HECMW_couple_free_comm(struct hecmw_couple_comm *comm)
Definition: hecmw_couple_info.c:79
hecmw_couple_ctrl_unit_ids
Definition: hecmw_couple_control.h:11
hecmw_couple_ctrl_boundary_ids::ids
char ** ids
Definition: hecmw_couple_control.h:23
HECMWCPL_E_MULTIPLE_CPLTYPE
#define HECMWCPL_E_MULTIPLE_CPLTYPE
Definition: hecmw_couple_define.h:161
HECMW_intracomm_get_rank
int HECMW_intracomm_get_rank(const char *boundary_id, int unit_specifier)
Definition: hecmw_couple_info.c:1251
HECMW_couple_ctrl_get_bgcoef
int HECMW_couple_ctrl_get_bgcoef(const char *boundary_id, double *bgcoef)
Definition: hecmw_couple_control.c:1874
HECMW_couple_ctrl_get_tolerance
int HECMW_couple_ctrl_get_tolerance(const char *boundary_id, double *tolerance)
Definition: hecmw_couple_control.c:1834
HECMWCPL_E_DISCONTINUOUS_RANKS
#define HECMWCPL_E_DISCONTINUOUS_RANKS
Definition: hecmw_couple_define.h:157
HECMW_COUPLE_TYPE_MXN
#define HECMW_COUPLE_TYPE_MXN
Definition: hecmw_couple_define.h:15
hecmw_couple_comm::is_root
int is_root
Definition: hecmw_couple_struct.h:22
hecmw_couple_ctrl_proc
Definition: hecmw_couple_control.h:26
hecmw_couple_comm::root
int root
Definition: hecmw_couple_struct.h:21
HECMW_couple_ctrl_get_proc
struct hecmw_couple_ctrl_proc * HECMW_couple_ctrl_get_proc(const char *unit_id)
Definition: hecmw_couple_control.c:1752
HECMW_malloc
#define HECMW_malloc(size)
Definition: hecmw_malloc.h:20
HECMW_couple_get_unit_id
char * HECMW_couple_get_unit_id(const char *boundary_id, int unit_specifier, char *buf, int bufsize)
Definition: hecmw_couple_info.c:1020
HECMW_COUPLE_TYPE_MANUAL
#define HECMW_COUPLE_TYPE_MANUAL
Definition: hecmw_couple_define.h:19
HECMW_couple_is_unit_member
int HECMW_couple_is_unit_member(const char *boundary_id, int unit_specifier)
Definition: hecmw_couple_info.c:1081
HECMW_comm_get_size
int HECMW_comm_get_size(void)
Definition: hecmw_comm.c:703
HECMW_comm_get_comm
HECMW_Comm HECMW_comm_get_comm(void)
Definition: hecmw_comm.c:699
HECMW_couple_ctrl_get_n_boundary
int HECMW_couple_ctrl_get_n_boundary(void)
Definition: hecmw_couple_control.c:1555
HECMW_intercomm_get_comm
HECMW_Comm HECMW_intercomm_get_comm(const char *boundary_id)
Definition: hecmw_couple_info.c:1290
HECMW_intracomm_get_comm
HECMW_Comm HECMW_intracomm_get_comm(const char *boundary_id, int unit_specifier)
Definition: hecmw_couple_info.c:1306
HECMW_Group_size
int HECMW_Group_size(HECMW_Group group, int *size)
Definition: hecmw_comm.c:560
HECMW_couple_ctrl_free_proc
void HECMW_couple_ctrl_free_proc(struct hecmw_couple_ctrl_proc *proc_info)
Definition: hecmw_couple_control.c:285
HECMW_couple_is_member
int HECMW_couple_is_member(const char *boundary_id)
Definition: hecmw_couple_info.c:1064
HECMW_couple_is_unit_member_u
int HECMW_couple_is_unit_member_u(const char *unit_id)
Definition: hecmw_couple_info.c:1107
hecmw_comm.h
HECMWCPL_E_INVALID_UNITTYPE
#define HECMWCPL_E_INVALID_UNITTYPE
Definition: hecmw_couple_define.h:171
HECMW_COUPLE_UNIT1
#define HECMW_COUPLE_UNIT1
Definition: hecmw_couple_define.h:23
HECMW_Group_rank
int HECMW_Group_rank(HECMW_Group group, int *rank)
Definition: hecmw_comm.c:541
HECMW_couple_is_unit_root
int HECMW_couple_is_unit_root(const char *boundary_id, int unit_specifier)
Definition: hecmw_couple_info.c:1139
HECMW_COUPLE_TYPE_UNDEF
#define HECMW_COUPLE_TYPE_UNDEF
Definition: hecmw_couple_define.h:13
HECMW_couple_comm_init
int HECMW_couple_comm_init(void)
Definition: hecmw_couple_info.c:981
HECMW_couple_ctrl_get_unit_id
char * HECMW_couple_ctrl_get_unit_id(const char *couple_id, int unit_specifier, char *buf, int bufsize)
Definition: hecmw_couple_control.c:1669
hecmw_couple_ctrl_couple_ids::ids
char ** ids
Definition: hecmw_couple_control.h:18
hecmw_couple_ctrl_couple_ids::n_couple
int n_couple
Definition: hecmw_couple_control.h:17
HECMW_comm_get_rank
int HECMW_comm_get_rank(void)
Definition: hecmw_comm.c:707
HECMWCPL_E_INVALID_RANKS
#define HECMWCPL_E_INVALID_RANKS
Definition: hecmw_couple_define.h:155
HECMW_couple_get_intercomm
struct hecmw_couple_comm * HECMW_couple_get_intercomm(const char *boundary_id)
Definition: hecmw_couple_info.c:1490
hecmw_error.h
hecmw_couple_comm::group
HECMW_Group group
Definition: hecmw_couple_struct.h:20
hecmw_couple_ctrl_boundary_ids
Definition: hecmw_couple_control.h:21
HECMW_couple_get_boundary_ids
struct hecmw_couple_ctrl_boundary_ids * HECMW_couple_get_boundary_ids(void)
Definition: hecmw_couple_control.c:1631
HECMW_couple_ctrl_get_type
int HECMW_couple_ctrl_get_type(const char *couple_id, int *couple_type)
Definition: hecmw_couple_control.c:1796
HECMW_calloc
#define HECMW_calloc(nmemb, size)
Definition: hecmw_malloc.h:21
hecmw_struct.h
HECMW_couple_ctrl_free_group
void HECMW_couple_ctrl_free_group(struct hecmw_couple_group *grp_info)
Definition: hecmw_couple_control.c:294
HECMW_Comm_create
int HECMW_Comm_create(HECMW_Comm comm, HECMW_Group group, HECMW_Comm *comm_out)
Definition: hecmw_comm.c:522
HECMW_couple_ctrl_get_couple_id
char * HECMW_couple_ctrl_get_couple_id(const char *boundary_id, char *buf, int bufsize)
Definition: hecmw_couple_control.c:1715
hecmw_couple_comm::rank
int rank
Definition: hecmw_couple_struct.h:17
hecmw_couple_comm::ranks
int * ranks
Definition: hecmw_couple_struct.h:18
HECMW_NAME_LEN
#define HECMW_NAME_LEN
Definition: hecmw_config.h:70
hecmw_couple_control.h
hecmw_msgno.h
hecmw_couple_comm::is_member
int is_member
Definition: hecmw_couple_struct.h:23
hecmw_couple_comm
Definition: hecmw_couple_struct.h:12
HECMW_intracomm_get_group
HECMW_Group HECMW_intracomm_get_group(const char *boundary_id, int unit_specifier)
Definition: hecmw_couple_info.c:1361
HECMW_strdup
#define HECMW_strdup(s)
Definition: hecmw_malloc.h:23
HECMW_couple_get_unit_ids
struct hecmw_couple_ctrl_unit_ids * HECMW_couple_get_unit_ids(void)
Definition: hecmw_couple_control.c:1557
HECMW_ERROR
#define HECMW_ERROR
Definition: hecmw_config.h:66
hecmw_couple_info
Definition: hecmw_couple_init.h:17
HECMW_couple_is_unit_root_u
int HECMW_couple_is_unit_root_u(const char *unit_id)
Definition: hecmw_couple_info.c:1165
hecmw_couple_group
Definition: hecmw_couple_control.h:32
HECMW_intracomm_get_comm_u
HECMW_Comm HECMW_intracomm_get_comm_u(const char *unit_id)
Definition: hecmw_couple_info.c:1331
hecmw_couple_ctrl_couple_ids
Definition: hecmw_couple_control.h:16
hecmw_couple_comm::psize
int psize
Definition: hecmw_couple_struct.h:16
HECMW_intercomm_get_rank
int HECMW_intercomm_get_rank(const char *boundary_id)
Definition: hecmw_couple_info.c:1235
HECMW_intercomm_get_size
int HECMW_intercomm_get_size(const char *boundary_id)
Definition: hecmw_couple_info.c:1180
HECMW_couple_get_couple_ids
struct hecmw_couple_ctrl_couple_ids * HECMW_couple_get_couple_ids(void)
Definition: hecmw_couple_control.c:1594
hecmw_couple_struct.h
HECMW_couple_ctrl_get_direction
int HECMW_couple_ctrl_get_direction(const char *boundary_id, int *direction)
Definition: hecmw_couple_control.c:1814
HECMW_SUCCESS
#define HECMW_SUCCESS
Definition: hecmw_config.h:64
HECMW_COUPLE_FALSE
#define HECMW_COUPLE_FALSE
Definition: hecmw_couple_define.h:11
HECMW_COUPLE_DIRECTION_UNDEF
#define HECMW_COUPLE_DIRECTION_UNDEF
Definition: hecmw_couple_define.h:27
hecmw_couple_ctrl_boundary_ids::n_boundary
int n_boundary
Definition: hecmw_couple_control.h:22
HECMWCPL_E_UNMATCH_PSIZE
#define HECMWCPL_E_UNMATCH_PSIZE
Definition: hecmw_couple_define.h:153
HECMW_Comm
MPI_Comm HECMW_Comm
Definition: hecmw_config.h:30
hecmw_couple_info.h
HECMW_Group
MPI_Group HECMW_Group
Definition: hecmw_config.h:32
hecmw_couple_ctrl_unit_ids::ids
char ** ids
Definition: hecmw_couple_control.h:16
HECMW_intracomm_get_size
int HECMW_intracomm_get_size(const char *boundary_id, int unit_specifier)
Definition: hecmw_couple_info.c:1196
HECMW_comm_get_group
HECMW_Group HECMW_comm_get_group(void)
Definition: hecmw_comm.c:711
HECMW_INT
#define HECMW_INT
Definition: hecmw_config.h:48
hecmw_couple_ctrl_proc::n_proc
int n_proc
Definition: hecmw_couple_control.h:27
HECMW_intracomm_get_size_u
int HECMW_intracomm_get_size_u(const char *unit_id)
Definition: hecmw_couple_info.c:1221
HECMW_intracomm_get_rank_u
int HECMW_intracomm_get_rank_u(const char *unit_id)
Definition: hecmw_couple_info.c:1276
HECMW_set_error
int HECMW_set_error(int errorno, const char *fmt,...)
Definition: hecmw_error.c:37
HECMWCPL_E_INVALID_CPLTYPE
#define HECMWCPL_E_INVALID_CPLTYPE
Definition: hecmw_couple_define.h:159
HECMW_COUPLE_TYPE_MAXMN
#define HECMW_COUPLE_TYPE_MAXMN
Definition: hecmw_couple_define.h:17
HECMW_COUPLE_TRUE
#define HECMW_COUPLE_TRUE
Definition: hecmw_couple_define.h:9
NULL
#define NULL
Definition: hecmw_io_nastran.c:30
HECMWCPL_E_INVALID_ARG
#define HECMWCPL_E_INVALID_ARG
Definition: hecmw_couple_define.h:91
HECMW_free
#define HECMW_free(ptr)
Definition: hecmw_malloc.h:24
HECMW_assert
#define HECMW_assert(cond)
Definition: hecmw_util.h:40
hecmw_couple_comm::comm
HECMW_Comm comm
Definition: hecmw_couple_struct.h:19
HECMW_couple_free_couple_info
void HECMW_couple_free_couple_info(void)
Definition: hecmw_couple_info.c:140
HECMW_Group_incl
int HECMW_Group_incl(HECMW_Group group, int n, int *ranks, HECMW_Group *newgroup)
Definition: hecmw_comm.c:484
HECMW_couple_is_root
int HECMW_couple_is_root(const char *boundary_id)
Definition: hecmw_couple_info.c:1122
HECMW_couple_get_intracomm
struct hecmw_couple_comm * HECMW_couple_get_intracomm(const char *boundary_id, int unit_specifier)
Definition: hecmw_couple_info.c:1400
hecmw_couple_ctrl_proc::ranks
int * ranks
Definition: hecmw_couple_control.h:29
hecmw_couple_define.h
HECMW_couple_ctrl_get_bbcoef
int HECMW_couple_ctrl_get_bbcoef(const char *boundary_id, double *bbcoef)
Definition: hecmw_couple_control.c:1854
HECMW_COUPLE_UNIT2
#define HECMW_COUPLE_UNIT2
Definition: hecmw_couple_define.h:25
HECMW_intercomm_get_group
HECMW_Group HECMW_intercomm_get_group(const char *boundary_id)
Definition: hecmw_couple_info.c:1345