Skip to content

Commit

Permalink
Merge branch 'df/#878-thermalGridIT' into df/#856-tap-water
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala
#	src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala
#	src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala
#	src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala
#	src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala
  • Loading branch information
danielfeismann committed Nov 26, 2024
2 parents 577bd3a + b90144d commit 5688a65
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 91 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,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
73 changes: 27 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 @@ -73,21 +73,19 @@ 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,
)
val (heatDemand, newHouseState) = if (
updatedHouseState.innerTemperature < thermalHouse.targetTemperature | (lastHouseState.qDot > zeroKW && updatedHouseState.innerTemperature < thermalHouse.upperBoundaryTemperature)
) {
(
thermalHouse.energyDemandHeating(
relevantData.currentTick,
relevantData.ambientTemperature,
relevantData,
updatedHouseState,
),
Some(updatedHouseState),
Expand Down Expand Up @@ -286,6 +284,7 @@ final case class ThermalGrid(
): (ThermalGridState, Option[ThermalThreshold]) = {
// TODO: We would need to issue a storage result model here...


/* Consider the action in the last state and if it's possible to continue*/
val (_, qDotHouseLastState, houseReachedBoundary, houseLeftBoundary) =
updateStateGetLastThermalActionAndCheckIfCanContinueThermalHouse(
Expand Down Expand Up @@ -314,7 +313,6 @@ final case class ThermalGrid(
relevantData.currentTick,
state,
)

val houseDemand = thermalDemands.houseDemand
val heatStorageDemand = thermalDemands.heatStorageDemand
val domesticHotWaterStorageDemand =
Expand Down Expand Up @@ -352,8 +350,6 @@ final case class ThermalGrid(
domesticHotWaterStorageLeftBoundary,
isRunning,
)
}
}

/** Handles the last cases of [[ThermalGrid.handleInfeed]], where the thermal
* infeed should be determined. FIXME adapt whole table
Expand Down Expand Up @@ -385,7 +381,7 @@ final case class ThermalGrid(
* | 4 | if(!house.reqD && house.addD && !storage.reqD && !storage.addD) => house | house |
* | 5 | if(all == false) => no output | no output |
*/
def handleFinaleInfeedCases(
private def handleFinaleInfeedCases(
thermalDemands: ThermalDemandWrapper,
relevantData: HpRelevantData,
lastAmbientTemperature: Temperature,
Expand All @@ -397,7 +393,7 @@ final case class ThermalGrid(
qDotDomesticWaterStorageLastState: Option[Power],
domesticHotWaterStorageLeftBoundary: Boolean,
isRunning: Boolean,
) = {
): (ThermalGridState, Option[ThermalThreshold]) = {
(
thermalDemands.houseDemand.hasRequiredDemand,
thermalDemands.houseDemand.hasAdditionalDemand,
Expand Down Expand Up @@ -728,9 +724,9 @@ final case class ThermalGrid(
houseInhabitants: Double,
) = {
handleCases(
tick,
relevantData,
lastAmbientTemperature,
ambientTemperature,

state,
qDot,
zeroKW,
Expand Down Expand Up @@ -769,9 +765,9 @@ final case class ThermalGrid(
houseInhabitants: Double,
) = {
handleCases(
tick,
relevantData,
lastAmbientTemperature,
ambientTemperature,

state,
zeroKW,
qDot,
Expand Down Expand Up @@ -810,9 +806,9 @@ final case class ThermalGrid(
houseInhabitants: Double,
) = {
handleCases(
tick,
relevantData,
lastAmbientTemperature,
ambientTemperature,

state,
zeroKW,
zeroKW,
Expand Down Expand Up @@ -886,12 +882,10 @@ final case class ThermalGrid(
/** Handles the different cases, of thermal flows from and into the 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 thermal grid
* @param qDotHouse
Expand All @@ -908,9 +902,8 @@ final case class ThermalGrid(
* Updated thermal grid state and the next threshold if there is one
*/
private def handleCases(
tick: Long,
relevantData: HpRelevantData,
lastAmbientTemperature: Temperature,
ambientTemperature: Temperature,
state: ThermalGridState,
qDotHouse: Power,
qDotHeatStorage: Power,
Expand All @@ -921,16 +914,15 @@ final case class ThermalGrid(
// FIXME: Is there any case where we get back some remainingQDotHouse?
val (updatedHouseState, thermalHouseThreshold, remainingQDotHouse) =
handleInfeedHouse(
tick,
relevantData,
lastAmbientTemperature,
ambientTemperature,
state,
qDotHouse,
)

val (updatedStorageState, thermalStorageThreshold) =
handleInfeedStorage(
tick,
relevantData.currentTick,
state,
qDotHeatStorage,
heatStorage,
Expand Down Expand Up @@ -971,12 +963,10 @@ final case class ThermalGrid(
/** Handles the case, when the house has heat demand and will be heated up
* here.
*
* @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 @@ -985,19 +975,17 @@ final case class ThermalGrid(
* Updated thermal house state, a ThermalThreshold and the remaining qDot
*/
private def handleInfeedHouse(
tick: Long,
relevantData: HpRelevantData,
lastAmbientTemperature: Temperature,
ambientTemperature: Temperature,
state: ThermalGridState,
qDot: Power,
): (Option[ThermalHouseState], Option[ThermalThreshold], Power) = {
(house, state.houseState) match {
case (Some(thermalHouse), Some(lastHouseState)) =>
val (newState, threshold) = thermalHouse.determineState(
tick,
relevantData,
lastHouseState,
lastAmbientTemperature,
ambientTemperature,
qDot,
)
/* Check if house can handle the thermal feed in */
Expand All @@ -1008,10 +996,9 @@ final case class ThermalGrid(
) {
val (fullHouseState, maybeFullHouseThreshold) =
thermalHouse.determineState(
tick,
relevantData,
lastHouseState,
lastAmbientTemperature,
ambientTemperature,
zeroKW,
)
(Some(fullHouseState), maybeFullHouseThreshold, qDot)
Expand Down Expand Up @@ -1148,14 +1135,14 @@ final case class ThermalGrid(
}
}


/** Returns the very next threshold or None if there isn't any.
*
* @param thresholds
* A sequence of thresholds
* @return
* The next [[ThermalThreshold]] or [[None]].
*/

private def determineMostRecentThreshold(
thresholds: Seq[Option[ThermalThreshold]]
): Option[ThermalThreshold] = {
Expand Down Expand Up @@ -1186,8 +1173,6 @@ final case class ThermalGrid(
* 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 Down Expand Up @@ -1337,8 +1322,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 @@ -1349,23 +1334,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 @@ -1383,7 +1365,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 @@ -1392,14 +1374,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 @@ -92,27 +93,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 for heating in the questioned tick
*/
def energyDemandHeating(
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 @@ -429,27 +427,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 @@ -459,11 +454,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 5688a65

Please sign in to comment.