Recent Feature Additions#

Version 2.1.5#

Graph bug fix#

The graphs returned from GDM are type MultiGraph and MultiDiGraph. This allows user to represent multiple single-phase components as parallel edges in the graph.

Note

  • Use of multiple parallel edges results in cycles in the graph.

  • A helper static method get_cycles has been added to the DistributionSystem class.

    • Unlike the networkX’s ‘simple_cycles’ method, this function ignores these parallel edges connecting two nodes and only returns cycles with lengths greater than two edges.

GDF Bug Fix#

DistributionSystem now uses system CRS when exporting to GeoDataFrame format.

Three-phase Model Reduction Algorithm Bug Fix#

Bug fixes in the three-phase model reduction algorithm

Version 2.1.3#

Plotting bug fix#

Plotting was broken after the last release. The bug has now been fixed.

Tariff model added#

The tariff model can now be imported using the code snippet below. In a future release, we will add model representations for aggregators and other market models.

from gdm.distribution.market import DistributionTariff

DistributionTariff.example().pprint()
DistributionTariff(
    name='Residential Summer Tariff',
    utility='Example Utility',
    customer_class=<CustomerClass.RESIDENTIAL: 'residential'>,
    fixed_charge=FixedCharge(name='', amount=15.0, description='Monthly fixed customer charge'),
    seasonal_tou=[
        SeasonalTOURates(
            name='',
            season=<Season.SUMMER: 'summer'>,
            tou_periods=[
                TOURatePeriod(
                    name='',
                    start_time=datetime.time(14, 0),
                    end_time=datetime.time(20, 0),
                    rate=0.25,
                    period_type=<TOUPeriodType.PEAK: 'peak'>
                ),
                TOURatePeriod(
                    name='',
                    start_time=datetime.time(20, 0),
                    end_time=datetime.time(23, 59),
                    rate=0.15,
                    period_type=<TOUPeriodType.OFF_PEAK: 'off_peak'>
                )
            ]
        ),
        SeasonalTOURates(
            name='',
            season=<Season.WINTER: 'winter'>,
            tou_periods=[
                TOURatePeriod(
                    name='',
                    start_time=datetime.time(14, 0),
                    end_time=datetime.time(20, 0),
                    rate=0.25,
                    period_type=<TOUPeriodType.PEAK: 'peak'>
                ),
                TOURatePeriod(
                    name='',
                    start_time=datetime.time(0, 0),
                    end_time=datetime.time(6, 0),
                    rate=0.1,
                    period_type=<TOUPeriodType.OFF_PEAK: 'off_peak'>
                )
            ]
        )
    ],
    demand_charges=[
        DemandCharge(
            name='',
            rate=12.5,
            billing_demand_basis=<BillingDemandBasis.PEAK_15MIN: 'peak_15min'>,
            time_applicability=[
                TOURatePeriod(
                    name='',
                    start_time=datetime.time(14, 0),
                    end_time=datetime.time(20, 0),
                    rate=0.25,
                    period_type=<TOUPeriodType.PEAK: 'peak'>
                )
            ]
        )
    ],
    tiered_energy_charges=[TieredRate(name='', upper_limit_kwh=500.0, rate=0.12)]
)

Version 2.1.2#

Support to line impedance calculations#

\(\quad\) GeometryBranch models can now be converted to MatrixImpedanceBranch model representation using the to_matrix_representation method.

from gdm.distribution.components import GeometryBranch, MatrixImpedanceBranch

g = GeometryBranch.example()
h: MatrixImpedanceBranch = g.to_matrix_representation()

\(\quad\) All GeometryBranch models in a given system can noe be replaced with MatrixImpedanceBranch model representation using the convert_geometry_to_matrix_representation method for DistributionSystem objects.

from gdm.distribution import DistributionSystem

sys = DistributionSystem.from_json(filename=<path to model>) 
sys.convert_geometry_to_matrix_representation()

Change to TrackChange object#

\(\quad\) update_date has been changed to timestamp. Now requires datetime object rather than date object..

class TrackedChange(InfraSysBaseModel):
    .
    .
    .
    
    update_date: Annotated[
        timestamp | None,
        Field(
            None,
            description="If these changes are to be applied on specific timestamp, provide a timestamp, else leave it blank",
        ),
    ]
    .
    .
    .

Version 2.1.0#

Improved validation for physical quantities#

\(\quad\) All Positive quantities have been removed. Additional constraints are now applied using Pydantic Field class. Reduces the number of class definations for physical quantities significantly.

Initial implementation to manage backward compatability for DistributionSystems#

\(\quad\) Going forward (v2.0.0 onwards), users will be able to load older models with newer GDM installations by passing the upgrade handler object, when loading the model from a json file.

from gdm.distribution import DistributionSystem
from gdm.distribution.upgrade_handler.upgrade_handler import UpgradeHandle

upgrade_handler = UpgradeHandler()
DistributionSystem.from_json(filename=<path to model>) 
upgrade_handler=upgrade_handler.upgrade)

Support to create a deepcopy of GDM system#

\(\quad\) Added functionality to easily create a deep copy of any GDM system object, ensuring that modifications to the copy do not affect the original instance.

from gdm.distribution import DistributionSystem

system = DistributionSystem.from_json(filename=<path to model>)
system_copy = system.deepcopy()