diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 8642851..1358aa1 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -15,7 +15,19 @@ permissions: jobs: build: name: Build and test - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + python-version: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + os: + - ubuntu-latest + - macos-latest + - windows-latest defaults: run: @@ -36,23 +48,36 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install flake8 pytest pyomo==6.4.1 if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: Install flake8 + run: | + python -m pip install flake8 - name: Install CBC + if: matrix.os != 'windows-latest' run: | - mamba install coincbc - - name: Lint with flake8 + mamba install coin-or-cbc coincbc + - name: install CBC (Windows) + if: matrix.os == 'windows-latest' run: | - # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - - name: Install osier package + curl -L https://github.com/coin-or/Cbc/releases/download/releases%2F2.10.10/Cbc-releases.2.10.10-w64-msvc17-md.zip -o cbc.zip + unzip cbc.zip -d ${HOME}/cbc + echo "${HOME}/cbc/bin" >> $GITHUB_PATH + - name: Install osier package (macos) + if: matrix.os == 'macos-latest' run: | - pip install . - - name : Install recent unyt update + pip install -e .'[doc]' + - name: Install osier package + if: matrix.os != 'macos-latest' run: | - python3 -m pip install -e git+https://github.com/yt-project/unyt.git#egg=unyt + pip install -e .[doc] + - name: Test with pytest run: | pytest tests/ + + - name: Lint with flake8 + run: | + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 277d6f9..49eb6b3 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -1,12 +1,9 @@ version: 2 build: - os: "ubuntu-20.04" + os: "ubuntu-22.04" tools: - python: "3.9" - jobs: - post_install: - - pip install pyomo==6.4.1 + python: "3.12" sphinx: configuration: docs/source/conf.py diff --git a/README.md b/README.md index 54b0f4e..8a61577 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Open source multi-objective energy system framework `osier` is available through [PyPI](https://pypi.org/project/osier/). It may be installed with ```bash -python -m pip install osier pyomo==6.4.1 +python -m pip install osier ``` or by cloning this repository and building from source: @@ -25,19 +25,9 @@ cd osier pip install . # to also install the documentation dependencies pip install .[doc] - -# followed by -pip install pyomo==6.4.1 ``` -```{note} -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](https://osier.readthedocs.io/en/latest/). You can also build the docs locally with: @@ -54,6 +44,11 @@ python -m http.server `osier`'s tests can be run by executing `pytest` in the top-level directory of `osier`. +```{note} +The test package assumes the user has `coin-or-cbc` installed as the default solver. For Windows machines, +this may require some additional steps to install the solver. [Here](https://stackoverflow.com/questions/58868054/how-to-install-coincbc-using-conda-in-windows) is a helpful place to start. +``` + ## Contributing diff --git a/osier/models/capacity_expansion.py b/osier/models/capacity_expansion.py index 786ceb3..f59f4ae 100644 --- a/osier/models/capacity_expansion.py +++ b/osier/models/capacity_expansion.py @@ -97,7 +97,7 @@ def __init__(self, curtailment=True, allow_blackout=False, verbosity=50, - solver='cplex', + solver='cbc', **kwargs): self.technology_list = deepcopy(technology_list) self.demand = demand diff --git a/osier/models/dispatch.py b/osier/models/dispatch.py index 4bfaf68..392b3a9 100644 --- a/osier/models/dispatch.py +++ b/osier/models/dispatch.py @@ -200,7 +200,7 @@ def __init__(self, technology_list, net_demand, time_delta=None, - solver='cplex', + solver='cbc', lower_bound=0.0, oversupply=0.0, undersupply=0.0, @@ -248,8 +248,8 @@ def __init__(self, unit_power=self.power_units, unit_time=self.time_delta.units) - - logging.getLogger('pyomo.core').setLevel(verbosity) + logging.basicConfig(level=verbosity, format='%(message)s') + @property def time_delta(self): diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..7c30ac0 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,69 @@ +[build-system] +requires = ["setuptools >= 64.0"] +build-backend = "setuptools.build_meta" + +[project] +name="osier" +version = "0.3.0" +description = "osier: A justice oriented energy system optimization tool" +readme = "README.md" +keywords = ["energy systems", "optimization", "multi-objective", "justice", "multi-criteria decision"] + +license = { file = "LICENSE" } + +requires-python = ">= 3.9" + +dependencies = [ + 'numpy', + 'pandas', + 'matplotlib', + 'pytest', + 'dill', + 'openpyxl', + 'nrelpy', + 'unyt', + 'pymoo', + 'pyentrp', + 'deap', + 'pyomo' +] + +authors = [ + {name = "Sam Dotson", email = "samgdotson@gmail.com"}, +] +maintainers = [ + {name = "Sam Dotson", email = "samgdotson@gmail.com"} +] + +classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Science/Research", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Environment :: Console", + "Natural Language :: English", + "Operating System :: OS Independent" +] + +[project.urls] +Homepage = "https://osier.readthedocs.io" +Repository = "https://github.com/arfc/osier" +Issues = "https://github.com/arfc/osier/issues" + +[project.optional-dependencies] +doc = [ + 'sphinx>=5.1', + 'sphinx-autobuild', + 'myst-parser', + "sphinx_design", + "sphinx-autodoc-typehints", + 'numpydoc', + 'pydata_sphinx_theme', + 'nbsphinx', + 'pandoc' +] + +[tool.setuptools.packages.find] +include = ['osier'] \ No newline at end of file diff --git a/setup.py b/setup.py deleted file mode 100644 index 45fcd3c..0000000 --- a/setup.py +++ /dev/null @@ -1,112 +0,0 @@ -from __future__ import absolute_import, division, print_function -from os.path import join as pjoin -import sys -from setuptools import setup, find_packages - - -# Format expected by setup.py and doc/source/conf.py: string of form "X.Y.Z" -_version_major = 0 -_version_minor = 3 -_version_micro = 0 # use '' for first of series, number for 1 and above -# _version_extra = 'dev' -_version_extra = '' # Uncomment this for full releases - -# Construct full version string from these. -_ver = [_version_major, _version_minor] -if _version_micro: - _ver.append(_version_micro) -if _version_extra: - _ver.append(_version_extra) - -__version__ = '.'.join(map(str, _ver)) - -CLASSIFIERS = ["Development Status :: 3 - Alpha", - "Environment :: Console", - "Intended Audience :: Science/Research", - "License :: OSI Approved :: BSD License", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Topic :: Scientific/Engineering"] - -# Description should be a one-liner: -description = "osier: A justice oriented energy system optimization tool" -# Long description will go up on the pypi page - -NAME = "osier" -MAINTAINER = "Samuel Dotson" -MAINTAINER_EMAIL = "samgdotson@gmail.com" -DESCRIPTION = description -with open("README.md", encoding="utf-8") as f: - LONG_DESCRIPTION = f.read() -LONG_DESCRIPTION_CONTENT_TYPE = 'text/markdown' -URL = "https://osier.readthedocs.io/en/latest/" -DOWNLOAD_URL = "http://github.com/arfc/osier" -LICENSE = "BSD-3" -AUTHOR = "Samuel Dotson" -AUTHOR_EMAIL = "sgd2@illinois.edu" -PLATFORMS = "OS Independent" -MAJOR = _version_major -MINOR = _version_minor -MICRO = _version_micro -VERSION = __version__ -PACKAGE_DATA = {'osier': [pjoin('data', '*')]} -REQUIRES = [ - 'numpy', - 'pandas', - 'matplotlib', - 'pytest', - 'dill', - 'openpyxl', - 'nrelpy', - 'unyt', - 'pymoo', - 'pyentrp', - 'deap',] -EXTRAS_REQUIRE = { - 'doc': [ - 'sphinx>=5.1', - 'sphinx-autobuild', - 'myst-parser', - "sphinx_design", - "sphinx-autodoc-typehints", - 'numpydoc', - 'pydata_sphinx_theme', - 'nbsphinx', - 'pandoc' - ]} -PYTHON_REQUIRES = ">= 3.6" - -PACKAGES = find_packages() - -ENTRY_POINTS = {} - -SETUP_REQUIRES = ['setuptools >= 24.2.0'] -# This enables setuptools to install wheel on-the-fly -SETUP_REQUIRES += ['wheel'] if 'bdist_wheel' in sys.argv else [] - -opts = dict(name=NAME, - maintainer=MAINTAINER, - maintainer_email=MAINTAINER_EMAIL, - description=DESCRIPTION, - long_description=LONG_DESCRIPTION, - long_description_content_type=LONG_DESCRIPTION_CONTENT_TYPE, - url=URL, - download_url=DOWNLOAD_URL, - license=LICENSE, - classifiers=CLASSIFIERS, - author=AUTHOR, - author_email=AUTHOR_EMAIL, - platforms=PLATFORMS, - version=VERSION, - packages=PACKAGES, - package_data=PACKAGE_DATA, - install_requires=REQUIRES, - extras_require=EXTRAS_REQUIRE, - python_requires=PYTHON_REQUIRES, - setup_requires=SETUP_REQUIRES, - requires=REQUIRES, - entry_points=ENTRY_POINTS) - - -if __name__ == '__main__': - setup(**opts) diff --git a/tests/test_equations.py b/tests/test_equations.py index 95833c9..7f5bc12 100644 --- a/tests/test_equations.py +++ b/tests/test_equations.py @@ -7,7 +7,7 @@ import functools if "win32" in sys.platform: - solver = 'cplex' + solver = 'cbc' elif "linux" in sys.platform: solver = "cbc" else: diff --git a/tests/test_models.py b/tests/test_models.py index 87396b9..2370a51 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -8,7 +8,7 @@ import sys if "win32" in sys.platform: - solver = 'cplex' + solver = 'cbc' elif "linux" in sys.platform: solver = "cbc" else: