Source code for commonpower.modeling.util

from pyomo.core import ConcreteModel
from pyomo.core.base.indexed_component import IndexedComponent

from commonpower.utils.helpers import rgetattr, rhasattr


[docs] def model_root(model: ConcreteModel) -> ConcreteModel: """ Returns the root model of the given model by recursively calling model.parent_block(). Args: model (ConcreteModel): Model. Returns: ConcreteModel: Root model. """ def get_root(model: ConcreteModel) -> ConcreteModel: root = model parent = model.parent_block() if parent is not None: root = get_root(parent) return root return get_root(model)
[docs] def get_element_from_model(name: str, model: ConcreteModel, local_id: str, global_id: str) -> IndexedComponent: root_model = model_root(model) # Try global access (works if root_model == global model) if rhasattr(root_model, global_id): return rgetattr(root_model, global_id) # Try local access if a local element was passed and the passed model is its own root model. # This would only happen for the system block or "cut-off" sub-global blocks (e.g. as accessed by controller) # that want to access a top-level element if model == root_model and local_id == name and rhasattr(model, local_id): return rgetattr(model, local_id) # Usually, the passed model has a root model higher up the hierarchy. # If global access did not work, this root is not the global model # (e.g. if the root is a sub-global block from a controller). # This is why we iterate though the global element id top-down until we find the right element. # We already know that local access did not work, so we will not try the local id. # This prevents finding the wrong element if it exists on a higher level. # E.g. "n0.n01.e1.p" -> "n01.e1.p" -> "e1.p" !-> "p" for level in range(len(global_id.split(".")) - 1): name_for_level = ".".join(global_id.split(".")[level:]) if rhasattr(root_model, name_for_level): return rgetattr(root_model, name_for_level)
[docs] class SubscriptableFloat(float): """ This is a dummy class to "fake" the behaviour of a model element when extracting the signature from a constraint/cost expression. """ def __getitem__(self, _): """Make the float subscriptable by returning itself for any index""" return self def is_indexed(self): return False @property def ub(self): return self @property def lb(self): return self