FrontISTR  5.7.0
Large-scale structural analysis program with finit element method
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 
30 struct link_list {
31  int id;
32  double weight;
33  struct link_list *next;
34 };
35 
36 /*================================================================================================*/
37 
38 static 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 
49 static 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 
70 static 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 
110 error:
111  HECMW_free(sendbuf);
112  HECMW_free(recvbuf);
113  return -1;
114 }
115 
116 static 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 
141 static 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 
166 extern 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 
262 error:
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 
299 error:
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 }
hecmw_couple_boundary::surf
struct hecmw_couple_boundary_item * surf
Definition: hecmw_couple_boundary_info.h:23
hecmw_malloc.h
hecmw_couple_weight
Definition: hecmw_couple_weight.h:9
hecmw_couple_weight_list::info
struct hecmw_couple_weight * info
Definition: hecmw_couple_weight.h:18
hecmw_couple_weight.h
HECMW_malloc
#define HECMW_malloc(size)
Definition: hecmw_malloc.h:20
mesh
struct hecmwST_local_mesh * mesh
Definition: hecmw_repart.h:71
hecmw_couple_weight::n
int n
Definition: hecmw_couple_weight.h:13
HECMW_couple_free_weight
void HECMW_couple_free_weight(struct hecmw_couple_weight *p)
Definition: hecmw_couple_weight.c:34
HECMW_couple_free_weight_list
void HECMW_couple_free_weight_list(struct hecmw_couple_weight_list *r)
Definition: hecmw_couple_weight.c:59
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_boundary_item::n
int n
Definition: hecmw_couple_boundary_info.h:17
hecmw_couple_boundary
Definition: hecmw_couple_boundary_info.h:18
hecmw_couple_comm.h
hecmw_couple_weight_list
Definition: hecmw_couple_weight.h:17
hecmw_couple_n2s_average.h
HECMW_COUPLE_IP_NODE_TO_SURF
#define HECMW_COUPLE_IP_NODE_TO_SURF
Definition: hecmw_couple_define.h:47
n2s_average
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)
Definition: hecmw_couple_n2s_average.c:166
hecmw_couple_intra_iftable
Definition: hecmw_couple_intra_iftable.h:13
HECMW_calloc
#define HECMW_calloc(nmemb, size)
Definition: hecmw_malloc.h:21
hecmw_struct.h
HECMWCPL_E_NONSUPPORT_ETYPE
#define HECMWCPL_E_NONSUPPORT_ETYPE
Definition: hecmw_couple_define.h:177
HECMW_couple_intra_send_recv
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)
Definition: hecmw_couple_comm.c:150
hecmw_couple_intra_iftable::neighbor_pe
int * neighbor_pe
Definition: hecmw_couple_intra_iftable.h:18
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_comm
Definition: hecmw_couple_struct.h:12
HECMW_couple_n2s_average
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)
Definition: hecmw_couple_n2s_average.c:270
hecmw_couple_intra_iftable::export_index
int * export_index
Definition: hecmw_couple_intra_iftable.h:21
hecmw_couple_weight::type
int type
Definition: hecmw_couple_weight.h:14
hecmw_couple_intra_iftable.h
hecmw_couple_struct.h
HECMW_couple_alloc_weight
struct hecmw_couple_weight * HECMW_couple_alloc_weight(void)
Definition: hecmw_couple_weight.c:16
hecmw_couple_intra_iftable::import_index
int * import_index
Definition: hecmw_couple_intra_iftable.h:19
HECMW_ETYPE_HEX1
#define HECMW_ETYPE_HEX1
Definition: hecmw_common_define.h:31
hecmw_couple_boundary_info.h
hecmw_couple_intra_iftable::import_item
int * import_item
Definition: hecmw_couple_intra_iftable.h:20
hecmw_common_define.h
hecmw_couple_intra_iftable::export_item
int * export_item
Definition: hecmw_couple_intra_iftable.h:22
HECMW_INT
#define HECMW_INT
Definition: hecmw_config.h:48
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
NULL
#define NULL
Definition: hecmw_io_nastran.c:30
hecmw_couple_intra_iftable::n_neighbor_pe
int n_neighbor_pe
Definition: hecmw_couple_intra_iftable.h:17
HECMWCPL_E_INVALID_ARG
#define HECMWCPL_E_INVALID_ARG
Definition: hecmw_couple_define.h:91
HECMW_free
#define HECMW_free(ptr)
Definition: hecmw_malloc.h:24
hecmw_couple_comm::comm
HECMW_Comm comm
Definition: hecmw_couple_struct.h:19
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_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_ETYPE_TET1
#define HECMW_ETYPE_TET1
Definition: hecmw_common_define.h:25