LCA

class qsdsan.LCA(system, lifetime, lifetime_unit='yr', indicators=(), uptime_ratio=1, annualize_construction=False, simulate_system=True, simulate_kwargs={}, **item_quantities)

For life cycle assessment (LCA) of a System.

Parameters:
  • system (biosteam.System) – System for which this LCA is conducted for.

  • lifetime (int) – Lifetime of the LCA.

  • lifetime_unit (str) – Unit of lifetime.

  • indicators (Iterable(obj)) – ImpactIndicator objects or their IDs/aliases.

  • uptime_ratio (float) – Fraction of time that the system is operating.

  • annualize_construction (bool) – Used in the case that the lifetime of this LCA (e.g., 10 years) is not divisible by the lifetime of certain equipment (e.g., 8 years). If True, then the impacts from construction will be annualized using the lifetime of the equipment; if False, then the total number of the equipment needed throughout this LCA will be calculated using ceil(LCA lifetime/equipment lifetime).

  • simulate_system (bool) – Whether to simulate the system before creating the LCA object.

  • simulate_kwargs (dict) – Keyword arguments for system simulation (used when simulate_system is True).

  • item_quantities (kwargs, ImpactItem or str = float/callable or (float/callable, unit)) – Other ImpactItem objects (e.g., electricity) and their quantities. Note that callable functions are used so that quantity of items can be updated.

Examples

A system should be constructed prior to LCA, here we import a pre-constructed one.

>>> import qsdsan as qs
>>> from qsdsan.utils import create_example_system
>>> sys = create_example_system()
>>> sys.diagram() 
>>> sys.simulate()
>>> sys.show()
System: sys
ins...
[0] salt_water
    phase: 'l', T: 298.15 K, P: 101325 Pa
    flow (kmol/hr): H2O   111
                    NaCl  0.856
[1] methanol
    phase: 'l', T: 298.15 K, P: 101325 Pa
    flow (kmol/hr): Methanol  0.624
[2] ethanol
    phase: 'l', T: 298.15 K, P: 101325 Pa
    flow (kmol/hr): Ethanol  0.217
outs...
[0] alcohols
    phase: 'l', T: 298.15 K, P: 101325 Pa
    flow (kmol/hr): Methanol  0.624
                    Ethanol   0.217
[1] waste_brine
    phase: 'l', T: 350 K, P: 101325 Pa
    flow (kmol/hr): H2O   88.8
                    NaCl  0.684

And we also need to specify the impact indicators that we are interested in.

>>> GWP = qs.ImpactIndicator('GlobalWarming', alias='GWP', unit='kg CO2-eq')
>>> FEC = qs.ImpactIndicator('FossilEnergyConsumption', alias='FEC', unit='MJ')

There are four different types of impacts in QSDsan: construction, transportation, stream, and others.

Note that it is best to add the impact items when developing the unit module, (i.e., typically in the _design function, but can also in _run or _cost) but for illustrative purpose, we add it after the system is constructed.

Construction is mainly used for impacts that only occur once per lifetime of the equipment or the unit.

For example, assume we want to consider the amount of stainless steel and concrete used in constructing the MixTank M1.

>>> # Make the impact item, numbers are made up
>>> SS = qs.ImpactItem('SS', functional_unit='kg', GWP=3, FEC=50)
>>> Concrete = qs.ImpactItem('Concrete', functional_unit='kg', GWP=4, FEC=30)
>>> # Specify the amount of stainless steel and concrete used in the unit
>>> SS_constr_M1 = qs.Construction(item=SS, quantity=100)
>>> Concrete_constr_M1 = qs.Construction(item=Concrete, quantity=50)
>>> # Retrieve the unit from the registry
>>> flowsheet = qs.Flowsheet.flowsheet.default
>>> M1 = flowsheet.unit.M1
>>> # Add the construction activity
>>> M1.construction = (SS_constr_M1, Concrete_constr_M1)

Transportation activity can be added in a similar manner, assuming that stainless steel and concrete are delivered by truck from 500 km away.

The interval set below is assuming a system lifetime of 10 year and this delivery is only needed once for the entire lifetime.

>>> lifetime = 10
>>> Trucking = qs.ImpactItem('Trucking', functional_unit='kg*km',
...                          GWP=0.5, FEC=1.5)
>>> total_quantity = SS_constr_M1.quantity + Concrete_constr_M1.quantity
>>> Trans_M1 = qs.Transportation(item=Trucking, load_type='mass',
...                              load=total_quantity, distance=500,
...                              interval=lifetime, interval_unit='yr')
>>> M1.transportation = Trans_M1

We can als consider the impacts associated with chemicals and emissions. For example, assume the acquisition of methanol, ethanol and disposal of the waste brine all have impacts, but the generated alcohols can be treated as a product therefore have credits with

>>> # Retrieve streams
>>> methanol = flowsheet.stream.methanol
>>> ethanol = flowsheet.stream.ethanol
>>> alcohols = flowsheet.stream.alcohols
>>> waste_brine = flowsheet.stream.waste_brine
>>> # Create `StreamImpactItem` and link to the streams
>>> methanol_item = qs.StreamImpactItem(linked_stream=methanol, GWP=2, FEC=13)
>>> ethanol_item = qs.StreamImpactItem(linked_stream=ethanol, GWP=2.1, FEC=25)
>>> alcohols_item = qs.StreamImpactItem(linked_stream=alcohols, GWP=-0.2, FEC=-5)
>>> brine_item = qs.StreamImpactItem(linked_stream=waste_brine, GWP=2, FEC=3)

Finally, there might be other impacts we want to include in the LCA, for example, the electricity needed to operate the system.

We can use add those additional items when creating the LCA object.

>>> # Get the electricity usage of the system throughout the lifetime,
>>> # note that the default power utility unit is hr
>>> total_power = sys.power_utility.rate*24*365*lifetime
>>> # Create an impact item for the electricity
>>> e_item = qs.ImpactItem('e_item', 'kWh', GWP=1.1, FEC=24)
>>> # Create the LCA object
>>> lca = qs.LCA(system=sys, lifetime=10, e_item=total_power)

Now we can look at the total impacts associate with this system.

>>> lca.show() 
LCA: sys (lifetime 10 yr)
...
>>> # Retrieve impacts associated with a specific indicator
>>> lca.get_total_impacts()[GWP.ID] 
349737809...
>>> # Or breakdowns of the different category
>>> lca.get_impact_table('Construction') 
>>> # Below is for testing purpose, you do not need it
>>> lca.get_impact_table('Construction').to_dict() 
{'Quantity': ...
>>> lca.get_impact_table('Transportation').to_dict() 
{'Quantity': ...
>>> lca.get_impact_table('Stream').to_dict() 
{'Mass [kg]': ...
>>> lca.get_impact_table('Construction').to_dict() 
{'Quantity': ...

You can also allocate the impact based on mass, energy, value, or a ratio you like

>>> lca.get_allocated_impacts(sys.products, allocate_by='mass')['waste_brine']['FossilEnergyConsumption'] 
46018554...
>>> lca.get_allocated_impacts(sys.products, allocate_by='energy')['alcohols']['GlobalWarming'] 
11063012...
>>> alcohols.price = 5
>>> waste_brine.price = 1
>>> GWP_alcohols = lca.get_allocated_impacts(sys.products, allocate_by='value')['alcohols']['GlobalWarming']
>>> GWP_brine = lca.get_allocated_impacts(sys.products, allocate_by='value')['waste_brine']['GlobalWarming']
>>> GWP_alcohols + GWP_brine 
5469809...
>>> lca.get_total_impacts(exclude=sys.products)['GlobalWarming'] 
5469809...
>>> # Clear all registries for testing purpose
>>> from qsdsan.utils import clear_lca_registries
>>> clear_lca_registries()
add_other_item(item, f_quantity, unit='')

Add other ImpactItem in LCA.

clear_lca_registries()

Clear registries related to LCA, including instances of ImpactIndicator, ImpactItem, Construction, and Transportation

Parameters:

print_msg (bool) – Whether to print registry clear notice.

Examples

>>> from qsdsan.utils import clear_lca_registries
>>> clear_lca_registries(True)
All impact indicators have been removed from the registry.
All impact items have been removed from the registry.
All construction activities have been removed from the registry.
All transportation activities have been removed from the registry.
property construction_inventory

[tuple] All construction activities.

property construction_units

[set] All units in the linked system with construction activity.

get_allocated_impacts(streams=(), allocate_by='mass')

Allocate total impacts to one or multiple streams.

Note that original impacts assigned to the streams will be excluded, i.e., the total impact for allocation will be calculated using LCA.get_total_impacts(exclude=streams).

Parameters:
  • streams (Iterable(obj)) – One or a Iterable of streams. Note that impacts of these streams will be excluded in calculating the total impacts.

  • allocate_by (str, Iterable, or function to generate an Iterable) – If provided as a str, can be “mass” (F_mass), “energy” (HHV), or ‘value’ (F_mass`*`price) to allocate the impacts accordingly. If provided as an Iterable (no need to normalize so that sum of the Iterable is 1), will allocate impacts according to the Iterable. If provided as a function, will call the function to generate an Iterable to allocate the impacts accordingly.

  • note:: (..) – Energy of the stream will be calculated as the sum of HHVs of all components in the stream.

get_construction_impacts(units=None, time=None, time_unit='hr')

Return all construction-related impacts for the given unit, normalized to a certain time frame.

get_impact_table(category, time=None, time_unit='hr')

Return a pandas.DataFrame table for the given impact category, normalized to a certain time frame.

get_other_impacts(time=None, time_unit='hr')

Return all additional impacts from “other” ImpactItems objects, based on defined quantity.

get_stream_impacts(stream_items=None, exclude=None, kind='all', time=None, time_unit='hr')

Return all stream-related impacts for the given streams, normalized to a certain time frame.

get_total_impacts(exclude=None, time=None, time_unit='hr')

Return total impacts, normalized to a certain time frame.

get_transportation_impacts(units=None, time=None, time_unit='hr')

Return all transportation-related impacts for the given unit, normalized to a certain time frame.

get_unit_impacts(units, time=None, time_unit='hr', exclude=None)

Return total impacts with certain units, normalized to a certain time frame.

property indicators

[list] All impact indicators associated with this LCA object. If not ImpactIndicator has been added, then will be defaulted to sum of the ImpactIndicator objects added to the system associated with this LCA (e.g., associated with construction, streams, etc.

property lca_streams

[set] All streams in the linked system with impacts.

property lifetime

[int] Lifetime of the system, [yr].

property lifetime_hr

[float] Lifetime of the system in hours, [hr].

property other_items

[dict] Other impact items (e.g., electricity) and their quantities.

refresh_other_items()

Refresh quantities of other items using the given functions.

save_report(file=None, sheet_name='LCA', time=None, time_unit='hr', n_row=0, row_space=2)

Save all LCA tables as an Excel file.

show(lifetime_unit='yr')

Show basic information of this LCA object.

property stream_inventory

[tuple] All chemical inputs, fugitive gases, waste emissions, and products.

property system

[biosteam.System] The system linked to this LCA.

property total_construction_impacts

[dict] Total impacts associated with construction activities.

property total_impacts

[dict] Total impacts of the entire system (construction, transportation, and wastestream).

property total_other_impacts

[dict] Total impacts associated with other ImpactItems (e.g., electricity).

property total_stream_impacts

[dict] Total impacts associated with WasteStreams (e.g., chemicals, emissions).

property total_transportation_impacts

[dict] Total impacts associated with transportation activities.

property transportation_inventory

[tuple] All transportation activities.

property transportation_units

[set] All units in the linked system with transportation activity.

property uptime_ratio

[float] Fraction of time that the system is operating.