How to do a LCA model with lca_algebraic ?

What is the goal of this notebook ? This notebook explains how to do a basic parameterised Life Cycle Assessment (LCA) using brightway and lca_algebraic librairies. This notebook gives the main coding parts and tries to explain for each parts how to use the main functions and how to write code.

How to read this notebook? Their are 2 types of sections in this notebook :

  • “To do” sections that countain the cells you need to run to make a basic LCA. Some of this sections are optional (optional in the title of the section) and should not be mandatory run.

  • Explanation section that explain how to find the usefull information to write the “to do” sections. You don’t need to run them to make the LCA. This sections title starts with explain. Note : If you have the “collapsible headings” extensions on Jupyter, the explanation sections can be hidden.

Warning The inventories examples given are not representative for real physical systems. The inventories have just been built to learn how to use lca_algebraic functions.

Setup

First, create and activate a dedicated Python (>=3.10) environement with Conda or Pip

Then install Jupyter and lca_algebraic (>=1.1.2) :

pip install jupyter
pip install lca_algebraic

You may also install Activity Browser :

pip install activity-browser

Import the libaries

[ ]:
# Initialise the library with instructions
from init import *

Explain : librairies imported

What does init.py do?

  • init.py loads the required libraries to run this notebook.

  • in init files, pay attention on the shortnames of libraries that will be used for using the functions of the loaded libraries.

  • Warning : the file init.py shall be in the same file as the file of this notebook !

Librairies This notebook uses functions from 6 librairies :

  • brightway is a library for computing advanced LCA.

  • lca_algebraic is library specificaly developped to build paramterized LCA model and perform sensitivity analysis (very efficiently by relying on symbolic calculus).

  • pandas is a usefull library for data manipulation and data analysis

  • numpy is a basic library for numeric calculations

  • scipy is a library for scientific tools

  • matplotlib is a library for plotting. Scipy and matplotlib are just partly imported. Indeed, lca_algebraic imports only the usefull tools from this libraries.

LCA librairies resources

  • brightway >

    • Brightway2 website

    • Tutorial

  • lca_algebraic > lca_algebraic relies on brightway2 and has additional functionnalities.

    • lca_algebraic github

    • lca_algebraic documentation

Init Brightway project

The following code creates or open a Brightsay projet and clear the foreground database and parameters. It is recommended to do so in order to start your code with a fresh inventory.

[ ]:
# To do : update the name of the bightway project
NAME_PROJECT="name-project"

# To do : update the name of the user database that will be stored in the brightway project
NAME_USER_DB='name of my database'


#Open a brightway project associated with the project name chosen
bw2data.projects.set_current(NAME_PROJECT)
bw2data.projects.current

# Create and reset the user (foreground) database
agb.resetDb(NAME_USER_DB)

# Reset the definition of all parameters
agb.resetParams()

Load the background ecoinvent database

This should be done only once :

[ ]:
#Give the password associated with your ecoinvent account
#Warning don't share your id/password on git
from ecoinvent_interface import Settings, permanent_setting
permanent_setting("username", "put_here_your_username")
permanent_setting("password", "put_here_your_password")
[ ]:
#load the chosen vesion of ecoinvent. Here an example with ecoinvent 3.9.1, cut off
bw2io.import_ecoinvent_release("3.9.1", "cutoff")
[ ]:
# Optional : If you need to manipulate the database keep references a reference to it
ecoinvent = bw2data.Database('ecoinvent-3.9.1-cutoff')

Managing databases

[ ]:
# Print the databases that have been set up with brightway function
bw.databases
[ ]:
# Print the databases that have been set up with lca_algebraic function
agb.list_databases()
#The size of database and the type of database (foregroung/background/biosphere) is also printed
[ ]:
#Optional : if you need to delete a USER_DB
#del bw.databases["name-db-to-delete"]

#Optional : If you need to manipulate a database, give it a variable name
#ecoinvent_3_8 = bw2data.Database('ecoinvent-3.8-cutoff')

Select LCIA method and impacts categories

Select LCIA methods

[ ]:
# Pick the LCIA method you want to use
# To do : update the name of the method you want to use
LCIA_method = 'EF v2.0 2018 no LT'

Explain : how to find the name of the LCIA method

  • bw.methods is a brightway dictionnary that contains all LCIA methods and impacts categories that were imported when initialising the notebook.

  • Objects in bw.methods are triplet (LCIA method, endpoint category, midpoint category) that corresponds to impacts categories calculated with a given LCIA method.

[ ]:
#See all triplets of bw.methods
list(bw.methods)

# Note : With Activity browser / section "impact categories", this list can alsobe explored easily
[ ]:
# See all the LCIA methods available in Brightway 2
list_LCIA_methods = [m[0] for m in bw.methods]
list_LCIA_methods = [*set(list_LCIA_methods)]
list_LCIA_methods
[ ]:
# See all the LCIA methods that were imported that contains ReCiPe in their name"
# Update the name of the "keywords" according to your search
list_LCIA_methods = [m[0] for m in bw.methods if "ReCiPe" in str(m)]
list_LCIA_methods = [*set(list_LCIA_methods)] #this line automatically delete the duplicates
list_LCIA_methods
[ ]:
# See all the LCIA methods that were imported excluding the one containing keywords such as "no LT" or "obsolete"
# Update the name of the "excluding keywords" according to your search
list_LCIA_methods = [m[0] for m in bw.methods if not "no LT" in str(m) and not'obsolete' in str(m)]
list_LCIA_methods = [*set(list_LCIA_methods)]  #this line automatically delete the duplicates
list_LCIA_methods

Select impacts categories

Select impact categories

[ ]:
#Select the impacts categories you want to calculate
#Remind : impact_categories are triplet (LCIA method, endpoint category, midpoint category)
# To do : update the name of the endpoint and midpoint category in the triplet and the name of impact_categories
climate = (LCIA_method, 'climate change no LT','global warming potential (GWP100) no LT')
resources = (LCIA_method, 'energy resources: non-renewable no LT','abiotic depletion potential (ADP): fossil fuels no LT')
soil = (LCIA_method, 'climate change: land use and land use change no LT','global warming potential (GWP100) no LT')

[ ]:
# Define a list of impacts categories chosen and print it
# To do : update the name of the impact categories in the list
impacts = [climate, resources, soil]
[ ]:
# Print the selected impact categories
# To do : nothing
nb_impacts=len(impacts)
print(f"We have selected {nb_impacts} impacts categories calculated with the LCIA method : '{LCIA_method}' that are :")
print(" ")
for m in impacts : print(m[1],">", m[-1])
[ ]:
#Test if the triplet you have just defined are methods in bw.methods
bw.methods[climate]
bw.methods[resources]
bw.methods[soil]
print("If there is no error, it means it is ok. If there is an error, it means at least one of the impact categories is not correctly defined and does not correspond to an existing impact category. Check that there is no tipping error. ")

Explain : how to choose impact categories with function agb.findMethods

[ ]:
# We list all the impacts categories that can be calculated with the selected LCIA method
# with the function agb.findMethods
# To do : nothing
list_impact_categories=agb.findMethods("",LCIA_method)
nb_impacts=len(list_impact_categories)

#Print the categories
# To do : nothing
print(f"There are {nb_impacts} impacts categories calculated with the LCIA method : '{LCIA_method}' that are :")
list_impact_categories

# Note : With Activity browser / section impact categories, this list can be explored easily
[ ]:
# Find all impacts categories calculated with the LCIA method chosen that contain a keyword such as "climate"
# with agb.findMethods("keyword", LCIA methods)
# To do : update the keyword
agb.findMethods("climate", LCIA_method)
[ ]:
# Other example with keyword "resource"
# To do : update the keyword

agb.findMethods("resource", LCIA_method)

Define the parameters

You can create a python variable density=3 in a code cell, and then use density to calculate a flows amount. You can change density’s value, re-run the code parts that use densityto remake the calculations with the updated value of density.

“lca_algebraic parameters” have functionalities that helps manipulating parameters while doing LCA. For example, it helps calculating scenarios or conducting fast sensitivity analysis for example.

In practice in your code, part of the parameters that you don’t want to make vary will be defined as standard python variables (eg density) and only the parameters you want to change will be defined as lca_algebraic parameters:

    1. define python variables (also called static variables)

    1. define lca_algebraic parameters as explained below

python variables / static parameters

[ ]:
STEEL_DENSITY=7850 #kg/m3

lca_algebraic parameters

lca_algebraic can define 3 types of parameters :

  • Float parameter, with newFloatParam(...)

  • Bool parameter, with newBoolParam(...)

  • “Exclusive choice”, that corresponds to the definition of several boolean parameters with newEnumParam(...) > for example, for an electricity mix, we have to choose one mix among others

[ ]:
# Float parameters definition > newFloatParam
# To do : You need to fulfill at least, "name" and "default value"

# Example : PV power installed in kWpeak
power_capacity = agb.newFloatParam(
    name="power_capacity",                        # short name
    label="roof system",                # label
    description="installed peak power", # long description
    unit="kWp",                         # unit
    group="intallation",                # (optional) to class your parameters in group
    default=1500,                       # default value
    min=3,                              # min value
    max=300,                            # max value
    distrib=agb.DistributionType.TRIANGLE)  # (optional) statistic distribution of the parameter

# Note: statistic distribution of the parameter can be : agb.DistributionType.NORMAL or .TRIANGLE or .LINEAR or.LOGNORMAL
# if "distrib" is empty, a uniform distribution will be chosen by default
# https://oie-mines-paristech.github.io/lca_algebraic/doc/params.html#lca_algebraic.params.DistributionType

# ignore the warning
[ ]:
# Bool parameters definition > newBoolParam

# Example: Bool parameter that defines the installation type
# 1 =  on roof / installation sur toit
# 0 = on soil / installation au sol

on_roof=agb.newBoolParam(
    name="on_roof",                     # short name
    label="mounting system",            # long label
    description="mounting system roof (on_roof=1) or ground mounting system (on_roof=0)", # long description
    group="installation",               # (optional) to class your parameters in group
    default=1                           # default value
    )

#We can define a variable that is a function of the lca_algebraic boolean parameter we have just created
on_ground = (1-on_roof)

#ignore the warning
[ ]:
# Definition of parameters that can select several exclusive choice > function newEnumParam*

# Example : electric mixes
# This parameter defines 5 boolean parameters

elec_mix_country=agb.newEnumParam(
    "elec_mix_country",                     # Short name
    label="electricial mix",        # label
    description="country chosen for the electricity mix", # Long description
    group="manufacturing",          # (optional) to class your parameters in group
    values =[                       # Statistic weight of each option that fits with the market
        "senegal",
        "france",
        "italy",
        "germany"
    ],
    default="senegal")                   # the default value is a string

# Ignore the warning

# If you used advanced functionalities of lca_algebraic, you can add statistic weight of each option by creating a dictionary
#    values ={"france": 2.4,"germany": 7.4,"italy": 71.4,"senegal": 5.7}
[ ]:
# Definition of an other float parameter
# note : nothing new compared with the first float parameter
# we just need to define it to run the model later

# Module efficacity, kWp/m2
efficacite_module = agb.newFloatParam(
    "efficacite_module",
    distrib=agb.DistributionType.TRIANGLE, # Distribution triangulaire, privilégiant la valeur par défaut
    default=0.175, min=0.15, max=0.22,
    group="installation",
    label_fr="efficacité module",
    description="efficacité du module par surface installée",
    unit="kWp/m²")
[ ]:
# Print the list of the parameters
agb.list_parameters()
[ ]:
#Warning
#When you define a lca_algebraic parameter, the name of the parameter has to be the same as the name of the variable

#Test if the name of parameters are the same as the name of the variable
for name, var in list(globals().items()):
    if isinstance(var, agb.ParamDef) and var.name != name :
        print("Warning : param name is different for var name : %s <> %s" % (var.name, name))

Parameters and variables values printing

lca_algebraic parameters with default value

[ ]:
#If you print an lca_algebraic parameter, its name is prnted but not its value
power_capacity
[ ]:
#Print the name, default value and unit of one parameter
(power_capacity.name, power_capacity.default, power_capacity.unit)
[ ]:
#Print the informations about parameters in one table with the function agb.list_parameters()
agb.list_parameters()

python variables that are functions of lca_algebraic parameters

[ ]:
#If you print the python variable surface, its expression (function of lca_algebrauic parameters) is printed
surface = power_capacity / efficacite_module
surface
[ ]:
#To get its value with default parameters value :
agb.compute_value(surface)
[ ]:
#To get its value with chosen parameters value (if you do not put a parameter value, the default one will be used for the calculation) :
agb.compute_value(
    surface,
    #power_capacity=1000,
    efficacite_module=0.2)

Activities of the inventory

Explain

There are 3 main databases :

  • The biosphere database that contains all the flows from and to the biosphere

  • The background reference database: the modelised inventory is built with activities taken from the reference database for background. In this notebook, the reference database is ecoinvent.

  • The model database : the modelised inventory is set up in the database ‘USER_DB’ that is independant of the reference database, so that the reference database is not modified.

In the following part, the terms “flow” and “activity” have the same meaning.

[ ]:
# The database that have been set up are :
bw.databases

Find activities in the reference database

Activities in the biosphere

[ ]:
# Define a biosphere flow
# To do : update the right termonology to find the right activity and update the activity_name
water_in_air = agb.findBioAct("Water, in air")

# Print this activity with the function agb.printAct
#To do : update the name of the activity
agb.printAct(water_in_air)

Activities in the technosphere

[ ]:
# Define a technosphere flow
# To do : update the right termonology to find the right activity and update the activity_name
ground_mounting_system = agb.findTechAct('photovoltaic mounting system production, for 570kWp open ground module')

# Print this activity with the function agb.printAct(name_of_the_activity)
#To do : update the name of the activity
agb.printAct(ground_mounting_system)
[ ]:
# Define another technosphere flow
# To do : if there are several activities in the database with the same name but not the same location, add the location as shown in this example
inverter = agb.findTechAct('inverter production, 0.5kW','RER')
pv_panel =agb.findTechAct("market for photovoltaic panel, multi-Si wafer")

Warning : If there is more than one technosphere background database, use findActivity

[ ]:
#Similar as function agb.findTechAct + specify the database name
steel= agb.findActivity('market for steel, low-alloyed',db_name='ecoinvent-3.8-cutoff')
aluminium=agb.findActivity('market for copper, cathode', db_name='ecoinvent-3.8-cutoff')
[ ]:
#Redatabases: to print database names
bw.databases

Parameterized inventory

While doing the LCA of a new system, there are two main options to modelise the system :

  • Either modify an existing activity

  • Either create a new activity and add all the flows with corresponding quantities

For both options, you can define the quantity as a mathematic formula of a parameter that have been defined above, to obtain a parameterized inventory

[ ]:
#Remind : to print the list of parameters defined above, run this cell
agb.list_parameters()

Create a new activity

[ ]:
# Create a new activity with the function agb.newActivity
new_activity = agb.newActivity(
                    db_name=NAME_USER_DB,         # Database where the new activity is created
                    name="new activity name ",  # Activity name
                    unit="unit",                # Unit
                    exchanges = {
                        ground_mounting_system :  1, #add flows and amount
                        inverter:  2          #add flows and amount
                        }
                    )

#Print the activity that you have just created
agb.printAct(new_activity)

Modify an existing activity

[ ]:
#If it is an activity from the reference database,
# First copy the activity that will be modified with the function agb.copyActivity
# and to do all the modification in the user database
#otherwise you will modify ecoinvent database !

#To do : update the name of the original and copied activities and the name of the copied activities

modified_mounting_system = agb.copyActivity(
    db_name=NAME_USER_DB,                            # Database where the new activity is copied
    activity = ground_mounting_system,                  # initial activity
    code = "mounting system adjusted")   # new name

#Print the copied activity that is for now not yet modified
agb.printAct(modified_mounting_system)

There are 4 main ways of modifying an existing activity :

  • change the value of a flow of this activity (with another number or with a mathematic formula)

example : technology development enables to reduce a quantity of a material.

  • change a flow by another flow : the new flow is either another flow of the background database or a flow that has been specifically created.

example : if I want to change the electric mix by antoher one.

  • add a new flow

example : there is a new material used in a new technology.

  • delete an existing flow

example : if I have a photovoltaic installation on a roof (and not on the soil), I want to delete the concrete flow in the mounting system activity.

[ ]:
# 1. change the value of a flow of this activity (with another number or with a mathematic formula) with the function updateExchanges
modified_mounting_system.updateExchanges({
   'zinc coat, coils' : 0.11 * on_ground,
   'reinforcing steel' : 7.25*0.8})
[ ]:
# 2. change a flow by another flow with the function updateExchanges

#define the new flow you want to introduce instead of another flow and name it
other_concrete=agb.findTechAct('market for concrete, sole plate and foundation')

#change the initial flow in the inventory with the new flow
modified_mounting_system.updateExchanges({
    'concrete, normal' : other_concrete})      #'name of the modified flow' : name of the new flow
[ ]:
# 3. Add a new flow with the function addExchanges

#find the flow you want to add with agb.findTechAct and name it
steel_2= agb.findTechAct('market for steel, low-alloyed, hot rolled')

#add it to the inventory with the function addExchanges
modified_mounting_system.addExchanges({
        steel_2: 7.25*0.2 })
[ ]:
# 4. Delete an existing flow with the function updateExchanges
modified_mounting_system.updateExchanges({
   'polyethylene, high density, granulate' : None})
[ ]:
# Print the differences between the original activity and the modified activity with the function agb.printAct
agb.printAct(ground_mounting_system, modified_mounting_system)

# Note : The modifications appear in YELLOW !
# Note : the mathematic formula with parameters are not calculated with default values > the mathematic formula are printed

Switching activity / enum parameter

If you want to use an enum parameter to switch from an activity to another

[ ]:
senegalese_elec_mix=agb.findTechAct('market for electricity, high voltage','SN')
french_elec_mix=agb.findTechAct('market for electricity, high voltage','FR')
german_elec_mix=agb.findTechAct('market for electricity, high voltage','DE')
italian_elec_mix=agb.findTechAct('market for electricity, high voltage','IT')
[ ]:
elec_mix = agb.newSwitchAct(
                    NAME_USER_DB, # Database where the new activity is created
                    "electricity mix",
                    elec_mix_country, #enum parameter that is used to switch the activity
                            {
                                "senegal":senegalese_elec_mix,
                                "france": french_elec_mix,
                                 "germany": german_elec_mix,
                                 "italy": italian_elec_mix,
                            })

Inventory of the system

Gather all the activities of the system in an inventory (called “system”) that will represent our whole system.

System inventory

[ ]:
# Create a new activity for the full system with the function agb.newActivity
system = agb.newActivity(
                    db_name=NAME_USER_DB,                 # Database where we load the new activity
                    name="full system",  # System name
                    unit="unit")                  # Unit

# If need, intermediate variables can be introduced
volume_steel_m3=0.03
mass_steel_kg=STEEL_DENSITY*volume_steel_m3

# Add new flows and corresponding quantity with the function addExchanges
system.addExchanges({
    modified_mounting_system : surface,
    pv_panel : surface,
    inverter: power_capacity/0.5,
    steel_2:mass_steel_kg,
    elec_mix:1000,

})

# Print the inventory of the modelised system
agb.printAct(system)

Impacts calculation

Most of the impacts calculations are performed with the functions agb.compute_impacts. If you need more information about a function, you can use ‘?’ or help as shown below ?agb.resetDb

[ ]:
agb.compute_impacts?
[ ]:
help(agb.compute_impacts)

How to calculate impacts of one activity ?

[ ]:
# Calculate the impacts of the system modelised with the function agb.multiLCAAlgebric
# The calculation is done with the selected LCIA_methods for the selected impact categories

agb.compute_impacts(
    system,               # activity whose impacts are calculated
    impacts)              # list of selected impacts

# If there is no specific value for parameters, default values are automatically chosen
[ ]:
#You can also print in a second sheet : the default parameters value and chosen parameters value for the calculation

agb.compute_impacts(
    system,               # activity whose impacts are calculated
    impacts,              # list of selected impacts
    return_params=True)   # To create the second sheet with parameters value

How to calculate impacts of several activities ?

[ ]:
agb.compute_impacts(
    [modified_mounting_system, inverter],         # list [] of activities
    impacts)                                      # list of selected impacts

# If there is no specific value for parameters, default values are automatically chosen

Parameter values change

These functionalities only work woth lca_algebraic parameters and not with python variables !

How to specify the value of some parameters to calculate the impacts of a specific set of parameters ?

[ ]:
# idem + specify parameters values
agb.compute_impacts(
    system,
    impacts,
    power_capacity = 50,       # parameters value
    on_roof=0,                 # boolen parameters value 0 or 1
    elec_mix_country="italy",
    return_params=True,        # To create the second sheet with parameters value
    )

How to compare several values of one parameter ?

[ ]:
# idem + compare several values for one parameter
agb.compute_impacts(
    system,
    impacts,
    power_capacity = [50,100,200],
    #return_params=True,             # optional : To create the second sheet with parameters value
)

How to compare several set of values of several parameter ?

[ ]:
# idem + compare several values for 2 or more parameter
# Warning : either you put one value for a given parameter, either you put a list of parameters values that shall have the same length for each parameters

agb.compute_impacts(
    system,
    impacts,
    power_capacity = [50,100,200],
    on_roof=0,
    elec_mix_country=["italy","senegal","france"],
    #return_params=True,             # optional : To create the second sheet with parameters value

)

How to change the functional unit ?

Option 1: Create a new activity for the normalised system and calculate its impacts

[ ]:
system_normalised_kWp = agb.newActivity(
   NAME_USER_DB,                  # Database where we load the new activity
   "impact per kWp installed",    # normalised system name
   "unit",                        # Unit
    exchanges={system: 1 / power_capacity}) #divide the inventory of the system by the normalisation factor
[ ]:
agb.compute_impacts(
    system_normalised_kWp,
    impacts,
)

Option 2 : use the functional_unit option in agb.compute_impacts

[ ]:
agb.compute_impacts(
    system,
    impacts,
    functional_unit=power_capacity #The impacts of the mentionned activity will be divided by this amount
)

How display the impact per subactivities ?

[ ]:
#Displays all exchanges of one or several activities and their impacts.
#Warning, in this case, the first argument is the impact category and not the activity
agb.exploreImpacts(
    climate,                  #impact category
    system,                   #name of the activity
    power_capacity = 1300     #optional : change the parameter value
    )

Axis functionnality

Divide your system in axis/subcategories to calculate the contribution of each subcategories to the impacts.

[ ]:
#Axis : subsystem with two subcategories
BOP="balance of plant"
PV="PV panels"
#Axis: stage (life cycle stage) with two subcategories
MANUFACTURING = "phase 1 = manufacturing"
OPERATION = "phase 2 = operation and maintenance"

Manufacturing stage for PV + BOP

[ ]:
#When creating the activity, you flag the chosen axis (The axis can be named as you want)

#Activity to model the manufacturing of the balance of plant
balance_of_plant_manufacturing = agb.newActivity(
                    db_name=NAME_USER_DB,
                    name="manufacturing of the balance of plant",
                    unit="unit",
                    subsystem=BOP,     #axis subsystem
                    stage=MANUFACTURING,#axis  stage
                    exchanges={
                        modified_mounting_system :  surface,
                        inverter: power_capacity/0.5
                        })

#Activity to model the manufacturing of pv panel
pv_panel_manufacturing=agb.newActivity(
                    db_name=NAME_USER_DB,
                    name="manufacturing of the pv panel",
                    unit="unit",
                    subsystem=PV,        #axis subsystem
                    stage=MANUFACTURING,  #axis  stage
                    exchanges={
                        pv_panel:  surface,
                        })

#Activity to model the manufacturing of the whole system
system_manufacturing=agb.newActivity(
                    db_name=NAME_USER_DB,
                    name="manufacturing of the system",
                    unit="unit",
                    #no need to put the axis name as it is associated with the chosen acitivites as it is done for the subactivities
                    exchanges={
                        balance_of_plant_manufacturing: 1,
                        pv_panel_manufacturing: 1,
                        })

Operantion and maintenance stage for PV + BOP

[ ]:
#When creating the activity, you flag the chosen axis (The axis can be named as you want)

#Activity to model the operation and maintenance of the balance of plant
balance_of_plant_operation = agb.newActivity(
                    db_name=NAME_USER_DB,
                    name="operation and maintenance of the balance of plant",
                    unit="unit",
                    subsystem=BOP,    #axis subsystem
                    stage=OPERATION,   #axis  stage
                    exchanges={
                        elec_mix :  1000
                        })

#Activity to model the operation and maintenance of pv panel
pv_panel_operation = agb.newActivity(
                    db_name=NAME_USER_DB,
                    name="operation and maintenance of the pv panels",
                    unit="unit",
                    exchanges={
                        elec_mix :  5000
                        })

#If the activity is already created, you can add the flags as shown below. Do not forget to save !!
pv_panel_operation["subsystem"]=PV
pv_panel_operation.save()

pv_panel_operation["stage"]=OPERATION
pv_panel_operation.save()

#Activity to model the operation and maintenance of the whole system
system_operation=agb.newActivity(
                    db_name=NAME_USER_DB,
                    name="operation and maintenance of the system",
                    unit="unit",
                    #no need to put the axis name as it is associated with the chosen acitivites
                    exchanges={
                        balance_of_plant_operation: 1,
                        pv_panel_operation: 1,
                        })

Impacts of full system per axis

[ ]:
#Activity to model the whole system
system_full=agb.newActivity(
                    db_name=NAME_USER_DB,
                    name="full system for axis function",
                    unit="unit",
                    exchanges={
                        system_manufacturing: 1,
                        system_operation: 1,
                        })
[ ]:
agb.compute_impacts(
    system_full,
    impacts,
    #functional_unit=power_capacity,
    #axis="subsystem",)
    axis="stage")

Advices for a correct use of axis functionalities

  • You can add as much axis as you want and name them as you want.

  • If the line _ other _ is not equal to zero, it means that you forgot to flag part of your modeled system.

  • Warning If you flag an inventory for a given axis (subsytem=”pv panel”), you can not flag an inventory that uses this inventory with another for this given axis. Otherwise you will get an issue while computing the impacts as shown in the example below.

[ ]:
#Axis subsystem=BOP
balance_of_plant_manufacturing_2 = agb.newActivity(
                    db_name=NAME_USER_DB,
                    name="manufacturing of the balance of plant",
                    unit="unit",
                    subsystem=BOP,        #axis subsystem
                    stage=MANUFACTURING,  #axis  stage
                    exchanges={
                        modified_mounting_system :  surface,
                        inverter: power_capacity/0.5
                        })

#Axis subsystem=PV
pv_panel_manufacturing_2=agb.newActivity(
                    db_name=NAME_USER_DB,
                    name="manufacturing of the pv panel",
                    unit="unit",
                    subsystem=PV,         #axis subsystem
                    stage=MANUFACTURING,  #axis  stage
                    exchanges={
                        pv_panel:  surface,
                        })


#Axis subsystem="full system"
system_manufacturing_2=agb.newActivity(
                    db_name=NAME_USER_DB,
                    name="manufacturing of the system",
                    unit="unit",
                    exchanges={
                        balance_of_plant_manufacturing: 1,
                        pv_panel_manufacturing: 1,
                        })

[ ]:
#You get an error when computing the impacts as their is a flag conflict
agb.compute_impacts(
    system_manufacturing_2,
    impacts,
    axis="subsystem")
[ ]:
system_manufacturing_3=agb.newActivity(
                    db_name=NAME_USER_DB,
                    name="manufacturing of the system",
                    unit="unit",
                    other_axis_name="plant",
                    exchanges={
                        balance_of_plant_manufacturing: 1,
                        pv_panel_manufacturing: 1,
                        })

agb.compute_impacts(
    system_manufacturing_3,
    impacts,
    axis="subsystem")

Export Excel

[ ]:
# Export excel of results

df = agb.compute_impacts(
    [system, modified_mounting_system],
    impacts,
    functional_unit=power_capacity))

df.to_excel("data/impact_test.xlsx")
df #To print it in Jupyter