FrontISTR 5.2.0
Large-scale structural analysis program with finit element method
Loading...
Searching...
No Matches
hecmw_couple_boundary_info.c
Go to the documentation of this file.
1/*****************************************************************************
2 * Copyright (c) 2019 FrontISTR Commons
3 * This software is released under the MIT License, see LICENSE.txt
4 *****************************************************************************/
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <assert.h>
10#include <errno.h>
11
12#include "hecmw_msgno.h"
13#include "hecmw_common_define.h"
14#include "hecmw_struct.h"
15
16#include "hecmw_couple_define.h"
17#include "hecmw_couple_struct.h"
18#include "hecmw_couple_table.h"
20#include "hecmw_couple_info.h"
22
23struct link_list {
24 int item;
25 struct link_list *next;
26};
27
28/*================================================================================================*/
29
30static void free_link_list(struct link_list *r) {
31 struct link_list *p, *q;
32
33 for (p = r; p; p = q) {
34 q = p->next;
35 HECMW_free(p);
36 }
37}
38
40 struct hecmw_couple_boundary *boundary) {
41 if (boundary == NULL) return;
42
43 if (boundary->node) {
44 HECMW_free(boundary->node->item);
45 HECMW_free(boundary->node);
46 }
47 if (boundary->elem) {
48 HECMW_free(boundary->elem->item);
49 HECMW_free(boundary->elem);
50 }
51 if (boundary->surf) {
52 HECMW_free(boundary->surf->item);
53 HECMW_free(boundary->surf);
54 }
55 HECMW_free(boundary->elem_node_index);
56 HECMW_free(boundary->elem_node_item);
57
58 HECMW_free(boundary);
59 boundary = NULL;
60}
61
63 struct hecmw_couple_boundary *boundary = NULL;
64 int size;
65
66 size = sizeof(struct hecmw_couple_boundary);
67 boundary = (struct hecmw_couple_boundary *)HECMW_malloc(size);
68 if (boundary == NULL) {
69 HECMW_set_error(errno, "");
70 goto error;
71 }
72 boundary->node = NULL;
73 boundary->elem = NULL;
74 boundary->surf = NULL;
75
78
79 size = sizeof(struct hecmw_couple_boundary_item);
80 boundary->node = (struct hecmw_couple_boundary_item *)HECMW_malloc(size);
81 if (boundary->node == NULL) {
82 HECMW_set_error(errno, "");
83 goto error;
84 }
85 boundary->node->n = 0;
86 boundary->node->item = NULL;
87
88 boundary->elem = (struct hecmw_couple_boundary_item *)HECMW_malloc(size);
89 if (boundary->elem == NULL) {
90 HECMW_set_error(errno, "");
91 goto error;
92 }
93 boundary->elem->n = 0;
94 boundary->elem->item = NULL;
95
96 boundary->surf = (struct hecmw_couple_boundary_item *)HECMW_malloc(size);
97 if (boundary->surf == NULL) {
98 HECMW_set_error(errno, "");
99 goto error;
100 }
101 boundary->surf->n = 0;
102 boundary->surf->item = NULL;
103
104 boundary->elem_node_item = NULL;
105 boundary->elem_node_index = NULL;
106
107 return boundary;
108
109error:
111 return NULL;
112}
113
114/*================================================================================================*/
115
116static int check_group_name(int n_grp_mesh, char **grp_name_mesh,
117 const char *grp_name_ctrl) {
118 int i;
119
120 for (i = 0; i < n_grp_mesh; i++) {
121 if ((strcmp(grp_name_ctrl, grp_name_mesh[i])) == 0) return i;
122 }
123
124 return -1;
125}
126
127static int check_node_group_name(const struct hecmwST_local_mesh *mesh,
128 const struct hecmw_couple_group *group) {
129 struct hecmwST_node_grp *node_grp = mesh->node_group;
130 int i;
131
132 for (i = 0; i < group->n_grp; i++) {
133 if (check_group_name(node_grp->n_grp, node_grp->grp_name,
134 group->grp_name[i]) < 0) {
136 group->grp_name[i]);
137 return -1;
138 }
139 }
140
141 return 0;
142}
143
144static int check_elem_group_name(const struct hecmwST_local_mesh *mesh,
145 const struct hecmw_couple_group *group) {
146 struct hecmwST_elem_grp *elem_grp = mesh->elem_group;
147 int i;
148
149 for (i = 0; i < group->n_grp; i++) {
150 if (check_group_name(elem_grp->n_grp, elem_grp->grp_name,
151 group->grp_name[i]) < 0) {
152 HECMW_set_error(HECMWCPL_E_UNDEF_GRPNAME, "element group: %s",
153 group->grp_name[i]);
154 return -1;
155 }
156 }
157
158 return 0;
159}
160
161static int check_surf_group_name(const struct hecmwST_local_mesh *mesh,
162 const struct hecmw_couple_group *group) {
163 struct hecmwST_surf_grp *surf_grp = mesh->surf_group;
164 int i;
165
166 for (i = 0; i < group->n_grp; i++) {
167 if (check_group_name(surf_grp->n_grp, surf_grp->grp_name,
168 group->grp_name[i]) < 0) {
169 HECMW_set_error(HECMWCPL_E_UNDEF_GRPNAME, "surface group: %s",
170 group->grp_name[i]);
171 return HECMW_ERROR;
172 }
173 }
174
175 return 0;
176}
177
178/*------------------------------------------------------------------------------------------------*/
179
180static int set_boundary_node_by_node(const struct hecmwST_local_mesh *mesh,
181 const struct hecmw_couple_group *group,
182 struct hecmw_couple_boundary *boundary) {
183 int *mask = NULL;
184 int node, index, n, i, j;
185
187 if (group->n_grp == 0) return 0;
188
189 /* mask boundary nodes */
190 mask = (int *)HECMW_malloc(sizeof(int) * mesh->n_node);
191 if (mask == NULL) {
192 HECMW_set_error(errno, "");
193 return -1;
194 }
195 for (i = 0; i < mesh->n_node; i++) {
196 mask[i] = HECMW_COUPLE_FALSE;
197 }
198
199 for (i = 0; i < group->n_grp; i++) {
200 index = check_group_name(mesh->node_group->n_grp,
201 mesh->node_group->grp_name, group->grp_name[i]);
202 HECMW_assert(index >= 0);
203
204 for (j = mesh->node_group->grp_index[index];
205 j < mesh->node_group->grp_index[index + 1]; j++) {
206 node = mesh->node_group->grp_item[j];
207 mask[node - 1] = HECMW_COUPLE_TRUE;
208 }
209 }
210
211 /* number of boundary nodes */
212 for (n = 0, i = 0; i < mesh->n_node; i++) {
213 if (mask[i] == HECMW_COUPLE_TRUE) n++;
214 }
215 boundary->node->n = n;
216 if (boundary->node->n == 0) {
217 HECMW_free(mask);
218 return 0;
219 }
220
221 /* ids of boundary node */
222 boundary->node->item = (int *)HECMW_calloc(boundary->node->n, sizeof(int));
223 if (boundary->node->item == NULL) {
224 HECMW_set_error(errno, "");
225 goto error;
226 }
227 for (n = 0, i = 0; i < mesh->n_node; i++) {
228 if (mask[i] == HECMW_COUPLE_TRUE) boundary->node->item[n++] = j + 1;
229 }
230 HECMW_assert(n == boundary->node->n);
231
232 HECMW_free(mask);
233 return 0;
234
235error:
236 HECMW_free(mask);
237 return -1;
238}
239
240static int set_boundary_elem_by_elem(const struct hecmwST_local_mesh *mesh,
241 const struct hecmw_couple_group *group,
242 struct hecmw_couple_boundary *boundary) {
243 int *mask = NULL;
244 int elem, index, n, i, j;
245
247 if (group->n_grp == 0) return 0;
248
249 /* mask boundary nodes */
250 mask = (int *)HECMW_malloc(sizeof(int) * mesh->n_elem);
251 if (mask == NULL) {
252 HECMW_set_error(errno, "");
253 return -1;
254 }
255 for (i = 0; i < mesh->n_elem; i++) {
256 mask[i] = HECMW_COUPLE_FALSE;
257 }
258
259 for (i = 0; i < group->n_grp; i++) {
260 index = check_group_name(mesh->elem_group->n_grp,
261 mesh->elem_group->grp_name, group->grp_name[i]);
262 HECMW_assert(index >= 0);
263
264 for (j = mesh->elem_group->grp_index[index];
265 j < mesh->elem_group->grp_index[index + 1]; j++) {
266 elem = mesh->elem_group->grp_item[j];
267 mask[elem - 1] = HECMW_COUPLE_TRUE;
268 }
269 }
270
271 /* number of boundary nodes */
272 for (n = 0, i = 0; i < mesh->n_elem; i++) {
273 if (mask[i] == HECMW_COUPLE_TRUE) n++;
274 }
275 boundary->elem->n = n;
276 if (boundary->elem->n == 0) {
277 HECMW_free(mask);
278 return 0;
279 }
280
281 /* ids of boundary node */
282 boundary->elem->item = (int *)HECMW_calloc(boundary->elem->n, sizeof(int));
283 if (boundary->elem->item == NULL) {
284 HECMW_set_error(errno, "");
285 goto error;
286 }
287 for (n = 0, i = 0; i < mesh->n_elem; i++) {
288 if (mask[i] == HECMW_COUPLE_TRUE) boundary->elem->item[n++] = j + 1;
289 }
290 HECMW_assert(n == boundary->elem->n);
291
292 HECMW_free(mask);
293 return 0;
294
295error:
296 HECMW_free(mask);
297 return -1;
298}
299
300static int set_boundary_node_by_elem(const struct hecmwST_local_mesh *mesh,
301 struct hecmw_couple_boundary *boundary) {
302 int *mask = NULL;
303 int elem, node, size, n, i, j;
304
305 /* mask boundary nodes */
306 mask = (int *)HECMW_malloc(sizeof(int) * mesh->n_node);
307 if (mask == NULL) {
308 HECMW_set_error(errno, "");
309 goto error;
310 }
311 for (i = 0; i < mesh->n_node; i++) {
312 mask[i] = HECMW_COUPLE_FALSE;
313 }
314
315 for (n = 0, i = 0; i < boundary->elem->n; i++) {
316 elem = boundary->elem->item[i];
317 for (j = mesh->elem_node_index[elem - 1]; j < mesh->elem_node_index[elem];
318 j++) {
319 node = mesh->elem_node_item[j];
320 if (mask[node - 1] < 0) {
321 mask[node - 1] = n++;
322 }
323 }
324 }
325
326 /* number of boundary nodes */
327 for (n = 0, i = 0; i < mesh->n_node; i++) {
328 if (mask[i] >= 0) n++;
329 }
330 boundary->node->n = n;
331 if (boundary->node->n == 0) {
332 HECMW_free(mask);
333 return 0;
334 }
335
336 /* ids of boundary node */
337 boundary->node->item = (int *)HECMW_malloc(sizeof(int) * boundary->node->n);
338 if (boundary->node->item == NULL) {
339 HECMW_set_error(errno, "");
340 goto error;
341 }
342 for (n = 0, i = 0; i < mesh->n_node; i++) {
343 if (mask[i] >= 0) {
344 boundary->node->item[mask[i]] = i + 1;
345 }
346 }
347
348 /* connectivity of component nodes */
349 boundary->elem_node_index =
350 (int *)HECMW_calloc(boundary->elem->n + 1, sizeof(int));
351 if (boundary->elem_node_index == NULL) {
352 HECMW_set_error(errno, "");
353 goto error;
354 }
355 for (i = 0; i < boundary->elem->n; i++) {
356 elem = boundary->elem->item[i];
357 boundary->elem_node_index[i + 1] =
358 boundary->elem_node_index[i] +
360 }
361
362 size = sizeof(int) * boundary->elem_node_index[boundary->elem->n];
363 boundary->elem_node_item = (int *)HECMW_malloc(size);
364 if (boundary->elem_node_item == NULL) {
365 HECMW_set_error(errno, "");
366 goto error;
367 }
368 for (n = 0, i = 0; i < boundary->elem->n; i++) {
369 elem = boundary->elem->item[i];
370 for (j = mesh->elem_node_index[elem - 1]; j < mesh->elem_node_index[elem];
371 j++) {
372 node = mesh->elem_node_item[j];
373 boundary->elem_node_item[n] = mask[node - 1];
374 }
375 }
376
377 HECMW_free(mask);
378 return 0;
379
380error:
381 HECMW_free(mask);
382 return -1;
383}
384
385static int set_boundary_surf_by_surf(const struct hecmwST_local_mesh *mesh,
386 const struct hecmw_couple_group *group,
387 struct hecmw_couple_boundary *boundary) {
388 struct link_list *mask, *p;
389 int size, index, elem, surf, is_exist, n, i, j;
390
392 if (group->n_grp == 0) return 0;
393
394 /* mask boundary surfaces */
395 mask =
396 (struct link_list *)HECMW_malloc(sizeof(struct link_list) * mesh->n_elem);
397 if (mask == NULL) {
398 HECMW_set_error(errno, "");
399 goto error;
400 }
401 for (i = 0; i < mesh->n_elem; i++) {
402 mask[i].item = 0;
403 mask[i].next = NULL;
404 }
405
406 for (n = 0, i = 0; i < group->n_grp; i++) {
407 index = check_group_name(mesh->surf_group->n_grp,
408 mesh->surf_group->grp_name, group->grp_name[i]);
409 HECMW_assert(index >= 0);
410
411 for (j = mesh->surf_group->grp_index[index];
412 j < mesh->surf_group->grp_index[index + 1]; j++) {
413 elem = mesh->surf_group->grp_item[2 * j];
414 surf = mesh->surf_group->grp_item[2 * j + 1];
415
416 is_exist = HECMW_COUPLE_FALSE;
417 p = &mask[elem - 1];
418 while (p->next) {
419 if (p->next->item == surf) {
420 is_exist = HECMW_COUPLE_TRUE;
421 break;
422 }
423 }
424
425 if (is_exist == HECMW_COUPLE_FALSE) {
426 p->next = (struct link_list *)HECMW_malloc(sizeof(struct link_list));
427 if (p->next == NULL) {
428 HECMW_set_error(errno, "");
429 goto error;
430 }
431 p->next->item = surf;
432 p->next->next = NULL;
433 n++;
434 }
435 }
436 }
437
438 /* number of boundary surfaces */
439 boundary->surf->n = n;
440 if (boundary->surf->n == 0) {
441 HECMW_free(mask);
442 return 0;
443 }
444
445 /* ids of boundary surface */
446 boundary->surf->item =
447 (int *)HECMW_calloc(boundary->surf->n * 2, sizeof(int));
448 if (boundary->surf->item == NULL) {
449 HECMW_set_error(errno, "");
450 goto error;
451 }
452 for (n = 0, i = 0; i < mesh->n_elem; i++) {
453 for (p = mask[i].next; p; p = p->next) {
454 boundary->surf->item[2 * n] = i + 1;
455 boundary->surf->item[2 * n + 1] = p->item;
456 n++;
457 }
458 }
459
460 for (i = 0; i < mesh->n_elem; i++) {
461 free_link_list(mask[i].next);
462 }
463 HECMW_free(mask);
464
465 return 0;
466
467error:
468 for (i = 0; i < mesh->n_elem; i++) {
469 free_link_list(mask[i].next);
470 }
471 HECMW_free(mask);
472
473 return -1;
474}
475
476static int set_boundary_node_by_surf(const struct hecmwST_local_mesh *mesh,
477 struct hecmw_couple_boundary *boundary) {
478 int *mask = NULL;
479 int elem, surf, node, node_index, offset, size, n, i, j;
480
481 /* mask boundary nodes */
482 mask = (int *)HECMW_malloc(sizeof(int) * mesh->n_node);
483 if (mask == NULL) {
484 HECMW_set_error(errno, "");
485 goto error;
486 }
487 for (i = 0; i < mesh->n_node; i++) {
488 mask[i] = -1;
489 }
490 for (n = 0, i = 0; i < boundary->surf->n; i++) {
491 elem = boundary->surf->item[2 * i];
492 surf = boundary->surf->item[2 * i + 1];
493 node_index = mesh->elem_node_index[elem - 1];
494
495 if (mesh->elem_type[elem - 1] ==
496 HECMW_ETYPE_TET1) { /* 1st-order Tetra */
497 for (j = 0; j < 3; j++) {
498 offset = hecmw_surf_node_table_tet1[surf - 1][j];
499 node = mesh->elem_node_item[node_index + offset - 1];
500 if (mask[node - 1] < 0) {
501 mask[node - 1] = n++;
502 }
503 }
504 } else if (mesh->elem_type[elem - 1] ==
505 HECMW_ETYPE_HEX1) { /* 1st-order Hexa */
506 for (j = 0; j < 4; j++) {
507 offset = hecmw_surf_node_table_hex1[surf - 1][j];
508 node = mesh->elem_node_item[node_index + offset - 1];
509 if (mask[node - 1] < 0) {
510 mask[node - 1] = n++;
511 }
512 }
513 } else { /* error */
515 mesh->elem_type[elem - 1]);
516 goto error;
517 }
518 }
519
520 /* number of boundary nodes */
521 for (n = 0, i = 0; i < mesh->n_node; i++) {
522 if (mask[i] >= 0) n++;
523 }
524 boundary->node->n = n;
525 if (boundary->node->n == 0) {
526 HECMW_free(mask);
527 return 0;
528 }
529
530 /* ids of boundary node */
531 boundary->node->item = (int *)HECMW_malloc(sizeof(int) * boundary->node->n);
532 if (boundary->node->item == NULL) {
533 HECMW_set_error(errno, "");
534 goto error;
535 }
536 for (n = 0, i = 0; i < mesh->n_node; i++) {
537 if (mask[i] >= 0) {
538 boundary->node->item[mask[i]] = i + 1;
539 }
540 }
541
542 /* connectivity of component nodes */
543 boundary->elem_node_index =
544 (int *)HECMW_calloc(boundary->surf->n + 1, sizeof(int));
545 if (boundary->elem_node_index == NULL) {
546 HECMW_set_error(errno, "");
547 goto error;
548 }
549 for (i = 0; i < boundary->surf->n; i++) {
550 elem = boundary->surf->item[2 * i];
551 if (mesh->elem_type[elem - 1] == HECMW_ETYPE_TET1) {
552 boundary->elem_node_index[i + 1] = boundary->elem_node_index[i] + 3;
553 } else if (mesh->elem_type[elem - 1] == HECMW_ETYPE_HEX1) {
554 boundary->elem_node_index[i + 1] = boundary->elem_node_index[i] + 4;
555 }
556 }
557
558 size = sizeof(int) * boundary->elem_node_index[boundary->surf->n];
559 boundary->elem_node_item = (int *)HECMW_malloc(size);
560 if (boundary->elem_node_item == NULL) {
561 HECMW_set_error(errno, "");
562 goto error;
563 }
564 for (n = 0, i = 0; i < boundary->surf->n; i++) {
565 elem = boundary->surf->item[2 * i];
566 surf = boundary->surf->item[2 * i + 1];
567 node_index = mesh->elem_node_index[elem - 1];
568 if (mesh->elem_type[elem - 1] ==
569 HECMW_ETYPE_TET1) { /* 1st-order Tetra */
570 for (j = 0; j < 3; j++) {
571 offset = hecmw_surf_node_table_tet1[surf - 1][j];
572 node = mesh->elem_node_item[node_index + offset - 1];
573 boundary->elem_node_item[n++] = mask[node - 1];
574 }
575 } else if (mesh->elem_type[elem - 1] ==
576 HECMW_ETYPE_HEX1) { /* 1st-order Hexa */
577 for (j = 0; j < 4; j++) {
578 offset = hecmw_surf_node_table_hex1[surf - 1][j];
579 node = mesh->elem_node_item[node_index + offset - 1];
580 boundary->elem_node_item[n++] = mask[node - 1];
581 }
582 } else { /* error */
584 mesh->elem_type[elem - 1]);
585 goto error;
586 }
587 }
588
589 HECMW_free(mask);
590 return 0;
591
592error:
593 HECMW_free(mask);
594 return -1;
595}
596
597/*================================================================================================*/
598
600 const char *boundary_id, int unit_specifier,
601 const struct hecmwST_local_mesh *mesh) {
602 struct hecmw_couple_boundary *boundary = NULL;
603 struct hecmw_couple_group *group = NULL;
604
605 if (boundary_id == NULL) {
607 "HECMW_couple_set_boundary_info(): 'boundary_id' is NULL");
608 return NULL;
609 }
610 if (mesh == NULL) {
612 "HECMW_couple_set_boundary_info(): 'mesh' is NULL");
613 return NULL;
614 }
615
616 if ((boundary = HECMW_couple_alloc_boundary_info()) == NULL) return NULL;
617
618 if ((group = HECMW_couple_ctrl_get_group(boundary_id, unit_specifier)) ==
619 NULL)
620 goto error;
621
622 if (group->geom_type == HECMW_COUPLE_NODE_GROUP) { /* Node Group
623 */
625 "In current version, node group is not supported");
626 goto error;
627
628 /*
629 boundary->geom_type = group->geom_type;
630 boundary->data_type = group->data_type;
631 if(check_node_group_name(mesh, group)) goto error;
632 if(set_boundary_node_by_node(mesh, group, boundary)) goto error;
633 */
634
635 } else if (group->geom_type ==
636 HECMW_COUPLE_ELEMENT_GROUP) { /* Element Group */
638 "In current version, element group is not supported");
639 goto error;
640
641 /*
642 boundary->geom_type = group->geom_type;
643 boundary->data_type = group->data_type;
644 if(check_elem_group_name(mesh, group)) goto error;
645 if(set_boundary_elem_by_elem(mesh, group, boundary)) goto error;
646 if(set_boundary_node_by_elem(mesh, boundary)) goto error;
647 */
648
649 } else if (group->geom_type ==
650 HECMW_COUPLE_SURFACE_GROUP) { /* Surface Group */
651 boundary->geom_type = group->geom_type;
652 boundary->data_type = group->data_type;
653 if (check_surf_group_name(mesh, group)) goto error;
654 if (set_boundary_surf_by_surf(mesh, group, boundary)) goto error;
655 if (set_boundary_node_by_surf(mesh, boundary)) goto error;
656
657 } else { /* Error */
659 goto error;
660 }
661
663 return boundary;
664
665error:
668 return NULL;
669}
#define HECMW_ETYPE_HEX1
#define HECMW_ETYPE_TET1
#define HECMW_ERROR
Definition: hecmw_config.h:66
void HECMW_couple_free_boundary_info(struct hecmw_couple_boundary *boundary)
struct hecmw_couple_boundary * HECMW_couple_set_boundary_info(const char *boundary_id, int unit_specifier, const struct hecmwST_local_mesh *mesh)
struct hecmw_couple_boundary * HECMW_couple_alloc_boundary_info(void)
struct hecmw_couple_group * HECMW_couple_ctrl_get_group(const char *boundary_id, int unit_specifier)
void HECMW_couple_ctrl_free_group(struct hecmw_couple_group *grp_info)
#define HECMW_COUPLE_ELEMENT_GROUP
#define HECMW_COUPLE_TRUE
#define HECMWCPL_E_NONSUPPORT_GEOMTYPE
#define HECMW_COUPLE_NODE_GROUP
#define HECMWCPL_E_UNDEF_GRPNAME
#define HECMW_COUPLE_FALSE
#define HECMWCPL_E_NONSUPPORT_ETYPE
#define HECMW_COUPLE_GROUP_UNDEF
#define HECMWCPL_E_INVALID_ARG
#define HECMW_COUPLE_SURFACE_GROUP
#define HECMWCPL_E_INVALID_GEOMTYPE
struct hecmwST_local_mesh * mesh
Definition: hecmw_repart.h:71
int HECMW_set_error(int errorno, const char *fmt,...)
Definition: hecmw_error.c:37
int HECMW_get_max_node(int etype)
Definition: hecmw_etype.c:409
#define NULL
#define HECMW_calloc(nmemb, size)
Definition: hecmw_malloc.h:21
#define HECMW_free(ptr)
Definition: hecmw_malloc.h:24
#define HECMW_malloc(size)
Definition: hecmw_malloc.h:20
#define HECMW_assert(cond)
Definition: hecmw_util.h:40
struct hecmw_couple_boundary_item * elem
struct hecmw_couple_boundary_item * node
struct hecmw_couple_boundary_item * surf
struct hecmwST_node_grp * node_group
Definition: hecmw_struct.h:248
struct hecmwST_surf_grp * surf_group
Definition: hecmw_struct.h:250
struct hecmwST_elem_grp * elem_group
Definition: hecmw_struct.h:249