43 -----------------------
44 The Python bindings provide access to most of the DPsim features implemented in C++.
45 It is possible to run powerflow, quasi-static, dynamic phasor and electromagnetic transient simulations
46 and to parameterize all components of the network from Python.
50 py::enum_<CPS::Logger::Level>(m,
"LogLevel")
51 .value(
"trace", CPS::Logger::Level::trace)
52 .value(
"debug", CPS::Logger::Level::debug)
53 .value(
"info", CPS::Logger::Level::info)
54 .value(
"warn", CPS::Logger::Level::warn)
55 .value(
"err", CPS::Logger::Level::err)
56 .value(
"critical", CPS::Logger::Level::critical)
57 .value(
"off", CPS::Logger::Level::off);
59 py::class_<CPS::Math>(m,
"Math")
60 .def_static(
"single_phase_variable_to_three_phase",
62 .def_static(
"single_phase_parameter_to_three_phase",
64 .def_static(
"single_phase_power_to_three_phase",
67 py::enum_<DPsim::Solver::Behaviour>(m,
"SolverBehaviour")
71 py::enum_<DPsim::Solver::SystemMatrixRecomputationMode>(
72 m,
"SystemMatrixRecomputationMode")
78 py::enum_<CPS::Domain>(m,
"Domain")
83 py::enum_<CPS::PhaseType>(m,
"PhaseType")
90 py::enum_<CPS::PowerflowBusType>(m,
"PowerflowBusType")
96 py::enum_<CPS::GeneratorType>(m,
"GeneratorType")
109 py::enum_<CPS::CouplingMethod>(m,
"CouplingMethod")
114 py::enum_<DPsim::Solver::Type>(m,
"Solver")
119 py::enum_<DPsim::DirectLinearSolverImpl>(m,
"DirectLinearSolverImpl")
128 py::enum_<DPsim::SCALING_METHOD>(m,
"scaling_method")
133 py::enum_<DPsim::FILL_IN_REDUCTION_METHOD>(m,
"fill_in_reduction_method")
139 py::enum_<DPsim::PARTIAL_REFACTORIZATION_METHOD>(
140 m,
"partial_refactorization_method")
141 .value(
"no_partial_refactorization",
143 .value(
"factorization_path",
145 .value(
"refactorization_restart",
148 py::enum_<DPsim::USE_BTF>(m,
"use_btf")
152 py::enum_<CPS::CSVReader::Mode>(m,
"CSVReaderMode")
156 py::enum_<CPS::CSVReader::DataFormat>(m,
"CSVReaderFormat")
162 py::enum_<DPsim::StateSpaceAnalysisFrame>(m,
"StateSpaceAnalysisFrame")
174 py::class_<DPsim::DirectLinearSolverConfiguration>(
175 m,
"DirectLinearSolverConfiguration")
177 .def(
"set_fill_in_reduction_method",
179 .def(
"set_scaling_method",
181 .def(
"set_partial_refactorization_method",
183 setPartialRefactorizationMethod)
185 .def(
"get_scaling_method",
187 .def(
"get_fill_in_reduction_method",
189 .def(
"get_partial_refactorization_method",
191 getPartialRefactorizationMethod)
194 py::class_<DPsim::MNAStateSpaceExtractor>(m,
"MNAStateSpaceExtractor")
198 .def(
"get_discrete_state_matrix",
200 py::return_value_policy::reference_internal);
202 py::class_<DPsim::StateSpaceModalAnalysis>(m,
"StateSpaceModalAnalysis")
203 .def(py::init<const DPsim::MNAStateSpaceExtractor &>(),
204 py::keep_alive<1, 2>())
205 .def(
"set_analysis_frame",
207 .def(
"set_global_dq0_frame",
211 .def(
"get_discrete_eigenvalues",
213 py::return_value_policy::reference_internal)
214 .def(
"get_continuous_eigenvalues",
216 py::return_value_policy::reference_internal)
217 .def(
"get_right_eigenvectors",
219 py::return_value_policy::reference_internal)
220 .def(
"get_left_eigenvectors",
222 py::return_value_policy::reference_internal)
223 .def(
"get_participation_factors",
225 py::return_value_policy::reference_internal)
227 py::return_value_policy::reference_internal);
229 py::class_<DPsim::Simulation>(m,
"Simulation")
230 .def(py::init<std::string, CPS::Logger::Level>(),
"name"_a,
231 "loglevel"_a = CPS::Logger::Level::off)
239 .def(
"set_pf_keep_last_solution",
241 .def(
"get_pf_keep_last_solution",
243 .def(
"set_pf_base_apparent_power_fallback",
245 .def(
"get_pf_base_apparent_power_fallback",
251 .def(
"set_pf_solver_enforce_q_limits",
253 .def(
"get_pf_solver_enforce_q_limits",
255 .def(
"set_pf_solver_base_voltage_loose_tolerance",
257 .def(
"get_pf_solver_base_voltage_loose_tolerance",
259 .def(
"set_pf_solver_base_voltage_strict_tolerance",
261 .def(
"get_pf_solver_base_voltage_strict_tolerance",
274 .def(
"do_init_from_nodes_and_terminals",
276 .def(
"set_system_matrix_recomputation_mode",
278 .def(
"do_system_matrix_recomputation",
280 .def(
"do_state_space_extraction",
282 py::arg_v(
"value",
true,
"True"))
283 .def(
"get_state_space_extractor",
285 py::return_value_policy::reference_internal)
287 .def(
"do_frequency_parallelization",
292 .def(
"set_solver_component_behaviour",
294 .def(
"set_direct_solver_implementation",
296 .def(
"set_direct_linear_solver_configuration",
301 py::class_<DPsim::RealTimeSimulation, DPsim::Simulation>(m,
302 "RealTimeSimulation")
303 .def(py::init<std::string, CPS::Logger::Level>(),
"name"_a,
304 "loglevel"_a = CPS::Logger::Level::info)
317 py::class_<CPS::SystemTopology, std::shared_ptr<CPS::SystemTopology>>(
323 .def(py::init<CPS::Real>())
332 if (PyErr_WarnEx(PyExc_DeprecationWarning,
333 "SystemTopology.add is deprecated; use "
334 "add_component for components and add_node "
335 "for nodes instead.",
337 throw py::error_already_set();
339 if (py::isinstance<py::list>(obj) ||
340 py::isinstance<py::tuple>(obj)) {
341 for (
const py::handle &item : obj)
347 "Deprecated alias for add_component and add_node.")
348 .def(
"node", py::overload_cast<std::string_view>(
350 .def(
"node", py::overload_cast<CPS::UInt>(
352 .def(
"connect_component",
356 .def(
"connect_component",
364 .def(
"_repr_svg_", &DPsim::SystemTopology::render)
365 .def(
"render_to_file", &DPsim::SystemTopology::renderToFile)
369 .def_readwrite(
"components_at_node",
374 "systemPF"_a,
"domain"_a)
378 py::class_<DPsim::Interface, std::shared_ptr<DPsim::Interface>>(m,
382 std::shared_ptr<DPsim::DataLoggerInterface>>(m,
383 "DataLoggerInterface")
384 .def(
"log_attribute",
388 "name"_a,
"attr"_a,
"max_cols"_a = 0,
"max_rows"_a = 0)
390 .def(
"log_attribute",
391 py::overload_cast<
const std::vector<CPS::String> &,
396 .def(
"log_attribute",
398 const std::vector<CPS::String> &names,
const CPS::String &attr,
404 std::shared_ptr<DPsim::DataLogger>>(m,
"Logger")
405 .def(py::init<std::string>())
408 .def(
"log_attribute",
412 "name"_a,
"attr"_a,
"max_cols"_a = 0,
"max_rows"_a = 0)
414 .def(
"log_attribute",
415 py::overload_cast<
const std::vector<CPS::String> &,
427 "name"_a,
"attr"_a,
"comp"_a,
"rows_max"_a = 0,
"cols_max"_a = 0)
429 .def(
"log_attribute",
436 std::shared_ptr<DPsim::RealTimeDataLogger>>(m,
437 "RealTimeDataLogger")
439 .def(py::init([](py::object filename,
DPsim::Real final_time,
442 py::module_::import(
"os").attr(
"fspath")(filename);
443 std::string s = py::cast<std::string>(fspath);
444 std::filesystem::path p(s);
445 return std::make_shared<DPsim::RealTimeDataLogger>(p, final_time,
448 "filename"_a,
"final_time"_a,
"time_step"_a)
450 .def(py::init([](py::object filename, std::size_t row_number) {
452 py::module_::import(
"os").attr(
"fspath")(filename);
453 std::string s = py::cast<std::string>(fspath);
454 std::filesystem::path p(s);
455 return std::make_shared<DPsim::RealTimeDataLogger>(p, row_number);
457 "filename"_a,
"row_number"_a)
459 .def(
"log_attribute",
463 "name"_a,
"attr"_a,
"max_cols"_a = 0,
"max_rows"_a = 0)
465 .def(
"log_attribute",
466 py::overload_cast<
const std::vector<CPS::String> &,
478 "name"_a,
"attr"_a,
"comp"_a,
"rows_max"_a = 0,
"cols_max"_a = 0)
483 const std::vector<CPS::String> &names,
const CPS::String &attr,
487 "names"_a,
"attr"_a,
"comp"_a);
490 py::class_<CPS::IdentifiedObject, std::shared_ptr<CPS::IdentifiedObject>>(
491 m,
"IdentifiedObject")
502 py::enum_<CPS::CIM::Reader::VoltageTargetUnit>(m,
503 "CIMReaderVoltageTargetUnit")
508 py::class_<CPS::CIM::Reader>(m,
"CIMReader")
509 .def(py::init<std::string, CPS::Logger::Level, CPS::Logger::Level>(),
510 "name"_a,
"loglevel"_a = CPS::Logger::Level::info,
511 "comploglevel"_a = CPS::Logger::Level::off)
513 CPS::Real,
const std::list<CPS::String> &,
516 .def(
"set_extnet_voltage_target_unit",
520 py::class_<CPS::CSVReader>(m,
"CSVReader")
521 .def(py::init<std::string,
const std::string &,
529 m,
"TopologicalPowerComp");
530 py::class_<CPS::SimPowerComp<CPS::Complex>,
531 std::shared_ptr<CPS::SimPowerComp<CPS::Complex>>,
538 py::class_<CPS::SimPowerComp<CPS::Real>,
539 std::shared_ptr<CPS::SimPowerComp<CPS::Real>>,
545 py::class_<CPS::TopologicalNode, std::shared_ptr<CPS::TopologicalNode>,
547 .def(
"initial_single_voltage",
553 m,
"TopologicalTerminal")
556 .def(
"set_power", py::overload_cast<CPS::MatrixComp>(
559 py::class_<CPS::SimTerminal<CPS::Complex>,
560 std::shared_ptr<CPS::SimTerminal<CPS::Complex>>,
562 py::class_<CPS::SimTerminal<CPS::Real>,
563 std::shared_ptr<CPS::SimTerminal<CPS::Real>>,
567 py::module mEvent = m.def_submodule(
"event",
"events");
568 py::class_<DPsim::Event, std::shared_ptr<DPsim::Event>>(mEvent,
"Event");
569 py::class_<DPsim::SwitchEvent, std::shared_ptr<DPsim::SwitchEvent>,
570 DPsim::Event>(mEvent,
"SwitchEvent", py::multiple_inheritance())
571 .def(py::init<
CPS::Real,
const std::shared_ptr<CPS::Base::Ph1::Switch>,
573 py::class_<DPsim::SwitchEvent3Ph, std::shared_ptr<DPsim::SwitchEvent3Ph>,
574 DPsim::Event>(mEvent,
"SwitchEvent3Ph", py::multiple_inheritance())
575 .def(py::init<
CPS::Real,
const std::shared_ptr<CPS::Base::Ph3::Switch>,
579 py::module mBase = m.def_submodule(
"base",
"base models");
582 py::module mDP = m.def_submodule(
"dp",
"dynamic phasor models");
585 py::module mEMT = m.def_submodule(
"emt",
"electromagnetic-transient models");
588 py::module mSP = m.def_submodule(
"sp",
"static phasor models");
589 mSP.attr(
"SimNode") = mDP.attr(
"SimNode");
592 py::module mSignal = m.def_submodule(
"signal",
"signal models");
596 m.attr(
"__version__") = VERSION_INFO;
598 m.attr(
"__version__") =
"dev";
static void systemTopologyAddSingle(DPsim::SystemTopology &sys, const py::handle &item)