YetAnotherCoupler 3.5.2
Loading...
Searching...
No Matches
fields.c
Go to the documentation of this file.
1// Copyright (c) 2024 The YAC Authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#include <stdlib.h>
6#include <string.h>
7#include "event.h"
8#include "utils_mci.h"
9#include "utils_common.h"
10#include "fields.h"
11
13
14 // general field related information
15
16 char * name;
17
19
21
25 char* timestep;
26
27 char current_datetime[MAX_DATETIME_STR_LEN]; // updated only in yac_coupling_field_get_datetime
28
29 // data exchange
30
32
33 union {
34 struct {
35 struct {
36 struct event * event;
39 double *** send_field_acc;
41 } * puts;
42 unsigned num_puts;
43 int ** mask;
44 } put;
45 struct {
46 struct event * event;
47 struct yac_interpolation * interpolation;
48 int * mask;
49 } get;
51};
52
53struct coupling_field *
54yac_coupling_field_new(char const * field_name, char const * component_name,
56 unsigned num_interp_fields, size_t collection_size, const char* timestep) {
57
58 struct coupling_field * cpl_field = xmalloc(1 * sizeof(*cpl_field));
59
60 cpl_field->name = xmalloc((strlen(field_name) + 1));
61 strcpy(cpl_field->name, field_name);
62 cpl_field->component_name = component_name?strdup(component_name):NULL;
63 cpl_field->grid = grid;
64 cpl_field->interp_fields = NULL;
65 cpl_field->num_interp_fields = (size_t)num_interp_fields;
67 cpl_field->timestep = strdup(timestep);
68 cpl_field->exchange_type = NOTHING;
69
70 if (num_interp_fields != 0) {
71
73 interp_fields != NULL,
74 "ERROR: num_interp_fields > 0 but not interpolation field provided")
75
76 cpl_field->interp_fields =
77 xmalloc((size_t)num_interp_fields * sizeof(*(cpl_field->interp_fields)));
78 memcpy(cpl_field->interp_fields, interp_fields,
79 (size_t)num_interp_fields * sizeof(*(cpl_field->interp_fields)));
80
81 }
82
83 return cpl_field;
84}
85
87
88 return field->collection_size;
89}
90
92
93 return field->timestep;
94}
95
97
98 return field->num_interp_fields;
99}
100
101enum yac_location
103 struct coupling_field * field, size_t interp_field_idx) {
104
105 return field->interp_fields[interp_field_idx].location;
106}
107
108const char * yac_get_coupling_field_name(struct coupling_field * field) {
109
110 return field->name;
111}
112
114 struct coupling_field * field) {
115
116 return field->grid;
117}
118
120
121 return field->component_name;
122}
123
126
127 return field->exchange_type;
128}
129
131 struct yac_interp_field field, struct yac_basic_grid * grid) {
132
133 return yac_basic_grid_get_data_size(grid, field.location);
134}
135
137 struct coupling_field * field, enum yac_location location) {
138
139 return yac_basic_grid_get_data_size(field->grid, location);
140}
141
142static void init_put_op_acc(
143 struct coupling_field * field, double init_value, double *** acc) {
144
145 size_t num_interp_fields = field->num_interp_fields;
146 size_t collection_size = field->collection_size;
147
148 for (size_t h = 0; h < collection_size; ++h) {
149 for (size_t j = 0; j < num_interp_fields; j++) {
150 size_t num_points =
151 get_interp_field_size(field->interp_fields[j], field->grid);
153 {
155 for (size_t m = 0; m < num_points; m++ ) {
156 acc[h][j][m] = init_value;
157 }
158 }
159 }
160 }
161}
162
163static void get_put_op_acc(
164 struct coupling_field * field, unsigned put_idx,
165 char const * routine_name, double **** acc) {
166
168 field->exchange_type == SOURCE,
169 "ERROR(%s): wrong field exchange type", routine_name)
170
172 put_idx < field->exchange_data.put.num_puts,
173 "ERROR(%s): put_idx is invalid", routine_name)
174
175 if (*acc != NULL) return;
176
177 size_t num_interp_fields = field->num_interp_fields;
178 size_t collection_size = field->collection_size;
179
180 /* Allocate memory for the accumulation */
181
182 *acc = xmalloc(collection_size * sizeof(**acc));
183
184 for (size_t h = 0; h < collection_size; ++h) {
185
186 (*acc)[h] = xmalloc(num_interp_fields * sizeof(***acc));
187
188 for (size_t j = 0; j < num_interp_fields; j++)
189 (*acc)[h][j] =
190 xmalloc(
192 field->interp_fields[j], field->grid) * sizeof(****acc));
193 }
194
195 /* Initialise memory for the accumulation */
196 init_put_op_acc(field, 0.0, *acc);
197}
198
200 struct coupling_field * field, unsigned put_idx) {
201
203 field, put_idx, "yac_get_coupling_field_put_op_send_field_acc",
204 &(field->exchange_data.put.puts[put_idx].send_field_acc));
205
206 return field->exchange_data.put.puts[put_idx].send_field_acc;
207}
208
210 struct coupling_field * field, unsigned put_idx) {
211
213 field, put_idx, "yac_get_coupling_field_put_op_send_frac_mask_acc",
214 &(field->exchange_data.put.puts[put_idx].send_frac_mask_acc));
215
216 return field->exchange_data.put.puts[put_idx].send_frac_mask_acc;
217}
218
220 struct coupling_field * field, size_t field_idx) {
221
222 int const * core_mask =
224 field->grid, field->interp_fields[field_idx].location);
225
226 int flag = 0;
227
228 // if the core mask is defined
229 if (core_mask != NULL) {
230
231 size_t field_size =
232 get_interp_field_size(field->interp_fields[field_idx], field->grid);
233
234 // check if the core mask contains values other than 1
235 for (size_t i = 0; (i < field_size) && !flag; ++i)
236 flag = core_mask[i] != 1;
237 }
238
239 return flag;
240}
241
243 struct coupling_field * field, size_t field_idx) {
244
245 int const * field_mask =
247 field->grid, field->interp_fields[field_idx]);
248
249 int flag = 0;
250
251 // if a field mask is defined
252 if (field_mask != NULL) {
253
254 size_t field_size =
255 get_interp_field_size(field->interp_fields[field_idx], field->grid);
256
257 // check if the core mask contains values other than 1
258 for (size_t i = 0; (i < field_size) && !flag; ++i)
259 flag = field_mask[i] != 1;
260 }
261
262 return flag;
263}
264
266
268 field->exchange_type == SOURCE,
269 "ERROR(yac_get_coupling_field_put_mask): "
270 "wrong field exchange type")
271
272 if (field->exchange_data.put.mask != NULL)
273 return field->exchange_data.put.mask;
274
275 size_t num_interp_fields = field->num_interp_fields;
276
277 // check whether for this put operation a field or core mask has been defined
278 int has_mask = 0;
279 for (size_t i = 0; (i < num_interp_fields) && !has_mask; ++i)
280 has_mask = check_core_mask(field, i) || check_field_mask(field, i);
281
282 int ** mask = NULL;
283
284 if (has_mask) {
285
286 mask = xmalloc(num_interp_fields * sizeof(*mask));
287
288 // generate mask from core and field mask
289 for (size_t i = 0; i < num_interp_fields; ++i) {
290 int const * core_mask =
292 field->grid, field->interp_fields[i].location);
293 int const * field_mask =
295 field->grid, field->interp_fields[i]);
296 size_t field_size =
297 get_interp_field_size(field->interp_fields[i], field->grid);
298 mask[i] = xmalloc(field_size * sizeof(**mask));
299 for (size_t j = 0; j < field_size; ++j)
300 mask[i][j] = ((core_mask == NULL) || (core_mask[j] != 0)) &&
301 ((field_mask == NULL) || (field_mask[j] != 0));
302 }
303 }
304
305 field->exchange_data.put.mask = mask;
306
307 return mask;
308}
309
311
313 field->exchange_type == TARGET,
314 "ERROR(yac_get_coupling_field_put_mask): "
315 "wrong field exchange type")
316
317 if (field->exchange_data.get.mask != NULL)
318 return field->exchange_data.get.mask;
319
320 // check whether for this put operation a field or core mask has been defined
321 int has_mask = check_core_mask(field, 0) || check_field_mask(field, 0);
322
323 int * mask = NULL;
324
325 if (has_mask) {
326
327 // generate mask from core and field mask
328 int const * core_mask =
330 field->grid, field->interp_fields[0].location);
331 int const * field_mask =
333 field->grid, field->interp_fields[0]);
334 size_t field_size =
335 get_interp_field_size(field->interp_fields[0], field->grid);
336 mask = xmalloc(field_size * sizeof(*mask));
337 for (size_t i = 0; i < field_size; ++i)
338 mask[i] = ((core_mask == NULL) || (core_mask[i] != 0)) &&
339 ((field_mask == NULL) || (field_mask[i] != 0));
340 }
341
342 field->exchange_data.get.mask = mask;
343
344 return mask;
345}
346
348 struct coupling_field * field, unsigned put_idx, double init_value) {
349
351 field->exchange_type == SOURCE,
352 "ERROR(yac_init_coupling_field_put_op_send_field_acc): "
353 "wrong field exchange type")
354
356 put_idx < field->exchange_data.put.num_puts,
357 "ERROR(yac_init_coupling_field_put_op_send_field_acc): "
358 "put_idx is invalid")
359
360 double *** send_field_acc =
361 (field->exchange_data.put.puts[put_idx].send_field_acc == NULL)?
363 field->exchange_data.put.puts[put_idx].send_field_acc;
364
365 init_put_op_acc(field, init_value, send_field_acc);
366}
367
369 struct coupling_field * field, unsigned put_idx, double init_value) {
370
372 field->exchange_type == SOURCE,
373 "ERROR(yac_init_coupling_field_put_op_send_frac_mask_acc): "
374 "wrong field exchange type")
375
377 put_idx < field->exchange_data.put.num_puts,
378 "ERROR(yac_init_coupling_field_put_op_send_frac_mask_acc): "
379 "put_idx is invalid")
380
381 double *** send_frac_mask_acc =
382 (field->exchange_data.put.puts[put_idx].send_frac_mask_acc == NULL)?
384 field->exchange_data.put.puts[put_idx].send_frac_mask_acc;
385
386 init_put_op_acc(field, init_value, send_frac_mask_acc);
387}
388
390 struct coupling_field * field, unsigned put_idx) {
391
393 field->exchange_type == SOURCE, "ERROR: wrong field exchange type")
394
396 put_idx < field->exchange_data.put.num_puts, "ERROR: put_idx is invalid")
397
398 return field->exchange_data.put.puts[put_idx].event;
399}
400
402 struct coupling_field * field, unsigned put_idx) {
403
405 field->exchange_type == SOURCE, "ERROR: wrong field exchange type")
406
408 put_idx < field->exchange_data.put.num_puts, "ERROR: put_idx is invalid")
409
410 return field->exchange_data.put.puts[put_idx].interpolation;
411}
412
414 struct coupling_field * field, unsigned put_idx) {
415
417 field->exchange_type == SOURCE, "ERROR: wrong field exchange type")
418
420 put_idx < field->exchange_data.put.num_puts, "ERROR: put_idx is invalid")
421
422 return field->exchange_data.put.puts[put_idx].time_accumulation_count;
423}
424
425void
427 unsigned put_idx, int count) {
428
430 field->exchange_type == SOURCE, "ERROR: wrong field exchange type")
431
433 put_idx < field->exchange_data.put.num_puts, "ERROR: put_idx is invalid")
434
435 field->exchange_data.put.puts[put_idx].time_accumulation_count = count;
436}
437
439
441 field->exchange_type == SOURCE, "ERROR: wrong field exchange type")
442
443 return field->exchange_data.put.num_puts;
444}
445
447 struct coupling_field * field) {
448
450 field->exchange_type == TARGET, "ERROR: wrong field exchange type")
451
452 return field->exchange_data.get.event;
453}
454
455struct yac_interpolation *
457
459 field->exchange_type == TARGET, "ERROR: wrong field exchange type")
460
461 return field->exchange_data.get.interpolation;
462}
463
465 struct coupling_field * field, struct event * event,
466 struct yac_interpolation * interpolation) {
467
469 field->exchange_type != TARGET,
470 "ERROR: a get operation has already been set (field \"%s\")",
471 field->name)
472
473 if (field->exchange_type == NOTHING) {
474 field->exchange_data.put.puts = NULL;
475 field->exchange_data.put.num_puts = 0;
476 field->exchange_type = SOURCE;
477 field->exchange_data.get.mask = NULL;
478 }
479
480 unsigned num_puts = field->exchange_data.put.num_puts;
481 field->exchange_data.put.num_puts++;
482
483 field->exchange_data.put.puts =
484 xrealloc(field->exchange_data.put.puts, (num_puts + 1) *
485 sizeof(*(field->exchange_data.put.puts)));
486
487 field->exchange_data.put.puts[num_puts].event = event;
488 field->exchange_data.put.puts[num_puts].interpolation = interpolation;
489 field->exchange_data.put.puts[num_puts].time_accumulation_count = 0;
490 field->exchange_data.put.puts[num_puts].send_field_acc = NULL;
491 field->exchange_data.put.puts[num_puts].send_frac_mask_acc = NULL;
492}
493
495 struct coupling_field * field, struct event * event,
496 struct yac_interpolation * interpolation) {
497
499 field->exchange_type == NOTHING,
500 "ERROR: a put or get operation has already been set (field \"%s\")",
501 field->name)
502
503 field->exchange_type = TARGET;
504 field->exchange_data.get.event = event;
505 field->exchange_data.get.interpolation = interpolation;
506 field->exchange_data.put.mask = NULL;
507}
508
510 struct coupling_field * cpl_field) {
511
512 return cpl_field->interp_fields;
513}
514
516 struct coupling_field * cpl_field) {
518 (cpl_field->exchange_type == SOURCE) ||
519 (cpl_field->exchange_type == TARGET),
520 "ERROR(yac_coupling_field_get_datetime): "
521 "datetime is not defined for non-exchanged fields "
522 "(field \"%s\")", cpl_field->name);
523 struct event * event =
524 (cpl_field->exchange_type == SOURCE)?
525 cpl_field->exchange_data.put.puts[0].event:
526 cpl_field->exchange_data.get.event;
527 return
529 event, cpl_field->current_datetime);
530}
531
533
534 size_t collection_size = cpl_field->collection_size;
535 size_t num_interp_fields = cpl_field->num_interp_fields;
536
537 if (cpl_field->exchange_type == SOURCE) {
538
539 for (unsigned put_idx = 0; put_idx < cpl_field->exchange_data.put.num_puts;
540 ++put_idx) {
541
542 struct event * event = cpl_field->exchange_data.put.puts[put_idx].event;
543 struct yac_interpolation * interpolation =
544 cpl_field->exchange_data.put.puts[put_idx].interpolation;
545 double ***send_field_acc =
546 cpl_field->exchange_data.put.puts[put_idx].send_field_acc;
547 double ***send_frac_mask_acc =
548 cpl_field->exchange_data.put.puts[put_idx].send_frac_mask_acc;
549
550 if (send_field_acc != NULL) {
551 for (size_t h = 0; h < collection_size; ++h) {
552 for (size_t j = 0; j < num_interp_fields; ++j)
553 free(send_field_acc[h][j]);
554 free(send_field_acc[h]);
555 }
556 free(send_field_acc);
557 }
558
559 if (send_frac_mask_acc != NULL) {
560 for (size_t h = 0; h < collection_size; ++h) {
561 for (size_t j = 0; j < num_interp_fields; ++j)
562 free(send_frac_mask_acc[h][j]);
563 free(send_frac_mask_acc[h]);
564 }
565 free(send_frac_mask_acc);
566 }
567
569 yac_interpolation_delete(interpolation);
570 }
571
572 free(cpl_field->exchange_data.put.puts);
573 if (cpl_field->exchange_data.put.mask) {
574 for (size_t i = 0; i < num_interp_fields; ++i)
575 free(cpl_field->exchange_data.put.mask[i]);
576 free(cpl_field->exchange_data.put.mask);
577 }
578
579 } else if (cpl_field->exchange_type == TARGET) {
580
583 if (cpl_field->exchange_data.get.mask)
584 free(cpl_field->exchange_data.get.mask);
585 }
586
587 free(cpl_field->name);
588 free(cpl_field->component_name);
589 free(cpl_field->interp_fields);
590 free(cpl_field->timestep);
591 free(cpl_field);
592}
int const * yac_basic_grid_get_field_mask(struct yac_basic_grid *grid, struct yac_interp_field field)
Definition basic_grid.c:118
size_t yac_basic_grid_get_data_size(struct yac_basic_grid *grid, enum yac_location location)
Definition basic_grid.c:147
int const * yac_basic_grid_get_core_mask(struct yac_basic_grid *grid, enum yac_location location)
Definition basic_grid.c:101
void yac_event_delete(struct event *event)
Definition event.c:258
char * yac_get_event_current_datetime(struct event *event, char *datetime_str)
Definition event.c:314
void yac_set_coupling_field_put_op(struct coupling_field *field, struct event *event, struct yac_interpolation *interpolation)
Definition fields.c:464
unsigned yac_get_coupling_field_collection_size(struct coupling_field *field)
Definition fields.c:86
static int check_core_mask(struct coupling_field *field, size_t field_idx)
Definition fields.c:219
const char * yac_get_coupling_field_timestep(struct coupling_field *field)
Definition fields.c:91
unsigned yac_get_coupling_field_num_puts(struct coupling_field *field)
Definition fields.c:438
void yac_set_coupling_field_get_op(struct coupling_field *field, struct event *event, struct yac_interpolation *interpolation)
Definition fields.c:494
char const * yac_get_coupling_field_comp_name(struct coupling_field *field)
Definition fields.c:119
int yac_get_coupling_field_put_op_time_accumulation_count(struct coupling_field *field, unsigned put_idx)
Definition fields.c:413
double *** yac_get_coupling_field_put_op_send_frac_mask_acc(struct coupling_field *field, unsigned put_idx)
Definition fields.c:209
struct yac_basic_grid * yac_coupling_field_get_basic_grid(struct coupling_field *field)
Definition fields.c:113
size_t yac_coupling_field_get_num_interp_fields(struct coupling_field *field)
Definition fields.c:96
struct yac_interpolation * yac_get_coupling_field_put_op_interpolation(struct coupling_field *field, unsigned put_idx)
Definition fields.c:401
enum yac_location yac_get_coupling_field_get_interp_field_location(struct coupling_field *field, size_t interp_field_idx)
Definition fields.c:102
struct event * yac_get_coupling_field_get_op_event(struct coupling_field *field)
Definition fields.c:446
static size_t get_interp_field_size(struct yac_interp_field field, struct yac_basic_grid *grid)
Definition fields.c:130
size_t yac_coupling_field_get_data_size(struct coupling_field *field, enum yac_location location)
Definition fields.c:136
struct yac_interp_field const * yac_coupling_field_get_interp_fields(struct coupling_field *cpl_field)
Definition fields.c:509
struct coupling_field * yac_coupling_field_new(char const *field_name, char const *component_name, struct yac_basic_grid *grid, struct yac_interp_field *interp_fields, unsigned num_interp_fields, size_t collection_size, const char *timestep)
Definition fields.c:54
int * yac_get_coupling_field_get_mask(struct coupling_field *field)
Definition fields.c:310
static void init_put_op_acc(struct coupling_field *field, double init_value, double ***acc)
Definition fields.c:142
struct event * yac_get_coupling_field_put_op_event(struct coupling_field *field, unsigned put_idx)
Definition fields.c:389
char * yac_coupling_field_get_datetime(struct coupling_field *cpl_field)
Definition fields.c:515
void yac_init_coupling_field_put_op_send_field_acc(struct coupling_field *field, unsigned put_idx, double init_value)
Definition fields.c:347
struct yac_interpolation * yac_get_coupling_field_get_op_interpolation(struct coupling_field *field)
Definition fields.c:456
void yac_set_coupling_field_put_op_time_accumulation_count(struct coupling_field *field, unsigned put_idx, int count)
Definition fields.c:426
enum yac_field_exchange_type yac_get_coupling_field_exchange_type(struct coupling_field *field)
Definition fields.c:125
const char * yac_get_coupling_field_name(struct coupling_field *field)
Definition fields.c:108
static int check_field_mask(struct coupling_field *field, size_t field_idx)
Definition fields.c:242
void yac_coupling_field_delete(struct coupling_field *cpl_field)
Definition fields.c:532
int ** yac_get_coupling_field_put_mask(struct coupling_field *field)
Definition fields.c:265
void yac_init_coupling_field_put_op_send_frac_mask_acc(struct coupling_field *field, unsigned put_idx, double init_value)
Definition fields.c:368
static void get_put_op_acc(struct coupling_field *field, unsigned put_idx, char const *routine_name, double ****acc)
Definition fields.c:163
double *** yac_get_coupling_field_put_op_send_field_acc(struct coupling_field *field, unsigned put_idx)
Definition fields.c:199
yac_field_exchange_type
Definition fields.h:12
@ SOURCE
Definition fields.h:14
@ TARGET
Definition fields.h:15
@ NOTHING
Definition fields.h:13
void yac_interpolation_delete(struct yac_interpolation *interp)
yac_location
Definition location.h:12
#define xrealloc(ptr, size)
Definition ppm_xfuncs.h:67
#define xmalloc(size)
Definition ppm_xfuncs.h:66
double *** send_field_acc
Definition fields.c:39
int time_accumulation_count
Definition fields.c:38
struct coupling_field::@61::@63 get
double *** send_frac_mask_acc
Definition fields.c:40
struct coupling_field::@61::@62 put
struct yac_basic_grid * grid
Definition fields.c:20
char current_datetime[MAX_DATETIME_STR_LEN]
Definition fields.c:27
union coupling_field::@61 exchange_data
struct yac_interp_field * interp_fields
Definition fields.c:22
enum yac_field_exchange_type exchange_type
Definition fields.c:31
unsigned num_puts
Definition fields.c:42
size_t num_interp_fields
Definition fields.c:23
char * timestep
Definition fields.c:25
struct event * event
Definition fields.c:36
struct coupling_field::@61::@62::@64 * puts
char * component_name
Definition fields.c:18
size_t collection_size
number of vertical levels or bundles
Definition fields.c:24
char * name
Definition fields.c:16
int * mask
Definition fields.c:48
int ** mask
Definition fields.c:43
struct yac_interpolation * interpolation
Definition fields.c:37
Definition event.c:18
enum yac_location location
Definition basic_grid.h:18
#define YAC_OMP_PARALLEL
#define YAC_OMP_FOR
static size_t num_points
Definition yac.c:137
#define YAC_ASSERT_F(exp, format,...)
Definition yac_assert.h:19
#define YAC_ASSERT(exp, msg)
Definition yac_assert.h:16