Skip to content

Commit

Permalink
Merge pull request #1052 from ie3-institute/df/#1051-Refactor-thermal…
Browse files Browse the repository at this point in the history
…-calcRelevantData

Refactor thermal calcRelevantData
  • Loading branch information
sebastian-peter authored Nov 26, 2024
2 parents 3b5a72f + f3ca7a0 commit e420a54
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 134 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Removing logs in `logs/simona` [#1017](https://github.com/ie3-institute/simona/issues/1017)
- Fix implausible test cases of HpModelSpec [#1042](https://github.com/ie3-institute/simona/issues/1042)
- Refactoring to only use 'lastHpState' and 'relevantData' for 'ThermalGrid' calculations [#916](https://github.com/ie3-institute/simona/issues/916)
- Refactor thermal calcRelevantData [#1051](https://github.com/ie3-institute/simona/issues/1051)

### Fixed
- Fix rendering of references in documentation [#505](https://github.com/ie3-institute/simona/issues/505)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,10 +234,9 @@ final case class HpModel(
/* Push thermal energy to the thermal grid and get its updated state in return */
val (thermalGridState, maybeThreshold) =
thermalGrid.updateState(
relevantData.currentTick,
relevantData,
lastState.thermalGridState,
lastState.ambientTemperature.getOrElse(relevantData.ambientTemperature),
relevantData.ambientTemperature,
newThermalPower,
)

Expand Down
80 changes: 34 additions & 46 deletions src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,11 @@ final case class ThermalGrid(
case Some((thermalHouse, lastHouseState)) =>
val (updatedHouseState, _) =
thermalHouse.determineState(
relevantData.currentTick,
relevantData,
lastHouseState,
lastHpState.ambientTemperature.getOrElse(
relevantData.ambientTemperature
),
relevantData.ambientTemperature,
lastHouseState.qDot,
)
if (
Expand All @@ -80,8 +79,7 @@ final case class ThermalGrid(
) {
(
thermalHouse.energyDemand(
relevantData.currentTick,
relevantData.ambientTemperature,
relevantData,
updatedHouseState,
),
Some(updatedHouseState),
Expand Down Expand Up @@ -147,45 +145,39 @@ final case class ThermalGrid(

/** Update the current state of the grid
*
* @param tick
* Instance in time
* @param relevantData
* data of heat pump including state of the heat pump
* @param state
* Currently applicable state
* @param lastAmbientTemperature
* Ambient temperature valid up until (not including) the current tick
* @param ambientTemperature
* Current ambient temperature
* @param qDot
* Thermal energy balance
* @return
* The updated state of the grid
*/
def updateState(
tick: Long,
relevantData: HpRelevantData,
state: ThermalGridState,
lastAmbientTemperature: Temperature,
ambientTemperature: Temperature,
qDot: Power,
): (ThermalGridState, Option[ThermalThreshold]) = if (qDot > zeroKW)
handleInfeed(tick, lastAmbientTemperature, ambientTemperature, state, qDot)
handleInfeed(relevantData, lastAmbientTemperature, state, qDot)
else
handleConsumption(
tick,
relevantData,
lastAmbientTemperature,
ambientTemperature,
state,
qDot,
)

/** Handles the case, when a grid has infeed. First, heat up all the houses to
* their maximum temperature, then fill up the storages
*
* @param tick
* Current tick
* @param relevantData
* data of heat pump including state of the heat pump
* @param lastAmbientTemperature
* Ambient temperature valid up until (not including) the current tick
* @param ambientTemperature
* Current ambient temperature
* @param state
* Current state of the houses
* @param qDot
Expand All @@ -194,9 +186,8 @@ final case class ThermalGrid(
* Updated thermal grid state
*/
private def handleInfeed(
tick: Long,
relevantData: HpRelevantData,
lastAmbientTemperature: Temperature,
ambientTemperature: Temperature,
state: ThermalGridState,
qDot: Power,
): (ThermalGridState, Option[ThermalThreshold]) =
Expand All @@ -209,7 +200,7 @@ final case class ThermalGrid(
Some(
thermalStorage
.updateState(
tick,
relevantData.currentTick,
zeroKW,
storageState,
)
Expand All @@ -220,10 +211,9 @@ final case class ThermalGrid(

val (updatedHouseState, maybeHouseThreshold) =
thermalHouse.determineState(
tick,
relevantData,
lastHouseState,
lastAmbientTemperature,
ambientTemperature,
qDot,
)

Expand All @@ -235,16 +225,19 @@ final case class ThermalGrid(
/* The house is already heated up fully, set back the infeed and put it into storage, if available */
val (fullHouseState, maybeFullHouseThreshold) =
thermalHouse.determineState(
tick,
relevantData,
lastHouseState,
lastAmbientTemperature,
ambientTemperature,
zeroKW,
)
storage.zip(updatedStorageState) match {
case Some((thermalStorage, storageState)) =>
val (updatedStorageState, maybeStorageThreshold) =
thermalStorage.updateState(tick, qDot, storageState)
thermalStorage.updateState(
relevantData.currentTick,
qDot,
storageState,
)

/* Both house and storage are updated. Determine what reaches the next threshold */
val nextThreshold = determineMostRecentThreshold(
Expand Down Expand Up @@ -278,7 +271,11 @@ final case class ThermalGrid(
storage.zip(state.storageState) match {
case Some((thermalStorage, storageState)) =>
val (updatedStorageState, maybeStorageThreshold) =
thermalStorage.updateState(tick, qDot, storageState)
thermalStorage.updateState(
relevantData.currentTick,
qDot,
storageState,
)
(
state.copy(storageState = Some(updatedStorageState)),
maybeStorageThreshold,
Expand Down Expand Up @@ -307,12 +304,10 @@ final case class ThermalGrid(

/** Handle consumption (or no infeed) from thermal grid
*
* @param tick
* Current tick
* @param relevantData
* data of heat pump including state of the heat pump
* @param lastAmbientTemperature
* Ambient temperature valid up until (not including) the current tick
* @param ambientTemperature
* Current ambient temperature
* @param state
* Current state of the houses
* @param qDot
Expand All @@ -321,39 +316,36 @@ final case class ThermalGrid(
* Updated thermal grid state
*/
private def handleConsumption(
tick: Long,
relevantData: HpRelevantData,
lastAmbientTemperature: Temperature,
ambientTemperature: Temperature,
state: ThermalGridState,
qDot: Power,
): (ThermalGridState, Option[ThermalThreshold]) = {
/* House will be left with no influx in all cases. Determine if and when a threshold is reached */
val maybeUpdatedHouseState =
house.zip(state.houseState).map { case (house, houseState) =>
house.determineState(
tick,
relevantData,
houseState,
lastAmbientTemperature,
ambientTemperature,
zeroMW,
)
}

/* Update the state of the storage */
val maybeUpdatedStorageState =
storage.zip(state.storageState).map { case (storage, storageState) =>
storage.updateState(tick, qDot, storageState)
storage.updateState(relevantData.currentTick, qDot, storageState)
}

val (revisedHouseState, revisedStorageState) =
reviseInfeedFromStorage(
tick,
relevantData,
maybeUpdatedHouseState,
maybeUpdatedStorageState,
state.houseState,
state.storageState,
lastAmbientTemperature,
ambientTemperature,
qDot,
)

Expand All @@ -376,8 +368,8 @@ final case class ThermalGrid(
* is no infeed from external and</li> <li>the storage is not empty
* itself</li> </ul>
*
* @param tick
* The current tick
* @param relevantData
* data of heat pump including state of the heat pump
* @param maybeHouseState
* Optional thermal house state
* @param maybeStorageState
Expand All @@ -388,23 +380,20 @@ final case class ThermalGrid(
* Previous thermal storage state before a first update was performed
* @param lastAmbientTemperature
* Ambient temperature valid up until (not including) the current tick
* @param ambientTemperature
* Current ambient temperature
* @param qDot
* Thermal influx
* @return
* Options to revised thermal house and storage state
*/
def reviseInfeedFromStorage(
tick: Long,
relevantData: HpRelevantData,
maybeHouseState: Option[(ThermalHouseState, Option[ThermalThreshold])],
maybeStorageState: Option[
(ThermalStorageState, Option[ThermalThreshold])
],
formerHouseState: Option[ThermalHouseState],
formerStorageState: Option[ThermalStorageState],
lastAmbientTemperature: Temperature,
ambientTemperature: Temperature,
qDot: Power,
): (
Option[(ThermalHouseState, Option[ThermalThreshold])],
Expand All @@ -422,7 +411,7 @@ final case class ThermalGrid(
) && !thermalStorage.isEmpty(storageState.storedEnergy) =>
/* Storage is meant to heat the house only, if there is no infeed from external (+/- 10 W) and the house is cold */
val revisedStorageState = thermalStorage.updateState(
tick,
relevantData.currentTick,
thermalStorage.getChargingPower * -1,
formerStorageState.getOrElse(
throw new InconsistentStateException(
Expand All @@ -431,14 +420,13 @@ final case class ThermalGrid(
),
)
val revisedHouseState = thermalHouse.determineState(
tick,
relevantData,
formerHouseState.getOrElse(
throw new InconsistentStateException(
"Impossible to find no house state"
)
),
lastAmbientTemperature,
ambientTemperature,
thermalStorage.getChargingPower,
)
(Some(revisedHouseState), Some(revisedStorageState))
Expand Down
34 changes: 17 additions & 17 deletions src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import edu.ie3.datamodel.models.input.thermal.{
ThermalBusInput,
ThermalHouseInput,
}
import edu.ie3.simona.model.participant.HpModel.HpRelevantData
import edu.ie3.simona.model.thermal.ThermalGrid.ThermalEnergyDemand
import edu.ie3.simona.model.thermal.ThermalHouse.ThermalHouseThreshold.{
HouseTemperatureLowerBoundaryReached,
Expand Down Expand Up @@ -82,27 +83,24 @@ final case class ThermalHouse(
* determining the thermal demand, a change in external infeed will take
* place.
*
* @param tick
* Questionable tick
* @param ambientTemperature
* Ambient temperature in the instance in question
* @param relevantData
* data of heat pump including state of the heat pump
* @param state
* most recent state, that is valid for this model
* @return
* the needed energy in the questioned tick
*/
def energyDemand(
tick: Long,
ambientTemperature: Temperature,
relevantData: HpRelevantData,
state: ThermalHouseState,
): ThermalEnergyDemand = {
/* Calculate the inner temperature of the house, at the questioned instance in time */
val duration = Seconds(tick - state.tick)
val duration = Seconds(relevantData.currentTick - state.tick)
val currentInnerTemp = newInnerTemperature(
state.qDot,
duration,
state.innerTemperature,
ambientTemperature,
relevantData.ambientTemperature,
)

/* Determine, which temperature boundary triggers a needed energy to reach the temperature constraints */
Expand Down Expand Up @@ -219,27 +217,24 @@ final case class ThermalHouse(

/** Update the current state of the house
*
* @param tick
* Current instance in time
* @param relevantData
* data of heat pump including state of the heat pump
* @param state
* Currently applicable state
* @param lastAmbientTemperature
* Ambient temperature valid up until (not including) the current tick
* @param ambientTemperature
* Current ambient temperature
* @param qDot
* New thermal influx
* @return
* Updated state and the tick in which the next threshold is reached
*/
def determineState(
tick: Long,
relevantData: HpRelevantData,
state: ThermalHouseState,
lastAmbientTemperature: Temperature,
ambientTemperature: Temperature,
qDot: Power,
): (ThermalHouseState, Option[ThermalThreshold]) = {
val duration = Seconds(tick - state.tick)
val duration = Seconds(relevantData.currentTick - state.tick)
val updatedInnerTemperature = newInnerTemperature(
state.qDot,
duration,
Expand All @@ -249,11 +244,16 @@ final case class ThermalHouse(

/* Calculate the next given threshold */
val threshold =
nextThreshold(tick, qDot, updatedInnerTemperature, ambientTemperature)
nextThreshold(
relevantData.currentTick,
qDot,
updatedInnerTemperature,
relevantData.ambientTemperature,
)

(
state.copy(
tick = tick,
tick = relevantData.currentTick,
innerTemperature = updatedInnerTemperature,
qDot = qDot,
),
Expand Down
Loading

0 comments on commit e420a54

Please sign in to comment.