Skip to content

Commit

Permalink
Merge branch 'to/#261-participant-adaptions' into freiamt-conversion
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/main/scala/edu/ie3/powerFactory2psdm/converter/LoadConverter.scala
#	src/main/scala/edu/ie3/powerFactory2psdm/generator/PvInputGenerator.scala
  • Loading branch information
t-ober committed Jan 26, 2023
2 parents 9080b9c + 564b3ed commit e17cf61
Show file tree
Hide file tree
Showing 8 changed files with 386 additions and 18 deletions.
1 change: 1 addition & 0 deletions .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
version = 2.7.5
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

package edu.ie3.powerFactory2psdm.converter

import edu.ie3.datamodel.models.StandardUnits
import edu.ie3.datamodel.models.input.system.characteristic.ReactivePowerCharacteristic
import edu.ie3.powerFactory2psdm.config.ConversionConfigUtils.{
DependentQCharacteristic,
Expand All @@ -14,7 +15,10 @@ import edu.ie3.powerFactory2psdm.config.ConversionConfigUtils.{
}
import edu.ie3.powerFactory2psdm.exception.pf.ElementConfigurationException
import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator
import edu.ie3.util.quantities.PowerSystemUnits
import tech.units.indriya.ComparableQuantity

import javax.measure.quantity.Power
import scala.util.{Failure, Success, Try}

/** Utility object to hold utility functions for model converison
Expand Down Expand Up @@ -43,6 +47,24 @@ object ConversionHelper {
ReactivePowerCharacteristic.parse(characteristic)
}

/** Specified cosinus phi with respect to the grid regulations (VDE-AR-N 4105)
*
* @param sRated
* rated power of the infeed system
* @return
* cosinus phi for the infeed system
*/
def lvGenerationCosPhi(sRated: ComparableQuantity[Power]): Double = {
val power =
sRated.to(PowerSystemUnits.KILOVOLTAMPERE).getValue.doubleValue()
if (power <= 3.86)
1d
else if ((3.86 < power) && (power <= 13.8))
0.95
else
0.9
}

/** Determines the cos phi rated of a static generator
*
* @param input
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,12 @@ package edu.ie3.powerFactory2psdm.converter

import com.typesafe.scalalogging.LazyLogging
import edu.ie3.datamodel.models.OperationTime
import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput}
import edu.ie3.datamodel.models.input.system.LoadInput
import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed
import edu.ie3.datamodel.models.profile.{
BdewStandardLoadProfile,
LoadProfile,
NbwTemperatureDependantLoadProfile
}
import edu.ie3.powerFactory2psdm.exception.pf.ElementConfigurationException
import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput}
import edu.ie3.datamodel.models.profile.{BdewStandardLoadProfile, LoadProfile, NbwTemperatureDependantLoadProfile}
import edu.ie3.powerFactory2psdm.converter.NodeConverter.getNode
import edu.ie3.powerFactory2psdm.exception.pf.ConversionException
import edu.ie3.powerFactory2psdm.exception.pf.{ConversionException, ElementConfigurationException}
import edu.ie3.powerFactory2psdm.model.entity.Load
import edu.ie3.powerFactory2psdm.util.QuantityUtils.RichQuantityDouble

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,18 @@ package edu.ie3.powerFactory2psdm.generator

import edu.ie3.datamodel.models.input.NodeInput
import edu.ie3.datamodel.models.input.system.PvInput
import edu.ie3.datamodel.models.input.system.characteristic.ReactivePowerCharacteristic
import edu.ie3.powerFactory2psdm.config.model.PvConversionConfig.PvModelGeneration
import edu.ie3.powerFactory2psdm.converter.ConversionHelper.{
convertQCharacteristic,
determineCosPhiRated
}
import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator
import edu.ie3.powerFactory2psdm.util.QuantityUtils.RichQuantityDouble
import edu.ie3.powerFactory2psdm.util.RandomSampler.sample
import edu.ie3.util.quantities.PowerSystemUnits.{DEGREE_GEOM, MEGAVOLTAMPERE}
import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble
import tech.units.indriya.ComparableQuantity
import tech.units.indriya.quantity.Quantities
import tech.units.indriya.unit.Units.PERCENT

import java.util.UUID
import javax.measure.quantity.{Angle, Dimensionless, Power}
import javax.measure.quantity.Power

object PvInputGenerator {

Expand All @@ -44,21 +40,52 @@ object PvInputGenerator {
input: StaticGenerator,
node: NodeInput,
params: PvModelGeneration
): PvInput = {
generate(
node,
input.id,
input.sRated.asKiloVoltAmpere,
determineCosPhiRated(input),
params
)
}

/** Generates a [[PvInput]]
*
* @param id
* name of the pv plant
* @param power
* rated power of the pv plant
* @param cosPhi
* cosPhi of the pv plant
* @param node
* the node the input is connected to
* @param params
* parameters for generating missing parameters
* @return
* a [[PvInput]]
*/
def generate(
node: NodeInput,
id: String,
power: ComparableQuantity[Power],
cosPhi: Double,
params: PvModelGeneration
): PvInput = {
val albedo = sample(params.albedo)
val azimuth = sample(params.azimuth).asDegreeGeom
val etaConv = sample(params.etaConv).asPercent
val height = sample(params.elevationAngle).asDegreeGeom
val kG = sample(params.kG)
val kT = sample(params.kT)
val sRated = input.sRated.asKiloVoltAmpere
val cosPhiRated = determineCosPhiRated(input)
val sRated = power
val cosPhiRated = cosPhi
val qCharacteristics =
convertQCharacteristic(params.qCharacteristic, cosPhiRated)

new PvInput(
UUID.randomUUID(),
input.id,
id,
node,
qCharacteristics,
albedo,
Expand All @@ -72,5 +99,4 @@ object PvInputGenerator {
cosPhiRated
)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* © 2023. TU Dortmund University,
* Institute of Energy Systems, Energy Efficiency and Energy Economics,
* Research group Distribution grid planning and operation
*/

package edu.ie3.powerFactory2psdm.util

import com.typesafe.scalalogging.LazyLogging
import edu.ie3.datamodel.models.input.container.{
JointGridContainer,
SystemParticipants
}
import edu.ie3.datamodel.models.input.system.LoadInput
import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed
import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile
import edu.ie3.powerFactory2psdm.config.model.PvConversionConfig.PvModelGeneration
import edu.ie3.powerFactory2psdm.converter.ConversionHelper.lvGenerationCosPhi
import edu.ie3.powerFactory2psdm.generator.PvInputGenerator
import edu.ie3.powerFactory2psdm.util.ParticipantInformation.Participants
import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble

import java.util.{Locale, UUID}
import scala.jdk.CollectionConverters.{IterableHasAsScala, SetHasAsJava}

object ParticipantAdjustments extends LazyLogging {

def adjust(
jgc: JointGridContainer,
nodalParticipantInfo: Map[
String,
Map[Participants.Value, ParticipantInformation]
],
pvModelGeneration: PvModelGeneration
): JointGridContainer = {
val nodes = jgc.getRawGrid.getNodes.asScala
val nodesMap = nodes.map(node => node.getId -> node).toMap
val oldSystemParticipants = jgc.getSystemParticipants
val updatedParticipants = nodalParticipantInfo.foldLeft(
oldSystemParticipants
)((systemParticipants, mapEntry) => {
val (id, participantInfos) = mapEntry
val node = nodesMap.getOrElse(
id,
throw new NoSuchElementException(s"Node with id $id not found")
)
participantInfos.foldLeft(systemParticipants)((sp, info) => {
val (participant, participantInfo) = info
participant match {
case Participants.LOAD =>
val oldLoads = sp.getLoads.asScala.filter(_.getNode == node)
val cosPhi = oldLoads.map(_.getCosPhiRated).sum / oldLoads.size
val oldSRated =
oldLoads.map(_.getsRated()).reduce((a, b) => a.add(b))
val newLoads = (0 until participantInfo.count).map(count => {
val energy = 3500d.asKiloWattHour
val varCharacteristicString =
"cosPhiFixed:{(0.0,%#.2f)}".formatLocal(Locale.ENGLISH, cosPhi)
val sRated = oldSRated.divide(participantInfo.count)
new LoadInput(
UUID.randomUUID(),
id + f"-Load-$count",
node,
new CosPhiFixed(varCharacteristicString),
BdewStandardLoadProfile.H0,
false,
energy,
sRated,
cosPhi
)
})
val updatedLoads =
sp.getLoads.asScala.filter(_.getNode != node) ++ newLoads
new SystemParticipants(
sp.getBmPlants,
sp.getChpPlants,
sp.getEvCS,
sp.getEvs,
sp.getFixedFeedIns,
sp.getHeatPumps,
updatedLoads.toSet.asJava,
sp.getPvPlants,
sp.getStorages,
sp.getWecPlants,
sp.getEmSystems
)

case Participants.PV =>
val newPvs = (0 until participantInfo.count).map(count => {
val power = participantInfo.power.divide(participantInfo.count)
PvInputGenerator.generate(
node,
id + s"-PV-$count",
power,
lvGenerationCosPhi(power),
pvModelGeneration
)
})
val updatedPvs = sp.getPvPlants.asScala
.filter(_.getNode != node) ++ newPvs
new SystemParticipants(
sp.getBmPlants,
sp.getChpPlants,
sp.getEvCS,
sp.getEvs,
sp.getFixedFeedIns,
sp.getHeatPumps,
sp.getLoads,
updatedPvs.toSet.asJava,
sp.getStorages,
sp.getWecPlants,
sp.getEmSystems
)
case participant: Participants.Value =>
logger.warn(
s"Handling $participant adjustment information not supported yet. Skipping ..."
)
sp
}
})
})
new JointGridContainer(
jgc.getGridName,
jgc.getRawGrid,
updatedParticipants,
jgc.getGraphics,
jgc.getSubGridTopologyGraph
)
}
}
Loading

0 comments on commit e17cf61

Please sign in to comment.