Skip to content

Commit

Permalink
Merge pull request #1900 from ibpsa/1891_headers
Browse files Browse the repository at this point in the history
separate files for weekly schedule includes for #1891
  • Loading branch information
mwetter authored Jun 19, 2024
2 parents 16a4d40 + f24c66a commit b794181
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 71 deletions.
72 changes: 3 additions & 69 deletions IBPSA/Resources/C-Sources/WeeklySchedule.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
This code implements a weekly schedule.
Changelog:
June 15, 2024 by Filip Jorissen, Builtwins
Revisions for #1891: compliance with Modelica include annotation rules.
April 9, 2024 by Filip Jorissen, Builtwins
Revisions for #1869 to remove a header requirement that contains the number of rows/columns.
March 30, 2024 by Filip Jorissen, Builtwins
Expand Down Expand Up @@ -416,6 +418,7 @@ void* weeklyScheduleInit(const int tableOnFile, const char* name, const double t
return (void*) scheduleID;
}


void weeklyScheduleFreeInit(void * ID) {
WeeklySchedule* scheduleID = (WeeklySchedule*)ID;

Expand All @@ -433,73 +436,4 @@ void weeklyScheduleFreeInit(void * ID) {

}


void weeklyScheduleFree(void * ID) {
int i;
WeeklySchedule* scheduleID = (WeeklySchedule*)ID;

if (ID == NULL) /* Otherwise OM segfaults when IBPSA.Utilities.IO.Files.Examples.WeeklySchedule triggers an error */
return;

for (i = 0; i < scheduleID->n_allocatedRulesData; ++i) {
free(scheduleID->rules[i]->data);
}

for (i = 0; i < scheduleID->n_allocatedRules; ++i) {
free(scheduleID->rules[i]);
}

if (scheduleID->rules != NULL)
free(scheduleID->rules);

free(ID);
ID = NULL;
}

/* Get a column value. Cache the last used row internally to speed up lookup. */
double getScheduleValue(void * ID, const int column, const double modelicaTime) {
WeeklySchedule* scheduleID = (WeeklySchedule*)ID;
/* extrapolation for weeks that are outside of the user-defined range */
double t = modelicaTime - scheduleID->t_offset;
const double weekLen = 7 * 24 * 3600;
double time = fmod(t - weekLen * floor(t / weekLen), weekLen);
int i;
const int columnIndex = column - 1; /* Since we do not store the time indices in the data table */

/* Not calling weeklyScheduleFreeInit() or weeklyScheduleFree() since weeklyScheduleFreeInit() has already been called at the end of the
initialization and Modelica will call weeklyScheduleFree() upon a call of ModelicaFormatError) */
if (column < 0 || column > scheduleID->n_data_cols) {
ModelicaFormatError("The requested column index '%i' is outside of the table range '%i'.", column + 1, scheduleID->n_data_cols);
}
if (column == 0 ) {
ModelicaFormatError("The column index 1 is not a data column and is reserved for 'time'. It should not be read.");
}


if (time == scheduleID->previousTimestamp) {
i = scheduleID->previousIndex;
} else if (time > scheduleID->rules[scheduleID->previousIndex]->time) {
for (i = scheduleID->previousIndex; i < scheduleID->n_allocatedRules - 1; i ++) {
if (scheduleID->rules[i + 1]->time > time) {
break;
}
}
} else {
for (i = scheduleID->previousIndex; i > 0; i--) {
if (scheduleID->rules[i - 1]->time < time) {
i = i - 1;
break;
}
}
/* if time is smaller than the first row, wrap back to the end of the week */
if (i == 0 && scheduleID->rules[0]->time > time) {
i = scheduleID->n_allocatedRules - 1;
}
}
scheduleID->previousIndex = i;
scheduleID->previousTimestamp = time;

return scheduleID->rules[i]->data[columnIndex];
}

#endif
44 changes: 44 additions & 0 deletions IBPSA/Resources/C-Sources/WeeklyScheduleFree.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
This code implements a weekly schedule.
Changelog:
June 15, 2024 by Filip Jorissen, Builtwins
Initial version for #1891: compliance with Modelica include annotation rules.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "WeeklySchedule.h"
#include "ModelicaUtilities.h"

#ifndef WEEKCALFREE_c
#define WEEKCALFREE_c


void weeklyScheduleFree(void * ID) {
int i;
WeeklySchedule* scheduleID = (WeeklySchedule*)ID;

if (ID == NULL) /* Otherwise OM segfaults when IBPSA.Utilities.IO.Files.Examples.WeeklySchedule triggers an error */
return;

for (i = 0; i < scheduleID->n_allocatedRulesData; ++i) {
free(scheduleID->rules[i]->data);
}

for (i = 0; i < scheduleID->n_allocatedRules; ++i) {
free(scheduleID->rules[i]);
}

if (scheduleID->rules != NULL)
free(scheduleID->rules);

free(ID);
ID = NULL;
}

#endif
69 changes: 69 additions & 0 deletions IBPSA/Resources/C-Sources/WeeklyScheduleGetValue.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
This code implements a weekly schedule.
Changelog:
June 15, 2024 by Filip Jorissen, Builtwins
Initial version for #1891: compliance with Modelica include annotation rules.
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "WeeklySchedule.h"
#include "ModelicaUtilities.h"

#ifndef WEEKCALGET_c
#define WEEKCALGET_c


/* Get a column value. Cache the last used row internally to speed up lookup. */
double getScheduleValue(void * ID, const int column, const double modelicaTime) {
WeeklySchedule* scheduleID = (WeeklySchedule*)ID;
/* extrapolation for weeks that are outside of the user-defined range */
double t = modelicaTime - scheduleID->t_offset;
const double weekLen = 7 * 24 * 3600;
double time = fmod(t - weekLen * floor(t / weekLen), weekLen);
int i;
const int columnIndex = column - 1; /* Since we do not store the time indices in the data table */

/* Not calling weeklyScheduleFreeInit() or weeklyScheduleFree() since weeklyScheduleFreeInit() has already been called at the end of the
initialization and Modelica will call weeklyScheduleFree() upon a call of ModelicaFormatError) */
if (column < 0 || column > scheduleID->n_data_cols) {
ModelicaFormatError("The requested column index '%i' is outside of the table range '%i'.", column + 1, scheduleID->n_data_cols);
}
if (column == 0 ) {
ModelicaFormatError("The column index 1 is not a data column and is reserved for 'time'. It should not be read.");
}


if (time == scheduleID->previousTimestamp) {
i = scheduleID->previousIndex;
} else if (time > scheduleID->rules[scheduleID->previousIndex]->time) {
for (i = scheduleID->previousIndex; i < scheduleID->n_allocatedRules - 1; i ++) {
if (scheduleID->rules[i + 1]->time > time) {
break;
}
}
} else {
for (i = scheduleID->previousIndex; i > 0; i--) {
if (scheduleID->rules[i - 1]->time < time) {
i = i - 1;
break;
}
}
/* if time is smaller than the first row, wrap back to the end of the week */
if (i == 0 && scheduleID->rules[0]->time > time) {
i = scheduleID->n_allocatedRules - 1;
}
}
scheduleID->previousIndex = i;
scheduleID->previousTimestamp = time;

return scheduleID->rules[i]->data[columnIndex];
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Object for storing weekly schedules.
pure function destructor "Release storage and close the external object, write data if needed"
input WeeklyScheduleObject weeklySchedule "Pointer to file writer object";
external "C" weeklyScheduleFree(weeklySchedule)
annotation(Include=" #include <WeeklySchedule.c>",
annotation(Include=" #include <WeeklyScheduleFree.c>",
IncludeDirectory="modelica://IBPSA/Resources/C-Sources");
annotation(Documentation(info="<html>
<p>
Expand Down
2 changes: 1 addition & 1 deletion IBPSA/Utilities/IO/Files/WeeklySchedule.mo
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ protected
input Real timeIn "Time for look-up";
output Real y "Schedule value";
external "C" y=getScheduleValue(ID, iCol, timeIn)
annotation(Include="#include <WeeklySchedule.c>",
annotation(Include="#include <WeeklyScheduleGetValue.c>",
IncludeDirectory="modelica://IBPSA/Resources/C-Sources");
end getCalendarValue;

Expand Down

0 comments on commit b794181

Please sign in to comment.