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  strncpy(p->unit_id, unit_ids->ids[i], HECMW_NAME_LEN);
234  p->unit_id[HECMW_NAME_LEN] = '\0';
235  p->comm = alloc_struct_comm();
236  if (p->comm == NULL) goto error;
237 
238  p->next = NULL;
239  }
240  }
241 
242  HECMW_free(mask);
243  return HECMW_SUCCESS;
244 
245 error:
246  HECMW_free(mask);
247  free_intracomm_info();
248  return HECMW_ERROR;
249 }
250 
251 static int init_intercomm_info(void) {
252  struct hecmw_couple_ctrl_couple_ids *couple_ids;
253  struct hecmw_couple_ctrl_boundary_ids *boundary_ids;
254  struct intercomm_info *p;
255  int *mask = NULL;
256  char *couple_id, unit1_id[HECMW_NAME_LEN + 1], unit2_id[HECMW_NAME_LEN + 1];
257  int i, j;
258 
259  if ((couple_ids = HECMW_couple_get_couple_ids()) == NULL) return HECMW_ERROR;
260  if ((boundary_ids = HECMW_couple_get_boundary_ids()) == NULL)
261  return HECMW_ERROR;
262 
263  /* masking */
264  mask = (int *)HECMW_malloc(sizeof(int) * couple_ids->n_couple);
265  if (mask == NULL) {
266  HECMW_set_error(errno, "");
267  goto error;
268  }
269  for (i = 0; i < couple_ids->n_couple; i++) {
270  mask[i] = HECMW_COUPLE_FALSE;
271  }
272  for (i = 0; i < boundary_ids->n_boundary; i++) {
273  couple_id = HECMW_couple_ctrl_get_couple_id(boundary_ids->ids[i], NULL, 0);
274  if (couple_id == NULL) goto error;
275 
276  for (j = 0; j < couple_ids->n_couple; j++) {
277  if (strcmp(couple_id, couple_ids->ids[j]) == 0) {
278  mask[j] = HECMW_COUPLE_TRUE;
279  }
280  }
281  }
282 
283  /* setting */
284  p = &intercomm_root;
285  for (i = 0; i < couple_ids->n_couple; i++) {
286  if (mask[i] == HECMW_COUPLE_TRUE) {
287  p->next =
288  (struct intercomm_info *)HECMW_malloc(sizeof(struct intercomm_info));
289  if (p->next == NULL) {
290  HECMW_set_error(errno, "");
291  goto error;
292  }
293  p = p->next;
294 
296  unit1_id, HECMW_NAME_LEN + 1) == NULL)
297  goto error;
299  unit2_id, HECMW_NAME_LEN + 1) == NULL)
300  goto error;
301 
302  strncpy(p->couple_id, couple_ids->ids[i], HECMW_NAME_LEN);
303  p->couple_id[HECMW_NAME_LEN] = '\0';
304  strncpy(p->unit1_id, unit1_id, HECMW_NAME_LEN);
305  p->unit1_id[HECMW_NAME_LEN] = '\0';
306  strncpy(p->unit2_id, unit2_id, HECMW_NAME_LEN);
307  p->unit2_id[HECMW_NAME_LEN] = '\0';
308  if ((p->comm = alloc_struct_comm()) == NULL) goto error;
309 
310  p->next = NULL;
311  }
312  }
313 
314  HECMW_free(mask);
315  return HECMW_SUCCESS;
316 
317 error:
318  HECMW_free(mask);
319  free_intercomm_info();
320  return HECMW_ERROR;
321 }
322 
323 static int init_couple_info(void) {
324  struct hecmw_couple_ctrl_boundary_ids *boundary_ids;
325  struct couple_info *p;
326  char *boundary_id, *unit1_id, *unit2_id;
327  int i;
328 
329  if ((boundary_ids = HECMW_couple_get_boundary_ids()) == NULL)
330  return HECMW_ERROR;
331 
332  p = &couple_root;
333  for (i = 0; i < boundary_ids->n_boundary; i++) {
334  boundary_id = boundary_ids->ids[i];
335 
336  p->next = (struct couple_info *)HECMW_malloc(sizeof(struct couple_info));
337  if (p->next == NULL) {
338  HECMW_set_error(errno, "");
339  goto error;
340  }
341  p = p->next;
342  p->unit1_grp = NULL;
343  p->unit2_grp = NULL;
344  p->next = NULL;
345 
346  strncpy(p->boundary_id, boundary_id, HECMW_NAME_LEN);
347  p->boundary_id[HECMW_NAME_LEN] = '\0';
348  if (HECMW_couple_ctrl_get_couple_id(boundary_id, p->couple_id,
349  HECMW_NAME_LEN + 1) == NULL)
350  goto error;
351  ;
353  p->unit1_id, HECMW_NAME_LEN + 1) == NULL)
354  goto error;
356  p->unit2_id, HECMW_NAME_LEN + 1) == NULL)
357  goto error;
358 
359  if (HECMW_couple_ctrl_get_type(p->couple_id, &p->couple_type) !=
361  goto error;
362  if (HECMW_couple_ctrl_get_direction(boundary_id, &p->direction) !=
364  goto error;
365  if (HECMW_couple_ctrl_get_tolerance(boundary_id, &p->tolerance) !=
367  goto error;
368  if (HECMW_couple_ctrl_get_bbcoef(boundary_id, &p->bbcoef) != HECMW_SUCCESS)
369  goto error;
370  if (HECMW_couple_ctrl_get_bgcoef(boundary_id, &p->bgcoef) != HECMW_SUCCESS)
371  goto error;
372 
373  p->unit1_grp = HECMW_couple_ctrl_get_group(boundary_id, HECMW_COUPLE_UNIT1);
374  if (p->unit1_grp == NULL) goto error;
375  p->unit2_grp = HECMW_couple_ctrl_get_group(boundary_id, HECMW_COUPLE_UNIT2);
376  if (p->unit2_grp == NULL) goto error;
377  }
378 
379  return HECMW_SUCCESS;
380 
381 error:
382  free_couple_info();
383  return HECMW_ERROR;
384 }
385 
386 /*------------------------------------------------------------------------------------------------*/
387 
388 static int set_couple_type(int *couple_type) {
389  struct couple_info *p;
390  int is_specified_mxn = 0;
391  int is_specified_maxmn = 0;
392  int is_specified_manual = 0;
393 
394  for (p = couple_root.next; p; p = p->next) {
395  if (p->couple_type == HECMW_COUPLE_TYPE_MXN) {
396  is_specified_mxn = 1;
397  } else if (p->couple_type == HECMW_COUPLE_TYPE_MAXMN) {
398  is_specified_maxmn = 1;
399  } else if (p->couple_type == HECMW_COUPLE_TYPE_MANUAL) {
400  is_specified_manual = 1;
401  } else {
403  return HECMW_ERROR;
404  }
405  }
406 
407  if (is_specified_mxn + is_specified_maxmn + is_specified_manual != 1) {
409  return HECMW_ERROR;
410  }
411 
412  if (is_specified_mxn) {
413  *couple_type = HECMW_COUPLE_TYPE_MXN;
414  } else if (is_specified_maxmn) {
415  *couple_type = HECMW_COUPLE_TYPE_MAXMN;
416  } else if (is_specified_manual) {
417  *couple_type = HECMW_COUPLE_TYPE_MANUAL;
418  } else {
419  HECMW_assert(0);
420  }
421 
422  return HECMW_SUCCESS;
423 }
424 
425 static int check_intracomm_psize_mxn(void) {
426  struct hecmw_couple_ctrl_proc *proc;
427  struct intracomm_info *p;
428  int psize_sum = 0;
429 
430  for (p = intracomm_root.next; p; p = p->next) {
431  proc = HECMW_couple_ctrl_get_proc(p->unit_id);
432  if (proc == NULL) return HECMW_ERROR;
433 
434  psize_sum += proc->n_proc;
435 
437  }
438 
439  if (psize_sum != HECMW_comm_get_size()) {
440  HECMW_set_error(HECMWCPL_E_UNMATCH_PSIZE, "Total number of processes is %d",
441  psize_sum);
442  return HECMW_ERROR;
443  }
444 
445  return HECMW_SUCCESS;
446 }
447 
448 static int check_intracomm_psize_maxmn(void) {
449  struct hecmw_couple_ctrl_proc *proc;
450  struct intracomm_info *p;
451  int psize_max = 0;
452 
453  for (p = intracomm_root.next; p; p = p->next) {
454  proc = HECMW_couple_ctrl_get_proc(p->unit_id);
455  if (proc == NULL) return HECMW_ERROR;
456 
457  if (proc->n_proc > psize_max) psize_max = proc->n_proc;
458 
460  }
461 
462  if (psize_max != HECMW_comm_get_size()) {
463  HECMW_set_error(HECMWCPL_E_UNMATCH_PSIZE, "Total number of processes is %d",
464  psize_max);
465  return HECMW_ERROR;
466  }
467 
468  return HECMW_SUCCESS;
469 }
470 
471 static int check_intracomm_psize_manual(void) {
472  struct hecmw_couple_ctrl_proc *proc;
473  struct intracomm_info *p;
474  int *mask = NULL;
475  int psize_sum = 0, psize_max = 0;
476  int rank, n, i;
477 
478  for (p = intracomm_root.next; p; p = p->next) {
479  proc = HECMW_couple_ctrl_get_proc(p->unit_id);
480  if (proc == NULL) return HECMW_ERROR;
481 
482  psize_sum += proc->n_proc;
483 
485  }
486 
487  /* masking */
488  mask = (int *)HECMW_malloc(sizeof(int) * psize_sum);
489  if (mask == NULL) {
490  HECMW_set_error(errno, "");
491  return HECMW_ERROR;
492  }
493  for (i = 0; i < psize_sum; i++) {
494  mask[i] = HECMW_COUPLE_FALSE;
495  }
496  for (p = intracomm_root.next; p; p = p->next) {
497  proc = HECMW_couple_ctrl_get_proc(p->unit_id);
498  if (proc == NULL) return HECMW_ERROR;
499 
500  for (i = 0; i < proc->n_proc; i++) {
501  rank = proc->ranks[i];
502  if (rank < 0) {
504  "specified rank number is too small (%d)", rank);
506  goto error;
507  }
508  if (rank >= psize_sum) {
510  "specified rank number is too large (%d)", rank);
512  goto error;
513  }
514  mask[rank]++;
515  }
517  }
518 
519  for (i = 0; i < psize_sum; i++) {
520  if (mask[i]) psize_max = i;
521  }
522  for (n = 0, i = 0; i <= psize_max; i++) {
523  if (!mask[i]) {
525  "Process No. %d is not used");
526  goto error;
527  }
528  n++;
529  }
530  if (n != HECMW_comm_get_size()) {
531  HECMW_set_error(HECMWCPL_E_UNMATCH_PSIZE, "Total number of processes is %d",
532  n);
533  }
534 
535  HECMW_free(mask);
536  return HECMW_SUCCESS;
537 
538 error:
539  HECMW_free(mask);
540  return HECMW_ERROR;
541 }
542 
543 static int check_intracomm_psize(int couple_type) {
544  if (couple_type == HECMW_COUPLE_TYPE_MXN) {
545  if (check_intracomm_psize_mxn() != HECMW_SUCCESS) return HECMW_ERROR;
546  } else if (couple_type == HECMW_COUPLE_TYPE_MAXMN) {
547  if (check_intracomm_psize_maxmn() != HECMW_SUCCESS) return HECMW_ERROR;
548  } else if (couple_type == HECMW_COUPLE_TYPE_MANUAL) {
549  if (check_intracomm_psize_manual() != HECMW_SUCCESS) return HECMW_ERROR;
550  } else {
551  HECMW_assert(0);
552  }
553 
554  return HECMW_SUCCESS;
555 }
556 
557 static int set_intracomm_psize(void) {
558  struct hecmw_couple_ctrl_proc *proc;
559  struct intracomm_info *p;
560 
561  for (p = intracomm_root.next; p; p = p->next) {
562  proc = HECMW_couple_ctrl_get_proc(p->unit_id);
563  if (proc == NULL) return HECMW_ERROR;
564 
565  HECMW_assert(p->comm);
566  p->comm->psize = proc->n_proc;
567 
569  }
570 
571  return HECMW_SUCCESS;
572 }
573 
574 static int set_intracomm_ranks_mxn(void) {
575  struct intracomm_info *p;
576  int n = 0;
577  int i;
578 
579  for (p = intracomm_root.next; p; p = p->next) {
580  p->comm->ranks = (int *)HECMW_calloc(p->comm->psize, sizeof(int));
581  if (p->comm->ranks == NULL) {
582  HECMW_set_error(errno, "");
583  free_intracomm_info();
584  return HECMW_ERROR;
585  }
586  for (i = 0; i < p->comm->psize; i++) {
587  p->comm->ranks[i] = n;
588  n++;
589  }
590  }
591 
592  return HECMW_SUCCESS;
593 }
594 
595 static int set_intracomm_ranks_maxmn(void) {
596  struct intracomm_info *p;
597  int i;
598 
599  for (p = intracomm_root.next; p; p = p->next) {
600  p->comm->ranks = (int *)HECMW_calloc(p->comm->psize, sizeof(int));
601  if (p->comm->ranks == NULL) {
602  HECMW_set_error(errno, "");
603  free_intracomm_info();
604  return HECMW_ERROR;
605  }
606  for (i = 0; i < p->comm->psize; i++) {
607  p->comm->ranks[i] = i;
608  }
609  }
610 
611  return HECMW_SUCCESS;
612 }
613 
614 static int set_intracomm_ranks_manual(void) {
615  struct hecmw_couple_ctrl_proc *proc;
616  struct intracomm_info *p;
617  int i;
618 
619  for (p = intracomm_root.next; p; p = p->next) {
620  proc = HECMW_couple_ctrl_get_proc(p->unit_id);
621  if (proc == NULL) return HECMW_ERROR;
622 
623  p->comm->ranks = (int *)HECMW_calloc(p->comm->psize, sizeof(int));
624  if (p->comm->ranks == NULL) {
625  HECMW_set_error(errno, "");
627  free_intracomm_info();
628  return HECMW_ERROR;
629  }
630  for (i = 0; i < p->comm->psize; i++) {
631  p->comm->ranks[i] = proc->ranks[i];
632  }
633 
635  }
636 
637  return HECMW_SUCCESS;
638 }
639 
640 static int set_intracomm_ranks(int couple_type) {
641  if (couple_type == HECMW_COUPLE_TYPE_MXN) {
642  if (set_intracomm_ranks_mxn() != HECMW_SUCCESS) return HECMW_ERROR;
643  } else if (couple_type == HECMW_COUPLE_TYPE_MAXMN) {
644  if (set_intracomm_ranks_maxmn() != HECMW_SUCCESS) return HECMW_ERROR;
645  } else if (couple_type == HECMW_COUPLE_TYPE_MANUAL) {
646  if (set_intracomm_ranks_manual() != HECMW_SUCCESS) return HECMW_ERROR;
647  } else {
648  HECMW_assert(0);
649  }
650 
651  return HECMW_SUCCESS;
652 }
653 
654 /*------------------------------------------------------------------------------------------------*/
655 
656 static int set_intercomm_psize_mxn(void) {
657  struct intercomm_info *p;
658  struct intracomm_info *q1, *q2;
659 
660  for (p = intercomm_root.next; p; p = p->next) {
661  q1 = get_intracomm_info(p->unit1_id);
662  if (q1 == NULL) return HECMW_ERROR;
663  q2 = get_intracomm_info(p->unit2_id);
664  if (q2 == NULL) return HECMW_ERROR;
665 
666  p->comm->psize = q1->comm->psize + q2->comm->psize;
667  }
668 
669  return HECMW_SUCCESS;
670 }
671 
672 static int set_intercomm_psize_maxmn(void) {
673  struct intercomm_info *p;
674  struct intracomm_info *q1, *q2;
675 
676  for (p = intercomm_root.next; p; p = p->next) {
677  q1 = get_intracomm_info(p->unit1_id);
678  if (q1 == NULL) return HECMW_ERROR;
679  q2 = get_intracomm_info(p->unit2_id);
680  if (q2 == NULL) return HECMW_ERROR;
681 
682  if (q1->comm->psize >= q2->comm->psize) {
683  p->comm->psize = q1->comm->psize;
684  } else {
685  p->comm->psize = q2->comm->psize;
686  }
687  }
688 
689  return HECMW_SUCCESS;
690 }
691 
692 static int set_intercomm_psize_manual(void) {
693  struct intercomm_info *p;
694  struct intracomm_info *q1, *q2;
695  int *mask = NULL;
696  int global_psize, n, i;
697 
698  global_psize = HECMW_comm_get_size();
699 
700  mask = (int *)HECMW_malloc(sizeof(int) * global_psize);
701  if (mask == NULL) {
702  HECMW_set_error(errno, "");
703  return HECMW_ERROR;
704  }
705 
706  for (p = intercomm_root.next; p; p = p->next) {
707  q1 = get_intracomm_info(p->unit1_id);
708  if (q1 == NULL) goto error;
709  q2 = get_intracomm_info(p->unit2_id);
710  if (q2 == NULL) goto error;
711 
712  for (i = 0; i < global_psize; i++) {
713  mask[i] = HECMW_COUPLE_FALSE;
714  }
715  for (i = 0; i < q1->comm->psize; i++) {
716  mask[q1->comm->ranks[i]] = HECMW_COUPLE_TRUE;
717  }
718  for (i = 0; i < q2->comm->psize; i++) {
719  mask[q2->comm->ranks[i]] = HECMW_COUPLE_TRUE;
720  }
721  for (n = 0, i = 0; i < global_psize; i++) {
722  if (mask[i] == HECMW_COUPLE_TRUE) n++;
723  }
724 
725  p->comm->psize = n;
726  }
727 
728  HECMW_free(mask);
729  return HECMW_SUCCESS;
730 
731 error:
732  HECMW_free(mask);
733  return HECMW_ERROR;
734 }
735 
736 static int set_intercomm_psize(int couple_type) {
737  if (couple_type == HECMW_COUPLE_TYPE_MXN) {
738  if (set_intercomm_psize_mxn() != HECMW_SUCCESS) return HECMW_ERROR;
739  } else if (couple_type == HECMW_COUPLE_TYPE_MAXMN) {
740  if (set_intercomm_psize_maxmn() != HECMW_SUCCESS) return HECMW_ERROR;
741  } else if (couple_type == HECMW_COUPLE_TYPE_MANUAL) {
742  if (set_intercomm_psize_manual() != HECMW_SUCCESS) return HECMW_ERROR;
743  } else {
745  return HECMW_ERROR;
746  }
747 
748  return HECMW_SUCCESS;
749 }
750 
751 /*------------------------------------------------------------------------------------------------*/
752 
753 static int set_intercomm_ranks_mxn(void) {
754  struct intercomm_info *p;
755  struct intracomm_info *q1, *q2;
756  int n, i;
757 
758  for (p = intercomm_root.next; p; p = p->next) {
759  q1 = get_intracomm_info(p->unit1_id);
760  if (q1 == NULL) goto error;
761  q2 = get_intracomm_info(p->unit2_id);
762  if (q2 == NULL) goto error;
763 
764  p->comm->ranks = (int *)HECMW_calloc(p->comm->psize, sizeof(int));
765  if (p->comm->ranks == NULL) {
766  HECMW_set_error(errno, "");
767  goto error;
768  }
769  HECMW_assert(p->comm->psize == q1->comm->psize + q2->comm->psize);
770  for (n = 0, i = 0; i < q1->comm->psize; i++, n++) {
771  p->comm->ranks[n] = q1->comm->ranks[i];
772  }
773  for (i = 0; i < q2->comm->psize; i++, n++) {
774  p->comm->ranks[n] = q2->comm->ranks[i];
775  }
776  }
777 
778  return HECMW_SUCCESS;
779 
780 error:
781  free_couple_info();
782  return HECMW_ERROR;
783 }
784 
785 static int set_intercomm_ranks_maxmn(void) {
786  struct intercomm_info *p;
787  struct intracomm_info *q1, *q2;
788  int i;
789 
790  for (p = intercomm_root.next; p; p = p->next) {
791  q1 = get_intracomm_info(p->unit1_id);
792  if (q1 == NULL) goto error;
793  q2 = get_intracomm_info(p->unit2_id);
794  if (q2 == NULL) goto error;
795 
796  p->comm->ranks = (int *)HECMW_calloc(p->comm->psize, sizeof(int));
797  if (p->comm->ranks == NULL) {
798  HECMW_set_error(errno, "");
799  goto error;
800  }
801  if (q1->comm->psize >= q2->comm->psize) {
802  HECMW_assert(p->comm->psize == q1->comm->psize);
803  for (i = 0; i < q1->comm->psize; i++) {
804  p->comm->ranks[i] = q1->comm->ranks[i];
805  }
806  } else {
807  HECMW_assert(p->comm->psize == q2->comm->psize);
808  for (i = 0; i < q2->comm->psize; i++) {
809  p->comm->ranks[i] = q2->comm->ranks[i];
810  }
811  }
812  }
813 
814  return HECMW_SUCCESS;
815 
816 error:
817  free_couple_info();
818  return HECMW_ERROR;
819 }
820 
821 static int set_intercomm_ranks_manual(void) {
822  struct intercomm_info *p;
823  struct intracomm_info *q1, *q2;
824  int *mask = NULL;
825  int global_psize, n, i;
826 
827  global_psize = HECMW_comm_get_size();
828 
829  mask = (int *)HECMW_malloc(sizeof(int) * global_psize);
830  if (mask == NULL) {
831  HECMW_set_error(errno, "");
832  goto error;
833  }
834 
835  for (p = intercomm_root.next; p; p = p->next) {
836  q1 = get_intracomm_info(p->unit1_id);
837  if (q1 == NULL) goto error;
838  q2 = get_intracomm_info(p->unit2_id);
839  if (q2 == NULL) goto error;
840 
841  p->comm->ranks = (int *)HECMW_calloc(p->comm->psize, sizeof(int));
842  if (p->comm->ranks == NULL) {
843  HECMW_set_error(errno, "");
844  goto error;
845  }
846 
847  for (i = 0; i < global_psize; i++) {
848  mask[i] = HECMW_COUPLE_FALSE;
849  }
850  for (i = 0; i < q1->comm->psize; i++) {
851  mask[q1->comm->ranks[i]] = HECMW_COUPLE_TRUE;
852  }
853  for (i = 0; i < q2->comm->psize; i++) {
854  mask[q2->comm->ranks[i]] = HECMW_COUPLE_TRUE;
855  }
856  for (n = 0, i = 0; i < global_psize; i++) {
857  if (mask[i] == HECMW_COUPLE_TRUE) {
858  HECMW_assert(n <= p->comm->psize);
859  p->comm->ranks[n] = i;
860  n++;
861  }
862  }
863  }
864 
865  HECMW_free(mask);
866  return HECMW_SUCCESS;
867 
868 error:
869  HECMW_free(mask);
870  free_couple_info();
871  return HECMW_ERROR;
872 }
873 
874 static int set_intercomm_ranks(int couple_type) {
875  if (couple_type == HECMW_COUPLE_TYPE_MXN) {
876  if (set_intercomm_ranks_mxn() != HECMW_SUCCESS) return HECMW_ERROR;
877  } else if (couple_type == HECMW_COUPLE_TYPE_MAXMN) {
878  if (set_intercomm_ranks_maxmn() != HECMW_SUCCESS) return HECMW_ERROR;
879  } else if (couple_type == HECMW_COUPLE_TYPE_MANUAL) {
880  if (set_intercomm_ranks_manual() != HECMW_SUCCESS) return HECMW_ERROR;
881  } else {
883  return HECMW_ERROR;
884  }
885 
886  return HECMW_SUCCESS;
887 }
888 
889 /*================================================================================================*/
890 
891 static int set_is_member(struct hecmw_couple_comm *comm) {
892  int global_rank, i;
893 
894  global_rank = HECMW_comm_get_rank();
895  if (global_rank < 0) return HECMW_ERROR;
896 
897  comm->is_member = 0;
898  for (i = 0; i < comm->psize; i++) {
899  if (comm->ranks[i] == global_rank) {
900  comm->is_member = 1;
901  break;
902  }
903  }
904 
905  return HECMW_SUCCESS;
906 }
907 
908 static int allgather_root(int *root) {
909  int *send_buf = NULL, *recv_buf = NULL;
910  HECMW_Comm global_comm;
911  int rtc, i;
912 
913  global_comm = HECMW_comm_get_comm();
914 
915  send_buf = (int *)HECMW_calloc(1, sizeof(int));
916  if (send_buf == NULL) {
917  HECMW_set_error(errno, "");
918  goto error;
919  }
920  recv_buf = (int *)HECMW_calloc(HECMW_comm_get_size(), sizeof(int));
921  if (recv_buf == NULL) {
922  HECMW_set_error(errno, "");
923  goto error;
924  }
925 
926  send_buf[0] = *root;
927 
928  rtc = HECMW_Allgather(send_buf, 1, HECMW_INT, recv_buf, 1, HECMW_INT,
929  global_comm);
930  if (rtc != HECMW_SUCCESS) goto error;
931 
932  for (i = 0; i < HECMW_comm_get_size(); i++) {
933  if (recv_buf[i] >= 0) {
934  *root = i;
935  }
936  }
937 
938  HECMW_free(send_buf);
939  HECMW_free(recv_buf);
940  return HECMW_SUCCESS;
941 
942 error:
943  HECMW_free(send_buf);
944  HECMW_free(recv_buf);
945  return HECMW_ERROR;
946 }
947 
948 static int set_root(struct hecmw_couple_comm *comm) {
949  if (comm->is_member == 1) {
950  if (comm->rank == 0) {
951  comm->root = HECMW_comm_get_rank();
952  comm->is_root = 1;
953  }
954  }
955 
956  if (allgather_root(&comm->root) != HECMW_SUCCESS) return HECMW_ERROR;
957 
958  return HECMW_SUCCESS;
959 }
960 
961 static int init_comm(struct hecmw_couple_comm *comm) {
962  int rtc, _psize;
963 
964  rtc = HECMW_Group_incl(HECMW_comm_get_group(), comm->psize, comm->ranks,
965  &comm->group);
966  if (rtc != HECMW_SUCCESS) return HECMW_ERROR;
967 
968  rtc = HECMW_Comm_create(HECMW_comm_get_comm(), comm->group, &comm->comm);
969  if (rtc != HECMW_SUCCESS) return HECMW_ERROR;
970 
971  rtc = HECMW_Group_rank(comm->group, &comm->rank);
972  if (rtc != HECMW_SUCCESS) return HECMW_ERROR;
973 
974  rtc = HECMW_Group_size(comm->group, &_psize);
975  if (rtc != HECMW_SUCCESS) return HECMW_ERROR;
976  HECMW_assert(_psize == comm->psize);
977 
978  if (set_is_member(comm) != HECMW_SUCCESS) return HECMW_ERROR;
979  if (set_root(comm) != HECMW_SUCCESS) return HECMW_ERROR;
980 
981  return HECMW_SUCCESS;
982 }
983 
984 /*================================================================================================*/
985 
986 extern int HECMW_couple_comm_init(void) {
987  struct intracomm_info *p;
988  struct intercomm_info *q;
989  int couple_type;
990 
992 
993  if (init_intracomm_info() != HECMW_SUCCESS) goto error;
994  if (init_intercomm_info() != HECMW_SUCCESS) goto error;
995  if (init_couple_info() != HECMW_SUCCESS) goto error;
996 
997  if (set_couple_type(&couple_type) != HECMW_SUCCESS) goto error;
998  if (check_intracomm_psize(couple_type) != HECMW_SUCCESS) goto error;
999 
1000  /* set intra-communication info. */
1001  if (set_intracomm_psize() != HECMW_SUCCESS) goto error;
1002  if (set_intracomm_ranks(couple_type) != HECMW_SUCCESS) goto error;
1003 
1004  for (p = intracomm_root.next; p; p = p->next) {
1005  if (init_comm(p->comm) != HECMW_SUCCESS) goto error;
1006  }
1007 
1008  /* set inter-communication info. */
1009  if (set_intercomm_psize(couple_type) != HECMW_SUCCESS) goto error;
1010  if (set_intercomm_ranks(couple_type) != HECMW_SUCCESS) goto error;
1011 
1012  for (q = intercomm_root.next; q; q = q->next) {
1013  if (init_comm(q->comm) != HECMW_SUCCESS) goto error;
1014  }
1015 
1016  return HECMW_SUCCESS;
1017 
1018 error:
1020  return HECMW_ERROR;
1021 }
1022 
1023 /*================================================================================================*/
1024 
1025 extern char *HECMW_couple_get_unit_id(const char *boundary_id,
1026  int unit_specifier, char *buf,
1027  int bufsize) {
1028  struct couple_info *couple;
1029  struct hecmw_couple_info *couple_info;
1030  char *unit_id, *ret_buf;
1031  int len;
1032 
1033  if (boundary_id == NULL) {
1035  "Invalid NULL pointer is found (boundary_id)");
1036  return NULL;
1037  }
1038 
1039  if ((couple = get_couple_info(boundary_id)) == NULL) return NULL;
1040 
1041  if (unit_specifier == HECMW_COUPLE_UNIT1) {
1042  unit_id = couple->unit1_id;
1043  } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1044  unit_id = couple->unit2_id;
1045  } else {
1047  return NULL;
1048  }
1049 
1050  if (buf == NULL) {
1051  ret_buf = HECMW_strdup(unit_id);
1052  if (ret_buf == NULL) {
1053  HECMW_set_error(errno, "");
1054  return NULL;
1055  }
1056  } else {
1057  len = strlen(unit_id);
1058  if (bufsize <= len) {
1059  len = bufsize - 1;
1060  }
1061  strncpy(buf, unit_id, len);
1062  buf[len] = '\0';
1063  ret_buf = buf;
1064  }
1065 
1066  return ret_buf;
1067 }
1068 
1069 extern int HECMW_couple_is_member(const char *boundary_id) {
1070  struct couple_info *couple;
1071  struct intercomm_info *intercomm;
1072 
1073  if (boundary_id == NULL) {
1075  "Invalid NULL pointer is found (boundary_id)");
1076  return -1;
1077  }
1078 
1079  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1080  if ((intercomm = get_intercomm_info(couple->couple_id)) == NULL) return -1;
1081 
1082  if (intercomm->comm->is_member) return 1;
1083  return 0;
1084 }
1085 
1086 extern int HECMW_couple_is_unit_member(const char *boundary_id,
1087  int unit_specifier) {
1088  struct couple_info *couple;
1089  struct intracomm_info *intracomm;
1090 
1091  if (boundary_id == NULL) {
1093  "Invalid NULL pointer is found (boundary_id)");
1094  return -1;
1095  }
1096 
1097  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1098 
1099  if (unit_specifier == HECMW_COUPLE_UNIT1) {
1100  if ((intracomm = get_intracomm_info(couple->unit1_id)) == NULL) return -1;
1101  } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1102  if ((intracomm = get_intracomm_info(couple->unit2_id)) == NULL) return -1;
1103  } else {
1105  return -1;
1106  }
1107 
1108  if (intracomm->comm->is_member) return 1;
1109  return 0;
1110 }
1111 
1112 extern int HECMW_couple_is_unit_member_u(const char *unit_id) {
1113  struct intracomm_info *intracomm;
1114 
1115  if (unit_id == NULL) {
1117  "Invalid NULL pointer is found (unit_id)");
1118  return -1;
1119  }
1120 
1121  if ((intracomm = get_intracomm_info(unit_id)) == NULL) return -1;
1122 
1123  if (intracomm->comm->is_member) return 1;
1124  return 0;
1125 }
1126 
1127 extern int HECMW_couple_is_root(const char *boundary_id) {
1128  struct couple_info *couple;
1129  struct intercomm_info *intercomm;
1130 
1131  if (boundary_id == NULL) {
1133  "Invalid NULL pointer is found (boundary_id)");
1134  return -1;
1135  }
1136 
1137  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1138  if ((intercomm = get_intercomm_info(couple->couple_id)) == NULL) return -1;
1139 
1140  if (intercomm->comm->is_root) return 1;
1141  return 0;
1142 }
1143 
1144 extern int HECMW_couple_is_unit_root(const char *boundary_id,
1145  int unit_specifier) {
1146  struct couple_info *couple;
1147  struct intracomm_info *intracomm;
1148 
1149  if (boundary_id == NULL) {
1151  "Invalid NULL pointer is found (boundary_id)");
1152  return -1;
1153  }
1154 
1155  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1156 
1157  if (unit_specifier == HECMW_COUPLE_UNIT1) {
1158  if ((intracomm = get_intracomm_info(couple->unit1_id)) == NULL) return -1;
1159  } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1160  if ((intracomm = get_intracomm_info(couple->unit2_id)) == NULL) return -1;
1161  } else {
1163  return -1;
1164  }
1165 
1166  if (intracomm->comm->is_root) return 1;
1167  return 0;
1168 }
1169 
1170 extern int HECMW_couple_is_unit_root_u(const char *unit_id) {
1171  struct intracomm_info *intracomm;
1172 
1173  if (unit_id == NULL) {
1175  "Invalid NULL pointer is found (unit_id)");
1176  return -1;
1177  }
1178 
1179  if ((intracomm = get_intracomm_info(unit_id)) == NULL) return -1;
1180 
1181  if (intracomm->comm->is_root) return 1;
1182  return 0;
1183 }
1184 
1185 extern int HECMW_intercomm_get_size(const char *boundary_id) {
1186  struct couple_info *couple;
1187  struct intercomm_info *intercomm;
1188 
1189  if (boundary_id == NULL) {
1191  "Invalid NULL pointer is found (boundary_id)");
1192  return -1;
1193  }
1194 
1195  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1196  if ((intercomm = get_intercomm_info(couple->couple_id)) == NULL) return -1;
1197 
1198  return intercomm->comm->psize;
1199 }
1200 
1201 extern int HECMW_intracomm_get_size(const char *boundary_id,
1202  int unit_specifier) {
1203  struct couple_info *couple;
1204  struct intracomm_info *intracomm;
1205 
1206  if (boundary_id == NULL) {
1208  "Invalid NULL pointer is found (boundary_id)");
1209  return -1;
1210  }
1211 
1212  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1213 
1214  if (unit_specifier == HECMW_COUPLE_UNIT1) {
1215  if ((intracomm = get_intracomm_info(couple->unit1_id)) == NULL) return -1;
1216  } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1217  if ((intracomm = get_intracomm_info(couple->unit2_id)) == NULL) return -1;
1218  } else {
1220  return -1;
1221  }
1222 
1223  return intracomm->comm->psize;
1224 }
1225 
1226 extern int HECMW_intracomm_get_size_u(const char *unit_id) {
1227  struct intracomm_info *intracomm;
1228 
1229  if (unit_id == NULL) {
1231  "Invalid NULL pointer is found (unit_id)");
1232  return -1;
1233  }
1234 
1235  if ((intracomm = get_intracomm_info(unit_id)) == NULL) return -1;
1236 
1237  return intracomm->comm->psize;
1238 }
1239 
1240 extern int HECMW_intercomm_get_rank(const char *boundary_id) {
1241  struct couple_info *couple;
1242  struct intercomm_info *intercomm;
1243 
1244  if (boundary_id == NULL) {
1246  "Invalid NULL pointer is found (boundary_id)");
1247  return -1;
1248  }
1249 
1250  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1251  if ((intercomm = get_intercomm_info(couple->couple_id)) == NULL) return -1;
1252 
1253  return intercomm->comm->rank;
1254 }
1255 
1256 extern int HECMW_intracomm_get_rank(const char *boundary_id,
1257  int unit_specifier) {
1258  struct couple_info *couple;
1259  struct intracomm_info *intracomm;
1260 
1261  if (boundary_id == NULL) {
1263  "Invalid NULL pointer is found (boundary_id)");
1264  return -1;
1265  }
1266 
1267  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1268 
1269  if (unit_specifier == HECMW_COUPLE_UNIT1) {
1270  if ((intracomm = get_intracomm_info(couple->unit1_id)) == NULL) return -1;
1271  } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1272  if ((intracomm = get_intracomm_info(couple->unit2_id)) == NULL) return -1;
1273  } else {
1275  return -1;
1276  }
1277 
1278  return intracomm->comm->rank;
1279 }
1280 
1281 extern int HECMW_intracomm_get_rank_u(const char *unit_id) {
1282  struct intracomm_info *intracomm;
1283 
1284  if (unit_id == NULL) {
1286  "Invalid NULL pointer is found (unit_id)");
1287  return -1;
1288  }
1289 
1290  if ((intracomm = get_intracomm_info(unit_id)) == NULL) return -1;
1291 
1292  return intracomm->comm->rank;
1293 }
1294 
1295 extern HECMW_Comm HECMW_intercomm_get_comm(const char *boundary_id) {
1296  struct couple_info *couple;
1297  struct intercomm_info *intercomm;
1298 
1299  if (boundary_id == NULL) {
1301  "Invalid NULL pointer is found (boundary_id)");
1302  return -1;
1303  }
1304 
1305  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1306  if ((intercomm = get_intercomm_info(couple->couple_id)) == NULL) return -1;
1307 
1308  return intercomm->comm->comm;
1309 }
1310 
1311 extern HECMW_Comm HECMW_intracomm_get_comm(const char *boundary_id,
1312  int unit_specifier) {
1313  struct couple_info *couple;
1314  struct intracomm_info *intracomm;
1315 
1316  if (boundary_id == NULL) {
1318  "Invalid NULL pointer is found (boundary_id)");
1319  return -1;
1320  }
1321 
1322  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1323 
1324  if (unit_specifier == HECMW_COUPLE_UNIT1) {
1325  if ((intracomm = get_intracomm_info(couple->unit1_id)) == NULL) return -1;
1326  } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1327  if ((intracomm = get_intracomm_info(couple->unit2_id)) == NULL) return -1;
1328  } else {
1330  return -1;
1331  }
1332 
1333  return intracomm->comm->comm;
1334 }
1335 
1336 extern HECMW_Comm HECMW_intracomm_get_comm_u(const char *unit_id) {
1337  struct intracomm_info *intracomm;
1338 
1339  if (unit_id == NULL) {
1341  "Invalid NULL pointer is found (unit_id)");
1342  return -1;
1343  }
1344 
1345  if ((intracomm = get_intracomm_info(unit_id)) == NULL) return -1;
1346 
1347  return intracomm->comm->comm;
1348 }
1349 
1350 extern HECMW_Group HECMW_intercomm_get_group(const char *boundary_id) {
1351  struct couple_info *couple;
1352  struct intercomm_info *intercomm;
1353 
1354  if (boundary_id == NULL) {
1356  "Invalid NULL pointer is found (boundary_id)");
1357  return -1;
1358  }
1359 
1360  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1361  if ((intercomm = get_intercomm_info(couple->couple_id)) == NULL) return -1;
1362 
1363  return intercomm->comm->group;
1364 }
1365 
1366 extern HECMW_Group HECMW_intracomm_get_group(const char *boundary_id,
1367  int unit_specifier) {
1368  struct couple_info *couple;
1369  struct intracomm_info *intracomm;
1370 
1371  if (boundary_id == NULL) {
1373  "Invalid NULL pointer is found (boundary_id)");
1374  return -1;
1375  }
1376 
1377  if ((couple = get_couple_info(boundary_id)) == NULL) return -1;
1378 
1379  if (unit_specifier == HECMW_COUPLE_UNIT1) {
1380  if ((intracomm = get_intracomm_info(couple->unit1_id)) == NULL) return -1;
1381  } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1382  if ((intracomm = get_intracomm_info(couple->unit2_id)) == NULL) return -1;
1383  } else {
1385  return -1;
1386  }
1387 
1388  return intracomm->comm->group;
1389 }
1390 
1391 extern HECMW_Group HECMW_intracomm_get_group_u(const char *unit_id) {
1392  struct intracomm_info *intracomm;
1393 
1394  if (unit_id == NULL) {
1396  "Invalid NULL pointer is found (unit_id)");
1397  return -1;
1398  }
1399 
1400  if ((intracomm = get_intracomm_info(unit_id)) == NULL) return -1;
1401 
1402  return intracomm->comm->group;
1403 }
1404 
1406  const char *boundary_id, int unit_specifier) {
1407  struct couple_info *couple = NULL;
1408  struct intracomm_info *intracomm = NULL;
1409  struct hecmw_couple_comm *comm;
1410  char *unit_id;
1411  int i;
1412 
1413  if (boundary_id == NULL) {
1415  "Invalid NULL pointer is found (boundary_id)");
1416  return NULL;
1417  }
1418 
1419  couple = get_couple_info(boundary_id);
1420  if (couple == NULL) return NULL;
1421 
1422  if (unit_specifier == HECMW_COUPLE_UNIT1) {
1423  unit_id = couple->unit1_id;
1424  } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1425  unit_id = couple->unit2_id;
1426  } else {
1428  return NULL;
1429  }
1430 
1431  intracomm = get_intracomm_info(unit_id);
1432  if (intracomm == NULL) return NULL;
1433 
1434  comm = alloc_struct_comm();
1435  if (comm == NULL) return NULL;
1436 
1437  comm->psize = intracomm->comm->psize;
1438  comm->rank = intracomm->comm->rank;
1439  comm->ranks = (int *)HECMW_calloc(comm->psize, sizeof(int));
1440  if (comm->ranks == NULL) {
1441  HECMW_set_error(errno, "");
1443  return NULL;
1444  }
1445  for (i = 0; i < comm->psize; i++) {
1446  comm->ranks[i] = intracomm->comm->ranks[i];
1447  }
1448  comm->comm = intracomm->comm->comm;
1449  comm->group = intracomm->comm->group;
1450  comm->root = intracomm->comm->root;
1451  comm->is_member = intracomm->comm->is_member;
1452  comm->is_root = intracomm->comm->is_root;
1453 
1454  return comm;
1455 }
1456 
1458  const char *unit_id) {
1459  struct intracomm_info *intracomm = NULL;
1460  struct hecmw_couple_comm *comm;
1461  int i;
1462 
1463  if (unit_id == NULL) {
1465  "Invalid NULL pointer is found (boundary_id)");
1466  return NULL;
1467  }
1468 
1469  intracomm = get_intracomm_info(unit_id);
1470  if (intracomm == NULL) return NULL;
1471 
1472  comm = alloc_struct_comm();
1473  if (comm == NULL) return NULL;
1474 
1475  comm->psize = intracomm->comm->psize;
1476  comm->rank = intracomm->comm->rank;
1477  comm->ranks = (int *)HECMW_calloc(comm->psize, sizeof(int));
1478  if (comm->ranks == NULL) {
1479  HECMW_set_error(errno, "");
1481  return NULL;
1482  }
1483  for (i = 0; i < comm->psize; i++) {
1484  comm->ranks[i] = intracomm->comm->ranks[i];
1485  }
1486  comm->comm = intracomm->comm->comm;
1487  comm->group = intracomm->comm->group;
1488  comm->root = intracomm->comm->root;
1489  comm->is_member = intracomm->comm->is_member;
1490  comm->is_root = intracomm->comm->is_root;
1491 
1492  return comm;
1493 }
1494 
1496  const char *boundary_id) {
1497  struct couple_info *couple;
1498  struct intercomm_info *intercomm;
1499  struct hecmw_couple_comm *comm;
1500  int i;
1501 
1502  if (boundary_id == NULL) {
1504  "Invalid NULL pointer is found (boundary_id)");
1505  return NULL;
1506  }
1507 
1508  couple = get_couple_info(boundary_id);
1509  if (couple == NULL) return NULL;
1510 
1511  intercomm = get_intercomm_info(couple->couple_id);
1512  if (intercomm == NULL) return NULL;
1513 
1514  comm = alloc_struct_comm();
1515  if (comm == NULL) return NULL;
1516 
1517  comm->psize = intercomm->comm->psize;
1518  comm->rank = intercomm->comm->rank;
1519  comm->ranks = (int *)HECMW_calloc(comm->psize, sizeof(int));
1520  if (comm->ranks == NULL) {
1521  HECMW_set_error(errno, "");
1523  return NULL;
1524  }
1525  for (i = 0; i < comm->psize; i++) {
1526  comm->ranks[i] = intercomm->comm->ranks[i];
1527  }
1528  comm->comm = intercomm->comm->comm;
1529  comm->group = intercomm->comm->group;
1530  comm->root = intercomm->comm->root;
1531  comm->is_member = intercomm->comm->is_member;
1532  comm->is_root = intercomm->comm->is_root;
1533 
1534  return comm;
1535 }
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:37
#define NULL
#define HECMW_calloc(nmemb, size)
Definition: hecmw_malloc.h:21
#define HECMW_free(ptr)
Definition: hecmw_malloc.h:24
#define HECMW_strdup(s)
Definition: hecmw_malloc.h:23
#define HECMW_malloc(size)
Definition: hecmw_malloc.h:20
#define HECMW_assert(cond)
Definition: hecmw_util.h:40