diff --git a/dpsim-models/include/dpsim-models/SimNode.h b/dpsim-models/include/dpsim-models/SimNode.h index 88588eb1ec..fea91b6e70 100644 --- a/dpsim-models/include/dpsim-models/SimNode.h +++ b/dpsim-models/include/dpsim-models/SimNode.h @@ -68,6 +68,8 @@ class SimNode : public TopologicalNode, void initialize(); /// Initialize state matrices with size according to phase type and frequency number void initialize(Matrix frequencies); + /// + std::shared_ptr clone() const override; /// Returns matrix index for specified phase UInt matrixNodeIndex(PhaseType phaseType = PhaseType::Single); /// Returns all matrix indices diff --git a/dpsim-models/include/dpsim-models/TopologicalNode.h b/dpsim-models/include/dpsim-models/TopologicalNode.h index 5718f76d35..bf1d49caa8 100644 --- a/dpsim-models/include/dpsim-models/TopologicalNode.h +++ b/dpsim-models/include/dpsim-models/TopologicalNode.h @@ -32,6 +32,9 @@ class TopologicalNode : public IdentifiedObject { /// virtual ~TopologicalNode() {} + /// + virtual std::shared_ptr clone() const = 0; + /// Bool isGround() const; /// diff --git a/dpsim-models/src/SimNode.cpp b/dpsim-models/src/SimNode.cpp index 77156c0d0c..9fd0fdd316 100644 --- a/dpsim-models/src/SimNode.cpp +++ b/dpsim-models/src/SimNode.cpp @@ -30,6 +30,7 @@ SimNode::SimNode(String uid, String name, } } + template SimNode::SimNode(PhaseType phaseType) : SimNode("gnd", "gnd", {0, 0, 0}, phaseType, {0, 0, 0}) { @@ -53,6 +54,13 @@ template <> void SimNode::initialize() { } } + template + std::shared_ptr SimNode::clone() const { + auto nodeCpy = SimNode::make(*mName, mPhaseType); + nodeCpy->setInitialVoltage(this->singleVoltage()); + return nodeCpy; + }; + template void SimNode::initialize(Matrix frequencies) { mFrequencies = frequencies; diff --git a/dpsim/src/pybind/main.cpp b/dpsim/src/pybind/main.cpp index 193bd6e05a..81f4840f2a 100644 --- a/dpsim/src/pybind/main.cpp +++ b/dpsim/src/pybind/main.cpp @@ -261,6 +261,10 @@ PYBIND11_MODULE(dpsimpy, m) { .def("list_idobjects", &DPsim::SystemTopology::listIdObjects) .def("init_with_powerflow", &DPsim::SystemTopology::initWithPowerflow, "systemPF"_a, "domain"_a); + // .def("multiply", &DPsim::SystemTopology::multiply); + // .def("check_topology_subnets", + // py::overload_cast::Ptr, int>>( + // &DPsim::SystemTopology::checkTopologySubnets)); py::class_>(m, "Interface"); @@ -348,7 +352,10 @@ PYBIND11_MODULE(dpsimpy, m) { CPS::IdentifiedObject>(m, "TopologicalNode") .def("initial_single_voltage", &CPS::TopologicalNode::initialSingleVoltage, - "phase_type"_a = CPS::PhaseType::Single); + "phase_type"_a = CPS::PhaseType::Single) + .def("__deepcopy__", [](const CPS::TopologicalNode &self, py::dict){ + return self.clone(); + }); py::class_, CPS::IdentifiedObject>( diff --git a/python/src/dpsim/matpower.py b/python/src/dpsim/matpower.py index ab69abd0ad..805c53b054 100644 --- a/python/src/dpsim/matpower.py +++ b/python/src/dpsim/matpower.py @@ -3,6 +3,7 @@ import scipy.io from enum import Enum import dpsimpy +import copy # define dpsimpy domains class Domain(Enum): @@ -639,7 +640,12 @@ def create_cosim_topologies(self, cosim_params): system_comp = [] system_nodes = [] eq_component=None - + split_node_added = False + + # self.system.multiply(1) + # num_subnets = self.system.check_topology_subnets() + # assert(num_subnets == 2) + for key, value in self.dpsimpy_comp_dict.items(): dpsim_component = value[0] connection_nodes = value[1] @@ -658,23 +664,39 @@ def create_cosim_topologies(self, cosim_params): # add node to node list for node in connection_nodes: - if node in system_nodes: - continue + if (cosim_params["split_node"] == node.name()) and not split_node_added: + # print('Here the split node, which must be deep copied') + + if (self.domain == Domain.EMT): + # intf_node = self.dpsimpy_components.SimNode(node.name(), dpsimpy.PhaseType.ABC) + # intf_node.set_initial_voltage(node.attr('voltage_init').get()) + intf_node = copy.deepcopy(node) + else: + intf_node = self.dpsimpy_components.SimNode(node.name(), dpsimpy.PhaseType.Single) + + system_nodes.append(intf_node) + split_node_added = True + else: - system_nodes.append(node) + if node in system_nodes: + continue + else: + system_nodes.append(node) # check if component is connected to split_node if eq_component is None: for node in connection_nodes: - if (cosim_params["split_node"] == node.name()): + if (cosim_params["split_node"] == node.name()): # add voltage/current source eq_component=None if (cosim_params["eq_component"][topologie_idx]=="VS"): eq_component = self.dpsimpy_components.VoltageSource("VS_"+node.name(), self.log_level) elif (cosim_params["eq_component"][topologie_idx]=="CS"): eq_component = self.dpsimpy_components.CurrentSource("CS_"+node.name(), self.log_level) - eq_component.connect([self.dpsimpy_components.SimNode.gnd, node]) + eq_component.connect([self.dpsimpy_components.SimNode.gnd, intf_node]) + # eq_component.connect([self.dpsimpy_components.SimNode.gnd, node]) + print('Added ' + cosim_params["eq_component"][topologie_idx] + ' to topology ' + str(topologie_idx)) system_comp.append(eq_component) topologies.append(dpsimpy.SystemTopology(self.mpc_freq, system_nodes, system_comp))