FrontISTR 5.2.0
Large-scale structural analysis program with finit element method
Loading...
Searching...
No Matches
hecmw_couple_intra_iftable.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 <assert.h>
10#include <errno.h>
11
12#include "hecmw_msgno.h"
13#include "hecmw_struct.h"
14#include "hecmw_malloc.h"
15#include "hecmw_error.h"
16
17#include "hecmw_couple_define.h"
18#include "hecmw_couple_struct.h"
19#include "hecmw_couple_comm.h"
22
23/*================================================================================================*/
24
27 if (p == NULL) return;
28
34 HECMW_free(p);
35 p = NULL;
36}
37
39 void) {
41 int size;
42
43 size = sizeof(struct hecmw_couple_intra_iftable);
44 p = (struct hecmw_couple_intra_iftable *)HECMW_malloc(size);
45 if (p == NULL) {
46 HECMW_set_error(errno, "");
47 return NULL;
48 }
49
50 p->n_neighbor_pe = 0;
51 p->neighbor_pe = NULL;
52 p->import_index = NULL;
53 p->import_item = NULL;
54 p->export_index = NULL;
55 p->export_item = NULL;
56
57 return p;
58}
59
60/*================================================================================================*/
61
62static int set_n_neighbor_pe(const struct hecmwST_local_mesh *mesh,
63 struct hecmw_couple_intra_iftable *intra_tbl) {
64 intra_tbl->n_neighbor_pe = mesh->n_neighbor_pe;
65
66 return 0;
67}
68
69static int set_neighbor_pe(const struct hecmwST_local_mesh *mesh,
70 struct hecmw_couple_intra_iftable *intra_tbl) {
71 int i;
72
73 if (intra_tbl->n_neighbor_pe == 0) return 0;
74
75 intra_tbl->neighbor_pe =
76 (int *)HECMW_malloc(sizeof(int) * intra_tbl->n_neighbor_pe);
77 if (intra_tbl->neighbor_pe == NULL) {
78 HECMW_set_error(errno, "");
79 return -1;
80 }
81 for (i = 0; i < mesh->n_neighbor_pe; i++) {
82 intra_tbl->neighbor_pe[i] = mesh->neighbor_pe[i];
83 }
84
85 return 0;
86}
87
88static int *mask_boundary_node(const struct hecmwST_local_mesh *mesh,
89 const struct hecmw_couple_boundary *boundary) {
90 int *is_boundary_node = NULL;
91 int node, i;
92
93 is_boundary_node = (int *)HECMW_malloc(sizeof(int) * mesh->n_node);
94 if (is_boundary_node == NULL) {
95 HECMW_set_error(errno, "");
96 return NULL;
97 }
98 for (i = 0; i < mesh->n_node; i++) {
99 is_boundary_node[i] = -1;
100 }
101 for (i = 0; i < boundary->node->n; i++) {
102 node = boundary->node->item[i];
103 is_boundary_node[node - 1] = i;
104 }
105
106 return is_boundary_node;
107}
108
109static int *mask_import_node(const struct hecmwST_local_mesh *mesh,
110 const int *is_boundary_node) {
111 int *is_import_node = NULL;
112 int node, i;
113
115
116 is_import_node = (int *)HECMW_calloc(
117 mesh->import_index[mesh->n_neighbor_pe] + 1, sizeof(int));
118 if (is_import_node == NULL) {
119 HECMW_set_error(errno, "");
120 return NULL;
121 }
122 for (i = 0; i < mesh->import_index[mesh->n_neighbor_pe]; i++) {
123 is_import_node[i] = -1;
124 }
125 for (i = 0; i < mesh->import_index[mesh->n_neighbor_pe]; i++) {
126 node = mesh->import_item[i];
127 if (is_boundary_node[node - 1] >= 0)
128 is_import_node[i] = is_boundary_node[node - 1];
129 }
130
131 return is_import_node;
132}
133
134static int *mask_export_node(const struct hecmwST_local_mesh *mesh,
135 const struct hecmw_couple_comm *intracomm,
136 int *is_import_node) {
137 int *is_export_node = NULL;
138 int rtc;
139
140 is_export_node = (int *)HECMW_calloc(
141 mesh->export_index[mesh->n_neighbor_pe] + 1, sizeof(int));
142 if (is_export_node == NULL) {
143 HECMW_set_error(errno, "");
144 return NULL;
145 }
146
148 mesh->import_index, is_import_node,
149 mesh->export_index, is_export_node,
150 HECMW_INT, intracomm->comm);
151 if (rtc != 0) {
152 HECMW_free(is_export_node);
153 return NULL;
154 }
155
156 return is_export_node;
157}
158
159static int set_intracomm_import_node(
160 const struct hecmwST_local_mesh *mesh, const int *is_boundary_node,
161 const int *is_import_node, struct hecmw_couple_intra_iftable *intra_tbl) {
162 int n_import, node, size, n, i, j;
163
164 HECMW_assert(intra_tbl->n_neighbor_pe > 0);
165
166 /* index */
167 intra_tbl->import_index =
168 (int *)HECMW_calloc(intra_tbl->n_neighbor_pe + 1, sizeof(int));
169 if (intra_tbl->import_index == NULL) {
170 HECMW_set_error(errno, "");
171 return -1;
172 }
173 for (n = 0, i = 0; i < mesh->n_neighbor_pe; i++) {
174 for (j = mesh->import_index[i]; j < mesh->import_index[i + 1]; j++) {
175 if (is_import_node[j] >= 0) n++;
176 }
177 intra_tbl->import_index[i + 1] = n;
178 }
179
180 /* item */
181 n_import = intra_tbl->import_index[intra_tbl->n_neighbor_pe];
182 if (n_import == 0) return 0;
183
184 intra_tbl->import_item = (int *)HECMW_malloc(sizeof(int) * n_import);
185 if (intra_tbl->import_item == NULL) {
186 HECMW_set_error(errno, "");
187 return -1;
188 }
189 for (n = 0, i = 0; i < mesh->n_neighbor_pe; i++) {
190 for (j = mesh->import_index[i]; j < mesh->import_index[i + 1]; j++) {
191 node = mesh->import_item[j];
192 if (is_import_node[j] >= 0) {
193 intra_tbl->import_item[n++] = is_boundary_node[node - 1];
194 }
195 }
196 HECMW_assert(n == intra_tbl->import_index[i + 1]);
197 }
198
199 return 0;
200}
201
202static int set_intracomm_export_node(
203 const struct hecmwST_local_mesh *mesh, const int *is_boundary_node,
204 const int *is_export_node, struct hecmw_couple_intra_iftable *intra_tbl) {
205 int n_export, size, node, n, i, j;
206
207 HECMW_assert(intra_tbl->n_neighbor_pe > 0);
208
209 /* index */
210 intra_tbl->export_index =
211 (int *)HECMW_calloc(intra_tbl->n_neighbor_pe + 1, sizeof(int));
212 if (intra_tbl->export_index == NULL) {
213 HECMW_set_error(errno, "");
214 return -1;
215 }
216 for (n = 0, i = 0; i < mesh->n_neighbor_pe; i++) {
217 for (j = mesh->export_index[i]; j < mesh->export_index[i + 1]; j++) {
218 node = mesh->export_item[j];
219 if (is_export_node[j] >= 0) n++;
220 }
221 intra_tbl->export_index[i + 1] = n;
222 }
223
224 /* item */
225 n_export = intra_tbl->export_index[intra_tbl->n_neighbor_pe];
226 if (n_export == 0) return 0;
227
228 intra_tbl->export_item = (int *)HECMW_malloc(sizeof(int) * n_export);
229 if (intra_tbl->export_item == NULL) {
230 HECMW_set_error(errno, "");
231 return -1;
232 }
233 for (n = 0, i = 0; i < mesh->n_neighbor_pe; i++) {
234 for (j = mesh->export_index[i]; j < mesh->export_index[i + 1]; j++) {
235 node = mesh->export_item[j];
236 if (is_export_node[j] >= 0) {
237 intra_tbl->export_item[n++] = is_boundary_node[node - 1];
238 }
239 }
240 HECMW_assert(n == intra_tbl->export_index[i + 1]);
241 }
242
243 return 0;
244}
245
246/*================================================================================================*/
247
249 const struct hecmwST_local_mesh *mesh,
250 const struct hecmw_couple_boundary *boundary,
251 const struct hecmw_couple_comm *intracomm) {
252 struct hecmw_couple_intra_iftable *intra_tbl;
253 int *is_boundary_node = NULL, *is_import_node = NULL, *is_export_node = NULL;
254
255 if (mesh == NULL) {
257 "HECMW_couple_make_intra_iftable(): 'mesh' is NULL");
258 return NULL;
259 }
260 if (boundary == NULL) {
262 "HECMW_couple_make_intra_iftable(): 'boundary' is NULL");
263 return NULL;
264 }
265 if (intracomm == NULL) {
267 "HECMW_couple_make_intra_iftable(): 'intracomm' is NULL");
268 return NULL;
269 }
270
271 /* allocation */
272 if ((intra_tbl = HECMW_couple_alloc_intra_iftable()) == NULL) return NULL;
273
274 /* set neighboring process information */
275 if (set_n_neighbor_pe(mesh, intra_tbl)) goto error;
276 if (intra_tbl->n_neighbor_pe == 0) return intra_tbl;
277
278 if (set_neighbor_pe(mesh, intra_tbl)) goto error;
279
280 /* masking */
281 if ((is_boundary_node = mask_boundary_node(mesh, boundary)) == NULL)
282 goto error;
283 if ((is_import_node = mask_import_node(mesh, is_boundary_node)) == NULL)
284 goto error;
285 if ((is_export_node = mask_export_node(mesh, intracomm, is_import_node)) ==
286 NULL)
287 goto error;
288
289 /* set import/export node information */
290 if (set_intracomm_import_node(mesh, is_boundary_node, is_import_node,
291 intra_tbl))
292 goto error;
293 if (set_intracomm_export_node(mesh, is_boundary_node, is_export_node,
294 intra_tbl))
295 goto error;
296
297 HECMW_free(is_import_node);
298 HECMW_free(is_export_node);
299 HECMW_free(is_boundary_node);
300 return intra_tbl;
301
302error:
303 HECMW_free(is_import_node);
304 HECMW_free(is_export_node);
305 HECMW_free(is_boundary_node);
307 return NULL;
308}
#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 HECMWCPL_E_INVALID_ARG
void HECMW_couple_free_intra_iftable(struct hecmw_couple_intra_iftable *p)
struct hecmw_couple_intra_iftable * HECMW_couple_alloc_intra_iftable(void)
struct hecmw_couple_intra_iftable * HECMW_couple_make_intra_iftable(const struct hecmwST_local_mesh *mesh, const struct hecmw_couple_boundary *boundary, const struct hecmw_couple_comm *intracomm)
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
#define HECMW_assert(cond)
Definition: hecmw_util.h:40
struct hecmw_couple_boundary_item * node