FrontISTR 5.2.0
Large-scale structural analysis program with finit element method
Loading...
Searching...
No Matches
hecmw_couple_n2s_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"
17#include "hecmw_couple_struct.h"
18#include "hecmw_couple_comm.h"
21#include "hecmw_couple_weight.h"
23
24#define FRAC_1_3 (0.33333333333333333)
25
26#define FRAC_1_4 (0.25)
27
28/*================================================================================================*/
29
30struct link_list {
31 int id;
32 double weight;
33 struct link_list *next;
34};
35
36/*================================================================================================*/
37
38static void free_link_list(struct link_list *r) {
39 struct link_list *p, *q;
40
41 for (p = r; p; p = q) {
42 q = p->next;
43 HECMW_free(p);
44 }
45}
46
47/*------------------------------------------------------------------------------------------------*/
48
49static int *count_shared_surf(const struct hecmw_couple_boundary *boundary) {
50 int *n_shared_surf = NULL;
51 int id, i, j;
52
53 n_shared_surf = (int *)HECMW_calloc(boundary->node->n, sizeof(int));
54 if (n_shared_surf == NULL) {
55 HECMW_set_error(errno, "");
56 return NULL;
57 }
58
59 for (i = 0; i < boundary->surf->n; i++) {
60 for (j = boundary->elem_node_index[i]; j < boundary->elem_node_index[i + 1];
61 j++) {
62 id = boundary->elem_node_item[j];
63 n_shared_surf[id] += 1;
64 }
65 }
66
67 return n_shared_surf;
68}
69
70static int send_recv_n_shared_surf(
71 const struct hecmw_couple_intra_iftable *intra_tbl,
72 const struct hecmw_couple_comm *intracomm, int *n_shared_surf) {
73 int *sendbuf = NULL, *recvbuf = NULL;
74 int nmemb, id, rtc, i;
75
76 if (intra_tbl->n_neighbor_pe == 0) return 0;
77
78 nmemb = intra_tbl->export_index[intra_tbl->n_neighbor_pe] + 1;
79 sendbuf = (int *)HECMW_malloc(sizeof(int) * nmemb);
80 if (sendbuf == NULL) {
81 HECMW_set_error(errno, "");
82 goto error;
83 }
84 for (i = 0; i < intra_tbl->export_index[intra_tbl->n_neighbor_pe]; i++) {
85 id = intra_tbl->export_item[i];
86 sendbuf[i] = n_shared_surf[id];
87 }
88
89 nmemb = intra_tbl->import_index[intra_tbl->n_neighbor_pe] + 1;
90 recvbuf = (int *)HECMW_malloc(sizeof(int) * nmemb);
91 if (recvbuf == NULL) {
92 HECMW_set_error(errno, "");
93 goto error;
94 }
95
97 intra_tbl->n_neighbor_pe, intra_tbl->neighbor_pe, intra_tbl->export_index,
98 sendbuf, intra_tbl->import_index, recvbuf, HECMW_INT, intracomm->comm);
99 if (rtc) goto error;
100
101 for (i = 0; i < intra_tbl->import_index[intra_tbl->n_neighbor_pe]; i++) {
102 id = intra_tbl->import_item[i];
103 n_shared_surf[id] = recvbuf[i];
104 }
105
106 HECMW_free(sendbuf);
107 HECMW_free(recvbuf);
108 return 0;
109
110error:
111 HECMW_free(sendbuf);
112 HECMW_free(recvbuf);
113 return -1;
114}
115
116static int n2s_average_tet1(const struct hecmwST_local_mesh *mesh,
117 const struct hecmw_couple_boundary *boundary,
118 int id, int *n_shared_surf,
119 struct link_list *weight_list) {
120 struct link_list *p;
121 int node_id, n, i;
122
123 for (n = 0, i = boundary->elem_node_index[id];
124 i < boundary->elem_node_index[id + 1]; i++) {
125 node_id = boundary->elem_node_item[i];
126
127 p = (struct link_list *)HECMW_malloc(sizeof(struct link_list));
128 if (p == NULL) {
129 HECMW_set_error(errno, "");
130 return -1;
131 }
132 p->id = node_id;
133 p->weight = 1.0 / (double)n_shared_surf[node_id];
134 p->next = weight_list[id].next;
135 weight_list[id].next = p;
136 }
137
138 return 0;
139}
140
141static int n2s_average_hex1(const struct hecmwST_local_mesh *mesh,
142 const struct hecmw_couple_boundary *boundary,
143 int id, int *n_shared_surf,
144 struct link_list *weight_list) {
145 struct link_list *p;
146 int node_id, n, i;
147
148 for (n = 0, i = boundary->elem_node_index[id];
149 i < boundary->elem_node_index[id + 1]; i++) {
150 node_id = boundary->elem_node_item[i];
151
152 p = (struct link_list *)HECMW_malloc(sizeof(struct link_list));
153 if (p == NULL) {
154 HECMW_set_error(errno, "");
155 return -1;
156 }
157 p->id = node_id;
158 p->weight = 1.0 / (double)n_shared_surf[node_id];
159 p->next = weight_list[id].next;
160 weight_list[id].next = p;
161 }
162
163 return 0;
164}
165
166extern int n2s_average(const struct hecmwST_local_mesh *mesh,
167 const struct hecmw_couple_boundary *boundary,
168 const struct hecmw_couple_comm *intracomm,
169 const struct hecmw_couple_intra_iftable *intra_tbl,
170 struct hecmw_couple_weight *weight_info) {
171 struct link_list *weight_list = NULL, *p;
172 int *n_shared_surf = NULL;
173 int elem, n_item, size, n, i;
174
175 size = sizeof(struct link_list) * boundary->surf->n;
176 weight_list = (struct link_list *)HECMW_malloc(size);
177 if (weight_list == NULL) {
178 HECMW_set_error(errno, "");
179 goto error;
180 }
181 for (i = 0; i < boundary->surf->n; i++) {
182 weight_list[i].id = -1;
183 weight_list[i].weight = 0.0;
184 weight_list[i].next = NULL;
185 }
186
187 /*
188 * calculate weight
189 */
190 if ((n_shared_surf = count_shared_surf(boundary)) == NULL) goto error;
191 if (send_recv_n_shared_surf(intra_tbl, intracomm, n_shared_surf)) goto error;
192
193 for (i = 0; i < boundary->surf->n; i++) {
194 elem = boundary->surf->item[2 * i];
195
196 if (mesh->elem_type[elem - 1] == HECMW_ETYPE_TET1) {
197 if (n2s_average_tet1(mesh, boundary, i, n_shared_surf, weight_list))
198 goto error;
199 } else if (mesh->elem_type[elem - 1] == HECMW_ETYPE_HEX1) {
200 if (n2s_average_hex1(mesh, boundary, i, n_shared_surf, weight_list))
201 goto error;
202 } else {
204 goto error;
205 }
206 }
207
208 HECMW_free(n_shared_surf);
209
210 /*
211 * make interpolating information
212 */
213 /* number of surfaces */
214 weight_info->n = boundary->surf->n;
215
216 /* interpolating type */
217 weight_info->type = HECMW_COUPLE_IP_NODE_TO_SURF;
218
219 /* index of list */
220 weight_info->index = (int *)HECMW_calloc(weight_info->n + 1, sizeof(int));
221 if (weight_info->index == NULL) {
222 HECMW_set_error(errno, "");
223 goto error;
224 }
225 for (n = 0, i = 0; i < boundary->surf->n; i++) {
226 for (p = weight_list[i].next; p; p = p->next) {
227 n++;
228 }
229 weight_info->index[i + 1] = n;
230 }
231
232 /* id & weight */
233 n_item = weight_info->index[weight_info->n];
234 weight_info->id = (int *)HECMW_malloc(sizeof(int) * n_item);
235 if (weight_info->id == NULL) {
236 HECMW_set_error(errno, "");
237 goto error;
238 }
239 weight_info->weight = (double *)HECMW_malloc(sizeof(double) * n_item);
240 if (weight_info->weight == NULL) {
241 HECMW_set_error(errno, "");
242 goto error;
243 }
244 for (n = 0, i = 0; i < boundary->surf->n; i++) {
245 for (p = weight_list[i].next; p; p = p->next) {
246 weight_info->id[n] = p->id;
247 weight_info->weight[n] = p->weight;
248 n++;
249 }
250 }
251
252 /*
253 * free linked list
254 */
255 for (i = 0; i < boundary->surf->n; i++) {
256 free_link_list(weight_list[i].next);
257 }
258 HECMW_free(weight_list);
259
260 return 0;
261
262error:
263 for (i = 0; i < boundary->surf->n; i++) {
264 free_link_list(weight_list[i].next);
265 }
266 HECMW_free(weight_list);
267 return -1;
268}
269
271 const struct hecmwST_local_mesh *mesh,
272 const struct hecmw_couple_boundary *boundary,
273 const struct hecmw_couple_comm *intracomm,
274 const struct hecmw_couple_intra_iftable *intra_tbl) {
275 struct hecmw_couple_weight_list *weight_info_list = NULL;
276 struct hecmw_couple_weight *weight_info = NULL;
277
278 if (mesh == NULL) {
280 "HECMW_couple_n2s_average(): 'mesh' is NULL");
281 return NULL;
282 }
283 if (boundary == NULL) {
285 "HECMW_couple_n2s_average(): 'boundary' is NULL");
286 }
287
288 if ((weight_info_list = HECMW_couple_alloc_weight_list()) == NULL)
289 return NULL;
290
291 if ((weight_info = HECMW_couple_alloc_weight()) == NULL) goto error;
292 weight_info_list->info = weight_info;
293
294 if (n2s_average(mesh, boundary, intracomm, intra_tbl, weight_info))
295 goto error;
296
297 return weight_info_list;
298
299error:
300 HECMW_couple_free_weight(weight_info);
301 weight_info_list->info = NULL;
302 HECMW_couple_free_weight_list(weight_info_list);
303 return NULL;
304}
#define HECMW_ETYPE_HEX1
#define HECMW_ETYPE_TET1
#define HECMW_INT
Definition: hecmw_config.h:48
int HECMW_couple_intra_send_recv(int n_neighbor_pe, int *neighbor_pe, int *sendbuf_index, void *sendbuf, int *recvbuf_index, void *recvbuf, HECMW_Datatype datatype, HECMW_Comm comm)
#define HECMW_COUPLE_IP_NODE_TO_SURF
#define HECMWCPL_E_NONSUPPORT_ETYPE
#define HECMWCPL_E_INVALID_ARG
struct hecmw_couple_weight_list * HECMW_couple_n2s_average(const struct hecmwST_local_mesh *mesh, const struct hecmw_couple_boundary *boundary, const struct hecmw_couple_comm *intracomm, const struct hecmw_couple_intra_iftable *intra_tbl)
int n2s_average(const struct hecmwST_local_mesh *mesh, const struct hecmw_couple_boundary *boundary, const struct hecmw_couple_comm *intracomm, const struct hecmw_couple_intra_iftable *intra_tbl, struct hecmw_couple_weight *weight_info)
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