package org.openlca.core.matrix; import org.openlca.core.math.NumberGenerator; import org.openlca.core.model.FlowType; import org.openlca.core.model.UncertaintyType; import org.openlca.expressions.FormulaInterpreter; import org.openlca.expressions.InterpreterException; import org.openlca.expressions.Scope; import org.slf4j.Logger; import org.slf4j.LoggerFactory; class ExchangeCell { final CalcExchange exchange; public double allocationFactor = 1d; private NumberGenerator generator; ExchangeCell(CalcExchange exchange) { this.exchange = exchange; } void eval(FormulaInterpreter interpreter) { if (interpreter == null) return; try { Scope scope = interpreter.getScope(exchange.processId); if (scope == null) scope = interpreter.getGlobalScope(); tryEval(scope); } catch (Exception e) { Logger log = LoggerFactory.getLogger(getClass()); log.error("Formula evaluation failed, exchange " + exchange.exchangeId, e); } } private void tryEval(Scope scope) throws InterpreterException { if (exchange.amountFormula != null) { double v = scope.eval(exchange.amountFormula); exchange.amount = v; } if (exchange.parameter1Formula != null) { double v = scope.eval(exchange.parameter1Formula); exchange.parameter1 = v; } if (exchange.parameter2Formula != null) { double v = scope.eval(exchange.parameter2Formula); exchange.parameter2 = v; } if (exchange.parameter3Formula != null) { double v = scope.eval(exchange.parameter3Formula); exchange.parameter3 = v; } if (exchange.costFormula != null) { double v = scope.eval(exchange.costFormula); exchange.costValue = v; } } double getMatrixValue() { if (exchange == null) return 0; double amount = exchange.amount * allocationFactor * exchange.conversionFactor; if (exchange.input && !exchange.avoidedProduct) return -amount; else return amount; } double getCostValue() { if (exchange == null) return 0; double val = exchange.costValue * allocationFactor; if (exchange.flowType == FlowType.PRODUCT_FLOW && !exchange.input) return -val; else return val; } double getNextSimulationValue() { UncertaintyType type = exchange.uncertaintyType; if (type == null || type == UncertaintyType.NONE) return getMatrixValue(); if (generator == null) generator = createGenerator(type); double amount = generator.next() * allocationFactor * exchange.conversionFactor; if (exchange.input && !exchange.avoidedProduct) return -amount; else return amount; } private NumberGenerator createGenerator(UncertaintyType type) { final CalcExchange e = exchange; switch (type) { case LOG_NORMAL: return NumberGenerator.logNormal(e.parameter1, e.parameter2); case NORMAL: return NumberGenerator.normal(e.parameter1, e.parameter2); case TRIANGLE: return NumberGenerator.triangular(e.parameter1, e.parameter2, e.parameter3); case UNIFORM: return NumberGenerator.uniform(e.parameter1, e.parameter2); default: return NumberGenerator.discrete(e.amount); } } }