FrontISTR  5.7.0
Large-scale structural analysis program with finit element method
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 
34 struct link_list {
35  int id;
36  double weight;
37  struct link_list *next;
38 };
39 
40 struct hecmw_couple_vertex {
41  double x;
42  double y;
43  double z;
44 };
45 
46 struct hecmw_couple_vector {
47  double x;
48  double y;
49  double z;
50 };
51 
52 /*================================================================================================*/
53 
54 static 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 
63 static 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 
133 error:
134  HECMW_free(sendbuf_index);
135  HECMW_free(sendbuf);
136  HECMW_free(recvbuf_index);
137  return -1;
138 }
139 
140 static 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 
183 static 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 
226 static 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 
314 error:
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 
356 error:
357  return NULL;
358 }
hecmw_couple_boundary::surf
struct hecmw_couple_boundary_item * surf
Definition: hecmw_couple_boundary_info.h:23
hecmw_malloc.h
hecmw_couple_vertex
Definition: hecmw_couple_n2s_with_area.c:35
hecmw_couple_weight
Definition: hecmw_couple_weight.h:9
hecmw_couple_mapped_point.h
hecmw_couple_weight_list::info
struct hecmw_couple_weight * info
Definition: hecmw_couple_weight.h:18
hecmw_couple_inter_iftable::export_index
int * export_index
Definition: hecmw_couple_inter_iftable.h:26
HECMW_couple_inter_send_recv
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)
Definition: hecmw_couple_comm.c:23
hecmw_couple_vertex::x
double x
Definition: hecmw_couple_n2s_with_area.c:36
HECMW_DOUBLE
#define HECMW_DOUBLE
Definition: hecmw_config.h:50
HECMW_couple_s2n_dist_node
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)
Definition: hecmw_couple_s2n_dist_node.c:324
hecmw_couple_vertex::z
double z
Definition: hecmw_couple_n2s_with_area.c:38
hecmw_couple_weight.h
EPS_ZERO
#define EPS_ZERO
Definition: hecmw_couple_s2n_dist_node.c:30
HECMW_malloc
#define HECMW_malloc(size)
Definition: hecmw_malloc.h:20
hecmw_couple_vector::y
double y
Definition: hecmw_couple_n2s_with_area.c:43
hecmw_couple_inter_iftable::import_item
int * import_item
Definition: hecmw_couple_inter_iftable.h:23
hecmw_couple_weight::n
int n
Definition: hecmw_couple_weight.h:13
hecmwST_local_mesh
Definition: hecmw_struct.h:139
hecmw_couple_weight::weight
double * weight
Definition: hecmw_couple_weight.h:17
hecmwST_local_mesh::elem_type
int * elem_type
Definition: hecmw_struct.h:191
hecmw_couple_inter_iftable::neighbor_pe_export
int * neighbor_pe_export
Definition: hecmw_couple_inter_iftable.h:25
hecmw_couple_boundary
Definition: hecmw_couple_boundary_info.h:18
hecmw_couple_weight_list
Definition: hecmw_couple_weight.h:17
HECMW_calloc
#define HECMW_calloc(nmemb, size)
Definition: hecmw_malloc.h:21
hecmw_struct.h
hecmwST_local_mesh::node
double * node
Definition: hecmw_struct.h:170
HECMWCPL_E_NONSUPPORT_ETYPE
#define HECMWCPL_E_NONSUPPORT_ETYPE
Definition: hecmw_couple_define.h:177
hecmw_couple_weight::id
int * id
Definition: hecmw_couple_weight.h:16
hecmw_couple_weight::index
int * index
Definition: hecmw_couple_weight.h:15
hecmw_couple_vector::x
double x
Definition: hecmw_couple_n2s_with_area.c:42
hecmw_couple_comm::is_member
int is_member
Definition: hecmw_couple_struct.h:23
hecmw_couple_comm
Definition: hecmw_couple_struct.h:12
hecmw_couple_s2n_dist_node.h
hecmw_couple_weight::type
int type
Definition: hecmw_couple_weight.h:14
hecmw_couple_inter_iftable::export_item
int * export_item
Definition: hecmw_couple_inter_iftable.h:27
hecmw_couple_inter_iftable
Definition: hecmw_couple_inter_iftable.h:16
hecmw_couple_vertex::y
double y
Definition: hecmw_couple_n2s_with_area.c:37
hecmw_couple_mapped_point::coord
double * coord
Definition: hecmw_couple_mapped_point.h:20
HECMW_COUPLE_IP_NODE_TO_NODE
#define HECMW_COUPLE_IP_NODE_TO_NODE
Definition: hecmw_couple_define.h:43
hecmw_couple_struct.h
HECMW_couple_alloc_weight
struct hecmw_couple_weight * HECMW_couple_alloc_weight(void)
Definition: hecmw_couple_weight.c:16
HECMW_ETYPE_HEX1
#define HECMW_ETYPE_HEX1
Definition: hecmw_common_define.h:31
HECMW_SUCCESS
#define HECMW_SUCCESS
Definition: hecmw_config.h:64
hecmw_couple_boundary_info.h
hecmw_common_define.h
hecmw_couple_mapped_point
Definition: hecmw_couple_mapped_point.h:12
hecmw_couple_boundary::node
struct hecmw_couple_boundary_item * node
Definition: hecmw_couple_boundary_info.h:21
HECMW_set_error
int HECMW_set_error(int errorno, const char *fmt,...)
Definition: hecmw_error.c:37
hecmw_couple_inter_iftable::n_neighbor_pe_import
int n_neighbor_pe_import
Definition: hecmw_couple_inter_iftable.h:20
hecmw_couple_inter_iftable::import_index
int * import_index
Definition: hecmw_couple_inter_iftable.h:22
NULL
#define NULL
Definition: hecmw_io_nastran.c:30
HECMW_free
#define HECMW_free(ptr)
Definition: hecmw_malloc.h:24
hecmw_couple_inter_iftable::neighbor_pe_import
int * neighbor_pe_import
Definition: hecmw_couple_inter_iftable.h:21
hecmw_couple_comm::comm
HECMW_Comm comm
Definition: hecmw_couple_struct.h:19
hecmw_couple_inter_iftable.h
HECMW_couple_alloc_weight_list
struct hecmw_couple_weight_list * HECMW_couple_alloc_weight_list(void)
Definition: hecmw_couple_weight.c:44
hecmw_couple_boundary::elem_node_index
int * elem_node_index
Definition: hecmw_couple_boundary_info.h:24
hecmw_couple_inter_iftable::n_neighbor_pe_export
int n_neighbor_pe_export
Definition: hecmw_couple_inter_iftable.h:24
hecmw_couple_boundary::elem_node_item
int * elem_node_item
Definition: hecmw_couple_boundary_info.h:25
hecmw_couple_boundary_item::item
int * item
Definition: hecmw_couple_boundary_info.h:18
hecmw_couple_define.h
hecmw_couple_vector::z
double z
Definition: hecmw_couple_n2s_with_area.c:44
HECMW_ETYPE_TET1
#define HECMW_ETYPE_TET1
Definition: hecmw_common_define.h:25
hecmw_couple_vector
Definition: hecmw_couple_n2s_with_area.c:41