diff --git a/pypsse/cli/run.py b/pypsse/cli/run.py index 04df06d..f53a61f 100644 --- a/pypsse/cli/run.py +++ b/pypsse/cli/run.py @@ -3,6 +3,8 @@ """ from pathlib import Path +import sys +sys.path.append('C:\\Program Files\\PTI\\PSSE35\\35.4\\PSSPY39\\') from loguru import logger import click diff --git a/pypsse/helics_interface.py b/pypsse/helics_interface.py index 29bd9e8..8736976 100644 --- a/pypsse/helics_interface.py +++ b/pypsse/helics_interface.py @@ -204,6 +204,7 @@ def register_subscriptions(self): ), "HELICS co-simulations requires a subscriptions_file property populated" sub_data = pd.read_csv(self.settings.simulation.subscriptions_file) self.psse_dict = {} + subs_by_element_id = {} for _, row in sub_data.iterrows(): try: row["element_property"] = ast.literal_eval(row["element_property"]) @@ -236,15 +237,34 @@ def register_subscriptions(self): element_id = str(row["element_id"]) - self.subscriptions[row["sub_tag"]] = { - "bus": row["bus"], - "element_id": element_id, - "element_type": row["element_type"], - "property": row["element_property"], - "scaler": row["scaler"], - "dStates": [self.init_state] * self.n_states, - "subscription": h.helicsFederateRegisterSubscription(self.psse_federate, row["sub_tag"], ""), - } + # if there are multiple inputs with the same element target, then set it up as a multi-input, rather than a subscription: + if element_id in subs_by_element_id.keys(): + matching_id_subs = subs_by_element_id[element_id] + subs_by_element_id[element_id].append(row["sub_tag"]) + input = h.helicsFederateRegisterInput(self.psse_federate, matching_id_subs[0]) + input.helics_handle_option_multi_input_handling_method = h.HelicsMultiInputMode.HELICS_MULTI_INPUT_NO_OP + input.helics_handle_option_targets = subs_by_element_id[element_id] + self.subscriptions[matching_id_subs[0]] = { + "bus": row["bus"], + "element_id": element_id, + "element_type": row["element_type"], + "property": row["element_property"], + "scaler": row["scaler"], + "dStates": [self.init_state] * self.n_states, + "subscription": input + } + msg = f"WARNING: Subscription element id {element_id} is duplicated, processed as multi-input with targets: {subs_by_element_id[element_id]}" + raise Warning(msg) + else: + self.subscriptions[row["sub_tag"]] = { + "bus": row["bus"], + "element_id": element_id, + "element_type": row["element_type"], + "property": row["element_property"], + "scaler": row["scaler"], + "dStates": [self.init_state] * self.n_states, + "subscription": h.helicsFederateRegisterSubscription(self.psse_federate, row["sub_tag"], ""), + } logger.info( "{} property of element {}.{} at bus {} has subscribed to {}".format( diff --git a/pypsse/simulator.py b/pypsse/simulator.py index 8cc508a..3aa9f07 100644 --- a/pypsse/simulator.py +++ b/pypsse/simulator.py @@ -17,7 +17,7 @@ import toml from loguru import logger from networkx import Graph -import pssepath +sys.path.append('C:\\Program Files\\PTI\\PSSE35\\35.4\\PSSPY39\\')#import pssepath import pypsse.contingencies as c import pypsse.simulation_controller as sc from pypsse.common import ( @@ -80,7 +80,7 @@ def __init__( self.settings = settings logger.debug(f"Instantiating psse version {psse_version}") - pssepath.add_pssepath(35.4) + #pssepath.add_pssepath(35.4) __import__(psse_version, fromlist=[""]) # noqa: F401 import dyntools