From c3f857562f0a0e21bf1378f1caca1f7c93e129f3 Mon Sep 17 00:00:00 2001
From: "christoph.von.oy" <christoph.von.oy@rwth-aachen.de>
Date: Thu, 2 May 2024 16:26:07 +0200
Subject: [PATCH] Split EntityResult creation and results extraction

---
 optimization_model.py |  7 -------
 topology.py           | 47 +++++++++++++++++++++++++++++++------------
 2 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/optimization_model.py b/optimization_model.py
index 31f2db6..c999fa8 100644
--- a/optimization_model.py
+++ b/optimization_model.py
@@ -94,13 +94,6 @@ class OptimizationBlock:
 
         return objectives
 
-    def extract_result(self, var_names):
-        result = EntityResult(var_names, self.dynamic)
-
-        result.extract_result(self)
-
-        return result
-
 
 class OptimizationModel(OptimizationBlock):
     def __init__(self, name, dynamic):
diff --git a/topology.py b/topology.py
index 550ce08..9fdd0ee 100644
--- a/topology.py
+++ b/topology.py
@@ -25,6 +25,7 @@ THE SOFTWARE.
 from Model_Library.component.core import ComponentCommodity, ComponentKind
 from Model_Library.dynamics import AggregatedDynamic, TreeDynamic, TrivialDynamic
 from Model_Library.optimization_model import (
+    EntityResult,
     OptimizationBlock,
     OptimizationModel,
     VariableKind,
@@ -253,6 +254,8 @@ class Topology:
         if not model.is_ok():
             raise RuntimeError("Model is infeasible or unbounded!")
 
+        self.create_empty_entity_result(key, self._dynamic)
+
         self.extract_result(model, key)
 
     def build_model(self, dynamic, strategy):
@@ -495,12 +498,11 @@ class Topology:
 
         return operational_objectives
 
-    def extract_result(self, block, key):
+    def create_empty_entity_result(self, key, dynamic):
         for asset in self._assets.values():
-            asset_block = block.blocks[asset._name]
-            asset.extract_result(asset_block, key)
+            asset.create_empty_entity_result(key, dynamic)
 
-        if isinstance(block.dynamic, (TrivialDynamic, TreeDynamic)):
+        if isinstance(dynamic, (TrivialDynamic, TreeDynamic)):
             base_variable_names = []
             for component in self._components:
                 base_variable_names.extend(
@@ -513,16 +515,16 @@ class Topology:
             for flow in self._flows:
                 base_variable_names.append((flow, VariableKind.INDEXED))
 
-            result = block.extract_result(base_variable_names)
+            result = EntityResult(base_variable_names, dynamic)
 
-        elif isinstance(block.dynamic, (AggregatedDynamic)):
+        elif isinstance(dynamic, (AggregatedDynamic)):
             design_base_variable_names = []
             for component in self._components:
                 design_base_variable_names.extend(
                     self._components[component].design_base_variable_names()
                 )
 
-            result = block.extract_result(design_base_variable_names)
+            result = EntityResult(design_base_variable_names, dynamic)
 
             operational_base_variable_names = []
             for component in self._components:
@@ -533,21 +535,40 @@ class Topology:
             for flow in self._flows:
                 operational_base_variable_names.append((flow, VariableKind.INDEXED))
 
-            for period_index in range(len(block.dynamic.period_dynamics)):
-                period_block = block.blocks[str(period_index)]
-
-                period_result = period_block.extract_result(
-                    operational_base_variable_names
+            for period_index, period_dynamic in enumerate(dynamic.period_dynamics):
+                period_result = EntityResult(
+                    operational_base_variable_names, period_dynamic
                 )
 
                 result.add_sub_result(period_index, period_result)
 
         else:
-            raise ValueError(f"Invalid dynamic type {type(block.dynamic)}")
+            raise ValueError(f"Invalid dynamic type {type(dynamic)}")
 
         self._results[key] = result
         self._last_result_key = key
 
+    def extract_result(self, block, key):
+        for asset in self._assets.values():
+            asset_block = block.blocks[asset._name]
+            asset.extract_result(asset_block, key)
+
+        if isinstance(block.dynamic, (TrivialDynamic, TreeDynamic)):
+            self._results[key].extract_result(block)
+
+        elif isinstance(block.dynamic, (AggregatedDynamic)):
+            self._results[key].extract_result(block)
+
+            for period_index in range(len(block.dynamic.period_dynamics)):
+                period_block = block.blocks[str(period_index)]
+
+                self._results[key].sub_results[period_index].extract_result(
+                    period_block
+                )
+
+        else:
+            raise ValueError(f"Invalid dynamic type {type(block.dynamic)}")
+
     def save_results(self, path, keys=None):
         for asset in self._assets.values():
             asset.save_results(path, keys)
-- 
GitLab