Skip to content

Commit

Permalink
Merge pull request #157 from ie3-institute/to/#151-handle-line-sections
Browse files Browse the repository at this point in the history
Handle line sections
  • Loading branch information
sebastian-peter authored Jan 4, 2022
2 parents 1a82810 + 319b347 commit bd65309
Show file tree
Hide file tree
Showing 14 changed files with 345 additions and 37 deletions.
2 changes: 1 addition & 1 deletion src/main/python/powerFactory2json/pf2json.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def get_attribute_dicts(raw_elements, attributes_to_include):
elements = []
single_node_connection = ["ElmLod", "ElmLodlv", "ElmLodmv", "ElmPvsys", "ElmSym", "ElmGenstat", "ElmXnet"]
edges = ["ElmLne", "ElmCoup"]
typed_models = ["ElmLne", "ElmTr2"]
typed_models = ["ElmLne", "ElmTr2", "ElmLnesec"]
for raw_element in raw_elements:
element_class = raw_element.GetClassName()
element = get_attribute_dict(raw_element, attributes_to_include)
Expand Down
9 changes: 7 additions & 2 deletions src/main/python/powerFactory2json/pf2jsonUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@
'extGrid': '*.ElmXnet',
'powerPlants': '*.ElmSym', # renewable power plants
'pvs': '*.ElmPvsys', # additional photovoltaic units
'switches': '*.ElmCoup'
'switches': '*.ElmCoup',
'lineSections': '*.ElmLnesec'
}


attributes4export = {
'lineSections': [
"dline"
],
'conElms': [],
'nodes': [
"vtarget",
Expand All @@ -27,7 +31,8 @@
],
'lines': [
"dline",
"GPScoords"
"GPScoords",
"cubsecs"
],
'lineTypes': [
"rline",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import edu.ie3.datamodel.models.input.connector.`type`.LineTypeInput
import edu.ie3.datamodel.models.input.system.characteristic.OlmCharacteristicInput
import edu.ie3.datamodel.utils.GridAndGeoUtils
import edu.ie3.powerFactory2psdm.converter.NodeConverter.getNode
import edu.ie3.powerFactory2psdm.converter.types.LineTypeConverter
import edu.ie3.powerFactory2psdm.converter.types.LineTypeConverter.getLineType
import edu.ie3.powerFactory2psdm.exception.pf.ConversionException
import edu.ie3.powerFactory2psdm.model.entity.Line
Expand Down Expand Up @@ -44,34 +45,51 @@ object LineConverter {
lineTypes: Map[String, LineTypeInput]
): List[LineInput] = {
lines.map(line => {
/*
Here we check if this is a line with line section and therefore multiple line types in which case we create an
averaged line type. If it isn't we just retrieve the line sections from the converted line types.
*/
val lineType = (line.typeId, line.lineSections) match {
case (_, Some(lineSections)) =>
LineTypeConverter.convert(
line.id,
line.length,
lineSections,
lineTypes
)
case (Some(lineTypeId), None) =>
getLineType(lineTypeId, lineTypes).getOrElse(
throw ConversionException(
s"Could not convert line: $line due to failed line type retrieval."
)
)
case (None, None) =>
throw ConversionException(
s"Could not convert line: ${line.id} since there is no defined type in the model and there are no line section that specify the type"
)
}
(
getNode(line.nodeAId, nodes),
getNode(line.nodeBId, nodes),
getLineType(line.typeId, lineTypes)
getNode(line.nodeBId, nodes)
) match {
case (Success(nodeA), Success(nodeB), Success(lineType)) =>
convert(
case (Success(nodeA), Success(nodeB)) =>
LineConverter.convert(
line,
lineLengthPrefix,
lineType,
nodeA,
nodeB
)
case (Failure(exc), _, _) =>
case (Failure(exc), _) =>
throw ConversionException(
s"Can't retrieve ${line.nodeAId} for line ${line.id}",
exc
)
case (_, Failure(exc), _) =>
case (_, Failure(exc)) =>
throw ConversionException(
s"Can't retrieve ${line.nodeBId} for line ${line.id}",
exc
)
case (_, _, Failure(exc)) =>
throw ConversionException(
s"Could not convert line: $line due to failed line type retrieval.",
exc
)
}
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@
*/

package edu.ie3.powerFactory2psdm.converter.types
import com.typesafe.scalalogging.LazyLogging
import edu.ie3.datamodel.models.input.connector.`type`.LineTypeInput
import edu.ie3.powerFactory2psdm.exception.pf.ConversionException
import edu.ie3.powerFactory2psdm.model.entity.{Line, LineSection}
import edu.ie3.powerFactory2psdm.model.entity.types.LineType
import edu.ie3.powerFactory2psdm.util.QuantityUtils.RichQuantityDouble

import java.util.UUID
import scala.math.abs
import scala.util.{Failure, Success, Try}

/** Functionality to translate a [[LineType]] to a [[LineTypeInput]]
*/
object LineTypeConverter {
object LineTypeConverter extends LazyLogging {

def convert(input: LineType): LineTypeInput = {

Expand All @@ -31,6 +34,85 @@ object LineTypeConverter {
)
}

/** In PowerFactory lines can be made up of line sections. We convert them to
* a single line by using the aggregated length of the line sections and
* generate a line type by calculating the weighted (by line length) average
* of the parameters.
*
* @param lineId
* name of the line made up of line sections
* @param lineLength
* the noted length of the line
* @param lineSections
* a list of the line sections
* @param lineTypes
* mapping of line types
* @return
* the averaged line type as [[LineTypeInput]]
*/
def convert(
lineId: String,
lineLength: Double,
lineSections: List[LineSection],
lineTypes: Map[String, LineTypeInput]
): LineTypeInput = {

val aggregatedLineSectionLength =
lineSections.map(section => section.length).sum

// sanity check of total line length versus aggregated line length of all corresponding line sections
lineLength - aggregatedLineSectionLength match {
case x if abs(x) < 1e-9 =>
case x if x < 0 =>
logger.error(
s"The line length of line: $lineId is smaller than the aggregated length of line sections by ${(1 - (lineLength / aggregatedLineSectionLength)) * 100}% which distorts results. This should be prevented by PF and therefore not happen."
)
case x if x > 0 =>
logger.error(
s"The line length of line: $lineId is greater than the aggregated length of line sections by ${((lineLength / aggregatedLineSectionLength) - 1) * 100}% which distorts results. This should be prevented by PF and therefore not happen."
)
}

val weightedLineTypes = lineSections.map(section => {
val lineType = getLineType(section.typeId, lineTypes)
.getOrElse(
throw ConversionException(
s"Can't find line type ${section.typeId} of section ${section.id} within the converted line types."
)
)
(section.length, lineType)
})
val emptyLineType = new LineTypeInput(
UUID.randomUUID(),
"Custom_line_type_" + lineId,
0.asMicroSiemensPerKilometre,
0.asMicroSiemensPerKilometre,
0.asOhmPerKilometre,
0.asOhmPerKilometre,
Double.MaxValue.asKiloAmpere,
Double.MaxValue.asKiloVolt
)

weightedLineTypes.foldLeft(emptyLineType)((averageType, current) => {
val currentLine = current._2
val weightingFactor = current._1 / lineLength
new LineTypeInput(
averageType.getUuid,
averageType.getId,
averageType.getB.add(currentLine.getB.multiply(weightingFactor)),
averageType.getG.add(currentLine.getG.multiply(weightingFactor)),
averageType.getR.add(currentLine.getR.multiply(weightingFactor)),
averageType.getX.add(currentLine.getX.multiply(weightingFactor)),
if (averageType.getiMax().isLessThan(currentLine.getiMax()))
averageType.getiMax()
else currentLine.getiMax(),
if (averageType.getvRated().equals(Double.MaxValue.asKiloVolt))
currentLine.getvRated()
else averageType.getvRated()
)
})
}

def getLineType(
id: String,
lineTypes: Map[String, LineTypeInput]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import edu.ie3.powerFactory2psdm.exception.pf.{
MissingParameterException
}
import edu.ie3.powerFactory2psdm.model.RawPfGridModel.{
LineSections,
LineTypes,
Lines,
Loads,
Expand All @@ -28,6 +29,7 @@ import edu.ie3.powerFactory2psdm.model.RawPfGridModel.{
}
import edu.ie3.powerFactory2psdm.model.entity.{
Line,
LineSection,
Load,
Node,
StaticGenerator,
Expand Down Expand Up @@ -108,6 +110,10 @@ object PreprocessedPfGridModel extends LazyLogging {
logger debug "There are no lines in the grid."
List.empty[LineTypes]
})
val rawLineSections = rawGrid.lineSections.getOrElse({
logger debug "There are no line sections in the grid."
List.empty[LineSections]
})
val rawSwitches = rawGrid.switches.getOrElse({
logger debug "There are no switches in the grid."
List.empty[Switches]
Expand All @@ -129,7 +135,7 @@ object PreprocessedPfGridModel extends LazyLogging {
})

val models =
rawNodes ++ rawLines ++ rawLineTypes ++ rawSwitches ++ rawTrafos2W ++ rawTrafoTpyes2W ++ rawLoads ++ rawStaticGenerators
rawNodes ++ rawLines ++ rawLineTypes ++ rawLineSections ++ rawSwitches ++ rawTrafos2W ++ rawTrafoTpyes2W ++ rawLoads ++ rawStaticGenerators
val modelIds = models.map {
case node: Nodes =>
node.id.getOrElse(
Expand All @@ -145,6 +151,12 @@ object PreprocessedPfGridModel extends LazyLogging {
s"Line type $lineType has no defined id"
)
)
case lineSection: LineSections =>
lineSection.id.getOrElse(
throw MissingParameterException(
s"Line section $lineSection has no defined id"
)
)
case switch: Switches =>
switch.id.getOrElse(
throw MissingParameterException(s"Switch $switch has no defined id")
Expand Down Expand Up @@ -195,7 +207,8 @@ object PreprocessedPfGridModel extends LazyLogging {
}

val nodes = rawNodes.map(Node.build)
val lines = rawLines.map(line => Line.build(line))
val lineSectionsMap = LineSection.buildLineSectionMap(rawLineSections)
val lines = rawLines.map(line => Line.build(line, lineSectionsMap))
val lineTypes = rawLineTypes.map(LineType.build)
val switches = rawSwitches.flatMap(Switch.maybeBuild)
val transformers2W = rawTrafos2W.map(Transformer2W.build)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import edu.ie3.powerFactory2psdm.model.RawPfGridModel.{
ExtGrid,
PowerPlants,
Trafos3w,
LineSections,
Lines,
Pvs,
Switches,
Expand All @@ -29,6 +30,7 @@ final case class RawPfGridModel(
loadsMV: Option[List[LoadsMV]],
nodes: Option[List[Nodes]],
projectSettings: Option[List[ProjectSettings]],
lineSections: Option[List[LineSections]],
powerPlants: Option[List[PowerPlants]],
trafoTypes3w: Option[List[TrafoTypes3w]],
pvs: Option[List[Pvs]],
Expand All @@ -52,8 +54,6 @@ object RawPfGridModel {
bus2Id: Option[String]
)

final case class Pvs()

final case class ConElms(id: Option[String], pfCls: Option[String])

final case class Loads(
Expand Down Expand Up @@ -102,6 +102,14 @@ object RawPfGridModel {

final case class ExtGrid(id: Option[String], busId: Option[String])

final case class LineSections(
id: Option[String],
dline: Option[Double],
typeId: Option[String]
)

final case class Pvs()

final case class TrafoTypes2w(
utrnH: Option[Double],
nntap0: Option[Double],
Expand Down
27 changes: 18 additions & 9 deletions src/main/scala/edu/ie3/powerFactory2psdm/model/entity/Line.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,31 @@ import edu.ie3.powerFactory2psdm.model.RawPfGridModel.Lines
* id of connected node
* @param nodeBId
* id of connected node
* @param typeId
* id of the corresponding line type
* @param lineSections
* optional list of line sections the line consists of
* @param length
* length of the line
* @param gpsCoords
* optional list of gps coordinates of geo position of the line
*/
final case class Line(
id: String,
nodeAId: String,
nodeBId: String,
typeId: String,
typeId: Option[String],
lineSections: Option[List[LineSection]],
length: Double,
gpsCoords: Option[(List[(Double, Double)])]
gpsCoords: Option[List[(Double, Double)]]
) extends EntityModel
with Edge

object Line {
def build(rawLine: Lines): Line = {
def build(
rawLine: Lines,
lineSectionsMap: Map[String, List[LineSection]]
): Line = {
val id = rawLine.id.getOrElse(
throw MissingParameterException(s"There is no id for line $rawLine")
)
Expand All @@ -39,12 +51,8 @@ object Line {
val nodeBId = rawLine.bus2Id.getOrElse(
throw MissingParameterException(s"Line: $id has no defined node b")
)
val typId = rawLine.typeId.getOrElse(
throw MissingParameterException(
s"Line: $id has no defined type - line conversion without defined type" +
s" is not supported "
)
)
val typId = rawLine.typeId
val lineSections = lineSectionsMap.get(id)
val length = rawLine.dline.getOrElse(
throw MissingParameterException(
s"Line: $id has no defined length"
Expand All @@ -65,6 +73,7 @@ object Line {
nodeAId,
nodeBId,
typId,
lineSections,
length,
gpsCoords
)
Expand Down
Loading

0 comments on commit bd65309

Please sign in to comment.