Beginner-type question here.
I have a function to run a Monte Carlo LCA that I used to use in BW2, but apparently, the old Monte Carlo LCA class is Deprecated from what I understood, and I use the normal LCA class.
I am using the latest version of brightway25.
def get_multiImpactMonteCarloLCA(iterations=20):
myMethods = methods
list_of_activities = activities
myDict = {}
for act in list_of_activities:
print("running Monte Carlo LCA for: ", act)
temp_act_dict = {str(act): []}
myDict.update(temp_act_dict)
MC_lca = bc.LCA({act: 1})
MC_lca.lci()
C_matrices = {}
for method in myMethods:
MC_lca.switch_method(method)
C_matrices[method] = MC_lca.characterization_matrix
results = np.empty((len(myMethods), iterations))
for iteration in range(iterations):
next(MC_lca)
for method_index, method in enumerate(myMethods):
results[method_index, iteration] = (
C_matrices[method]*MC_lca.inventory).sum()
myDict[str(act)].append(results)
return myDict
print("Monte Carlo LCA calculation finished")
Running it gives me the results like a static LCA, and nothing changes between iterations. A) What am I missing here? B) is there a better way to structure this? Because it's kind of slow in how I'm doing it now.
To get better performance, try to:
Also, you need to pass use_distributions=True
to actually use the probability distributions during LCA calculations.
We can then rewrite your function:
import bw2data as bd
import bw2calc as bc
def MultiLCA(
demands: list[dict[bd.Node, float]], methods: list[tuple], iterations: int = 20
) -> dict[int : dict[tuple, list[float]]]:
# Create all possible demands
all_demands = {k: 1 for demand in demands for k in demand}
# Create a single LCA object and use uncertainty distributions
lca = bc.LCA(demand=all_demands, method=methods[0], use_distributions=True)
lca.lci()
# Create a list of characterization matrices
C_matrices = {}
for method in methods:
lca.switch_method(method)
C_matrices[method] = lca.characterization_matrix.copy()
# Create container for results
results = {
index: {method: [] for method in methods} for index, _ in enumerate(demands)
}
# Do one monte carlo iteration for all functional units and impact categories
for _ in range(iterations):
# Resample all matrices
next(lca)
for index, demand in enumerate(demands):
# Convert to integer ids instead of `bd.Node` objects
lca.lci({key.id: value for key, value in demand.items()})
for method in methods:
results[index][method].append(
(C_matrices[method] * lca.inventory).sum()
)
return results
And use it like:
import random
demands = [
{bd.Database("ecoinvent-3.7.1-apos").random(): random.random()}
for _ in range(5)
]
methods = [bd.methods.random() for _ in range(5)]
results = MultiLCA(demands=demands, methods=methods, iterations=5)
This function isn't perfect - the indexing into demands
isn't great, and the results should probably be converted to numpy arrays, but it is a start.