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")
91 py::enum_<CPS::PowerflowBusType>(m,
"PowerflowBusType")
97 py::enum_<CPS::GeneratorType>(m,
"GeneratorType")
110 py::enum_<CPS::CouplingMethod>(m,
"CouplingMethod")
115 py::enum_<DPsim::Solver::Type>(m,
"Solver")
120 py::enum_<DPsim::DirectLinearSolverImpl>(m,
"DirectLinearSolverImpl")
129 py::enum_<DPsim::SCALING_METHOD>(m,
"scaling_method")
134 py::enum_<DPsim::FILL_IN_REDUCTION_METHOD>(m,
"fill_in_reduction_method")
140 py::enum_<DPsim::PARTIAL_REFACTORIZATION_METHOD>(
141 m,
"partial_refactorization_method")
142 .value(
"no_partial_refactorization",
144 .value(
"factorization_path",
146 .value(
"refactorization_restart",
149 py::enum_<DPsim::USE_BTF>(m,
"use_btf")
153 py::enum_<CPS::CSVReader::Mode>(m,
"CSVReaderMode")
157 py::enum_<CPS::CSVReader::DataFormat>(m,
"CSVReaderFormat")
163 py::enum_<DPsim::StateSpaceAnalysisFrame>(m,
"StateSpaceAnalysisFrame")
167 py::enum_<DPsim::StateSpacePoleMapping>(m,
"StateSpacePoleMapping")
179 py::class_<DPsim::DirectLinearSolverConfiguration>(
180 m,
"DirectLinearSolverConfiguration")
182 .def(
"set_fill_in_reduction_method",
184 .def(
"set_scaling_method",
186 .def(
"set_partial_refactorization_method",
188 setPartialRefactorizationMethod)
190 .def(
"get_scaling_method",
192 .def(
"get_fill_in_reduction_method",
194 .def(
"get_partial_refactorization_method",
196 getPartialRefactorizationMethod)
199 py::class_<DPsim::MNAStateSpaceExtractor>(m,
"MNAStateSpaceExtractor")
203 .def(
"get_discrete_state_matrix",
205 py::return_value_policy::reference_internal);
207 py::class_<DPsim::StateSpaceModalAnalysis>(m,
"StateSpaceModalAnalysis")
208 .def(py::init<const DPsim::MNAStateSpaceExtractor &>(),
209 py::keep_alive<1, 2>())
210 .def(
"set_analysis_frame",
212 .def(
"set_global_dq0_frame",
217 .def(
"get_discrete_eigenvalues",
219 py::return_value_policy::reference_internal)
220 .def(
"get_continuous_eigenvalues",
222 py::return_value_policy::reference_internal)
223 .def(
"get_right_eigenvectors",
225 py::return_value_policy::reference_internal)
226 .def(
"get_left_eigenvectors",
228 py::return_value_policy::reference_internal)
229 .def(
"get_participation_factors",
231 py::return_value_policy::reference_internal)
233 py::return_value_policy::reference_internal);
235 py::class_<DPsim::Simulation>(m,
"Simulation")
236 .def(py::init<std::string, CPS::Logger::Level>(),
"name"_a,
237 "loglevel"_a = CPS::Logger::Level::off)
245 .def(
"set_pf_keep_last_solution",
247 .def(
"get_pf_keep_last_solution",
249 .def(
"set_pf_base_apparent_power_fallback",
251 .def(
"get_pf_base_apparent_power_fallback",
257 .def(
"set_pf_solver_enforce_q_limits",
259 .def(
"get_pf_solver_enforce_q_limits",
261 .def(
"set_pf_solver_base_voltage_loose_tolerance",
263 .def(
"get_pf_solver_base_voltage_loose_tolerance",
265 .def(
"set_pf_solver_base_voltage_strict_tolerance",
267 .def(
"get_pf_solver_base_voltage_strict_tolerance",
280 .def(
"do_init_from_nodes_and_terminals",
282 .def(
"set_system_matrix_recomputation_mode",
284 .def(
"do_system_matrix_recomputation",
286 .def(
"do_state_space_extraction",
288 py::arg_v(
"value",
true,
"True"))
289 .def(
"get_state_space_extractor",
291 py::return_value_policy::reference_internal)
293 .def(
"do_frequency_parallelization",
298 .def(
"set_solver_component_behaviour",
300 .def(
"set_direct_solver_implementation",
302 .def(
"set_direct_linear_solver_configuration",
307 py::class_<DPsim::RealTimeSimulation, DPsim::Simulation>(m,
308 "RealTimeSimulation")
309 .def(py::init<std::string, CPS::Logger::Level>(),
"name"_a,
310 "loglevel"_a = CPS::Logger::Level::info)
323 py::class_<CPS::SystemTopology, std::shared_ptr<CPS::SystemTopology>>(
329 .def(py::init<CPS::Real>())
338 if (PyErr_WarnEx(PyExc_DeprecationWarning,
339 "SystemTopology.add is deprecated; use "
340 "add_component for components and add_node "
341 "for nodes instead.",
343 throw py::error_already_set();
345 if (py::isinstance<py::list>(obj) ||
346 py::isinstance<py::tuple>(obj)) {
347 for (
const py::handle &item : obj)
353 "Deprecated alias for add_component and add_node.")
354 .def(
"node", py::overload_cast<std::string_view>(
356 .def(
"node", py::overload_cast<CPS::UInt>(
358 .def(
"connect_component",
362 .def(
"connect_component",
370 .def(
"_repr_svg_", &DPsim::SystemTopology::render)
371 .def(
"render_to_file", &DPsim::SystemTopology::renderToFile)
375 .def_property_readonly(
"components_at_node",
384 "systemPF"_a,
"domain"_a)
389 py::class_<DPsim::Interface, std::shared_ptr<DPsim::Interface>>(m,
393 std::shared_ptr<DPsim::DataLoggerInterface>>(m,
394 "DataLoggerInterface")
395 .def(
"log_attribute",
399 "name"_a,
"attr"_a,
"max_cols"_a = 0,
"max_rows"_a = 0)
401 .def(
"log_attribute",
402 py::overload_cast<
const std::vector<CPS::String> &,
407 .def(
"log_attribute",
409 const std::vector<CPS::String> &names,
const CPS::String &attr,
415 std::shared_ptr<DPsim::DataLogger>>(m,
"Logger")
416 .def(py::init<std::string>())
419 .def(
"log_attribute",
423 "name"_a,
"attr"_a,
"max_cols"_a = 0,
"max_rows"_a = 0)
425 .def(
"log_attribute",
426 py::overload_cast<
const std::vector<CPS::String> &,
438 "name"_a,
"attr"_a,
"comp"_a,
"rows_max"_a = 0,
"cols_max"_a = 0)
440 .def(
"log_attribute",
447 std::shared_ptr<DPsim::RealTimeDataLogger>>(m,
448 "RealTimeDataLogger")
450 .def(py::init([](py::object filename,
DPsim::Real final_time,
453 py::module_::import(
"os").attr(
"fspath")(filename);
454 std::string s = py::cast<std::string>(fspath);
455 std::filesystem::path p(s);
456 return std::make_shared<DPsim::RealTimeDataLogger>(p, final_time,
459 "filename"_a,
"final_time"_a,
"time_step"_a)
461 .def(py::init([](py::object filename, std::size_t row_number) {
463 py::module_::import(
"os").attr(
"fspath")(filename);
464 std::string s = py::cast<std::string>(fspath);
465 std::filesystem::path p(s);
466 return std::make_shared<DPsim::RealTimeDataLogger>(p, row_number);
468 "filename"_a,
"row_number"_a)
470 .def(
"log_attribute",
474 "name"_a,
"attr"_a,
"max_cols"_a = 0,
"max_rows"_a = 0)
476 .def(
"log_attribute",
477 py::overload_cast<
const std::vector<CPS::String> &,
489 "name"_a,
"attr"_a,
"comp"_a,
"rows_max"_a = 0,
"cols_max"_a = 0)
494 const std::vector<CPS::String> &names,
const CPS::String &attr,
498 "names"_a,
"attr"_a,
"comp"_a);
501 py::class_<CPS::IdentifiedObject, std::shared_ptr<CPS::IdentifiedObject>>(
502 m,
"IdentifiedObject")
513 py::enum_<CPS::CIM::Reader::VoltageTargetUnit>(m,
514 "CIMReaderVoltageTargetUnit")
519 py::class_<CPS::CIM::Reader>(m,
"CIMReader")
520 .def(py::init<std::string, CPS::Logger::Level, CPS::Logger::Level>(),
521 "name"_a,
"loglevel"_a = CPS::Logger::Level::info,
522 "comploglevel"_a = CPS::Logger::Level::off)
524 CPS::Real,
const std::list<CPS::String> &,
527 .def(
"set_extnet_voltage_target_unit",
531 py::class_<CPS::CSVReader>(m,
"CSVReader")
532 .def(py::init<std::string,
const std::string &,
540 m,
"TopologicalPowerComp");
541 py::class_<CPS::SimPowerComp<CPS::Complex>,
542 std::shared_ptr<CPS::SimPowerComp<CPS::Complex>>,
549 py::class_<CPS::SimPowerComp<CPS::Real>,
550 std::shared_ptr<CPS::SimPowerComp<CPS::Real>>,
556 py::class_<CPS::TopologicalNode, std::shared_ptr<CPS::TopologicalNode>,
558 .def(
"initial_single_voltage",
564 m,
"TopologicalTerminal")
567 .def(
"set_power", py::overload_cast<CPS::MatrixComp>(
570 py::class_<CPS::SimTerminal<CPS::Complex>,
571 std::shared_ptr<CPS::SimTerminal<CPS::Complex>>,
573 py::class_<CPS::SimTerminal<CPS::Real>,
574 std::shared_ptr<CPS::SimTerminal<CPS::Real>>,
578 py::module mEvent = m.def_submodule(
"event",
"events");
579 py::class_<DPsim::Event, std::shared_ptr<DPsim::Event>>(mEvent,
"Event");
580 py::class_<DPsim::SwitchEvent, std::shared_ptr<DPsim::SwitchEvent>,
581 DPsim::Event>(mEvent,
"SwitchEvent", py::multiple_inheritance())
582 .def(py::init<
CPS::Real,
const std::shared_ptr<CPS::Base::Ph1::Switch>,
584 py::class_<DPsim::SwitchEvent3Ph, std::shared_ptr<DPsim::SwitchEvent3Ph>,
585 DPsim::Event>(mEvent,
"SwitchEvent3Ph", py::multiple_inheritance())
586 .def(py::init<
CPS::Real,
const std::shared_ptr<CPS::Base::Ph3::Switch>,
590 py::module mBase = m.def_submodule(
"base",
"base models");
593 py::module mDP = m.def_submodule(
"dp",
"dynamic phasor models");
596 py::module mEMT = m.def_submodule(
"emt",
"electromagnetic-transient models");
599 py::module mSP = m.def_submodule(
"sp",
"static phasor models");
600 mSP.attr(
"SimNode") = mDP.attr(
"SimNode");
603 py::module mSignal = m.def_submodule(
"signal",
"signal models");
607 m.attr(
"__version__") = VERSION_INFO;
609 m.attr(
"__version__") =
"dev";
static void systemTopologyAddSingle(DPsim::SystemTopology &sys, const py::handle &item)