Skip to content

Instantly share code, notes, and snippets.

@jetuk
Created October 4, 2016 21:05
Show Gist options
  • Save jetuk/817dcffd6e6643581895f892a12f7667 to your computer and use it in GitHub Desktop.
Save jetuk/817dcffd6e6643581895f892a12f7667 to your computer and use it in GitHub Desktop.
Example of Scottish DO method with Pywr
{
"demand_scaling": {
"minimum": 0.8,
"maximum": 1.8,
"steps": 50
},
"nodes" : ["demand"],
"recorder" : "deficit_freq"
}
from pywr.core import Model, Scenario
from pywr.parameters import ConstantScenarioParameter, BaseParameter, AggregatedParameter, ConstantParameter
def update_node_max_flow(node, factor_parameter):
existing_param = node.max_flow
if not isinstance(existing_param, BaseParameter):
# Convert float parameters to Parameter instances
existing_param = ConstantParameter(existing_param)
new_param = AggregatedParameter([existing_param, factor_parameter], "product")
node.max_flow = new_param
def apply_demand_scenario(model, demand_nodes, demand_factors):
demand_scenario = Scenario(model, 'demand scaling', size=len(demand_factors))
factor_param = ConstantScenarioParameter(demand_scenario, demand_factors)
for demand_node in demand_nodes:
node = model.nodes[demand_node]
update_node_max_flow(node, factor_param)
if __name__ == '__main__':
import argparse
import json
import numpy as np
parser = argparse.ArgumentParser(description='Scottish deployable output method.')
parser.add_argument('config', type=str, help='JSON file defining Scottish method configuration.')
parser.add_argument('model', type=str, help='JSON file defining the Pywr model.')
args = parser.parse_args()
with open(args.config, 'r') as fh:
config = json.load(fh)
# Load the model
model = Model.load(args.model)
# Setup the demand scaling
scale_params = config['demand_scaling']
factors = np.linspace(scale_params['minimum'], scale_params['maximum'], scale_params['steps'])
apply_demand_scenario(model, config['nodes'], factors)
# Check the recorder exists
rec = model.recorders[config['recorder']]
# Run the model
model.run()
# Plot the results
deficits = np.asarray(rec.values())
from matplotlib import pyplot as plt
fig, ax = plt.subplots()
ax.scatter(factors, deficits)
ax.grid(True)
ax.set_xlabel('Demand scaling factor')
ax.set_ylabel(config['recorder'])
plt.show()
{
"metadata": {
"title": "A simple reservoir example.",
"description": "A model with a reservoir.",
"minimum_version": "0.1"
},
"timestepper": {
"start": "2015-09-01",
"end": "2016-08-31",
"timestep": 1
},
"nodes": [
{
"name": "inflow",
"type": "catchment",
"flow": {
"type": "monthlyprofile",
"values": [1300, 1000, 900, 864, 450, 300, 216, 280, 360, 432, 800, 1100]
}
},
{
"name": "reservoir",
"type": "Storage",
"max_volume": 200000,
"initial_volume": 100000
},
{
"name": "waste",
"type": "Output"
},
{
"name": "demand",
"type": "Output",
"max_flow": 800,
"cost": -10
}
],
"edges": [
["inflow", "reservoir"],
["reservoir", "waste"],
["reservoir", "demand"]
],
"recorders": {
"deficit_freq" : {
"type": "DeficitFrequencyNodeRecorder",
"node": "demand"
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment