FrontISTR 5.2.0
Large-scale structural analysis program with finit element method
Loading...
Searching...
No Matches
hecmw_couple_s2n_average.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 <errno.h>
10#include <assert.h>
11
12#include "hecmw_common_define.h"
13#include "hecmw_struct.h"
14#include "hecmw_malloc.h"
15
16#include "hecmw_couple_define.h"
18#include "hecmw_couple_weight.h"
20
21#define FRAC_1_3 (0.33333333333333333)
22
23#define FRAC_1_4 (0.25)
24
25struct link_list {
26 int id;
27 double weight;
28 struct link_list *next;
29};
30
31/*================================================================================================*/
32
33static void free_link_list(struct link_list *r) {
34 struct link_list *p, *q;
35
36 for (p = r; p; p = q) {
37 q = p->next;
38 HECMW_free(p);
39 }
40}
41
42static int s2n_average_tet1(const struct hecmwST_local_mesh *mesh,
43 const struct hecmw_couple_boundary *boundary,
44 int id, struct link_list *weight_list) {
45 struct link_list *p;
46 int node_id, n, i;
47
48 for (n = 0, i = boundary->elem_node_index[id];
49 i < boundary->elem_node_index[id + 1]; i++) {
50 node_id = boundary->elem_node_item[i];
51
52 p = (struct link_list *)HECMW_malloc(sizeof(struct link_list));
53 if (p == NULL) {
54 HECMW_set_error(errno, "");
55 return -1;
56 }
57 p->id = id;
58 p->weight = FRAC_1_3;
59 p->next = weight_list[node_id].next;
60 weight_list[node_id].next = p;
61 }
62
63 return 0;
64}
65
66static int s2n_average_hex1(const struct hecmwST_local_mesh *mesh,
67 const struct hecmw_couple_boundary *boundary,
68 int id, struct link_list *weight_list) {
69 struct link_list *p;
70 int node_id, n, i;
71
72 for (n = 0, i = boundary->elem_node_index[id];
73 i < boundary->elem_node_index[id + 1]; i++) {
74 node_id = boundary->elem_node_item[i];
75
76 p = (struct link_list *)HECMW_malloc(sizeof(struct link_list));
77 if (p == NULL) {
78 HECMW_set_error(errno, "");
79 return -1;
80 }
81 p->id = id;
82 p->weight = FRAC_1_4;
83 p->next = weight_list[node_id].next;
84 weight_list[node_id].next = p;
85 }
86
87 return 0;
88}
89
90static int s2n_average(const struct hecmwST_local_mesh *mesh,
91 const struct hecmw_couple_boundary *boundary,
92 struct hecmw_couple_weight *weight_info) {
93 struct link_list *weight_list = NULL, *p;
94 int elem, n_item, size, n, i;
95
96 size = sizeof(struct link_list) * boundary->node->n;
97 weight_list = (struct link_list *)HECMW_malloc(size);
98 if (weight_list == NULL) {
99 HECMW_set_error(errno, "");
100 goto error;
101 }
102 for (i = 0; i < boundary->node->n; i++) {
103 weight_list[i].id = -1;
104 weight_list[i].weight = 0.0;
105 weight_list[i].next = NULL;
106 }
107
108 /*
109 * calculate weight
110 */
111 for (i = 0; i < boundary->surf->n; i++) {
112 elem = boundary->surf->item[2 * i];
113
114 if (mesh->elem_type[elem - 1] == HECMW_ETYPE_TET1) {
115 if (s2n_average_tet1(mesh, boundary, i, weight_list)) goto error;
116 } else if (mesh->elem_type[elem - 1] == HECMW_ETYPE_HEX1) {
117 if (s2n_average_hex1(mesh, boundary, i, weight_list)) goto error;
118 } else {
120 goto error;
121 }
122 }
123
124 /*
125 * make interpolating information
126 */
127 /* number of nodes */
128 weight_info->n = boundary->node->n;
129
130 /* interpolating type */
131 weight_info->type = HECMW_COUPLE_IP_SURF_TO_NODE;
132
133 /* index of list */
134 weight_info->index = (int *)HECMW_calloc(weight_info->n + 1, sizeof(int));
135 if (weight_info->index == NULL) {
136 HECMW_set_error(errno, "");
137 goto error;
138 }
139 for (n = 0, i = 0; i < boundary->node->n; i++) {
140 for (p = weight_list[i].next; p; p = p->next) {
141 n++;
142 }
143 weight_info->index[i + 1] = n;
144 }
145
146 /* id which interpolates nodes and its weight */
147 n_item = weight_info->index[weight_info->n];
148 weight_info->id = (int *)HECMW_malloc(sizeof(int) * n_item);
149 if (weight_info->id == NULL) {
150 HECMW_set_error(errno, "");
151 goto error;
152 }
153 weight_info->weight = (double *)HECMW_malloc(sizeof(double) * n_item);
154 if (weight_info->weight == NULL) {
155 HECMW_set_error(errno, "");
156 goto error;
157 }
158 for (n = 0, i = 0; i < boundary->node->n; i++) {
159 for (p = weight_list[i].next; p; p = p->next) {
160 weight_info->id[n] = p->id;
161 weight_info->weight[n] = p->weight;
162 n++;
163 }
164 }
165
166 /*
167 * free linked list
168 */
169 for (i = 0; i < boundary->node->n; i++) {
170 free_link_list(weight_list[i].next);
171 }
172 HECMW_free(weight_list);
173
174 return 0;
175
176error:
177 for (i = 0; i < boundary->node->n; i++) {
178 free_link_list(weight_list[i].next);
179 }
180 HECMW_free(weight_list);
181 return -1;
182}
183
185 const struct hecmwST_local_mesh *mesh,
186 const struct hecmw_couple_boundary *boundary) {
187 struct hecmw_couple_weight_list *weight_info_list = NULL;
188 struct hecmw_couple_weight *weight_info = NULL;
189 struct link_list *weight_list = NULL, *p;
190 int elem, n_item, size, n, i;
191
192 if (mesh == NULL) {
194 "HECMW_couple_s2n_by_area(): 'mesh' is NULL");
195 return NULL;
196 }
197 if (boundary == NULL) {
199 "HECMW_couple_s2n_by_area(): 'boundary' is NULL");
200 return NULL;
201 }
202
203 if ((weight_info_list = HECMW_couple_alloc_weight_list()) == NULL)
204 return NULL;
205
206 if ((weight_info = HECMW_couple_alloc_weight()) == NULL) goto error;
207 weight_info_list->info = weight_info;
208
209 if (s2n_average(mesh, boundary, weight_info)) goto error;
210
211 return weight_info_list;
212
213error:
214 HECMW_couple_free_weight(weight_info);
215 weight_info_list->info = NULL;
216 HECMW_couple_free_weight_list(weight_info_list);
217 return NULL;
218}
#define HECMW_ETYPE_HEX1
#define HECMW_ETYPE_TET1
#define HECMW_COUPLE_IP_SURF_TO_NODE
#define HECMWCPL_E_NONSUPPORT_ETYPE
#define HECMWCPL_E_INVALID_ARG
struct hecmw_couple_weight_list * HECMW_couple_s2n_average(const struct hecmwST_local_mesh *mesh, const struct hecmw_couple_boundary *boundary)
#define FRAC_1_4
#define FRAC_1_3
struct hecmw_couple_weight * HECMW_couple_alloc_weight(void)
struct hecmw_couple_weight_list * HECMW_couple_alloc_weight_list(void)
void HECMW_couple_free_weight(struct hecmw_couple_weight *p)
void HECMW_couple_free_weight_list(struct hecmw_couple_weight_list *r)
struct hecmwST_local_mesh * mesh
Definition: hecmw_repart.h:71
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_malloc(size)
Definition: hecmw_malloc.h:20
struct hecmw_couple_boundary_item * node
struct hecmw_couple_boundary_item * surf
struct hecmw_couple_weight * info