Brightway 中不同影响评估方法计算 Monte Carlo 结果的有效方法

efficient way of calculating Monte Carlo results for different impact assessment methods in Brightway

我正在尝试使用不同的影响评估方法对 brightway2 进行比较 monte carlo 计算。我考虑过使用 switch_method 方法来提高效率,因为对于给定的迭代,技术圈矩阵是相同的。但是,我收到断言错误。重现它的代码可能是这样的

    import brighway as bw
    bw.projects.set_current('ei35') # project with ecoinvent 3.5
    db = bw.Database("ei_35cutoff")

    # select two different transport activities to compare
    activity_name = 'transport, freight, lorry >32 metric ton, EURO4'    
    for activity in bw.Database("ei_35cutoff"):
        if activity['name'] == activity_name:
            truckE4 = bw.Database("ei_35cutoff").get(activity['code'])
            print(truckE4['name'])
            break

    activity_name = 'transport, freight, lorry >32 metric ton, EURO6'    
    for activity in bw.Database("ei_35cutoff"):
        if activity['name'] == activity_name:
            truckE6 = bw.Database("ei_35cutoff").get(activity['code'])
            print(truckE6['name'])
            break

    demands = [{truckE4: 1}, {truckE6: 1}]

    # impact assessment method:
    recipe_midpoint=[method for method in bw.methods.keys() 
    if method[0]=="ReCiPe Midpoint (H)"]

    mc_mm = bw.MonteCarloLCA(demands[0], recipe_midpoint[0])
    next(mc_mm)

如果我尝试 switch 方法,我会收到断言错误。

    mc_mm.switch_method(recipe_midpoint[1])
    assert mc_mm.method==recipe_midpoint[1]
    mc_mm.redo_lcia()
    next(mc_mm)

我是不是做错了什么?

不是很优雅,但试试这个:

iterations = 10 
simulations = []

for _ in range(iterations):
    mc_mm = MonteCarloLCA(demands[0], recipe_midpoint[0])
    next(mc_mm)

    mcresults = []
    for i in demands:    
        print(i)
        for m in recipe_midpoint[0:3]:
            mc_mm.switch_method(m)
            print(mc_mm.method)    
            mc_mm.redo_lcia(i)
            print(mc_mm.score)
            mcresults.append(mc_mm.score)
    simulations.append(mcresults)

CC_truckE4 = [i[1] for i in simulations] # Climate Change, truck E4 
CC_truckE6 = [i[1+3] for i in simulations] # Climate Change, truck E6

from matplotlib import pyplot as plt 
plt.plot(CC_truckE4 , CC_truckE6, 'o')

如果您随后进行测试并对同一需求向量进行两次模拟,通过设置 demands = [{truckE4: 1}, {truckE4: 1}] 并绘制结果,您应该会得到一条直线。这意味着您正在对每个需求向量和每个 LCIA 进行相关抽样并重新使用相同的技术矩阵。我不是 100% 确定这一点,但我希望它能回答你的问题。

我通常将特征因子矩阵存储在临时字典中,并将这些 cfs 与直接从 MonteCarloLCA 得到的 LCI 相乘。

import brightway2 as bw
import numpy as np

# Generate objects for analysis

bw.projects.set_current("my_mcs")
my_db = bw.Database('db')
my_act = my_db.random()
my_demand = {my_act:1}
my_methods = [bw.methods.random() for _ in range(2)]

我编写了这个简单的函数来获取我将在 MonteCarloLCA 中生成的产品系统的特征因子矩阵。它使用一个 temporara "sacrificial LCA" 对象,该对象将具有与 MonteCarloLCA 相同的 A 和 B 矩阵。 这可能看起来是在浪费时间,但它只做一次,而且会使蒙特卡洛更快更简单。

def get_C_matrices(demand, list_of_methods):
    """ Return a dict with {method tuple:cf_matrix} for a list of methods
    Uses a "sacrificial LCA" with exactly the same demand as will be used
    in the MonteCarloLCA
    """
    C_matrices = {}
    sacrificial_LCA = bw.LCA(demand)
    sacrificial_LCA.lci()
    for method in list_of_methods:
        sacrificial_LCA.switch_method(method)
        C_matrices[method] = sacrificial_LCA.characterization_matrix
    return C_matrices

然后:

# Create array that will store mc results.
# Shape is (number of methods, number of iteration)

my_iterations = 10
mc_scores = np.empty(shape=[len(my_methods), my_iterations])

# Instantiate MonteCarloLCA object
my_mc = bw.MonteCarloLCA(my_demand)

# Get characterization factor matrices
my_C_matrices = get_C_matrices(my_demand, my_methods)

# Generate results
for iteration in range(my_iterations):
    lci = next(my_mc)
    for i, m in enumerate(my_methods):
        mc_scores[i, iteration] = (my_C_matrices[m]*my_mc.inventory).sum()  

您的所有结果都在 mc_scores 中。每行对应一个方法,每列对应一个 MC 迭代。