Mapping Equipment#

You will need to extend exsiting equipment mapper class to map equipment to nodes and edges depending on your need.

Here is an example where EdgeEquipmentMapper is extended to map equipment to nodes and assets. EdgeEquipmentMapper takes care of mapping equipment to edges (both transformer and branch) from a given catalog. You can use any valid DistributionSystem as catalog. Here we are using p4u.json file (which was created using ditto reader by passing P4U SMARTDS models.) as catalog file. We are mapping load kW based on parcels area in this example. Assuming points are already available.

from shift import (
    EdgeEquipmentMapper, 
    BaseVoltageMapper,
    BasePhaseMapper,
    ParcelModel,
    GeoLocation
)

from gdm import (
    DistributionGraph,
    LoadEquipment,
    PhaseLoadEquipment,
    PhaseVoltageSourceEquipment,
    VoltageSourceEquipment
)
from gdm.quantities import (
    ReactivePower,
    Reactance
)

from infrasys import System
from infrasys.quantities import ActivePower, Resistance, Voltage, Angle

catalog_sys = DistributionSystem.from_json("p4u.json")

class AreaBasedLoadMapper(EdgeEquipmentMapper):

    def __init__(
        self,
        graph: DistributionGraph,
        catalog_sys: System,
        voltage_mapper: BaseVoltageMapper,
        phase_mapper: BasePhaseMapper,
        points: list[ParcelModel],
    ):

        self.points = points
        super().__init__(graph, catalog_sys, voltage_mapper, phase_mapper)

    def _get_area_for_node(self, node: NodeModel) -> float:
        """Internal function to return point"""
        tree = KDTree(_get_parcel_points(self.points))
        _, idx = tree.query([GeoLocation(node.location.x, node.location.y)], k=1)
        first_indexes = [el[0] for el in idx]
        nearest_point: ParcelModel = self.points[first_indexes[0]]
        return (
            Polygon(nearest_point.geometry).area if isinstance(nearest_point.geometry, list) else 0
        )

    @cached_property
    def node_asset_equipment_mapping(self):
        node_equipment_dict = {}

        for node in self.graph.get_nodes():
            node_equipment_dict[node.name] = {}
            area = self._get_area_for_node(node)
            if area > 10 and area < 30:
                kw = 1.2
            elif area <= 10:
                kw = 0.8
            else:
                kw = 1.3

            num_phase = len(self.phase_mapper.node_phase_mapping[node.name] - set(Phase.N))
            node_equipment_dict[node.name][DistributionLoad] = LoadEquipment(
                name=f"load_{node.name}",
                phase_loads=[
                    PhaseLoadEquipment(
                        name=f"load_{node.name}_{idx}",
                        z_real=ActivePower(0, "kilowatt"),
                        i_real=ActivePower(0, "kilowatt"),
                        p_real=ActivePower(kw / num_phase, "kilowatt"),
                        z_imag=ReactivePower(0, "kilovar"),
                        i_imag=ReactivePower(0, "kilovar"),
                        p_imag=ReactivePower(0, "kilovar"),
                    )
                    for idx in range(num_phase)
                ],
            )

            if DistributionVoltageSource in node.assets:
                node_equipment_dict[node.name][DistributionVoltageSource] = VoltageSourceEquipment(
                    name="vsource_test",
                    sources=[
                        PhaseVoltageSourceEquipment(
                            name=f"vsource_{idx}",
                            r0=Resistance(1e-5, "ohm"),
                            r1=Resistance(1e-5, "ohm"),
                            x0=Reactance(1e-5, "ohm"),
                            x1=Reactance(1e-5, "ohm"),
                            voltage=Voltage(27, "kilovolt"),
                            angle=Angle(0, "degree"),
                        )
                        for idx in range(3)
                    ],
                )

        return node_equipment_dict


eq_mapper = AreaBasedLoadMapper(
    new_graph,
    catalog_sys=catalog_sys,
    voltage_mapper=voltage_mapper,
    phase_mapper=phase_mapper,
    points=points,
)