Skip to content

Commit

Permalink
Spawn - support RunPeriod (#3988)
Browse files Browse the repository at this point in the history
* Implemented support for EnergyPlus RunPeriod

For #2926
  • Loading branch information
mwetter authored Sep 4, 2024
1 parent 77e582f commit eadbd6c
Show file tree
Hide file tree
Showing 35 changed files with 392 additions and 53 deletions.
17 changes: 17 additions & 0 deletions Buildings/Resources/C-Sources/EnergyPlus_9_6_0_Wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ void* allocate_Modelica_EnergyPlus_9_6_0(
const char* idfVersion,
const char* idfName,
const char* epwName,
int runPeriod_startDayOfYear,
int runPeriod_applyWeekEndHolidayRule,
int runPeriod_use_weatherFileDaylightSavingPeriod,
int runPeriod_use_weatherFileHolidaysAndSpecialDays,
int runPeriod_use_weatherFileRainIndicators,
int runPeriod_use_weatherFileSnowIndicators,
double relativeSurfaceTolerance,
const char* epName,
int usePrecompiledFMU,
Expand Down Expand Up @@ -63,6 +69,16 @@ void* allocate_Modelica_EnergyPlus_9_6_0(
const double* derivatives_delta,
const size_t nDer){


runPeriod runPer;
runPer.startDayOfYear = runPeriod_startDayOfYear;
runPer.applyWeekEndHolidayRule = runPeriod_applyWeekEndHolidayRule;
runPer.use_weatherFileDaylightSavingPeriod = runPeriod_use_weatherFileDaylightSavingPeriod;
runPer.use_weatherFileHolidaysAndSpecialDays = runPeriod_use_weatherFileHolidaysAndSpecialDays;
runPer.use_weatherFileRainIndicators = runPeriod_use_weatherFileRainIndicators;
runPer.use_weatherFileSnowIndicators = runPeriod_use_weatherFileSnowIndicators;


return allocate_Spawn_EnergyPlus_9_6_0(
objectType,
startTime,
Expand All @@ -72,6 +88,7 @@ void* allocate_Modelica_EnergyPlus_9_6_0(
idfVersion,
idfName,
epwName,
&runPer,
relativeSurfaceTolerance,
epName,
usePrecompiledFMU,
Expand Down
10 changes: 10 additions & 0 deletions Buildings/Resources/C-Sources/EnergyPlus_9_6_0_Wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@

#include "ModelicaUtilities.h"

typedef struct {
int startDayOfYear; /* Day of week from Buildings.ThermalZones.EnergyPlus_9_6_0.Types.WeekDays */
int applyWeekEndHolidayRule;
int use_weatherFileDaylightSavingPeriod;
int use_weatherFileHolidaysAndSpecialDays;
int use_weatherFileRainIndicators;
int use_weatherFileSnowIndicators;
} runPeriod;

/* ********************************************************* */
/* Thermal zone */
extern void* allocate_Spawn_EnergyPlus_9_6_0(
Expand All @@ -40,6 +49,7 @@ extern void* allocate_Spawn_EnergyPlus_9_6_0(
const char* idfVersion,
const char* idfName,
const char* epwName,
const runPeriod* runPer,
double relativeSurfaceTolerance,
const char* epName,
int usePrecompiledFMU,
Expand Down
Git LFS file not shown
Git LFS file not shown
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
last-generated=2024-08-21
statistics-simulation=
{
"linear": "0, 0",
"nonlinear": " ",
"number of continuous time states": "8",
"numerical Jacobians": "0"
}
time=[0e+00, 6.048e+05]
sunEle.y=[0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00]
monEle.y=[0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 5e+02, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00, 0e+00]
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
simulateModel("Buildings.ThermalZones.EnergyPlus_9_6_0.Validation.RunPeriod.StartDayOfYear", method="Cvode", stopTime=604800, tolerance=1e-06, resultFile="StartDayOfYear");
createPlot(id=1, position={35, 35, 857, 532}, y={"sunEle.y"}, range={0.0, 8.5, -500.0, 1000.0}, grid=true, subPlot=101, colors={{28,108,200}}, timeUnit="d", displayUnits={"W"});
createPlot(id=1, position={35, 35, 857, 532}, y={"monEle.y"}, range={0.0, 8.5, -500.0, 1000.0}, grid=true, subPlot=102, colors={{28,108,200}}, timeUnit="d", displayUnits={"W"});

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
compareVars :=
{
"sunEle.y",
"monEle.y"
};
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def print_output(typ, stream):
def run_test(pathVariable):
# List of files to be moved
fileMoves = [
{"src": os.path.abspath(os.path.join("Buildings", "Resources", "bin", "spawn-0.5.0-c10e8c6d7e", "linux64")),
{"src": os.path.abspath(os.path.join("Buildings", "Resources", "bin", "spawn-0.5.0-ab07bde9bb", "linux64")),
"des": "my-bin"},
{"src": os.path.abspath(os.path.join("Buildings", "Resources", "weatherdata")),
"des": "some_weather_directory_that_the_fmu_does_not_know_about"},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,34 @@ void closeJSONModelArrayBracket(
}
}

/* Return the day of the week to be used in the EnergyPlus RunPeriod object.
This function calls malloc on the returned value.
*/
char* getStartDayOfYear(
const int startDayOfYear,
void (*SpawnFormatError)(const char *string, ...)){


int startDay;
size_t sLen;

char * const days[] = {"Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday", "Sunday"};
char* day;

startDay = startDayOfYear - 1;
/* 1 is Monday per Modelica implementation, but C has 0 as the first index. */
sLen = strlen( days[startDay] ) + 1;

day = (char *)malloc(sizeof(char) * (sLen));

if (day == NULL){
SpawnFormatError("%s\n", "Failed to allocate memory for day of week.");
}
strcpy(day, days[startDay]);
return day;
}

void buildJSONModelStructureForEnergyPlus(
const FMUBuilding* bui, char* *buffer, size_t* size, char** modelHash){
size_t i;
Expand All @@ -99,6 +127,7 @@ void buildJSONModelStructureForEnergyPlus(
size_t iMod = 0;
int objectType;
size_t objectCount[6];
char* startDayOfYear;
const int nObjectTypes = sizeof(objectCount)/sizeof(objectCount[0]);

void (*SpawnFormatError)(const char *string, ...) = bui->SpawnFormatError;
Expand All @@ -117,7 +146,7 @@ void buildJSONModelStructureForEnergyPlus(
}

saveAppend(buffer, "{\n", size, SpawnFormatError);
buildJSONKeyStringValue(buffer, 1, "version", "0.1", true, size, SpawnFormatError);
buildJSONKeyStringValue(buffer, 1, "version", "0.2", true, size, SpawnFormatError);
saveAppend(buffer, " \"EnergyPlus\": {\n", size, SpawnFormatError);
/* idf name */
buildJSONKeyStringValue(buffer, 2, "idf", bui->idfName, true, size, SpawnFormatError);
Expand All @@ -131,6 +160,23 @@ void buildJSONModelStructureForEnergyPlus(

saveAppend(buffer, " },\n", size, SpawnFormatError);

/* RunPeriod */
saveAppend(buffer, " \"RunPeriod\": {\n", size, SpawnFormatError);

startDayOfYear = getStartDayOfYear(bui->runPer->startDayOfYear, SpawnFormatError);
buildJSONKeyStringValue(buffer, 2, "start_day_of_year",
startDayOfYear,
true, size, SpawnFormatError);
free(startDayOfYear);

buildJSONKeyStringValue(buffer, 2, "apply_weekend_holiday_rule", bui->runPer->applyWeekEndHolidayRule ? "Yes": "No", true, size, SpawnFormatError);
buildJSONKeyStringValue(buffer, 2, "use_weather_file_daylight_saving_period", bui->runPer->use_weatherFileDaylightSavingPeriod ? "Yes": "No", true, size, SpawnFormatError);
buildJSONKeyStringValue(buffer, 2, "use_weather_file_holidays_and_special_days", bui->runPer->use_weatherFileHolidaysAndSpecialDays ? "Yes": "No", true, size, SpawnFormatError);
buildJSONKeyStringValue(buffer, 2, "use_weather_file_rain_indicators", bui->runPer->use_weatherFileRainIndicators ? "Yes": "No", true, size, SpawnFormatError);
buildJSONKeyStringValue(buffer, 2, "use_weather_file_snow_indicators", bui->runPer->use_weatherFileSnowIndicators ? "Yes": "No", false, size, SpawnFormatError);

saveAppend(buffer, " },\n", size, SpawnFormatError);

/* model information */
saveAppend(buffer, " \"model\": {\n", size, SpawnFormatError);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ size_t AllocateBuildingDataStructure(
const char* idfVersion,
const char* idfName,
const char* epwName,
const runPeriod* runPer,
double relativeSurfaceTolerance,
int usePrecompiledFMU,
const char* fmuName,
Expand Down Expand Up @@ -139,6 +140,12 @@ size_t AllocateBuildingDataStructure(
SpawnFormatError);
strcpy(Buildings_FMUS[nFMU]->weather, epwName);

/* Assign the RunPeriod object */
Buildings_FMUS[nFMU]->runPer = malloc(sizeof(runPeriod));
if ( Buildings_FMUS[nFMU]->runPer == NULL )
SpawnError("Not enough memory in SpawnFMU.c. to allocate array for Buildings_FMU[nFMU]->runPer.");
memcpy(Buildings_FMUS[nFMU]->runPer, runPer, sizeof(runPeriod));

/* Set relative surface tolerance */
Buildings_FMUS[nFMU]->relativeSurfaceTolerance = relativeSurfaceTolerance;
/* Set the model hash to null */
Expand Down Expand Up @@ -321,6 +328,8 @@ void FMUBuildingFree(FMUBuilding* bui){
free(bui->idfName);
if (bui->weather != NULL)
free(bui->weather);
if (bui->runPer != NULL)
free(bui->runPer);
if (bui->exchange != NULL)
free(bui->exchange);
if (bui->tmpDir != NULL)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ size_t AllocateBuildingDataStructure(
const char* epwName,
const char* spawnExe,
const char* idfVersion,
const runPeriod* runPer,
double relativeSurfaceTolerance,
int usePrecompiledFMU,
const char* fmuName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ void* allocate_Spawn_EnergyPlus_9_6_0(
const char* idfVersion,
const char* idfName,
const char* epwName,
const runPeriod* runPer,
double relativeSurfaceTolerance,
const char* epName,
int usePrecompiledFMU,
Expand Down Expand Up @@ -325,6 +326,7 @@ void* allocate_Spawn_EnergyPlus_9_6_0(
idfVersion,
idfName,
epwName,
runPer,
relativeSurfaceTolerance,
usePrecompiledFMU,
fmuName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ LBNL_Spawn_EXPORT void* allocate_Spawn_EnergyPlus_9_6_0(
const char* idfVersion,
const char* idfName,
const char* epwName,
const runPeriod* runPer,
double relativeSurfaceTolerance,
const char* epName,
int usePrecompiledFMU,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ typedef enum {instantiationMode, initializationMode, eventMode, continuousTimeMo
enum logLevels {ERRORS = 1, WARNINGS = 2, QUIET = 3, MEDIUM = 4, TIMESTEP = 5};
enum objectTypes {THERMALZONE = 1, SCHEDULE = 2, ACTUATOR = 3, OUTPUT = 4, SURFACE = 5, DETAILEDSURFACE = 6};

typedef struct {
int startDayOfYear; /* Day of week from Buildings.ThermalZones.EnergyPlus_9_6_0.Types.WeekDays */
int applyWeekEndHolidayRule;
int use_weatherFileDaylightSavingPeriod;
int use_weatherFileHolidaysAndSpecialDays;
int use_weatherFileRainIndicators;
int use_weatherFileSnowIndicators;
} runPeriod;

typedef struct FMUBuilding
{
Expand All @@ -78,6 +86,7 @@ typedef struct FMUBuilding
char* idfVersion; /* IDF version with underscores, such as 9_6_0. This must be the same as is used as suffix for Buildings.ThermalZones.EnergyPlus_ */
fmi2Byte* idfName; /* if usePrecompiledFMU == true, the user-specified fmu name, else the idf name */
fmi2Byte* weather;
runPeriod* runPer; /* EnergyPlus RunPeriod */
double relativeSurfaceTolerance; /* Relative surface tolerance for heat balance calculations */
size_t nExcObj; /* Number of exc that use this FMU */
void** exchange; /* Pointers to all exchange objects*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
# build_type is either custom or builds
spawn_dists = [
{"version": "0.5.0",
"commit": "c10e8c6d7e",
"commit": "ab07bde9bb",
"build_type": "custom"}
]
###########################################################################
Expand Down
1 change: 1 addition & 0 deletions Buildings/ThermalZones/EnergyPlus_9_6_0/Actuator.mo
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ protected
idfVersion=idfVersion,
idfName=idfName,
epwName=epwName,
runPeriod=runPeriod,
relativeSurfaceTolerance=relativeSurfaceTolerance,
epName=variableName,
usePrecompiledFMU=usePrecompiledFMU,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ protected
"Name of the EnergyPlus weather file (but with mos extension)";
final parameter Real relativeSurfaceTolerance=building.relativeSurfaceTolerance
"Relative tolerance of surface temperature calculations";

final parameter Buildings.ThermalZones.EnergyPlus_9_6_0.Data.RunPeriod runPeriod=building.runPeriod
"EnergyPlus RunPeriod configuration"
annotation (Dialog(tab="Run period"));

final parameter Boolean usePrecompiledFMU=building.usePrecompiledFMU
"Set to true to use pre-compiled FMU with name specified by fmuName"
annotation (Dialog(tab="Debug"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class SpawnExternalObject
"Name of the IDF";
input String epwName
"Name of the weather file";
input Buildings.ThermalZones.EnergyPlus_9_6_0.Data.RunPeriod runPeriod
"EnergyPlus RunPeriod configuration";
input Real relativeSurfaceTolerance
"Relative tolerance of surface temperature calculations";
input String epName
Expand Down Expand Up @@ -72,6 +74,12 @@ class SpawnExternalObject
idfVersion,
idfName,
epwName,
runPeriod.startDayOfYear,
runPeriod.applyWeekEndHolidayRule,
runPeriod.use_weatherFileDaylightSavingPeriod,
runPeriod.use_weatherFileHolidaysAndSpecialDays,
runPeriod.use_weatherFileRainIndicators,
runPeriod.use_weatherFileSnowIndicators,
relativeSurfaceTolerance,
epName,
usePrecompiledFMU,
Expand Down Expand Up @@ -105,30 +113,35 @@ class SpawnExternalObject
annotation (
Documentation(
info="<html>
<p>
The function <code>constructor</code> is a C function that is called by a Modelica simulator
exactly once during the initialization.
The function returns the object <code>adapter</code> that
will be used to store the data structure needed to communicate with EnergyPlus.
</p>
</html>",
<p>
The function <code>constructor</code> is a C function that is called by a Modelica simulator
exactly once during the initialization.
The function returns the object <code>adapter</code> that
will be used to store the data structure needed to communicate with EnergyPlus.
</p>
</html>",
revisions="<html>
<ul>
<li>
December 11, 2021, by Michael Wetter:<br/>
Declared function as <code>impure</code> for MSL 4.0.0.
</li>
<li>
February 18, 2021, by Michael Wetter:<br/>
Refactor synchronization of constructors.<br/>
This is for <a href=\"https://github.com/lbl-srg/modelica-buildings/issues/2360\">#2360</a>.
</li>
<li>
February 14, 2018, by Michael Wetter:<br/>
First implementation.
</li>
</ul>
</html>"));
<ul>
<li>
April 21, 2022, by Michael Wetter:<br/>
Added support for EnergyPlus <code>RunPeriod</code> object.<br/>
This is for <a href=\"https://github.com/lbl-srg/modelica-buildings/issues/2926\">#2926</a>.
</li>
<li>
December 11, 2021, by Michael Wetter:<br/>
Declared function as <code>impure</code> for MSL 4.0.0.
</li>
<li>
February 18, 2021, by Michael Wetter:<br/>
Refactor synchronization of constructors.<br/>
This is for <a href=\"https://github.com/lbl-srg/modelica-buildings/issues/2360\">#2360</a>.
</li>
<li>
February 14, 2018, by Michael Wetter:<br/>
First implementation.
</li>
</ul>
</html>"));
end constructor;

pure function destructor
Expand Down Expand Up @@ -198,4 +211,4 @@ First implementation.
</li>
</ul>
</html>"));
end SpawnExternalObject;
end SpawnExternalObject;
Loading

0 comments on commit eadbd6c

Please sign in to comment.