From 235f28499b5a03bb84dcdd36f5b42567319a4dc3 Mon Sep 17 00:00:00 2001 From: lexverheem Date: Fri, 12 Dec 2025 10:17:17 +0100 Subject: [PATCH 1/3] add skip_fair_fraction to Allocation struct --- core/src/parameter.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/parameter.jl b/core/src/parameter.jl index 010fd5022..48519bc6a 100644 --- a/core/src/parameter.jl +++ b/core/src/parameter.jl @@ -316,6 +316,7 @@ record_control: A record of all flow rates assigned to pumps and outlets by allo primary_network_connections::OrderedDict{Int32, Vector{Tuple{NodeID, NodeID}}} = OrderedDict() demand_priorities_all::Vector{Int32} = [] + skip_fair_fraction::Vector{Bool} = [] record_demand::Vector{DemandRecordDatum} = [] record_flow::Vector{FlowRecordDatum} = [] record_control::Vector{AllocationControlRecordDatum} = [] From f03896fa6eee42548a68dd0ce4da6efa0856edb4 Mon Sep 17 00:00:00 2001 From: lexverheem Date: Mon, 15 Dec 2025 14:40:47 +0100 Subject: [PATCH 2/3] bugfix --- core/src/allocation_optim.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/allocation_optim.jl b/core/src/allocation_optim.jl index 9e30a2411..41d1a6e29 100644 --- a/core/src/allocation_optim.jl +++ b/core/src/allocation_optim.jl @@ -831,7 +831,7 @@ function parse_allocations!( is_user_demand ? node_id : get_external_demand_id(p_independent, node_id) for (demand_priority_idx, demand_priority) in enumerate(demand_priorities_all) - !has_demand_priority[node_id.idx, demand_priority_idx] && continue + !has_demand_priority[demand_id.idx, demand_priority_idx] && continue allocated_flow = max(0, JuMP.value(node_allocated[node_id, demand_priority]) * scaling.flow) push!( From 25d6efce8b8a859d507dbe312459b0a98e6a2136 Mon Sep 17 00:00:00 2001 From: lexverheem Date: Mon, 22 Dec 2025 11:01:09 +0100 Subject: [PATCH 3/3] test skipping fair fraction --- core/src/allocation_optim.jl | 18 +++---- python/ribasim/ribasim/input_base.py | 2 +- .../ribasim_testmodels/allocation.py | 47 ++++++++++++++----- 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/core/src/allocation_optim.jl b/core/src/allocation_optim.jl index 41d1a6e29..e1a3c80b8 100644 --- a/core/src/allocation_optim.jl +++ b/core/src/allocation_optim.jl @@ -719,7 +719,7 @@ function optimize_multi_objective!( for metadata in objectives.objective_metadata (; expression_first, expression_second, type, demand_priority_idx) = metadata - # First expression + # Optimize the absolute error in the system JuMP.@objective(problem, Min, expression_first) JuMP.optimize!(problem) push!( @@ -727,15 +727,15 @@ function optimize_multi_objective!( JuMP.@constraint(problem, expression_first == JuMP.objective_value(problem)) ) - # Second expression - JuMP.@objective(problem, Min, expression_second) - JuMP.optimize!(problem) - push!( - temporary_constraints, - JuMP.@constraint(problem, expression_second == JuMP.objective_value(problem),) - ) + # # Optimize sum of errors for fair distribution of resources + # JuMP.@objective(problem, Min, expression_second) + # JuMP.optimize!(problem) + # push!( + # temporary_constraints, + # JuMP.@constraint(problem, expression_second == JuMP.objective_value(problem),) + # ) - # Source priority + # Optimize for source priorities JuMP.@objective(problem, Min, source_priority_expression) JuMP.optimize!(problem) diff --git a/python/ribasim/ribasim/input_base.py b/python/ribasim/ribasim/input_base.py index 7bcaa052e..70fcc6ff8 100644 --- a/python/ribasim/ribasim/input_base.py +++ b/python/ribasim/ribasim/input_base.py @@ -614,7 +614,7 @@ class NodeModel(ChildModel): """Base class to handle combining the tables for a single node type.""" @model_serializer(mode="wrap") - def set_modeld( + def set_model( self, serializer: Callable[["NodeModel"], dict[str, object]] ) -> dict[str, object]: content = serializer(self) diff --git a/python/ribasim_testmodels/ribasim_testmodels/allocation.py b/python/ribasim_testmodels/ribasim_testmodels/allocation.py index d3f549e6f..6a9b6342a 100644 --- a/python/ribasim_testmodels/ribasim_testmodels/allocation.py +++ b/python/ribasim_testmodels/ribasim_testmodels/allocation.py @@ -2075,10 +2075,27 @@ def polder_management_model() -> Model: basin.State(level=[0.9]), ] - basin3 = model.basin.add(Node(3, Point(2.0, 0.0), name="Boezem"), basin_data) + evaporation[0:90] = 1e-6 + evaporation[90:180] = 1e-6 + evaporation[180:270] = 1.1e-6 + evaporation[270:366] = 1.1e-6 + + basin_data_boezem: list[TableModel[Any]] = [ + basin.Profile(area=[0.01, 1000000.0, 1000000.0], level=[-10, 1.5, 3.0]), + basin.Time( + time=pd.date_range(model.starttime, model.endtime), + drainage=0.0, + potential_evaporation=evaporation, + infiltration=0.0, + precipitation=precipitation, + ), + basin.State(level=[2.0]), + ] + + basin3 = model.basin.add(Node(3, Point(2.0, 0.0), name="Boezem"), basin_data_boezem) basin4 = model.basin.add(Node(4, Point(2.0, 2.0), name="Polder"), basin_data) basin6 = model.basin.add(Node(6, Point(4.0, 2.0), name="Polder"), basin_data) - basin9 = model.basin.add(Node(9, Point(4.0, 0.0), name="Boezem"), basin_data) + basin9 = model.basin.add(Node(9, Point(4.0, 0.0), name="Boezem"), basin_data_boezem) # Level demand on polder 4 exactly maintain 1 m level4 = model.level_demand.add( @@ -2091,8 +2108,14 @@ def polder_management_model() -> Model: [level_demand.Static(min_level=[0.9], max_level=0.9, demand_priority=1)], ) + level9 = model.level_demand.add( + Node(102, Point(4.0, -0.5), name="boezem#9 level demand"), + [level_demand.Static(min_level=[5.0], max_level=5.0, demand_priority=1)], + ) + model.link.add(level4, basin4) model.link.add(level6, basin6) + model.link.add(level9, basin9) ###Setup outlet: outlet10 = model.outlet.add( @@ -2100,10 +2123,10 @@ def polder_management_model() -> Model: [outlet.Static(flow_rate=20, min_upstream_level=[1.2])], ) - outlet12 = model.outlet.add( - Node(12, Point(1.0, 0)), - [outlet.Static(flow_rate=[10])], - ) + # outlet12 = model.outlet.add( + # Node(12, Point(1.0, 0)), + # [outlet.Static(flow_rate=[10])], + # ) # --- Outlet 5 Controlled by Allocation --- outlet5 = model.outlet.add( @@ -2166,10 +2189,10 @@ def polder_management_model() -> Model: ) model.link.add(pump7_alloc, pump7) - ##Setup level boundary - level_boundary11 = model.level_boundary.add( - Node(11, Point(0, 0)), [level_boundary.Static(level=[1.3])] - ) + # ##Setup level boundary + # level_boundary11 = model.level_boundary.add( + # Node(11, Point(0, 0)), [level_boundary.Static(level=[1.3])] + # ) level_boundary17 = model.level_boundary.add( Node(17, Point(6, 0)), [level_boundary.Static(level=[0.9])] ) @@ -2191,8 +2214,8 @@ def polder_management_model() -> Model: model.link.add(basin6, pump7) model.link.add(pump7, basin9) model.link.add(basin9, outlet10) - model.link.add(level_boundary11, outlet12) - model.link.add(outlet12, basin3) + # model.link.add(level_boundary11, outlet12) + # model.link.add(outlet12, basin3) model.link.add(outlet10, level_boundary17) # Give all nodes subnetwork_id 1