Skip to content

Commit

Permalink
Add compound_variable_id
Browse files Browse the repository at this point in the history
  • Loading branch information
SouthEndMusic committed Apr 15, 2024
1 parent 2a27fb9 commit 17d2a15
Show file tree
Hide file tree
Showing 12 changed files with 52 additions and 20 deletions.
21 changes: 15 additions & 6 deletions core/src/read.jl
Original file line number Diff line number Diff line change
Expand Up @@ -546,17 +546,26 @@ function DiscreteControl(db::DB, config::Config)::DiscreteControl
compound_variable = load_structvector(db, config, DiscreteControlVariableV1)
condition = load_structvector(db, config, DiscreteControlConditionV1)

node_id = NodeID[]
listen_node_id = Vector{NodeID}[]
variable = Vector{String}[]
weight = Vector{Float64}[]
look_ahead = Vector{Float64}[]

for id in unique(condition.node_id)
group = filter(row -> row.node_id == id, compound_variable)
push!(listen_node_id, NodeID.(group.listen_node_type, group.listen_node_id))
push!(variable, group.variable)
push!(weight, coalesce.(group.weight, 1.0))
push!(look_ahead, coalesce.(group.look_ahead, 0.0))
group_id = filter(row -> row.node_id == id, compound_variable)
for group_variable in
StructVector.(IterTools.groupby(row -> row.compound_variable_id, group_id))
first_row = first(group_variable)
push!(node_id, NodeID(NodeType.DiscreteControl, first_row.node_id))
push!(
listen_node_id,
NodeID.(group_variable.listen_node_type, group_variable.listen_node_id),
)
push!(variable, group_variable.variable)
push!(weight, coalesce.(group_variable.weight, 1.0))
push!(look_ahead, coalesce.(group_variable.look_ahead, 0.0))
end
end

condition_value = fill(false, length(condition.node_id))
Expand Down Expand Up @@ -589,7 +598,7 @@ function DiscreteControl(db::DB, config::Config)::DiscreteControl
)

return DiscreteControl(
NodeID.(NodeType.DiscreteControl, condition.node_id), # Not unique
node_id, # Not unique
listen_node_id,
variable,
weight,
Expand Down
2 changes: 2 additions & 0 deletions core/src/schema.jl
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ end

@version DiscreteControlVariableV1 begin
node_id::Int32
compound_variable_id::Int
listen_node_type::String
listen_node_id::Int
variable::String
Expand All @@ -195,6 +196,7 @@ end

@version DiscreteControlConditionV1 begin
node_id::Int32
compound_variable_id::Int
greater_than::Float64
end

Expand Down
1 change: 0 additions & 1 deletion core/src/validation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ sort_by_function(table::StructVector{UserDemandTimeV1}) = sort_by_priority_time
sort_by_function(table::StructVector{BasinSubgridV1}) = sort_by_subgrid_level
sort_by_function(table::StructVector{DiscreteControlVariableV1}) = sort_by_variable
sort_by_function(table::StructVector{DiscreteControlConditionV1}) = sort_by_id_greater_than
sort_by_function(table::StructVector{DiscreteControlLogicV1}) = sort_by_truth_state

const TimeSchemas = Union{
BasinTimeV1,
Expand Down
8 changes: 4 additions & 4 deletions docs/python/examples.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -492,10 +492,10 @@
"model.discrete_control.add(\n",
" Node(7, Point(1.0, 0.0)),\n",
" [\n",
" discrete_control.Variable(\n",
" listen_node_id=[1], listen_node_type=\"Basin\", variable=\"level\"\n",
" ),\n",
" discrete_control.Condition(\n",
" listen_node_id=[1, 1, 1],\n",
" listen_node_type=[\"Basin\", \"Basin\", \"Basin\"],\n",
" variable=[\"level\", \"level\", \"level\"],\n",
" greater_than=[5.0, 10.0, 15.0],\n",
" ),\n",
" discrete_control.Logic(\n",
Expand Down Expand Up @@ -691,7 +691,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Now run the model with `level_setpoint_with_minmax/ribasim.toml`.\n",
"Now run the model with `ribasim level_setpoint_with_minmax/ribasim.toml`.\n",
"After running the model, read back the results:\n"
]
},
Expand Down
2 changes: 1 addition & 1 deletion python/ribasim/ribasim/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ class DiscreteControl(MultiNodeModel):
)
logic: TableModel[DiscreteControlLogicSchema] = Field(
default_factory=TableModel[DiscreteControlLogicSchema],
json_schema_extra={"sort_keys": ["node_id", "truth_state"]},
json_schema_extra={"sort_keys": ["node_id"]},
)


Expand Down
11 changes: 3 additions & 8 deletions python/ribasim/ribasim/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,14 +321,9 @@ def plot_control_listen(self, ax):
df_listen_edge = pd.concat([df_listen_edge, to_add])

# Listen edges from DiscreteControl
for table in (
self.discrete_control.condition.df,
self.discrete_control.variable.df,
):
if table is None:
continue

to_add = table[
df_variable = self.discrete_control.variable.df
if df_variable is not None:
to_add = df_variable[
["node_id", "listen_node_id", "listen_node_type"]
].drop_duplicates()
to_add = to_add[to_add["listen_node_type"] != "compound"]
Expand Down
2 changes: 2 additions & 0 deletions python/ribasim/ribasim/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class BasinTimeSchema(_BaseSchema):

class DiscreteControlConditionSchema(_BaseSchema):
node_id: Series[Int32] = pa.Field(nullable=False, default=0)
compound_variable_id: Series[Int32] = pa.Field(nullable=False, default=0)
greater_than: Series[float] = pa.Field(nullable=False)


Expand All @@ -61,6 +62,7 @@ class DiscreteControlLogicSchema(_BaseSchema):

class DiscreteControlVariableSchema(_BaseSchema):
node_id: Series[Int32] = pa.Field(nullable=False, default=0)
compound_variable_id: Series[Int32] = pa.Field(nullable=False, default=0)
listen_node_type: Series[str] = pa.Field(nullable=False)
listen_node_id: Series[Int32] = pa.Field(nullable=False, default=0)
variable: Series[str] = pa.Field(nullable=False)
Expand Down
6 changes: 6 additions & 0 deletions python/ribasim_testmodels/ribasim_testmodels/allocation.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,9 +410,11 @@ def fractional_flow_subnetwork_model() -> Model:
listen_node_type="FlowBoundary",
listen_node_id=[1],
variable="flow_rate",
compound_variable_id=1,
),
discrete_control.Condition(
greater_than=[3e-3],
compound_variable_id=1,
),
discrete_control.Logic(truth_state=["F", "T"], control_state=["A", "B"]),
],
Expand Down Expand Up @@ -506,9 +508,11 @@ def allocation_example_model() -> Model:
listen_node_type="Basin",
listen_node_id=[5],
variable="level",
compound_variable_id=1,
),
discrete_control.Condition(
greater_than=[0.52],
compound_variable_id=1,
),
discrete_control.Logic(
truth_state=["T", "F"], control_state=["divert", "close"]
Expand Down Expand Up @@ -687,9 +691,11 @@ def main_network_with_subnetworks_model() -> Model:
listen_node_type="Basin",
listen_node_id=[25],
variable="level",
compound_variable_id=1,
),
discrete_control.Condition(
greater_than=[0.003],
compound_variable_id=1,
),
discrete_control.Logic(truth_state=["F", "T"], control_state=["A", "B"]),
],
Expand Down
13 changes: 13 additions & 0 deletions python/ribasim_testmodels/ribasim_testmodels/discrete_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ def pump_discrete_control_model() -> Model:
listen_node_type="Basin",
listen_node_id=[1, 3],
variable="level",
compound_variable_id=[1, 2],
),
discrete_control.Condition(
greater_than=[0.8, 0.4],
compound_variable_id=[1, 2],
),
discrete_control.Logic(
truth_state=["FF", "TF", "FT", "TT"],
Expand All @@ -75,9 +77,11 @@ def pump_discrete_control_model() -> Model:
listen_node_type="Basin",
listen_node_id=[3],
variable="level",
compound_variable_id=1,
),
discrete_control.Condition(
greater_than=[0.45],
compound_variable_id=1,
),
discrete_control.Logic(
truth_state=["T", "F"],
Expand Down Expand Up @@ -149,9 +153,11 @@ def flow_condition_model() -> Model:
listen_node_id=[1],
variable="flow_rate",
look_ahead=60 * 86400,
compound_variable_id=1,
),
discrete_control.Condition(
greater_than=[20 / (86400)],
compound_variable_id=1,
),
discrete_control.Logic(truth_state=["T", "F"], control_state=["off", "on"]),
],
Expand Down Expand Up @@ -214,9 +220,11 @@ def level_boundary_condition_model() -> Model:
listen_node_id=[1],
variable="level",
look_ahead=60 * 86400,
compound_variable_id=1,
),
discrete_control.Condition(
greater_than=[6.0],
compound_variable_id=1,
),
discrete_control.Logic(truth_state=["T", "F"], control_state=["on", "off"]),
],
Expand Down Expand Up @@ -287,6 +295,7 @@ def tabulated_rating_curve_control_model() -> Model:
listen_node_type="Basin",
listen_node_id=[1],
variable="level",
compound_variable_id=1,
),
discrete_control.Condition(
greater_than=[0.5],
Expand Down Expand Up @@ -356,10 +365,12 @@ def level_setpoint_with_minmax_model() -> Model:
listen_node_type="Basin",
listen_node_id=[1],
variable="level",
compound_variable_id=1,
),
discrete_control.Condition(
# min, setpoint, max
greater_than=[5.0, 10.0, 15.0],
compound_variable_id=1,
),
discrete_control.Logic(
truth_state=["FFF", "U**", "T*F", "**D", "TTT"],
Expand Down Expand Up @@ -443,9 +454,11 @@ def compound_variable_condition_model() -> Model:
listen_node_id=[2, 3],
variable="flow_rate",
weight=0.5,
compound_variable_id=1,
),
discrete_control.Condition(
greater_than=[0.5],
compound_variable_id=1,
),
discrete_control.Logic(truth_state=["T", "F"], control_state=["On", "Off"]),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,11 @@ def dutch_waterways_model() -> Model:
listen_node_type="FlowBoundary",
listen_node_id=[1],
variable="flow_rate",
compound_variable_id=1,
),
discrete_control.Condition(
greater_than=[250, 275, 750, 800],
compound_variable_id=1,
),
discrete_control.Logic(
truth_state=["FFFF", "U***", "T**F", "***D", "TTTT"],
Expand Down
2 changes: 2 additions & 0 deletions python/ribasim_testmodels/ribasim_testmodels/invalid.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,11 @@ def invalid_discrete_control_model() -> Model:
# Invalid: this look_ahead will go past the provided timeseries during simulation.
# Invalid: look_ahead must be non-negative.
look_ahead=[100.0, 40 * 24 * 60 * 60, -10.0],
compound_variable_id=[1, 2, 3],
),
discrete_control.Condition(
greater_than=[0.5, 1.5, 1.5],
compound_variable_id=[1, 2, 3],
),
# Invalid: DiscreteControl node #4 has 2 conditions so
# truth states have to be of length 2
Expand Down
2 changes: 2 additions & 0 deletions python/ribasim_testmodels/ribasim_testmodels/pid_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,11 @@ def discrete_control_of_pid_control_model() -> Model:
listen_node_type="LevelBoundary",
listen_node_id=[1],
variable="level",
compound_variable_id=1,
),
discrete_control.Condition(
greater_than=[5.0],
compound_variable_id=1,
),
discrete_control.Logic(
truth_state=["T", "F"], control_state=["target_high", "target_low"]
Expand Down

0 comments on commit 17d2a15

Please sign in to comment.