Code Structure Overview¶
MORL4Water models a multi-objective water resource management environment by simulating interconnected components like reservoirs, irrigation districts, power plants, inflows, and catchments. It is organized around facilities that exchange water via flows, all within an environment managed by a custom (MO)Gym-compatible class.
Top-level, general structure of the codebase:
morl4water
├── core
│ ├── envs
│ │ └── water_management_system.py
│ ├── models
│ │ ├── catchment.py
│ │ ├── facility.py
│ │ ├── flow.py
│ │ ├── irrigation_district.py
│ │ ├── objective.py
│ │ ├── power_plant.py
│ │ ├── reservoir.py
│ │ ├── reservoir_with_pump.py
│ │ └── weir.py
Core Environment: WaterManagementSystem
¶
The WaterManagementSystem
class, defined in core/envs/water_management_system.py
, implements a custom environment that is fully compatible with mo-gymnasium.Env
. It simulates a complex water infrastructure system over time.
Key Features¶
Inherits from
gym.Env
Supports multi-objective settings
Fully vectorized observation and reward spaces
Modular design via a list of facilities and flow objects
Components of the Gym Environment API¶
__init__()
¶
Initializes the environment with:
A list of components (facilities and flows)
A dictionary of reward signals
Start date and timestep duration
Optional timestamp and custom reward objectives
Determines:
observation_space
andaction_space
reward_space
max_capacities
(used to normalize observations)
reset(seed, options)
¶
Resets the environment state:
Sets date and timestep to initial values
Resets each facility’s internal state
Returns normalized observation and info dictionary
step(action)
¶
Core simulation logic:
Propagates actions to
ControlledFacility
objectsSteps through all components (facilities, flows)
Aggregates rewards based on objectives
Advances the environment time
Returns:
observation
: normalized state ofControlledFacility
, which represents volume of water stored at the specific timestep in the Resevoirreward
: vector of objective valuesterminated
: True if the capacity of any Facility is exceededtruncated
: False unless simulation endsinfo
: dictionary with simulation metadata
Model Components¶
Facility
and ControlledFacility
¶
Base classes in
core/models/facility.py
Facility
is for passive components (e.g. irrigation districts)ControlledFacility
is for components with actions (reservoirs, reservoirs with a pump and weir)Provide common methods:
reset()
,step()
,determine_reward()
,determine_observation()
Flow Routing: flow.py
¶
Flow
,Inflow
, andOutflow
classes define directed edges between componentsHandle delay, capacity, and direction of water flow
Connect upstream and downstream
Facility
instances
Objective Functions: objective.py
¶
Provides a library of scalarizable reward functions:
deficit_minimised
,scalar_identity
, etc.
Used by each facility to compute its local reward contribution
Specialized Components¶
Reservoir
,ReservoirWithPump
(storage and release logic)PowerPlant
(hydropower generation)IrrigationDistrict
(demand satisfaction)Catchment
(rainfall accumulation)Weir
(overflow mechanisms)
Each inherits from either Facility
or ControlledFacility
and overrides reward and flow handling logic.
Interaction Flow¶
User constructs an environment (e.g., via
create_nile_river_env()
)Gym agent calls
reset()
andstep(action)
Each component updates state, computes reward
WaterManagementSystem
aggregates outputs and steps simulation
Extensibility¶
New components can be added by subclassing
Facility
Objectives can be extended in
objective.py
Works seamlessly with MO-RL algorithms via
gymnasium
Data Flow in the Environment¶
The environment simulates time-dependent water movement across interconnected infrastructure components. Each timestep, the environment performs the following sequence:
External Inputs
Components such asInflow
andCatchment
introduce water into the system using external time-series data (e.g., rainfall or river inflows).Processing Nodes
Reservoir
,PowerPlant
, andWeir
components store, transform, or release water based on physical constraints and action inputs.IrrigationDistrict
components withdraw water based on predefined or data-driven demand.
Routing
Flow
,Inflow
, andOutflow
classes connect components, enforcing directionality, capacity limits, and transport delays.
State Updates
Each facility and flow updates its internal state.
The environment collects and normalizes observations across all
ControlledFacility
components.
Reward Calculation
Rewards are computed at the facility level using objective functions defined in
objective.py
.The environment aggregates and normalizes these values into a vectorized reward output.
Code Structure