Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/df/#827_fix_hp_stor…
Browse files Browse the repository at this point in the history
…age_refill' into df/#878-thermalGridIT

# Conflicts:
#	CHANGELOG.md
#	src/main/scala/edu/ie3/simona/model/participant/HpModel.scala
#	src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.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 Aug 22, 2024
2 parents d2c433b + 1f829e6 commit 25de224
Show file tree
Hide file tree
Showing 11 changed files with 584 additions and 103 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Enhanced Newton-Raphson-PowerFlow failures with more information [#815](https://github.com/ie3-institute/simona/issues/815)
- Update RTD references and bibliography [#868](https://github.com/ie3-institute/simona/issues/868)
- Add gradle application plugin for command line execution with gradle run [#890](https://github.com/ie3-institute/simona/issues/890)
- Additional tests to check flexibility options of thermal house and storage [#729](https://github.com/ie3-institute/simona/issues/729)
- Integration test for thermal grids [#878](https://github.com/ie3-institute/simona/issues/878)

### Changed
Expand Down Expand Up @@ -77,6 +78,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Updated AUTHORS.md [#904](https://github.com/ie3-institute/simona/issues/904)
- Updated `Gradle` to version V8.10 [#829](https://github.com/ie3-institute/simona/issues/829)
- Updated AUTHORS.md [#905](https://github.com/ie3-institute/simona/issues/905)
- Prepare ThermalStorageTestData for Storage without storageVolumeLvlMin [#894](https://github.com/ie3-institute/simona/issues/894)

### Fixed
- Removed a repeated line in the documentation of vn_simona config [#658](https://github.com/ie3-institute/simona/issues/658)
Expand Down
1 change: 1 addition & 0 deletions docs/readthedocs/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ models/two_winding_transformer_model
models/three_winding_transformer_model
models/reference_system
models/thermal_grid_model
models/thermal_house_model
```

## System Participant Related Models
Expand Down
2 changes: 2 additions & 0 deletions docs/readthedocs/models/thermal_grid_model.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

The Thermal Grid Model introduces a coupling point to thermal system, equivalent to an electrical node. It can be used to interconnect thermal units to a thermal heat network.

A Thermal Grid Model consists of a {ref}`thermal_house_model` and / or a {ref}`cts_model` which are supplied by a thermal source like a {ref}`hp_model`.

## Attributes, Units and Remarks

Please refer to {doc}`PowerSystemDataModel - Thermal Bus <psdm:models/input/thermal/thermalbus>` for Attributes and Units used in this Model.
13 changes: 13 additions & 0 deletions docs/readthedocs/models/thermal_house_model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
(thermal_house_model)=

# Thermal House Model

This page documents the functionality of the thermal house available in SIMONA.

## Behaviour

This house model represents the thermal behaviour of a building. This reflects a simple shoe box with a thermal capacity and with transmission losses.

## Attributes, Units and Remarks

Please refer to {doc}`PowerSystemDataModel - Thermal House Model <psdm:models/input/thermal/thermalhouse>` for Attributes and Units used in this Model.
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,11 @@ trait HpAgentFundamentals
calcRelevantData: HpRelevantData,
nodalVoltage: squants.Dimensionless,
model: HpModel,
): HpState = model.determineState(modelState, calcRelevantData)
): HpState = {
val (canOperate, canBeOutOfOperation, state) =
model.determineState(modelState, calcRelevantData)
state
}

/** Abstract definition, individual implementations found in individual agent
* fundamental classes
Expand Down
57 changes: 26 additions & 31 deletions src/main/scala/edu/ie3/simona/model/participant/HpModel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -115,20 +115,23 @@ final case class HpModel(
* function calculates the heat pump's next state to get the actual active
* power of this state use [[calculateActivePower]] with the generated state
*
* @param state
* Current state of the heat pump
* @param lastState
* Last state of the heat pump
* @param relevantData
* data of heat pump including
* @return
* next [[HpState]]
* Booleans if Hp can operate and can be out of operation plus next
* [[HpState]]
*/
def determineState(
state: HpState,
lastState: HpState,
relevantData: HpRelevantData,
): HpState = {
val (turnOn, houseDemand, storageDemand) =
operatesInNextState(state, relevantData)
calcState(state, relevantData, turnOn, houseDemand, storageDemand)
): (Boolean, Boolean, HpState) = {
val (turnOn, canOperate, canBeOutOfOperation, houseDemand, storageDemand) =
operatesInNextState(lastState, relevantData)
val updatedState =
calcState(lastState, relevantData, turnOn, houseDemand, storageDemand)
(canOperate, canBeOutOfOperation, updatedState)
}

/** Depending on the input, this function decides whether the heat pump will
Expand All @@ -142,8 +145,8 @@ final case class HpModel(
* @param relevantData
* Relevant (external) data
* @return
* boolean defining if heat pump runs in next time step and if house and
* storage have some demand
* boolean defining if heat pump runs in next time step, if it can be in
* operation and out of operation plus the demand of house and storage
*/
private def operatesInNextState(
state: HpState,
Expand All @@ -162,6 +165,7 @@ final case class HpModel(
_.storedEnergy =~ zeroKWH
)

//FIXME harmonise this
val houseDemand =
(demandHouse.hasRequiredDemand && noThermalStorageOrThermalStorageIsEmpty) || (state.isRunning && demandHouse.hasAdditionalDemand)
val heatStorageDemand =
Expand All @@ -170,10 +174,18 @@ final case class HpModel(
val turnHpOn: Boolean =
houseDemand || heatStorageDemand

val canOperate =
demandHouse.hasRequiredDemand || demandHouse.hasAdditionalDemand ||
demandStorage.hasRequiredDemand || demandStorage.hasAdditionalDemand
val canBeOutOfOperation =
!(demandHouse.hasRequiredDemand && noStorageOrStorageIsEmpty)

(
turnHpOn,
houseDemand,
heatStorageDemand,
canOperate,
canBeOutOfOperation,
demandHouse,
demandStorage,
)
}

Expand Down Expand Up @@ -241,25 +253,8 @@ final case class HpModel(
lastState: HpState,
): ProvideFlexOptions = {
/* Determine the operating state in the given tick */
val updatedHpState: HpState = determineState(lastState, data)

/* Determine the options we have */
val (
thermalEnergyDemandHouse,
thermalEnergyDemandStorage,
updatedThermalGridState,
) =
thermalGrid.energyDemandAndUpdatedState(
data.currentTick,
lastState.ambientTemperature.getOrElse(data.ambientTemperature),
data.ambientTemperature,
lastState.thermalGridState,
)
val canOperate =
thermalEnergyDemandHouse.hasRequiredDemand || thermalEnergyDemandHouse.hasAdditionalDemand ||
thermalEnergyDemandStorage.hasRequiredDemand || thermalEnergyDemandStorage.hasAdditionalDemand
val canBeOutOfOperation =
!thermalEnergyDemandHouse.hasRequiredDemand && !thermalEnergyDemandStorage.hasRequiredDemand
val (canOperate, canBeOutOfOperation, updatedHpState)
: (Boolean, Boolean, HpState) = determineState(lastState, data)

val lowerBoundary =
if (canBeOutOfOperation)
Expand Down
18 changes: 11 additions & 7 deletions src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import edu.ie3.datamodel.models.result.thermal.{
CylindricalStorageResult,
ThermalHouseResult,
}
import edu.ie3.simona.exceptions.InvalidParameterException
import edu.ie3.simona.exceptions.agent.InconsistentStateException
import edu.ie3.simona.model.thermal.ThermalGrid.{
ThermalEnergyDemand,
Expand Down Expand Up @@ -103,8 +104,8 @@ final case class ThermalGrid(
storage
.zip(state.storageState)
.map { case (storage, state) =>
val updatedStorageState =
storage.updateState(tick, state.qDot, state)._1
val (updatedStorageState, _) =
storage.updateState(tick, state.qDot, state)
val storedEnergy = updatedStorageState.storedEnergy
val soc = storedEnergy / storage.getMaxEnergyThreshold
val storageRequired = {
Expand Down Expand Up @@ -785,13 +786,12 @@ object ThermalGrid {

def hasRequiredDemand: Boolean = required > zeroMWH

def hasAdditionalDemand: Boolean = possible > required
def hasAdditionalDemand: Boolean = possible > zeroMWH
}
object ThermalEnergyDemand {

/** Builds a new instance of [[ThermalEnergyDemand]]. If the possible energy
* is less than the required energy, this is considered to be a bad state
* and the required energy is curtailed to the possible energy.
* is less than the required energy, this is considered to be a bad state.
* @param required
* The absolutely required energy to reach target state
* @param possible
Expand All @@ -803,8 +803,12 @@ object ThermalGrid {
required: Energy,
possible: Energy,
): ThermalEnergyDemand = {
if (possible < required)
new ThermalEnergyDemand(possible, possible)
if (
math.abs(possible.toKilowattHours) < math.abs(required.toKilowattHours)
)
throw new InvalidParameterException(
s"The possible amount of energy {$possible} is smaller than the required amount of energy {$required}. This is not supported."
)
else
new ThermalEnergyDemand(required, possible)
}
Expand Down
Loading

0 comments on commit 25de224

Please sign in to comment.