FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
hecmw_couple_control.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_config.h"
13 #include "hecmw_msgno.h"
14 #include "hecmw_malloc.h"
15 #include "hecmw_error.h"
16 #include "hecmw_ctrllex.h"
17 #include "hecmw_control.h"
18 #include "hecmw_util.h"
19 
20 #include "hecmw_couple_define.h"
21 /* #include "hecmw_couple_struct.h" */
22 #include "hecmw_couple_control.h"
23 
24 /*================================================================================================*/
25 
26 struct link_list_i {
27  int rank;
28  struct link_list_i *next;
29 };
30 
31 struct link_list_s {
32  char name[HECMW_NAME_LEN + 1];
33  struct link_list_s *next;
34 };
35 
36 static struct unit_info_by_ctrl {
37  char unit_id[HECMW_NAME_LEN + 1];
38  int n_proc;
39  int is_specified_ranks;
40  struct link_list_i ranks;
41  struct unit_info_by_ctrl *next;
42 } unit_info_root = {
43  "", /* unit_id */
44  0, /* n_proc */
45  HECMW_COUPLE_FALSE, /* is_specified_ranks */
46  {
47  -1, /* ranks.rank */
48  NULL, /* ranks.next */
49  },
50  NULL, /* next */
51 };
52 
53 static struct couple_info_by_ctrl {
54  char couple_id[HECMW_NAME_LEN + 1];
55  char unit1_id[HECMW_NAME_LEN + 1];
56  char unit2_id[HECMW_NAME_LEN + 1];
57  int couple_type;
58  struct couple_info_by_ctrl *next;
59 } couple_info_root = {
60  "", /* couple_id */
61  "", /* unit1_id */
62  "", /* unit2_id */
63  HECMW_COUPLE_TYPE_UNDEF, /* couple_type */
64  NULL, /* next */
65 };
66 
68  int n_grp;
69  int geom_type;
70  int data_type;
71  struct link_list_s grp_name;
72 };
73 
74 static struct boundary_info_by_ctrl {
75  char boundary_id[HECMW_NAME_LEN + 1];
76  char couple_id[HECMW_NAME_LEN + 1];
77  int interpolation;
78  int direction;
79  double tolerance;
80  double bbcoef;
81  double bgcoef;
82  struct group_info_by_ctrl unit1_grp;
83  struct group_info_by_ctrl unit2_grp;
84  struct boundary_info_by_ctrl *next;
85 } boundary_info_root = {
86  "", /* boundary_id */
87  "", /* couple_id */
88  HECMW_COUPLE_IP_UNDEF, /* interpolation */
89  HECMW_COUPLE_DIRECTION_UNDEF, /* direction */
90  HECMW_COUPLE_TOLERANCE_DEFAULT, /* tolrance */
91  HECMW_COUPLE_BBCOEF_DEFAULT, /* bb_coef */
92  HECMW_COUPLE_BGCOEF_DEFAULT, /* bg_coef */
93  {0, /* unit1_grp.n_grp */
94  HECMW_COUPLE_GROUP_UNDEF, /* unit1_grp.geom_type */
95  HECMW_COUPLE_GROUP_UNDEF, /* unit1_grp.data_type */
96  {
97  "", /* unit1_grp.grp_name.name */
98  NULL /* unit1_grp.grp_name.next */
99  }},
100  {0, /* unit2_grp.n_grp */
101  HECMW_COUPLE_GROUP_UNDEF, /* unit2_grp.geom_type */
102  HECMW_COUPLE_GROUP_UNDEF, /* unit2_grp.data_type */
103  {
104  "", /* unit2_grp.grp_name.name */
105  NULL /* unit2_grp.grp_name.next */
106  }},
107  NULL, /* next */
108 };
109 
110 static struct unit_info_by_ctrl *unit_info_current = &unit_info_root;
111 
112 static struct couple_info_by_ctrl *couple_info_current = &couple_info_root;
113 
114 static struct boundary_info_by_ctrl *boundary_info_current =
115  &boundary_info_root;
116 
117 static int n_unit = 0;
118 
119 static int n_couple = 0;
120 
121 static int n_boundary = 0;
122 
123 /*================================================================================================*/
124 
125 static void free_link_list_s(struct link_list_s *r) {
126  struct link_list_s *p, *q;
127 
128  for (p = r->next; p; p = q) {
129  q = p->next;
130  HECMW_free(p);
131  }
132 }
133 
134 static void free_link_list_i(struct link_list_i *r) {
135  struct link_list_i *p, *q;
136 
137  for (p = r->next; p; p = q) {
138  q = p->next;
139  HECMW_free(p);
140  }
141 }
142 
143 extern void HECMW_couple_ctrl_print_unit(FILE *fp) {
144  struct unit_info_by_ctrl *p;
145  struct link_list_i *q;
146 
147  for (p = unit_info_root.next; p; p = p->next) {
148  fprintf(fp, "Unit ID: %s\n", p->unit_id);
149  fprintf(fp, "Number of Processes: %d\n", p->n_proc);
150  fprintf(fp, "Process rank is specified or not: %d\n",
151  p->is_specified_ranks);
152  for (q = p->ranks.next; q; q = q->next) {
153  fprintf(fp, "Process Number: %d\n", q->rank);
154  }
155  }
156 }
157 
158 extern void HECMW_couple_ctrl_print_couple(FILE *fp) {
159  struct couple_info_by_ctrl *p;
160 
161  for (p = couple_info_root.next; p; p = p->next) {
162  fprintf(fp, "Couple ID: %s\n", p->couple_id);
163  fprintf(fp, "Unit1 ID: %s\n", p->unit1_id);
164  fprintf(fp, "Unit2 ID: %s\n", p->unit2_id);
165  fprintf(fp, "Couple Type: %d\n", p->couple_type);
166  }
167 }
168 
169 extern void HECMW_couple_ctrl_print_boundary(FILE *fp) {
170  struct boundary_info_by_ctrl *p;
171  struct link_list_s *q;
172 
173  for (p = boundary_info_root.next; p; p = p->next) {
174  fprintf(fp, "Boundary ID: %s\n", p->boundary_id);
175  fprintf(fp, "Couple ID: %s\n", p->couple_id);
176  fprintf(fp, "Direction: %d\n", p->direction);
177  fprintf(fp, "Interpolation: %d\n", p->interpolation);
178  fprintf(fp, "Tolerance: %e\n", p->tolerance);
179  fprintf(fp, "BBcoef: %e\n", p->bbcoef);
180  fprintf(fp, "BGcoef: %e\n", p->bgcoef);
181  fprintf(fp, "Unit1 Group: %d\n", p->unit1_grp.n_grp);
182  fprintf(fp, "Unit1 Group Type (Geometry): %d\n", p->unit1_grp.geom_type);
183  fprintf(fp, "Unit1 Group Type (Data): %d\n", p->unit1_grp.data_type);
184  for (q = p->unit1_grp.grp_name.next; q; q = q->next) {
185  fprintf(fp, "Unit1 Group Name: %s\n", q->name);
186  }
187  fprintf(fp, "Unit2 Group: %d\n", p->unit2_grp.n_grp);
188  fprintf(fp, "Unit2 Group Type (Geometry): %d\n", p->unit2_grp.geom_type);
189  fprintf(fp, "Unit2 Group Type (Data): %d\n", p->unit2_grp.data_type);
190  for (q = p->unit2_grp.grp_name.next; q; q = q->next) {
191  fprintf(fp, "Unit2 Group Name: %s\n", q->name);
192  }
193  }
194 }
195 
196 /*------------------------------------------------------------------------------------------------*/
197 
198 static struct couple_info_by_ctrl *get_couple_by_id(const char *couple_id) {
199  struct couple_info_by_ctrl *p;
200 
201  if (couple_id == NULL) return NULL;
202 
203  for (p = couple_info_root.next; p; p = p->next) {
204  if ((strcmp(p->couple_id, couple_id)) == 0) return p;
205  }
206 
207  return NULL;
208 }
209 
210 static struct unit_info_by_ctrl *get_unit_by_id(const char *unit_id) {
211  struct unit_info_by_ctrl *p;
212 
213  if (unit_id == NULL) return NULL;
214 
215  for (p = unit_info_root.next; p; p = p->next) {
216  if ((strcmp(p->unit_id, unit_id)) == 0) return p;
217  }
218 
219  return NULL;
220 }
221 
222 static struct boundary_info_by_ctrl *get_boundary_by_id(
223  const char *boundary_id) {
224  struct boundary_info_by_ctrl *p;
225 
226  if (boundary_id == NULL) return NULL;
227 
228  for (p = boundary_info_root.next; p; p = p->next) {
229  if ((strcmp(p->boundary_id, boundary_id)) == 0) return p;
230  }
231 
232  return NULL;
233 }
234 
235 /*================================================================================================*/
236 
238  struct hecmw_couple_ctrl_unit_ids *unit_ids) {
239  int i;
240 
241  if (unit_ids == NULL) return;
242 
243  if (unit_ids->ids) {
244  for (i = 0; i < unit_ids->n_unit; i++) {
245  HECMW_free(unit_ids->ids[i]);
246  }
247  HECMW_free(unit_ids->ids);
248  }
249  HECMW_free(unit_ids);
250  unit_ids = NULL;
251 }
252 
254  struct hecmw_couple_ctrl_couple_ids *couple_ids) {
255  int i;
256 
257  if (couple_ids == NULL) return;
258 
259  if (couple_ids->ids) {
260  for (i = 0; i < couple_ids->n_couple; i++) {
261  HECMW_free(couple_ids->ids[i]);
262  }
263  HECMW_free(couple_ids->ids);
264  }
265  HECMW_free(couple_ids);
266  couple_ids = NULL;
267 }
268 
270  struct hecmw_couple_ctrl_boundary_ids *boundary_ids) {
271  int i;
272 
273  if (boundary_ids == NULL) return;
274 
275  if (boundary_ids->ids) {
276  for (i = 0; i < boundary_ids->n_boundary; i++) {
277  HECMW_free(boundary_ids->ids[i]);
278  }
279  HECMW_free(boundary_ids->ids);
280  }
281  HECMW_free(boundary_ids);
282  boundary_ids = NULL;
283 }
284 
286  struct hecmw_couple_ctrl_proc *proc_info) {
287  if (proc_info == NULL) return;
288 
289  HECMW_free(proc_info->ranks);
290  HECMW_free(proc_info);
291  proc_info = NULL;
292 }
293 
294 extern void HECMW_couple_ctrl_free_group(struct hecmw_couple_group *grp_info) {
295  int i;
296 
297  if (grp_info == NULL) return;
298 
299  for (i = 0; i < grp_info->n_grp; i++) {
300  HECMW_free(grp_info->grp_name[i]);
301  }
302  HECMW_free(grp_info);
303  grp_info == NULL;
304 }
305 
306 static void free_unit(void) {
307  struct unit_info_by_ctrl *p, *q;
308 
309  for (p = unit_info_root.next; p; p = q) {
310  q = p->next;
311  free_link_list_i(&p->ranks);
312  HECMW_free(p);
313  }
314  unit_info_root.next = NULL;
315 }
316 
317 static void free_couple(void) {
318  struct couple_info_by_ctrl *p, *q;
319 
320  for (p = couple_info_root.next; p; p = q) {
321  q = p->next;
322  HECMW_free(p);
323  }
324  couple_info_root.next = NULL;
325 }
326 
327 static void free_boundary(void) {
328  struct boundary_info_by_ctrl *p, *q;
329 
330  for (p = boundary_info_root.next; p; p = q) {
331  q = p->next;
332  free_link_list_s(&p->unit1_grp.grp_name);
333  free_link_list_s(&p->unit2_grp.grp_name);
334  HECMW_free(p);
335  }
336  boundary_info_root.next = NULL;
337 }
338 
339 extern void HECMW_couple_ctrl_free(void) {
340  free_unit();
341  free_couple();
342  free_boundary();
343 }
344 
345 /*================================================================================================*/
346 
347 static int get_unit_name(char *unit_id, size_t unit_id_len) {
348  int token;
349  char *s;
350 
351  /* = */
352  if ((token = HECMW_ctrllex_next_token()) != '=') {
354  "line %d: '=' is not found after 'NAME' in '!COUPLE UNIT'",
356  return -1;
357  }
358 
359  /* Name of coupling unit */
360  if ((token = HECMW_ctrllex_next_token()) != HECMW_CTRLLEX_NAME) {
362  "line %d: Invalid 'NAME' is specified in '!COUPLE UNIT'",
364  return -1;
365  }
367  if (strlen(s) > HECMW_NAME_LEN) {
369  "line %d: 'NAME' is too long in '!COUPLE UNIT'",
371  return -1;
372  }
373  snprintf(unit_id, unit_id_len, "%s", s);
374 
375  return 0;
376 }
377 
378 static int get_unit_nproc(int *n_proc) {
379  int token;
380 
381  /* = */
382  if ((token = HECMW_ctrllex_next_token()) != '=') {
384  "line %d: '=' is not found after 'NPROC' in '!COUPLE UNIT'",
386  return -1;
387  }
388 
389  /* Number of processes */
390  if ((token = HECMW_ctrllex_next_token()) != HECMW_CTRLLEX_INT) {
392  "line %d: Invalid 'NPROC' is specified in '!COUPLE UNIT'",
394  return -1;
395  }
396  *n_proc = (int)HECMW_ctrllex_get_number();
397  if (n_proc < 0) {
400  "line %d: 'NPROC' in '!COUPLE UNIT' must be natural number (%d)",
401  HECMW_ctrllex_get_lineno(), *n_proc);
402  return -1;
403  }
404 
405  return 0;
406 }
407 
408 static int get_unit_ranks(struct link_list_i *p, int *counter) {
409  int token, rank;
410 
411  while (1) {
412  /* Process number */
413  token = HECMW_ctrllex_next_token();
414  if (token == HECMW_CTRLLEX_NL) break;
415  if (token != HECMW_CTRLLEX_INT) {
418  "line %d: Invalid process number is found in '!COUPLE UNIT'",
420  return -1;
421  }
422  rank = (int)HECMW_ctrllex_get_number();
423  if (rank < 0) {
425  "line %d: Process number in '!COUPLE UNIT' must be "
426  "natural number (%d)",
427  HECMW_ctrllex_get_lineno(), rank);
428  return -1;
429  }
430 
431  p->next = (struct link_list_i *)HECMW_malloc(sizeof(struct link_list_i));
432  if (p->next == NULL) {
433  HECMW_set_error(errno, "");
434  return -1;
435  }
436  p = p->next;
437  p->rank = rank;
438  p->next = NULL;
439  (*counter)++;
440 
441  /* , */
442  token = HECMW_ctrllex_next_token();
443  if (token == HECMW_CTRLLEX_NL) break;
444  if (token != ',') {
447  "line %d: Process number must be delimited by ',' in '!COUPLE UNIT'",
449  return -1;
450  }
451  }
452 
453  return 0;
454 }
455 
456 static int get_unit_1st_line(struct unit_info_by_ctrl *p) {
457  int token;
458  int is_specified_name = 0;
459  int is_specified_nproc = 0;
460 
461  while (1) {
462  if ((token = HECMW_ctrllex_next_token()) != ',') {
463  if (token == HECMW_CTRLLEX_NL) break;
466  return -1;
467  }
468 
469  token = HECMW_ctrllex_next_token();
470 
471  /* NAME=<name-of-coupling-unit> */
472  if (token == HECMW_CTRLLEX_K_NAME) {
473  if (is_specified_name) {
475  "line %d: 'NAME' is re-defined in !COUPLE UNIT",
477  return -1;
478  }
479  if (get_unit_name(p->unit_id, sizeof(p->unit_id))) return -1;
480  is_specified_name = 1;
481 
482  /* NPROC=<number-of-processes> */
483  } else if (token == HECMW_CTRLLEX_K_NPROC) {
484  if (is_specified_nproc) {
486  "line %d: 'NPROC' is re-defined in !COUPLE UNIT",
488  return -1;
489  }
490  if (get_unit_nproc(&p->n_proc)) return -1;
491  is_specified_nproc = 1;
492 
493  /* New Line */
494  } else if (token == HECMW_CTRLLEX_NL) {
495  break;
496 
497  /* Invalid Token */
498  } else {
501  return -1;
502  }
503  }
504 
505  /* NAME is not specified */
506  if (is_specified_name == 0) {
509  return -1;
510  }
511  /* NPROC is not specified */
512  if (is_specified_nproc <= 0) {
515  return -1;
516  }
517 
518  return 0;
519 }
520 
521 static int get_unit_2nd_line(struct unit_info_by_ctrl *p) {
522  int token, counter;
523  struct link_list_i *q;
524 
525  /* proc-1, proc-2, ..., proc-n */
526  q = &p->ranks;
527  counter = 0;
528  while ((token = HECMW_ctrllex_next_token())) {
529  if (token == HECMW_CTRLLEX_NL) continue;
530 
532 
533  if (token != HECMW_CTRLLEX_INT) break;
534 
535  if (get_unit_ranks(q, &counter)) return -1;
536  }
537 
538  /* check number of processes */
539  if (counter > 0) {
540  if (counter != p->n_proc) {
542  return -1;
543  }
544  p->is_specified_ranks = 1;
545  }
546 
547  return 0;
548 }
549 
550 extern int HECMW_couple_ctrl_unit(void) {
551  int token, size;
552  struct unit_info_by_ctrl *p;
553 
554  token = HECMW_ctrllex_next_token();
555  HECMW_assert(token == HECMW_CTRLLEX_H_COUPLE_UNIT);
556 
557  /* allocation & initialization */
558  size = sizeof(struct unit_info_by_ctrl);
559  unit_info_current->next = (struct unit_info_by_ctrl *)HECMW_malloc(size);
560  if (unit_info_current->next == NULL) {
561  HECMW_set_error(errno, "");
562  return -1;
563  }
564  p = unit_info_current->next;
565  memset(p->unit_id, 0, HECMW_NAME_LEN + 1);
566  p->n_proc = 0;
567  p->is_specified_ranks = HECMW_COUPLE_FALSE;
568  p->ranks.rank = -1;
569  p->ranks.next = NULL;
570  p->next = NULL;
571 
572  /* get 1st line */
573  if (get_unit_1st_line(p)) return -1;
574 
575  /* skip blank line */
576  if ((token = HECMW_ctrllex_next_token()) == HECMW_CTRLLEX_NL)
577  ;
579 
580  /* get 2nd line */
581  if (get_unit_2nd_line(p)) return -1;
582 
583  unit_info_current = p;
584  n_unit++;
585 
586  return 0;
587 }
588 
589 /*================================================================================================*/
590 
591 static int get_couple_name(char *couple_id, size_t couple_id_len) {
592  int token;
593  char *s;
594 
595  /* = */
596  if ((token = HECMW_ctrllex_next_token()) != '=') {
598  "line %d: '=' is not found after 'NAME' in '!COUPLE'",
600  return -1;
601  }
602 
603  /* Name of couple */
604  if ((token = HECMW_ctrllex_next_token()) != HECMW_CTRLLEX_NAME) {
606  "line %d: Invalid 'NAME' is specified in '!COUPLE'",
608  return -1;
609  }
611  if (strlen(s) > HECMW_NAME_LEN) {
613  "line %d: 'NAME' in '!COUPLE' is too long",
615  return -1;
616  }
617  snprintf(couple_id, couple_id_len, "%s", s);
618 
619  return 0;
620 }
621 
622 static int get_couple_type(int *type) {
623  int token;
624 
625  /* = */
626  if ((token = HECMW_ctrllex_next_token()) != '=') {
628  "line %d: '=' is not found after 'TYPE' in '!COUPLE'",
630  return -1;
631  }
632 
633  /* Coupling type */
634  token = HECMW_ctrllex_next_token();
635  if (token == HECMW_CTRLLEX_K_MXN) { /* MXN */
636  *type = HECMW_COUPLE_TYPE_MXN;
637  } else if (token == HECMW_CTRLLEX_K_MAXMN) { /* MAXMN */
638  *type = HECMW_COUPLE_TYPE_MAXMN;
639  } else if (token == HECMW_CTRLLEX_K_MANUAL) { /* MANUAL */
640  *type = HECMW_COUPLE_TYPE_MANUAL;
641  } else { /* Invalid Token */
643  "line %d: Invalid 'TYPE' is specified in '!COUPLE'",
645  return -1;
646  }
647 
648  return 0;
649 }
650 
651 static int get_couple_unit1(char *unit1_id, size_t unit1_id_len) {
652  int token;
653  char *s;
654 
655  /* = */
656  if ((token = HECMW_ctrllex_next_token()) != '=') {
658  "line %d: '=' is not found after 'UNIT1' in '!COUPLE'",
660  return -1;
661  }
662 
663  /* Name of coupling unit 1 */
664  if ((token = HECMW_ctrllex_next_token()) != HECMW_CTRLLEX_NAME) {
666  "line %d: Invalid 'UNIT1' is specified in '!COUPLE'",
668  return -1;
669  }
671  if (strlen(s) > HECMW_NAME_LEN) {
673  "line %d: 'UNIT1' in '!COUPLE' is too long",
675  return -1;
676  }
677  if (get_unit_by_id(s) == NULL) {
679  return -1;
680  }
681  snprintf(unit1_id, unit1_id_len, "%s", s);
682 
683  return 0;
684 }
685 
686 static int get_couple_unit2(char *unit2_id, size_t unit2_id_len) {
687  int token;
688  char *s;
689 
690  /* = */
691  if ((token = HECMW_ctrllex_next_token()) != '=') {
693  "line %d: '=' is not found after 'UNIT2' in '!COUPLE'",
695  return -1;
696  }
697 
698  /* Name of coupling unit 2 */
699  if ((token = HECMW_ctrllex_next_token()) != HECMW_CTRLLEX_NAME) {
701  "line %d: Invalid 'UNIT2' is specified in '!COUPLE'",
703  return -1;
704  }
706  if (strlen(s) > HECMW_NAME_LEN) {
708  "line %d: 'UNIT2' in '!COUPLE' is too long",
710  return -1;
711  }
712  if (get_unit_by_id(s) == NULL) {
714  return -1;
715  }
716  snprintf(unit2_id, unit2_id_len, "%s", s);
717 
718  return 0;
719 }
720 
721 static int get_couple_1st_line(struct couple_info_by_ctrl *p) {
722  int token;
723  int is_specified_name = 0;
724  int is_specified_type = 0;
725  int is_specified_unit1 = 0;
726  int is_specified_unit2 = 0;
727 
728  while (1) {
729  token = HECMW_ctrllex_next_token();
730  if (token == HECMW_CTRLLEX_NL) break;
731  if (token != ',') {
734  return -1;
735  }
736 
737  token = HECMW_ctrllex_next_token();
738  /* NAME=<name-of-couple> */
739  if (token == HECMW_CTRLLEX_K_NAME) {
740  if (is_specified_name) {
742  "line %d: 'NAME' is re-defined in '!COUPLE'",
744  return -1;
745  }
746  if (get_couple_name(p->couple_id, sizeof(p->couple_id))) return -1;
747  is_specified_name = 1;
748 
749  /* TYPE=<couple-type> */
750  } else if (token == HECMW_CTRLLEX_K_TYPE) {
751  if (is_specified_type) {
753  "line %d: 'TYPE' is re-defined in '!COUPLE'",
755  return -1;
756  }
757  if (get_couple_type(&p->couple_type)) return -1;
758  is_specified_type = 1;
759 
760  /* UNIT1=<name-of-unit1> */
761  } else if (token == HECMW_CTRLLEX_K_UNIT1) {
762  if (is_specified_unit1) {
764  "line %d: 'UNIT1' is re-defined in '!COUPLE'",
766  return -1;
767  }
768  if (get_couple_unit1(p->unit1_id, sizeof(p->unit1_id))) return -1;
769  is_specified_unit1 = 1;
770 
771  /* UNIT2=<name-of-unit2> */
772  } else if (token == HECMW_CTRLLEX_K_UNIT2) {
773  if (is_specified_unit2) {
775  "line %d: 'UNIT2' is re-defined in '!COUPLE'",
777  return -1;
778  }
779  if (get_couple_unit2(p->unit2_id, sizeof(p->unit2_id))) return -1;
780  is_specified_unit2 = 1;
781 
782  /* New Line */
783  } else if (token == HECMW_CTRLLEX_NL) {
784  break;
785 
786  /* Invalid Token */
787  } else {
790  return -1;
791  }
792  }
793 
794  /* NAME is not specified */
795  if (!is_specified_name) {
798  return -1;
799  }
800  /* TYPE is not specified */
801  if (!is_specified_type) {
804  return -1;
805  }
806  /* UNIT1 is not specified */
807  if (!is_specified_unit1) {
810  return -1;
811  }
812  /* UNIT2 is not specified */
813  if (!is_specified_unit2) {
816  return -1;
817  }
818 
819  return 0;
820 }
821 
822 extern int HECMW_couple_ctrl_couple(void) {
823  int token, size;
824  struct couple_info_by_ctrl *p;
825 
826  token = HECMW_ctrllex_next_token();
827  HECMW_assert(token == HECMW_CTRLLEX_H_COUPLE);
828 
829  /* allocation & initialization */
830  size = sizeof(struct couple_info_by_ctrl);
831  couple_info_current->next = (struct couple_info_by_ctrl *)HECMW_malloc(size);
832  if (couple_info_current->next == NULL) {
833  HECMW_set_error(errno, "");
834  return -1;
835  }
836  p = couple_info_current->next;
837  memset(p->couple_id, 0, HECMW_NAME_LEN + 1);
838  memset(p->unit1_id, 0, HECMW_NAME_LEN + 1);
839  memset(p->unit2_id, 0, HECMW_NAME_LEN + 1);
840  p->couple_type = HECMW_COUPLE_TYPE_UNDEF;
841  p->next = NULL;
842 
843  /* get 1st line */
844  if (get_couple_1st_line(p)) return -1;
845 
846  couple_info_current = p;
847  n_couple++;
848 
849  return 0;
850 }
851 
852 /*------------------------------------------------------------------------------------------------*/
853 
854 static int get_boundary_name(char *boundary_id, size_t boundary_id_len) {
855  int token;
856  char *s;
857 
858  /* = */
859  if ((token = HECMW_ctrllex_next_token()) != '=') {
862  "line %d: '=' is not found after 'NAME' in '!COUPLE BOUNDARY'",
864  return -1;
865  }
866 
867  /* Name of coupling boundary */
868  if ((token = HECMW_ctrllex_next_token()) != HECMW_CTRLLEX_NAME) {
871  "line %d: Invalid 'NAME' is specified in '!COUPLE BOUNDARY'",
873  return -1;
874  }
876  if (strlen(s) > HECMW_NAME_LEN) {
878  "line %d: 'NAME' in '!COUPLE BOUNDARY' is too long",
880  return -1;
881  }
882  snprintf(boundary_id, boundary_id_len, "%s", s);
883 
884  return 0;
885 }
886 
887 static int get_boundary_couple(char *couple_id, size_t couple_id_len) {
888  int token;
889  char *s;
890 
891  /* = */
892  if ((token = HECMW_ctrllex_next_token()) != '=') {
895  "line %d: '=' is not found after 'COUPLE' in '!COUPLE BOUNDARY'",
897  return -1;
898  }
899 
900  /* Name of coupling */
901  if ((token = HECMW_ctrllex_next_token()) != HECMW_CTRLLEX_NAME) {
904  "line %d: Invalid 'COUPLE' is specified in '!COUPLE BOUNDARY'",
906  return -1;
907  }
909  if (strlen(s) > HECMW_NAME_LEN) {
911  "line %d: 'COUPLE' is too long in '!COUPLE BOUNDARY'",
913  return -1;
914  }
915  if (get_couple_by_id(s) == NULL) {
917  return -1;
918  }
919  snprintf(couple_id, couple_id_len, "%s", s);
920 
921  return 0;
922 }
923 
924 static int get_boundary_direction(int *direction) {
925  int token;
926 
927  /* = */
928  if ((token = HECMW_ctrllex_next_token()) != '=') {
931  "line %d: '=' is not found after 'DIRECTION' in '!COUPLE BOUNDARY'",
933  return -1;
934  }
935 
936  /* Coupling direction */
937  token = HECMW_ctrllex_next_token();
938  if (token == HECMW_CTRLLEX_K_UNIT1_TO_UNIT2) { /* from UNIT1 to UNIT2 */
939  *direction = HECMW_COUPLE_UNIT1_TO_UNIT2;
940  } else if (token ==
941  HECMW_CTRLLEX_K_UNIT2_TO_UNIT1) { /* from UNIT2 to UNIT1 */
942  *direction = HECMW_COUPLE_UNIT2_TO_UNIT1;
943  } else {
946  "line %d: Invalid 'DIRECTION' is specified in '!COUPLE BOUNDARY'",
948  return -1;
949  }
950 
951  return 0;
952 }
953 
954 static int get_boundary_interpolation(int *interpolation) {
955  int token;
956 
957  /* = */
958  if ((token = HECMW_ctrllex_next_token()) != '=') {
961  "line %d: '=' is not found after 'INTERPOLATION' in '!COUPLE BOUNDARY'",
963  return -1;
964  }
965 
966  /* Interpolating method */
967  token = HECMW_ctrllex_next_token();
968 
969  /*@@@@@ NOT mounting @@@@@*/
970 
971  return 0;
972 }
973 
974 static int get_boundary_tolerance(double *tolerance) {
975  int token;
976 
977  /* = */
978  if ((token = HECMW_ctrllex_next_token()) != '=') {
981  "line %d: '=' is not found after 'TOLERANCE' in '!COUPLE BOUNDARY'",
983  return -1;
984  }
985 
986  /* Tolerance */
987  if ((token = HECMW_ctrllex_next_token()) != HECMW_CTRLLEX_DOUBLE) {
990  "line %d: Invalid 'TOLERANCE' is specified in '!COUPLE BOUNDARY'",
992  return -1;
993  }
994  *tolerance = (double)HECMW_ctrllex_get_number();
995  if (*tolerance < 0.0) {
997  "line %d: 'TOLERANCE' in '!COUPLE BOUNDARY' must be grater "
998  "than or equal 0 (%e)",
999  HECMW_ctrllex_get_lineno(), *tolerance);
1000  return -1;
1001  }
1002 
1003  return 0;
1004 }
1005 
1006 static int get_boundary_bbcoef(double *bbcoef) {
1007  int token;
1008 
1009  /* = */
1010  if ((token = HECMW_ctrllex_next_token()) != '=') {
1013  "line %d: '=' is not found after 'BBCOEF' in '!COUPLE BOUNDARY'",
1015  return -1;
1016  }
1017 
1018  /* Enlarging coefficient for bounding box */
1019  if ((token = HECMW_ctrllex_next_token()) != HECMW_CTRLLEX_DOUBLE) {
1022  "line %d: Invalid 'BBCOEF' is specified in '!COUPLE BOUNDARY'",
1024  return -1;
1025  }
1026  *bbcoef = (double)HECMW_ctrllex_get_number();
1027  if (*bbcoef <= 0.0) {
1030  "line %d: 'BBCOEF' in '!COUPLE BOUNDARY' must be grater than 0 (%e)",
1031  HECMW_ctrllex_get_lineno(), *bbcoef);
1032  return -1;
1033  }
1034 
1035  return 0;
1036 }
1037 
1038 static int get_boundary_bgcoef(double *bgcoef) {
1039  int token;
1040 
1041  /* = */
1042  if ((token = HECMW_ctrllex_next_token()) != '=') {
1045  "line %d: '=' is not found after 'BGCOEF' in '!COUPLE BOUNDARY'",
1047  return -1;
1048  }
1049 
1050  /* Enlarging coefficient for background cell */
1051  if ((token = HECMW_ctrllex_next_token()) != HECMW_CTRLLEX_DOUBLE) {
1054  "line %d: Invalid 'BGCOEF' is specified in '!COUPLE BOUNDARY'",
1056  return -1;
1057  }
1058  *bgcoef = (double)HECMW_ctrllex_get_number();
1059  if (*bgcoef <= 0.0) {
1062  "line %d: 'BGCOEF' in '!COUPLE BOUNDARY' must be grater than 0 (%e)",
1063  HECMW_ctrllex_get_lineno(), *bgcoef);
1064  return -1;
1065  }
1066 
1067  return 0;
1068 }
1069 
1070 static int get_boundary_1st_line(struct boundary_info_by_ctrl *p) {
1071  int token;
1072  int is_specified_name = 0;
1073  int is_specified_couple = 0;
1074  int is_specified_direction = 0;
1075  int is_specified_interpolation = 0;
1076  int is_specified_tolrance = 0;
1077  int is_specified_bbcoef = 0;
1078  int is_specified_bgcoef = 0;
1079 
1080  while (1) {
1081  token = HECMW_ctrllex_next_token();
1082  if (token == HECMW_CTRLLEX_NL) break;
1083  if (token != ',') {
1086  return -1;
1087  }
1088 
1089  token = HECMW_ctrllex_next_token();
1090  /* NAME=<name-of-coupling-boundary> */
1091  if (token == HECMW_CTRLLEX_K_NAME) {
1092  if (is_specified_name) {
1094  "line %d: 'NAME' is re-defined in '!COUPLE BOUNDARY'",
1096  return -1;
1097  }
1098  if (get_boundary_name(p->boundary_id, sizeof(p->boundary_id)) != HECMW_SUCCESS) return -1;
1099  is_specified_name = 1;
1100 
1101  /* COUPLE=<name-of-couple> */
1102  } else if (token == HECMW_CTRLLEX_K_COUPLE) {
1103  if (is_specified_couple) {
1105  "line %d: 'COUPLE' is re-defined in '!COUPLE BOUNDARY'",
1107  return -1;
1108  }
1109  if (get_boundary_couple(p->couple_id, sizeof(p->couple_id)) != HECMW_SUCCESS) return -1;
1110  is_specified_couple = 1;
1111 
1112  /* DIRECTION=<coupling-direction> */
1113  } else if (token == HECMW_CTRLLEX_K_DIRECTION) {
1114  if (is_specified_direction) {
1117  "line %d: 'DIRECTION' is re-defined in '!COUPLE BOUNDARY'",
1119  return -1;
1120  }
1121  if (get_boundary_direction(&p->direction) != HECMW_SUCCESS) return -1;
1122  is_specified_direction = 1;
1123 
1124  /* INTERPOLATION=<interpolating-method> */
1125  } else if (token == HECMW_CTRLLEX_K_INTERPOLATION) {
1126  if (is_specified_interpolation) {
1129  "line %d: 'INTERPOLATION' is re-defined in '!COUPLE BOUNDARY'",
1131  return -1;
1132  }
1133  if (get_boundary_interpolation(&p->interpolation) != HECMW_SUCCESS)
1134  return -1;
1135  is_specified_interpolation = 1;
1136 
1137  /* TOLERANCE=<tolerance> */
1138  } else if (token == HECMW_CTRLLEX_K_TOLERANCE) {
1139  if (is_specified_tolrance) {
1142  "line %d: 'TOLRANCE' is re-defined in '!COUPLE BOUNDARY'",
1144  return -1;
1145  }
1146  if (get_boundary_tolerance(&p->tolerance) != HECMW_SUCCESS) return -1;
1147  is_specified_tolrance = 1;
1148 
1149  /* BBCOEF=<bounding-box-enlargement-coefficient> */
1150  } else if (token == HECMW_CTRLLEX_K_BBCOEF) {
1151  if (is_specified_bbcoef) {
1153  "line %d: 'BBCOEF' is re-defined in '!COUPLE BOUNDARY'",
1155  return -1;
1156  }
1157  if (get_boundary_bbcoef(&p->bbcoef) != HECMW_SUCCESS) return -1;
1158  is_specified_bbcoef = 1;
1159 
1160  /* BGCOEF=<background-cell-enlargement-coefficient> */
1161  } else if (token == HECMW_CTRLLEX_K_BGCOEF) {
1162  if (is_specified_bgcoef) {
1164  "line %d: 'BGCOEF' is re-defined in '!COUPLE BOUNDARY'",
1166  return -1;
1167  }
1168  if (get_boundary_bgcoef(&p->bgcoef) != HECMW_SUCCESS) return -1;
1169  is_specified_bgcoef = 1;
1170 
1171  /* New Line */
1172  } else if (token == HECMW_CTRLLEX_NL) {
1173  break;
1174 
1175  /* Invalid Token */
1176  } else {
1179  return -1;
1180  }
1181  }
1182 
1183  /* NAME is not specified */
1184  if (!is_specified_name) {
1186  HECMW_ctrllex_get_lineno() - 1);
1187  return -1;
1188  }
1189  /* COUPLE is not specified */
1190  if (!is_specified_couple) {
1192  HECMW_ctrllex_get_lineno() - 1);
1193  return -1;
1194  }
1195  /* DIRECTION is not specified */
1196  if (!is_specified_direction) {
1198  HECMW_ctrllex_get_lineno() - 1);
1199  return -1;
1200  }
1201 
1202  return 0;
1203 }
1204 
1205 /*------------------------------------------------------------------------------------------------*/
1206 
1207 static int get_boundary_geom(int *geom_type) {
1208  int token;
1209 
1210  /* = */
1211  if ((token = HECMW_ctrllex_next_token()) != '=') {
1214  "line %d: '=' is not found after 'GEOM' in '!UNIT1' or '!UNIT2'",
1216  return -1;
1217  }
1218 
1219  /* Boundary group type */
1220  token = HECMW_ctrllex_next_token();
1221  if (token == HECMW_CTRLLEX_K_NODE) { /* NODE GROUP */
1222  *geom_type = HECMW_COUPLE_NODE_GROUP;
1223  } else if (token == HECMW_CTRLLEX_K_ELEMENT) { /* ELEMENT GROUP */
1224  *geom_type = HECMW_COUPLE_ELEMENT_GROUP;
1225  } else if (token == HECMW_CTRLLEX_K_SURFACE) { /* SURFACE GROUP */
1226  *geom_type = HECMW_COUPLE_SURFACE_GROUP;
1227  } else { /* Invalid Token */
1230  "line %d: Invalid 'GEOM' is specified in '!UNIT1' or '!UNIT2'",
1232  return -1;
1233  }
1234 
1235  return 0;
1236 }
1237 
1238 static int get_boundary_data(int *data_type) {
1239  int token;
1240 
1241  /* = */
1242  if ((token = HECMW_ctrllex_next_token()) != '=') {
1245  "line %d: '=' is not found after 'DATA' in '!UNIT1' or '!UNIT2'",
1247  return -1;
1248  }
1249 
1250  /* Boundary group type */
1251  token = HECMW_ctrllex_next_token();
1252  if (token == HECMW_CTRLLEX_K_NODE) { /* NODE GROUP */
1253  *data_type = HECMW_COUPLE_NODE_GROUP;
1254  } else if (token == HECMW_CTRLLEX_K_ELEMENT) { /* ELEMENT GROUP */
1255  *data_type = HECMW_COUPLE_ELEMENT_GROUP;
1256  } else if (token == HECMW_CTRLLEX_K_SURFACE) { /* SURFACE GROUP */
1257  *data_type = HECMW_COUPLE_SURFACE_GROUP;
1258  } else { /* Invalid Token */
1261  "line %d: Invalid 'DATA' is specified in '!UNIT1' or '!UNIT2'",
1263  return -1;
1264  }
1265 
1266  return 0;
1267 }
1268 
1269 static int get_boundary_group_inner(struct link_list_s *p, int *counter) {
1270  char *s;
1271  int token;
1272 
1273  while (1) {
1274  /* Group Name */
1275  token = HECMW_ctrllex_next_token();
1276  if (token == HECMW_CTRLLEX_NL) break;
1277  if (token != HECMW_CTRLLEX_NAME) {
1280  "line %d: Invalid group name is found in '!COUPLE BOUNDARY'",
1282  return -1;
1283  }
1284  s = HECMW_ctrllex_get_text();
1285  if (strlen(s) > HECMW_NAME_LEN) {
1287  "line %d: Group name in '!COUPLE BOUNDARY' is too long",
1289  return -1;
1290  }
1291 
1292  p->next = (struct link_list_s *)HECMW_malloc(sizeof(struct link_list_s));
1293  if (p->next == NULL) {
1294  HECMW_set_error(errno, "");
1295  return -1;
1296  }
1297  p = p->next;
1298  snprintf(p->name, sizeof(p->name), "%s", s);
1299  p->next = NULL;
1300  (*counter)++;
1301 
1302  /* , */
1303  token = HECMW_ctrllex_next_token();
1304  if (token == HECMW_CTRLLEX_NL) break;
1305  if (token != ',') {
1308  "line %d: Group name must be delimited by ',' in '!COUPLE BOUNDARY'",
1310  return -1;
1311  }
1312  }
1313 
1314  return 0;
1315 }
1316 
1317 static int get_boundary_unit_2nd_line(struct group_info_by_ctrl *p) {
1318  int token, counter;
1319  struct link_list_s *q;
1320 
1321  q = &p->grp_name;
1322  counter = 0;
1323  while ((token = HECMW_ctrllex_next_token())) {
1324  if (token == HECMW_CTRLLEX_NL) continue;
1325 
1327 
1328  if (token != HECMW_CTRLLEX_NAME) break;
1329 
1330  if (get_boundary_group_inner(q, &counter) != HECMW_SUCCESS) return -1;
1331  }
1332 
1333  p->n_grp = counter;
1334 
1335  /* Group name is not specified */
1336  if (counter <= 0) {
1338  HECMW_ctrllex_get_lineno() - 1);
1339  return -1;
1340  }
1341 
1342  return 0;
1343 }
1344 
1345 static int get_boundary_unit_1st_line(struct group_info_by_ctrl *p) {
1346  int token;
1347  int is_specified_geom = 0;
1348  int is_specified_data = 0;
1349 
1350  while (1) {
1351  if ((token = HECMW_ctrllex_next_token()) != ',') {
1352  if (token == HECMW_CTRLLEX_NL) break;
1355  return -1;
1356  }
1357 
1358  token = HECMW_ctrllex_next_token();
1359 
1360  /* GEOM=<group-type-for-geometry> */
1361  if (token == HECMW_CTRLLEX_K_GEOM) {
1362  if (is_specified_geom) {
1364  "'GEOM' is re-defined in '!COUPLE BOUNDARY'",
1366  return -1;
1367  }
1368  if (get_boundary_geom(&p->geom_type)) return -1;
1369  is_specified_geom = 1;
1370 
1371  /* DATA=<group-type-for-data> */
1372  } else if (token == HECMW_CTRLLEX_K_DATA) {
1373  if (is_specified_data) {
1375  "'DATA' is re-defined in '!COUPLE BOUNDARY'",
1377  return -1;
1378  }
1379  if (get_boundary_data(&p->data_type)) return -1;
1380  is_specified_data = 1;
1381 
1382  /* New Line */
1383  } else if (token == HECMW_CTRLLEX_NL) {
1384  break;
1385 
1386  /* Invalid Token */
1387  } else {
1390  return -1;
1391  }
1392  }
1393 
1394  if (!is_specified_geom) {
1396  HECMW_ctrllex_get_lineno() - 1);
1397  return -1;
1398  }
1399  if (!is_specified_data) {
1401  HECMW_ctrllex_get_lineno() - 1);
1402  return -1;
1403  }
1404 
1405  if (p->geom_type == HECMW_COUPLE_NODE_GROUP) {
1406  if (p->data_type != HECMW_COUPLE_NODE_GROUP) {
1409  "line %d: NODE is specified in 'GEOM', but 'DATA' is not NODE",
1410  HECMW_ctrllex_get_lineno() - 1);
1411  return -1;
1412  }
1413  } else if (p->geom_type == HECMW_COUPLE_ELEMENT_GROUP) {
1417  "line %d: ELEMENT is specified in 'GEOM', but 'DATA' is "
1418  "not NODE or ELEMENT",
1419  HECMW_ctrllex_get_lineno() - 1);
1420  return -1;
1421  }
1422  } else if (p->geom_type == HECMW_COUPLE_SURFACE_GROUP) {
1426  "line %d: SURFACE is specified in 'GEOM', but 'DATA' is "
1427  "not NODE or SURFACE",
1428  HECMW_ctrllex_get_lineno() - 1);
1429  return -1;
1430  }
1431  } else {
1432  HECMW_assert(0);
1433  }
1434 
1435  return 0;
1436 }
1437 
1438 static int get_boundary_2nd_line(struct boundary_info_by_ctrl *p) {
1439  int token;
1440  int is_specified_unit1 = 0;
1441  int is_specified_unit2 = 0;
1442 
1443  while ((token = HECMW_ctrllex_next_token()) == HECMW_CTRLLEX_NL)
1444  ;
1445 
1446  /* !UNIT1 */
1447  if (token == HECMW_CTRLLEX_H_UNIT1) {
1448  if (get_boundary_unit_1st_line(&p->unit1_grp)) return -1;
1449  if (get_boundary_unit_2nd_line(&p->unit1_grp)) return -1;
1450  is_specified_unit1 = 1;
1451 
1452  while ((token = HECMW_ctrllex_next_token()) == HECMW_CTRLLEX_NL)
1453  ;
1454 
1455  if (token == HECMW_CTRLLEX_H_UNIT2) {
1456  if (get_boundary_unit_1st_line(&p->unit2_grp)) return -1;
1457  if (get_boundary_unit_2nd_line(&p->unit2_grp)) return -1;
1458  is_specified_unit2 = 1;
1459  }
1460 
1461  /* !UNIT2 */
1462  } else if (token == HECMW_CTRLLEX_H_UNIT2) {
1463  if (get_boundary_unit_1st_line(&p->unit2_grp)) return -1;
1464  if (get_boundary_unit_2nd_line(&p->unit2_grp)) return -1;
1465  is_specified_unit2 = 1;
1466 
1467  while ((token = HECMW_ctrllex_next_token()) == HECMW_CTRLLEX_NL)
1468  ;
1469 
1470  if (token == HECMW_CTRLLEX_H_UNIT1) {
1471  if (get_boundary_unit_1st_line(&p->unit1_grp)) return -1;
1472  if (get_boundary_unit_1st_line(&p->unit2_grp)) return -1;
1473  is_specified_unit1 = 1;
1474  }
1475 
1476  /* Invalid Token */
1477  } else {
1480  return -1;
1481  }
1482 
1483  if (!is_specified_unit1) {
1486  return -1;
1487  }
1488  if (!is_specified_unit2) {
1491  return -1;
1492  }
1493 
1494  return 0;
1495 }
1496 
1497 extern int HECMW_couple_ctrl_boundary(void) {
1498  int token, size;
1499  struct boundary_info_by_ctrl *p;
1500 
1501  token = HECMW_ctrllex_next_token();
1502  HECMW_assert(token == HECMW_CTRLLEX_H_COUPLE_BOUNDARY);
1503 
1504  /* allocation & initialization */
1505  size = sizeof(struct boundary_info_by_ctrl);
1506  boundary_info_current->next =
1507  (struct boundary_info_by_ctrl *)HECMW_malloc(size);
1508  if (boundary_info_current->next == NULL) {
1509  HECMW_set_error(errno, "");
1510  return -1;
1511  }
1512  p = boundary_info_current->next;
1513 
1514  memset(p->boundary_id, 0, HECMW_NAME_LEN + 1);
1515  memset(p->couple_id, 0, HECMW_NAME_LEN + 1);
1516  p->interpolation = HECMW_COUPLE_IP_UNDEF;
1517  p->direction = HECMW_COUPLE_DIRECTION_UNDEF;
1518  p->tolerance = HECMW_COUPLE_TOLERANCE_DEFAULT;
1519  p->bbcoef = HECMW_COUPLE_BBCOEF_DEFAULT;
1520  p->bgcoef = HECMW_COUPLE_BGCOEF_DEFAULT;
1521  p->unit1_grp.n_grp = 0;
1522  p->unit1_grp.geom_type = HECMW_COUPLE_GROUP_UNDEF;
1523  p->unit1_grp.data_type = HECMW_COUPLE_GROUP_UNDEF;
1524  memset(p->unit1_grp.grp_name.name, 0, HECMW_NAME_LEN + 1);
1525  p->unit1_grp.grp_name.next = NULL;
1526  p->unit2_grp.n_grp = 0;
1527  p->unit2_grp.geom_type = HECMW_COUPLE_GROUP_UNDEF;
1528  p->unit2_grp.data_type = HECMW_COUPLE_GROUP_UNDEF;
1529  memset(p->unit2_grp.grp_name.name, 0, HECMW_NAME_LEN + 1);
1530  p->unit2_grp.grp_name.next = NULL;
1531  p->next = NULL;
1532 
1533  /* Line 1 */
1534  if (get_boundary_1st_line(p)) return -1;
1535 
1536  if ((token = HECMW_ctrllex_next_token()) == HECMW_CTRLLEX_NL)
1537  ;
1539 
1540  /* Line 2 */
1541  if (get_boundary_2nd_line(p)) return -1;
1542 
1543  boundary_info_current = p;
1544  n_boundary++;
1545 
1546  return 0;
1547 }
1548 
1549 /*================================================================================================*/
1550 
1551 extern int HECMW_couple_ctrl_get_n_unit(void) { return n_unit; }
1552 
1553 extern int HECMW_couple_ctrl_get_n_couple(void) { return n_couple; }
1554 
1555 extern int HECMW_couple_ctrl_get_n_boundary(void) { return n_boundary; }
1556 
1558  int size, i, n;
1559  struct unit_info_by_ctrl *p;
1560  struct hecmw_couple_ctrl_unit_ids *unit_ids = NULL;
1561 
1562  size = sizeof(struct hecmw_couple_ctrl_unit_ids);
1563  unit_ids = (struct hecmw_couple_ctrl_unit_ids *)HECMW_malloc(size);
1564  if (unit_ids == NULL) {
1565  HECMW_set_error(errno, "");
1566  return NULL;
1567  }
1568  unit_ids->n_unit = n_unit;
1569  unit_ids->ids = NULL;
1570 
1571  if (n_unit == 0) return unit_ids;
1572 
1573  unit_ids->ids = (char **)HECMW_malloc(sizeof(char *) * n_unit);
1574  if (unit_ids->ids == NULL) {
1575  HECMW_set_error(errno, "");
1576  HECMW_couple_free_unit_ids(unit_ids);
1577  return NULL;
1578  }
1579  for (i = 0; i < n_unit; i++) {
1580  unit_ids->ids[i] = NULL;
1581  }
1582  for (n = 0, p = unit_info_root.next; p; p = p->next, n++) {
1583  unit_ids->ids[n] = HECMW_strdup(p->unit_id);
1584  if (unit_ids->ids[n] == NULL) {
1585  HECMW_set_error(errno, "");
1586  HECMW_couple_free_unit_ids(unit_ids);
1587  return NULL;
1588  }
1589  }
1590 
1591  return unit_ids;
1592 }
1593 
1595  int size, i, n;
1596  struct couple_info_by_ctrl *p;
1597  struct hecmw_couple_ctrl_couple_ids *couple_ids = NULL;
1598 
1599  size = sizeof(struct hecmw_couple_ctrl_couple_ids);
1600  couple_ids = (struct hecmw_couple_ctrl_couple_ids *)HECMW_malloc(size);
1601  if (couple_ids == NULL) {
1602  HECMW_set_error(errno, "");
1603  return NULL;
1604  }
1605  couple_ids->n_couple = n_couple;
1606  couple_ids->ids = NULL;
1607 
1608  if (n_couple == 0) return couple_ids;
1609 
1610  couple_ids->ids = (char **)HECMW_malloc(sizeof(char *) * n_couple);
1611  if (couple_ids->ids == NULL) {
1612  HECMW_set_error(errno, "");
1613  HECMW_couple_free_couple_ids(couple_ids);
1614  return NULL;
1615  }
1616  for (i = 0; i < n_couple; i++) {
1617  couple_ids->ids[i] = NULL;
1618  }
1619  for (n = 0, p = couple_info_root.next; p; p = p->next, n++) {
1620  couple_ids->ids[n] = HECMW_strdup(p->couple_id);
1621  if (couple_ids->ids[n] == NULL) {
1622  HECMW_set_error(errno, "");
1623  HECMW_couple_free_couple_ids(couple_ids);
1624  return NULL;
1625  }
1626  }
1627 
1628  return couple_ids;
1629 }
1630 
1632  void) {
1633  int size, i, n;
1634  struct boundary_info_by_ctrl *p;
1635  struct hecmw_couple_ctrl_boundary_ids *boundary_ids = NULL;
1636 
1637  size = sizeof(struct hecmw_couple_ctrl_boundary_ids);
1638  boundary_ids = (struct hecmw_couple_ctrl_boundary_ids *)HECMW_malloc(size);
1639  if (boundary_ids == NULL) {
1640  HECMW_set_error(errno, "");
1641  return NULL;
1642  }
1643  boundary_ids->n_boundary = n_boundary;
1644  boundary_ids->ids = NULL;
1645 
1646  if (n_boundary == 0) return boundary_ids;
1647 
1648  boundary_ids->ids = (char **)HECMW_malloc(sizeof(char *) * n_boundary);
1649  if (boundary_ids->ids == NULL) {
1650  HECMW_set_error(errno, "");
1651  HECMW_couple_free_boundary_ids(boundary_ids);
1652  return NULL;
1653  }
1654  for (i = 0; i < n_boundary; i++) {
1655  boundary_ids->ids[i] = NULL;
1656  }
1657  for (n = 0, p = boundary_info_root.next; p; p = p->next, n++) {
1658  boundary_ids->ids[n] = HECMW_strdup(p->boundary_id);
1659  if (boundary_ids->ids[n] == NULL) {
1660  HECMW_set_error(errno, "");
1661  HECMW_couple_free_boundary_ids(boundary_ids);
1662  return NULL;
1663  }
1664  }
1665 
1666  return boundary_ids;
1667 }
1668 
1669 extern char *HECMW_couple_ctrl_get_unit_id(const char *couple_id,
1670  int unit_specifier, char *buf,
1671  int bufsize) {
1672  char *retbuf, *unit_id;
1673  struct couple_info_by_ctrl *p;
1674 
1675  if (couple_id == NULL) {
1677  "Invalid NULL pointer is found (couple_id)");
1678  return NULL;
1679  }
1680 
1681  p = get_couple_by_id(couple_id);
1682  if (p == NULL) {
1683  HECMW_set_error(HECMWCPL_E_UNDEF_COUPLE_ID, "%s", couple_id);
1684  return NULL;
1685  }
1686 
1687  if (unit_specifier == HECMW_COUPLE_UNIT1) {
1688  unit_id = p->unit1_id;
1689  } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1690  unit_id = p->unit2_id;
1691  } else {
1692  HECMW_assert(0);
1693  }
1694 
1695  if (buf == NULL) {
1696  retbuf = HECMW_strdup(unit_id);
1697  if (retbuf == NULL) {
1698  HECMW_set_error(errno, "");
1699  return NULL;
1700  }
1701  } else {
1702  snprintf(buf, bufsize, "%s", unit_id);
1703  retbuf = buf;
1704  }
1705 
1706  return retbuf;
1707 }
1708 
1709 extern char *HECMW_couple_ctrl_get_couple_id(const char *boundary_id, char *buf,
1710  int bufsize) {
1711  char *retbuf;
1712  struct boundary_info_by_ctrl *p;
1713 
1714  if (boundary_id == NULL) {
1716  "Invalid NULL pointer is found (boundary_id)");
1717  return NULL;
1718  }
1719 
1720  p = get_boundary_by_id(boundary_id);
1721  if (p == NULL) {
1722  HECMW_set_error(HECMWCPL_E_UNDEF_BOUNDARY_ID, "%s", boundary_id);
1723  return NULL;
1724  }
1725 
1726  if (buf == NULL) {
1727  retbuf = HECMW_strdup(p->couple_id);
1728  if (retbuf == NULL) {
1729  HECMW_set_error(errno, "");
1730  return NULL;
1731  }
1732  } else {
1733  snprintf(buf, bufsize, "%s", p->couple_id);
1734  retbuf = buf;
1735  }
1736 
1737  return retbuf;
1738 }
1739 
1741  const char *unit_id) {
1742  int size, n;
1743  struct hecmw_couple_ctrl_proc *proc_info;
1744  struct unit_info_by_ctrl *p;
1745  struct link_list_i *q;
1746 
1747  if (unit_id == NULL) {
1749  "Invalid NULL pointer is found (unit_id)");
1750  return NULL;
1751  }
1752 
1753  p = get_unit_by_id(unit_id);
1754  if (p == NULL) {
1755  HECMW_set_error(HECMWCPL_E_UNDEF_UNIT_ID, "%s", unit_id);
1756  return NULL;
1757  }
1758 
1759  size = sizeof(struct hecmw_couple_ctrl_proc);
1760  proc_info = (struct hecmw_couple_ctrl_proc *)HECMW_malloc(size);
1761  if (proc_info == NULL) {
1762  HECMW_set_error(errno, "");
1763  return NULL;
1764  }
1765  proc_info->n_proc = p->n_proc;
1766  proc_info->is_specified_ranks = p->is_specified_ranks;
1767  proc_info->ranks = NULL;
1768 
1769  if (!proc_info->is_specified_ranks) return proc_info;
1770 
1771  proc_info->ranks = (int *)HECMW_calloc(proc_info->n_proc, sizeof(int));
1772  if (proc_info->ranks == NULL) {
1773  HECMW_set_error(errno, "");
1774  HECMW_couple_ctrl_free_proc(proc_info);
1775  return NULL;
1776  }
1777  for (n = 0, q = p->ranks.next; q; q = q->next, n++) {
1778  proc_info->ranks[n] = q->rank;
1779  }
1780 
1781  return proc_info;
1782 }
1783 
1784 extern int HECMW_couple_ctrl_get_type(const char *couple_id, int *couple_type) {
1785  struct couple_info_by_ctrl *p;
1786 
1787  if (couple_id == NULL) {
1789  return -1;
1790  }
1791 
1792  p = get_couple_by_id(couple_id);
1793  if (p == NULL) {
1794  HECMW_set_error(HECMWCPL_E_UNDEF_COUPLE_ID, "%s", couple_id);
1795  return -1;
1796  }
1797  *couple_type = p->couple_type;
1798 
1799  return 0;
1800 }
1801 
1802 extern int HECMW_couple_ctrl_get_direction(const char *boundary_id,
1803  int *direction) {
1804  struct boundary_info_by_ctrl *p;
1805 
1806  if (boundary_id == NULL) {
1808  "Invalid NULL pointer is found (boundary_id)");
1809  return -1;
1810  }
1811 
1812  p = get_boundary_by_id(boundary_id);
1813  if (p == NULL) {
1814  HECMW_set_error(HECMWCPL_E_UNDEF_BOUNDARY_ID, "%s", boundary_id);
1815  return -1;
1816  }
1817  *direction = p->direction;
1818 
1819  return 0;
1820 }
1821 
1822 extern int HECMW_couple_ctrl_get_tolerance(const char *boundary_id,
1823  double *tolerance) {
1824  struct boundary_info_by_ctrl *p;
1825 
1826  if (boundary_id == NULL) {
1828  "Invalid NULL pointer is found (boundary_id)");
1829  return -1;
1830  }
1831 
1832  p = get_boundary_by_id(boundary_id);
1833  if (p == NULL) {
1834  HECMW_set_error(HECMWCPL_E_UNDEF_BOUNDARY_ID, "%s", boundary_id);
1835  return -1;
1836  }
1837  *tolerance = p->tolerance;
1838 
1839  return 0;
1840 }
1841 
1842 extern int HECMW_couple_ctrl_get_bbcoef(const char *boundary_id,
1843  double *bbcoef) {
1844  struct boundary_info_by_ctrl *p;
1845 
1846  if (boundary_id == NULL) {
1848  "Invalid NULL pointer is found (boundary_id)");
1849  return -1;
1850  }
1851 
1852  p = get_boundary_by_id(boundary_id);
1853  if (p == NULL) {
1854  HECMW_set_error(HECMWCPL_E_UNDEF_BOUNDARY_ID, "%s", boundary_id);
1855  return -1;
1856  }
1857  *bbcoef = p->bbcoef;
1858 
1859  return 0;
1860 }
1861 
1862 extern int HECMW_couple_ctrl_get_bgcoef(const char *boundary_id,
1863  double *bgcoef) {
1864  struct boundary_info_by_ctrl *p;
1865 
1866  if (boundary_id == NULL) {
1868  "Invalid NULL pointer is found (boundary_id)");
1869  return -1;
1870  }
1871 
1872  p = get_boundary_by_id(boundary_id);
1873  if (p == NULL) {
1874  HECMW_set_error(HECMWCPL_E_UNDEF_BOUNDARY_ID, "%s", boundary_id);
1875  return -1;
1876  }
1877  *bgcoef = p->bgcoef;
1878 
1879  return 0;
1880 }
1881 
1883  const char *boundary_id, int unit_specifier) {
1884  int size, i, n;
1885  struct hecmw_couple_group *grp_info = NULL;
1886  struct group_info_by_ctrl *grp_info_ctrl = NULL;
1887  struct boundary_info_by_ctrl *p;
1888  struct link_list_s *q;
1889 
1890  if (boundary_id == NULL) {
1892  "Invalid NULL pointer is found (boundary_id)");
1893  return NULL;
1894  }
1895  if ((unit_specifier != HECMW_COUPLE_UNIT1) &&
1896  (unit_specifier != HECMW_COUPLE_UNIT2)) {
1898  "Unrecognized unit specifier is found (unit_specifier)");
1899  return NULL;
1900  }
1901 
1902  p = get_boundary_by_id(boundary_id);
1903  if (p == NULL) {
1904  HECMW_set_error(HECMWCPL_E_UNDEF_BOUNDARY_ID, "%s", boundary_id);
1905  return NULL;
1906  }
1907 
1908  if (unit_specifier == HECMW_COUPLE_UNIT1) {
1909  grp_info_ctrl = &p->unit1_grp;
1910  } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1911  grp_info_ctrl = &p->unit2_grp;
1912  } else {
1914  return NULL;
1915  }
1916 
1917  size = sizeof(struct hecmw_couple_group);
1918  grp_info = (struct hecmw_couple_group *)HECMW_malloc(size);
1919  if (grp_info == NULL) {
1920  HECMW_set_error(errno, "");
1921  return NULL;
1922  }
1923  grp_info->n_grp = grp_info_ctrl->n_grp;
1924  grp_info->geom_type = grp_info_ctrl->geom_type;
1925  grp_info->data_type = grp_info_ctrl->data_type;
1926 
1927  grp_info->grp_name = (char **)HECMW_malloc(sizeof(char *) * grp_info->n_grp);
1928  if (grp_info->grp_name == NULL) {
1929  HECMW_set_error(errno, "");
1930  HECMW_couple_ctrl_free_group(grp_info);
1931  return NULL;
1932  }
1933  for (i = 0; i < grp_info->n_grp; i++) {
1934  grp_info->grp_name[i] == NULL;
1935  }
1936  for (n = 0, q = grp_info_ctrl->grp_name.next; q; q = q->next, n++) {
1937  grp_info->grp_name[n] = HECMW_strdup(q->name);
1938  if (grp_info->grp_name[n] == NULL) {
1939  HECMW_set_error(errno, "");
1940  HECMW_couple_ctrl_free_group(grp_info);
1941  return NULL;
1942  }
1943  }
1944 
1945  return grp_info;
1946 }
#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)
void HECMW_couple_free_couple_ids(struct hecmw_couple_ctrl_couple_ids *couple_ids)
int HECMW_couple_ctrl_get_n_couple(void)
void HECMW_couple_free_unit_ids(struct hecmw_couple_ctrl_unit_ids *unit_ids)
int HECMW_couple_ctrl_get_direction(const char *boundary_id, int *direction)
int HECMW_couple_ctrl_get_tolerance(const char *boundary_id, double *tolerance)
int HECMW_couple_ctrl_boundary(void)
void HECMW_couple_free_boundary_ids(struct hecmw_couple_ctrl_boundary_ids *boundary_ids)
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)
int HECMW_couple_ctrl_get_n_unit(void)
int HECMW_couple_ctrl_couple(void)
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)
void HECMW_couple_ctrl_print_couple(FILE *fp)
void HECMW_couple_ctrl_print_boundary(FILE *fp)
struct hecmw_couple_ctrl_proc * HECMW_couple_ctrl_get_proc(const char *unit_id)
void HECMW_couple_ctrl_free(void)
int HECMW_couple_ctrl_get_bbcoef(const char *boundary_id, double *bbcoef)
int HECMW_couple_ctrl_unit(void)
void HECMW_couple_ctrl_print_unit(FILE *fp)
int HECMW_couple_ctrl_get_n_boundary(void)
struct hecmw_couple_ctrl_couple_ids * HECMW_couple_get_couple_ids(void)
#define HECMW_COUPLE_ELEMENT_GROUP
#define HECMWCPL_E_CPL_NO_NAME
#define HECMWCPL_E_INVALID_UNITTYPE
#define HECMW_COUPLE_BGCOEF_DEFAULT
#define HECMWCPL_E_CPLU_NO_NAME
#define HECMWCPL_E_UNDEF_UNIT_ID
#define HECMW_COUPLE_TYPE_UNDEF
#define HECMWCPL_E_CPLB_UNMATCH_GRPTYPE
#define HECMWCPL_E_CPLB_NO_UNIT1
#define HECMWCPL_E_CPLU_UNMATCH_RANKS
#define HECMW_COUPLE_UNIT1
#define HECMWCPL_E_UNDEF_COUPLE_ID
#define HECMW_COUPLE_NODE_GROUP
#define HECMWCPL_E_CPLB_NO_NAME
#define HECMWCPL_E_CPLB_NO_DATA
#define HECMW_COUPLE_BBCOEF_DEFAULT
#define HECMWCPL_E_CPL_NO_UNIT2
#define HECMWCPL_E_CTRL_INVALID_TOKEN
#define HECMW_COUPLE_DIRECTION_UNDEF
#define HECMWCPL_E_CPL_NO_UNIT1
#define HECMW_COUPLE_FALSE
#define HECMW_COUPLE_UNIT2_TO_UNIT1
#define HECMWCPL_E_CPLB_NO_UNIT2
#define HECMWCPL_E_CPL_NO_TYPE
#define HECMWCPL_E_UNDEF_BOUNDARY_ID
#define HECMW_COUPLE_IP_UNDEF
#define HECMWCPL_E_CPLU_NO_NPROC
#define HECMW_COUPLE_GROUP_UNDEF
#define HECMW_COUPLE_TYPE_MAXMN
#define HECMW_COUPLE_TOLERANCE_DEFAULT
#define HECMWCPL_E_CPLB_NO_DIRECTION
#define HECMWCPL_E_CPLB_NO_GEOM
#define HECMWCPL_E_INVALID_ARG
#define HECMW_COUPLE_SURFACE_GROUP
#define HECMWCPL_E_CPLB_NO_GRPNAME
#define HECMW_COUPLE_TYPE_MXN
#define HECMWCPL_E_CPLB_NO_COUPLE
#define HECMW_COUPLE_UNIT1_TO_UNIT2
#define HECMW_COUPLE_UNIT2
#define HECMW_COUPLE_TYPE_MANUAL
double HECMW_ctrllex_get_number(void)
char * HECMW_ctrllex_get_text(void)
int HECMW_ctrllex_unput_token(void)
@ HECMW_CTRLLEX_K_NAME
Definition: hecmw_ctrllex.h:35
@ HECMW_CTRLLEX_DOUBLE
Definition: hecmw_ctrllex.h:14
@ HECMW_CTRLLEX_INT
Definition: hecmw_ctrllex.h:13
@ HECMW_CTRLLEX_K_TYPE
Definition: hecmw_ctrllex.h:41
@ HECMW_CTRLLEX_NL
Definition: hecmw_ctrllex.h:12
@ HECMW_CTRLLEX_NAME
Definition: hecmw_ctrllex.h:15
int HECMW_ctrllex_next_token(void)
int HECMW_ctrllex_get_lineno(void)
int HECMW_set_error(int errorno, const char *fmt,...)
Definition: hecmw_error.c:33
#define NULL
#define HECMW_calloc(nmemb, size)
Definition: hecmw_malloc.h:21
#define HECMW_free(ptr)
Definition: hecmw_malloc.h:24
#define HECMW_strdup(s)
Definition: hecmw_malloc.h:23
#define HECMW_malloc(size)
Definition: hecmw_malloc.h:20
#define HECMW_assert(cond)
Definition: hecmw_util.h:40
struct link_list_s grp_name