YetAnotherCoupler 3.2.0_a
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 // if the model time step and the coupling time step are identical, a time
95 // operation does not make sense
96 if (compareTimeDelta(event->model_time_step, event->coupling_time_step)
97 == equal_to) {
98 event->time_operation = TIME_NONE;
99 }
100
101 calendarType set_calender = getCalendarType ();
102
104 set_calender != CALENDAR_NOT_SET, "ERROR: Calendar is not set.")
105
106 event->startdate = newDateTime(startdate);
107 YAC_ASSERT(event->startdate != NULL, "ERROR in event definition: failed to parse startdate")
108
109 event->currentdate = newDateTime(startdate);
110 YAC_ASSERT(event->currentdate != NULL, "ERROR in event definition: failed to parse startdate")
111
112 event->stopdate = newDateTime(stopdate);
113 YAC_ASSERT(event->stopdate != NULL, "ERROR in event definition: failed to parse stopdate")
114
115 char timedelta_str[MAX_TIMEDELTA_STR_LEN];
116
117 event->coupling =
118 newEvent(
119 "Coupling", (char *) startdate, (char *) startdate, (char *) stopdate,
120 timedeltaToString(event->coupling_time_step, timedelta_str), NULL );
121
122 YAC_ASSERT(event->coupling != NULL, "ERROR in event definition")
123
124#ifdef YAC_VERBOSE_EVENT
125 char datetime_str[MAX_DATETIME_STR_LEN];
126 printf ("event add for event ID %d \n", event_id );
127 printf ("- start date: %s\n",
128 datetimeToString(event->startdate,datetime_str) );
129 printf ("- current date: %s\n",
130 datetimeToString(event->currentdate,datetime_str) );
131 printf ("- stop date: %s\n",
132 datetimeToString(event->stopdate,datetime_str) );
133 printf ("- model time step: %s\n",
134 timedeltaToString(event->model_time_step,timedelta_str) );
135 printf ("- coupling time step: %s\n",
136 timedeltaToString(event->coupling_time_step,timedelta_str) );
137#endif
138
139 YAC_ASSERT(event->lag >= 0, "ERROR: lag has to be positive or zero")
140
141 /* add lag times delta(t) to the current date such that we can detect
142 a restart event which has to be performed lag times delta(t) before
143 the final date is reached. */
144 if ( event->lag > 0 ) {
145 for ( int i = 0; i < event->lag; ++i )
147 addTimeDeltaToDateTime (
149#ifdef YAC_VERBOSE_EVENT
150 printf ("- model time lag: %d\n", event->lag );
151 printf ("- new current date: %s\n",
152 datetimeToString(event->currentdate,datetime_str) );
153#endif
154 }
155}
156
157/* ---------------------------------------------------------------------- */
158
159void yac_event_update ( struct event * event ) {
160
162 "ERROR(yac_event_update): event has not yet been initialised");
163
164 event->currentdate =
165 addTimeDeltaToDateTime(
167}
168
169/* ---------------------------------------------------------------------- */
170
172
173 /* Return value action:
174 --------------------
175
176 action = 0 : no action to be performed
177 action = 1 : time operation required (only put)
178 action = 2 : coupling action required
179 action = 3 : restart file needs to be written
180 action = 4-7: last put/get for restart
181 action = 8 : date is out of bound, beyond restart
182
183 -------------------------------------------------------------------- */
184
185#ifdef YAC_VERBOSE_EVENT
186 char datetime_str[MAX_DATETIME_STR_LEN];
187 printf ("- current date: %s\n",
188 datetimeToString(event->currentdate,datetime_str) );
189 printf ("- stop date: %s\n",
190 datetimeToString(event->stopdate,datetime_str) );
191#endif
192
193 compare_return_val check_stopdate =
194 compareDatetime(event->currentdate,event->stopdate);
195
197 (check_stopdate == less_than) ||
198 (check_stopdate == equal_to) ||
199 (check_stopdate == greater_than),
200 "ERROR(yac_event_check): compareDatetime(currentdate,stopdate) failed")
201
203
204 /* Detect out of bound */
205 if (check_stopdate == greater_than) {
206
207#ifdef YAC_VERBOSE_EVENT
208 printf ("event check for event ID %d delivers OUT_OF_BOUND\n", event_id );
209#endif
211
212 } else {
213
214 compare_return_val check_startdate =
215 compareDatetime(event->currentdate,event->startdate);
217 check_startdate != less_than,
218 "ERROR(yac_event_check): compareDatetime(currentdate,startdate) failed; "
219 "current date is before start date")
221 (check_startdate == equal_to) ||
222 (check_startdate == greater_than),
223 "ERROR(yac_event_check): compareDatetime(currentdate,startdate) failed")
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 for event ID %d delivers RESTART\n", event_id );
236#endif
237 action = RESTART;
238
239 } else {
240
241#ifdef YAC_VERBOSE_EVENT
242 printf ("event check for event ID %d delivers COUPLING\n", event_id );
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
334 (time_unit == C_SECOND) ||
335 (time_unit == C_MINUTE) ||
336 (time_unit == C_HOUR) ||
338 "ERROR(yac_time_to_ISO): unsupported time unit")
339
341 getCalendarType() != CALENDAR_NOT_SET,
342 "ERROR(yac_time_to_ISO): calendar has not yet been set")
343
344 static char PT_String_buffer[MAX_TIMEDELTA_STR_LEN];
345
346 switch (time_unit) {
347
348 default:
349 case (C_MILLISECOND):
350 getPTStringFromMS(str2int64(time), PT_String_buffer);
351 break;
352 case (C_SECOND):
353 getPTStringFromSeconds(str2int64(time), PT_String_buffer);
354 break;
355 case (C_MINUTE):
356 getPTStringFromMinutes(str2int64(time), PT_String_buffer);
357 break;
358 case (C_HOUR):
359 getPTStringFromHours(str2int64(time), PT_String_buffer);
360 break;
361 case (C_ISO_FORMAT):
362 strncpy(PT_String_buffer, time, MAX_TIMEDELTA_STR_LEN-1);
363 break;
364 };
365
366 return PT_String_buffer;
367}
@ COUPLING
Definition config_yaml.c:83
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:171
void yac_event_update(struct event *event)
Definition event.c:159
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:18
#define YAC_ASSERT(exp, msg)
Definition yac_assert.h:15