Skip to content
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

Swap LCOW LCOT in REFLOSystemCosting #168

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

Zhuoran29
Copy link
Collaborator

Swap the definition of LCOW and LCOT for the system level costing:

  • LCOT: equivalent to the LCOW from the Treatment component
  • LCOW: Calculated using both Treatment and Energy components

@Zhuoran29
Copy link
Collaborator Author

Not sure why but other 7 files got reformatted. @kurbansitterley

@kurbansitterley
Copy link
Contributor

Not sure why but other 7 files got reformatted. @kurbansitterley

Yes that is goofy!

@kurbansitterley
Copy link
Contributor

Added some features to ensure we get the behavior we want for the two likely scenarios:

  1. when TreatmentCosting is used alone on a flowsheet and,
  2. when REFLOSystemCosting is used with TreatmentCosting and EnergyCosting ("integrated flowsheet")

To clarify, the "behavior we want" applies to the integrated flowsheet:

  • LCOE and LCOH reflects the levelized cost of electricity/heat (this behavior is not affected by this PR)
  • LCOT reflects the levelized cost associated only with the treatment system
  • LCOW reflects the levelized cost of the integrated system (i.e., accounts for capex/opex of both the treatment and energy systems, including the reduced electricity/heat flows and opex that come with including energy generating systems on the flowsheet).

Implementing this behavior got slightly more complicated because all three costing packages inherit the add_LCOW method from WaterTAPCosting. So what happens in scenario (2) when a user calls add_LCOW on TreatmentCosting prior to calling add_LCOW on REFLOSystemCosting? This would result in two parameters named LCOW that are calculated differently (one with treatment capex/opex and the other with both treatment and energy capex/opex). This is confusing.

So in that scenario, I added features that an LCOW parameter on TreatmentCosting would get renamed to LCOT using the same flow rate and then the only LCOW on the integrated flowsheet would be the one on REFLOSystemCosting. Using add_LCOW on EnergyCosting will continue to raise an error (you can't have an LCOW for an energy system).

This should preserve the ability to add_LCOW on flowsheets with only a TreatmentCosting package. In other words, a user that is familiar with WaterTAPCosting will still be able to add_LCOW as expected.

@Zhuoran29 @MuktaHardikar @zacharybinger @adam-a-a

@kurbansitterley kurbansitterley self-assigned this Feb 4, 2025
@kurbansitterley kurbansitterley added the costing_package Changes related to costing packages label Feb 4, 2025
@Zhuoran29
Copy link
Collaborator Author

Smart design! It makes sense and thanks for extending its feasibility and consistency. @kurbansitterley

# the parameter can be renamed from LCOW to LCOT and use the same flow rate.
add_object_reference(self, "_LCOW_flow_rate", flow_rate)

def add_LCOT(self, flow_rate):
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need this separate function? You can just use add_LCOW with name of "LCOT" and point to relevant flowrate, right?

Comment on lines +842 to +844
_log.warning(warning_msg)
treat_cost.del_component("LCOW")
treat_cost.add_LCOT(treat_cost._LCOW_flow_rate)
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure we should be doing this. Typically, we'd be more restrictive and just raise an error, telling the user that LCOW already exists and to specify a different name. Also not clear when just looking at the diff why we have a second add_LCOW definition.

Copy link
Contributor

Choose a reason for hiding this comment

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

All this monkey business I do here is to make a consideration for when the user add_LCOW using the treatment costing package (e.g., m.fs.treatment.costing.add_LCOW(flow_rate)) before doing add_LCOW with REFLOSystemCosting (e.g., m.fs.costing.add_LCOW(flow_rate)) . In that scenario, you would have two different identically named variables (LCOW) that are calculated differently.

This seemed problematic to me and potentially confusing to the user. Especially as the behavior we wanted to enforce is to have is swapping LCOW and LCOT (LCOT really just being a metric we sort of made up that is focused purely on the treatment side and to distinguish from LCOW, the levelized metric we are all familiar with). Thus, this is a way to make sure the metrics are where we want them to be. The _LCOW_flow_rate attribute is for the (probably extreme) edge case where the user wants the two levelized metrics calculated on the basis of different flow rates. (I may have really over coddled the user on this one.)

@adam-a-a
Copy link
Contributor

adam-a-a commented Feb 4, 2025

Added some features to ensure we get the behavior we want for the two likely scenarios:

  1. when TreatmentCosting is used alone on a flowsheet and,
  2. when REFLOSystemCosting is used with TreatmentCosting and EnergyCosting ("integrated flowsheet")

To clarify, the "behavior we want" applies to the integrated flowsheet:

  • LCOE and LCOH reflects the levelized cost of electricity/heat (this behavior is not affected by this PR)
  • LCOT reflects the levelized cost associated only with the treatment system
  • LCOW reflects the levelized cost of the integrated system (i.e., accounts for capex/opex of both the treatment and energy systems, including the reduced electricity/heat flows and opex that come with including energy generating systems on the flowsheet).

Implementing this behavior got slightly more complicated because all three costing packages inherit the add_LCOW method from WaterTAPCosting. So what happens in scenario (2) when a user calls add_LCOW on TreatmentCosting prior to calling add_LCOW on REFLOSystemCosting? This would result in two parameters named LCOW that are calculated differently (one with treatment capex/opex and the other with both treatment and energy capex/opex). This is confusing.

So in that scenario, I added features that an LCOW parameter on TreatmentCosting would get renamed to LCOT using the same flow rate and then the only LCOW on the integrated flowsheet would be the one on REFLOSystemCosting. Using add_LCOW on EnergyCosting will continue to raise an error (you can't have an LCOW for an energy system).

This should preserve the ability to add_LCOW on flowsheets with only a TreatmentCosting package. In other words, a user that is familiar with WaterTAPCosting will still be able to add_LCOW as expected.

@Zhuoran29 @MuktaHardikar @zacharybinger @adam-a-a

I would need to read through and review this much more carefully, but my immediate thought is that we should really just have LCOW, LCOE, LCOH, and LCOW would account for energy costs via LCOE/LCOH. I don't see the immediate need and complexity added that comes with including a separate LCOT explicitly for treatment. In my view, LCOW should account for the treatment system and also account for energy costs, which would channel through as LCOE and LCOH. Now, maybe you want options to alter how energy costs are accounted for together with treatment costs, but I am just not totally clear on why you'd need to do this.

@kurbansitterley
Copy link
Contributor

Added some features to ensure we get the behavior we want for the two likely scenarios:

  1. when TreatmentCosting is used alone on a flowsheet and,
  2. when REFLOSystemCosting is used with TreatmentCosting and EnergyCosting ("integrated flowsheet")

To clarify, the "behavior we want" applies to the integrated flowsheet:

  • LCOE and LCOH reflects the levelized cost of electricity/heat (this behavior is not affected by this PR)
  • LCOT reflects the levelized cost associated only with the treatment system
  • LCOW reflects the levelized cost of the integrated system (i.e., accounts for capex/opex of both the treatment and energy systems, including the reduced electricity/heat flows and opex that come with including energy generating systems on the flowsheet).

Implementing this behavior got slightly more complicated because all three costing packages inherit the add_LCOW method from WaterTAPCosting. So what happens in scenario (2) when a user calls add_LCOW on TreatmentCosting prior to calling add_LCOW on REFLOSystemCosting? This would result in two parameters named LCOW that are calculated differently (one with treatment capex/opex and the other with both treatment and energy capex/opex). This is confusing.
So in that scenario, I added features that an LCOW parameter on TreatmentCosting would get renamed to LCOT using the same flow rate and then the only LCOW on the integrated flowsheet would be the one on REFLOSystemCosting. Using add_LCOW on EnergyCosting will continue to raise an error (you can't have an LCOW for an energy system).
This should preserve the ability to add_LCOW on flowsheets with only a TreatmentCosting package. In other words, a user that is familiar with WaterTAPCosting will still be able to add_LCOW as expected.
@Zhuoran29 @MuktaHardikar @zacharybinger @adam-a-a

I would need to read through and review this much more carefully, but my immediate thought is that we should really just have LCOW, LCOE, LCOH, and LCOW would account for energy costs via LCOE/LCOH. I don't see the immediate need and complexity added that comes with including a separate LCOT explicitly for treatment. In my view, LCOW should account for the treatment system and also account for energy costs, which would channel through as LCOE and LCOH. Now, maybe you want options to alter how energy costs are accounted for together with treatment costs, but I am just not totally clear on why you'd need to do this.

The main reason to do this is to make sure that the proper capex/opex costs are going into the levelized metric we want them to. You can see my comment above but because of the way these are set up and costs/flows are aggregated, adding it to the wrong costing package would probably result in very different values for the same system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
costing_package Changes related to costing packages
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants