Skip to content

Plots#84

Merged
johnjasa merged 18 commits intoNatLabRockies:developfrom
jaredthomas68:plots
Mar 7, 2025
Merged

Plots#84
johnjasa merged 18 commits intoNatLabRockies:developfrom
jaredthomas68:plots

Conversation

@jaredthomas68
Copy link
Collaborator

Include plotting functionality for greenheart output

This PR provides a few plotting options based on the energy_flows.csv data output from greenheart to visualize the electricity and hydrogen dispatch/flow/production independently and together. There are certainly better ways this could be done, but I'm not sure how far to go given the impending changes.

PR Checklist

  • CHANGELOG.md has been updated to describe the changes made in this PR
  • Documentation
    • Docstrings are up-to-date
    • [-] Related docs/ files are up-to-date, or added when necessary
    • [-] Documentation has been rebuilt successfully
    • Examples have been updated
  • Tests pass (If not, and this is expected, please elaborate in the tests section)
  • PR description thoroughly describes the new feature, bug fix, etc.

Related issues

Impacted areas of the software

  • examples/01-green-hydrogen.ipynb: add example of using the new plots
  • greenheart/tools/eco/utilities.py
    • visualize_plant: adjustments for slightly more automatic scaling and better looking plots for onshore and offshore
  • greenheart/tools/plot.py
    • get_hour_from_datetime
    • plot_hydrogen_flows: new function
    • plot_energy_flows: new function
    • plot_energy: new function

Additional supporting information

Test results, if applicable

@review-notebook-app
Copy link

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@jaredthomas68 jaredthomas68 changed the base branch from main to develop February 12, 2025 22:50
@jaredthomas68 jaredthomas68 marked this pull request as ready for review February 13, 2025 17:58
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@johnjasa can you remind me, did you say something about not pushing results in Jupyters?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe you are right @kbrunik. @RHammond2 I pushed these results since there were new figures in the example. What is the correct/accepted approach on this?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right @kbrunik we discussed it, though for now we should keep the jupyter notebooks as-is and push results with them. In the future, we might avoid keeping results in the repo; see (and add to!) the discussion here: #75

onshorey = 50

wind_buffer = np.min(turbine_x) - (onshorey + 2 * rotor_diameter + electrolyzer_side)
wind_buffer = np.min(turbine_x) - (onshorey + 3 * rotor_diameter + electrolyzer_side)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did this change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We needed a larger buffer so I called the buffer by an extra rotor diameter to avoid overlap in the wind/solar farms

for x, y in zip(turbine_x, turbine_y):
if i == 0:
elable = "Electrolyzer"
elabel = "Electrolyzer"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we want to change this to "H$_2$ Electrolyzer" or "PEM Electrolyzer" since we are working on additional types of electrolysis (iron, alkaline, etc)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I've changed it to "H$_2$ Electrolyzer" in all instances for now but am open to further changes.

label="Solar Array",
hatch=solar_hatch,
)
if design_scenario["wind_location"] != "offshore":
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be an if statement for "pv_location"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, there are different plots to add solar to depending on if wind is onshore or offshore. Convoluted and should be fixed, but I think that making this plot more clear/robust should wait for another PR.

Comment on lines +1250 to +1255
# ax[ax_index_wind_plant].autoscale()
ax[ax_index_wind_plant].set(aspect="equal")
# ax[ax_index_wind_plant].xaxis.set_major_locator(ticker.\
# MultipleLocator(np.round(point_range_x*0.5, decimals=-3)))
# ax[ax_index_wind_plant].yaxis.set_major_locator(ticker.\
# MultipleLocator(np.round(point_range_y*0.5, device_spacing=-3)))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and in a few spots below here, do you intend to keep these commented lines on purpose?

@johnjasa
Copy link
Collaborator

johnjasa commented Feb 17, 2025

Looking at the generated plots, I think there's a small error in the Electricity Output; it should probably be divided by 1e6 instead of multiplied by 1e6 somewhere. Okay, I've pushed up a fix directly to this branch, so no action needed for this point. The plots will be updated the next time you update the jupyter notebook itself.

Also, is the battery power in the correct units here? Seeing tens of GW spikes is throwing me off.

image

@johnjasa
Copy link
Collaborator

Non-blocking nitpick: at hour 0 there's a vertical line for net dispatch; is this meaningful or sort of a plotting artifact? is it easy to remove if it's spurious?
image

@jaredthomas68
Copy link
Collaborator Author

jaredthomas68 commented Mar 7, 2025

Looking at the generated plots, I think there's a small error in the Electricity Output; it should probably be divided by 1e6 instead of multiplied by 1e6 somewhere. Okay, I've pushed up a fix directly to this branch, so no action needed for this point. The plots will be updated the next time you update the jupyter notebook itself.

Also, is the battery power in the correct units here? Seeing tens of GW spikes is throwing me off.

image

The spikes are due to having a 100 MW/100 MWh battery. It looks like the output is giving orders of magnitude larger than expected for the battery though. This shows up in the output files. During the simulation, one of the spikes actually charge in about 4 hours and then discharges in one hour. The x scale makes that hard to see, but here is the figure zoomed in a little in the x axis:
image

I also found a scaling problem in the plotting function. I just pushed a fix for it with this result:
image

@johnjasa
Copy link
Collaborator

johnjasa commented Mar 7, 2025

Looking at the generated plots, I think there's a small error in the Electricity Output; it should probably be divided by 1e6 instead of multiplied by 1e6 somewhere. Okay, I've pushed up a fix directly to this branch, so no action needed for this point. The plots will be updated the next time you update the jupyter notebook itself.
Also, is the battery power in the correct units here? Seeing tens of GW spikes is throwing me off.
image

The spikes are due to having a 100 MW/100 MWh battery. During the simulation, one of the spikes actually charge in about 4 hours and then discharges in one hour. The x scale makes that hard to see, but here is the figure zoomed in a little in the x axis: image

Thanks for looking into this, Jared! This makes sense, though I do have a question about the scale of the battery power. In the top right subplot of the figure you shared, it looks like battery power is in the 10s of GW as it charges and discharges. Is this correct for a 100MW/100MWh battery?

@johnjasa johnjasa merged commit 5186cd3 into NatLabRockies:develop Mar 7, 2025
4 checks passed
@jaredthomas68
Copy link
Collaborator Author

Looking at the generated plots, I think there's a small error in the Electricity Output; it should probably be divided by 1e6 instead of multiplied by 1e6 somewhere. Okay, I've pushed up a fix directly to this branch, so no action needed for this point. The plots will be updated the next time you update the jupyter notebook itself.
Also, is the battery power in the correct units here? Seeing tens of GW spikes is throwing me off.
image

The spikes are due to having a 100 MW/100 MWh battery. During the simulation, one of the spikes actually charge in about 4 hours and then discharges in one hour. The x scale makes that hard to see, but here is the figure zoomed in a little in the x axis: image

Thanks for looking into this, Jared! This makes sense, though I do have a question about the scale of the battery power. In the top right subplot of the figure you shared, it looks like battery power is in the 10s of GW as it charges and discharges. Is this correct for a 100MW/100MWh battery?

Fixed

@jaredthomas68 jaredthomas68 mentioned this pull request Mar 7, 2025
6 tasks
RHammond2 added a commit that referenced this pull request Apr 7, 2025
* Delete .github/workflows/conda_build.yml

Build was long outdated and did not work; can revisit in the future

* Save output (#81)

* first pass

* update default financial config files in tests to work with current HOPP

* update required hopp version

* lower case hopp in .toml

* remove support for python 3.9

* update model year to 2022

* specify equation year for steel

* remove work towards dynamic cost year for steel and ammonia

* update changelog

* trying to get save working

* working io for greenheart output

* update io to work with ammonia and steel

* working with ammonia and steel finance

* revert steel.py changes

* revert openmdao.py changes

* update changelog and docstring

* add PyYAML to .toml

* remove temp file

* remove unnecessary input to  and update doc string for  and

* simplify IO control flow

* adjust logic so numpy types are caught before checking for python native types

* adjust io tests comparison to work in python 3.10

* fix ignore catch in test

* make greenheart output loader a class method

* make if statements in  standalone

* remove old commented doc string and duplicate pandas setting call

---------

Co-authored-by: John Jasa <johnjasa11@gmail.com>

* Figure label naming (#85)

* update all figure data labels to use sentence capitalization

* update from 'tonne' and 'metric tonne' to 'metric ton' as per direction from NREL communications team

* Expanding GreenHEART docs to include how to add a new tech (#89)

* Remove reference plants from examples (#87)

* remove reference plants from examples

* update changelog

* update examples readme

---------

Co-authored-by: John Jasa <johnjasa11@gmail.com>

* Plots (#84)

* include plots

* update doc strings

* add show and save parameters

* update plot size, bounds, and labels

* onshore plots working

* make all labels and names and legends sentence case

* updated plot scaling

* update changelog

* update example 01 with plot

* provide default data path and resize figure

* remove duplicate plot

* update to specify that electrolyzers in these figures are hydrogen electrolyzers

* Fixing units bug on plotting

* fix scaling

* updated example with energy flow plot working

* updated example with energy flow plot working

---------

Co-authored-by: John Jasa <johnjasa11@gmail.com>

* Plots update h2 dispatch (#95)

* include plots

* update doc strings

* add show and save parameters

* update plot size, bounds, and labels

* onshore plots working

* make all labels and names and legends sentence case

* updated plot scaling

* update changelog

* update example 01 with plot

* provide default data path and resize figure

* remove duplicate plot

* update to specify that electrolyzers in these figures are hydrogen electrolyzers

* Fixing units bug on plotting

* fix scaling

* updated example with energy flow plot working

* updated example with energy flow plot working

* shift energy flow plot to use h2 demand from sizing function

* update changelog

* update doc string

---------

Co-authored-by: John Jasa <johnjasa11@gmail.com>

* Update CONTRIBUTING.md

* Create build_book.sh

* Update CONTRIBUTING.md

* Update pyproject.toml

* Update pyproject.toml

* LCOH Update and Custom Electrolyzer Costs (#79)

* updated lcoh calc for to be more aligned with GS methodology

* fixed circular import error with electrolyzer cost tools

* ran formatter on new file

* ran formatter on modified files

* formatted

* actually fixed for tests

* updated tests with new values

* modified adjust_dollar_year to be able to take in dictionaries or lists too

* updated electrolyzer cost tools integrated variable om

* updated example input files

* updated test input files for test_greensteel

* added test for custom PEM cost function

* changed input for custom pem cost

* update test input file

* adjusted openmdao test assert

* added profast_reverse_tools functions

* added some docstrings to new functions

* added more doc strings to profast tools

* updated input file to fix tests

* updated doc strings and refurb period in electrolyzer output config

* moved setting default installation time to setup_greenheart

* updated variable names in finance.py and added doc strings to pem cost functions and put userwarning in electrolysis

* removed unused functions from profast tools

* renamed fixed om name in custom pem cost test input

* Updated optimization test to be better posed

* changed warning format in electrolysis.py

* minor changes from review

* updated formatting units in comments in pem_cost_tools.py

* removed commented out code and updated some docstrings

* Changed custom to basic_custom for PEM costs

---------

Co-authored-by: John Jasa <johnjasa11@gmail.com>

* Update PEM efficiency to 51.0 kWh/kg from 54.6 kWh/kg (#102)

* update PEM efficiency

* update test values for new PEM efficiency

* update examples/docs

* update the changelog

* Updates for HOPP v3.2.0, update PySAM version to 6.0+ (#104)

* Updates for HOPP v3.2.0

* Updated all floris-running tests with layout_mode per HOPP v3.2.0 change

* Updated more floris-running tests with layout_mode per HOPP v3.2.0 change

* Updated wave-related tests due to pysam updates

* CRF/WACC/ProFAST Solution (#105)

* get and save full profast solution output

* update tests

* update change log

* Rename legacy GreenHEART to H2Integrate (#106)

* rename greenheart to h2integrate within files

* rename greenheart to h2integrate in the docs

* rename greenheart to h2integrate in the examples

* rename greenheart to h2integrate in code and tests

* pre-commit updates

* additional renaming updates

* Update CHANGELOG.md

* Pinned orbit version (#108)

* Pinned floris version

* Adding iron capabilities to GreenHEART (#90)

* Initial changes from before greenheart split

* Saving 'checkpoint' pickles

* Adding Stinn model for costs

* Adding csv to yaml tool

* Pulled Rosner model inputs and coeffs into .csvs

* Created 4 new files based on iron.py, one for each step in process (ore mining, ore preprocessing, electrowinning, and post processing)

* Updating greenheart_simulation.py to import and use iron ore, pre, win, and post files from previous commit

* Costs synchronized between Rosner model and placeholder

* Keep example script running

* Moving Stinn to named folder

* Adding templates for future work

* Added modular_iron switch

* add Rosner cost models

* update performance coeffs and ensure each tech in Rosner runs

* update cost model with ng feedstocks

* Refactored Stinn cost model

* Changing location and lcoe and lcoh

* get lin and exp for power fit

* capital cost updates

* refit cost curve, including peters model

* remove unnecessary file

* Save pkls to nice subdirectories

* ng dri coeffs

* refit coeffs ng dri

* Mapping online

* Mapping in greenheart, can't skip webcall yet

* Mapping iron

* Ore working in ProFAST

* Rosner running with finance_model

* Modular working

* remove unused files

* mapping ore and iron

* updating rosner models to be modular

* iron post financial model

* ng eaf

* Mapping points without arcgis

* Combined map

* updated openmdao import to fix bug with install

* added profast tools

* moved saving and loading previous data to individual functions

* load in pf instance

* equivalent lco for dri_eaf and dri with eaf

* remove to_csv

* moved all saving and loading results to external script functions

* added ability for user to input lcoe,lcoh and annual h2

* Moving maps out of greenheart

* Fixing indent of hydrogen_amount_kgpy

* Fix for amiguous truth value of empty array

* Updating GreenHEART files for H2 DRI and NG DRI

* Correcting failing pytests, removed passing of iron_performance in utilities.py and added iron_out_fn to greenheart_config to easily open iron_performance results in lca calculations

* Quality checked models with Rosner Ore and Rosner Override

* lunch

* LCA multiprocessing and mapping (with error)

* Making run_example_plant run

* Fixed column in top_down_coeffs

* All geography calculated

* debugging after name change

* WIP: converting to functions nicely for iron in greenheart simulation

* Updating names from pre_iron to run_full_simulation

* Removed erroneous prints

* rename to fit typical gh naming convention

* update necessary naming for iron model runs

* add iron tests

* test full iron run

* fix tests

* Pulling wind and solar annual energies out of hopp_results within run_physics

* added return to greenheart simulation

* remove copy files

* fix type

* Working through pre-commit issues

* WIP: fixing other pre-commit issues

* docstrings

* WIP: handling pre-commit issues

* Renaming capitalized directories for Windows compatability

* Fixed kwarg dataclass default for dict

* Fixed path error for python 3.10

* Added a check for iron win or iron post product selection

* Docstring cleanup and pickle saving refactoring

* Fixed import path

* Fixed logic check for test

* Added changelog notes

* Expanded changelog

* Removing unused files, adding precision to tests

* Trying to resolve merge issues

* Setting the power curve in floris

* Removing debt_equity_split

* Removing iron carbon intensity test

* Adding coke and lime emissions to iron h2_dri_eaf and ng_dri_eaf

* Renamed sim file utils

* Rearranging files for iron

* Fixed import

* Fixing pre-commit errors

* fixing pre-commit errors in h2integrate_simulation.py

* Passing, missing coke GREET values

* Bringing coke back in

* Addressing cbay comments

* Added docstrings to h2integrate_simulation

* Added missing vars to docstrings

---------

Co-authored-by: jmartin4 <jonathan.martin@nrel.gov>
Co-authored-by: Jonathan Martin <94018654+jmartin4nrel@users.noreply.github.com>
Co-authored-by: Dakota Ramos <dakota.ramos@nrel.gov>
Co-authored-by: kbrunik <kbrunik@gmail.com>
Co-authored-by: kbrunik <102193481+kbrunik@users.noreply.github.com>
Co-authored-by: elenya-grant <116225007+elenya-grant@users.noreply.github.com>

* release v0.2 prep

---------

Co-authored-by: John Jasa <johnjasa11@gmail.com>
Co-authored-by: Jared Thomas <jaredthomas68@users.noreply.github.com>
Co-authored-by: kbrunik <102193481+kbrunik@users.noreply.github.com>
Co-authored-by: elenya-grant <116225007+elenya-grant@users.noreply.github.com>
Co-authored-by: Chris Bay <12664940+bayc@users.noreply.github.com>
Co-authored-by: jmartin4 <jonathan.martin@nrel.gov>
Co-authored-by: Jonathan Martin <94018654+jmartin4nrel@users.noreply.github.com>
Co-authored-by: Dakota Ramos <dakota.ramos@nrel.gov>
Co-authored-by: kbrunik <kbrunik@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants