FrontISTR 5.2.0
Large-scale structural analysis program with finit element method
Loading...
Searching...
No Matches
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" */
23
24/*================================================================================================*/
25
27 int rank;
29};
30
34};
35
36static 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
53static 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;
72};
73
74static 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
110static struct unit_info_by_ctrl *unit_info_current = &unit_info_root;
111
112static struct couple_info_by_ctrl *couple_info_current = &couple_info_root;
113
114static struct boundary_info_by_ctrl *boundary_info_current =
115 &boundary_info_root;
116
117static int n_unit = 0;
118
119static int n_couple = 0;
120
121static int n_boundary = 0;
122
123/*================================================================================================*/
124
125static 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
134static 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
143extern 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
158extern 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
169extern 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
198static 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
210static 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
222static 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);
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
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
306static 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
317static 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
327static 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
339extern void HECMW_couple_ctrl_free(void) {
340 free_unit();
341 free_couple();
342 free_boundary();
343}
344
345/*================================================================================================*/
346
347static int get_unit_name(char *unit_id) {
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 strcpy(unit_id, s);
374
375 return 0;
376}
377
378static 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
408static 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)",
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
456static 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)) 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
521static 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
550extern 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 */
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
591static int get_couple_name(char *couple_id) {
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 strcpy(couple_id, s);
618
619 return 0;
620}
621
622static 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 */
639 } else if (token == HECMW_CTRLLEX_K_MANUAL) { /* MANUAL */
641 } else { /* Invalid Token */
643 "line %d: Invalid 'TYPE' is specified in '!COUPLE'",
645 return -1;
646 }
647
648 return 0;
649}
650
651static int get_couple_unit1(char *unit1_id) {
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 strcpy(unit1_id, s);
682
683 return 0;
684}
685
686static int get_couple_unit2(char *unit2_id) {
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 strcpy(unit2_id, s);
717
718 return 0;
719}
720
721static 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)) 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)) 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)) 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
822extern 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
854static int get_boundary_name(char *boundary_id) {
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 strcpy(boundary_id, s);
883
884 return 0;
885}
886
887static int get_boundary_couple(char *couple_id) {
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 strcpy(couple_id, s);
920
921 return 0;
922}
923
924static 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
954static 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
974static 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 */
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
1006static 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 */
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
1038static 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 */
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
1070static 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) != 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) != 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) {
1187 return -1;
1188 }
1189 /* COUPLE is not specified */
1190 if (!is_specified_couple) {
1193 return -1;
1194 }
1195 /* DIRECTION is not specified */
1196 if (!is_specified_direction) {
1199 return -1;
1200 }
1201
1202 return 0;
1203}
1204
1205/*------------------------------------------------------------------------------------------------*/
1206
1207static 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
1238static 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
1269static 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 }
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 strcpy(p->name, 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
1317static 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) {
1339 return -1;
1340 }
1341
1342 return 0;
1343}
1344
1345static 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) {
1397 return -1;
1398 }
1399 if (!is_specified_data) {
1402 return -1;
1403 }
1404
1409 "line %d: NODE is specified in 'GEOM', but 'DATA' is not NODE",
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",
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",
1429 return -1;
1430 }
1431 } else {
1432 HECMW_assert(0);
1433 }
1434
1435 return 0;
1436}
1437
1438static 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
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
1551extern int HECMW_couple_ctrl_get_n_unit(void) { return n_unit; }
1552
1553extern int HECMW_couple_ctrl_get_n_couple(void) { return n_couple; }
1554
1555extern 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, "");
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, "");
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
1669extern char *HECMW_couple_ctrl_get_unit_id(const char *couple_id,
1670 int unit_specifier, char *buf,
1671 int bufsize) {
1672 int len;
1673 char *retbuf, *unit_id;
1674 struct couple_info_by_ctrl *p;
1675
1676 if (couple_id == NULL) {
1678 "Invalid NULL pointer is found (couple_id)");
1679 return NULL;
1680 }
1681
1682 p = get_couple_by_id(couple_id);
1683 if (p == NULL) {
1685 return NULL;
1686 }
1687
1688 if (unit_specifier == HECMW_COUPLE_UNIT1) {
1689 unit_id = p->unit1_id;
1690 } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1691 unit_id = p->unit2_id;
1692 } else {
1693 HECMW_assert(0);
1694 }
1695
1696 if (buf == NULL) {
1697 retbuf = HECMW_strdup(unit_id);
1698 if (retbuf == NULL) {
1699 HECMW_set_error(errno, "");
1700 return NULL;
1701 }
1702 } else {
1703 len = strlen(unit_id);
1704 if (bufsize <= len) {
1705 len = bufsize - 1;
1706 }
1707 strncpy(buf, unit_id, len);
1708 buf[len] = '\0';
1709 retbuf = buf;
1710 }
1711
1712 return retbuf;
1713}
1714
1715extern char *HECMW_couple_ctrl_get_couple_id(const char *boundary_id, char *buf,
1716 int bufsize) {
1717 int len;
1718 char *retbuf;
1719 struct boundary_info_by_ctrl *p;
1720
1721 if (boundary_id == NULL) {
1723 "Invalid NULL pointer is found (boundary_id)");
1724 return NULL;
1725 }
1726
1727 p = get_boundary_by_id(boundary_id);
1728 if (p == NULL) {
1730 return NULL;
1731 }
1732
1733 if (buf == NULL) {
1734 retbuf = HECMW_strdup(p->couple_id);
1735 if (retbuf == NULL) {
1736 HECMW_set_error(errno, "");
1737 return NULL;
1738 }
1739 } else {
1740 len = strlen(p->couple_id);
1741 if (bufsize <= len) {
1742 len = bufsize - 1;
1743 }
1744 strncpy(buf, p->couple_id, len);
1745 buf[len] = '\0';
1746 retbuf = buf;
1747 }
1748
1749 return retbuf;
1750}
1751
1753 const char *unit_id) {
1754 int size, n;
1755 struct hecmw_couple_ctrl_proc *proc_info;
1756 struct unit_info_by_ctrl *p;
1757 struct link_list_i *q;
1758
1759 if (unit_id == NULL) {
1761 "Invalid NULL pointer is found (unit_id)");
1762 return NULL;
1763 }
1764
1765 p = get_unit_by_id(unit_id);
1766 if (p == NULL) {
1768 return NULL;
1769 }
1770
1771 size = sizeof(struct hecmw_couple_ctrl_proc);
1772 proc_info = (struct hecmw_couple_ctrl_proc *)HECMW_malloc(size);
1773 if (proc_info == NULL) {
1774 HECMW_set_error(errno, "");
1775 return NULL;
1776 }
1777 proc_info->n_proc = p->n_proc;
1778 proc_info->is_specified_ranks = p->is_specified_ranks;
1779 proc_info->ranks = NULL;
1780
1781 if (!proc_info->is_specified_ranks) return proc_info;
1782
1783 proc_info->ranks = (int *)HECMW_calloc(proc_info->n_proc, sizeof(int));
1784 if (proc_info->ranks == NULL) {
1785 HECMW_set_error(errno, "");
1786 HECMW_couple_ctrl_free_proc(proc_info);
1787 return NULL;
1788 }
1789 for (n = 0, q = p->ranks.next; q; q = q->next, n++) {
1790 proc_info->ranks[n] = q->rank;
1791 }
1792
1793 return proc_info;
1794}
1795
1796extern int HECMW_couple_ctrl_get_type(const char *couple_id, int *couple_type) {
1797 struct couple_info_by_ctrl *p;
1798
1799 if (couple_id == NULL) {
1801 return -1;
1802 }
1803
1804 p = get_couple_by_id(couple_id);
1805 if (p == NULL) {
1807 return -1;
1808 }
1809 *couple_type = p->couple_type;
1810
1811 return 0;
1812}
1813
1814extern int HECMW_couple_ctrl_get_direction(const char *boundary_id,
1815 int *direction) {
1816 struct boundary_info_by_ctrl *p;
1817
1818 if (boundary_id == NULL) {
1820 "Invalid NULL pointer is found (boundary_id)");
1821 return -1;
1822 }
1823
1824 p = get_boundary_by_id(boundary_id);
1825 if (p == NULL) {
1827 return -1;
1828 }
1829 *direction = p->direction;
1830
1831 return 0;
1832}
1833
1834extern int HECMW_couple_ctrl_get_tolerance(const char *boundary_id,
1835 double *tolerance) {
1836 struct boundary_info_by_ctrl *p;
1837
1838 if (boundary_id == NULL) {
1840 "Invalid NULL pointer is found (boundary_id)");
1841 return -1;
1842 }
1843
1844 p = get_boundary_by_id(boundary_id);
1845 if (p == NULL) {
1847 return -1;
1848 }
1849 *tolerance = p->tolerance;
1850
1851 return 0;
1852}
1853
1854extern int HECMW_couple_ctrl_get_bbcoef(const char *boundary_id,
1855 double *bbcoef) {
1856 struct boundary_info_by_ctrl *p;
1857
1858 if (boundary_id == NULL) {
1860 "Invalid NULL pointer is found (boundary_id)");
1861 return -1;
1862 }
1863
1864 p = get_boundary_by_id(boundary_id);
1865 if (p == NULL) {
1867 return -1;
1868 }
1869 *bbcoef = p->bbcoef;
1870
1871 return 0;
1872}
1873
1874extern int HECMW_couple_ctrl_get_bgcoef(const char *boundary_id,
1875 double *bgcoef) {
1876 struct boundary_info_by_ctrl *p;
1877
1878 if (boundary_id == NULL) {
1880 "Invalid NULL pointer is found (boundary_id)");
1881 return -1;
1882 }
1883
1884 p = get_boundary_by_id(boundary_id);
1885 if (p == NULL) {
1887 return -1;
1888 }
1889 *bgcoef = p->bgcoef;
1890
1891 return 0;
1892}
1893
1895 const char *boundary_id, int unit_specifier) {
1896 int size, i, n;
1897 struct hecmw_couple_group *grp_info = NULL;
1898 struct group_info_by_ctrl *grp_info_ctrl = NULL;
1899 struct boundary_info_by_ctrl *p;
1900 struct link_list_s *q;
1901
1902 if (boundary_id == NULL) {
1904 "Invalid NULL pointer is found (boundary_id)");
1905 return NULL;
1906 }
1907 if ((unit_specifier != HECMW_COUPLE_UNIT1) &&
1908 (unit_specifier != HECMW_COUPLE_UNIT2)) {
1910 "Unrecognized unit specifier is found (unit_specifier)");
1911 return NULL;
1912 }
1913
1914 p = get_boundary_by_id(boundary_id);
1915 if (p == NULL) {
1917 return NULL;
1918 }
1919
1920 if (unit_specifier == HECMW_COUPLE_UNIT1) {
1921 grp_info_ctrl = &p->unit1_grp;
1922 } else if (unit_specifier == HECMW_COUPLE_UNIT2) {
1923 grp_info_ctrl = &p->unit2_grp;
1924 } else {
1926 return NULL;
1927 }
1928
1929 size = sizeof(struct hecmw_couple_group);
1930 grp_info = (struct hecmw_couple_group *)HECMW_malloc(size);
1931 if (grp_info == NULL) {
1932 HECMW_set_error(errno, "");
1933 return NULL;
1934 }
1935 grp_info->n_grp = grp_info_ctrl->n_grp;
1936 grp_info->geom_type = grp_info_ctrl->geom_type;
1937 grp_info->data_type = grp_info_ctrl->data_type;
1938
1939 grp_info->grp_name = (char **)HECMW_malloc(sizeof(char *) * grp_info->n_grp);
1940 if (grp_info->grp_name == NULL) {
1941 HECMW_set_error(errno, "");
1943 return NULL;
1944 }
1945 for (i = 0; i < grp_info->n_grp; i++) {
1946 grp_info->grp_name[i] == NULL;
1947 }
1948 for (n = 0, q = grp_info_ctrl->grp_name.next; q; q = q->next, n++) {
1949 grp_info->grp_name[n] = HECMW_strdup(q->name);
1950 if (grp_info->grp_name[n] == NULL) {
1951 HECMW_set_error(errno, "");
1953 return NULL;
1954 }
1955 }
1956
1957 return grp_info;
1958}
#define HECMW_SUCCESS
Definition: hecmw_config.h:64
#define HECMW_NAME_LEN
Definition: hecmw_config.h:70
int HECMW_couple_ctrl_get_type(const char *couple_id, int *couple_type)
struct hecmw_couple_ctrl_unit_ids * HECMW_couple_get_unit_ids(void)
void HECMW_couple_ctrl_free_proc(struct hecmw_couple_ctrl_proc *proc_info)
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)
struct hecmw_couple_group * HECMW_couple_ctrl_get_group(const char *boundary_id, int unit_specifier)
void HECMW_couple_free_boundary_ids(struct hecmw_couple_ctrl_boundary_ids *boundary_ids)
struct hecmw_couple_ctrl_couple_ids * HECMW_couple_get_couple_ids(void)
int HECMW_couple_ctrl_get_bgcoef(const char *boundary_id, double *bgcoef)
int HECMW_couple_ctrl_get_n_unit(void)
int HECMW_couple_ctrl_couple(void)
void HECMW_couple_ctrl_free_group(struct hecmw_couple_group *grp_info)
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)
struct hecmw_couple_ctrl_boundary_ids * HECMW_couple_get_boundary_ids(void)
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)
char * HECMW_couple_ctrl_get_couple_id(const char *boundary_id, char *buf, int bufsize)
int HECMW_couple_ctrl_get_n_boundary(void)
char * HECMW_couple_ctrl_get_unit_id(const char *couple_id, int unit_specifier, char *buf, int bufsize)
#define 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)
int HECMW_ctrllex_next_token(void)
int HECMW_ctrllex_get_lineno(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_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
struct link_list_s grp_name