BioSTEAMDevelopmentGroup / biosteam

The Biorefinery Simulation and Techno-Economic Analysis Modules; Life Cycle Assessment; Chemical Process Simulation Under Uncertainty
Other
175 stars 35 forks source link

Updated installed equipment cost formulation #59

Closed yoelcortes closed 3 years ago

yoelcortes commented 3 years ago

Previously, the installed equipment cost was calculated as follows:

C_BM = C_P * F_BM

Which only applies when the bare-module factor is for the given material, pressure, and design. Now we use the more complete formula:

C_BM = C_Pb (F_BM + F_D F_P * F_M - 1)

Where:

All previous code should still work, but if you're working with different design, pressure or material factors, you can use the new F_D, F_Pand F_M dictionaries to specify them. You'll also need to add values to the baseline_purchase_costs dictionary (not the purchase_costs dictionary), then BioSTEAM will take care of calculating both the actual purchase costs (after accounting for construction material and design) and the installed equipment costs.

Here is an example:

import biosteam as bst
class Tank(bst.Unit):
    _BM = {'Tank': 2.3}

    def _cost(self):
        self.F_M['Tank'] = 1.25
        self.baseline_purchase_costs['Tank'] = 1e6

bst.settings.set_thermo(['Water'])
T1 = Tank(ins=bst.Stream(Water=10))
T1.simulate()
print(T1.baseline_purchase_costs)
print(T1.purchase_costs) # Correctly accounts for material factor
print(T1.installed_costs) # Correctly accounts for bare-module and material factor

Output:

{'Tank': 1000000.0}
{'Tank': 1250000.0}
{'Tank': 2550000.0}

Note that adding values to the baseline_purchase_costs dictionary is preferable over the purchase_costs dictionary, regardless if you are using different material factors or not. You'll get a helpful warning if you add items to the purchase_costs dictionary instead of the baseline_purchase_costs. For more details, you can checkout the code:

https://github.com/BioSTEAMDevelopmentGroup/biosteam/blob/af1faa9548521cfa3732317bb5dedbc32d0513fc/biosteam/_unit.py#L310

@yalinli2, I also made BioSTEAM spit out a warning if the BM is not included for a purchase cost item (instead of raising an error).

Hope this helps!

yalinli2 commented 3 years ago

Hi Yoel, thanks for the notice, some questions:

C_BM = C_Pb (F_BM + F_D F_P * F_M - 1)

Where:

  • C_BM is the bare module cost

So is C_BM installed cost or the bare module cost? Are they the same?

Thanks!

yoelcortes commented 3 years ago

Hi Yalin,

Here are the answers to your questions:

Let me know if you have more questions!

yalinli2 commented 3 years ago

This all looks good, thanks for explaining and adding the references!

yoelcortes commented 3 years ago

Quick update; The factors are now public (so they are called F_D, F_P, and F_M now).

yalinli2 commented 3 years ago

Cool! Is F_BM public?

yoelcortes commented 3 years ago

@yalinli2, not yet... but yeah, I've been thinking about making the _BM dictionary the default values for a public F_BM dictionary that gets created with the unit instance. I think this would be better than having bare-module factors as class attributes... which leaves little room for flexibility.

What do you think? Thumbs up and I'll go ahead and fix this up over the weekend.

yalinli2 commented 3 years ago

I'm on board! 👍 Thanks Yoel!!!

yoelcortes commented 3 years ago

Done!

Additionally, to make it easier to understand for future new users, I renamed _BM to _F_BM_default. I also added equipment_lifetime as an instance attribute and renamed the _equipment_lifetime class attribute to _default_equipment_lifetime (again, to make it easier to understand without necessarily reading documentation).

I added some checks for Unit subclassing to make sure '_BM' and '_equipment_lifetime' are not used anymore. All tests passed on my computer.

Hopefully it's not too much trouble to make the renames in QSDsan (just import, let it error, and rename).

Thanks!

yalinli2 commented 3 years ago

Sounds good, thanks Yoel!!!