Commit cb9bcd39 authored by Jesse VanderWees's avatar Jesse VanderWees 🐘

re-arrange examples and add in some of the plots

parent e67a6d26
......@@ -32,7 +32,9 @@ import sphinx_rtd_theme
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'matplotlib.sphinxext.plot_directive',
'sphinx.ext.autodoc',
'sphinx.ext.mathjax',
'sphinx.ext.viewcode',
......@@ -348,7 +350,7 @@ texinfo_documents = [
# -- Hack to strip annotations from Modelica files ------------------------
MODELICA_EXAMPLE_BASE_FOLDER = '../examples'
MODELICA_EXAMPLES = ['basic', 'ensembles', 'goal_programming', 'mixed_integer', 'lookup_tables']
MODELICA_EXAMPLES = ['basic', 'ensemble', 'goal_programming', 'mixed_integer', 'lookup_table']
MODELICA_STRIPPED_EXAMPLE_FOLDER = '_build/mo'
......
......@@ -6,8 +6,8 @@ This section provides examples demonstrating key features of RTC-Tools.
.. toctree::
:maxdepth: 2
example_basic
example_mixed_integer
example_goal_programming
example_lookuptable_storage
example_ensembles
examples/basic
examples/mixed_integer
examples/goal_programming
examples/lookup_table
examples/ensemble
......@@ -51,7 +51,7 @@ program. Make sure to load the Deltares libray before loading the example:
Once loaded, we have an OpenModelica Connection Editor window that looks like
this:
.. image:: images/simple_storage_openmodelica.png
.. image:: ../images/simple_storage_openmodelica.png
The model ``Example.mo`` represents a simple system with the following
......@@ -74,7 +74,7 @@ and drag between the ports on the elements.
In text mode, the Modelica model looks as follows (with
annotation statements removed):
.. literalinclude:: _build/mo/basic.mo
.. literalinclude:: ../_build/mo/basic.mo
:language: modelica
:lineno-match:
......@@ -125,7 +125,7 @@ package ``run_optimization_problem`` form the ``rtctools.util`` package, and
any extra packages we want to use. For this example, the import block looks
like:
.. literalinclude:: ../examples/basic/src/example.py
.. literalinclude:: ../../examples/basic/src/example.py
:language: python
:lines: 1-5
:lineno-match:
......@@ -139,7 +139,7 @@ parent classes each perform different tasks realted to importing and exporting
data and solving the optimization problem. Each imported class makes a set of
methods available to the our optimization class.
.. literalinclude:: ../examples/basic/src/example.py
.. literalinclude:: ../../examples/basic/src/example.py
:language: python
:pyobject: Example
:lineno-match:
......@@ -148,7 +148,7 @@ methods available to the our optimization class.
The next, we define an objective function. This is a class method that returns
the value that needs to be minimized.
.. literalinclude:: ../examples/basic/src/example.py
.. literalinclude:: ../../examples/basic/src/example.py
:language: python
:pyobject: Example.objective
:lineno-match:
......@@ -160,7 +160,7 @@ at an individual timestep, we could define it inside the ``constraints`` method.
Other parent classes also declare this method, so we call the ``super()`` method
so that we don't overwrite their behaviour.
.. literalinclude:: ../examples/basic/src/example.py
.. literalinclude:: ../../examples/basic/src/example.py
:language: python
:pyobject: Example.path_constraints
:lineno-match:
......@@ -172,7 +172,7 @@ To make our script run, at the bottom of our file we just have to call
the ``run_optimization_problem()`` method we imported on the optimization
problem class we just created.
.. literalinclude:: ../examples/basic/src/example.py
.. literalinclude:: ../../examples/basic/src/example.py
:language: python
:lineno-match:
:start-after: # Run
......@@ -182,7 +182,7 @@ The Whole Script
All together, the whole example script is as follows:
.. literalinclude:: ../examples/basic/src/example.py
.. literalinclude:: ../../examples/basic/src/example.py
:language: python
:lineno-match:
......@@ -201,7 +201,7 @@ The results from the run are found in ``output/timeseries_export.csv``. Any
CSV-reading software can import it, but this is what the results look like when
plotted in Microsoft Excel:
.. image:: images/basic_example_resultplot.png
.. image:: ../images/basic_resultplot.png
This plot shows that the operator is able to keep the water level within the
bounds over the entire time horizon and end with a full reservoir.
......
Using Forecast Ensembles
~~~~~~~~~~~~~~~~~~~~~~~~
Using an Ensemble Forecast
~~~~~~~~~~~~~~~~~~~~~~~~~~
.. note::
This example is an extension of :doc:`example_lookuptable_storage`. It
This example is an extension of :doc:`lookup_table`. It
assumes prior knowledge of goal programming and the lookuptables components
of RTC-Tools. If you are a first-time user of RTC-Tools, see
:doc:`example_basic`.
:doc:`basic`.
Then biggest change to RTC-Tools when using ensembles is the structure of the
directory. The folder ``<installation directory>\RTCTools2\examples\ensembles``
Then biggest change to RTC-Tools when using an ensemble is the structure of the
directory. The folder ``<installation directory>\RTCTools2\examples\ensemble``
contains a complete RTC-Tools ensemble optimization problem. An RTC-Tools
ensemble directory has the following structure:
......@@ -20,8 +20,8 @@ ensemble directory has the following structure:
* ``input``: This folder contains the model input data pertaining to each
ensemble member:
* ``ensemble.csv``: a file where the names and probabilities of the ensembles
are defined
* ``ensemble.csv``: a file where the names and probabilities of the ensemble
members are defined
* ``forcast1``
......@@ -53,17 +53,17 @@ The Model
.. note::
This example uses the same hydraulic model as the basic example. For a
detalied explaination of the hydraulic model, see :doc:`example_basic`.
detalied explaination of the hydraulic model, see :doc:`basic`.
In OpenModelica Connection Editor, the model looks like this:
.. image:: images/simple_storage_openmodelica.png
.. image:: ../images/simple_storage_openmodelica.png
In text mode, the Modelica model is as follows (with annotation statements
removed):
.. literalinclude:: _build/mo/ensembles.mo
.. literalinclude:: ../_build/mo/ensemble.mo
:language: modelica
:lineno-match:
......@@ -92,7 +92,7 @@ Declaring Goals
First, we have a high priority goal to keep the water volume within a minimum
and maximum.
.. literalinclude:: ../examples/ensembles/src/example.py
.. literalinclude:: ../../examples/ensemble/src/example.py
:language: python
:pyobject: WaterVolumeRangeGoal
:lineno-match:
......@@ -100,7 +100,7 @@ and maximum.
We also want to save energy, so we define a goal to minimize ``Q_release``. This
goal has a lower priority.
.. literalinclude:: ../examples/ensembles/src/example.py
.. literalinclude:: ../../examples/ensemble/src/example.py
:language: python
:pyobject: MinimizeQreleaseGoal
:lineno-match:
......@@ -110,7 +110,7 @@ Importing Packages
For this example, the import block is as follows:
.. literalinclude:: ../examples/ensembles/src/example.py
.. literalinclude:: ../../examples/ensemble/src/example.py
:language: python
:lines: 1-11
:lineno-match:
......@@ -121,7 +121,7 @@ Optimization Problem
Next, we construct the class by declaring it and inheriting the desired parent
classes.
.. literalinclude:: ../examples/ensembles/src/example.py
.. literalinclude:: ../../examples/ensemble/src/example.py
:language: python
:pyobject: Example
:lineno-match:
......@@ -129,7 +129,7 @@ classes.
We turn on ensemble mode by setting ``csv_ensemble_mode = True``:
.. literalinclude:: ../examples/ensembles/src/example.py
.. literalinclude:: ../../examples/ensemble/src/example.py
:language: python
:lines: 50-51
:lineno-match:
......@@ -139,20 +139,20 @@ a line to it to create a variable for storing intermediate results. To do this,
we declare a new ``pre()`` method, call ``super(Example, self).pre()`` to ensure
that the original method runs unmodified, and add in a variable declaration to
store our list of intermediate results. This variable is a dict, reflecting the
need to store results from multiple ensembles.
need to store results from multiple ensemble.
Because the timeseries we set will be the same for both ensemble members, we
also make sure that the timeseries we set are set for both ensemble members
using for loops.
.. literalinclude:: ../examples/ensembles/src/example.py
.. literalinclude:: ../../examples/ensemble/src/example.py
:language: python
:pyobject: Example.pre
:lineno-match:
Now we pass in the goals:
.. literalinclude:: ../examples/ensembles/src/example.py
.. literalinclude:: ../../examples/ensemble/src/example.py
:language: python
:pyobject: Example.path_goals
:lineno-match:
......@@ -160,14 +160,14 @@ Now we pass in the goals:
We define the ``priority_completed()`` method. We ensure that it stores the
results from both ensemble members.
.. literalinclude:: ../examples/ensembles/src/example.py
.. literalinclude:: ../../examples/ensemble/src/example.py
:language: python
:pyobject: Example.priority_completed
:lineno-match:
We output our intermediate results using the ``post()`` method:
.. literalinclude:: ../examples/ensembles/src/example.py
.. literalinclude:: ../../examples/ensemble/src/example.py
:language: python
:pyobject: Example.post
:lineno-match:
......@@ -175,7 +175,7 @@ We output our intermediate results using the ``post()`` method:
Finally, we want to apply some additional configuration, reducing the amount of
information the solver outputs:
.. literalinclude:: ../examples/ensembles/src/example.py
.. literalinclude:: ../../examples/ensemble/src/example.py
:language: python
:pyobject: Example.solver_options
:lineno-match:
......@@ -187,7 +187,7 @@ To make our script run, at the bottom of our file we just have to call
the ``run_optimization_problem()`` method we imported on the optimization
problem class we just created.
.. literalinclude:: ../examples/ensembles/src/example.py
.. literalinclude:: ../../examples/ensemble/src/example.py
:language: python
:lineno-match:
:start-after: # Run
......@@ -197,7 +197,7 @@ The Whole Script
All together, the whole example script is as follows:
.. literalinclude:: ../examples/ensembles/src/example.py
.. literalinclude:: ../../examples/ensemble/src/example.py
:language: python
:lineno-match:
......@@ -228,7 +228,7 @@ should print out the following lines::
Level goal satisfied at 12 of 12 time steps
Integral of Q_release = 16.26
This is the same output as the output for :doc:`example_mixed_integer`, except
This is the same output as the output for :doc:`mixed_integer`, except
now the output for each ensemble is printed.
Extracting Results
......@@ -242,4 +242,4 @@ plotted in Microsoft Excel:
TODO: Plot these results
.. image:: images/lookuptable_example_resultplot.png
.. image:: ../images/lookuptable_resultplot.png
......@@ -6,7 +6,7 @@ Defining Multiple Objectives
This example focuses on how to implement multiobjective optimization in
RTC-Tools using Goal Programming. It assumes basic exposure to
RTC-Tools. If you are a first-time user of RTC-Tools, see
:doc:`example_basic`.
:doc:`basic`.
Goal programming is a way to satisfy (sometimes conflicting) goals by ranking
the goals by priority. The optimization algorithm will attempt to optimize each
......@@ -34,7 +34,7 @@ The Model
This example uses the same hydraulic model as the MILP example. For a
detalied explaination of the hydraulic model, including how to to formulate
mixed integers in your model, see :doc:`example_mixed_integer`.
mixed integers in your model, see :doc:`mixed_integer`.
For this example, the model represents a typical setup for the dewatering of
lowland areas. Water is routed from the hinterland (modeled as discharge
......@@ -47,12 +47,12 @@ weir). If the sea water level is higher than in the canal, water must be pumped.
In OpenModelica Connection Editor, the model looks like this:
.. image:: images/orifice_vs_pump_openmodelica.png
.. image:: ../images/orifice_vs_pump_openmodelica.png
In text mode, the Modelica model looks as follows (with annotation statements
removed):
.. literalinclude:: _build/mo/goal_programming.mo
.. literalinclude:: ../_build/mo/goal_programming.mo
:language: modelica
:lineno-match:
......@@ -80,7 +80,7 @@ Importing Packages
For this example, the import block is as follows:
.. literalinclude:: ../examples/goal_programming/src/example.py
.. literalinclude:: ../../examples/goal_programming/src/example.py
:language: python
:lines: 1-8
:lineno-match:
......@@ -89,12 +89,12 @@ Declaring Goals
'''''''''''''''
Goals are defined as classes that inherit the ``Goal`` parent class. The
components of goals can be found in :doc:`multi_objective`.
components of goals can be found in :doc:`../optimization/multi_objective`.
First, we have a high priority goal to keep the water level within a minimum and
maximum:
.. literalinclude:: ../examples/goal_programming/src/example.py
.. literalinclude:: ../../examples/goal_programming/src/example.py
:language: python
:pyobject: WaterLevelRangeGoal
:lineno-match:
......@@ -102,7 +102,7 @@ maximum:
We also want to save energy, so we define a goal to minimize ``Q_pump``. This
goal has a lower priority.
.. literalinclude:: ../examples/goal_programming/src/example.py
.. literalinclude:: ../../examples/goal_programming/src/example.py
:language: python
:pyobject: MinimizeQpumpGoal
:lineno-match:
......@@ -113,7 +113,7 @@ Optimization Problem
Next, we construct the class by declaring it and inheriting the desired parent
classes.
.. literalinclude:: ../examples/goal_programming/src/example.py
.. literalinclude:: ../../examples/goal_programming/src/example.py
:language: python
:pyobject: Example
:lineno-match:
......@@ -126,7 +126,7 @@ at an individual timestep, define it inside the ``constraints()`` method.
Other parent classes also declare this method, so we call the ``super()`` method
so that we don't overwrite their behaviour.
.. literalinclude:: ../examples/goal_programming/src/example.py
.. literalinclude:: ../../examples/goal_programming/src/example.py
:language: python
:pyobject: Example.path_constraints
:lineno-match:
......@@ -135,7 +135,7 @@ Now we pass in the goals. We want to apply our goals to every timestep, so we
use the ``path_goals()`` method. This is a method that returns a list of the goals
we defined above.
.. literalinclude:: ../examples/goal_programming/src/example.py
.. literalinclude:: ../../examples/goal_programming/src/example.py
:language: python
:pyobject: Example.path_goals
:lineno-match:
......@@ -151,7 +151,7 @@ we declare a new ``pre()`` method, call ``super(Example, self).pre()`` to ensure
that the original method runs unmodified, and add in a variable declaration to
store our list of intermediate results:
.. literalinclude:: ../examples/goal_programming/src/example.py
.. literalinclude:: ../../examples/goal_programming/src/example.py
:language: python
:pyobject: Example.pre
:lineno-match:
......@@ -160,7 +160,7 @@ Next, we define the ``priority_completed()`` method to inspect and summerize the
results. These are appended to our intermediate results variable after each
priority is completed.
.. literalinclude:: ../examples/goal_programming/src/example.py
.. literalinclude:: ../../examples/goal_programming/src/example.py
:language: python
:pyobject: Example.priority_completed
:lineno-match:
......@@ -169,7 +169,7 @@ We want some way to output our intermediate results. This is accomplished using
the ``post()`` method. Again, we nedd to call the ``super()`` method to avoid
overwiting the internal method.
.. literalinclude:: ../examples/goal_programming/src/example.py
.. literalinclude:: ../../examples/goal_programming/src/example.py
:language: python
:pyobject: Example.post
:lineno-match:
......@@ -177,7 +177,7 @@ overwiting the internal method.
Finally, we want to apply some additional configuration, reducing the amount of
information the solver outputs:
.. literalinclude:: ../examples/goal_programming/src/example.py
.. literalinclude:: ../../examples/goal_programming/src/example.py
:language: python
:pyobject: Example.solver_options
:lineno-match:
......@@ -189,7 +189,7 @@ To make our script run, at the bottom of our file we just have to call
the ``run_optimization_problem()`` method we imported on the optimization
problem class we just created.
.. literalinclude:: ../examples/goal_programming/src/example.py
.. literalinclude:: ../../examples/goal_programming/src/example.py
:language: python
:lineno-match:
:start-after: # Run
......@@ -199,7 +199,7 @@ The Whole Script
All together, the whole example script is as follows:
.. literalinclude:: ../examples/goal_programming/src/example.py
.. literalinclude:: ../../examples/goal_programming/src/example.py
:language: python
:lineno-match:
......@@ -229,11 +229,8 @@ Extracting Results
------------------
The results from the run are found in ``output/timeseries_export.csv``. Any
CSV-reading software can import it, but this is what the results look like when
plotted in Microsoft Excel:
CSV-reading software can import it, but this is how results can be plotted using
the python library matplotlib:
.. note::
TODO: Plot these results
.. image:: images/goal_example_resultplot.png
.. plot:: examples/pyplots/goal_programming_results.py
:include-source:
......@@ -6,11 +6,11 @@ Using Lookup Tables
This example focuses on how to implement non-linear storage elements in
RTC-Tools using lookup tables . It assumes basic exposure to
RTC-Tools. If you are a first-time user of RTC-Tools, see
:doc:`example_basic`.
:doc:`basic`.
This example also uses goal programming in the formulation. If you are
unfamiliar with goal programming, please see
:doc:`example_goal_programming`.
:doc:`goal_programming`.
The Model
......@@ -19,17 +19,17 @@ The Model
.. note::
This example uses the same hydraulic model as the basic example. For a
detalied explaination of the hydraulic model, see :doc:`example_basic`.
detalied explaination of the hydraulic model, see :doc:`basic`.
In OpenModelica Connection Editor, the model looks like this:
.. image:: images/simple_storage_openmodelica.png
.. image:: ../images/simple_storage_openmodelica.png
In text mode, the Modelica model is as follows (with annotation statements
removed):
.. literalinclude:: _build/mo/lookup_tables.mo
.. literalinclude:: ../_build/mo/lookup_table.mo
:language: modelica
:lineno-match:
......@@ -55,7 +55,7 @@ Declaring Goals
'''''''''''''''
Goals are defined as classes that inherit the ``Goal`` parent class. The
components of goals can be found in :doc:`multi_objective`.
components of goals can be found in :doc:`../optimization/multi_objective`.
First, we have a high priority goal to keep the water volume within a minimum
and maximum. We use a water volume goal instead of a water level goal when the
......@@ -67,7 +67,7 @@ convert the water level goals into volume goals within the optimization problem
class, so we define the ``__init__()`` method so we can pass the values of the
goals in later.
.. literalinclude:: ../examples/lookup_tables/src/example.py
.. literalinclude:: ../../examples/lookup_table/src/example.py
:language: python
:pyobject: WaterVolumeRangeGoal
:lineno-match:
......@@ -75,7 +75,7 @@ goals in later.
We also want to save energy, so we define a goal to minimize ``Q_release``. This
goal has a lower priority.
.. literalinclude:: ../examples/lookup_tables/src/example.py
.. literalinclude:: ../../examples/lookup_table/src/example.py
:language: python
:pyobject: MinimizeQreleaseGoal
:lineno-match:
......@@ -85,7 +85,7 @@ Importing Packages
For this example, the import block is as follows:
.. literalinclude:: ../examples/lookup_tables/src/example.py
.. literalinclude:: ../../examples/lookup_table/src/example.py
:language: python
:lines: 1-10
:lineno-match:
......@@ -96,7 +96,7 @@ Optimization Problem
Next, we construct the class by declaring it and inheriting the desired parent
classes.
.. literalinclude:: ../examples/lookup_tables/src/example.py
.. literalinclude:: ../../examples/lookup_table/src/example.py
:language: python
:pyobject: Example
:lineno-match:
......@@ -111,11 +111,11 @@ store our list of intermediate results.
We also want to convert our water level rane goal into a water volume range
goal. We can access the spline function describing the water level-storage
relation using the ``lookup_tables()`` method. We cache the functions for
relation using the ``lookup_table()`` method. We cache the functions for
convenience. The ``lookup_storage_V()`` method can convert timeseries objects,
and we save the water volume goal bounds as timeseries.
.. literalinclude:: ../examples/lookup_tables/src/example.py
.. literalinclude:: ../../examples/lookup_table/src/example.py
:language: python
:pyobject: Example.pre
:lineno-match:
......@@ -124,14 +124,14 @@ Notice that H_max was not defined in pre(). This is because it was defined as a
timeseries import. We access timeseries using get_timeseries() and store them
using set_timeseries(). Once a timeseries is set, we can access it later. In
addition, all timeseries that are set are automatically included in the output
file. You can find more information on timeseries here :doc:`basics`.
file. You can find more information on timeseries here :doc:`../optimization/basics`.
Now we pass in the goals. We want to apply our goals to every timestep, so we
use the ``path_goals()`` method. This is a method that returns a list of the
goals we defined above. The ``WaterVolumeRangeGoal`` needs to be instantiated
with the new water volume timeseries we just defined.
.. literalinclude:: ../examples/lookup_tables/src/example.py
.. literalinclude:: ../../examples/lookup_table/src/example.py
:language: python
:pyobject: Example.path_goals
:lineno-match:
......@@ -145,7 +145,7 @@ We define the ``priority_completed()`` method to inspect and summerize the
results. These are appended to our intermediate results variable after each
priority is completed.
.. literalinclude:: ../examples/lookup_tables/src/example.py
.. literalinclude:: ../../examples/lookup_table/src/example.py
:language: python
:pyobject: Example.priority_completed
:lineno-match:
......@@ -155,7 +155,7 @@ to call the ``super()`` method to avoid overwiting the internal method. We can
convert volmes back into water levels using an inverted version of the lookup
table.
.. literalinclude:: ../examples/lookup_tables/src/example.py
.. literalinclude:: ../../examples/lookup_table/src/example.py
:language: python
:pyobject: Example.post
:lineno-match:
......@@ -163,7 +163,7 @@ table.
Finally, we want to apply some additional configuration, reducing the amount of
information the solver outputs:
.. literalinclude:: ../examples/lookup_tables/src/example.py
.. literalinclude:: ../../examples/lookup_table/src/example.py
:language: python
:pyobject: Example.solver_options
:lineno-match:
......@@ -175,7 +175,7 @@ To make our script run, at the bottom of our file we just have to call
the ``run_optimization_problem()`` method we imported on the optimization
problem class we just created.
.. literalinclude:: ../examples/lookup_tables/src/example.py
.. literalinclude:: ../../examples/lookup_table/src/example.py
:language: python
:lineno-match:
:start-after: # Run
......@@ -185,7 +185,7 @@ The Whole Script
All together, the whole example script is as follows:
.. literalinclude:: ../examples/lookup_tables/src/example.py
.. literalinclude:: ../../examples/lookup_table/src/example.py
:language: python
:lineno-match:
......@@ -222,4 +222,4 @@ plotted in Microsoft Excel:
TODO: Plot these results
.. image:: images/lookuptable_example_resultplot.png
.. image:: ../images/lookuptable_resultplot.png
......@@ -5,7 +5,7 @@ Mixed Integer Optimization: Pumps and Orifices
This example focuses on how to incorporate mixed integer components into a
hydraulic model, and assumes basic exposure to RTC-Tools. To start with
basics, see :doc:`example_basic`.
basics, see :doc:`basic`.
The Model
......@@ -45,12 +45,12 @@ elements:
* a pump,
* an orifice.
.. image:: images/orifice_vs_pump_openmodelica.png
.. image:: ../images/orifice_vs_pump_openmodelica.png
In text mode, the Modelica model looks as follows (with annotation statements
removed):
.. literalinclude:: _build/mo/mixed_integer.mo
.. literalinclude:: ../_build/mo/mixed_integer.mo
:language: modelica
:lineno-match:
......@@ -65,10 +65,11 @@ element only. It extends the ``HQOnePort`` which again inherits from the
connector ``HQPort``.
In addition to elements, the input variables ``Q_in``, ``H_sea``, ``Q_pump``,
and ``Q_orifice`` are also defined. Because we want to view the water level in
the storage element in the output file, we also define an output
variable ``water_level``. In the ``equation`` section, equations defined to
relate the inputs to the appropriate water system elements.
and ``Q_orifice`` are also defined. Because we want to view the water levels in
the storage element in the output file, we also define output
variables ``storage_level`` and ``sea_level``. In the ``equation`` section,
equations are defined to relate the inputs and outputs to the appropriate water
system elements.
To maintain the linearity of the model, we input the Boolean ``is_downhill`` as
a way to keep track of whether water can flow by gravity to the sea. This
......@@ -95,7 +96,7 @@ Importing Packages
For this example, the import block is as follows:
.. literalinclude:: ../examples/mixed_integer/src/example.py
.. literalinclude:: ../../examples/mixed_integer/src/example.py
:language: python
:lines: 1-6
:lineno-match:
......@@ -109,7 +110,7 @@ Optimization Problem
Next, we construct the class by declaring it and inheriting the desired parent
classes.
.. literalinclude:: ../examples/mixed_integer/src/example.py
.. literalinclude:: ../../examples/mixed_integer/src/example.py
:language: python
:pyobject: Example
:lineno-match:
......@@ -119,7 +120,7 @@ Now we define an objective function. This is a class method that returns the
value that needs to be minimized. Here we specify that we want to minimize the
volume pumped:
.. literalinclude:: ../examples/mixed_integer/src/example.py
.. literalinclude:: ../../examples/mixed_integer/src/example.py
:language: python
:pyobject: Example.objective
:lineno-match:
......@@ -131,7 +132,7 @@ at an individual timestep, define it inside the ``constraints`` method.
Other parent classes also declare this method, so we call the ``super()`` method
so that we don't overwrite their behaviour.
.. literalinclude:: ../examples/mixed_integer/src/example.py
.. literalinclude:: ../../examples/mixed_integer/src/example.py
:language: python
:pyobject: Example.path_constraints
:lineno-match:
......@@ -139,7 +140,7 @@ so that we don't overwrite their behaviour.
Finally, we want to apply some additional configuration, reducing the amount of
information the solver outputs:
.. literalinclude:: ../examples/mixed_integer/src/example.py
.. literalinclude:: ../../examples/mixed_integer/src/example.py
:language: python
:pyobject: Example.solver_options
:lineno-match:
......@@ -151,7 +152,7 @@ To make our script run, at the bottom of our file we just have to call
the ``run_optimization_problem()`` method we imported on the optimization
problem class we just created.
.. literalinclude:: ../examples/mixed_integer/src/example.py
.. literalinclude:: ../../examples/mixed_integer/src/example.py
:language: python
:lineno-match:
:start-after: # Run
......@@ -161,7 +162,7 @@ The Whole Script
All together, the whole example script is as follows:
.. literalinclude:: ../examples/mixed_integer/src/example.py
.. literalinclude:: ../../examples/mixed_integer/src/example.py
:language: python
:lineno-match:
......@@ -175,12 +176,8 @@ Extracting Results
------------------
The results from the run are found in ``output/timeseries_export.csv``. Any
CSV-reading software can import it, but this is what the results look like when
plotted in Microsoft Excel:
CSV-reading software can import it, but this is how results can be plotted using
the python library matplotlib:
.. note::
The results are ugly- perhaps we should tweak the example. There is funny
hydraulics going on. Then we can insert an image of results.
.. image:: images/milp_example_resultplot.png
.. plot:: examples/pyplots/mixed_integer_results.py
:include-source:
......@@ -3,35 +3,43 @@ import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from datetime import datetime
data_path = '../../../examples/mixed_integer/output/timeseries_export.csv'
delimiter = ','
# Import Data
ncols = len(np.genfromtxt(data_path, max_rows=1, delimiter=delimiter))
datefunc = lambda x: datetime.strptime(x, '%Y-%m-%d %H:%M:%S')
results = np.genfromtxt('../examples/mixed_integer/output/timeseries_export.csv',
converters={0: datefunc},
dtype='object, float, float, float, float, float',
delimiter=",",
names=True)
results = np.genfromtxt(data_path, converters={0: datefunc}, delimiter=delimiter,
dtype='object' + ',float' * (ncols - 1), names=True)
# Generate Plot
f, axarr = plt.subplots(2, sharex=True)
axarr[0].set_title('Water Level and Discharge')
axarr[0].plot(results['time'], results['storage_level'], label='Storage', linewidth=2, color='b')
axarr[0].plot(results['time'], results['sea_level'], label='Sea', linewidth=2, color='m')
# Upper subplot
axarr[0].set_ylabel('Water Level [m]')
axarr[1].plot(results['time'], results['Q_orifice'], label='Orifice', linewidth=2, color='g')
axarr[1].plot(results['time'], results['Q_pump'], label='Pump', linewidth=2, color='r')
axarr[1].xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
axarr[0].plot(results['time'], results['storage_level'], label='Storage',
linewidth=2, color='b')
axarr[0].plot(results['time'], results['sea_level'], label='Sea',
linewidth=2, color='m')
axarr[0].plot(results['time'], 0.5 * np.ones_like(results