FrontISTR 5.2.0
Large-scale structural analysis program with finit element method
Loading...
Searching...
No Matches
hecmw_couple_s2n_dist_node.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_weight.h"
23
24#define FRAC_1_2 (0.5)
25
26#define FRAC_1_3 (0.33333333333333333)
27
28#define FRAC_1_4 (0.25)
29
30#define EPS_ZERO (1.0E-24)
31
32/*================================================================================================*/
33
34struct link_list {
35 int id;
36 double weight;
37 struct link_list *next;
38};
39
41 double x;
42 double y;
43 double z;
44};
45
47 double x;
48 double y;
49 double z;
50};
51
52/*================================================================================================*/
53
54static void free_link_list(struct link_list *r) {
55 struct link_list *p, *q;
56
57 for (p = r; p; p = q) {
58 q = p->next;
59 HECMW_free(p);
60 }
61}
62
63static int intercomm_d2s_coord(
64 const struct hecmw_couple_mapped_point *mapped_point,
65 const struct hecmw_couple_inter_iftable *inter_tbl,
66 const struct hecmw_couple_comm *comm_src,
67 const struct hecmw_couple_comm *comm_dst,
68 const struct hecmw_couple_comm *intercomm, double **coord) {
69 int *sendbuf_index = NULL, *recvbuf_index = NULL;
70 double *sendbuf = NULL;
71 int size, rtc, i;
72
73 if (comm_dst->is_member) {
74 sendbuf_index =
75 (int *)HECMW_calloc(inter_tbl->n_neighbor_pe_import + 1, sizeof(int));
76 if (sendbuf_index == NULL) {
77 HECMW_set_error(errno, "");
78 goto error;
79 }
80 for (i = 0; i <= inter_tbl->n_neighbor_pe_import; i++) {
81 sendbuf_index[i] = 3 * inter_tbl->import_index[i];
82 }
83
84 size = sizeof(double) *
85 (inter_tbl->import_index[inter_tbl->n_neighbor_pe_import] * 3 + 1);
86 sendbuf = (double *)HECMW_malloc(size);
87 if (sendbuf == NULL) {
88 HECMW_set_error(errno, "");
89 goto error;
90 }
91 for (i = 0; i < inter_tbl->import_index[inter_tbl->n_neighbor_pe_import];
92 i++) {
93 sendbuf[3 * i] = mapped_point->coord[3 * (inter_tbl->import_item[i])];
94 sendbuf[3 * i + 1] =
95 mapped_point->coord[3 * (inter_tbl->import_item[i]) + 1];
96 sendbuf[3 * i + 2] =
97 mapped_point->coord[3 * (inter_tbl->import_item[i]) + 2];
98 }
99 }
100
101 if (comm_src->is_member) {
102 recvbuf_index =
103 (int *)HECMW_calloc(inter_tbl->n_neighbor_pe_export + 1, sizeof(int));
104 if (recvbuf_index == NULL) {
105 HECMW_set_error(errno, "");
106 goto error;
107 }
108 for (i = 0; i <= inter_tbl->n_neighbor_pe_export; i++) {
109 recvbuf_index[i] = 3 * inter_tbl->export_index[i];
110 }
111
112 size = sizeof(double) *
113 (inter_tbl->export_index[inter_tbl->n_neighbor_pe_export] * 3 + 1);
114 *coord = (double *)HECMW_malloc(size);
115 if (*coord == NULL) {
116 HECMW_set_error(errno, "");
117 goto error;
118 }
119 }
120
122 inter_tbl->n_neighbor_pe_import, inter_tbl->neighbor_pe_import,
123 sendbuf_index, sendbuf, inter_tbl->n_neighbor_pe_export,
124 inter_tbl->neighbor_pe_export, recvbuf_index, *coord, HECMW_DOUBLE,
125 intercomm->comm);
126 if (rtc != 0) goto error;
127
128 HECMW_free(sendbuf_index);
129 HECMW_free(sendbuf);
130 HECMW_free(recvbuf_index);
131 return 0;
132
133error:
134 HECMW_free(sendbuf_index);
135 HECMW_free(sendbuf);
136 HECMW_free(recvbuf_index);
137 return -1;
138}
139
140static int s2n_dist_node_tet1(const struct hecmwST_local_mesh *mesh_src,
141 const struct hecmw_couple_boundary *boundary_src,
142 int id,
143 const struct hecmw_couple_vertex *coord_dst,
144 struct link_list *weight_list) {
145 struct link_list *p;
146 struct hecmw_couple_vertex coord[3], gravity;
147 double d, r_d_surf, r_d_node[3], r_d_sum = 0.0;
148 int node_id[3], node, n, i;
149
150 for (n = 0, i = boundary_src->elem_node_index[id];
151 i < boundary_src->elem_node_index[id + 1]; i++) {
152 node_id[n] = boundary_src->elem_node_item[i];
153 node = boundary_src->node->item[node_id[n]];
154 coord[n].x = mesh_src->node[3 * (node - 1)];
155 coord[n].y = mesh_src->node[3 * (node - 1) + 1];
156 coord[n].z = mesh_src->node[3 * (node - 1) + 2];
157 n++;
158 }
159
160 for (i = 0; i < 3; i++) {
161 d = sqrt((coord[i].x - coord_dst->x) * (coord[i].x - coord_dst->x) +
162 (coord[i].y - coord_dst->y) * (coord[i].y - coord_dst->y) +
163 (coord[i].z - coord_dst->z) * (coord[i].z - coord_dst->z));
164 r_d_node[i] = 1.0 / (d + EPS_ZERO);
165 r_d_sum += r_d_node[i];
166 }
167
168 for (i = 0; i < 3; i++) {
169 p = (struct link_list *)HECMW_malloc(sizeof(struct link_list));
170 if (p == NULL) {
171 HECMW_set_error(errno, "");
172 return -1;
173 }
174 p->id = node_id[i];
175 p->weight = r_d_node[i] / r_d_sum;
176 p->next = weight_list->next;
177 weight_list->next = p;
178 }
179
180 return 0;
181}
182
183static int s2n_dist_node_hex1(const struct hecmwST_local_mesh *mesh_src,
184 const struct hecmw_couple_boundary *boundary_src,
185 int id,
186 const struct hecmw_couple_vertex *coord_dst,
187 struct link_list *weight_list) {
188 struct link_list *p;
189 struct hecmw_couple_vertex coord[4], gravity;
190 double d, r_d_surf, r_d_node[4], r_d_sum = 0.0;
191 int node_id[4], node, n, i;
192
193 for (n = 0, i = boundary_src->elem_node_index[id];
194 i < boundary_src->elem_node_index[id + 1]; i++) {
195 node_id[n] = boundary_src->elem_node_item[i];
196 node = boundary_src->node->item[node_id[n]];
197 coord[n].x = mesh_src->node[3 * (node - 1)];
198 coord[n].y = mesh_src->node[3 * (node - 1) + 1];
199 coord[n].z = mesh_src->node[3 * (node - 1) + 2];
200 n++;
201 }
202
203 for (i = 0; i < 4; i++) {
204 d = sqrt((coord[i].x - coord_dst->x) * (coord[i].x - coord_dst->x) +
205 (coord[i].y - coord_dst->y) * (coord[i].y - coord_dst->y) +
206 (coord[i].z - coord_dst->z) * (coord[i].z - coord_dst->z));
207 r_d_node[i] = 1.0 / (d + EPS_ZERO);
208 r_d_sum += r_d_node[i];
209 }
210
211 for (i = 0; i < 4; i++) {
212 p = (struct link_list *)HECMW_malloc(sizeof(struct link_list));
213 if (p == NULL) {
214 HECMW_set_error(errno, "");
215 return -1;
216 }
217 p->id = node_id[i];
218 p->weight = r_d_node[i] / r_d_sum;
219 p->next = weight_list->next;
220 weight_list->next = p;
221 }
222
223 return 0;
224}
225
226static int s2n_dist_node(const struct hecmwST_local_mesh *mesh_src,
227 const struct hecmw_couple_boundary *boundary_src,
228 const struct hecmw_couple_inter_iftable *inter_tbl,
229 double *coord,
230 struct hecmw_couple_weight *weight_info) {
231 struct link_list *weight_list = NULL, *p;
232 struct hecmw_couple_vertex coord_dst;
233 int elem, n_item, id, rtc, n, i;
234
235 n_item = inter_tbl->export_index[inter_tbl->n_neighbor_pe_export] + 1;
236 weight_list =
237 (struct link_list *)HECMW_malloc(sizeof(struct link_list) * n_item);
238 if (weight_list == NULL) {
239 HECMW_set_error(errno, "");
240 goto error;
241 }
242 for (i = 0; i < n_item; i++) {
243 weight_list[i].id = -1;
244 weight_list[i].weight = 0.0;
245 weight_list[i].next = NULL;
246 }
247
248 for (i = 0; i < inter_tbl->export_index[inter_tbl->n_neighbor_pe_export];
249 i++) {
250 coord_dst.x = coord[3 * i];
251 coord_dst.y = coord[3 * i + 1];
252 coord_dst.z = coord[3 * i + 2];
253
254 id = inter_tbl->export_item[i];
255 elem = boundary_src->surf->item[2 * id];
256 if (mesh_src->elem_type[elem - 1] == HECMW_ETYPE_TET1) {
257 rtc = s2n_dist_node_tet1(mesh_src, boundary_src, id, &coord_dst,
258 &weight_list[i]);
259 if (rtc != HECMW_SUCCESS) goto error;
260 } else if (mesh_src->elem_type[elem - 1] == HECMW_ETYPE_HEX1) {
261 rtc = s2n_dist_node_hex1(mesh_src, boundary_src, id, &coord_dst,
262 &weight_list[i]);
263 if (rtc != HECMW_SUCCESS) goto error;
264 } else {
266 goto error;
267 }
268 }
269
270 weight_info->n = inter_tbl->export_index[inter_tbl->n_neighbor_pe_export];
271 weight_info->type = HECMW_COUPLE_IP_NODE_TO_NODE;
272
273 weight_info->index = (int *)HECMW_calloc(weight_info->n + 1, sizeof(int));
274 if (weight_info->index == NULL) {
275 HECMW_set_error(errno, "");
276 goto error;
277 }
278 for (n = 0, i = 0;
279 i < inter_tbl->export_index[inter_tbl->n_neighbor_pe_export]; i++) {
280 for (p = weight_list[i].next; p; p = p->next) {
281 n++;
282 }
283 weight_info->index[i + 1] = n;
284 }
285
286 n_item = weight_info->index[weight_info->n];
287 weight_info->id = (int *)HECMW_malloc(sizeof(int) * n_item);
288 if (weight_info->id == NULL) {
289 HECMW_set_error(errno, "");
290 goto error;
291 }
292 weight_info->weight = (double *)HECMW_malloc(sizeof(double) * n_item);
293 if (weight_info->weight == NULL) {
294 HECMW_set_error(errno, "");
295 goto error;
296 }
297 for (n = 0, i = 0;
298 i < inter_tbl->export_index[inter_tbl->n_neighbor_pe_export]; i++) {
299 for (p = weight_list[i].next; p; p = p->next) {
300 weight_info->id[n] = p->id;
301 weight_info->weight[n] = p->weight;
302 n++;
303 }
304 }
305
306 for (i = 0; i < inter_tbl->export_index[inter_tbl->n_neighbor_pe_export];
307 i++) {
308 free_link_list(weight_list[i].next);
309 }
310 HECMW_free(weight_list);
311
312 return 0;
313
314error:
315 for (i = 0; i < inter_tbl->export_index[inter_tbl->n_neighbor_pe_export];
316 i++) {
317 free_link_list(weight_list[i].next);
318 }
319 HECMW_free(weight_list);
320
321 return -1;
322}
323
325 const struct hecmwST_local_mesh *mesh_src,
326 const struct hecmwST_local_mesh *mesh_dst,
327 const struct hecmw_couple_comm *comm_src,
328 const struct hecmw_couple_comm *comm_dst,
329 const struct hecmw_couple_comm *intercomm,
330 const struct hecmw_couple_boundary *boundary_src,
331 const struct hecmw_couple_boundary *boundary_dst,
332 const struct hecmw_couple_mapped_point *mapped_point,
333 const struct hecmw_couple_inter_iftable *inter_tbl) {
334 struct hecmw_couple_weight_list *weight_info_list = NULL;
335 struct hecmw_couple_weight *weight_info = NULL;
336 double *coord = NULL;
337 int rtc, i;
338
339 if ((weight_info_list = HECMW_couple_alloc_weight_list()) == NULL)
340 return NULL;
341
342 rtc = intercomm_d2s_coord(mapped_point, inter_tbl, comm_src, comm_dst,
343 intercomm, &coord);
344 if (rtc) goto error;
345
346 if (comm_src->is_member) {
347 if ((weight_info = HECMW_couple_alloc_weight()) == NULL) goto error;
348 weight_info_list->info = weight_info;
349
350 if (s2n_dist_node(mesh_src, boundary_src, inter_tbl, coord, weight_info))
351 goto error;
352 }
353
354 return weight_info_list;
355
356error:
357 return NULL;
358}
#define HECMW_ETYPE_HEX1
#define HECMW_ETYPE_TET1
#define HECMW_DOUBLE
Definition: hecmw_config.h:50
#define HECMW_SUCCESS
Definition: hecmw_config.h:64
int HECMW_couple_inter_send_recv(int n_neighbor_pe_send, int *neighbor_pe_send, int *sendbuf_index, void *sendbuf, int n_neighbor_pe_recv, int *neighbor_pe_recv, int *recvbuf_index, void *recvbuf, HECMW_Datatype datatype, HECMW_Comm comm)
#define HECMW_COUPLE_IP_NODE_TO_NODE
#define HECMWCPL_E_NONSUPPORT_ETYPE
struct hecmw_couple_weight_list * HECMW_couple_s2n_dist_node(const struct hecmwST_local_mesh *mesh_src, const struct hecmwST_local_mesh *mesh_dst, const struct hecmw_couple_comm *comm_src, const struct hecmw_couple_comm *comm_dst, const struct hecmw_couple_comm *intercomm, const struct hecmw_couple_boundary *boundary_src, const struct hecmw_couple_boundary *boundary_dst, const struct hecmw_couple_mapped_point *mapped_point, const struct hecmw_couple_inter_iftable *inter_tbl)
#define EPS_ZERO
struct hecmw_couple_weight * HECMW_couple_alloc_weight(void)
struct hecmw_couple_weight_list * HECMW_couple_alloc_weight_list(void)
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