Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ cython_debug/
*.dbl
*.DBL
.qodo
.DS_Store

# OpenDSS output artifacts (written by tests / writer)
/*.dss
Expand Down
1 change: 1 addition & 0 deletions src/ditto/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
LL_LN_CONVERSION_FACTOR = 1.732
3 changes: 3 additions & 0 deletions src/ditto/enumerations.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ class OpenDSSFileTypes(str, Enum):
COORDINATE_FILE = "BusCoords.dss"
LOADSHAPE_FILE = "LoadShape.dss"
WIRES_FILE = "WireData.dss"
CABLES_FILE = "CableData.dss"
LINE_GEOMETRIES_FILE = "LineGeometry.dss"
LINECODES_FILE = "LineCodes.dss"
SWITCH_CODES_FILE = "SwitchCodes.dss"
FUSE_CODES_FILE = "FuseCodes.dss"
RECLOSER_CODES_FILE = "RecloserCodes.dss"
TRANSFORMERS_FILE = "Transformers.dss"
CAPACITORS_FILE = "Capacitors.dss"
LINES_FILE = "Lines.dss"
LOADS_FILE = "Loads.dss"
SOLAR_FILE = "Solar.dss"
SWITCH_FILE = "Switches.dss"
FUSE_FILE = "Fuses.dss"
RECLOSER_FILE = "Reclosers.dss"
REGULATOR_CONTROLLERS_FILE = "RegControllers.dss"
10 changes: 10 additions & 0 deletions src/ditto/writers/opendss/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
)
from ditto.writers.opendss.equipment.geometry_branch_equipment import GeometryBranchEquipmentMapper
from ditto.writers.opendss.equipment.bare_conductor_equipment import BareConductorEquipmentMapper
from ditto.writers.opendss.equipment.concentric_cable_equipment import (
ConcentricCableEquipmentMapper,
)
from ditto.writers.opendss.components.distribution_capacitor import DistributionCapacitorMapper
from ditto.writers.opendss.components.distribution_load import DistributionLoadMapper
from ditto.writers.opendss.components.distribution_transformer import DistributionTransformerMapper
Expand All @@ -34,3 +37,10 @@
)
from ditto.writers.opendss.profile import ProfileMapper
from ditto.writers.opendss.components.distribution_solar import DistributionSolarMapper

from ditto.writers.opendss.components.matrix_impedance_recloser import (
MatrixImpedanceRecloserMapper,
)
from ditto.writers.opendss.equipment.matrix_impedance_recloser_equipment import (
MatrixImpedanceRecloserEquipmentMapper,
)
6 changes: 3 additions & 3 deletions src/ditto/writers/opendss/components/distribution_branch.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ def __init__(self, model: Component, system: DistributionSystem):
opendss_file = OpenDSSFileTypes.LINES_FILE.value

def map_name(self):
self.opendss_dict["Name"] = self.model.name
self.opendss_dict["Name"] = self.get_opendss_safe_name(self.model.name)

def map_buses(self):
self.opendss_dict["Bus1"] = self.model.buses[0].name
self.opendss_dict["Bus2"] = self.model.buses[1].name
self.opendss_dict["Bus1"] = self.get_opendss_safe_name(self.model.buses[0].name)
self.opendss_dict["Bus2"] = self.get_opendss_safe_name(self.model.buses[1].name)
for phase in self.model.phases:
if phase != Phase.N:
self.opendss_dict["Bus1"] += self.phase_map[phase]
Expand Down
2 changes: 1 addition & 1 deletion src/ditto/writers/opendss/components/distribution_bus.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def __init__(self, model: Component, system: DistributionSystem):
opendss_file = OpenDSSFileTypes.COORDINATE_FILE.value

def map_name(self):
self.opendss_dict["Name"] = self.model.name
self.opendss_dict["Name"] = self.get_opendss_safe_name(self.model.name)

def map_coordinate(self):
if hasattr(self.model.coordinate, "x"):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from ditto.writers.opendss.opendss_mapper import OpenDSSMapper
from ditto.enumerations import OpenDSSFileTypes
from ditto.constants import LL_LN_CONVERSION_FACTOR


class DistributionCapacitorMapper(OpenDSSMapper):
Expand All @@ -19,16 +20,18 @@ def map_in_service(self):
self.opendss_dict["enabled"] = self.model.in_service

def map_name(self):
self.opendss_dict["Name"] = self.model.name
self.opendss_dict["Name"] = self.get_opendss_safe_name(self.model.name)

def map_bus(self):
self.opendss_dict["Bus1"] = self.model.bus.name
self.opendss_dict["Bus1"] = self.get_opendss_safe_name(self.model.bus.name)
num_phases = len(self.model.phases)
for phase in self.model.phases:
self.opendss_dict["Bus1"] += self.phase_map[phase]
# TODO: Should we include the phases its connected to here?
nom_voltage = self.model.bus.rated_voltage.to("kV").magnitude
self.opendss_dict["kV"] = nom_voltage if num_phases == 1 else nom_voltage * 1.732
self.opendss_dict["kV"] = (
nom_voltage if num_phases == 1 else nom_voltage * LL_LN_CONVERSION_FACTOR
)

def map_phases(self):
if (
Expand Down
11 changes: 7 additions & 4 deletions src/ditto/writers/opendss/components/distribution_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from ditto.writers.opendss.opendss_mapper import OpenDSSMapper
from ditto.enumerations import OpenDSSFileTypes
from ditto.constants import LL_LN_CONVERSION_FACTOR


class DistributionLoadMapper(OpenDSSMapper):
Expand All @@ -17,23 +18,25 @@ def __init__(self, model: Component, system: DistributionSystem):
opendss_file = OpenDSSFileTypes.LOADS_FILE.value

def map_in_service(self):
self.opendss_dict["enabled"] = self.model.in_service
self.opendss_dict["Enabled"] = self.model.in_service

def map_name(self):
self.opendss_dict["Name"] = self.model.name
self.opendss_dict["Name"] = self.get_opendss_safe_name(self.model.name)

profile_name = self.get_profile_name(self.model)
if profile_name:
self.opendss_dict["Yearly"] = profile_name

def map_bus(self):
num_phases = len(self.model.phases)
self.opendss_dict["Bus1"] = self.model.bus.name
self.opendss_dict["Bus1"] = self.get_opendss_safe_name(self.model.bus.name)
for phase in self.model.phases:
self.opendss_dict["Bus1"] += self.phase_map[phase]
# TODO: Should we include the phases its connected to here?
nom_voltage = self.model.bus.rated_voltage.to("kV").magnitude
self.opendss_dict["kV"] = nom_voltage if num_phases == 1 else nom_voltage * 1.732
self.opendss_dict["kV"] = (
nom_voltage if num_phases == 1 else nom_voltage * LL_LN_CONVERSION_FACTOR
)

def map_phases(self):
if (
Expand Down
10 changes: 5 additions & 5 deletions src/ditto/writers/opendss/components/distribution_regulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ def __init__(self, model: Component, system: DistributionSystem):
opendss_file = OpenDSSFileTypes.TRANSFORMERS_FILE.value

def map_in_service(self):
self.opendss_dict["enabled"] = self.model.in_service
self.opendss_dict["Enabled"] = self.model.in_service

def map_name(self):
self.opendss_dict["Name"] = self.model.name
self.opendss_dict["Name"] = self.get_opendss_safe_name(self.model.name)

def map_buses(self):
buses = []
Expand All @@ -27,7 +27,7 @@ def map_buses(self):
if is_center_tapped:
for i in range(len(self.model.buses)):
bus = self.model.buses[i]
buses.append(bus.name)
buses.append(self.get_opendss_safe_name(bus.name))
dss_phases = ""
for phase in self.model.winding_phases[0]:
dss_phases += self.phase_map[phase]
Expand All @@ -37,7 +37,7 @@ def map_buses(self):

else:
for bus in self.model.buses:
buses.append(bus.name)
buses.append(self.get_opendss_safe_name(bus.name))
for winding_phases in self.model.winding_phases:
dss_phases = ""
for phase in winding_phases:
Expand All @@ -54,7 +54,7 @@ def map_winding_phases(self):

def map_equipment(self):
equipment = self.model.equipment
self.opendss_dict["XfmrCode"] = equipment.name
self.opendss_dict["XfmrCode"] = self.get_opendss_safe_name(equipment.name)

def map_controllers(self):
...
11 changes: 7 additions & 4 deletions src/ditto/writers/opendss/components/distribution_solar.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from ditto.writers.opendss.opendss_mapper import OpenDSSMapper
from ditto.enumerations import OpenDSSFileTypes
from ditto.constants import LL_LN_CONVERSION_FACTOR


class DistributionSolarMapper(OpenDSSMapper):
Expand All @@ -15,23 +16,25 @@ def __init__(self, model: DistributionSolar, system: DistributionSystem):
opendss_file = OpenDSSFileTypes.SOLAR_FILE.value

def map_in_service(self):
self.opendss_dict["enabled"] = self.model.in_service
self.opendss_dict["Enabled"] = self.model.in_service

def map_name(self):
self.opendss_dict["Name"] = self.model.name
self.opendss_dict["Name"] = self.get_opendss_safe_name(self.model.name)

profile_name = self.get_profile_name(self.model)
if profile_name:
self.opendss_dict["Yearly"] = profile_name

def map_bus(self):
num_phases = len(self.model.phases)
self.opendss_dict["Bus1"] = self.model.bus.name
self.opendss_dict["Bus1"] = self.get_opendss_safe_name(self.model.bus.name)
for phase in self.model.phases:
self.opendss_dict["Bus1"] += self.phase_map[phase]
# TODO: Should we include the phases its connected to here?
nom_voltage = self.model.bus.rated_voltage.to("kV").magnitude
self.opendss_dict["kV"] = nom_voltage if num_phases == 1 else nom_voltage * 1.732
self.opendss_dict["kV"] = (
nom_voltage if num_phases == 1 else nom_voltage * LL_LN_CONVERSION_FACTOR
)

def map_phases(self):
self.opendss_dict["Phases"] = len(self.model.phases)
Expand Down
10 changes: 5 additions & 5 deletions src/ditto/writers/opendss/components/distribution_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ def __init__(self, model: Component, system: DistributionSystem):
opendss_file = OpenDSSFileTypes.TRANSFORMERS_FILE.value

def map_in_service(self):
self.opendss_dict["enabled"] = self.model.in_service
self.opendss_dict["Enabled"] = self.model.in_service

def map_name(self):
self.opendss_dict["Name"] = self.model.name
self.opendss_dict["Name"] = self.get_opendss_safe_name(self.model.name)

def map_buses(self):
buses = []
Expand All @@ -28,7 +28,7 @@ def map_buses(self):
if is_center_tapped:
for i in range(len(self.model.buses)):
bus = self.model.buses[i]
buses.append(bus.name)
buses.append(self.get_opendss_safe_name(bus.name))
dss_phases = ""
for phase in self.model.winding_phases[0]:
dss_phases += self.phase_map[phase]
Expand All @@ -38,7 +38,7 @@ def map_buses(self):

else:
for bus in self.model.buses:
buses.append(bus.name)
buses.append(self.get_opendss_safe_name(bus.name))
for winding_phases in self.model.winding_phases:
dss_phases = ""
for phase in winding_phases:
Expand All @@ -55,4 +55,4 @@ def map_winding_phases(self):

def map_equipment(self):
equipment = self.model.equipment
self.opendss_dict["XfmrCode"] = equipment.name
self.opendss_dict["XfmrCode"] = self.get_opendss_safe_name(equipment.name)
23 changes: 17 additions & 6 deletions src/ditto/writers/opendss/components/distribution_vsource.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from ditto.writers.opendss.opendss_mapper import OpenDSSMapper
from ditto.enumerations import OpenDSSFileTypes
from ditto.constants import LL_LN_CONVERSION_FACTOR


class DistributionVoltageSourceMapper(OpenDSSMapper):
Expand All @@ -16,17 +17,17 @@ def __init__(self, model: Component, system: DistributionSystem):
opendss_file = OpenDSSFileTypes.MASTER_FILE.value

def map_in_service(self):
self.opendss_dict["enabled"] = self.model.in_service
self.opendss_dict["Enabled"] = self.model.in_service

def map_name(self):
self.opendss_dict["Name"] = self.model.name
self.opendss_dict["Name"] = self.get_opendss_safe_name(self.model.name)

profile_name = self.get_profile_name(self.model)
if profile_name:
self.opendss_dict["Yearly"] = profile_name

def map_bus(self):
self.opendss_dict["Bus1"] = self.model.bus.name
self.opendss_dict["Bus1"] = self.get_opendss_safe_name(self.model.bus.name)
for phase in self.model.phases:
self.opendss_dict["Bus1"] += self.phase_map[phase]

Expand Down Expand Up @@ -64,14 +65,24 @@ def map_equipment(self):
if num_phases == 1:
v_mag = voltage.magnitude
else:
v_mag = voltage.magnitude * 1.732
v_mag = voltage.magnitude * LL_LN_CONVERSION_FACTOR
else:
if num_phases == 1:
v_mag = voltage.magnitude / 1.732
v_mag = voltage.magnitude / LL_LN_CONVERSION_FACTOR
else:
v_mag = voltage.magnitude

v_nom = rated_voltage.magnitude if num_phases == 1 else rated_voltage.magnitude * 1.732
if self.model.bus.voltage_type == VoltageTypes.LINE_TO_GROUND:
if num_phases == 1:
v_nom = rated_voltage.magnitude
else:
v_nom = rated_voltage.magnitude * LL_LN_CONVERSION_FACTOR
else:
if num_phases == 1:
v_nom = rated_voltage.magnitude / LL_LN_CONVERSION_FACTOR
else:
v_nom = rated_voltage.magnitude
Comment thread
zzink-nrel marked this conversation as resolved.

self.opendss_dict["Angle"] = angle.magnitude
self.opendss_dict["pu"] = v_mag / v_nom
self.opendss_dict["BasekV"] = v_nom
Expand Down
5 changes: 4 additions & 1 deletion src/ditto/writers/opendss/components/geometry_branch.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ def __init__(self, model: Component, system: DistributionSystem):
altdss_composition_name = "Line"
opendss_file = OpenDSSFileTypes.LINES_FILE.value

def map_name(self):
self.opendss_dict["Name"] = self.get_opendss_safe_name(self.model.name)

def map_equipment(self):
self.opendss_dict["Geometry"] = self.model.equipment.name
self.opendss_dict["Geometry"] = self.get_opendss_safe_name(self.model.equipment.name)

def map_in_service(self):
self.opendss_dict["enabled"] = self.model.in_service
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ def __init__(self, model: Component, system: DistributionSystem):
altdss_composition_name = "Line"
opendss_file = OpenDSSFileTypes.LINES_FILE.value

def map_name(self):
self.opendss_dict["Name"] = self.get_opendss_safe_name(self.model.name)

def map_equipment(self):
self.opendss_dict["LineCode"] = self.model.equipment.name
self.opendss_dict["LineCode"] = self.get_opendss_safe_name(self.model.equipment.name)

def map_in_service(self):
self.opendss_dict["enabled"] = self.model.in_service
11 changes: 9 additions & 2 deletions src/ditto/writers/opendss/components/matrix_impedance_fuse.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,16 @@ def __init__(self, model: Component, system: DistributionSystem):
altdss_composition_name = "Line"
opendss_file = OpenDSSFileTypes.FUSE_FILE.value

def map_name(self):
self.opendss_dict["Name"] = self.get_opendss_safe_name(self.model.name)

def map_equipment(self):
self.opendss_dict["LineCode"] = self.model.equipment.name
self.opendss_dict["LineCode"] = self.get_opendss_safe_name(self.model.equipment.name)

def map_is_closed(self):
# Require every phase to be enabled for the OpenDSS line to be enabled.
self.opendss_dict["Switch"] = "true"
self.opendss_dict["Switch"] = True

def map_in_service(self):
if not self.model.in_service:
self.opendss_dict["Enabled"] = False
31 changes: 31 additions & 0 deletions src/ditto/writers/opendss/components/matrix_impedance_recloser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from gdm.distribution import DistributionSystem
from infrasys import Component


from ditto.writers.opendss.components.distribution_branch import DistributionBranchMapper
from ditto.enumerations import OpenDSSFileTypes


class MatrixImpedanceRecloserMapper(DistributionBranchMapper):
def __init__(self, model: Component, system: DistributionSystem):
super().__init__(model, system)

altdss_name = "Line_LineCode"
altdss_composition_name = "Line"
opendss_file = OpenDSSFileTypes.RECLOSER_FILE.value

def map_name(self):
self.opendss_dict["Name"] = self.get_opendss_safe_name(self.model.name)

def map_equipment(self):
self.opendss_dict["LineCode"] = self.get_opendss_safe_name(self.model.equipment.name)

def map_is_closed(self):
# Require every phase to be enabled for the OpenDSS line to be enabled.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Shouldn't this be a switch by default, and the is_closed be covered by in_service?
How is in_service different from is_closed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think it's good to question this. I did not and just copied what's here from the matrix_impedance_switch mapper.

self.opendss_dict["Switch"] = True

def map_in_service(self):
self.opendss_dict["Enabled"] = self.model.in_service

def map_controller(self):
pass
Loading