FrontISTR 5.2.0
Large-scale structural analysis program with finit element method
Loading...
Searching...
No Matches
hecmw_couple.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#include <math.h>
12
13#include "hecmw_msgno.h"
14#include "hecmw_common_define.h"
15#include "hecmw_struct.h"
16#include "hecmw_malloc.h"
17#include "hecmw_log.h"
18
19#include "hecmw_couple_define.h"
20#include "hecmw_couple_struct.h"
21#include "hecmw_couple_comm.h"
22#include "hecmw_couple_init.h"
26#include "hecmw_couple_weight.h"
28#include "hecmw_couple.h"
29
35};
36
37/*================================================================================================*/
38
39static void free_couple_values(struct hecmw_couple_values *p) {
40 if (p == NULL) return;
41
45 HECMW_free(p);
46 p = NULL;
47}
48
49static struct hecmw_couple_values *alloc_couple_values(void) {
50 struct hecmw_couple_values *p = NULL;
51
53 sizeof(struct hecmw_couple_values));
54 if (p == NULL) {
55 HECMW_set_error(errno, "");
56 return NULL;
57 }
59 p->node = NULL;
60 p->elem = NULL;
61 p->surf = NULL;
62
63 if ((p->node = HECMW_couple_alloc_couple_value()) == NULL) goto error;
64 if ((p->elem = HECMW_couple_alloc_couple_value()) == NULL) goto error;
65 if ((p->surf = HECMW_couple_alloc_couple_value()) == NULL) goto error;
69
70 return p;
71
72error:
73 free_couple_values(p);
74 return NULL;
75}
76
77/*================================================================================================*/
78
79static int update_import_node_value(
80 struct hecmw_couple_comm *intracomm,
81 struct hecmw_couple_intra_iftable *intra_tbl,
82 struct hecmw_couple_value *node_value) {
83 int *sendbuf_index = NULL, *recvbuf_index = NULL;
84 double *sendbuf = NULL, *recvbuf = NULL;
85 int nmemb, rtc, id, i, j;
86
87 if (intra_tbl->n_neighbor_pe == 0) return 0;
88
89 /*
90 * send buffer
91 */
92 /* index for send buffer */
93 sendbuf_index =
94 (int *)HECMW_calloc(intra_tbl->n_neighbor_pe + 1, sizeof(int));
95 if (sendbuf_index == NULL) {
96 HECMW_set_error(errno, "");
97 goto error;
98 }
99 for (i = 0; i < intra_tbl->n_neighbor_pe; i++) {
100 sendbuf_index[i + 1] = intra_tbl->export_index[i + 1] * node_value->n_dof;
101 }
102
103 /* send buffer */
104 nmemb =
105 intra_tbl->export_index[intra_tbl->n_neighbor_pe] * node_value->n_dof + 1;
106 sendbuf = (double *)HECMW_malloc(sizeof(double) * nmemb);
107 if (sendbuf == NULL) {
108 HECMW_set_error(errno, "");
109 goto error;
110 }
111 for (i = 0; i < intra_tbl->export_index[intra_tbl->n_neighbor_pe]; i++) {
112 id = intra_tbl->export_item[i];
113 for (j = 0; j < node_value->n_dof; j++) {
114 sendbuf[node_value->n_dof * i + j] =
115 node_value->value[node_value->n_dof * id + j];
116 }
117 }
118
119 /*
120 * receive buffer
121 */
122 /* index for receive buffer */
123 recvbuf_index =
124 (int *)HECMW_calloc(intra_tbl->n_neighbor_pe + 1, sizeof(int));
125 if (recvbuf_index == NULL) {
126 HECMW_set_error(errno, "");
127 goto error;
128 }
129 for (i = 0; i < intra_tbl->n_neighbor_pe; i++) {
130 recvbuf_index[i + 1] = intra_tbl->import_index[i + 1] * node_value->n_dof;
131 }
132
133 /* receive buffer */
134 nmemb =
135 intra_tbl->import_index[intra_tbl->n_neighbor_pe] * node_value->n_dof + 1;
136 recvbuf = (double *)HECMW_malloc(sizeof(double) * nmemb);
137 if (recvbuf == NULL) {
138 HECMW_set_error(errno, "");
139 goto error;
140 }
141
142 /*
143 * send and receive
144 */
146 intra_tbl->n_neighbor_pe, intra_tbl->neighbor_pe, sendbuf_index, sendbuf,
147 recvbuf_index, recvbuf, HECMW_DOUBLE, intracomm->comm);
148 if (rtc != 0) goto error;
149
150 /*
151 * store received value
152 */
153 for (i = 0; i < intra_tbl->import_index[intra_tbl->n_neighbor_pe]; i++) {
154 id = intra_tbl->import_item[i];
155 for (j = 0; j < node_value->n_dof; j++) {
156 node_value->value[node_value->n_dof * id + j] =
157 recvbuf[node_value->n_dof * i + j];
158 }
159 }
160
161 HECMW_free(sendbuf_index);
162 HECMW_free(sendbuf);
163 HECMW_free(recvbuf_index);
164 HECMW_free(recvbuf);
165 return 0;
166
167error:
168 HECMW_free(sendbuf_index);
169 HECMW_free(sendbuf);
170 HECMW_free(recvbuf_index);
171 HECMW_free(recvbuf);
172 return -1;
173}
174
175static int interpolation(const struct hecmw_couple_weight *p,
176 struct hecmw_couple_value *value_src,
177 struct hecmw_couple_value *value_dst) {
178 int n_dof, i, j, k;
179
180 n_dof = value_dst->n_dof;
181 for (i = 0; i < p->n; i++) {
182 for (j = p->index[i]; j < p->index[i + 1]; j++) {
183 for (k = 0; k < n_dof; k++) {
184 value_dst->value[i * n_dof + k] +=
185 value_src->value[(p->id[j]) * n_dof + k] * p->weight[j];
186 }
187 }
188 }
189
190 return 0;
191}
192
193static int pre_interpolation(const struct hecmw_couple_weight_list *ip_list_pre,
194 struct hecmw_couple_values *values) {
195 struct hecmw_couple_weight_list *p;
196
197 for (p = ip_list_pre->next; p; p = p->next) {
198 if (p->info->type ==
199 HECMW_COUPLE_IP_SURF_TO_NODE) { /* surface -> node */
200 if (interpolation(p->info, values->surf, values->node)) return -1;
201
202 } else { /* error */
204 return -1;
205 }
206 }
207
208 return 0;
209}
210
211static int main_interpolation(
212 const struct hecmw_couple_weight_list *ip_list_main,
213 const struct hecmw_couple_values *values_src,
214 struct hecmw_couple_value *value_send) {
215 struct hecmw_couple_weight_list *p;
216
217 for (p = ip_list_main->next; p; p = p->next) {
218 if (p->info->type ==
219 HECMW_COUPLE_IP_NODE_TO_NODE) { /* node -> node */
220 if (interpolation(p->info, values_src->node, value_send)) return -1;
221
222 } else if (p->info->type ==
223 HECMW_COUPLE_IP_SURF_TO_NODE) { /* surface -> node */
224 if (interpolation(p->info, values_src->surf, value_send)) return -1;
225
226 } else { /* error */
228 return -1;
229 }
230 }
231
232 return 0;
233}
234
235static int post_interpolation(
236 const struct hecmw_couple_weight_list *ip_list_post,
237 struct hecmw_couple_values *values) {
238 struct hecmw_couple_weight_list *p;
239
240 for (p = ip_list_post->next; p; p = p->next) {
241 if (p->info->type ==
242 HECMW_COUPLE_IP_NODE_TO_SURF) { /* node -> surface */
243 if (interpolation(p->info, values->node, values->surf)) return -1;
244
245 } else { /* error */
247 return -1;
248 }
249 }
250
251 return 0;
252}
253
254/*================================================================================================*/
255
256static int send_recv_n_dof(const struct hecmw_couple_inter_iftable *inter_tbl,
257 const struct hecmw_couple_value *value_src,
258 struct hecmw_couple_value *value_dst,
259 const struct hecmw_couple_comm *comm_src,
260 const struct hecmw_couple_comm *comm_dst,
261 const struct hecmw_couple_comm *intercomm) {
262 int n_send_pe = 0, n_recv_pe = 0, *send_pe = NULL, *recv_pe = NULL;
263 int *sendbuf_index = NULL, *recvbuf_index = NULL, *sendbuf = NULL,
264 *recvbuf = NULL;
265 int n_dof, size, rtc, i;
266
267 /*
268 * send buffer
269 */
270 if (comm_src->is_member) {
271 if (inter_tbl->n_neighbor_pe_export > 0) {
272 /* index for send buffer */
273 sendbuf_index =
274 (int *)HECMW_calloc(inter_tbl->n_neighbor_pe_export + 1, sizeof(int));
275 if (sendbuf_index == NULL) {
276 HECMW_set_error(errno, "");
277 goto error;
278 }
279 for (i = 0; i < inter_tbl->n_neighbor_pe_export; i++) {
280 sendbuf_index[i + 1] = sendbuf_index[i] + 1;
281 }
282
283 /* send buffer */
284 size = sizeof(int) * sendbuf_index[inter_tbl->n_neighbor_pe_export];
285 sendbuf = (int *)HECMW_malloc(size);
286 if (sendbuf == NULL) {
287 HECMW_set_error(errno, "");
288 goto error;
289 }
290 for (i = 0; i < sendbuf_index[inter_tbl->n_neighbor_pe_export]; i++) {
291 sendbuf[i] = value_src->n_dof;
292 }
293 }
294 }
295
296 /*
297 * receive buffer
298 */
299 if (comm_dst->is_member) {
300 if (inter_tbl->n_neighbor_pe_import > 0) {
301 /* index for receive buffer */
302 recvbuf_index =
303 (int *)HECMW_calloc(inter_tbl->n_neighbor_pe_import + 1, sizeof(int));
304 if (recvbuf_index == NULL) {
305 HECMW_set_error(errno, "");
306 goto error;
307 }
308 for (i = 0; i < inter_tbl->n_neighbor_pe_import; i++) {
309 recvbuf_index[i + 1] = recvbuf_index[i] + 1;
310 }
311
312 /* receive buffer */
313 size = sizeof(int) * recvbuf_index[inter_tbl->n_neighbor_pe_import];
314 recvbuf = (int *)HECMW_malloc(size);
315 if (recvbuf == NULL) {
316 HECMW_set_error(errno, "");
317 goto error;
318 }
319 }
320 }
321
322 /*
323 * send and receive
324 */
326 inter_tbl->n_neighbor_pe_export, inter_tbl->neighbor_pe_export,
327 sendbuf_index, sendbuf, inter_tbl->n_neighbor_pe_import,
328 inter_tbl->neighbor_pe_import, recvbuf_index, recvbuf, HECMW_INT,
329 intercomm->comm);
330 if (rtc != 0) goto error;
331
332 /*
333 * store received value
334 */
335 if (comm_dst->is_member) {
336 n_dof = recvbuf[0];
337 for (i = 1; i < inter_tbl->n_neighbor_pe_import; i++) {
338 HECMW_assert(n_dof == recvbuf[i]);
339 }
340 value_dst->n_dof = n_dof;
341 }
342
343 HECMW_free(send_pe);
344 HECMW_free(sendbuf_index);
345 HECMW_free(sendbuf);
346 HECMW_free(recv_pe);
347 HECMW_free(recvbuf_index);
348 HECMW_free(recvbuf);
349 return 0;
350
351error:
352 HECMW_free(send_pe);
353 HECMW_free(sendbuf_index);
354 HECMW_free(sendbuf);
355 HECMW_free(recv_pe);
356 HECMW_free(recvbuf_index);
357 HECMW_free(recvbuf);
358 return -1;
359}
360
361static int send_recv_couple_value(
362 const struct hecmw_couple_inter_iftable *inter_tbl,
363 const struct hecmw_couple_value *value_src,
364 struct hecmw_couple_value *value_dst,
365 const struct hecmw_couple_comm *comm_src,
366 const struct hecmw_couple_comm *comm_dst,
367 const struct hecmw_couple_comm *intercomm) {
368 int n_send_pe = 0, n_recv_pe = 0, *send_pe = NULL, *recv_pe = NULL;
369 int *sendbuf_index = NULL, *recvbuf_index = NULL;
370 double *sendbuf = NULL, *recvbuf = NULL;
371 int boundary_index, id, n_dof, size, rtc, i, j;
372
373 /*
374 * send buffer
375 */
376 if (comm_src->is_member) {
377 n_dof = value_src->n_dof;
378
379 if (inter_tbl->n_neighbor_pe_export > 0) {
380 /* index for send buffer */
381 sendbuf_index =
382 (int *)HECMW_calloc(inter_tbl->n_neighbor_pe_export + 1, sizeof(int));
383 if (sendbuf_index == NULL) {
384 HECMW_set_error(errno, "");
385 goto error;
386 }
387 for (i = 0; i < inter_tbl->n_neighbor_pe_export; i++) {
388 sendbuf_index[i + 1] = inter_tbl->export_index[i + 1] * n_dof;
389 }
390
391 /* send buffer */
392 size =
393 sizeof(double) * (sendbuf_index[inter_tbl->n_neighbor_pe_export] + 1);
394 sendbuf = (double *)HECMW_malloc(size);
395 if (sendbuf == NULL) {
396 HECMW_set_error(errno, "");
397 goto error;
398 }
399 for (i = 0;
400 i < inter_tbl->export_index[inter_tbl->n_neighbor_pe_export] * n_dof;
401 i++) {
402 sendbuf[i] = value_src->value[i];
403 }
404 }
405 }
406
407 /*
408 * receive buffer
409 */
410 if (comm_dst->is_member) {
411 if (inter_tbl->n_neighbor_pe_import > 0) {
412 /* index for receive buffer */
413 recvbuf_index =
414 (int *)HECMW_calloc(inter_tbl->n_neighbor_pe_import + 1, sizeof(int));
415 if (recvbuf_index == NULL) {
416 HECMW_set_error(errno, "");
417 goto error;
418 }
419 for (i = 0; i < inter_tbl->n_neighbor_pe_import; i++) {
420 recvbuf_index[i + 1] =
421 inter_tbl->import_index[i + 1] * value_dst->n_dof;
422 }
423
424 /* receive buffer */
425 size =
426 sizeof(double) * (recvbuf_index[inter_tbl->n_neighbor_pe_import] + 1);
427 recvbuf = (double *)HECMW_malloc(size);
428 if (recvbuf == NULL) {
429 HECMW_set_error(errno, "");
430 goto error;
431 }
432 }
433 }
434
435 if (!comm_src->is_member && !comm_dst->is_member) return HECMW_SUCCESS;
436
437 /*
438 * send and receive
439 */
441 inter_tbl->n_neighbor_pe_export, inter_tbl->neighbor_pe_export,
442 sendbuf_index, sendbuf, inter_tbl->n_neighbor_pe_import,
443 inter_tbl->neighbor_pe_import, recvbuf_index, recvbuf, HECMW_DOUBLE,
444 intercomm->comm);
445 if (rtc != 0) goto error;
446
447 /*
448 * store received value
449 */
450 if (comm_dst->is_member) {
451 n_dof = value_dst->n_dof;
452
453 size = sizeof(double) *
454 inter_tbl->import_index[inter_tbl->n_neighbor_pe_import] * n_dof;
455 value_dst->value = (double *)HECMW_malloc(size);
456 if (value_dst->value == NULL) {
457 HECMW_set_error(errno, "");
458 goto error;
459 }
460
461 for (i = 0; i < inter_tbl->import_index[inter_tbl->n_neighbor_pe_import];
462 i++) {
463 id = inter_tbl->import_item[i];
464 for (j = 0; j < n_dof; j++) {
465 value_dst->value[n_dof * id + j] = recvbuf[n_dof * i + j];
466 }
467 }
468 }
469
470 HECMW_free(send_pe);
471 HECMW_free(sendbuf_index);
472 HECMW_free(sendbuf);
473 HECMW_free(recv_pe);
474 HECMW_free(recvbuf_index);
475 HECMW_free(recvbuf);
476 return 0;
477
478error:
479 HECMW_free(send_pe);
480 HECMW_free(sendbuf_index);
481 HECMW_free(sendbuf);
482 HECMW_free(recv_pe);
483 HECMW_free(recvbuf_index);
484 HECMW_free(recvbuf);
485 return -1;
486}
487
488static int send_recv(const struct hecmw_couple_inter_iftable *inter_tbl,
489 const struct hecmw_couple_value *value_src,
490 struct hecmw_couple_value *value_dst,
491 const struct hecmw_couple_comm *comm_src,
492 const struct hecmw_couple_comm *comm_dst,
493 const struct hecmw_couple_comm *intercomm) {
494 if (send_recv_n_dof(inter_tbl, value_src, value_dst, comm_src, comm_dst,
495 intercomm))
496 return -1;
497 if (send_recv_couple_value(inter_tbl, value_src, value_dst, comm_src,
498 comm_dst, intercomm))
499 return -1;
500
501 return 0;
502}
503
504/*------------------------------------------------------------------------------------------------*/
505
506static int set_default_value(struct hecmw_couple_value *couple_value,
507 struct hecmw_couple_values *values_src) {
508 int nmemb, i;
509
510 if (couple_value->item_type ==
511 HECMW_COUPLE_NODE_GROUP) { /* Node Group */
512 nmemb = couple_value->n * couple_value->n_dof;
513 for (i = 0; i < nmemb; i++) {
514 values_src->node->value[i] = couple_value->value[i];
515 }
516
517 } else if (couple_value->item_type ==
518 HECMW_COUPLE_ELEMENT_GROUP) { /* Element Group */
519 nmemb = couple_value->n * couple_value->n_dof;
520 for (i = 0; i < nmemb; i++) {
521 values_src->elem->value[i] = couple_value->value[i];
522 }
523
524 } else if (couple_value->item_type ==
525 HECMW_COUPLE_SURFACE_GROUP) { /* Surface Group */
526 nmemb = couple_value->n * couple_value->n_dof;
527 for (i = 0; i < nmemb; i++) {
528 values_src->surf->value[i] = couple_value->value[i];
529 }
530
531 } else { /* error */
533 return -1;
534 }
535
536 HECMW_free(couple_value->item);
537 HECMW_free(couple_value->value);
538 couple_value->n = 0;
539 couple_value->n_dof = 0;
540 couple_value->item_type = HECMW_COUPLE_GROUP_UNDEF;
541 couple_value->item = NULL;
542 couple_value->value = NULL;
543
544 return 0;
545}
546
547static int init_send_value(const struct hecmw_couple_inter_iftable *inter_tbl,
548 const struct hecmw_couple_value *couple_value,
549 struct hecmw_couple_value *value_send) {
550 int nmemb, i;
551
552 /* n */
553 value_send->n = inter_tbl->export_index[inter_tbl->n_neighbor_pe_export];
554
555 /* n_dof */
556 value_send->n_dof = couple_value->n_dof;
557
558 /* item_type */
560
561 /* item */
562 value_send->item = (int *)HECMW_malloc(sizeof(int) * (value_send->n + 1));
563 if (value_send->item == NULL) {
564 HECMW_set_error(errno, "");
565 return -1;
566 }
567 for (i = 0; i < value_send->n; i++) {
568 value_send->item[i] = inter_tbl->export_item[i];
569 }
570
571 /* value */
572 nmemb = value_send->n * value_send->n_dof + 1;
573 value_send->value = (double *)HECMW_malloc(sizeof(double) * nmemb);
574 if (value_send->value == NULL) {
575 HECMW_set_error(errno, "");
576 return -1;
577 }
578 for (i = 0; i < nmemb; i++) {
579 value_send->value[i] = 0.0;
580 }
581
582 return 0;
583}
584
585static int init_recv_value(const struct hecmw_couple_inter_iftable *inter_tbl,
586 struct hecmw_couple_value *value_recv) {
587 int i;
588
589 /* n */
590 value_recv->n = inter_tbl->import_index[inter_tbl->n_neighbor_pe_import];
591
592 /* n_dof */
593 value_recv->n_dof = 0;
594
595 /* item_type */
597
598 /* item */
599 value_recv->item = (int *)HECMW_malloc(sizeof(int) * (value_recv->n + 1));
600 if (value_recv->item == NULL) {
601 HECMW_set_error(errno, "");
602 return -1;
603 }
604 for (i = 0; i < value_recv->n; i++) {
605 value_recv->item[i] = inter_tbl->import_item[i];
606 }
607
608 /* value */
609 value_recv->value = NULL;
610
611 return 0;
612}
613
614static int set_result_value(struct hecmw_couple_value *couple_value,
615 struct hecmw_couple_values *values_dst) {
616 if (values_dst->item_type ==
617 HECMW_COUPLE_NODE_GROUP) { /* Node Group */
618 couple_value->n = values_dst->node->n;
619 couple_value->n_dof = values_dst->node->n_dof;
620 couple_value->item_type = values_dst->node->item_type;
621 couple_value->item = values_dst->node->item;
622 couple_value->value = values_dst->node->value;
623 values_dst->node->item = NULL;
624 values_dst->node->value = NULL;
625
626 } else if (values_dst->item_type ==
627 HECMW_COUPLE_ELEMENT_GROUP) { /* Element Group */
628 couple_value->n = values_dst->elem->n;
629 couple_value->n_dof = values_dst->elem->n_dof;
630 couple_value->item_type = values_dst->elem->item_type;
631 couple_value->item = values_dst->elem->item;
632 couple_value->value = values_dst->elem->value;
633 values_dst->elem->item = NULL;
634 values_dst->elem->value = NULL;
635
636 } else if (values_dst->item_type ==
637 HECMW_COUPLE_SURFACE_GROUP) { /* Surface Group */
638 couple_value->n = values_dst->surf->n;
639 couple_value->n_dof = values_dst->surf->n_dof;
640 couple_value->item_type = values_dst->surf->item_type;
641 couple_value->item = values_dst->surf->item;
642 couple_value->value = values_dst->surf->value;
643 values_dst->surf->item = NULL;
644 values_dst->surf->value = NULL;
645
646 } else { /* error */
648 return -1;
649 }
650
651 return 0;
652}
653
654static int init_values(const struct hecmw_couple_boundary *boundary,
655 const struct hecmw_couple_value *couple_value,
656 struct hecmw_couple_values *couple_values) {
657 int nmemb, i;
658
659 couple_values->item_type = boundary->data_type;
660
661 /* Node */
662 if (boundary->node->n > 0) {
663 couple_values->node->n = boundary->node->n;
664 couple_values->node->n_dof = couple_value->n_dof;
665 couple_values->node->item_type = HECMW_COUPLE_NODE_GROUP;
666
667 couple_values->node->item =
668 (int *)HECMW_malloc(sizeof(int) * couple_values->node->n);
669 if (couple_values->node->item == NULL) {
670 HECMW_set_error(errno, "");
671 return -1;
672 }
673 for (i = 0; i < couple_values->node->n; i++) {
674 couple_values->node->item[i] = boundary->node->item[i];
675 }
676
677 nmemb = couple_values->node->n * couple_values->node->n_dof;
678 couple_values->node->value = (double *)HECMW_malloc(sizeof(double) * nmemb);
679 if (couple_values->node->value == NULL) {
680 HECMW_set_error(errno, "");
681 return -1;
682 }
683 for (i = 0; i < nmemb; i++) {
684 couple_values->node->value[i] = 0.0;
685 }
686 }
687
688 /* Element */
689 if (boundary->elem->n > 0) {
690 couple_values->elem->n = boundary->elem->n;
691 couple_values->elem->n_dof = couple_value->n_dof;
692 couple_values->elem->item_type = HECMW_COUPLE_ELEMENT_GROUP;
693
694 couple_values->elem->item =
695 (int *)HECMW_malloc(sizeof(int) * couple_values->elem->n);
696 if (couple_values->elem->item == NULL) {
697 HECMW_set_error(errno, "");
698 return -1;
699 }
700 for (i = 0; i < couple_values->elem->n; i++) {
701 couple_values->elem->item[i] = boundary->elem->item[i];
702 }
703
704 nmemb = couple_values->elem->n * couple_values->elem->n_dof;
705 couple_values->elem->value = (double *)HECMW_malloc(sizeof(double) * nmemb);
706 if (couple_values->elem->value == NULL) {
707 HECMW_set_error(errno, "");
708 return -1;
709 }
710 for (i = 0; i < nmemb; i++) {
711 couple_values->elem->value[i] = 0.0;
712 }
713 }
714
715 /* Surface */
716 if (boundary->surf->n > 0) {
717 couple_values->surf->n = boundary->surf->n;
718 couple_values->surf->n_dof = couple_value->n_dof;
719 couple_values->surf->item_type = HECMW_COUPLE_SURFACE_GROUP;
720
721 couple_values->surf->item =
722 (int *)HECMW_malloc(sizeof(int) * couple_values->surf->n * 2);
723 if (couple_values->surf->item == NULL) {
724 HECMW_set_error(errno, "");
725 return -1;
726 }
727 for (i = 0; i < couple_values->surf->n; i++) {
728 couple_values->surf->item[2 * i] = boundary->surf->item[2 * i];
729 couple_values->surf->item[2 * i + 1] = boundary->surf->item[2 * i + 1];
730 }
731
732 nmemb = couple_values->surf->n * couple_values->surf->n_dof;
733 couple_values->surf->value = (double *)HECMW_malloc(sizeof(double) * nmemb);
734 if (couple_values->surf->value == NULL) {
735 HECMW_set_error(errno, "");
736 return -1;
737 }
738 for (i = 0; i < nmemb; i++) {
739 couple_values->surf->value[i] = 0.0;
740 }
741 }
742
743 return 0;
744}
745
746/*================================================================================================*/
747
748extern int HECMW_couple(const char *boundary_id,
749 struct hecmw_couple_value *couple_value) {
750 struct hecmw_couple_values *values_src = NULL, *values_dst = NULL;
751 struct hecmw_couple_value *value_send = NULL, *value_recv = NULL;
752 struct hecmw_couple_info *couple_info = NULL;
753
754 if (boundary_id == NULL) {
756 "HECMW_couple(): 'boundary_id' is NULL");
757 return HECMW_ERROR;
758 }
759
760 if ((couple_info = HECMW_couple_get_info(boundary_id)) == NULL) goto error;
761
762 if (couple_info->comm_src->is_member) {
763 if (couple_value == NULL) {
765 "HECMW_couple(): 'couple_value' is NULL");
766 goto error;
767 }
768 }
769 if (couple_info->comm_dst->is_member) {
770 if (couple_value == NULL) {
771 if ((couple_value = HECMW_couple_alloc_couple_value()) == NULL)
772 goto error;
773 }
774 }
775
776 if ((value_send = HECMW_couple_alloc_couple_value()) == NULL) goto error;
777 if ((value_recv = HECMW_couple_alloc_couple_value()) == NULL) goto error;
778 if (couple_info->comm_src->is_member) {
779 if (init_send_value(couple_info->inter_tbl, couple_value, value_send))
780 goto error;
781 }
782 if (couple_info->comm_dst->is_member) {
783 if (init_recv_value(couple_info->inter_tbl, value_recv)) goto error;
784 }
785
786 /*
787 * pre-processing
788 */
789 if (couple_info->comm_src->is_member) {
790 if ((values_src = alloc_couple_values()) == NULL) goto error;
791
792 if (init_values(couple_info->boundary_src, couple_value, values_src))
793 goto error;
794 if (set_default_value(couple_value, values_src)) goto error;
795 if (pre_interpolation(couple_info->ip_list_pre, values_src)) goto error;
796 if (update_import_node_value(couple_info->comm_src,
797 couple_info->intra_tbl_src, values_src->node))
798 goto error;
799 if (main_interpolation(couple_info->ip_list_main, values_src, value_send))
800 goto error;
801
802 free_couple_values(values_src);
803 }
804
805 /* main interpolation */
806 if (couple_info->comm_src->is_member || couple_info->comm_dst->is_member) {
807 if (send_recv(couple_info->inter_tbl, value_send, value_recv,
808 couple_info->comm_src, couple_info->comm_dst,
809 couple_info->intercomm))
810 goto error;
811 }
813
814 /* post-processing */
815 if (couple_info->comm_dst->is_member) {
816 if ((values_dst = alloc_couple_values()) == NULL) goto error;
817
818 if (init_values(couple_info->boundary_dst, value_recv, values_dst))
819 goto error;
820 if (set_default_value(value_recv, values_dst)) goto error;
821 if (post_interpolation(couple_info->ip_list_post, values_dst)) goto error;
822 if (set_result_value(couple_value, values_dst)) goto error;
823
824 free_couple_values(values_dst);
825 }
826
828 return HECMW_SUCCESS;
829
830error:
831 free_couple_values(values_src);
832 free_couple_values(values_dst);
835 return HECMW_ERROR;
836}
#define HECMW_INT
Definition: hecmw_config.h:48
#define HECMW_DOUBLE
Definition: hecmw_config.h:50
#define HECMW_ERROR
Definition: hecmw_config.h:66
#define HECMW_SUCCESS
Definition: hecmw_config.h:64
int HECMW_couple(const char *boundary_id, struct hecmw_couple_value *couple_value)
Definition: hecmw_couple.c:748
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)
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_ELEMENT_GROUP
#define HECMWCPL_E_INVALID_MAPTYPE
#define HECMW_COUPLE_IP_NODE_TO_NODE
#define HECMW_COUPLE_NODE_GROUP
#define HECMW_COUPLE_IP_SURF_TO_NODE
#define HECMWCPL_E_INVALID_GRPTYPE
#define HECMW_COUPLE_IP_NODE_TO_SURF
#define HECMW_COUPLE_GROUP_UNDEF
#define HECMWCPL_E_INVALID_IPTYPE
#define HECMWCPL_E_INVALID_ARG
#define HECMW_COUPLE_SURFACE_GROUP
struct hecmw_couple_info * HECMW_couple_get_info(const char *boundary_id)
struct hecmw_couple_value * HECMW_couple_alloc_couple_value(void)
void HECMW_couple_free_couple_value(struct hecmw_couple_value *couple_value)
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
real(kind=kreal), dimension(:), allocatable values
a
struct hecmw_couple_boundary_item * elem
struct hecmw_couple_boundary_item * node
struct hecmw_couple_boundary_item * surf
struct hecmw_couple_weight_list * ip_list_pre
struct hecmw_couple_comm * comm_src
struct hecmw_couple_comm * comm_dst
struct hecmw_couple_comm * intercomm
struct hecmw_couple_boundary * boundary_dst
struct hecmw_couple_weight_list * ip_list_post
struct hecmw_couple_weight_list * ip_list_main
struct hecmw_couple_boundary * boundary_src
struct hecmw_couple_intra_iftable * intra_tbl_src
struct hecmw_couple_inter_iftable * inter_tbl
struct hecmw_couple_value * elem
Definition: hecmw_couple.c:33
struct hecmw_couple_value * surf
Definition: hecmw_couple.c:34
struct hecmw_couple_value * node
Definition: hecmw_couple.c:32
struct hecmw_couple_weight_list * next
struct hecmw_couple_weight * info