Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ScheduleDay: new timeseries method and interpolation options #5111

Merged
merged 73 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
76f4f41
Introduce new getValues method on ScheduleDay.
joseph-robertson Mar 13, 2024
48ac02d
Stub model test for new method.
joseph-robertson Mar 13, 2024
0242a8c
Formatting.
joseph-robertson Mar 13, 2024
389f6cb
Typo.
joseph-robertson Mar 13, 2024
6e075a3
Update scheduleday files and get new tests passing.
joseph-robertson Mar 14, 2024
27865fa
Return timeseries instead of separate getTimes and getValues.
joseph-robertson Mar 18, 2024
80ef75b
Clean up and try again.
joseph-robertson Mar 18, 2024
f01fba7
Update idd for new interpolation method keys.
joseph-robertson Mar 19, 2024
a365a99
Update model files and tests.
joseph-robertson Mar 19, 2024
d96338a
Update ft and rt files and tests.
joseph-robertson Mar 19, 2024
9fa369a
Get interpolation working on timeseries.
joseph-robertson Mar 19, 2024
3282bda
Stub new AverageInterp in vector files.
joseph-robertson Mar 19, 2024
47d03f3
Take a cut at the average interpolation.
joseph-robertson Mar 21, 2024
aed3dea
One more typo.
joseph-robertson Mar 21, 2024
7bee45b
Move average interp code into AverageInterp.
joseph-robertson Mar 22, 2024
8f1aed5
Formatting.
joseph-robertson Mar 22, 2024
81cfbd0
Cache timeseries results and clear when object changes.
joseph-robertson Mar 25, 2024
07992ed
Add AverageInterp no-op case to matrix cpp.
joseph-robertson Mar 25, 2024
b178a6b
Update docs for new timeseries method.
joseph-robertson Mar 25, 2024
f9a2eae
Set left endpoint of getvalue.
joseph-robertson Mar 25, 2024
d1d7708
Update left endpoint per method and update tests.
joseph-robertson Mar 26, 2024
6c7198e
Merge branch 'develop' into dayschedule-getvalues
joseph-robertson Mar 27, 2024
160585a
Interpolate using seconds instead of days.
joseph-robertson Mar 27, 2024
686b725
Need ti in seconds and not days.
joseph-robertson Mar 27, 2024
e742966
Try updating timestep with cache clear.
joseph-robertson Mar 27, 2024
2ded730
New protected method for clearing ts, and friend timestep.
joseph-robertson Mar 27, 2024
bfb876f
Updates for vt and deprecating interp setter.
joseph-robertson Mar 27, 2024
dd39ffd
Building but tests failing.
joseph-robertson Mar 28, 2024
4af6ee3
Fix the new vt.
joseph-robertson Mar 28, 2024
9be8c90
Remove deprecation of old setter.
joseph-robertson Mar 28, 2024
bb57a4d
Add one more test showing change in getValue for small enough timestep.
joseph-robertson Mar 28, 2024
9b82fed
Merge branch 'develop' into dayschedule-getvalues
joseph-robertson Apr 15, 2024
f8fcada
Merge branch 'develop' into dayschedule-getvalues
jmarrec Apr 18, 2024
6c33a6b
Update comments and release notes.
joseph-robertson Apr 18, 2024
e8b0015
Update ti default to -9999, add assert, update comments.
joseph-robertson Apr 18, 2024
c74f8b6
Few more updates to release notes.
joseph-robertson Apr 18, 2024
d2c195d
Introduce new getValues method on ScheduleDay.
joseph-robertson Mar 13, 2024
5037966
Stub model test for new method.
joseph-robertson Mar 13, 2024
96e9514
Formatting.
joseph-robertson Mar 13, 2024
d55dc20
Typo.
joseph-robertson Mar 13, 2024
a58faef
Update scheduleday files and get new tests passing.
joseph-robertson Mar 14, 2024
94685d5
Return timeseries instead of separate getTimes and getValues.
joseph-robertson Mar 18, 2024
1549488
Clean up and try again.
joseph-robertson Mar 18, 2024
a75a333
Update idd for new interpolation method keys.
joseph-robertson Mar 19, 2024
838df44
Update model files and tests.
joseph-robertson Mar 19, 2024
2b919ab
Update ft and rt files and tests.
joseph-robertson Mar 19, 2024
8eede82
Get interpolation working on timeseries.
joseph-robertson Mar 19, 2024
8da8085
Stub new AverageInterp in vector files.
joseph-robertson Mar 19, 2024
85da8ef
Take a cut at the average interpolation.
joseph-robertson Mar 21, 2024
065d022
One more typo.
joseph-robertson Mar 21, 2024
1104600
Move average interp code into AverageInterp.
joseph-robertson Mar 22, 2024
4af64a0
Formatting.
joseph-robertson Mar 22, 2024
dc202f1
Cache timeseries results and clear when object changes.
joseph-robertson Mar 25, 2024
30fd11d
Add AverageInterp no-op case to matrix cpp.
joseph-robertson Mar 25, 2024
8d50877
Update docs for new timeseries method.
joseph-robertson Mar 25, 2024
825b270
Set left endpoint of getvalue.
joseph-robertson Mar 25, 2024
bbd26f8
Update left endpoint per method and update tests.
joseph-robertson Mar 26, 2024
e257209
Interpolate using seconds instead of days.
joseph-robertson Mar 27, 2024
a22dbb2
Need ti in seconds and not days.
joseph-robertson Mar 27, 2024
1389577
Try updating timestep with cache clear.
joseph-robertson Mar 27, 2024
805f14c
New protected method for clearing ts, and friend timestep.
joseph-robertson Mar 27, 2024
740a0b2
Updates for vt and deprecating interp setter.
joseph-robertson Mar 27, 2024
f20d840
Building but tests failing.
joseph-robertson Mar 28, 2024
881d27c
Fix the new vt.
joseph-robertson Mar 28, 2024
1794d58
Remove deprecation of old setter.
joseph-robertson Mar 28, 2024
e4cef89
Add one more test showing change in getValue for small enough timestep.
joseph-robertson Mar 28, 2024
138cbad
Update comments and release notes.
joseph-robertson Apr 18, 2024
4572fc0
Update ti default to -9999, add assert, update comments.
joseph-robertson Apr 18, 2024
ceba909
Few more updates to release notes.
joseph-robertson Apr 18, 2024
012f076
Missing include
jmarrec Apr 25, 2024
90e86c6
Merge branch 'dayschedule-getvalues' of github.com:NREL/OpenStudio in…
joseph-robertson Apr 25, 2024
fddbc7d
Update assert and get optional timestep object.
joseph-robertson Apr 25, 2024
7493115
Merge branch 'develop' into dayschedule-getvalues
joseph-robertson Apr 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 63 additions & 7 deletions src/model/ScheduleDay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,20 @@ namespace model {
return m_cachedValues.get();
}

double ScheduleDay_Impl::getValue(const openstudio::Time& time) const {
double ScheduleDay_Impl::getValue(const openstudio::Time& time, int numberOfTimestepsPerHour) const {
if (time.totalMinutes() < 0.0 || time.totalDays() > 1.0) {
return 0.0;
}

std::vector<double> values = this->values(); // these are already sorted
std::vector<openstudio::Time> times = this->times(); // these are already sorted
std::vector<double> values;
std::vector<openstudio::Time> times;
if (numberOfTimestepsPerHour > 0) {
values = this->getValues(numberOfTimestepsPerHour);
times = this->getTimes(numberOfTimestepsPerHour);
} else {
values = this->values(); // these are already sorted
times = this->times(); // these are already sorted
}

unsigned N = times.size();
OS_ASSERT(values.size() == N);
Expand All @@ -201,7 +208,7 @@ namespace model {
y[N + 1] = 0.0;

InterpMethod interpMethod;
if (this->interpolatetoTimestep()) {
if (numberOfTimestepsPerHour > 0) {
interpMethod = LinearInterp;
} else {
interpMethod = HoldNextInterp;
Expand All @@ -212,6 +219,48 @@ namespace model {
return result;
}

std::vector<openstudio::Time> ScheduleDay_Impl::getTimes(int numberOfTimestepsPerHour) const {
std::vector<openstudio::Time> result;

std::vector<int> allowables{1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60};
if (std::find(allowables.begin(), allowables.end(), numberOfTimestepsPerHour) == allowables.end()) {
return result;
}

int minutes = 60 / numberOfTimestepsPerHour;
for (size_t hour = 0; hour < 24; ++hour) {
for (size_t minute = minutes; minute <= 60; minute += minutes) {
if (minute == 60) {
openstudio::Time t(0, hour + 1, 0);
result.push_back(t);
} else {
openstudio::Time t(0, hour, minute);
result.push_back(t);
}
}
}
return result;
}

std::vector<double> ScheduleDay_Impl::getValues(int numberOfTimestepsPerHour) const {
std::vector<double> values = this->values(); // these are already sorted
std::vector<openstudio::Time> times = this->times(); // these are already sorted
std::vector<openstudio::Time> getTimes = this->getTimes(numberOfTimestepsPerHour); // these are already sorted
std::vector<double> result;

for (const openstudio::Time& t : getTimes) {
size_t i = 0;
for (const openstudio::Time& time : times) {
if (t <= time) {
result.push_back(values[i]);
break;
}
++i;
}
}
return result;
}

bool ScheduleDay_Impl::setScheduleTypeLimits(const ScheduleTypeLimits& scheduleTypeLimits) {
if (scheduleTypeLimits.model() != model()) {
return false;
Expand All @@ -231,7 +280,6 @@ namespace model {

bool ScheduleDay_Impl::setInterpolatetoTimestep(bool interpolatetoTimestep) {
return setBooleanFieldValue(OS_Schedule_DayFields::InterpolatetoTimestep, interpolatetoTimestep);
;
}

void ScheduleDay_Impl::resetInterpolatetoTimestep() {
Expand Down Expand Up @@ -410,8 +458,16 @@ namespace model {
return getImpl<detail::ScheduleDay_Impl>()->values();
}

double ScheduleDay::getValue(const openstudio::Time& time) const {
return getImpl<detail::ScheduleDay_Impl>()->getValue(time);
double ScheduleDay::getValue(const openstudio::Time& time, int numberOfTimestepsPerHour) const {
return getImpl<detail::ScheduleDay_Impl>()->getValue(time, numberOfTimestepsPerHour);
}

std::vector<openstudio::Time> ScheduleDay::getTimes(int numberOfTimestepsPerHour) const {
return getImpl<detail::ScheduleDay_Impl>()->getTimes(numberOfTimestepsPerHour);
}

std::vector<double> ScheduleDay::getValues(int numberOfTimestepsPerHour) const {
return getImpl<detail::ScheduleDay_Impl>()->getValues(numberOfTimestepsPerHour);
}

bool ScheduleDay::setInterpolatetoTimestep(bool interpolatetoTimestep) {
Expand Down
15 changes: 13 additions & 2 deletions src/model/ScheduleDay.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,19 @@ namespace model {
/// Returns a vector of values in the same order and with the same number of elements as times.
std::vector<double> values() const;

/// Returns the value in effect at the given time. If time is less than 0 days or greater than 1 day, 0 is returned.
double getValue(const openstudio::Time& time) const;
/// Returns the value in effect at the given time.
/// If time is less than 0 days or greater than 1 day, 0 is returned.
double getValue(const openstudio::Time& time, int numberOfTimestepsPerHour = 0) const;
joseph-robertson marked this conversation as resolved.
Show resolved Hide resolved

/// Returns the vector of times marking the end value intervals for a given timesteps per hour.
/// Allowable values include 1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, and 60.
/// These times will be in order and have the same number of elements as getValues.
/// All times will be less than or equal to 1 day.
std::vector<openstudio::Time> getTimes(int numberOfTimestepsPerHour) const;

/// Returns the values for a given timesteps per hour.
/// Allowable values include 1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, and 60.
std::vector<double> getValues(int numberOfTimestepsPerHour) const;

//@}
/** @name Setters */
Expand Down
15 changes: 13 additions & 2 deletions src/model/ScheduleDay_Impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,19 @@ namespace model {
/// Returns a vector of values in the same order and with the same number of elements as times.
virtual std::vector<double> values() const override;

/// Returns the value in effect at the given time. If time is less than 0 days or greater than 1 day, 0 is returned.
double getValue(const openstudio::Time& time) const;
/// Returns the value in effect at the given time.
/// If time is less than 0 days or greater than 1 day, 0 is returned.
double getValue(const openstudio::Time& time, int numberOfTimestepsPerHour) const;

/// Returns the vector of times marking the end value intervals for a given timesteps per hour.
/// Allowable values include 1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, and 60.
/// These times will be in order and have the same number of elements as getValues.
/// All times will be less than or equal to 1 day.
std::vector<openstudio::Time> getTimes(int numberOfTimestepsPerHour) const;

/// Returns the values for a given timesteps per hour.
/// Allowable values include 1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, and 60.
std::vector<double> getValues(int numberOfTimestepsPerHour) const;

//@}
/** @name Setters */
Expand Down
99 changes: 96 additions & 3 deletions src/model/test/ScheduleDay_GTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,10 @@ TEST_F(ModelFixture, Schedule_Day_Interp) {
EXPECT_FALSE(daySchedule.isInterpolatetoTimestepDefaulted());

EXPECT_NEAR(0.0, daySchedule.getValue(Time(0, -1, 0)), tol);
EXPECT_NEAR(0.0, daySchedule.getValue(Time(0, 0, 0)), tol);
EXPECT_NEAR(0.5, daySchedule.getValue(Time(0, 6, 0)), tol);
EXPECT_NEAR(0.0, daySchedule.getValue(Time(0, 0, 0)), tol); // FIXME: Fails. Should be 1.0?
EXPECT_NEAR(0.5, daySchedule.getValue(Time(0, 6, 0)), tol); // FIXME: Fails. Should be 1.0?
EXPECT_NEAR(1.0, daySchedule.getValue(Time(0, 12, 0)), tol);
EXPECT_NEAR(0.5, daySchedule.getValue(Time(0, 18, 0)), tol);
EXPECT_NEAR(0.5, daySchedule.getValue(Time(0, 18, 0)), tol); // FIXME: Fails. Should be 0.0?
EXPECT_NEAR(0.0, daySchedule.getValue(Time(0, 24, 0)), tol);
EXPECT_NEAR(0.0, daySchedule.getValue(Time(0, 25, 0)), tol);
}
Expand Down Expand Up @@ -320,3 +320,96 @@ TEST_F(ModelFixture, Schedule_Day_addValue_NaN_Infinity) {
EXPECT_FALSE(sch_day.addValue(t, std::numeric_limits<double>::infinity()));
EXPECT_FALSE(sch_day.addValue(t, -std::numeric_limits<double>::infinity()));
}

TEST_F(ModelFixture, Schedule_Day_getValues) {
Model model;

double tol = 1e-5;

ScheduleDay sch_day(model);

Time t1("08:15:00");
sch_day.addValue(t1, 0);
Time t2("21:45:00");
sch_day.addValue(t2, 1);

std::vector<openstudio::Time> times = sch_day.getTimes(7);
EXPECT_EQ(0, times.size());

std::vector<openstudio::Time> times24 = sch_day.getTimes(1);
EXPECT_EQ(24 * 1, times24.size());

std::vector<openstudio::Time> times15 = sch_day.getTimes(4);
EXPECT_EQ(24 * 4, times15.size());

std::vector<openstudio::Time> times10 = sch_day.getTimes(6);
EXPECT_EQ(24 * 6, times10.size());
Time times10_1("00:10:00");
EXPECT_EQ(times10_1, times10[0]);
Time times10_48("08:00:00");
EXPECT_EQ(times10_48, times10[47]);
Time times10_49("08:10:00");
EXPECT_EQ(times10_49, times10[48]);
Time times10_50("08:20:00");
EXPECT_EQ(times10_50, times10[49]);
Time times10_144("24:00:00");
EXPECT_EQ(times10_144, times10[143]);

std::vector<double> values = sch_day.getValues(18);
EXPECT_EQ(0, values.size());

std::vector<double> values24 = sch_day.getValues(1);
EXPECT_EQ(24 * 1, values24.size());

std::vector<double> values15 = sch_day.getValues(4);
EXPECT_EQ(24 * 4, values15.size());

std::vector<double> values10 = sch_day.getValues(6);
EXPECT_EQ(24 * 6, values10.size());
EXPECT_DOUBLE_EQ(0.0, values10[0]);
EXPECT_DOUBLE_EQ(0.0, values10[47]);
EXPECT_DOUBLE_EQ(0.0, values10[48]);
EXPECT_DOUBLE_EQ(1.0, values10[49]);
EXPECT_DOUBLE_EQ(0.0, values10[143]);

double value;

Time t3("08:10:00");
EXPECT_NEAR((8.0 + (10.0 / 60.0)) / 24.0, t3.totalDays(), tol);
value = sch_day.getValue(t3);
EXPECT_DOUBLE_EQ(0.0, value);
value = sch_day.getValue(t3, 1);
EXPECT_NEAR(10.0 / 60.0, value, tol); // 10 min in a 60 min interval
value = sch_day.getValue(t3, 4);
EXPECT_DOUBLE_EQ(0.0, value);
value = sch_day.getValue(t3, 6);
EXPECT_DOUBLE_EQ(0.0, value);
value = sch_day.getValue(t3, 10);
EXPECT_DOUBLE_EQ(0.0, value);

Time t4("08:18:00");
EXPECT_NEAR((8.0 + (18.0 / 60.0)) / 24.0, t4.totalDays(), tol);
value = sch_day.getValue(t4);
EXPECT_DOUBLE_EQ(1.0, value);
value = sch_day.getValue(t4, 1);
EXPECT_NEAR(18.0 / 60.0, value, tol); // 18 min in a 60 min interval
value = sch_day.getValue(t4, 4);
EXPECT_NEAR(3.0 / 15.0, value, tol); // 3 min in a 15 min interval
value = sch_day.getValue(t4, 6);
EXPECT_NEAR(8.0 / 10.0, value, tol); // 8 min in a 10 min interval
value = sch_day.getValue(t4, 10);
EXPECT_DOUBLE_EQ(1.0, value);

Time t5("09:00:00");
EXPECT_NEAR(9.0 / 24.0, t5.totalDays(), tol);
value = sch_day.getValue(t5);
EXPECT_DOUBLE_EQ(1.0, value);
value = sch_day.getValue(t5, 1);
EXPECT_DOUBLE_EQ(1.0, value);
value = sch_day.getValue(t5, 4);
EXPECT_DOUBLE_EQ(1.0, value);
value = sch_day.getValue(t5, 6);
EXPECT_DOUBLE_EQ(1.0, value);
value = sch_day.getValue(t5, 10);
EXPECT_DOUBLE_EQ(1.0, value);
}
Loading