use of org.openlca.core.matrix.index.TechIndex in project olca-modules by GreenDelta.
the class TechIndexBuilder method build.
@Override
public TechIndex build(TechFlow refFlow) {
log.trace("build product index for {}", refFlow);
TechIndex index = new TechIndex(refFlow);
index.setDemand(1.0);
addSystemLinks(index);
List<TechFlow> block = new ArrayList<>();
block.add(refFlow);
HashSet<TechFlow> handled = new HashSet<>();
while (!block.isEmpty()) {
var nextBlock = new ArrayList<TechFlow>();
log.trace("fetch next block with {} entries", block.size());
Map<Long, List<CalcExchange>> exchanges = fetchExchanges(block);
for (TechFlow recipient : block) {
handled.add(recipient);
List<CalcExchange> all = exchanges.get(recipient.providerId());
List<CalcExchange> candidates = providers.getLinkCandidates(all);
for (CalcExchange linkExchange : candidates) {
TechFlow provider = providers.find(linkExchange);
if (provider == null)
continue;
LongPair exchange = new LongPair(recipient.providerId(), linkExchange.exchangeId);
index.putLink(exchange, provider);
if (!handled.contains(provider) && !nextBlock.contains(provider))
nextBlock.add(provider);
}
}
block = nextBlock;
}
return index;
}
use of org.openlca.core.matrix.index.TechIndex in project olca-modules by GreenDelta.
the class NoForegroundElemFlowsTest method test.
@Test
public void test() throws IOException {
// init the library
var tmpDir = Files.createTempDirectory("_olca_tests");
var libDir = LibraryDir.of(tmpDir.toFile());
var lib = Library.create(libDir, LibraryInfo.of("testlib", Version.of(1)));
var db = Tests.getDb();
// create the reference data
var units = UnitGroup.of("Units of mass", "kg");
var mass = FlowProperty.of("Mass", units);
var e1 = Flow.elementary("e1", mass);
var e2 = Flow.elementary("e2", mass);
db.insert(units, mass, e1, e2);
var enviIndex = EnviIndex.create();
enviIndex.add(EnviFlow.inputOf(FlowDescriptor.of(e1)));
enviIndex.add(EnviFlow.outputOf(FlowDescriptor.of(e2)));
// create stubs for the library processes
var libProviders = new ArrayList<TechFlow>();
Process libProcess = null;
for (int i = 1; i < 4; i++) {
var product = db.insert(Flow.product("p" + i, mass));
var process = Process.of("p" + i, product);
process.library = lib.id();
db.insert(process);
libProviders.add(TechFlow.of(process));
if (i == 2) {
libProcess = process;
}
}
var techIdx = new TechIndex(libProviders.get(0));
techIdx.add(libProviders.get(1));
techIdx.add(libProviders.get(2));
// create the foreground system
var product = db.insert(Flow.product("fp", mass));
var process = Process.of("fp", product);
process.input(libProcess.quantitativeReference.flow, 0.5);
db.insert(process);
var system = ProductSystem.of(process).link(libProcess, process);
system.targetAmount = 2;
db.insert(system);
// create library resources
LibTechIndex.write(lib, db, techIdx);
LibEnviIndex.write(lib, db, enviIndex);
// write the library matrices
var matrixA = DenseMatrix.of(new double[][] { // p1
{ 1.0, -0.1, 0.0 }, // p2
{ -0.5, 1.0, -0.2 }, // p3
{ 0.0, -0.7, 1.0 } });
var matrixB = DenseMatrix.of(new double[][] { // e1
{ -3.0, -4.0, -7.0 }, // e2
{ 9.0, 2.0, 3.0 } });
var solver = new JavaSolver();
var inv = solver.invert(matrixA);
var matrixM = solver.multiply(matrixB, inv);
LibMatrix.A.write(lib, matrixA);
LibMatrix.B.write(lib, matrixB);
LibMatrix.INV.write(lib, inv);
LibMatrix.M.write(lib, matrixM);
// calculate the results
var setup = CalculationSetup.fullAnalysis(system);
var result = new SystemCalculator(db).withLibraryDir(libDir).calculateFull(setup);
// check the result
var expected = matrixM.getColumn(1);
var totals = result.totalFlowResults();
for (int i = 0; i < expected.length; i++) {
Assert.assertEquals(expected[i], totals[i], 1e-16);
}
db.clear();
Dirs.delete(libDir.folder());
}
use of org.openlca.core.matrix.index.TechIndex in project olca-modules by GreenDelta.
the class Library method syncProducts.
/**
* Returns the products of the library in matrix order. If this library has
* no product index or if this index is not in sync with the database, an
* empty option is returned.
*/
public Optional<TechIndex> syncProducts(IDatabase db) {
var processes = descriptors(new ProcessDao(db));
var products = descriptors(new FlowDao(db));
TechIndex index = null;
var proto = getProductIndex();
int size = proto.getProductCount();
for (int i = 0; i < size; i++) {
var entry = proto.getProduct(i);
var process = processes.get(entry.getProcess().getId());
var product = products.get(entry.getProduct().getId());
if (process == null || product == null)
return Optional.empty();
if (index == null) {
index = new TechIndex(TechFlow.of(process, product));
} else {
index.add(TechFlow.of(process, product));
}
}
return Optional.ofNullable(index);
}
use of org.openlca.core.matrix.index.TechIndex in project olca-modules by GreenDelta.
the class LazyProviderTest method testScalingVector.
@Test
public void testScalingVector() {
var data = new MatrixData();
data.techMatrix = HashPointMatrix.of(new double[][] { { 1.0, 0.0, 0.0 }, { -1.0, 1.0, 0.0 }, { 0.0, -1.0, 1.0 } });
data.techIndex = new TechIndex(product(1));
data.techIndex.add(product(2));
data.techIndex.add(product(3));
data.techIndex.setDemand(1.0);
var provider = LazyResultProvider.create(SolverContext.of(data));
var scaling = provider.scalingVector();
Assert.assertArrayEquals(new double[] { 1.0, 1.0, 1.0 }, scaling, 1e-10);
}
use of org.openlca.core.matrix.index.TechIndex in project olca-app by GreenDelta.
the class ImpactPage method compute.
private ContributionResult compute() {
var data = new MatrixData();
// create a virtual demand of 1.0
var refProduct = TechFlow.of(getModel());
data.techIndex = new TechIndex(refProduct);
data.techIndex.setDemand(1.0);
data.techMatrix = JavaMatrix.of(new double[][] { { 1.0 } });
// collect the elementary flow exchanges
var elemFlows = new ArrayList<Exchange>();
boolean regionalized = false;
for (var e : getModel().exchanges) {
if (e.flow == null || e.flow.flowType != FlowType.ELEMENTARY_FLOW)
continue;
if (e.location != null) {
regionalized = true;
}
elemFlows.add(e);
}
if (elemFlows.isEmpty()) {
// return an empty result if there are no elementary flows
var provider = EagerResultProvider.create(SolverContext.of(data));
return new ContributionResult(provider);
}
// create the flow index and B matrix / vector
data.enviIndex = regionalized ? EnviIndex.createRegionalized() : EnviIndex.create();
var enviBuilder = new MatrixBuilder();
for (var e : elemFlows) {
var flow = Descriptor.of(e.flow);
var loc = e.location != null ? Descriptor.of(e.location) : null;
int i = e.isInput ? data.enviIndex.add(EnviFlow.inputOf(flow, loc)) : data.enviIndex.add(EnviFlow.outputOf(flow, loc));
double amount = ReferenceAmount.get(e);
if (e.isInput && amount != 0) {
amount = -amount;
}
enviBuilder.add(i, 0, amount);
}
data.enviMatrix = enviBuilder.finish();
// build the impact index and matrix
var db = Database.get();
data.impactIndex = ImpactIndex.of(db);
var contexts = new HashSet<Long>();
contexts.add(getModel().id);
data.impactIndex.each((i, d) -> contexts.add(d.id));
var interpreter = ParameterTable.interpreter(db, contexts, Collections.emptySet());
data.impactMatrix = ImpactBuilder.of(db, data.enviIndex).withImpacts(data.impactIndex).withInterpreter(interpreter).build().impactMatrix;
// create the result
var provider = EagerResultProvider.create(SolverContext.of(data));
var result = new ContributionResult(provider);
return result;
}
Aggregations