Giter Club home page Giter Club logo

osier's Introduction

osier

/ˈōZHər/
Open source multi-objective energy system framework

status Build Status Documentation Status

Installation

osier is available through PyPI. It may be installed with

python -m pip install osier pyomo==6.4.1

or by cloning this repository and building from source:

git clone [email protected]:arfc/osier.git  # requires ssh-keys
# or
git clone https://github.com/arfc/osier.git
cd osier
# for a basic installation
pip install .
# to also install the documentation dependencies
pip install .[doc]

# followed by 
pip install pyomo==6.4.1
Although `pyomo` is a dependency, the current version of `pyomo` (6.7.1, as of 2/29/24) has a bug
that prints erroneous errors during an `osier` simulation. Therefore, users are recommended to 
install a specific version of `pyomo` after the main installation of `osier`. There is an open issue [#50](https://github.com/arfc/osier/issues/50) 
related to this concern.

Documentation

The documentation for osier can be viewed here. You can also build the docs locally with:

cd osier/docs
make html
cd build/html
# to serve the documentation
python -m http.server

Tests

osier's tests can be run by executing pytest in the top-level directory of osier.

Contributing

Contributions to osier are welcome. For details on how to make bug reports, pull requests, and other information, check the contributing page.

Credits

Some of the documentation infrastructure was inspired by and borrowed from the watts documentation.

osier's People

Contributors

samgdotson avatar lukeseifert avatar yardasol avatar abachma2 avatar nsryan2 avatar smpark7 avatar

Stargazers

Robin Lovelace avatar Hussein Mahfouz avatar longritian avatar Bankn8II©$A avatar PEP 8 Speaks avatar

Watchers

Madicken Munk avatar  avatar

osier's Issues

Documentation on penalty

This issue request better documentation about the penalty attribute in the DipatchModel class in osier/models/dispatch.py.

The current docstring in the class says that a user may need to tune this. I think this needs to expanded some in a theory section of documentation. The expanded discussion should include topics such as:

  • What would be an instance when a user would need to tune the parameter
  • What are effects of increasing or decreasing the parameter

Although this is a small part of the code that probably won't be adjusted much, I think that calling it out in the docstring brings up some of these questions. Especially since this parameter was introduced to prevent unrealistic behavior in the models.

Properly handle units in the dispatch model

Currently, the DispatchModel handles units for the net demand parameter, badly. For example,

import numpy as np
net_dem = np.ones(24)

assumes that net_dem is in units of MWh.
However, users can currently specify a time_delta for the DispatchModel (required for ramping constraints) which leads to the following issue.

from osier import DispatchModel
from unyt import minute
model = DispatchModel(technology_list, net_demand=net_dem, time_delta=5*minute)

This model is now infeasible because all of the technologies (assuming default settings) have a capacity in MW -- the issue seems to be because _validate_quantity converts all time units to HOURS.

Additionally, the generation limit constraint assumes that the time delta is 1 hour...

Create a dispatch model

This PR can be closed when a basic dispatch model is added to osier with appropriate tests.

Create a technology class

This issue can be closed when a pull request is made that includes a

  • technology base class
  • tests for base class
  • documentation for base class

Remove unyt installation step from github workflow

This issue can be closed when a PR that removes the step Install most recent unyt from the github CI workflow is merged. This step makes it possible to use the new features I added to unyt but does not reflect the typical user's experience.

Fixing this issue depends on the release of a new version of unyt.

New Pyomo version bug?

Here's what I know, last week (2/20/2024) I could run an osier.CapacityExpansion problem just fine and the output would look something like this

Working configurations

platform python version pyomo version
Win10 3.9.3 6.4.1
==========================================================
n_gen  |  n_eval  | n_nds  |      eps      |   indicator  
==========================================================
     1 |       10 |      1 |             - |             -
     2 |       20 |      1 |  0.000000E+00 |             f
     3 |       30 |      1 |  0.000000E+00 |             f
     4 |       40 |      1 |  0.000000E+00 |             f
     5 |       50 |      1 |  0.000000E+00 |             f

Now, the problem still runs but the output is a lot less pretty

Broken configurations

platform python version pyomo version
Win10, MacOS Monterey 12.6 3.9.3. 3.10.13 6.7.1
==========================================================
n_gen  |  n_eval  | n_nds  |      eps      |   indicator  
==========================================================
     1 |       10 |      1 |             - |             -
ERROR: evaluating object as numeric value: x[NaturalGas_Conv,0]
        (object: <class 'pyomo.core.base.var._GeneralVarData'>)
    No value for uninitialized NumericValue object x[NaturalGas_Conv,0]
ERROR: evaluating object as numeric value: x[NaturalGas_Conv,0]
        (object: <class 'pyomo.core.base.var._GeneralVarData'>)
    No value for uninitialized NumericValue object x[NaturalGas_Conv,0]
ERROR: evaluating object as numeric value: x[NaturalGas_Conv,0]
        (object: <class 'pyomo.core.base.var._GeneralVarData'>)
     2 |       20 |      1 |  0.000000E+00 |             f
ERROR: evaluating object as numeric value: x[NaturalGas_Conv,0]
        (object: <class 'pyomo.core.base.var._GeneralVarData'>)
    No value for uninitialized NumericValue object x[NaturalGas_Conv,0]
ERROR: evaluating object as numeric value: x[NaturalGas_Conv,0]
        (object: <class 'pyomo.core.base.var._GeneralVarData'>)
    No value for uninitialized NumericValue object x[NaturalGas_Conv,0]
ERROR: evaluating object as numeric value: x[NaturalGas_Conv,0]
        (object: <class 'pyomo.core.base.var._GeneralVarData'>)
     3 |       30 |      1 |  0.000000E+00 |             f
ERROR: evaluating object as numeric value: x[NaturalGas_Conv,0]
        (object: <class 'pyomo.core.base.var._GeneralVarData'>)
    No value for uninitialized NumericValue object x[NaturalGas_Conv,0]
     4 |       40 |      1 |  0.000000E+00 |             f
     5 |       50 |      1 |  0.000000E+00 |             f

What I have tried

  1. I plugged the error into Google, found this post from 2018. I can verify that this problem only occurs when a model is unfeasible. However, that will be the case for many many models tested in osier because that's just how genetic algorithms work so it would be nice to turn off whatever error message is causing this.
  2. I checked the verbosity settings -- the verbosity is as high as it can possibly go.
logging.getLogger('pyomo.core').setLevel(verbosity)`   # default = logging.Critical
  1. I also tried
import warnings
warnings.filter('ignore')
  1. I reinstalled osier in two fresh conda environments. One with Python 3.9 and the other with Python 3.10. I also tested it with Pyomo versions 6.4.1 and 6.7.1 (see above configurations) -- this behavior is only present with the most recent pyomo version, 6.7.1. This pyomo update was released this week which is consistent with the timeline where my code was working fine on Friday and today it is not. Especially since it was previously working on two other machines with more recent versions of pyomo, bet less recent than the current (until I updated them today and now they're broken).
  2. I have tried specifying the pyomo version in setup.py under the install_requires parameter, however doing so results in the following error message
Obtaining file:///C:/Users/samgd/Research/osier
  Preparing metadata (setup.py) ... error
  error: subprocess-exited-with-error

  × python setup.py egg_info did not run successfully.
  │ exit code: 1
  ╰─> [28 lines of output]
      C:\Users\samgd\anaconda3\envs\pyomo64\lib\site-packages\setuptools\__init__.py:80: _DeprecatedInstaller: setuptools.installer and fetch_build_eggs are deprecated.
      !!

              ********************************************************************************
              Requirements should be satisfied by a PEP 517 installer.
              If you are using pip, you can try `pip install --use-pep517`.
              ********************************************************************************

      !!
        dist.fetch_build_eggs(dist.setup_requires)
      Traceback (most recent call last):
        File "<string>", line 2, in <module>
        File "<pip-setuptools-caller>", line 34, in <module>
        File "C:\Users\samgd\Research\osier\setup.py", line 113, in <module>
          setup(**opts)
        File "C:\Users\samgd\anaconda3\envs\pyomo64\lib\site-packages\setuptools\__init__.py", line 103, in setup
          return distutils.core.setup(**attrs)
        File "C:\Users\samgd\anaconda3\envs\pyomo64\lib\site-packages\setuptools\_distutils\core.py", line 147, in setup
          _setup_distribution = dist = klass(attrs)
        File "C:\Users\samgd\anaconda3\envs\pyomo64\lib\site-packages\setuptools\dist.py", line 303, in __init__
          _Distribution.__init__(self, dist_attrs)
        File "C:\Users\samgd\anaconda3\envs\pyomo64\lib\site-packages\setuptools\_distutils\dist.py", line 258, in __init__
          getattr(self.metadata, "set_" + key)(val)
        File "C:\Users\samgd\anaconda3\envs\pyomo64\lib\site-packages\setuptools\_distutils\dist.py", line 1255, in set_requires
          distutils.versionpredicate.VersionPredicate(v)
        File "C:\Users\samgd\anaconda3\envs\pyomo64\lib\site-packages\setuptools\_distutils\versionpredicate.py", line 122, in __init__
          raise ValueError("expected parenthesized list: %r" % paren)
      ValueError: expected parenthesized list: '<=6.7.0'
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

× Encountered error while generating package metadata.
╰─> See above for output.

note: This is an issue with the package mentioned above, not pip.
hint: See above for details.

What needs to change

This issue can be closed when setup.py specifies a version of pyomo<=6.7.0.

OR

Update the way osier is installed per the line in the error message C:\Users\samgd\anaconda3\envs\pyomo64\lib\site-packages\setuptools\__init__.py:80: _DeprecatedInstaller: setuptools.installer and fetch_build_eggs are deprecated.

@yardasol would you mind helping with this?

Add a ramping constraint to DispatchModel

This issue depends on #17.
Currently, the DispatchModel only has the following constraints

  • limit generation to capacity
  • match supply/demand.

These are the "minimum" physical requirements for an energy system. However, dispatchable technologies, such as nuclear and coal, often have physical limits to their ramping capabilities. Therefore a ThermalTechnology subclass might have a ramp up / ramp down attribute expressed as a percentage of its rated capacity.

Design considerations

  • should the ramping parameter be interpreted as a unyt quantity?
  • should it remain a simple float?

Set up build system for pypi

Initialize build system for treetop. This issue can be closed when treetop has the appropriate structure to build with pip install.

  • setup.py file
  • treetop directory
  • init.py file (in the treetop directory)

Example accessibility

Nice example notebooks! i found them in the docs and wanted to have a play with them. I encountered two blockers:

  • was expecting to find them in an examples directory near root (not in docs)
  • jupyter is not included in the requirements
  • required kernel installation (ipython kernel install --user --name=osier)

Note that the latter two (especially the last) are quite specific to people using an env/package manager.

propagate name change

This issue can be closed when relevant files referencing treetop are converted to osier

simplify units in osier

After releasing v3.0.0, unyt now includes common energy system units such as Wh, mmbtu, and others. Osier currently uses MW*hr instead of MWh (since it previously didn't exist).

This issue may be closed once there is a merged PR that simplifies the units in osier to match this update.

More clear function names inosier/equations.py

The current names objective_from_capacity and objective_from_energy in osier/equations.py are reasonable, but could be more descriptive based on the conversation around these function names in PR #38.This issue can be closed if/when more descriptive function names are developed.

Docs: Technology Tutorial - Satisfy Objective 2

In the Technology Tutorial page, it states 3 objectives. The second one - "Modify the attributes of a technology object in the current instance" is not included on the page.

This issue can be closed with a PR that adds a section to the Technology Tutorial docs page satisfying learning objective 2.

No env control in installation instructions

I think it is a good idea to include an env/package manager such as conda or mamba in the installation instructions.

  • This will create more homogenous experience for users on different OS
  • You should get less awkward bug reports from less expereinced users

There is an example of a (also energy) project that makes use of mamba here.

[Feature] Enable optional parameters for objective functions with functools

Currently, all objectives and constraints in osier require two items, the list of technologies and a solved dispatch model. Some calculations will require tunable parameters. Such as a volatility calculation using weighted_permutation_entropy, for example. Therefore, allowing users to specify the optional parameters at run time with some thing like:

objectives = (func1, functools.partial(func2, m = 7, tau=60))

Where the second objective function func2 has some optional parameters that cannot be set once a simulation begins (except by using functools.partial).

Edit:
To clarify the desired behavior, users should be able to pass a function and it's parameters to osier without explicitly calling functools.partial. E.g.,

from osier import CapacityExpansion

problem = CapacityExpansion(..., objectives=[func1, {func2: {m:7, tau:60}}], ...)

Users would be required to know which parameters they need.

Conversation

@yardasol @ZoeRichter @smpark7 @nsryan2 @munkm

Does this functionality make sense? Which version is clearer? The clarification would add more complexity to the osier.CapacityExpansion object, but it's already so similar to the functools implementation that I'm not sure anymore if the "simplification" makes sense. Looking for thoughts.

Create a model class for solving genetic algorithms with Pymoo

This issue can be closed when a pull request is made containing the following

  • a basic model class that can run a pymoo problem
  • documentation for the class
  • basic tests for the class

The class itself should have at least

  • metadata for the problem
  • pymoo specific parameters (e.g. which algorithm to use, number of generations, population size, etc.)
  • ...

Create a sub class for common technologies

This issue can be closed when a PR containing the following sub-classes (all inheriting from osier.Technology) is created

  • solar panel
  • wind turbine
  • natural gas combined cycle
  • coal
  • nuclear
  • hydro

Further, the following requirements should be met

  • the default cost technology should be populated using the nrelpy package. osier should not carry any datasets (and the number of "magic numbers" should be minimized).
  • a solar panel class should have a method that calculates its own power production based on a GHI time series (for example).
  • new class methods should be tested!
  • these classes should live in a technologies directory osier/technologies/
  • osier.__init__.py should import these new classes automatically.

Failed pip install

Failed pip install using latest python.

Details:

Windows (10)
python -m pip install osier pyomo==6.4.1

I tried:

Fixed by back-tracking to 3.10.

BUT please clarify expected supported python versions in installation instructions.

Suggest you also explicitly add version of python to CI.

Failed tests on Windows (10)

Following "developer" installation I had failing tests due to missing solver:

git clone [email protected]:arfc/osier.git
cd osier
pip install .
pip install .[doc]
pip install pyomo==6.4.1
pytest

Results in (for example) pyomo.common.errors.ApplicationError: No executable found for solver 'cplex'.

Please move solver installation instructions from "Getting Started" to "Installation".

To allow a smoother onboarding for windows users I suggest adding installation instructions for glpk (eg conda install -c conda-forge glpk). I appreciate this might not be the best solver but it is more easilly accessible which is nice for casual users and will be easier for windows based CI.

Add an MGA module to osier

This issue can be closed when osier has a module that enables modeling-to-generate-alternatives (MGA) functionality.

Clean up the osier test suite

The osier test suite has fairly comprehensive tests, however, some share resources and could use some reorganizing.

One of the first things that could be done is create conftest.py file that configures the test session.

  • create a conftest.py file in tests/

Docs: Technology Tutorial - Satisfy Objective 3

In the Technology Tutorial page, it states 3 objectives. The third one - "Create your own osier technology" is not included on the page.

This issue can be closed with a PR that adds a section to the Technology Tutorial docs page satisfying learning objective 3.

Determine if treetop is the best name for this tool

This issue can be closed once one of the following has happened

  1. treetop is determined to be the best name for this tool
  2. a better name has been agreed upon (with a subsequent pull request that renames the tool)

Add unit registry for osier specific units

This issue can be closed when a pull request is made that includes a unit registry with energy-system-specific units. For example

  • grams of CO2
  • MWh (kWh, Wh, ...)
  • $/MWh

This issue depends on an update from unyt that would enable a currency dimension.

DispatchModel storage constraints are not correct

Currently, a "storage" technology in the DispatchModel can charge itself without any external electricity production. This is incorrect.

This issue can be closed when the storage constraints do not allow a battery to charge without excess energy being produced.

Create basic documentation

This issue can be closed when documentation is added to the repository.

  • sphinx documentation
  • more detailed readme
  • package dependencies added
  • contributing file

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.