diff --git a/Project.toml b/Project.toml index bbdfb63..12ee9f8 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "TimeStruct" uuid = "f9ed5ce0-9f41-4eaa-96da-f38ab8df101c" authors = ["Lars Hellemo , Truls.Flatberg "] -version = "0.9.8" +version = "0.9.9" [deps] Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" diff --git a/src/strat_scenarios/core_types.jl b/src/strat_scenarios/core_types.jl index 6f5bac7..200f78c 100644 --- a/src/strat_scenarios/core_types.jl +++ b/src/strat_scenarios/core_types.jl @@ -100,7 +100,7 @@ n_children(n::StratNode, ts::TwoLevelTree) = count(c -> _parent(c) == n, strat_n """ n_leaves(ts::TwoLevelTree) -Returns the number of children of a [`TwoLevelTree`](@ref). +Returns the number of leaves of a [`TwoLevelTree`](@ref). """ n_leaves(ts::TwoLevelTree) = count(n -> n_children(n, ts) == 0, strat_nodes(ts)) diff --git a/src/strat_scenarios/strat_scenarios.jl b/src/strat_scenarios/strat_scenarios.jl index c3994b0..d4816bf 100644 --- a/src/strat_scenarios/strat_scenarios.jl +++ b/src/strat_scenarios/strat_scenarios.jl @@ -86,10 +86,9 @@ decomposition algorithm. struct StrategicScenario{S,T,N,OP<:AbstractTreeNode{S,T}} <: AbstractStrategicScenario{T} scen::Int64 probability::Float64 - nodes::NTuple{N,<:OP} + nodes::NTuple{N,OP} op_per_strat::Float64 end - Base.show(io::IO, scen::StrategicScenario) = print(io, "scen$(scen.scen)") # Add basic functions of iterators @@ -162,20 +161,16 @@ iterator `StratScens`. strategic_scenarios(ts::TwoLevelTree) = StratScens(ts) # Provide a constructor to simplify the design -function StrategicScenario( - scs::StratScens{S,T,OP}, - scen::Int, -) where {S,T,OP<:TimeStructure{T}} +function StrategicScenario(scs::StratScens{S,T,OP}, scen::Int) where {S,T,OP} node = get_leaf(scs.ts, scen) prob = probability_branch(node) - n_strat_per = _strat_per(node) - nodes = Vector{OP}(undef, n_strat_per) - for sp in n_strat_per:-1:1 + N = _strat_per(node) + nodes = Vector{OP}(undef, N) + for sp in N:-1:1 nodes[sp] = node node = _parent(node) end - - return StrategicScenario(scen, prob, Tuple(nodes), scs.ts.op_per_strat) + return StrategicScenario{S,T,N,OP}(scen, prob, Tuple(nodes), scs.ts.op_per_strat) end # Add basic functions of iterators diff --git a/test/runtests.jl b/test/runtests.jl index bf4c7e9..cdeb8e9 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -665,12 +665,12 @@ end test_invariants(TwoLevel(5, 10, SimpleTimes(10, 1))) test_invariants(TwoLevel(5, 30, opscen)) - repr = RepresentativePeriods(2, 20, [0.2, 0.8], [SimpleTimes(5, 1), SimpleTimes(5, 1)]) - two_level = TwoLevel(100, [repr, repr, repr]; op_per_strat = 1.0) + rpers = RepresentativePeriods(2, 20, [0.2, 0.8], [SimpleTimes(5, 1), SimpleTimes(5, 1)]) + two_level = TwoLevel(100, [rpers, rpers, rpers]; op_per_strat = 1.0) test_invariants(two_level) - repr = RepresentativePeriods(2, 20, [0.2, 0.8], [opscen, opscen]) - two_level = TwoLevel(100, [repr, repr]; op_per_strat = 1.0) + rpers = RepresentativePeriods(2, 20, [0.2, 0.8], [opscen, opscen]) + two_level = TwoLevel(100, [rpers, rpers]; op_per_strat = 1.0) test_invariants(two_level) end @@ -1275,6 +1275,45 @@ end @test repr(sc) == "scen$(k)" @test eltype(typeof(sc)) == eltype(typeof(regtree)) end + + # Test that non regular structures are working + day = SimpleTimes(24, 1) + week = SimpleTimes(168, 1) + scen = OperationalScenarios(2, [day, week], [7, 1]/8) + rpers = RepresentativePeriods(4, 8760, scen) + + ts = TwoLevelTree( + TreeNode( + 5, + rpers, + [0.7, 0.05, 0.1, 0.15], + [ + TreeNode(5, rpers, TreeNode(5, rpers, TreeNode(5, week))), + TreeNode(2, week, TreeNode(8, week, TreeNode(5, week))), + TreeNode( + 4, + scen, + [ + TreeNode(6, week, TreeNode(5, week)), + TreeNode(6, week, 2, TreeNode(5, week)), + ], + ), + TreeNode(5, rpers, 2, TreeNode(8, rpers, TreeNode(5, week))), + ], + ), + ; + op_per_strat = 8760.0, + ) + + # Test that the strategic periods are correct + sps = strat_periods(ts) + scens = strategic_scenarios(ts) + sps_scens = strat_periods(scens) + sps_scen_1 = strat_periods(first(scens)) + @test sps == sps_scens + @test all(sps1 === sps2 for (sps1, sps2) in zip(sps_scen_1, collect(sps)[1:3])) + @test last(sps_scen_1) == collect(sps)[4] + @test isa(sps_scen_1, TS.ScenTreeNodes) end @testitem "Strategic scenarios with TwoLevel" begin @@ -1336,8 +1375,8 @@ end vals = collect(profile[sp] for sp in strat_periods(ts)) @test vals == [1, 2, 3] - repr = RepresentativePeriods(2, 5, [0.6, 0.4], [SimpleTimes(5, 1), SimpleTimes(5, 1)]) - ts = TwoLevel(3, 5, repr) + rpers = RepresentativePeriods(2, 5, [0.6, 0.4], [SimpleTimes(5, 1), SimpleTimes(5, 1)]) + ts = TwoLevel(3, 5, rpers) vals = collect(profile[sp] for sp in strat_periods(ts)) @test vals == [1, 2, 3] @@ -1355,8 +1394,8 @@ end vals = collect(profile[rp] for rp in repr_periods(ts)) @test vals == [1, 1, 1] - repr = RepresentativePeriods(2, 5, [0.6, 0.4], [SimpleTimes(5, 1), SimpleTimes(5, 1)]) - ts = TwoLevel(3, 5, repr) + rpers = RepresentativePeriods(2, 5, [0.6, 0.4], [SimpleTimes(5, 1), SimpleTimes(5, 1)]) + ts = TwoLevel(3, 5, rpers) vals = collect(profile[rp] for rp in repr_periods(ts)) @test vals == [1, 2, 1, 2, 1, 2] @@ -1382,8 +1421,8 @@ end @test vals == [1, 1, 1] oscen = OperationalScenarios([SimpleTimes(5, 1), SimpleTimes(5, 1)]) - repr = RepresentativePeriods(2, 5, [0.6, 0.4], [oscen, oscen]) - ts = TwoLevel(3, 5, repr) + rpers = RepresentativePeriods(2, 5, [0.6, 0.4], [oscen, oscen]) + ts = TwoLevel(3, 5, rpers) vals = collect(profile[sc] for sc in opscenarios(ts)) @test vals == [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2] @@ -1473,8 +1512,8 @@ end # ScenarioProfile oscen = OperationalScenarios([SimpleTimes(5, 1), SimpleTimes(5, 1)]) - repr = RepresentativePeriods(2, 5, [0.6, 0.4], [oscen, oscen]) - ts = TwoLevel(3, 5, repr) + rpers = RepresentativePeriods(2, 5, [0.6, 0.4], [oscen, oscen]) + ts = TwoLevel(3, 5, rpers) profile = +ScenarioProfile([1, 2, 3]) vals = collect(profile[sc] for sc in opscenarios(ts)) @test vals == [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2] @@ -1484,8 +1523,8 @@ end @test vals == [-1, -2, -1, -2, -1, -2, -1, -2, -1, -2, -1, -2] # RepresentativeProfile - repr = RepresentativePeriods(2, 5, [0.6, 0.4], [SimpleTimes(5, 1), SimpleTimes(5, 1)]) - ts = TwoLevel(3, 5, repr) + rpers = RepresentativePeriods(2, 5, [0.6, 0.4], [SimpleTimes(5, 1), SimpleTimes(5, 1)]) + ts = TwoLevel(3, 5, rpers) profile = +RepresentativeProfile([1, 2, 3]) vals = collect(profile[rp] for rp in repr_periods(ts)) @@ -1761,4 +1800,4 @@ end end @run_package_tests -Aqua.test_all(TimeStruct; ambiguities = false) +Aqua.test_all(TimeStruct; ambiguities = false, unbound_args = false)