YAC 3.21.0
Yet Another Coupler
Loading...
Searching...
No Matches
event.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//#define YAC_VERBOSE_EVENT
6
7#include <stdlib.h>
8#include <stdio.h>
9#include <string.h>
10#include "event.h"
11#include "utils_mci.h"
12#include "utils_common.h"
13
14#define SECONDS_PER_DAY 86400
15
17
18struct event {
19 int is_set;
20 struct _timedelta *model_time_step;
21 struct _timedelta *coupling_time_step;
22 struct _timedelta *dummy_time_step;
23 int lag;
27 struct _datetime *startdate;
28 struct _datetime *stopdate;
29 struct _datetime *currentdate;
30 struct _datetime *offset;
31 struct _event* coupling;
32};
33
34/* ---------------------------------------------------------------------- */
35
36struct event * yac_event_new () {
37
38 /* allocate memory for one event */
39 struct event * event = xmalloc(1 * sizeof (*event));
40
41 /* initialise the event struct */
42
43 event->is_set = 0;
44 event->lag = 0;
45
46 event->time_operation = TIME_NONE;
47
49
50 return event;
51}
52
53/* ---------------------------------------------------------------------- */
54
55void yac_event_add ( struct event * event,
56 char const * delta_model_time,
57 char const * delta_coupling_time,
58 int lag,
60 const char * startdate,
61 const char * stopdate) {
62
64 getCalendarType() != CALENDAR_NOT_SET, "no calendar has been defined")
65 YAC_ASSERT(!event->is_set, "event is already initialised.");
66
67 /* set the event triggering parameters */
68
69 char PTstring[MAX_TIMEDELTA_STR_LEN];
70
71 event->is_set = 1;
72 event->lag = lag;
73 event->time_operation = time_operation;
74
75 /* create dummy_event */
76
77 event->dummy_time_step = newTimeDelta(getPTStringFromMS(0, PTstring));
78
79 /* model time step and coupling time step need to be converted */
80 event->model_time_step = newTimeDelta(delta_model_time);
81 event->coupling_time_step = newTimeDelta(delta_coupling_time);
82
85 "failed to generate model timestep from \"%s\" "
86 "(has to be in ISO 8601 format)", delta_model_time)
88 event->coupling_time_step, "failed to generate model timestep from \"%s\" "
89 "(has to be in ISO 8601 format)", delta_coupling_time)
90
91 compare_return_val compare_timestep =
92 compareTimeDelta(event->model_time_step, event->coupling_time_step);
94 compare_timestep != greater_than,
95 "model timestep is bigger than coupling timestep (\"%s\" > \"%s\")",
96 delta_model_time, delta_coupling_time)
97
98 // if the model time step and the coupling time step are identical, a time
99 // operation does not make sense
100 if (compare_timestep == equal_to) event->time_operation = TIME_NONE;
101
102 calendarType set_calender = getCalendarType ();
103
105 set_calender != CALENDAR_NOT_SET, "Calendar is not set.")
106
107 event->startdate = newDateTime(startdate);
109 event->startdate != NULL, "Failed to parse startdate (\"%s\")",
110 startdate?startdate:"<NULL>")
111
112 event->currentdate = newDateTime(startdate);
114 event->currentdate != NULL, "Failed to parse startdate (\"%s\")",
115 startdate?startdate:"<NULL>")
116
117 event->stopdate = newDateTime(stopdate);
119 event->stopdate != NULL, "Failed to parse stopdate (\"%s\")",
120 stopdate?stopdate:"<NULL>")
121
122 // adjust current date by lag
123 if (lag < 0) {
124 event->model_time_step->sign='-';
125 lag = -lag;
126 }
127 for (int i = 0; i < lag; ++i)
129 addTimeDeltaToDateTime (
131
132 // start date has to be equal or less than the current date
133 if (event->model_time_step->sign == '-') {
134
135 event->coupling_time_step->sign = '-';
136 while (compareDatetime(event->currentdate, event->startdate) == less_than)
138 addTimeDeltaToDateTime (
140 event->coupling_time_step->sign = '+';
141 }
142 event->model_time_step->sign='+';
143
144 char timedelta_str[MAX_TIMEDELTA_STR_LEN];
145 char datetime_str[MAX_DATETIME_STR_LEN];
146 datetimeToString(event->startdate,datetime_str);
147 event->coupling =
148 newEvent(
149 "Coupling", (char *) datetime_str, (char *) datetime_str,
150 (char *) stopdate,
151 timedeltaToString(event->coupling_time_step, timedelta_str), NULL );
152
153 YAC_ASSERT(event->coupling != NULL, "ERROR in event definition")
154
155#ifdef YAC_VERBOSE_EVENT
156 printf ("event added\n" );
157 printf ("- start date: %s\n",
158 datetimeToString(event->startdate,datetime_str) );
159 printf ("- current date: %s\n",
160 datetimeToString(event->currentdate,datetime_str) );
161 printf ("- stop date: %s\n",
162 datetimeToString(event->stopdate,datetime_str) );
163 printf ("- model time step: %s\n",
164 timedeltaToString(event->model_time_step,timedelta_str) );
165 printf ("- coupling time step: %s\n",
166 timedeltaToString(event->coupling_time_step,timedelta_str) );
167#endif
168}
169
170/* ---------------------------------------------------------------------- */
171
172void yac_event_update ( struct event * event ) {
173
174 YAC_ASSERT(event->is_set, "event has not yet been initialised");
175
176 event->currentdate =
177 addTimeDeltaToDateTime(
179}
180
181/* ---------------------------------------------------------------------- */
182
184
185 /* Return value action:
186 --------------------
187
188 action = 0 : no action to be performed (NONE)
189 action = 1 : time operation required (only put) (REDUCTION)
190 action = 2 : coupling action required (COUPLING)
191 action = 3 : restart file needs to be written (RESTART)
192 action = 8 : date is out of bound, beyond restart (OUT_OF_BOUND)
193
194 action = 4-7: last put/get for restart (not used here)
195
196 -------------------------------------------------------------------- */
197
198#ifdef YAC_VERBOSE_EVENT
199 char datetime_str[MAX_DATETIME_STR_LEN];
200 printf ("- current date: %s\n",
201 datetimeToString(event->currentdate,datetime_str) );
202 printf ("- stop date: %s\n",
203 datetimeToString(event->stopdate,datetime_str) );
204#endif
205
206 compare_return_val check_stopdate =
207 compareDatetime(event->currentdate,event->stopdate);
208
210 (check_stopdate == less_than) ||
211 (check_stopdate == equal_to) ||
212 (check_stopdate == greater_than),
213 "compareDatetime(currentdate,stopdate) failed")
214
216
217 /* Detect out of bound */
218 if (check_stopdate == greater_than) {
219
220#ifdef YAC_VERBOSE_EVENT
221 printf ("event check delivers OUT_OF_BOUND\n");
222#endif
224
225 } else {
226
227 /* Detect active event */
228 if (isCurrentEventActive(event->coupling,
232
233 /* Detect restart event */
234 if (check_stopdate == equal_to) {
235
236#ifdef YAC_VERBOSE_EVENT
237 printf ("event check delivers RESTART\n" );
238#endif
239 action = RESTART;
240
241 } else {
242
243#ifdef YAC_VERBOSE_EVENT
244 printf ("event check delivers COUPLING\n" );
245#endif
247 }
248 } else {
249
250 action = (event->time_operation == TIME_NONE)?NONE:REDUCTION;
251 }
252 }
253
255 (action == NONE) || (action == REDUCTION) ||
256 (action == COUPLING) || (action == RESTART) ||
257 (action == OUT_OF_BOUND), "computed action is invalid")
258
259 event->action = action;
260 return action;
261}
262
263/* ---------------------------------------------------------------------- */
264
265void yac_event_delete ( struct event * event ) {
266
267 deallocateDateTime(event->startdate);
268 deallocateDateTime(event->currentdate);
269 deallocateDateTime(event->stopdate);
270
271 deallocateTimeDelta(event->dummy_time_step);
272 deallocateTimeDelta(event->model_time_step);
273 deallocateTimeDelta(event->coupling_time_step);
274
275 deallocateEvent(event->coupling);
276
277 free(event);
278
280}
281
282/* ---------------------------------------------------------------------- */
283
284int yac_get_event_lag ( struct event * event ) {
285
286 return event->lag;
287}
288
289/* ---------------------------------------------------------------------- */
290
292
293 return event->time_operation;
294}
295
296/* ---------------------------------------------------------------------- */
297
299 struct event * event, char * timedelta_str ) {
300
301 memset(timedelta_str,'\0',MAX_TIMEDELTA_STR_LEN);
302
303 timedeltaToString(event->coupling_time_step,timedelta_str);
304
305 return timedelta_str;
306}
307
308
309/* ---------------------------------------------------------------------- */
310
312 struct event * event, char * timedelta_str ) {
313
314 memset(timedelta_str,'\0',MAX_TIMEDELTA_STR_LEN);
315
316 timedeltaToString(event->model_time_step,timedelta_str);
317
318 return timedelta_str;
319}
320
322 struct event * event, char* datetime_str) {
323 datetimeToString(event->currentdate, datetime_str);
324 return datetime_str;
325}
326
328 struct event * event, char* datetime_str) {
329
330 YAC_ASSERT(event->is_set, "event has not yet been initialised");
331
332 struct _timedelta back = *(event->model_time_step);
333 back.sign = '-';
334
335 struct _datetime previousdate;
336 struct _datetime * result =
337 addTimeDeltaToDateTime(event->currentdate, &back, &previousdate);
339 result, "could not determine the previous datetime of the event");
340
341 datetimeToString(&previousdate, datetime_str);
342 return datetime_str;
343}
344
345static int64_t str2int64(char const * time) {
346
347 char * endptr;
348 int64_t time_int64_t = (int64_t)strtol(time, &endptr, 10);
349 YAC_ASSERT_F(*endptr == '\0', "invalid time string '%s'", time)
350 return time_int64_t;
351}
352
353char const * yac_time_to_ISO(
354 char const * time, enum yac_time_unit_type time_unit) {
355
356 YAC_ASSERT(time, "time is NULL");
358 (time_unit == C_MILLISECOND) ||
359 (time_unit == C_SECOND) ||
360 (time_unit == C_MINUTE) ||
361 (time_unit == C_HOUR) ||
362 (time_unit == C_ISO_FORMAT), "unsupported time unit")
363
365 getCalendarType() != CALENDAR_NOT_SET, "calendar has not yet been set")
366
367 static char PT_String_buffer[MAX_TIMEDELTA_STR_LEN];
368
369 switch (time_unit) {
370
371 default:
372 case (C_MILLISECOND):
373 getPTStringFromMS(str2int64(time), PT_String_buffer);
374 break;
375 case (C_SECOND):
376 getPTStringFromSeconds(str2int64(time), PT_String_buffer);
377 break;
378 case (C_MINUTE):
379 getPTStringFromMinutes(str2int64(time), PT_String_buffer);
380 break;
381 case (C_HOUR):
382 getPTStringFromHours(str2int64(time), PT_String_buffer);
383 break;
384 case (C_ISO_FORMAT):
385 strncpy(PT_String_buffer, time, MAX_TIMEDELTA_STR_LEN-1);
386 break;
387 };
388
389 return PT_String_buffer;
390}
#define YAC_ASSERT(exp, msg)
@ COUPLING
yac_reduction_type
@ TIME_NONE
yac_time_unit_type
@ C_SECOND
@ C_HOUR
@ C_MILLISECOND
@ C_MINUTE
@ C_ISO_FORMAT
char * yac_get_event_model_timestep(struct event *event, char *timedelta_str)
Definition event.c:311
char * yac_get_event_coupling_timestep(struct event *event, char *timedelta_str)
Definition event.c:298
int yac_get_event_lag(struct event *event)
Definition event.c:284
void yac_event_delete(struct event *event)
Definition event.c:265
char * yac_get_event_current_datetime(struct event *event, char *datetime_str)
Definition event.c:321
static int64_t str2int64(char const *time)
Definition event.c:345
struct event * yac_event_new()
Definition event.c:36
char * yac_get_event_previous_datetime(struct event *event, char *datetime_str)
Definition event.c:327
char const * yac_time_to_ISO(char const *time, enum yac_time_unit_type time_unit)
Definition event.c:353
int yac_get_event_time_operation(struct event *event)
Definition event.c:291
int yac_number_of_events
Definition event.c:16
void yac_event_add(struct event *event, char const *delta_model_time, char const *delta_coupling_time, int lag, enum yac_reduction_type time_operation, const char *startdate, const char *stopdate)
Definition event.c:55
enum yac_action_type yac_event_check(struct event *event)
Definition event.c:183
void yac_event_update(struct event *event)
Definition event.c:172
yac_action_type
Definition event.h:13
@ REDUCTION
Definition event.h:15
@ RESTART
Definition event.h:17
@ OUT_OF_BOUND
Definition event.h:22
@ NONE
Definition event.h:14
#define xmalloc(size)
Definition ppm_xfuncs.h:66
Definition event.c:18
enum yac_time_unit_type time_unit
Definition event.c:26
enum yac_reduction_type time_operation
Definition event.c:24
struct _datetime * stopdate
Definition event.c:28
struct _datetime * startdate
Definition event.c:27
struct _event * coupling
Definition event.c:31
enum yac_action_type action
Definition event.c:25
struct _datetime * offset
Definition event.c:30
struct _timedelta * model_time_step
Definition event.c:20
struct _datetime * currentdate
Definition event.c:29
int lag
Definition event.c:23
struct _timedelta * dummy_time_step
Definition event.c:22
struct _timedelta * coupling_time_step
Definition event.c:21
int is_set
Definition event.c:19
#define YAC_ASSERT_F(exp, format,...)
Definition yac_assert.h:39