Skip to content

Commit

Permalink
update cost function
Browse files Browse the repository at this point in the history
  • Loading branch information
mcosovic committed Dec 5, 2024
1 parent 8d6bec1 commit dba0121
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 93 deletions.
10 changes: 5 additions & 5 deletions docs/src/manual/acOptimalPowerFlow.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ addBranch!(system; label = "Branch 1", from = "Bus 1", to = "Bus 2", maxFromBus
addGenerator!(system; label = "Generator 1", bus = "Bus 1", active = 0.4, reactive = 0.2)
addGenerator!(system; label = "Generator 2", bus = "Bus 2", active = 0.2, reactive = 0.1)
cost!(system; label = "Generator 1", active = 2, polynomial = [800.0; 200.0; 80.0])
cost!(system; label = "Generator 2", active = 1, piecewise = [10.8 12.3; 14.7 16.8; 18 18.1])
cost!(system; generator = "Generator 1", active = 2, polynomial = [800.0; 200.0; 80.0])
cost!(system; generator = "Generator 2", active = 1, piecewise = [10.8 12.3; 14.7 16.8; 18 18.1])
cost!(system; label = "Generator 1", reactive = 2, polynomial = [2.0])
cost!(system; label = "Generator 2", reactive = 1, piecewise = [2.0 4.0; 6.0 8.0])
cost!(system; generator = "Generator 1", reactive = 2, polynomial = [2.0])
cost!(system; generator = "Generator 2", reactive = 1, piecewise = [2.0 4.0; 6.0 8.0])
acModel!(system)
nothing # hide
Expand Down Expand Up @@ -339,7 +339,7 @@ JuliaGrid also stores the objective function in a separate variable, which can b
##### Update Objective Function
By utilizing the [`cost!`](@ref cost!) functions, users have the flexibility to modify the objective function by adjusting polynomial or linear piecewise coefficients or by changing the type of polynomial or linear piecewise function employed. For example, consider `Generator 1`, which employs a quadratic polynomial cost function for active power. We can redefine the cost function for this generator as a cubic polynomial and thereby define a nonlinear objective function:
```@example ACOptimalPowerFlow
cost!(system, analysis; label = "Generator 1", active = 2, polynomial = [631; 257; 40; 5.0])
cost!(system, analysis; generator = "Generator 1", active = 2, polynomial = [631; 257; 40; 5.0])
nothing # hide
```

Expand Down
8 changes: 4 additions & 4 deletions docs/src/manual/dcOptimalPowerFlow.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ addGenerator!(system; label = "Generator 1", bus = "Bus 1", active = 0.6, maxAct
addGenerator!(system; label = "Generator 2", bus = "Bus 2", active = 0.1, maxActive = 0.3)
addGenerator!(system; label = "Generator 3", bus = "Bus 2", active = 0.2, maxActive = 0.4)
cost!(system; label = "Generator 1", active = 2, polynomial = [1100.2; 500; 80])
cost!(system; label = "Generator 2", active = 1, piecewise = [8.0 11.0; 14.0 17.0])
cost!(system; label = "Generator 3", active = 1, piecewise = [6.8 12.3; 8.7 16.8; 11.2 19.8])
cost!(system; generator = "Generator 1", active = 2, polynomial = [1100.2; 500; 80])
cost!(system; generator = "Generator 2", active = 1, piecewise = [8.0 11.0; 14.0 17.0])
cost!(system; generator = "Generator 3", active = 1, piecewise = [6.8 12.3; 8.7 16.8; 11.2 19.8])
dcModel!(system)
nothing # hide
Expand Down Expand Up @@ -285,7 +285,7 @@ Additionally, JuliaGrid stores the objective function in a separate variable, al
##### Update Objective Function
By utilizing the [`cost!`](@ref cost!) functions, users have the flexibility to modify the objective function by adjusting polynomial or linear piecewise cost coefficients or by changing the type of polynomial or linear piecewise function employed. For instance, consider `Generator 3`, which incorporates a piecewise cost structure with two segments. Now, we can define a polynomial function for this generator and activate it by specifying the keyword `active = 2` as shown:
```@example DCOptimalPowerFlow
cost!(system, analysis; label = "Generator 3", active = 2, polynomial = [853.4; 257; 40])
cost!(system, analysis; generator = "Generator 3", active = 2, polynomial = [853.4; 257; 40])
```

This results in the updated objective function, which can be observed as follows:
Expand Down
8 changes: 4 additions & 4 deletions docs/src/manual/powerSystemModel.md
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ nothing # hide
##### Polynomial Cost
Let us define a quadratic polynomial cost function for the active power produced by the `Generator 1`:
```@example addActiveCost
cost!(system; label = "Generator 1", active = 2, polynomial = [1100.0; 500.0; 150.0])
cost!(system; generator = "Generator 1", active = 2, polynomial = [1100.0; 500.0; 150.0])
```
In essence, what we have accomplished is the establishment of a cost function depicted as ``f(P_{\text{g}1}) = 1100 P_{\text{g}1}^2 + 500 P_{\text{g}1} + 150`` through the code provided. In general, when constructing a polynomial cost function, the coefficients must be ordered from the highest degree to the lowest.

Expand All @@ -720,7 +720,7 @@ By setting `active = 2` within the function, we express our intent to specify th
##### Piecewise Linear Cost
We can also create a piecewise linear cost function, for example, let us create the reactive power cost function for the same generator using the following code:
```@example addActiveCost
cost!(system; label = "Generator 1", reactive = 1, piecewise = [0.11 12.3; 0.15 16.8])
cost!(system; generator = "Generator 1", reactive = 1, piecewise = [0.11 12.3; 0.15 16.8])
nothing # hide
```

Expand All @@ -740,7 +740,7 @@ nothing # hide

Now, we can add the quadratic polynomial function using megawatts:
```@example addActiveCost
cost!(system; label = "Generator 1", active = 2, polynomial = [0.11; 5.0; 150.0])
cost!(system; generator = "Generator 1", active = 2, polynomial = [0.11; 5.0; 150.0])
```

After inspecting the resulting cost data, we can see that it is the same as before:
Expand All @@ -750,7 +750,7 @@ system.generator.cost.active.polynomial[1]

Similarly, we can define the linear piecewise cost using megavolt-amperes reactive:
```@example addActiveCost
cost!(system; label = "Generator 1", reactive = 1, piecewise = [11.0 12.3; 15.0 16.8])
cost!(system; generator = "Generator 1", reactive = 1, piecewise = [11.0 12.3; 15.0 16.8])
nothing # hide
```

Expand Down
8 changes: 4 additions & 4 deletions docs/src/tutorials/acOptimalPowerFlow.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ addBranch!(system; label = 1, from = 1, to = 2, maxFromBus = 0.15, maxToBus = 0.
addGenerator!(system; label = 1, bus = 1, active = 0.4, reactive = 0.2)
addGenerator!(system; label = 2, bus = 2, active = 0.2, reactive = 0.1)
cost!(system; label = 1, active = 2, polynomial = [900.0; 500.0; 80.0; 5.0])
cost!(system; label = 2, active = 1, piecewise = [10.8 12.3; 14.7 16.8; 18 18.1])
cost!(system; generator = 1, active = 2, polynomial = [900.0; 500.0; 80.0; 5.0])
cost!(system; generator = 2, active = 1, piecewise = [10.8 12.3; 14.7 16.8; 18 18.1])
cost!(system; label = 1, reactive = 1, piecewise = [10.0 20.0; 20.0 40.0])
cost!(system; label = 2, reactive = 2, polynomial = [2.0])
cost!(system; generator = 1, reactive = 1, piecewise = [10.0 20.0; 20.0 40.0])
cost!(system; generator = 2, reactive = 2, polynomial = [2.0])
nothing # hide
```

Expand Down
4 changes: 2 additions & 2 deletions docs/src/tutorials/dcOptimalPowerFlow.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ addBranch!(system; label = 3, from = 2, to = 3, reactance = 0.01, maxFromBus = 0
addGenerator!(system; label = 1, bus = 1, active = 3.2, maxActive = 0.5)
addGenerator!(system; label = 2, bus = 2, active = 0.2, maxActive = 0.3)
cost!(system; label = 1, active = 2, polynomial = [1100.2; 500; 80])
cost!(system; label = 2, active = 1, piecewise = [10.85 12.3; 14.77 16.8; 18 18.1])
cost!(system; generator = 1, active = 2, polynomial = [1100.2; 500; 80])
cost!(system; generator = 2, active = 1, piecewise = [10.85 12.3; 14.77 16.8; 18 18.1])
nothing # hide
```

Expand Down
2 changes: 1 addition & 1 deletion src/backend/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ PrecompileTools.@setup_workload begin
addBus!(system; label = 2, type = 1, reactive = 0.05)
addBranch!(system; from = 1, to = 2, reactance = 0.05)
addGenerator!(system; bus = 1, active = 0.5, reactive = 0.1)
cost!(system; label = 1, active = 2, polynomial = [0.11; 5.0; 150.0])
cost!(system; generator = 1, active = 2, polynomial = [0.11; 5.0; 150.0])

addPmu!(system, device; bus = 1, magnitude = 1.0, angle = 0.0)
addPmu!(system, device; bus = 2, magnitude = 1.0, angle = 0.0)
Expand Down
36 changes: 18 additions & 18 deletions src/powerSystem/generator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ macro generator(kwargs...)
end

"""
cost!(system::PowerSystem, [analysis::Analysis]; label, active, reactive,
cost!(system::PowerSystem, [analysis::Analysis]; generator, active, reactive,
piecewise, polynomial)
The function either adds a new cost or modifies an existing one for the active or reactive
Expand All @@ -748,7 +748,7 @@ for completely reconstructing vectors and matrices when adding a new branch.
# Keywords
The function accepts five keywords:
* `label`: Corresponds to the already defined generator label.
* `generator`: Corresponds to the already defined generator label.
* `active`: Active power cost model:
* `active = 1`: adding or updating cost, and piecewise linear is being used,
* `active = 2`: adding or updating cost, and polynomial is being used.
Expand Down Expand Up @@ -780,7 +780,7 @@ system = powerSystem()
addBus!(system; label = "Bus 1", active = 0.25, reactive = -0.04, base = 132e3)
addGenerator!(system; label = "Generator 1", bus = "Bus 1", active = 0.5)
cost!(system; label = "Generator 1", active = 2, polynomial = [1100.0; 500.0; 150.0])
cost!(system; generator = "Generator 1", active = 2, polynomial = [1100.0; 500.0; 150.0])
```
Adding a cost using a custom unit system:
Expand All @@ -791,12 +791,12 @@ system = powerSystem()
addBus!(system; label = "Bus 1", active = 25, reactive = -4, base = 132e3)
addGenerator!(system; label = "Generator 1", bus = "Bus 1", active = 50, reactive = 10)
cost!(system; label = "Generator 1", active = 2, polynomial = [0.11; 5.0; 150.0])
cost!(system; generator = "Generator 1", active = 2, polynomial = [0.11; 5.0; 150.0])
```
"""
function cost!(
system::PowerSystem;
label::IntStrMiss,
generator::IntStrMiss,
active::FltIntMiss = missing,
reactive::FltIntMiss = missing,
polynomial::Vector{Float64} = Float64[],
Expand All @@ -815,7 +815,7 @@ function cost!(
)
end

idx = system.generator.label[getLabel(system.generator, label, "generator")]
idx = system.generator.label[getLabel(system.generator, generator, "generator")]

if isset(active)
container = system.generator.cost.active
Expand Down Expand Up @@ -859,7 +859,7 @@ end
function cost!(
system::PowerSystem,
analysis::ACOptimalPowerFlow;
label::IntStrMiss,
generator::IntStrMiss,
active::FltIntMiss = missing,
reactive::FltIntMiss = missing,
polynomial::Vector{Float64} = Float64[],
Expand All @@ -872,14 +872,14 @@ function cost!(
obj = analysis.method.objective

dropZero = false
idx = gen.label[getLabel(gen, label, "generator")]
idx = gen.label[getLabel(gen, generator, "generator")]

if gen.layout.status[idx] == 1
actCost, isActwiseOld, isActNonlin = costExpr(
gen.cost.active, variable.active[idx], idx, label; ac = true
gen.cost.active, variable.active[idx], idx, generator; ac = true
)
reactCost, isReactwisOld, isReactNonlin = costExpr(
gen.cost.reactive, variable.reactive[idx], idx, label; ac = true
gen.cost.reactive, variable.reactive[idx], idx, generator; ac = true
)

@objective(jump, Min, 0.0)
Expand All @@ -905,14 +905,14 @@ function cost!(
end
end

cost!(system; label, active, reactive, polynomial, piecewise)
cost!(system; generator, active, reactive, polynomial, piecewise)

if gen.layout.status[idx] == 1
actCost, isActwiseNew, isActNonlin = costExpr(
gen.cost.active, variable.active[idx], idx, label; ac = true
gen.cost.active, variable.active[idx], idx, generator; ac = true
)
reactCost, isReactwiseNew, isReactNonlin = costExpr(
gen.cost.reactive, variable.reactive[idx], idx, label; ac = true
gen.cost.reactive, variable.reactive[idx], idx, generator; ac = true
)

if isActwiseNew
Expand Down Expand Up @@ -984,7 +984,7 @@ end
function cost!(
system::PowerSystem,
analysis::DCOptimalPowerFlow;
label::IntStrMiss,
generator::IntStrMiss,
active::FltIntMiss = missing,
reactive::FltIntMiss = missing,
polynomial::Vector{Float64} = Float64[],
Expand All @@ -996,10 +996,10 @@ function cost!(
variable = analysis.method.variable

dropZero = false
idx = gen.label[getLabel(gen, label, "generator")]
idx = gen.label[getLabel(gen, generator, "generator")]

if gen.layout.status[idx] == 1
costOld, isPowerwiseOld = costExpr(gen.cost.active, variable.active[idx], idx, label)
costOld, isPowerwiseOld = costExpr(gen.cost.active, variable.active[idx], idx, generator)

if isPowerwiseOld
remove!(jump, constr.piecewise.active, idx)
Expand All @@ -1009,10 +1009,10 @@ function cost!(
end
end

cost!(system; label, active, reactive, polynomial, piecewise)
cost!(system; generator, active, reactive, polynomial, piecewise)

if gen.layout.status[idx] == 1
costNew, isWiseNew = costExpr(gen.cost.active, variable.active[idx], idx, label)
costNew, isWiseNew = costExpr(gen.cost.active, variable.active[idx], idx, generator)

if isWiseNew
if !isPowerwiseOld
Expand Down
8 changes: 4 additions & 4 deletions test/optimalPowerFlow/analysis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -291,26 +291,26 @@ end
err = ErrorException("The slack bus is missing.")
@test_throws err dcOptimalPowerFlow(system, Ipopt.Optimizer)

cost!(system; label = "Gen 1", active = 1, piecewise = [5.1 6.2])
cost!(system; generator = "Gen 1", active = 1, piecewise = [5.1 6.2])
updateBus!(system; label = "Bus 1", type = 3)
err = ErrorException(
"The generator labeled Gen 1 has a piecewise linear cost " *
"function with only one defined point."
)
@test_throws err dcOptimalPowerFlow(system, Ipopt.Optimizer)

cost!(system; label = "Gen 1", active = 1, piecewise = [5.1 6.2; 4.1 5.2])
cost!(system; generator = "Gen 1", active = 1, piecewise = [5.1 6.2; 4.1 5.2])
dc = dcOptimalPowerFlow(system, Ipopt.Optimizer)
err = ErrorException(
"The generator labeled Gen 1 has a piecewise linear cost " *
"function with only one defined point."
)
@test_throws err cost!(system, dc; label = "Gen 1", active = 1, piecewise = [5.1 6.2])
@test_throws err cost!(system, dc; generator = "Gen 1", active = 1, piecewise = [5.1 6.2])

@capture_out print(dc.method.constraint.balance.active)
@capture_out print(system.bus.label, dc.method.constraint.balance.active)

cost!(system; label = "Gen 1", active = 1, piecewise = [1.1 2.2; 2.1 3.2])
cost!(system; generator = "Gen 1", active = 1, piecewise = [1.1 2.2; 2.1 3.2])
dc = dcOptimalPowerFlow(system, Ipopt.Optimizer)
@capture_out print(system.generator.label, dc.method.constraint.piecewise.active)
@capture_out print(dc.method.constraint.piecewise.active)
Expand Down
Loading

0 comments on commit dba0121

Please sign in to comment.