BioSTEAMDevelopmentGroup / Bioindustrial-Park

BioSTEAM's Premier Repository for Biorefinery Models and Results
MIT License
38 stars 17 forks source link

Consultation on modifying all unit costs #151

Open zasddsgg opened 4 months ago

zasddsgg commented 4 months ago

a) Hello, since BioSTEAM does not have Chinese investment_site_factors (https://biosteam.readthedocs.io/en/latest/API/TEA.html#:~:text=investment_site_factors%3A%20dict%5Bstr%2C%20float%5D%20%3D%20%7B%27India%27%3A%200.85%2C%20%27Japan%27%3A%201.15%2C%20%27Mexico%27%3A%200.95%2C%20%27Pacific%20Rim%27%3A%201.0%2C%20%27U.S.%20Gulf%20Coast%27%3A%201.0%2C%20%27U.S.%20Midwest%27%3A%201.15%2C%20%27U.S.%20Northwest%27%3A%201.1%2C%20%27U.S.%20Southwest%27%3A%200.95%2C%20%27U.S.%20West%20Coast%27%3A%201.25%2C%20%27Western%20Europe%27%3A%201.2%7D), may I ask you how to call investment_site_factors when executing TEA and how to call Chinese investment_site_factors (0.83) when executing TEA ? Because I didn't find any tutorials for investment_site_factors.

b) Or I can modify the unit cost according to the tutorial in TAL model (https://github.com/agvaughan/Bioindustrial-Park/blob/8ce1740633fac93821137019eaec11be0f5d94a2/biorefineries/TAL/analyses/models_ethyl_esters.py#L194-L200), but I can only change the cost of some units through the following code (only the unit with cost_items), could I consult you how to modify the cost of all units in the system?

from biorefineries import TAL
import biosteam as bst
bst.nbtutorial()
TAL.load_TAL_model('A') 
TAL.system.diagram('thorough', format='png', number=True)
for unit in TAL.system.units:
    if hasattr(unit, 'cost_items'):
        print(unit)
zasddsgg commented 4 months ago

Hello, could someone help look at this problem.

zasddsgg commented 3 months ago

@yoelcortes, @yalinli2, @sarangbhagwat Hello, could you help look at this problem.

zasddsgg commented 3 months ago

I try to use tea.FCI *= 0.83, but AttributeError: can't set attribute 'FCI' was reported.

yalinli2 commented 3 months ago

FCI is automatically calculated once the TEA._FCI method is set, if you want to update how FCI is calculated.

I think you should be able to directly update the investment_site_factors dict to include additional factors you want to use.

zasddsgg commented 3 months ago

@yalinli2 Thank you for your answer. I try to call investment_site_factors with TEA.investment_site_factors, but I get the following result.

{'U.S. Gulf Coast': 1.0,
 'U.S. Southwest': 0.95,
 'U.S. Northwest': 1.1,
 'U.S. Midwest': 1.15,
 'U.S. West Coast': 1.25,
 'Western Europe': 1.2,
 'Mexico': 0.95,
 'Japan': 1.15,
 'Pacific Rim': 1.0,
 'India': 0.85}

If I want to set the investment_site_factors of the process to 0.83 and the country is China, may I ask you how to set it? After setting, could I consult you how to call investment_site_factors to 0.83? Because investment_site_factors now seems to default to 1, and I do not know how to modify it to 0.83.

zasddsgg commented 3 months ago

@yalinli2 I did not find the use of investment_site_factors in the relevant tutorials or code in https://github.com/BioSTEAMDevelopmentGroup/Bioindustrial-Park and https://github.com/BioSTEAMDevelopmentGroup/biosteam. So could I consult you how to set investment_site_factors.

yalinli2 commented 3 months ago

I'm not sure if there's a better way to do it, but I imagine you can just make a new TEA class, then set

TEA.investment_site_factors['China'] = 0.83

Then set the _DPI function as here: https://github.com/BioSTEAMDevelopmentGroup/BLocS/blob/d9983a1f67de9e8b5d7eebb033d0c3582c0e225f/blocs/incentives/incentives_tea.py#L395 (I think F_investment is similar to the investment factor)

zasddsgg commented 3 months ago

Thanks for your advice, I have created the following code, but there are still errors TypeError: TEA.__init__() got an unexpected keyword argument 'system'.

The code is as follows.

class TEA(CellulosicEthanolTEA):
    def __init__(self, investment_site_factors=0.83):
        CellulosicEthanolTEA.__init__(self)
        self.investment_site_factors = investment_site_factors
    def _DPI(self, installed_equipment_cost):
        return self.investment_site_factors * installed_equipment_cost

def create_new_tea(sys, OSBL_units=None, cls=None):
    if OSBL_units is None: OSBL_units = bst.get_OSBL(sys.cost_units) 
    try:
        BT = tmo.utils.get_instance(OSBL_units, (bst.BoilerTurbogenerator, bst.Boiler))
    except:
        BT = None
    if cls is None: cls = TEA 
    tea = cls(
        system=sys, 
        IRR=0.10, 
        duration=(2016, 2046), 
        depreciation='MACRS10', 
        income_tax=0.35,
        operating_days=0.9*365, 
        lang_factor=None, 
        construction_schedule=(0.08, 0.60, 0.32),
        startup_months=3, 
        startup_FOCfrac=1,
        startup_salesfrac=0.5,
        startup_VOCfrac=0.75,
        WC_over_FCI=0.05,
        finance_interest=0.08,
        finance_years=10,
        finance_fraction=0.6,
        OSBL_units=OSBL_units,
        warehouse=0.04, 
        site_development=0.09, 
        additional_piping=0.045,
        proratable_costs=0.10,
        field_expenses=0.10,
        construction=0.20,
        contingency=0.10,
        other_indirect_costs=0.10, 
        labor_cost=1000000,
        labor_burden=0.30, 
        property_insurance=0.007, 
        maintenance=0.03,
        steam_power_depreciation='MACRS10', 
        boiler_turbogenerator=BT)
    return tea
tea = create_new_tea(sys)
zasddsgg commented 3 months ago

@yalinli2 I try to use the following code. The code can run well. But when I check the ratio of the FCI after multiplying the location factor to the FCI before multiplying the location factor, it's not 0.83, it's 0.78, which doesn't seem right.

class TEA(CellulosicEthanolTEA):
    _TCI_ratio_cached = 1
    def _FCI(self, FCI):
        return 0.83 * FCI

def create_new_tea(sys, OSBL_units=None, cls=None):
    if OSBL_units is None: OSBL_units = bst.get_OSBL(sys.cost_units) 
    try:
        BT = tmo.utils.get_instance(OSBL_units, (bst.BoilerTurbogenerator, bst.Boiler))
    except:
        BT = None
    if cls is None: cls = TEA 
    tea = cls(
        system=sys, 
        IRR=0.10, 
        duration=(2016, 2046), 
        depreciation='MACRS10', 
        income_tax=0.35,
        operating_days=0.9*365, 
        lang_factor=None, 
        construction_schedule=(0.08, 0.60, 0.32),
        startup_months=3, 
        startup_FOCfrac=1,
        startup_salesfrac=0.5,
        startup_VOCfrac=0.75,
        WC_over_FCI=0.05,
        finance_interest=0.08,
        finance_years=10,
        finance_fraction=0.6,
        OSBL_units=OSBL_units,
        warehouse=0.04, 
        site_development=0.09, 
        additional_piping=0.045,
        proratable_costs=0.10,
        field_expenses=0.10,
        construction=0.20,
        contingency=0.10,
        other_indirect_costs=0.10, 
        labor_cost=1000000,
        labor_burden=0.30, 
        property_insurance=0.007, 
        maintenance=0.03,
        steam_power_depreciation='MACRS10', 
        boiler_turbogenerator=BT)
    return tea
tea = create_new_tea(sys)
yalinli2 commented 3 months ago

_FCI shouldn't be calculating FCI based on FCI, it should be calculating FCI based on TDC https://github.com/BioSTEAMDevelopmentGroup/Bioindustrial-Park/blob/3a639670c9673e0b354e3aef36a35f728f6038d9/biorefineries/tea/conventional_ethanol_tea.py#L92

you probably want to look into each step of the calculation and figure out where the discrepancy was

zasddsgg commented 3 months ago

Thank you for your suggestion. According to the code for calculating FCI (https://github.com/BioSTEAMDevelopmentGroup/Bioindustrial-Park/blob/master/biorefineries/tea/cellulosic_ethanol_tea.py#L150-L152), I have changed the code to the following code. And I check the ratio of the FCI after multiplying the location factor to the FCI before multiplying the location factor, it's 0.83. Could I confirm with you that the following code is correct.

class TEA(CellulosicEthanolTEA):
    _TCI_ratio_cached = 1
    def _FCI(self, TDC):
        self._FCI_cached = FCI = TDC + self._nondepreciable_indirect_costs(self._DPI_cached)
        return 0.83 * FCI
def create_new_tea(sys, OSBL_units=None, cls=None):
    if OSBL_units is None: OSBL_units = bst.get_OSBL(sys.cost_units) 
    try:
        BT = tmo.utils.get_instance(OSBL_units, (bst.BoilerTurbogenerator, bst.Boiler))
    except:
        BT = None
    if cls is None: cls = TEA 
    tea = cls(
        system=sys, 
        IRR=0.10, 
        duration=(2016, 2046), 
        depreciation='MACRS10', 
        income_tax=0.35,
        operating_days=0.9*365, 
        lang_factor=None, 
        construction_schedule=(0.08, 0.60, 0.32),
        startup_months=3, 
        startup_FOCfrac=1,
        startup_salesfrac=0.5,
        startup_VOCfrac=0.75,
        WC_over_FCI=0.05,
        finance_interest=0.08,
        finance_years=10,
        finance_fraction=0.6,
        OSBL_units=OSBL_units,
        warehouse=0.04, 
        site_development=0.09, 
        additional_piping=0.045,
        proratable_costs=0.10,
        field_expenses=0.10,
        construction=0.20,
        contingency=0.10,
        other_indirect_costs=0.10, 
        labor_cost=1000000,
        labor_burden=0.30, 
        property_insurance=0.007, 
        maintenance=0.03,
        steam_power_depreciation='MACRS10', 
        boiler_turbogenerator=BT)
    return tea
tea = create_new_tea(sys)