Skip to content

Commit

Permalink
Merge branch 'main' into gks/td/component_selector_port
Browse files Browse the repository at this point in the history
  • Loading branch information
GabrielKS committed Dec 12, 2024
2 parents 037435f + 774695e commit 2359e64
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 45 deletions.
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "PowerSystems"
uuid = "bcd98974-b02a-5e2f-9ee0-a103f5c450dd"
authors = ["Jose Daniel Lara", "Daniel Thom", "Clayton Barrows", "Sourabh Dalvi", "Dheepak Krishnamurthy"]
version = "4.4.0"
version = "4.4.1"

[deps]
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
Expand All @@ -27,7 +27,7 @@ DataFrames = "1"
DataStructures = "~0.18"
Dates = "1"
DocStringExtensions = "0.8, 0.9.2"
InfrastructureSystems = "^2.2"
InfrastructureSystems = "^2.3"
InteractiveUtils = "1"
JSON3 = "1"
LinearAlgebra = "1"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The `PowerSystems.jl` package provides a rigorous data model using Julia structu
- Dynamic Generators Models
- Dynamic Inverter Models

For a more exhaustive list, check the [Documentation](https://nrel-sienna.github.io/PowerSystems.jl/stable).
For information on using the package and a more extensive list of device data enabled, see the [stable documentation](https://nrel-sienna.github.io/PowerSystems.jl/stable/). Use the [in-development documentation](https://nrel-sienna.github.io/PowerSystems.jl/dev/) for the version of the documentation which contains the unreleased features.

## Parsing capabilities in PowerSystems

Expand Down
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pages = OrderedDict(
"Reference" =>
Any["Public API" => "api/public.md",
"Glossary and Acronyms" => "api/glossary.md",
"Type Hierarchy" => "api/type_tree.md",
"Type Tree" => "api/type_tree.md",
"`ValueCurve` Options" => "api/valuecurve_options.md",
"Specifying the category of..." => "api/enumerated_types.md",
"Citation" => "api/citation.md",
Expand Down
2 changes: 1 addition & 1 deletion docs/src/api/type_tree.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Type Hierarchy
# Type Tree

Here is the complete `PowerSystems.jl` type hierarchy:

Expand Down
27 changes: 15 additions & 12 deletions src/base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ System(; kwargs...)
`"DEVICE_BASE"`, or `"NATURAL_UNITS"`)
By default, time series data is stored in an HDF5 file in the tmp file system to prevent
large datasets from overwhelming system memory (see [Data Storage](@ref)).
large datasets from overwhelming system memory (see [Data Storage](@ref)).
**If the system's time series
data will be larger than the amount of tmp space available**, use the
`time_series_directory` parameter to change its location.
Expand Down Expand Up @@ -1084,22 +1084,25 @@ function IS.get_component(
end

"""
Returns an iterator of components. T can be concrete or abstract.
Return an iterator of components of a given `Type` from a [`System`](@ref).
`T` can be a concrete or abstract [`Component`](@ref) type from the [Type Tree](@ref).
Call collect on the result if an array is desired.
# Examples
```julia
iter = PowerSystems.get_components(ThermalStandard, sys)
iter = PowerSystems.get_components(Generator, sys)
iter = PowerSystems.get_components(x -> PowerSystems.get_available(x), Generator, sys)
thermal_gens = get_components(ThermalStandard, sys) do gen
get_available(gen)
end
generators = collect(PowerSystems.get_components(Generator, sys))
iter = get_components(ThermalStandard, sys)
iter = get_components(Generator, sys)
generators = collect(get_components(Generator, sys))
```
See also: [`iterate_components`](@ref)
See also: [`iterate_components`](@ref), [`get_components` with a filter](@ref get_components(
filter_func::Function,
::Type{T},
sys::System;
subsystem_name = nothing,
) where {T <: Component}),
[`get_available_components`](@ref), [`get_buses`](@ref)
"""
function IS.get_components(
::Type{T},
Expand Down Expand Up @@ -1299,7 +1302,7 @@ function _get_buses(data::IS.SystemData, aggregator::T) where {T <: AggregationT
buses = Vector{ACBus}()
for bus in IS.get_components(ACBus, data)
_aggregator = accessor_func(bus)
if IS.get_uuid(_aggregator) == IS.get_uuid(aggregator)
if !isnothing(_aggregator) && IS.get_uuid(_aggregator) == IS.get_uuid(aggregator)
push!(buses, bus)
end
end
Expand Down
21 changes: 21 additions & 0 deletions src/get_components_interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,27 @@ Return a vector of components that are attached to the supplemental attribute.
get_components(sys::System, attribute::SupplementalAttribute) =
IS.get_components(sys, attribute)

"""
Return an iterator of components of a given `Type` from a [`System`](@ref), using an
additional filter
`T` can be a concrete or abstract [`Component`](@ref) type from the [Type Tree](@ref).
Call collect on the result if an array is desired.
# Examples
```julia
iter_coal = get_components(x -> get_fuel(x) == ThermalFuels.COAL, Generator, sys)
pv_gens =
collect(get_components(x -> get_prime_mover_type(x) == PrimeMovers.PVe, Generator, sys))
```
See also: [`get_components`](@ref get_components(
::Type{T},
sys::System;
subsystem_name = nothing,
) where {T <: Component}), [`get_available_components`](@ref),
[`get_buses`](@ref)
"""
get_components(
filter_func::Function,
::Type{T},
Expand Down
49 changes: 32 additions & 17 deletions src/models/components.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,38 @@ Default behavior of a component. If there is no base_power field, assume is in t
"""
get_base_power(c::Component) = get_system_base_power(c)

function _get_multiplier(c::T) where {T <: Component}
setting = get_internal(c).units_info
if isnothing(setting)
return 1.0
elseif setting.unit_system == IS.UnitSystem.DEVICE_BASE
return 1.0
elseif setting.unit_system == IS.UnitSystem.SYSTEM_BASE
numerator = get_base_power(c)
denominator = setting.base_value
elseif setting.unit_system == IS.UnitSystem.NATURAL_UNITS
numerator = get_base_power(c)
denominator = 1.0
else
error("Undefined Conditional")
end
return numerator / denominator
end
_get_multiplier(c::T) where {T <: Component} =
_get_multiplier(c, get_internal(c).units_info)

_get_multiplier(::T, ::Nothing) where {T <: Component} =
1.0
_get_multiplier(c::T, setting::IS.SystemUnitsSettings) where {T <: Component} =
_get_multiplier(c, setting, Val(setting.unit_system))

# PERF: dispatching on the UnitSystem values instead of comparing with if/else avoids the
# performance hit associated with consulting the dictionary that backs the @scoped_enum --
# i.e., IS.UnitSystem.NATURAL_UNITS by itself isn't treated as a constant, it's a dictionary
# lookup each time.
_get_multiplier(
::T,
::IS.SystemUnitsSettings,
::Val{IS.UnitSystem.DEVICE_BASE},
) where {T <: Component} =
1.0
_get_multiplier(
c::T,
setting::IS.SystemUnitsSettings,
::Val{IS.UnitSystem.SYSTEM_BASE},
) where {T <: Component} =
get_base_power(c) / setting.base_value
_get_multiplier(
c::T,
::IS.SystemUnitsSettings,
::Val{IS.UnitSystem.NATURAL_UNITS},
) where {T <: Component} =
get_base_power(c)
_get_multiplier(::T, ::IS.SystemUnitsSettings, ::Val) where {T <: Component} =
error("Undefined Conditional")

function get_value(c::Component, value::Float64)
return _get_multiplier(c) * value
Expand Down
51 changes: 40 additions & 11 deletions src/parsers/power_models_data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,14 @@ function make_hydro_gen(
ramp_agc = get(d, "ramp_agc", get(d, "ramp_10", get(d, "ramp_30", abs(d["pmax"]))))
curtailcost = HydroGenerationCost(zero(CostCurve), 0.0)

base_conversion = sys_mbase / d["mbase"]
if d["mbase"] != 0.0
mbase = d["mbase"]
else
@warn "Generator $gen_name has base power equal to zero: $(d["mbase"]). Changing it to system base: $sys_mbase"
mbase = sys_mbase
end

base_conversion = sys_mbase / mbase
return HydroDispatch(; # No way to define storage parameters for gens in PM so can only make HydroDispatch
name = gen_name,
available = Bool(d["gen_status"]),
Expand All @@ -394,7 +401,7 @@ function make_hydro_gen(
ramp_limits = (up = ramp_agc, down = ramp_agc),
time_limits = nothing,
operation_cost = curtailcost,
base_power = d["mbase"],
base_power = mbase,
)
end

Expand All @@ -405,12 +412,20 @@ function make_renewable_dispatch(
sys_mbase::Float64,
)
cost = RenewableGenerationCost(zero(CostCurve))
base_conversion = sys_mbase / d["mbase"]

if d["mbase"] != 0.0
mbase = d["mbase"]
else
@warn "Generator $gen_name has base power equal to zero: $(d["mbase"]). Changing it to system base: $sys_mbase"
mbase = sys_mbase
end

base_conversion = sys_mbase / mbase

rating = calculate_rating(d["pmax"], d["qmax"])
if rating > d["mbase"]
@warn "rating is larger than base power for $gen_name, setting to $(d["mbase"])"
rating = d["mbase"]
if rating > mbase
@warn "rating is larger than base power for $gen_name, setting to $mbase"
rating = mbase
end

generator = RenewableDispatch(;
Expand All @@ -427,7 +442,7 @@ function make_renewable_dispatch(
),
power_factor = 1.0,
operation_cost = cost,
base_power = d["mbase"],
base_power = mbase,
)

return generator
Expand All @@ -439,7 +454,14 @@ function make_renewable_fix(
bus::ACBus,
sys_mbase::Float64,
)
base_conversion = sys_mbase / d["mbase"]
if d["mbase"] != 0.0
mbase = d["mbase"]
else
@warn "Generator $gen_name has base power equal to zero: $(d["mbase"]). Changing it to system base: $sys_mbase"
mbase = sys_mbase
end

base_conversion = sys_mbase / mbase
generator = RenewableNonDispatch(;
name = gen_name,
available = Bool(d["gen_status"]),
Expand All @@ -449,7 +471,7 @@ function make_renewable_fix(
rating = float(d["pmax"]) * base_conversion,
prime_mover_type = parse_enum_mapping(PrimeMovers, d["type"]),
power_factor = 1.0,
base_power = d["mbase"],
base_power = mbase,
)

return generator
Expand Down Expand Up @@ -555,7 +577,14 @@ function make_thermal_gen(
ext["z_source"] = (r = d["r_source"], x = d["x_source"])
end

base_conversion = sys_mbase / d["mbase"]
if d["mbase"] != 0.0
mbase = d["mbase"]
else
@warn "Generator $gen_name has base power equal to zero: $(d["mbase"]). Changing it to system base: $sys_mbase"
mbase = sys_mbase
end

base_conversion = sys_mbase / mbase
thermal_gen = ThermalStandard(;
name = gen_name,
status = Bool(d["gen_status"]),
Expand All @@ -577,7 +606,7 @@ function make_thermal_gen(
ramp_limits = (up = ramp_lim, down = ramp_lim),
time_limits = nothing,
operation_cost = operation_cost,
base_power = d["mbase"],
base_power = mbase,
ext = ext,
)

Expand Down

0 comments on commit 2359e64

Please sign in to comment.