diff --git a/README.md b/README.md index 496cfcba..46feb81f 100644 --- a/README.md +++ b/README.md @@ -5,34 +5,28 @@ [![Documentation Status](https://readthedocs.org/projects/energiapy/badge/)](https://energiapy.readthedocs.io/en/latest/) [![PyPI](https://img.shields.io/pypi/v/energiapy.svg)](https://pypi.org/project/energiapy) +[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/energiapy.svg)](https://pypi.org/project/energiapy/) [![Downloads](https://static.pepy.tech/personalized-badge/energiapy?period=total&units=international_system&left_color=grey&right_color=orange&left_text=Downloads)](https://pepy.tech/project/energiapy) -[![Python package](https://github.com/TAMUparametric/energiapy/actions/workflows/energia.yml/badge.svg)](https://github.com/TAMUparametric/energiapy/actions/workflows/energia.yml) +[![CI](https://github.com/TAMUparametric/energiapy/actions/workflows/energia.yml/badge.svg)](https://github.com/TAMUparametric/energiapy/actions/workflows/energia.yml) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/994d46ab40ac4f0ead5ed9d1ea1b0fab)](https://app.codacy.com/gh/TAMUparametric/energiapy/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) -[![DOI](https://zenodo.org/badge/600269309.svg)](https://doi.org/10.5281/zenodo.17478608) -[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/energiapy.svg)](https://pypi.org/project/energiapy/) [![codecov](https://codecov.io/gh/TAMUparametric/energiapy/branch/main/graph/badge.svg)](https://codecov.io/gh/TAMUparamteric/energiapy) +[![DOI](https://zenodo.org/badge/600269309.svg)](https://doi.org/10.5281/zenodo.17478608) -Energia is a tool for the data-driven multiscale modeling and optimization of energy systems under uncertainty. Users are directed to {cite}`kakodkar2022review` for an overview of the state-of-the-art in the field. -The component-driven methodology is inspired by the resource task network (RTN) methodology {cite}`barbosa_povoa_pantelides_1997` and constituent functionalities developed through the research conducted in -the [Multiparameteric Optimization and Control (Pistikopoulos) Group](https://parametric.tamu.edu/). The Tutorials and Examples sections are a good starting point. +Energia is a decision-making tool. Models can be constructed by providing data regarding bounds on commodity streams and operations. Spatial specificity and time-series input of varying sizes renders multiscale models. Their analysis yields insight into the interactions between different decisions. The term 'streams' is applied broadly. pre-categorized streams are broadly classified into commodities (resource, currency, emission, land, material, land, etc.) and impact (economic, environmental, social). - +Operation types current include process, storage, and transportation. A process is a catch-all for power generation, dense energy carrier (DEC) or chemical production. Storage involves charging and discharging which can both be configured individually. Transportation networks can involve multiple linkages between locations. Operational parameters include material and land use, impact, conversion efficiency. Construction can also be modeled as capacity sizing problems. +Broadly, Energia can be applied towards the multiscale modeling and optimization of energy systems under uncertainty. Risk analysis can be performed using various approaches such as scenario analysis, stochastic and robust programming, and multiparametric programming. The general class of problems is currently multiparametric mixed integer non-linear programming (mpMILP). Non-linear programs (mpMINLPs) can be modeled using piece-wise linearization. The multiscale nature of models affords simultaneous design and scheduling. Further Comprehensive resource balances allow cost optimization, carbon accounting, social life cycle analysis, and other forms of impact analysis. -# Applications +Notably, impact is ascertained as a function of decisions. The trade-offs between minimizing or maximizing different impact streams can be determined as pareto fronts. Outputs such as stream contributions, production levels, capacities as a function of time and space can also be exported and illustrated. Additionally, scenario reduction via clustering, and integer cuts can be utilized to manage computational tractability. -Models can also simultaneously perform the following analyses under an integrated paradigm: -- Multiperiod Multiscale Design and Scheduling {cite}`kakodkar2023hydrogen,kakodkar2024multiperiod` -- Modeling the Material-Energy-Mobility Nexus {cite}`montano2025modeling,flores2025integrating` -- Carbon Accounting and Life Cycle Assessment Under Uncertainty {cite}`sousa2025integrating,de2025integrated` -- Robust Scheduling Using Multiparametric Programming {cite}`kakodkar2024robust` -- Resilience Analysis of Distributed Energy and Manufacturing Systems {cite}`vedant2024information` + -# Select Features +# Features Available constraints are able to model: @@ -52,10 +46,11 @@ Examples of objectives towards which the model can be optimized include: 2. minimizing impact 3. maximizing resource discharge -Large scenarios can be aggregated using the following available techniques: +Clustering submodules include: 1. agglomerative hierarchial clustering (AHC) 2. dynamic time warping (DTW) +3. k-means Both the input data and solution output can be illustrated, examples include: @@ -63,13 +58,21 @@ Both the input data and solution output can be illustrated, examples include: 2. solution output: inventory, production, consumption, discharge/sales schedule; contribution towards costs (capital, variable and fixed operational), meeting demand. -Other (and optional) features include: +Callable external packages are available for: -1. math utilities for calculating euclidean distances, generation connectivity matrices, etc. -2. generating dataframes with missing data fixed (weekends, public holidays) for time-series data such as resource price -3. function to fetch weather data at an appropriate resolution from [NREL NSRDB](https://nsrdb.nrel.gov/) for any county +1. Integration with high-fidelity process modeling modules such as +2. Filling missing data (weekends, public holidays) for time-series data such as resource price +3. Fetch weather data at an appropriate resolution from [NREL NSRDB](https://nsrdb.nrel.gov/) for any county in the US -4. latex constraints writer for model documentation -Direct any communication to Rahul Kakodkar (cacodcar@gmail.com) +Libraries have pre-loaded sets of: + +1. Components such as SI and miscellaneous units, currencies, time units, environmental indicators. +2. Example and test problems across various applicative domains +3. Recipes for decision-making, instructions for calculations, and attribute aliases. + + +Note that some of these functionalities are available in [Energia<2.0.0](https://github.com/TAMUparametric/energiapy/tree/v1.0.7) and are being ported to the 2.0 interface. + + diff --git a/background.rst b/background.rst new file mode 100644 index 00000000..c356de29 --- /dev/null +++ b/background.rst @@ -0,0 +1,21 @@ +Background and Theory +===================== + +For an overview on the state-of-the-art in energy systems modeling and optimization +including key challenges and opportunities see :cite:`kakodkar2022review`. +To understand the mathematical programming implementation, the resource task network (RTN) +methodology :cite:`barbosa_povoa_pantelides_1997` is a great starting point. +Energia's :ref:`publication_history` is indicative of key capabilities and applicative +domains. For more research on advancing computational methods in modeling and optimization +see `Multiparameteric Optimization and Control (Pistikopoulos) Group `_. + + +Direct any queries regarding the implementation or theoretical background to Rahul Kakodkar (cacodcar@gmail.com). + + +.. seealso:: + + `Gana `_, an Algebraic Modeling Language (AML) + for Multiscale Modeling and Optimization which serves as the backend. + + diff --git a/docs/_autosummary/energia.components.operations.process.rst b/docs/_autosummary/energia.components.operations.process.rst index 565236d2..42a751c5 100644 --- a/docs/_autosummary/energia.components.operations.process.rst +++ b/docs/_autosummary/energia.components.operations.process.rst @@ -1,4 +1,4 @@ -energia.components.operations.process +energia.components.operations.process ===================================== .. automodule:: energia.components.operations.process diff --git a/docs/_autosummary/energia.components.operations.transport.rst b/docs/_autosummary/energia.components.operations.transport.rst index ef50164e..2d91fda5 100644 --- a/docs/_autosummary/energia.components.operations.transport.rst +++ b/docs/_autosummary/energia.components.operations.transport.rst @@ -1,4 +1,4 @@ -energia.components.operations.transport +energia.components.operations.transport ======================================= .. automodule:: energia.components.operations.transport diff --git a/docs/_autosummary/energia.components.temporal.modes.rst b/docs/_autosummary/energia.components.temporal.modes.rst index 9fdf7f83..3dfa1b86 100644 --- a/docs/_autosummary/energia.components.temporal.modes.rst +++ b/docs/_autosummary/energia.components.temporal.modes.rst @@ -1,4 +1,4 @@ -energia.components.temporal.modes +energia.components.temporal.modes ================================= .. automodule:: energia.components.temporal.modes diff --git a/docs/_autosummary/energia.library.processes.rst b/docs/_autosummary/energia.library.external.rst similarity index 65% rename from docs/_autosummary/energia.library.processes.rst rename to docs/_autosummary/energia.library.external.rst index 9d523e43..f4ed76ee 100644 --- a/docs/_autosummary/energia.library.processes.rst +++ b/docs/_autosummary/energia.library.external.rst @@ -1,16 +1,16 @@ -energia.library.processes -========================= +energia.library.external +======================== -.. automodule:: energia.library.processes +.. automodule:: energia.library.external .. rubric:: Functions .. autosummary:: - pv + pvlib retrieve_sam - wf + windpowerlib .. rubric:: Classes diff --git a/docs/_autosummary/energia.library.rst b/docs/_autosummary/energia.library.rst index a3309a66..c69ff837 100644 --- a/docs/_autosummary/energia.library.rst +++ b/docs/_autosummary/energia.library.rst @@ -13,6 +13,6 @@ energia.library aliases components examples + external instructions - processes recipes diff --git a/docs/_autosummary/energia.modeling.constraints.bind.rst b/docs/_autosummary/energia.modeling.constraints.bind.rst index 11fe2245..736d9d5a 100644 --- a/docs/_autosummary/energia.modeling.constraints.bind.rst +++ b/docs/_autosummary/energia.modeling.constraints.bind.rst @@ -1,4 +1,4 @@ -energia.modeling.constraints.bind +energia.modeling.constraints.bind ================================= .. automodule:: energia.modeling.constraints.bind diff --git a/docs/_autosummary/energia.modeling.variables.aspect.rst b/docs/_autosummary/energia.modeling.variables.aspect.rst index 3471530f..dcc5e170 100644 --- a/docs/_autosummary/energia.modeling.variables.aspect.rst +++ b/docs/_autosummary/energia.modeling.variables.aspect.rst @@ -1,4 +1,4 @@ -energia.modeling.variables.aspect +energia.modeling.variables.aspect ================================= .. automodule:: energia.modeling.variables.aspect diff --git a/docs/_autosummary/energia.modeling.variables.control.rst b/docs/_autosummary/energia.modeling.variables.control.rst index f974fc21..b04ce30b 100644 --- a/docs/_autosummary/energia.modeling.variables.control.rst +++ b/docs/_autosummary/energia.modeling.variables.control.rst @@ -1,4 +1,4 @@ -energia.modeling.variables.control +energia.modeling.variables.control ================================== .. automodule:: energia.modeling.variables.control diff --git a/docs/_autosummary/energia.represent.ations.scenario.rst b/docs/_autosummary/energia.represent.ations.scenario.rst index 11b24fc0..e49f8a3e 100644 --- a/docs/_autosummary/energia.represent.ations.scenario.rst +++ b/docs/_autosummary/energia.represent.ations.scenario.rst @@ -1,4 +1,4 @@ -energia.represent.ations.scenario +energia.represent.ations.scenario ================================= .. automodule:: energia.represent.ations.scenario diff --git a/docs/_autosummary/energia.represent.model.rst b/docs/_autosummary/energia.represent.model.rst index e9ed7f14..2c6ebd9c 100644 --- a/docs/_autosummary/energia.represent.model.rst +++ b/docs/_autosummary/energia.represent.model.rst @@ -1,4 +1,4 @@ -energia.represent.model +energia.represent.model ======================= .. automodule:: energia.represent.model @@ -34,19 +34,18 @@ Economic Emission Environ + Game Graph - Idx Impact Instruction Interact + Lag Land Linkage Location - MParam Material Model Modes - Param Periods Player Problem diff --git a/docs/_static/custom.css b/docs/_static/custom.css index ef5e1d28..0ca0128b 100644 --- a/docs/_static/custom.css +++ b/docs/_static/custom.css @@ -64,3 +64,10 @@ code, pre { :root { --sb-width: 320px; /* or whatever width you like */ } + +/* Justify all normal text in Book Theme */ +.bd-content p, +.bd-content li { + text-align: justify; + text-justify: inter-word; +} \ No newline at end of file diff --git a/docs/changelog.rst b/docs/changelog.rst index 5aff0389..3ab47245 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,4 +1,4 @@ -New Features and Updates +New Features & Updates ========================= This lists recent changes to the project. If there are features you would like to see added, diff --git a/docs/examples/scheduling.ipynb b/docs/examples/scheduling.ipynb index 5b443bd9..ef5c76ff 100644 --- a/docs/examples/scheduling.ipynb +++ b/docs/examples/scheduling.ipynb @@ -21,7 +21,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 47, "id": "c7f232b9", "metadata": {}, "outputs": [], @@ -44,7 +44,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 48, "id": "93b6ad8f", "metadata": {}, "outputs": [], @@ -63,7 +63,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 49, "id": "cc5709be", "metadata": {}, "outputs": [ @@ -73,7 +73,7 @@ "y" ] }, - "execution_count": 22, + "execution_count": 49, "metadata": {}, "output_type": "execute_result" } @@ -96,7 +96,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 50, "id": "9307292c", "metadata": {}, "outputs": [ @@ -106,7 +106,7 @@ "l0" ] }, - "execution_count": 23, + "execution_count": 50, "metadata": {}, "output_type": "execute_result" } @@ -127,7 +127,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 51, "id": "aa6d04e2", "metadata": {}, "outputs": [], @@ -159,7 +159,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 52, "id": "1ea59eb2", "metadata": {}, "outputs": [ @@ -167,8 +167,8 @@ "name": "stderr", "output_type": "stream", "text": [ - "⚖ Initiated power balance in (l0, q) ⏱ 0.0001 s\n", - "🔗 Bound [≥] power release in (l0, q) ⏱ 0.0009 s\n", + "⚖ Initiated power balance in (l0, q) ⏱ 0.0002 s\n", + "🔗 Bound [≥] power release in (l0, q) ⏱ 0.0011 s\n", "⚖ Initiated wind balance in (l0, y) ⏱ 0.0001 s\n", "🔗 Bound [≤] wind consume in (l0, y) ⏱ 0.0006 s\n" ] @@ -189,7 +189,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 53, "id": "6ac13464", "metadata": {}, "outputs": [], @@ -200,14 +200,14 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 54, "id": "19966303", "metadata": {}, "outputs": [ { "data": { "text/latex": [ - "$\\displaystyle [9]\\text{ }{\\mathbf{{cons}}}_{{wind},{l0},{{{y}_{0}}}} - 400.0 \\leq 0$" + "$\\displaystyle [8]\\text{ }{\\mathbf{{cons}}}_{{wind},{l0},{{{y}_{0}}}} = 0$" ], "text/plain": [ "" @@ -219,7 +219,7 @@ { "data": { "text/latex": [ - "$\\displaystyle [8]\\text{ }{\\mathbf{{cons}}}_{{wind},{l0},{{{y}_{0}}}} = 0$" + "$\\displaystyle [9]\\text{ }{\\mathbf{{cons}}}_{{wind},{l0},{{{y}_{0}}}} - 400.0 \\leq 0$" ], "text/plain": [ "" @@ -247,14 +247,14 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 55, "id": "caee4b3b", "metadata": {}, "outputs": [ { "data": { "text/latex": [ - "$\\displaystyle [0]\\text{ }-{\\mathbf{{rlse}}}_{{power},{l0},{{{y}_{0}}},{{{q}_{0}}}} = 0$" + "$\\displaystyle [4]\\text{ }-{\\mathbf{{rlse}}}_{{power},{l0},{{{y}_{0}}},{{{q}_{0}}}} + 60.0 \\leq 0$" ], "text/plain": [ "" @@ -266,7 +266,7 @@ { "data": { "text/latex": [ - "$\\displaystyle [1]\\text{ }-{\\mathbf{{rlse}}}_{{power},{l0},{{{y}_{0}}},{{{q}_{1}}}} = 0$" + "$\\displaystyle [5]\\text{ }-{\\mathbf{{rlse}}}_{{power},{l0},{{{y}_{0}}},{{{q}_{1}}}} + 70.0 \\leq 0$" ], "text/plain": [ "" @@ -278,7 +278,7 @@ { "data": { "text/latex": [ - "$\\displaystyle [2]\\text{ }-{\\mathbf{{rlse}}}_{{power},{l0},{{{y}_{0}}},{{{q}_{2}}}} = 0$" + "$\\displaystyle [6]\\text{ }-{\\mathbf{{rlse}}}_{{power},{l0},{{{y}_{0}}},{{{q}_{2}}}} + 100.0 \\leq 0$" ], "text/plain": [ "" @@ -290,7 +290,7 @@ { "data": { "text/latex": [ - "$\\displaystyle [3]\\text{ }-{\\mathbf{{rlse}}}_{{power},{l0},{{{y}_{0}}},{{{q}_{3}}}} = 0$" + "$\\displaystyle [7]\\text{ }-{\\mathbf{{rlse}}}_{{power},{l0},{{{y}_{0}}},{{{q}_{3}}}} + 30.0 \\leq 0$" ], "text/plain": [ "" @@ -302,7 +302,7 @@ { "data": { "text/latex": [ - "$\\displaystyle [4]\\text{ }-{\\mathbf{{rlse}}}_{{power},{l0},{{{y}_{0}}},{{{q}_{0}}}} + 60.0 \\leq 0$" + "$\\displaystyle [0]\\text{ }-{\\mathbf{{rlse}}}_{{power},{l0},{{{y}_{0}}},{{{q}_{0}}}} = 0$" ], "text/plain": [ "" @@ -314,7 +314,7 @@ { "data": { "text/latex": [ - "$\\displaystyle [5]\\text{ }-{\\mathbf{{rlse}}}_{{power},{l0},{{{y}_{0}}},{{{q}_{1}}}} + 70.0 \\leq 0$" + "$\\displaystyle [1]\\text{ }-{\\mathbf{{rlse}}}_{{power},{l0},{{{y}_{0}}},{{{q}_{1}}}} = 0$" ], "text/plain": [ "" @@ -326,7 +326,7 @@ { "data": { "text/latex": [ - "$\\displaystyle [6]\\text{ }-{\\mathbf{{rlse}}}_{{power},{l0},{{{y}_{0}}},{{{q}_{2}}}} + 100.0 \\leq 0$" + "$\\displaystyle [2]\\text{ }-{\\mathbf{{rlse}}}_{{power},{l0},{{{y}_{0}}},{{{q}_{2}}}} = 0$" ], "text/plain": [ "" @@ -338,7 +338,7 @@ { "data": { "text/latex": [ - "$\\displaystyle [7]\\text{ }-{\\mathbf{{rlse}}}_{{power},{l0},{{{y}_{0}}},{{{q}_{3}}}} + 30.0 \\leq 0$" + "$\\displaystyle [3]\\text{ }-{\\mathbf{{rlse}}}_{{power},{l0},{{{y}_{0}}},{{{q}_{3}}}} = 0$" ], "text/plain": [ "" @@ -389,7 +389,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 56, "id": "5b1b0756", "metadata": {}, "outputs": [ @@ -397,9 +397,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "🔗 Bound [≤] wf operate in (l0, q) ⏱ 0.0005 s\n", + "🔗 Bound [≤] wf operate in (l0, q) ⏱ 0.0003 s\n", "🧭 Mapped time for operate (wf, l0, q) ⟺ (wf, l0, y) ⏱ 0.0002 s\n", - "🔗 Bound [=] usd spend in (l0, q) ⏱ 0.0003 s\n" + "🔗 Bound [=] usd spend in (l0, q) ⏱ 0.0006 s\n" ] } ], @@ -434,7 +434,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 57, "id": "8b29d105", "metadata": {}, "outputs": [], @@ -455,7 +455,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 58, "id": "cbdbd4c9", "metadata": {}, "outputs": [], @@ -475,7 +475,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 59, "id": "a14255e1", "metadata": {}, "outputs": [], @@ -507,7 +507,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 60, "id": "3b9dcebf", "metadata": {}, "outputs": [], @@ -517,14 +517,14 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 61, "id": "1667fbc1", "metadata": {}, "outputs": [ { "data": { "text/latex": [ - "$\\displaystyle [4]\\text{ }{\\mathbf{{\\mathbf{{opr}}}}}_{{wf},{l0},{y},{q}} - {\\mathrm{φ}}_{{}} \\leq 0$" + "$\\displaystyle [6]\\text{ }{\\mathbf{{\\mathbf{spend}}}}_{{usd},{l0},{y},{q},{\\mathbf{{opr}}},{wf}} - {\\mathrm{φ}}_{{}} \\cdot {\\mathbf{{\\mathbf{{\\mathbf{{opr}}}}}}}_{{wf},{l0},{y},{q}} = 0$" ], "text/plain": [ "" @@ -548,7 +548,7 @@ { "data": { "text/latex": [ - "$\\displaystyle [6]\\text{ }{\\mathbf{{\\mathbf{spend}}}}_{{usd},{l0},{y},{q},{\\mathbf{{opr}}},{wf}} - {\\mathrm{φ}}_{{}} \\cdot {\\mathbf{{\\mathbf{{\\mathbf{{opr}}}}}}}_{{wf},{l0},{y},{q}} = 0$" + "$\\displaystyle [4]\\text{ }{\\mathbf{{\\mathbf{{opr}}}}}_{{wf},{l0},{y},{q}} - {\\mathrm{φ}}_{{}} \\leq 0$" ], "text/plain": [ "" @@ -582,7 +582,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 62, "id": "651cf1ae", "metadata": {}, "outputs": [ @@ -592,13 +592,13 @@ "text": [ "💡 Assumed wf capacity unbounded in (l0, y) ⏱ 0.0002 s\n", "💡 Assumed wf operate bounded by capacity in (l0, q) ⏱ 0.0001 s\n", - "⚖ Updated power balance with produce(power, l0, q, operate, wf) ⏱ 0.0002 s\n", - "🔗 Bound [=] power produce in (l0, q) ⏱ 0.0011 s\n", + "⚖ Updated power balance with produce(power, l0, q, operate, wf) ⏱ 0.0001 s\n", + "🔗 Bound [=] power produce in (l0, q) ⏱ 0.0009 s\n", "⚖ Updated wind balance with expend(wind, l0, y, operate, wf) ⏱ 0.0001 s\n", "🔗 Bound [=] wind expend in (l0, y) ⏱ 0.0007 s\n", - "🏭 Operating streams introduced for wf in l0 ⏱ 0.0028 s\n", + "🏭 Operating streams introduced for wf in l0 ⏱ 0.0026 s\n", "🏗 Construction streams introduced for wf in l0 ⏱ 0.0000 s\n", - "🌍 Located wf in l0 ⏱ 0.0045 s\n" + "🌍 Located wf in l0 ⏱ 0.0043 s\n" ] } ], @@ -616,7 +616,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 63, "id": "f292e987", "metadata": {}, "outputs": [], @@ -629,7 +629,7 @@ "id": "649dae6d", "metadata": {}, "source": [ - "# The Model\n", + "## The Model\n", "\n", "The model consists of the following:\n", "\n", @@ -642,7 +642,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 64, "id": "cd8cc461", "metadata": {}, "outputs": [ @@ -1131,24 +1131,23 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 65, "id": "ac3381a5", "metadata": {}, "outputs": [ { - "ename": "AttributeError", - "evalue": "'Scenario' object has no attribute 'ubs'", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mAttributeError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[38]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[43mm\u001b[49m\u001b[43m.\u001b[49m\u001b[43mscenario\u001b[49m\u001b[43m.\u001b[49m\u001b[43mubs\u001b[49m[m.operate][m.wf][m.l0][m.q].line()\n", - "\u001b[31mAttributeError\u001b[39m: 'Scenario' object has no attribute 'ubs'" - ] + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" } ], "source": [ - "m.scenario.ubs[m.operate][m.wf][m.l0][m.q].line()" + "m.scenario[m.operate][m.wf][m.l0][m.q][\"ub\"].line()" ] }, { @@ -1163,7 +1162,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 66, "id": "27258021", "metadata": {}, "outputs": [ @@ -1172,15 +1171,13 @@ "output_type": "stream", "text": [ "🧭 Mapped time for spend (usd, l0, q, operate, wf) ⟺ (usd, l0, y) ⏱ 0.0002 s\n", - "📝 Generated Program(scheduling).mps ⏱ 0.0032 s\n" + "📝 Generated Program(scheduling).mps ⏱ 0.0017 s\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Set parameter Username\n", - "Academic license - for non-commercial use only - expires 2026-08-01\n", "Warning: column name V14 in bound section not defined\n", "Read MPS format model from file Program(scheduling).mps\n", "Reading time = 0.00 seconds\n", @@ -1191,7 +1188,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "📝 Generated gurobipy model. See .formulation ⏱ 0.0107 s\n" + "📝 Generated gurobipy model. See .formulation ⏱ 0.0049 s\n" ] }, { @@ -1225,7 +1222,7 @@ "output_type": "stream", "text": [ "📝 Generated Solution object for Program(scheduling). See .solution ⏱ 0.0002 s\n", - "✅ Program(scheduling) optimized using gurobi. Display using .output() ⏱ 0.0165 s\n" + "✅ Program(scheduling) optimized using gurobi. Display using .output() ⏱ 0.0126 s\n" ] } ], @@ -1251,7 +1248,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 67, "id": "ec82432f", "metadata": {}, "outputs": [ @@ -1584,7 +1581,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 68, "id": "d24d554d", "metadata": {}, "outputs": [ @@ -1665,7 +1662,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 69, "id": "00d410b0", "metadata": {}, "outputs": [ @@ -1686,7 +1683,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 70, "id": "3252b301", "metadata": {}, "outputs": [ diff --git a/docs/frameworks.rst b/docs/frameworks.rst index 6b17efc6..12cc51d7 100644 --- a/docs/frameworks.rst +++ b/docs/frameworks.rst @@ -1,8 +1,16 @@ -List of Publications -==================== +.. _publication_history: -Listed are publications that have utilized Energia to develop frameworks: -.. bibliography:: frameworks.bib - :style: unsrt - :all: \ No newline at end of file +Publication History +=================== + +The applications of Energia have been reported for the following concerns: + +- Multiperiod Multiscale Design and Scheduling (:cite:`kakodkar2023hydrogen, kakodkar2024multiperiod`) +- Modeling the Material-Energy-Mobility Nexus (:cite:`montano2025modeling, flores2025integrating`) +- Carbon Accounting and Life Cycle Assessment Under Uncertainty (:cite:`sousa2025integrating, de2025integrated`) +- Robust Scheduling Using Multiparametric Programming (:cite:`kakodkar2024robust`) +- Resilience Analysis of Distributed Energy and Manufacturing Systems (:cite:`vedant2024information`) + + +.. bibliography:: \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 14439809..19c5e38b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,14 +1,11 @@ -Energia on Python -================= +Decision-making with Energia +============================= .. include:: ../README.md :parser: myst_parser.sphinx_ +.. include:: ../background.rst -.. seealso:: - - `Gana `_, an Algebraic Modeling Language (AML) - for Multiscale Modeling and Optimization which serves as the backend .. toctree:: :maxdepth: 2 @@ -38,22 +35,18 @@ Energia on Python .. toctree:: :maxdepth: 1 - :caption: Information + :caption: Stay Up To Date :hidden: frameworks - license changelog - - -References ----------- + license -.. bibliography:: +Dive into Energia +================== -API Reference -============= +Refer to the API documentation for a detailed description of the classes and methods available in Energia. .. autosummary:: :toctree: _autosummary @@ -63,6 +56,12 @@ API Reference energia + +References +=========== + +.. bibliography:: + Indices and tables ================== diff --git a/src/energia/components/commodities/commodity.py b/src/energia/components/commodities/commodity.py index 34e890b2..280ad209 100644 --- a/src/energia/components/commodities/commodity.py +++ b/src/energia/components/commodities/commodity.py @@ -123,7 +123,6 @@ def __eq__(self, other: Conversion | Self): if isinstance(other, int | float): conv = Conversion(resource=self, hold=other) - return conv return super().__eq__(other) diff --git a/src/energia/library/processes.py b/src/energia/library/external.py similarity index 99% rename from src/energia/library/processes.py rename to src/energia/library/external.py index fedd58b8..edc77842 100644 --- a/src/energia/library/processes.py +++ b/src/energia/library/external.py @@ -26,7 +26,7 @@ import_all = True -def pv( +def pvlib( data: DataFrame, coord: tuple[float, float], sam: str = "cecmod", @@ -99,7 +99,7 @@ def pv( return [float(i) for i in array] -def wf( +def windpowerlib( data: DataFrame, roughness_length: float = 0.1, turbine_type: str = "V100/1800", diff --git a/src/energia/modeling/constraints/bind.py b/src/energia/modeling/constraints/bind.py index 785f6b90..443a48e3 100644 --- a/src/energia/modeling/constraints/bind.py +++ b/src/energia/modeling/constraints/bind.py @@ -88,15 +88,18 @@ def __init__( # if a dict is passed, it is assumed to be mode bounds return self._calc_w_modes() if self.iscalc else self._write_w_modes() - try: - self.write() + self.write() - except TypeError: - # TODO: not yet implemented - # TODO: this is essentially mode of a mode - # TODO: modes will need to made tuple maybe - if any(isinstance(x, dict) for x in self._parameter): - self._write_w_modes_of_modes() + + # try: + # self.write() + + # except TypeError: + # # TODO: not yet implemented + # # TODO: this is essentially mode of a mode + # # TODO: modes will need to made tuple maybe + # if any(isinstance(x, dict) for x in self._parameter): + # self._write_w_modes_of_modes() @timer(logger, kind="bind") def write(self): @@ -290,27 +293,27 @@ def _write_w_modes(self): _ = self.sample(self.modes) >= [b[0] for b in mode_bounds] _ = self.sample(self.modes) <= [b[1] for b in mode_bounds] - def _write_w_modes_of_modes(self): - """Writes the bind constraint with modes of modes""" - # Consider something like this: - # m.USD.spend(m.PV.capacity, m.PV.construction.modes) == [ - # {100: 1000, 500: 900, 1000: 800}, - # {100: 2000, 500: 1800, 1000: 1600}, - # {100: 3000, 500: 2700, 1000: 2400}, - # ] - # I don't want to run a check for this every time, so just catch the error - if self.domain.modes is not None: - for n, p in enumerate(self._parameter): - s = self.sample.aspect( - *self.domain.edit({'modes': self.domain.modes[n]}) - ) - - if self.leq: - _ = s <= p - elif self.geq: - _ = s >= p - elif self.eq: - _ = s == p + # def _write_w_modes_of_modes(self): + # """Writes the bind constraint with modes of modes""" + # # Consider something like this: + # # m.USD.spend(m.PV.capacity, m.PV.construction.modes) == [ + # # {100: 1000, 500: 900, 1000: 800}, + # # {100: 2000, 500: 1800, 1000: 1600}, + # # {100: 3000, 500: 2700, 1000: 2400}, + # # ] + # # I don't want to run a check for this every time, so just catch the error + # if self.domain.modes is not None: + # for n, p in enumerate(self._parameter): + # s = self.sample.aspect( + # *self.domain.edit({'modes': self.domain.modes[n]}) + # ) + + # if self.leq: + # _ = s <= p + # elif self.geq: + # _ = s >= p + # elif self.eq: + # _ = s == p def _check_existing(self) -> bool: """Checks if aspect already has been bound in that space"""