-
Notifications
You must be signed in to change notification settings - Fork 27
Iron: Example with independently sized mine and iron/steel plant #433
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Iron: Example with independently sized mine and iron/steel plant #433
Conversation
…on_mine_plant_diff_sizes
| total_priority = np.sum(commodity_to_priority) | ||
| total_other = np.sum(commodity_to_other) | ||
| # Need to do this in case _out is different units than _producced | ||
| frac_priority = total_priority / (total_priority + total_other) | ||
| total_produced = inputs[f"total_{self.config.commodity}_produced"] | ||
| total_priority = total_produced * frac_priority | ||
| total_other = total_produced * (1 - frac_priority) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May be able to refactor this to not require total_iron_ore_produced and instead get the sum in the splitter directly. This simplifies the tech interconnections. Suggested by @dakotaramos
…e_plant_diff_sizes
elenya-grant
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this looks good! Thanks for updating this example, adding a doc page, and removing the old files. And thanks for updating the feedstock component to be more flexible! This PR looks good to me but I'd want your review of the changes I made before it gets merged in!
I made the change you requested, but would like your feedback on it (many of my comments are pointing out where I made changes). Its a bit of a workaround at the moment but I don't think we should make any large changes to the H2I framework to accommodate the specific use-case (using the consumed amount of something for a transport model) until we have other transport models and better understand whether this use-case is common enough to require a more polished integration.
If you haven't done so already, could you put a quick blurb in the PR description to explain why the test values changed (increased) for the example 21 integration test?
| ["natural_gas_feedstock","iron_plant","natural_gas","pipe"], | ||
| # connect feedstocks to steel plant | ||
| # Use the iron ore consumed by the iron plant to calculate transport costs | ||
| ["iron_plant","iron_transport", ["iron_ore_consumed","iron_ore_in"]], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jmartin4u - this is where I'm connecting the iron ore consumed to the iron transport model
| # Connect the LCOI of iron ore to the price of a feedstock component representing the ore to be used in DRI | ||
| ["finance_subgroup_iron_ore","processed_ore_feedstock",["price_iron_ore","price"]], | ||
| # Connect the ore feedstock available to the iron plant | ||
| ["processed_ore_feedstock","iron_plant","iron_ore","pipe"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I replaced iron_transport here with a pipe so that the iron_transport model is not input the total iron ore available
| n_timesteps = self.options["plant_config"]["plant"]["simulation"]["n_timesteps"] | ||
| feedstock_type = self.config.feedstock_type | ||
| self.n_timesteps = self.options["plant_config"]["plant"]["simulation"]["n_timesteps"] | ||
| self.add_input( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jmartin4u - I also added rated capacity as an input to the feedstock, felt like it could be useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for adding this doc page! It looks great!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for removing the old files!
| with subtests.test("Value check on LCOP"): | ||
| lcop = h2i.model.get_val("finance_subgroup_pig_iron.LCOP", units="USD/t")[0] | ||
| assert pytest.approx(lcop, rel=1e-4) == 353.99805215243265 | ||
| assert pytest.approx(lcop, rel=1e-4) == 359.670379351 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jmartin4u - these numbers decreased from what you had changed them to before, but are higher than what they were before this PR
Example with independently sized mine and iron/steel plant
This PR changes the iron example (#21) so that the
iron_minecan be realistically large and produce a largeiron_ore_outstream that is not entirely consumed by the downstreamiron_plant. This allows theprice_iron_oreto be calculated separately in its own financial subgroup, then passed to theiron_plantvia a feedstock. To achieve this, I exposed thepriceconfig variable in the feedstock model as an OpenMDAO input.This is still a draft PR because there is one issue that needs to be resolved: When
iron_transportis connected to aniron_orefeedstock, it calculates its cost based on theiron_ore_inconnected to theiron_ore_outfrom the feedstock, which is calculated in the feedstock performance model as the fullrated_capacity. Theiron_transportneeds itsiron_ore_into instead be connected to theiron_ore_consumedfrom theiron_plant, but I'm not sure how to do this. I think it is only an issue when transporters themselves are calculating cost per unit of the feedstock transported - it doesn't crop up when we are just using simple pass-throughpipeandcabletransporters. I think @elenya-grant is probably the best person for this and tagged her in the TODO listAt the same time I am working in a doc page for
iron_minewhich was missing. If it's not cramming too much into one PR, it would be great if @kbrunik could write a doc page foriron_dri_planttoo.Section 1: Type of Contribution
Section 2: Draft PR Checklist
TODO:
iron_transportcosts using a feedstock.iron_plant.mdto go with theiron_mine.mdpage that's already in this PR?Type of Reviewer Feedback Requested (on Draft PR)
Structural feedback:
Implementation feedback:
Other feedback:
Section 3: General PR Checklist
docs/files are up-to-date, or added when necessaryCHANGELOG.mdhas been updated to describe the changes made in this PRSection 3: Related Issues
Section 4: Impacted Areas of the Software
Section 4.1: New Files
docs\technology_models\iron_mine.md: Rectifying the missing technology doc page foriron_mineSection 4.2: Modified Files
examples\21_iron_mn_to_il\: Updated example to show the breakdown of ore, iron, and steel costs, removed comparisons with old code now that we are fully running on H2I framework.tech_config.yaml- Added aprocessed_ore_feedstockthat represents the subset of theiron_mineore output that is passed toiron_plant, so that these two converters can be sized independentlyexamples\test\test_all_examples.py: Slight differences in test values due to changes in the exampleh2integrate\core\feedstocks.py: Changedpricefrom a config variable to an inputSection 5: Additional Supporting Information
When I run
run_iron.py, the last two cases should produce the same levelized costs, but they are not. This is because theiron_transporttransporter is calculating its costs based on therated_capacity. I want to get this running so that when I change therated_capacityofprocessed_iron_ore_feedstocks, the levelized costs are not affected (as long as the capacity is above what theiron_plantneeds to consume).Section 6: Test Results, if applicable
Section 7 (Optional): New Model Checklist
docs/developer_guide/coding_guidelines.mdattrsclass to define theConfigto load in attributes for the modelBaseConfigorCostModelBaseConfiginitialize()method,setup()method,compute()methodCostModelBaseClasssupported_models.pycreate_financial_modelinh2integrate_model.pytest_all_examples.pydocs/user_guide/model_overview.mddocs/section<model_name>.mdis added to the_toc.yml