YetAnotherCoupler 3.5.2
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,
65 "ERROR(yac_event_add): no calendar has been defined")
67 "ERROR(yac_event_add): event is already initialised.");
68
69 /* set the event triggering parameters */
70
71 char PTstring[MAX_TIMEDELTA_STR_LEN];
72
73 event->is_set = 1;
74 event->lag = lag;
75 event->time_operation = time_operation;
76
77 /* create dummy_event */
78
79 event->dummy_time_step = newTimeDelta(getPTStringFromMS(0, PTstring));
80
81 /* model time step and coupling time step need to be converted */
82 event->model_time_step = newTimeDelta(delta_model_time);
83 event->coupling_time_step = newTimeDelta(delta_coupling_time);
84
87 "ERROR(yac_event_add): failed to generate model timestep from \"%s\" "
88 "(has to be in ISO 8601 format)", delta_model_time)
91 "ERROR(yac_event_add): failed to generate model timestep from \"%s\""
92 "(has to be in ISO 8601 format)", delta_coupling_time)
93
94 compare_return_val compare_timestep =
95 compareTimeDelta(event->model_time_step, event->coupling_time_step);
97 compare_timestep != greater_than,
98 "ERROR(yac_event_add): model timestep is bigger than coupling timestep "
99 "(\"%s\" > \"%s\")", delta_model_time, delta_coupling_time)
100
101 // if the model time step and the coupling time step are identical, a time
102 // operation does not make sense
103 if (compare_timestep == equal_to) event->time_operation = TIME_NONE;
104
105 calendarType set_calender = getCalendarType ();
106
108 set_calender != CALENDAR_NOT_SET, "ERROR: Calendar is not set.")
109
110 event->startdate = newDateTime(startdate);
111 YAC_ASSERT(event->startdate != NULL, "ERROR in event definition: failed to parse startdate")
112
113 event->currentdate = newDateTime(startdate);
114 YAC_ASSERT(event->currentdate != NULL, "ERROR in event definition: failed to parse startdate")
115
116 event->stopdate = newDateTime(stopdate);
117 YAC_ASSERT(event->stopdate != NULL, "ERROR in event definition: failed to parse stopdate")
118
119
120 // adjust current date by lag
121 if (lag < 0) {
122 event->model_time_step->sign='-';
123 lag = -lag;
124 }
125 for (int i = 0; i < lag; ++i)
127 addTimeDeltaToDateTime (
129
130 // start date has to be equal or less than the current date
131 if (event->model_time_step->sign == '-') {
132
133 event->coupling_time_step->sign = '-';
134 while (compareDatetime(event->currentdate, event->startdate) == less_than)
135 event->startdate =
136 addTimeDeltaToDateTime (
138 event->coupling_time_step->sign = '+';
139 }
140 event->model_time_step->sign='+';
141
142 char timedelta_str[MAX_TIMEDELTA_STR_LEN];
143 char datetime_str[MAX_DATETIME_STR_LEN];
144 datetimeToString(event->startdate,datetime_str);
145 event->coupling =
146 newEvent(
147 "Coupling", (char *) datetime_str, (char *) datetime_str,
148 (char *) stopdate,
149 timedeltaToString(event->coupling_time_step, timedelta_str), NULL );
150
151 YAC_ASSERT(event->coupling != NULL, "ERROR in event definition")
152
153#ifdef YAC_VERBOSE_EVENT
154 printf ("event added\n" );
155 printf ("- start date: %s\n",
156 datetimeToString(event->startdate,datetime_str) );
157 printf ("- current date: %s\n",
158 datetimeToString(event->currentdate,datetime_str) );
159 printf ("- stop date: %s\n",
160 datetimeToString(event->stopdate,datetime_str) );
161 printf ("- model time step: %s\n",
162 timedeltaToString(event->model_time_step,timedelta_str) );
163 printf ("- coupling time step: %s\n",
164 timedeltaToString(event->coupling_time_step,timedelta_str) );
165#endif
166}
167
168/* ---------------------------------------------------------------------- */
169
170void yac_event_update ( struct event * event ) {
171
173 "ERROR(yac_event_update): event has not yet been initialised");
174
175 event->currentdate =
176 addTimeDeltaToDateTime(
178}
179
180/* ---------------------------------------------------------------------- */
181
183
184 /* Return value action:
185 --------------------
186
187 action = 0 : no action to be performed
188 action = 1 : time operation required (only put)
189 action = 2 : coupling action required
190 action = 3 : restart file needs to be written
191 action = 4-7: last put/get for restart
192 action = 8 : date is out of bound, beyond restart
193
194 -------------------------------------------------------------------- */
195
196#ifdef YAC_VERBOSE_EVENT
197 char datetime_str[MAX_DATETIME_STR_LEN];
198 printf ("- current date: %s\n",
199 datetimeToString(event->currentdate,datetime_str) );
200 printf ("- stop date: %s\n",
201 datetimeToString(event->stopdate,datetime_str) );
202#endif
203
204 compare_return_val check_stopdate =
205 compareDatetime(event->currentdate,event->stopdate);
206
208 (check_stopdate == less_than) ||
209 (check_stopdate == equal_to) ||
210 (check_stopdate == greater_than),
211 "ERROR(yac_event_check): compareDatetime(currentdate,stopdate) failed")
212
214
215 /* Detect out of bound */
216 if (check_stopdate == greater_than) {
217
218#ifdef YAC_VERBOSE_EVENT
219 printf ("event check delivers OUT_OF_BOUND\n");
220#endif
222
223 } else {
224
225 /* Detect active event */
226 if (isCurrentEventActive(event->coupling,
230
231 /* Detect restart event */
232 if (check_stopdate == equal_to) {
233
234#ifdef YAC_VERBOSE_EVENT
235 printf ("event check delivers RESTART\n" );
236#endif
237 action = RESTART;
238
239 } else {
240
241#ifdef YAC_VERBOSE_EVENT
242 printf ("event check delivers COUPLING\n" );
243#endif
245 }
246 } else {
247
248 action = (event->time_operation == TIME_NONE)?NONE:REDUCTION;
249 }
250 }
251
252 event->action = action;
253 return action;
254}
255
256/* ---------------------------------------------------------------------- */
257
258void yac_event_delete ( struct event * event ) {
259
260 deallocateDateTime(event->startdate);
261 deallocateDateTime(event->currentdate);
262 deallocateDateTime(event->stopdate);
263
264 deallocateTimeDelta(event->dummy_time_step);
265 deallocateTimeDelta(event->model_time_step);
266 deallocateTimeDelta(event->coupling_time_step);
267
268 deallocateEvent(event->coupling);
269
270 free(event);
271
273}
274
275/* ---------------------------------------------------------------------- */
276
277int yac_get_event_lag ( struct event * event ) {
278
279 return event->lag;
280}
281
282/* ---------------------------------------------------------------------- */
283
285
286 return event->time_operation;
287}
288
289/* ---------------------------------------------------------------------- */
290
292 struct event * event, char * timedelta_str ) {
293
294 memset(timedelta_str,'\0',MAX_TIMEDELTA_STR_LEN);
295
296 timedeltaToString(event->coupling_time_step,timedelta_str);
297
298 return timedelta_str;
299}
300
301
302/* ---------------------------------------------------------------------- */
303
305 struct event * event, char * timedelta_str ) {
306
307 memset(timedelta_str,'\0',MAX_TIMEDELTA_STR_LEN);
308
309 timedeltaToString(event->model_time_step,timedelta_str);
310
311 return timedelta_str;
312}
313
315 struct event * event, char* datetime_str) {
316 datetimeToString(event->currentdate, datetime_str);
317 return datetime_str;
318}
319
320static int64_t str2int64(char const * time) {
321
322 char * endptr;
323 int64_t time_int64_t = (int64_t)strtol(time, &endptr, 10);
325 *endptr == '\0', "ERROR(str2int64): invalid time string '%s'", time)
326 return time_int64_t;
327}
328
329char const * yac_time_to_ISO(
330 char const * time, enum yac_time_unit_type time_unit) {
331
332 YAC_ASSERT(time, "ERROR(yac_time_to_ISO): time is NULL");
335 (time_unit == C_SECOND) ||
336 (time_unit == C_MINUTE) ||
337 (time_unit == C_HOUR) ||
339 "ERROR(yac_time_to_ISO): unsupported time unit")
340
342 getCalendarType() != CALENDAR_NOT_SET,
343 "ERROR(yac_time_to_ISO): calendar has not yet been set")
344
345 static char PT_String_buffer[MAX_TIMEDELTA_STR_LEN];
346
347 switch (time_unit) {
348
349 default:
350 case (C_MILLISECOND):
351 getPTStringFromMS(str2int64(time), PT_String_buffer);
352 break;
353 case (C_SECOND):
354 getPTStringFromSeconds(str2int64(time), PT_String_buffer);
355 break;
356 case (C_MINUTE):
357 getPTStringFromMinutes(str2int64(time), PT_String_buffer);
358 break;
359 case (C_HOUR):
360 getPTStringFromHours(str2int64(time), PT_String_buffer);
361 break;
362 case (C_ISO_FORMAT):
363 strncpy(PT_String_buffer, time, MAX_TIMEDELTA_STR_LEN-1);
364 break;
365 };
366
367 return PT_String_buffer;
368}
@ 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:304
char * yac_get_event_coupling_timestep(struct event *event, char *timedelta_str)
Definition event.c:291
int yac_get_event_lag(struct event *event)
Definition event.c:277
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
static int64_t str2int64(char const *time)
Definition event.c:320
struct event * yac_event_new()
Definition event.c:36
char const * yac_time_to_ISO(char const *time, enum yac_time_unit_type time_unit)
Definition event.c:329
int yac_get_event_time_operation(struct event *event)
Definition event.c:284
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:182
void yac_event_update(struct event *event)
Definition event.c:170
yac_action_type
Definition event.h:17
@ REDUCTION
Definition event.h:19
@ RESTART
Definition event.h:21
@ OUT_OF_BOUND
Definition event.h:26
@ NONE
Definition event.h:18
#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:19
#define YAC_ASSERT(exp, msg)
Definition yac_assert.h:16