Modelling availability of assets #304
-
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 1 reply
-
Here the problem is that each particular parameter function needs to return a single value, not a vector of values. Here it appears that @parameter_function(model, γ_cont[i in 1:2, nEV] == (t) -> γ_interp(nEV, t)[i]) You can place the additional index dimension either before or after P.S. For future posts, please provide a minimal working example if at all possible to make easier to help you. Please see https://discourse.julialang.org/t/please-read-make-it-easier-to-help-you/14757 for more info. |
Beta Was this translation helpful? Give feedback.
-
Yes! Sorry I forgot a few lines. Here's the min. working example: using JuMP, InfiniteOpt, Ipopt, Juniper, Plots, LinearAlgebra, Distributions, Statistics
using LaTeXStrings
nEV=1:2; ndays=1; Δt=0.25;
tend=24*ndays
Dtw=0:Δt:tend
PevMax = [20, 20]; PevMin = [-20, -20]
model = InfiniteModel(Ipopt.Optimizer) # create model
@infinite_parameter(model, t in [0, tend], supports = Dtw, derivative_method = FiniteDifference(Backward()) )
# EV availability
# First, we create availability vectors for each EV in the disc t-domain.
tDep=zeros(length(nEV), ndays);
tArr=zeros(length(nEV), ndays);
γ=ones(length(nEV),1); # start with dummy col
for day in 1:ndays # loop through the days
tDep[:,day] = rand(6:12, nEV[end]); # departure time
tArr[:,day] = tDep[:,day]+rand(1:8, nEV[end]); # arrival time
av = ones(length(nEV), 24);
for n in nEV
td=Integer(tDep[n,day]); ta=Integer(tArr[n,day]);
av[n, td:ta] .= 0;
end
γ=[γ av]
# correction for t-axis
tDep[:,day] .= tDep[:,day].+24*(day-1);
tArr[:,day] .= tArr[:,day].+24*(day-1);
end
γ=repeat(γ, inner=(1,Integer(1/Δt))) # upsample
γ=γ[:,Integer(1/Δt):end] # eliminate dummy cols
# Now we need to project it into the cont t-domain.
γ_interp = linear_interpolation((nEV,Dtw), γ);
@parameter_function(model, γ_cont[nEV] == (t) -> γ_interp(nEV, t)) # original
@parameter_function(model, γ_cont1[n in nEV] == (t) -> γ_interp(nEV, t)[n]) # I think its the right one
@parameter_function(model, γ_cont2[i in 1:2, nEV] == (t) -> γ_interp(nEV, t)[i]) # original from Pulsipher
Pdrive = rand(Normal(5,2), length(nEV)); # Gaussian distribution
@variable(model, Pev[nEV], Infinite(t)) # EV charger power
@variable(model, PevTot[nEV], Infinite(t)) # total power of each EV, driving+V2G
# Dummy variables for bidirectional flow
@variable(model, 0 ≤ PevPos[n ∈ nEV] ≤ PevMax[n], Infinite(t)) # Pev^+ out power
@variable(model, PevMin[n] ≤ PevNeg[n ∈ nEV] ≤ 0, Infinite(t)) # Pev^- in power
@constraint(model, [n ∈ nEV], PevNeg[n] + PevPos[n] == Pev[n])
@constraint(model, [n ∈ nEV], PevNeg[n] * PevPos[n] == 0)
@constraint(model, [n ∈ nEV], PevTot[n] == Pev[n]*γ_cont1[n] - (1-γ_cont1[n])*Pdrive[n]) # power balance
build_optimizer_model!(model) A few things after playing a bit with the 3 definitions given above
print(γ_cont2)
which is not what I need I think. What I need that every car in
print(γ_cont)
doesn't that mean that each plot(Dtw,γ_interp(1,Dtw), label=L"EV_{1}\ availability")
plot!(Dtw,γ_interp(2,Dtw), label=L"EV_{2}\ availability") which means that for every value of @parameter_function(model, γ_cont[nEV] == (t) -> γ_interp(nEV, t)) # original giving me a vector output for
Thanks again for the help. |
Beta Was this translation helpful? Give feedback.
-
Sorry for the confusion in my last response, it greatly helps to see the full model. I know understand what is going on and can explain. First, you should rewrite the time definition to: @infinite_parameter(model, t in [0, tend], supports = collect(Dtw), derivative_method = FiniteDifference(Backward()) ) since a vector is expected for supports. I probably should add direct support for ranges to avoid this.... Now let's go through the varies parameter function definitions above. First we have: @parameter_function(model, γ_cont[nEV] == (t) -> γ_interp(nEV, t)) This is problematic since julia> call_function(γ_cont[1], 0)
ERROR: MethodError: Cannot `convert` an object of type Vector{Float64} to an object of type Float64
Closest candidates are:
convert(::Type{T}, ::Base.TwicePrecision) where T<:Number at Julia-1.7.1\share\julia\base\twiceprecision.jl:262
convert(::Type{T}, ::AbstractChar) where T<:Number at Julia-1.7.1\share\julia\base\char.jl:185
convert(::Type{T}, ::CartesianIndex{1}) where T<:Number at Julia-1.7.1\share\julia\base\multidimensional.jl:136
...
Stacktrace:
[1] call_function(fref::ParameterFunctionRef, supps::Int64)
@ InfiniteOpt ~InfiniteOpt.jl\src\expressions.jl:310
[2] call_function(fref::GeneralVariableRef, support::Int64)
@ InfiniteOpt ~InfiniteOpt.jl\src\general_variables.jl:696
[3] top-level scope
@ REPL[23]:1 Now for the 2nd definition we have: @parameter_function(model, γ_cont1[n in nEV] == (t) -> γ_interp(nEV, t)[n]) This will work since it returns a scalar output: julia> call_function(γ_cont1[1], 0)
1.0 However, this has some unnecessary complexity. julia> @parameter_function(model, γ_cont_direct[n in nEV] == (t) -> γ_interp(n, t))
1-dimensional DenseAxisArray{GeneralVariableRef,1,...} with index sets:
Dimension 1, 1:2
And data, a 2-element Vector{GeneralVariableRef}:
γ_cont_direct[1](t)
γ_cont_direct[2](t) This creates one parameter function for each julia> call_function(γ_cont_direct[1], 0)
1.0
julia> γ_interp(1, 0)
1.0 The reason why the wrong syntax printed as you expected, is that the parameter functions where created as you expected, but the underlying function didn't return a scalar as they expect which triggers an error when the functions are called during the discretization model build. Ideally it would be nice to check the functions upfront when defining the parameter functions, but this is nontrivial to accomplish in a general way. |
Beta Was this translation helpful? Give feedback.
Sorry for the confusion in my last response, it greatly helps to see the full model. I know understand what is going on and can explain.
First, you should rewrite the time definition to:
since a vector is expected for supports. I probably should add direct support for ranges to avoid this....
Now let's go through the varies parameter function definitions above. First we have:
This is problematic since
nEV = 1:2
so this returns a vector for all thenEV
values at time t. Since, InfiniteOpt expects scalar out…