Skip to content

Commit

Permalink
Merge branch 'dev' into sp/#273-simplify-ParticipantConfigUtil
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastian-peter authored Jul 4, 2022
2 parents 85acee1 + d2254c1 commit c825a5c
Show file tree
Hide file tree
Showing 10 changed files with 340 additions and 299 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Made SimonaConfig.BaseRuntimeConfig serializable [#36](https://github.com/ie3-institute/simona/issues/36)
- Adapt to new simonaAPI snapshot [#95](https://github.com/ie3-institute/simona/issues/95)
- Update Sphinx to 4.5.0 as well as extensions [#214](https://github.com/ie3-institute/simona/issues/214)
- Improved code quality in and around DBFS algorithm [#265](https://github.com/ie3-institute/simona/issues/265)

### Fixed
- Location of `vn_simona` test grid (was partially in Berlin and Dortmund) [#72](https://github.com/ie3-institute/simona/issues/72)
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ dependencies {
/* config */
implementation 'com.typesafe:config:1.4.2'
implementation "com.github.carueda:tscfg_2.13:$tscfgVersion"
implementation "com.github.scopt:scopt_${scalaVersion}:4.0.1" // cmd args parser
implementation "com.github.scopt:scopt_${scalaVersion}:4.1.0" // cmd args parser

// JTS
implementation ("org.locationtech.jts:jts-core:${jtsVersion}"){
Expand Down
32 changes: 17 additions & 15 deletions input/samples/vn_simona/vn_simona.conf
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,23 @@ simona.output.participant.defaultConfig = {
powerRequestReply = false
simulationResult = true
}
simona.output.participant.individualConfigs = [{
notifier = "pv"
powerRequestReply = false
simulationResult = true
}]
simona.output.participant.individualConfigs = [{
notifier = "wec"
powerRequestReply = false
simulationResult = true
}]
simona.output.participant.individualConfigs = [{
notifier = "evcs"
powerRequestReply = false
simulationResult = true
}]
simona.output.participant.individualConfigs = [
{
notifier = "pv"
powerRequestReply = false
simulationResult = true
},
{
notifier = "wec"
powerRequestReply = false
simulationResult = true
},
{
notifier = "evcs"
powerRequestReply = false
simulationResult = true
}
]

##################################################################
# Runtime Configuration // todo refactor as this naming is misleading and partly unneeded
Expand Down
203 changes: 93 additions & 110 deletions src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,11 @@ import edu.ie3.simona.ontology.messages.VoltageMessage.{
import edu.ie3.simona.ontology.trigger.Trigger._
import edu.ie3.simona.util.TickUtil._
import edu.ie3.util.quantities.PowerSystemUnits._
import edu.ie3.util.quantities.{PowerSystemUnits, QuantityUtil}
import tech.units.indriya.quantity.Quantities

import java.time.{Duration, ZonedDateTime}
import java.util.UUID
import javax.measure.Quantity
import javax.measure.quantity.{Dimensionless, ElectricPotential}
import javax.measure.quantity.ElectricPotential
import scala.concurrent.{ExecutionContext, Future}

/** Trait that is normally mixed into every [[GridAgent]] to enable distributed
Expand Down Expand Up @@ -119,6 +117,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport {
// we just received either all provided slack voltage values or all provided power values
val updatedGridAgentBaseData: GridAgentBaseData = receivedValues match {
case receivedPowers: ReceivedPowerValues =>
/* Can be a message from an asset or a message from an inferior grid */
gridAgentBaseData.updateWithReceivedPowerValues(receivedPowers)
case receivedSlacks: ReceivedSlackValues =>
gridAgentBaseData.updateWithReceivedSlackVoltages(receivedSlacks)
Expand Down Expand Up @@ -154,7 +153,6 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport {
allValuesReceived,
updatedGridAgentBaseData
)

}

// if we receive a request for slack voltages from our inferior grids we want to answer it
Expand All @@ -171,10 +169,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport {

// we either have voltages ready calculated (not the first sweep) or we don't have them here
// -> return calculated value or target voltage as physical value
val (slackE, slackF): (
Quantity[ElectricPotential],
Quantity[ElectricPotential]
) =
val (slackE, slackF) =
(gridAgentBaseData.sweepValueStores.get(currentSweepNo) match {
case Some(result) =>
Some(result, currentSweepNo)
Expand Down Expand Up @@ -226,7 +221,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport {
uuid == nodeUuid && isSlack
}
.map(_.vTarget)
.getOrElse(Quantities.getQuantity(1d, PowerSystemUnits.PU))
.getOrElse(Quantities.getQuantity(1d, PU))
val vSlack = vTarget
.multiply(
gridAgentBaseData.gridEnv.gridModel.mainRefSystem.nominalVoltage
Expand Down Expand Up @@ -368,12 +363,11 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport {
gridAgentBaseData: GridAgentBaseData
) =>
// inform my child grids about the end of this grid simulation
gridAgentBaseData.inferiorGridGates.foreach(inferiorGridGate => {
gridAgentBaseData.gridEnv
.subnetGateToActorRef(inferiorGridGate) ! FinishGridSimulationTrigger(
currentTick
)
})
gridAgentBaseData.inferiorGridGates
.map {
gridAgentBaseData.gridEnv.subnetGateToActorRef(_)
}
.foreach(_ ! FinishGridSimulationTrigger(currentTick))

// inform every system participant about the end of this grid simulation
gridAgentBaseData.gridEnv.nodeToAssetAgents.foreach { case (_, actors) =>
Expand Down Expand Up @@ -516,12 +510,8 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport {
// if yes, we do another PF with adapted values
// if no, we are done with the pf and ready to report to our parent grid
val changed = receivedPowerValues.values.exists {
case (_, providePowerResponseMsgOpt) =>
providePowerResponseMsgOpt.exists {
case _: AssetPowerChangedMessage => true
case _ => false
}
case _ => false
case (_, _: AssetPowerChangedMessage) => true
case _ => false
}

if (changed) {
Expand Down Expand Up @@ -1005,7 +995,8 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport {
* a map contains a mapping between nodes and the [[ActorRef]] s located @
* those nodes
* @param refSystem
* the reference system of the [[GridModel]] of this [[GridAgent]]
* the reference system of the [[edu.ie3.simona.model.grid.GridModel]] of
* this [[GridAgent]]
* @param askTimeout
* a timeout for the request
* @return
Expand All @@ -1028,53 +1019,46 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport {
Some(
Future
.sequence(
nodeToAssetAgents
.flatten(nodeUuidWithActorRefs => {
val assetActorRefs = nodeUuidWithActorRefs._2
val nodeUuid = nodeUuidWithActorRefs._1
assetActorRefs.map(assetAgent => {

val (eInPu, fInPU): (
Quantity[Dimensionless],
Quantity[Dimensionless]
) =
sweepValueStore match {
case Some(sweepValueStore) =>
val assetNodeVoltageInSi = refSystem.vInSi(
sweepValueStore.sweepData
.find(_.nodeUuid == nodeUuid)
.getOrElse(
throw new DBFSAlgorithmException(
s"Provided Sweep value store contains no data for node with id $nodeUuid"
)
nodeToAssetAgents.flatten { case (nodeUuid, assetActorRefs) =>
assetActorRefs.map(assetAgent => {

val (eInPu, fInPU) =
sweepValueStore match {
case Some(sweepValueStore) =>
val (eInSi, fInSi) = refSystem.vInSi(
sweepValueStore.sweepData
.find(_.nodeUuid == nodeUuid)
.getOrElse(
throw new DBFSAlgorithmException(
s"Provided Sweep value store contains no data for node with id $nodeUuid"
)
.stateData
.voltage
)
(
refSystem.vInPu(assetNodeVoltageInSi._1),
refSystem.vInPu(assetNodeVoltageInSi._2)
)
case None =>
(
Quantities.getQuantity(1, PU),
Quantities.getQuantity(0, PU)
)
}

(assetAgent ? RequestAssetPowerMessage(
currentTick,
QuantityUtil.asComparable(eInPu),
QuantityUtil.asComparable(fInPU)
)).map {
case providedPowerValuesMessage: AssetPowerChangedMessage =>
(assetAgent, Some(providedPowerValuesMessage))
case assetPowerUnchangedMessage: AssetPowerUnchangedMessage =>
(assetAgent, Some(assetPowerUnchangedMessage))
}.mapTo[ActorPowerRequestResponse]
})
)
.stateData
.voltage
)
(
refSystem.vInPu(eInSi),
refSystem.vInPu(fInSi)
)
case None =>
(
Quantities.getQuantity(1, PU),
Quantities.getQuantity(0, PU)
)
}

(assetAgent ? RequestAssetPowerMessage(
currentTick,
eInPu,
fInPU
)).map {
case providedPowerValuesMessage: AssetPowerChangedMessage =>
(assetAgent, providedPowerValuesMessage)
case assetPowerUnchangedMessage: AssetPowerUnchangedMessage =>
(assetAgent, assetPowerUnchangedMessage)
}
})
.toVector
}.toVector
)
.map(ReceivedAssetPowerValues)
.pipeTo(self)
Expand Down Expand Up @@ -1108,29 +1092,30 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport {
s"asking inferior grids for power values: {}",
inferiorGridGates
)
if (inferiorGridGates.nonEmpty)
Some(
Future
.sequence(
inferiorGridGates.map(inferiorGridGate => {
val inferiorGridAgent =
subGridGateToActorRef(inferiorGridGate)
(inferiorGridAgent ? RequestGridPowerMessage(
Option.when(inferiorGridGates.nonEmpty) {
Future
.sequence(
inferiorGridGates
.map { inferiorGridGate =>
subGridGateToActorRef(
inferiorGridGate
) -> inferiorGridGate.getSuperiorNode.getUuid
}
.map { case (inferiorGridAgentRef, inferiorGridGateNode) =>
(inferiorGridAgentRef ? RequestGridPowerMessage(
currentSweepNo,
inferiorGridGate.getSuperiorNode.getUuid
inferiorGridGateNode
)).map {
case provideGridPowerMessage: ProvideGridPowerMessage =>
(inferiorGridAgent, Option(provideGridPowerMessage))
(inferiorGridAgentRef, provideGridPowerMessage)
case FailedPowerFlow =>
(inferiorGridAgent, Some(FailedPowerFlow))
}.mapTo[ActorPowerRequestResponse]
})
)
.map(ReceivedGridPowerValues)
.pipeTo(self)
)
else
None
(inferiorGridAgentRef, FailedPowerFlow)
}
}
)
.map(ReceivedGridPowerValues)
.pipeTo(self)
}
}

/** Triggers an execution of the akka `ask` pattern for all slack voltages of
Expand Down Expand Up @@ -1158,32 +1143,30 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport {
s"asking superior grids for slack voltage values: {}",
superiorGridGates
)
if (superiorGridGates.nonEmpty)
Some(
Future
.sequence(
superiorGridGates.map(superiorGridGate => {
val superiorGridAgent = subGridGateToActorRef(superiorGridGate)
(superiorGridAgent ? RequestSlackVoltageMessage(
currentSweepNo,
superiorGridGate.getSuperiorNode.getUuid
)).map(providedSlackValues =>
(superiorGridAgent, Option(providedSlackValues))
).mapTo[(ActorRef, Option[ProvideSlackVoltageMessage])]
})
)
.map(ReceivedSlackValues)
.pipeTo(self)
)
else
None
Option.when(superiorGridGates.nonEmpty) {
Future
.sequence(
superiorGridGates.map(superiorGridGate => {
val superiorGridAgent = subGridGateToActorRef(superiorGridGate)
(superiorGridAgent ? RequestSlackVoltageMessage(
currentSweepNo,
superiorGridGate.getSuperiorNode.getUuid
)).map { case providedSlackValues: ProvideSlackVoltageMessage =>
(superiorGridAgent, providedSlackValues)
}
})
)
.map(ReceivedSlackValues)
.pipeTo(self)
}
}

/** Create an instance of [[PowerFlowResults]] and send it to all listener
* Note: in the future this one could become a bottleneck for power flow
* calculation timesteps. For performance improvements one might consider
* putting this into a future with pipeTo. One has to consider how to deal
* with unfinished futures in shutdown phase then
/** Create an instance of
* [[edu.ie3.simona.event.ResultEvent.PowerFlowResultEvent]] and send it to
* all listener Note: in the future this one could become a bottleneck for
* power flow calculation timesteps. For performance improvements one might
* consider putting this into a future with pipeTo. One has to consider how
* to deal with unfinished futures in shutdown phase then
*
* @param gridAgentBaseData
* the grid agent base data
Expand Down
Loading

0 comments on commit c825a5c

Please sign in to comment.