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

Refactoring of ThermalGrid.handleInfeed to fix thermal storage recharge correctly when empty #931

Merged
merged 105 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from 78 commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
baabf85
Merge remote-tracking branch 'refs/remotes/origin/df/#926-Fix-determi…
danielfeismann Aug 24, 2024
7659750
Merge remote-tracking branch 'refs/remotes/origin/df/#924-ThermalStor…
danielfeismann Aug 24, 2024
0b1868d
Merge remote-tracking branch 'refs/remotes/origin/df/#922-Fix-activat…
danielfeismann Aug 24, 2024
e2d7133
Merge remote-tracking branch 'refs/remotes/origin/df/#928-Refactor-Th…
danielfeismann Aug 24, 2024
64a67ec
Refactoring of ThermalGrid.handleInfeed to fix thermal storage rechar…
danielfeismann Aug 24, 2024
cb34618
Merge branch 'refs/heads/dev' into df/#930-refactor-handleInfeed
danielfeismann Aug 29, 2024
9ce13f9
Merge branch 'refs/heads/dev' into df/#930-refactor-handleInfeed
danielfeismann Aug 29, 2024
1573bcc
Merge branch 'refs/heads/dev' into df/#930-refactor-handleInfeed
danielfeismann Sep 16, 2024
355d765
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Sep 17, 2024
c1e37ee
Merge branch 'refs/heads/dev' into df/#930-refactor-handleInfeed
danielfeismann Sep 17, 2024
47e4052
Merge branch 'refs/heads/dev' into df/#930-refactor-handleInfeed
danielfeismann Sep 26, 2024
de1b0c5
Merge branch 'refs/heads/dev' into df/#930-refactor-handleInfeed
danielfeismann Oct 1, 2024
b6c596f
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Oct 28, 2024
e1df392
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Nov 1, 2024
339a020
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Nov 7, 2024
20664ab
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Nov 13, 2024
165371d
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Nov 14, 2024
ba6b581
Merge branch 'df/#928-Refactor-ThermalGird-energyDemand' into df/#930…
danielfeismann Nov 14, 2024
441359c
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Nov 14, 2024
a669b5b
remove double entry in changelog
danielfeismann Nov 14, 2024
7884541
Revert "remove double entry in changelog"
danielfeismann Nov 14, 2024
86b3256
remove correct double entry in changelog
danielfeismann Nov 14, 2024
f4fa810
reintroduce demand booleans indicating demand when handle thermal infeed
danielfeismann Nov 14, 2024
963670c
add some scala doc
danielfeismann Nov 14, 2024
bfd633b
handle sonar code smell
danielfeismann Nov 14, 2024
9eee886
Revert "handle sonar code smell"
danielfeismann Nov 14, 2024
122cb69
handle sonar code smell
danielfeismann Nov 14, 2024
eba3b89
fmt
danielfeismann Nov 15, 2024
1f6311f
fix scala doc
danielfeismann Nov 15, 2024
95d0562
refactor demand booleans of thermal units into ThermalDemandIndicator…
danielfeismann Nov 15, 2024
30e4318
Merge branch 'df/#1023-zeroKW-and-kWh-in-test' into df/#930-refactor-…
danielfeismann Nov 15, 2024
9fb1523
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Nov 15, 2024
94397ee
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Nov 15, 2024
7341e10
remove unnecessary value
danielfeismann Nov 15, 2024
b69dd06
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Nov 15, 2024
36ce30a
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Nov 19, 2024
aa2db68
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Nov 19, 2024
41e2441
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Nov 19, 2024
debae48
refactoring thermal demand indicators
danielfeismann Nov 22, 2024
a95a242
Merge branch 'refs/heads/dev' into df/#930-refactor-handleInfeed
danielfeismann Nov 22, 2024
5c00a89
fix thermalPower determination in calcState of HpModel
danielfeismann Nov 22, 2024
cbd997e
fix EmAgentIT
danielfeismann Nov 22, 2024
a07b626
also turn Hp on in case house has additional demand and the Hp was ru…
danielfeismann Nov 22, 2024
92e6c51
fix EmAgentIT
danielfeismann Nov 23, 2024
481da32
fmt
danielfeismann Nov 23, 2024
b03b576
correct direction of thermal power of thermal heat storage
danielfeismann Nov 23, 2024
7b58297
fix handleInfeed of thermal energy
danielfeismann Nov 23, 2024
c763b72
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Nov 23, 2024
8d452ec
enhance ThermalGridSpec when checking for required and additional demand
danielfeismann Nov 23, 2024
07746a4
fix inputs for thermalGridWith specs plus add another test case
danielfeismann Nov 23, 2024
aa9ffc9
remove unused parameter
danielfeismann Nov 23, 2024
6dabaf7
Merge branch 'df/#1049-Introduce-ThermalDemandWrapper' into df/#930-r…
danielfeismann Nov 25, 2024
0d157db
fix after merging
danielfeismann Nov 25, 2024
9a9096d
fmt
danielfeismann Nov 25, 2024
7e8afb0
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Nov 25, 2024
81694cc
hard fix for zero values as minimum storage volume level to prevent n…
danielfeismann Nov 25, 2024
d9f859c
adapt ChpModelSpec and CylindricalThermalStorageSpec to zero for mini…
danielfeismann Nov 25, 2024
bed4f7b
adapt cases for handling thermal infeed into ThermalGrid
danielfeismann Nov 25, 2024
badd6d9
fix consider qDot as heat result of hp only when hp is running
danielfeismann Nov 25, 2024
ae84f16
fmt
danielfeismann Nov 25, 2024
dab5a85
fix wrong case within thermalGrid
danielfeismann Nov 26, 2024
0adc6c9
split handleInfeed method a tiny bit
danielfeismann Nov 26, 2024
1586bd3
fmt
danielfeismann Nov 26, 2024
88c6e3a
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Nov 26, 2024
be3b094
fix after merging dev
danielfeismann Nov 26, 2024
6163afd
fix tests after merging dev
danielfeismann Nov 26, 2024
634fbf4
fmt
danielfeismann Nov 26, 2024
6b97e8e
fmt
danielfeismann Nov 26, 2024
0e484c4
remove commented-out code
danielfeismann Nov 27, 2024
be33961
fix chp storage level check
danielfeismann Nov 27, 2024
88c4e24
use table for testing purposes
danielfeismann Nov 27, 2024
51fa462
fix ChpModelSpec
danielfeismann Nov 27, 2024
42105bd
hopefully final fix for ChpModelSpec
danielfeismann Nov 27, 2024
cae9db3
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Dec 10, 2024
8ad45f3
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Dec 11, 2024
ef8556b
fmt
danielfeismann Dec 11, 2024
2e14fce
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Dec 30, 2024
eb98330
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Jan 13, 2025
9887c47
fmt
danielfeismann Jan 14, 2025
ee6e326
correctly name thermalGridState
danielfeismann Jan 14, 2025
35f601f
Apply suggestions from code review
danielfeismann Jan 14, 2025
e8be5c8
Merge remote-tracking branch 'origin/df/#930-refactor-handleInfeed' i…
danielfeismann Jan 14, 2025
83866d3
split cases and handle another edge case
danielfeismann Jan 14, 2025
c34a83b
some comments for the cases
danielfeismann Jan 14, 2025
6229c18
some more comments and rename of variables for better understanding
danielfeismann Jan 14, 2025
85d92d4
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Jan 16, 2025
ff8feb5
Merge branch 'df/#917-Refactor-ThermalEnergyDemand' into df/#930-refa…
danielfeismann Jan 16, 2025
b7bb639
fix ThermalGridSpec
danielfeismann Jan 16, 2025
4e0367d
Merge branch 'df/#917-Refactor-ThermalEnergyDemand' into df/#930-refa…
danielfeismann Jan 16, 2025
4ae46cf
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Jan 28, 2025
d9c6eaa
Merge branch 'dev' into df/#930-refactor-handleInfeed
sebastian-peter Jan 30, 2025
457dcf1
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Feb 3, 2025
ff60ba5
Merge branch 'dev' into df/#930-refactor-handleInfeed
danielfeismann Feb 3, 2025
fb5ee23
fix tests after merging dev
danielfeismann Feb 3, 2025
6a9c2c3
Proposed simplification for infeed cases
sebastian-peter Feb 4, 2025
17c492b
ScalaDoc fix
sebastian-peter Feb 4, 2025
0b6599c
renaming handleInfeedStorage to handleStorageCases
danielfeismann Feb 5, 2025
1485df6
Merge remote-tracking branch 'origin/df/#930-refactor-handleInfeed' i…
danielfeismann Feb 5, 2025
4e2f49d
update scalaDoc regarding qDot
danielfeismann Feb 5, 2025
4ce951f
distinguish between thermalPower of Hp and qDot into grid to avoid ch…
danielfeismann Feb 5, 2025
f48ad51
clearer naming of state
danielfeismann Feb 5, 2025
b1a188f
Enhance ScalaDoc for clearer understanding of required thermalDemand …
danielfeismann Feb 5, 2025
0af10b3
Add ScalaDoc ThermalStorageState
danielfeismann Feb 5, 2025
c6fcf41
Merge remote-tracking branch 'origin/dev' into df/#930-refactor-handl…
danielfeismann Feb 5, 2025
3f67ba7
Some nitpicky formatting things
sebastian-peter Feb 6, 2025
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed Deployment of `simona` to `Maven Central` in new GHA Pipeline [#1029](https://github.com/ie3-institute/simona/issues/1029)
- Fixed SonarQube quality gate using the right link for PRs or Branches [#1061](https://github.com/ie3-institute/simona/issues/1061)
- Fixed ignored EM strategy [#1091](https://github.com/ie3-institute/simona/issues/1091)
- Refactoring of `ThermalGrid.handleInfeed` to fix thermal storage recharge correctly when empty [#930](https://github.com/ie3-institute/simona/issues/930)

## [3.0.0] - 2023-08-07

Expand Down
42 changes: 35 additions & 7 deletions src/main/scala/edu/ie3/simona/model/participant/HpModel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,12 @@ final case class HpModel(
tick: Long,
currentState: HpState,
data: HpRelevantData,
): Power = currentState.qDot
): Power =
// only if Hp is running qDot will be from Hp, else qDot results from other source, e.g. some storage
if (currentState.isRunning)
currentState.qDot
else
zeroKW

/** Given a [[HpRelevantData]] object and the last [[HpState]], this function
* calculates the heat pump's next state to get the actual active power of
Expand Down Expand Up @@ -149,7 +154,7 @@ final case class HpModel(

// Updating the HpState
val updatedState =
calcState(lastHpState, relevantData, turnOn)
calcState(lastHpState, relevantData, turnOn, thermalDemandWrapper)
(canOperate, canBeOutOfOperation, updatedState)
}

Expand Down Expand Up @@ -212,32 +217,45 @@ final case class HpModel(
* data of heat pump including state of the heat pump
* @param isRunning
* determines whether the heat pump is running or not
* @param demandWrapper
* holds the thermal demands of the thermal units (house, storage)
* @return
* next [[HpState]]
*/
private def calcState(
lastState: HpState,
relevantData: HpRelevantData,
isRunning: Boolean,
demandWrapper: ThermalDemandWrapper,
): HpState = {
val lastStateStorageQDot = lastState.thermalGridState.storageState
.map(_.qDot)
.getOrElse(zeroKW)

val (newActivePower, newThermalPower) =
val (newActivePower, newThermalPower) = {
if (isRunning)
(pRated, pThermal)
else if (lastStateStorageQDot < zeroKW)
(zeroKW, lastStateStorageQDot * -1)
(zeroKW, lastStateStorageQDot * (-1))
else if (
lastStateStorageQDot == zeroKW && (demandWrapper.houseDemand.hasRequiredDemand || demandWrapper.heatStorageDemand.hasRequiredDemand)
)
(
zeroKW,
thermalGrid.storage.map(_.getChargingPower: squants.Power).get,
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would love some help understanding what is being done here. Maybe we could enhance the overall code documentation here? To someone who knows the implementation well, these probably seem trivial, but for the untrained eye they're maybe not. For example:

  • There's multiple thermal powers, but they're not clearly defined. In HpState, is qDot the combined thermal power including storage, or just the heat pump, or just storage?
  • Does qDot in the house state include the heat loss of the building, or just infeed by the grid?
  • What does it mean if the storage has "required demand"? Maybe one could argue that storage demand is always somewhat optional.
  • I suppose positive charging power of the storage means charging, negative means discharging? Would love to have this documented
  • Generally, the selected piece of code here could maybe be commented a bit, i.e. why is each case doing what it is doing?

Those are just some things that "jumped" at me...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right! Even after some time understanding what happens here get's hard, to be honest...

Regarding your questions:

  • qDot of HpState is just the qDot from the Hp.
  • qDot in the house state includes only the infeed (from grid or from storage), losses comes separate since they depending also from temperature difference.
  • imho: storage has required demand if they are empty. They're having additionalDemand unless they're full.
  • please see here but I will add it to the other scalaDocs whenever it makes sense...
  • Agreed. Let's see if I can make it easier to understand.

Copy link
Member Author

@danielfeismann danielfeismann Jan 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

partly the interpretation of required and additional demand is handled here. Which we should merge before. #918

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding this large amount of commentary to the code! I have only two more places with "additional documentation demand" ;)

About storages: I guess one could argue about the required demand for empty storage (what if it's filled with a mWh of energy - there'd be no required demand). But, I'd suggest to just document the way this is currently implemented. Maybe it makes sense to enhance the documentation of ThermalDemandWrapper.heatStorageDemand in that regard?

Furthermore, ScalaDoc for ThermalStorageState would be great. Questions about the sign/direction of its qDot would be solved then.

else (zeroKW, zeroKW)
}

/* Push thermal energy to the thermal grid and get its updated state in return */
val (thermalGridState, maybeThreshold) =
thermalGrid.updateState(
relevantData,
lastState.thermalGridState,
lastState.ambientTemperature.getOrElse(relevantData.ambientTemperature),
isRunning,
newThermalPower,
demandWrapper,
)

HpState(
Expand Down Expand Up @@ -285,7 +303,7 @@ final case class HpModel(
* operating state and give back the next tick in which something will
* change.
*
* @param data
* @param relevantData
* Relevant data for model calculation
* @param lastState
* The last known model state
Expand All @@ -296,17 +314,27 @@ final case class HpModel(
* options will change next
*/
override def handleControlledPowerChange(
data: HpRelevantData,
relevantData: HpRelevantData,
lastState: HpState,
setPower: Power,
): (HpState, FlexChangeIndicator) = {
/* If the set point value is above 50 % of the electrical power, turn on the heat pump otherwise turn it off */
val turnOn = setPower > (sRated.toActivePower(cosPhiRated) * 0.5)

val (
thermalDemandWrapper,
_,
) =
thermalGrid.energyDemandAndUpdatedState(
relevantData,
lastState,
)

val updatedHpState = calcState(
lastState,
data,
relevantData,
turnOn,
thermalDemandWrapper,
)

(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,23 +187,10 @@ object CylindricalThermalStorage {
input: CylindricalStorageInput,
initialStoredEnergy: Energy = DefaultQuantities.zeroKWh,
): CylindricalThermalStorage = {
val minEnergyThreshold: Energy =
CylindricalThermalStorage.volumeToEnergy(
CubicMeters(
input.getStorageVolumeLvlMin
.to(Units.CUBIC_METRE)
.getValue
.doubleValue
),
KilowattHoursPerKelvinCubicMeters(
input.getC
.to(PowerSystemUnits.KILOWATTHOUR_PER_KELVIN_TIMES_CUBICMETRE)
.getValue
.doubleValue
),
Celsius(input.getInletTemp.to(Units.CELSIUS).getValue.doubleValue()),
Celsius(input.getReturnTemp.to(Units.CELSIUS).getValue.doubleValue()),
)
val minEnergyThreshold: Energy = {
// Temporary fix until changes in PSDM are released, Some minimumEnergyThreshold would lead to non-plausible behaviour
zeroKWh
}

val maxEnergyThreshold: Energy =
CylindricalThermalStorage.volumeToEnergy(
Expand Down
Loading
Loading