diff --git a/python/stepspy-current/README.md b/python/stepspy-current/README.md index 8cfeb452..ba823c99 100644 --- a/python/stepspy-current/README.md +++ b/python/stepspy-current/README.md @@ -19,9 +19,10 @@ stepspy is a Python module of Simulation Toolkit for Electrical Power Systems (S stepspy is a Python module of Simulation Toolkit for Electrical Power Systems (STEPS). It provides wrapper of APIs of STEPS in a dynamic library. -STEPS is a simulation toolkit for powerflow and dynamic simulation of large-scale power systems. It provides detailed models of bus, line, transformer, HVDC, generator, wind turbine generator, load, and fixed shunt. For more information about STEPS, see (https://github.com/changgang/steps). +STEPS is a simulation toolkit for powerflow, short circuit and dynamic simulation of large-scale power systems. It provides detailed models of bus, line, transformer, HVDC, VSC-HVDC, generator, wind turbine generator, photovoltaic unit, load, and fixed shunt. For more information about STEPS, see (https://gitee.com/lichgang/steps/ or https://github.com/changgang/steps). ## Release Note +- 2.0.0. Oct. 16, 2023. Major version. Add short circuit analysis functions. - 1.6.2. Oct. 13, 2023. Add option to select libSTEPS version when calling STEPS(). - 1.6.1. Sep. 26, 2022. Fix bug in set_bus_capacity. - 1.6.0. April 13, 2022. Add VSC HVDC model APIs. Use STEPS>=1.6.0. diff --git a/python/stepspy-current/setup.py b/python/stepspy-current/setup.py index 9e9c7ae7..b096c58a 100644 --- a/python/stepspy-current/setup.py +++ b/python/stepspy-current/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="stepspy", - version="1.6.2", + version="2.0.0", author="Changgang Li", author_email="lichgang@sdu.edu.cn", description="Python module of Simulation Toolkit for Electrical Power Systems", diff --git a/python/stepspy-current/stepspy/libsteps/pylibsteps.py b/python/stepspy-current/stepspy/libsteps/pylibsteps.py index 61c07d9a..744bd6e6 100644 --- a/python/stepspy-current/stepspy/libsteps/pylibsteps.py +++ b/python/stepspy-current/stepspy/libsteps/pylibsteps.py @@ -115,6 +115,8 @@ def load_library(libsteps_file): libsteps.api_load_vsc_hvdc_powerflow_data_from_file.argtypes = (c_char_p, c_char_p, c_uint) libsteps.api_load_powerflow_result_from_file.restype = None libsteps.api_load_powerflow_result_from_file.argtypes = (c_char_p, c_char_p, c_uint) + libsteps.api_load_sequence_data_from_file.restype = None + libsteps.api_load_sequence_data_from_file.argtypes = (c_char_p, c_char_p, c_uint) libsteps.api_load_dynamic_data_from_file.restype = None libsteps.api_load_dynamic_data_from_file.argtypes = (c_char_p, c_char_p, c_uint) @@ -122,6 +124,8 @@ def load_library(libsteps_file): libsteps.api_save_powerflow_data_to_file.argtypes = (c_char_p, c_char_p, c_bool, c_bool, c_bool, c_uint, c_uint) libsteps.api_save_vsc_hvdc_powerflow_data_to_file.restype = None libsteps.api_save_vsc_hvdc_powerflow_data_to_file.argtypes = (c_char_p, c_char_p, c_bool, c_bool, c_bool, c_uint, c_uint) + libsteps.api_save_sequence_data_to_file.restype = None + libsteps.api_save_sequence_data_to_file.argtypes = (c_char_p, c_char_p, c_uint) libsteps.api_save_dynamic_data_to_file.restype = None libsteps.api_save_dynamic_data_to_file.argtypes = (c_char_p, c_char_p, c_bool, c_uint) @@ -380,6 +384,19 @@ def load_library(libsteps_file): libsteps.api_set_source_boolean_data.restype = None libsteps.api_set_source_boolean_data.argtypes = (c_uint, c_char_p, c_char_p, c_bool, c_uint) + libsteps.api_get_generator_sequence_float_data.restype = (c_double) + libsteps.api_get_generator_sequence_float_data.argtypes = (c_uint, c_char_p, c_char_p, c_uint) + libsteps.api_get_wt_generator_sequence_float_data.restype = (c_double) + libsteps.api_get_wt_generator_sequence_float_data.argtypes = (c_uint, c_char_p, c_char_p, c_uint) + libsteps.api_get_pv_unit_sequence_float_data.restype = (c_double) + libsteps.api_get_pv_unit_sequence_float_data.argtypes = (c_uint, c_char_p, c_char_p, c_uint) + libsteps.api_set_generator_sequence_float_data.restype = None + libsteps.api_set_generator_sequence_float_data.argtypes = (c_uint, c_char_p, c_char_p, c_double, c_uint) + libsteps.api_set_wt_generator_sequence_float_data.restype = None + libsteps.api_set_wt_generator_sequence_float_data.argtypes = (c_uint, c_char_p, c_char_p, c_double, c_uint) + libsteps.api_set_pv_unit_sequence_float_data.restype = None + libsteps.api_set_pv_unit_sequence_float_data.argtypes = (c_uint, c_char_p, c_char_p, c_double, c_uint) + libsteps.api_get_fixed_shunt_integer_data.restype = (c_int) libsteps.api_get_fixed_shunt_integer_data.argtypes = (c_uint, c_char_p, c_char_p, c_uint) libsteps.api_get_fixed_shunt_float_data.restype = (c_double) @@ -625,8 +642,6 @@ def load_library(libsteps_file): libsteps.api_build_decoupled_network_B_matrix.argtypes = (c_uint, ) libsteps.api_build_dc_network_B_matrix.restype = None libsteps.api_build_dc_network_B_matrix.argtypes = (c_uint, ) - libsteps.api_build_dynamic_network_Y_matrix.restype = None - libsteps.api_build_dynamic_network_Y_matrix.argtypes = (c_uint, ) libsteps.api_build_network_Z_matrix.restype = None libsteps.api_build_network_Z_matrix.argtypes = (c_uint, ) libsteps.api_save_network_Y_matrix.restype = None @@ -635,11 +650,54 @@ def load_library(libsteps_file): libsteps.api_save_decoupled_network_B_matrix.argtypes = (c_char_p, c_uint) libsteps.api_save_dc_network_B_matrix.restype = None libsteps.api_save_dc_network_B_matrix.argtypes = (c_char_p, c_uint) - libsteps.api_save_dynamic_network_Y_matrix.restype = None - libsteps.api_save_dynamic_network_Y_matrix.argtypes = (c_char_p, c_uint) libsteps.api_save_network_Z_matrix.restype = None libsteps.api_save_network_Z_matrix.argtypes = (c_char_p, c_uint) + libsteps.api_build_sequence_network_Y_matrix.restype = None + libsteps.api_build_sequence_network_Y_matrix.argtypes = (c_uint, ) + libsteps.api_save_positive_sequence_network_Y_matrix.restype = None + libsteps.api_save_positive_sequence_network_Y_matrix.argtypes = (c_char_p, c_uint) + libsteps.api_save_negative_sequence_network_Y_matrix.restype = None + libsteps.api_save_negative_sequence_network_Y_matrix.argtypes = (c_char_p, c_uint) + libsteps.api_save_zero_sequence_network_Y_matrix.restype = None + libsteps.api_save_zero_sequence_network_Y_matrix.argtypes = (c_char_p, c_uint) + + libsteps.api_build_dynamic_network_Y_matrix.restype = None + libsteps.api_build_dynamic_network_Y_matrix.argtypes = (c_uint, ) + libsteps.api_save_dynamic_network_Y_matrix.restype = None + libsteps.api_save_dynamic_network_Y_matrix.argtypes = (c_char_p, c_uint) + + libsteps.api_get_short_circuit_solver_integer_parameter.restype = (c_uint) + libsteps.api_get_short_circuit_solver_integer_parameter.argtypes = (c_char_p, c_uint) + libsteps.api_get_short_circuit_solver_float_parameter.restype = (c_double) + libsteps.api_get_short_circuit_solver_float_parameter.argtypes = (c_char_p, c_uint) + libsteps.api_get_short_circuit_solver_boolean_parameter.restype = (c_bool) + libsteps.api_get_short_circuit_solver_boolean_parameter.argtypes = (c_char_p, c_uint) + libsteps.api_set_short_circuit_solver_integer_parameter.restype = None + libsteps.api_set_short_circuit_solver_integer_parameter.argtypes = (c_char_p, c_int, c_uint) + libsteps.api_set_short_circuit_solver_float_parameter.restype = None + libsteps.api_set_short_circuit_solver_float_parameter.argtypes = (c_char_p, c_double, c_uint) + libsteps.api_set_short_circuit_solver_boolean_parameter.restype = None + libsteps.api_set_short_circuit_solver_boolean_parameter.argtypes = (c_char_p, c_bool, c_uint) + + libsteps.api_solve_short_circuit.restype = None + libsteps.api_solve_short_circuit.argtypes = (c_uint, ) + libsteps.api_get_short_circuit_result_float_data.restype = (c_double) + libsteps.api_get_short_circuit_result_float_data.argtypes = (c_char_p, c_uint) + libsteps.api_show_short_circuit_result.restype = None + libsteps.api_show_short_circuit_result.argtypes = (c_uint, ) + libsteps.api_save_short_circuit_result_to_file.restype = None + libsteps.api_save_short_circuit_result_to_file.argtypes = (c_char_p, c_uint) + libsteps.api_save_extended_short_circuit_result_to_file.restype = None + libsteps.api_save_extended_short_circuit_result_to_file.argtypes = (c_char_p, c_uint) + + libsteps.api_short_circuit_set_bus_fault.restype = None + libsteps.api_short_circuit_set_bus_fault.argtypes = (c_uint, c_char_p, c_double, c_double, c_uint) + libsteps.api_short_circuit_set_line_fault.restype = None + libsteps.api_short_circuit_set_line_fault.argtypes = (c_uint, c_uint, c_char_p, c_char_p, c_double, c_double, c_double, c_uint) + libsteps.api_short_circuit_clear_fault.restype = None + libsteps.api_short_circuit_clear_fault.argtype = (c_uint) + libsteps.api_get_dynamic_simulator_integer_parameter.restype = (c_uint) libsteps.api_get_dynamic_simulator_integer_parameter.argtypes = (c_char_p, c_uint) libsteps.api_get_dynamic_simulator_float_parameter.restype = (c_double) diff --git a/python/stepspy-current/stepspy/stepspy.py b/python/stepspy-current/stepspy/stepspy.py index 5295eca6..0ed9b7ef 100644 --- a/python/stepspy-current/stepspy/stepspy.py +++ b/python/stepspy-current/stepspy/stepspy.py @@ -2494,6 +2494,37 @@ def get_generator_data(self, generator, par_type, par_name): global STEPS_LIB return self.__get_source_data(generator, par_type, par_name) + def get_generator_sequence_data(self, generator, par_type, par_name): + """ + Get generator sequence data. + Args: + (1) generator: Generator device id in format of (bus, ickt) + (2) par_type: String of parameter type. Choose one from {"I", "F", "D", "S", "B"}. + (3) par_name: String of parameter name. + Rets: + (1) Value of parameter. + Tips: + The par_type meaning: "I": integer number, "F" or "D": float number, "S": string, "B": boolean data. + The type of given parameter MUST be consistent with the given parameter type. Otherwise, 0, 0.0, "", or False will be returned. + Example: N/A + """ + global STEPS_LIB + par_type = par_type.upper() + if par_type not in ['I', 'INT', 'INTEGER', 'F', 'D', 'FLOAT', 'DOUBLE', 'B', 'BOOL', 'BOOLEAN', 'S', 'STRING']: + return None + bus, ickt = self.__extract_single_bus_device_id(generator) + ickt = self.__get_c_char_p_of_string(ickt) + par_name = self.__get_c_char_p_of_string(par_name) + if par_type in ['I', 'INT', 'INTEGER']: + return None + if par_type in ['F', 'D', 'FLOAT', 'DOUBLE']: + return STEPS_LIB.api_get_generator_sequence_float_data(bus, ickt, par_name, self.toolkit_index) + if par_type in ['B', 'BOOL', 'BOOLEAN']: + return None + if par_type in ['S', 'STRING']: + return None + return None + def get_wt_generator_data(self, wt_generator, par_type, par_name): """ Get wind turbine generator data. @@ -2511,6 +2542,37 @@ def get_wt_generator_data(self, wt_generator, par_type, par_name): global STEPS_LIB return self.__get_source_data(wt_generator, par_type, par_name) + def get_wt_generator_sequence_data(self, wt_generator, par_type, par_name): + """ + Get wt_generator sequence data. + Args: + (1) wt_generator: Generator device id in format of (bus, ickt) + (2) par_type: String of parameter type. Choose one from {"I", "F", "D", "S", "B"}. + (3) par_name: String of parameter name. + Rets: + (1) Value of parameter. + Tips: + The par_type meaning: "I": integer number, "F" or "D": float number, "S": string, "B": boolean data. + The type of given parameter MUST be consistent with the given parameter type. Otherwise, 0, 0.0, "", or False will be returned. + Example: N/A + """ + global STEPS_LIB + par_type = par_type.upper() + if par_type not in ['I', 'INT', 'INTEGER', 'F', 'D', 'FLOAT', 'DOUBLE', 'B', 'BOOL', 'BOOLEAN', 'S', 'STRING']: + return None + bus, ickt = self.__extract_single_bus_device_id(wt_generator) + ickt = self.__get_c_char_p_of_string(ickt) + par_name = self.__get_c_char_p_of_string(par_name) + if par_type in ['I', 'INT', 'INTEGER']: + return None + if par_type in ['F', 'D', 'FLOAT', 'DOUBLE']: + return STEPS_LIB.api_get_wt_generator_sequence_float_data(bus, ickt, par_name, self.toolkit_index) + if par_type in ['B', 'BOOL', 'BOOLEAN']: + return None + if par_type in ['S', 'STRING']: + return None + return None + def get_pv_unit_data(self, pv_unit, par_type, par_name): """ Get PV unit data. @@ -2528,6 +2590,37 @@ def get_pv_unit_data(self, pv_unit, par_type, par_name): global STEPS_LIB return self.__get_source_data(pv_unit, par_type, par_name) + def get_pv_unit_sequence_data(self, pv_unit, par_type, par_name): + """ + Get pv_unit sequence data. + Args: + (1) pv_unit: pv_unit device id in format of (bus, ickt) + (2) par_type: String of parameter type. Choose one from {"I", "F", "D", "S", "B"}. + (3) par_name: String of parameter name. + Rets: + (1) Value of parameter. + Tips: + The par_type meaning: "I": integer number, "F" or "D": float number, "S": string, "B": boolean data. + The type of given parameter MUST be consistent with the given parameter type. Otherwise, 0, 0.0, "", or False will be returned. + Example: N/A + """ + global STEPS_LIB + par_type = par_type.upper() + if par_type not in ['I', 'INT', 'INTEGER', 'F', 'D', 'FLOAT', 'DOUBLE', 'B', 'BOOL', 'BOOLEAN', 'S', 'STRING']: + return None + bus, ickt = self.__extract_single_bus_device_id(pv_unit) + ickt = self.__get_c_char_p_of_string(ickt) + par_name = self.__get_c_char_p_of_string(par_name) + if par_type in ['I', 'INT', 'INTEGER']: + return None + if par_type in ['F', 'D', 'FLOAT', 'DOUBLE']: + return STEPS_LIB.api_get_pv_unit_sequence_float_data(bus, ickt, par_name, self.toolkit_index) + if par_type in ['B', 'BOOL', 'BOOLEAN']: + return None + if par_type in ['S', 'STRING']: + return None + return None + def get_energy_storage_data(self, energy_storage, par_type, par_name): """ Get energy storage data. @@ -2946,6 +3039,38 @@ def set_generator_data(self, generator, par_type, par_name, value): global STEPS_LIB return self.__set_source_data(generator, par_type, par_name, value) + def set_generator_sequence_data(self, generator, par_type, par_name, value): + """ + Set generator sequence data + Args: + (1) generator: generator device id in format of (bus, ickt). + (2) par_type: String of parameter type. Choose one from {"I", "F", "D", "S", "B"}. + (3) par_name: String of parameter name. + (4) value: Value of parameter. + Rets: N/A + Tips: + The par_type meaning: "I": integer number, "F" or "D": float number, "S": string, "B": boolean data. + The type of given parameter MUST be consistent with the given parameter type. Otherwise, nothing will be done. + The value MUST be consistent with the given parameter type. Otherwise, function may malfunction and package may exist with error. + Example: N/A + """ + global STEPS_LIB + par_type = par_type.upper() + if par_type not in ['I', 'INT', 'INTEGER', 'F', 'D', 'FLOAT', 'DOUBLE', 'B', 'BOOL', 'BOOLEAN', 'S', 'STRING']: + return + bus, ickt = self.__extract_single_bus_device_id(generator) + ickt = self.__get_c_char_p_of_string(ickt) + par_name = self.__get_c_char_p_of_string(par_name) + if par_type in ['I', 'INT', 'INTEGER']: + return + if par_type in ['F', 'D', 'FLOAT', 'DOUBLE']: + return STEPS_LIB.api_set_generator_sequence_float_data(bus, ickt, par_name, value, self.toolkit_index) + if par_type in ['B', 'BOOL', 'BOOLEAN']: + return + if par_type in ['S', 'STRING']: + return + return + def set_wt_generator_data(self, wt_generator, par_type, par_name, value): """ Set wind turbine generator data. @@ -2964,6 +3089,38 @@ def set_wt_generator_data(self, wt_generator, par_type, par_name, value): global STEPS_LIB return self.__set_source_data(wt_generator, par_type, par_name, value) + def set_wt_generator_sequence_data(self, wt_generator, par_type, par_name, value): + """ + Set wt_generator sequence data + Args: + (1) wt_generator: wt_generator device id in format of (bus, ickt). + (2) par_type: String of parameter type. Choose one from {"I", "F", "D", "S", "B"}. + (3) par_name: String of parameter name. + (4) value: Value of parameter. + Rets: N/A + Tips: + The par_type meaning: "I": integer number, "F" or "D": float number, "S": string, "B": boolean data. + The type of given parameter MUST be consistent with the given parameter type. Otherwise, nothing will be done. + The value MUST be consistent with the given parameter type. Otherwise, function may malfunction and package may exist with error. + Example: N/A + """ + global STEPS_LIB + par_type = par_type.upper() + if par_type not in ['I', 'INT', 'INTEGER', 'F', 'D', 'FLOAT', 'DOUBLE', 'B', 'BOOL', 'BOOLEAN', 'S', 'STRING']: + return + bus, ickt = self.__extract_single_bus_device_id(wt_generator) + ickt = self.__get_c_char_p_of_string(ickt) + par_name = self.__get_c_char_p_of_string(par_name) + if par_type in ['I', 'INT', 'INTEGER']: + return + if par_type in ['F', 'D', 'FLOAT', 'DOUBLE']: + return STEPS_LIB.api_set_wt_generator_sequence_float_data(bus, ickt, par_name, value, self.toolkit_index) + if par_type in ['B', 'BOOL', 'BOOLEAN']: + return + if par_type in ['S', 'STRING']: + return + return + def set_pv_unit_data(self, pv_unit, par_type, par_name, value): """ Set PV unit data. @@ -2982,6 +3139,38 @@ def set_pv_unit_data(self, pv_unit, par_type, par_name, value): global STEPS_LIB return self.__set_source_data(pv_unit, par_type, par_name, value) + def set_pv_unit_sequence_data(self, pv_unit, par_type, par_name, value): + """ + Set pv_unit sequence data + Args: + (1) pv_unit: pv_unit device id in format of (bus, ickt). + (2) par_type: String of parameter type. Choose one from {"I", "F", "D", "S", "B"}. + (3) par_name: String of parameter name. + (4) value: Value of parameter. + Rets: N/A + Tips: + The par_type meaning: "I": integer number, "F" or "D": float number, "S": string, "B": boolean data. + The type of given parameter MUST be consistent with the given parameter type. Otherwise, nothing will be done. + The value MUST be consistent with the given parameter type. Otherwise, function may malfunction and package may exist with error. + Example: N/A + """ + global STEPS_LIB + par_type = par_type.upper() + if par_type not in ['I', 'INT', 'INTEGER', 'F', 'D', 'FLOAT', 'DOUBLE', 'B', 'BOOL', 'BOOLEAN', 'S', 'STRING']: + return + bus, ickt = self.__extract_single_bus_device_id(pv_unit) + ickt = self.__get_c_char_p_of_string(ickt) + par_name = self.__get_c_char_p_of_string(par_name) + if par_type in ['I', 'INT', 'INTEGER']: + return + if par_type in ['F', 'D', 'FLOAT', 'DOUBLE']: + return STEPS_LIB.api_set_pv_unit_sequence_float_data(bus, ickt, par_name, value, self.toolkit_index) + if par_type in ['B', 'BOOL', 'BOOLEAN']: + return + if par_type in ['S', 'STRING']: + return + return + def set_energy_storage_data(self, energy_storage, par_type, par_name, value): """ Set energy storage data. @@ -3502,7 +3691,6 @@ def save_vsc_hvdc_powerflow_data(self, file, ftype): (2) ftype: string, powerflow data format. Rets: N/A """ - global STEPS_LIB file = self.__get_c_char_p_of_string(file) ftype = self.__get_c_char_p_of_string(ftype) @@ -3590,6 +3778,33 @@ def load_powerflow_result(self, file, ftype): ftype = self.__get_c_char_p_of_string(ftype) STEPS_LIB.api_load_powerflow_result_from_file(file, ftype, self.toolkit_index) + def load_sequence_data(self, file, ftype): + """ + Load sequence data from file. + Args: + (1) file: string, source sequence file name. + (2) ftype: string, sequence data format. + Rets: N/A + Example: N/A + """ + global STEPS_LIB + file = self.__get_c_char_p_of_string(file) + ftype = self.__get_c_char_p_of_string(ftype) + STEPS_LIB.api_load_sequence_data_from_file(file, ftype, self.toolkit_index) + + def save_sequence_data(self, file, ftype): + """ + Save sequence data to file + Args: + (1) file: string, target sequence file name. + (2) ftype: string, sequence data format. + Rets: N/A + """ + global STEPS_LIB + file = self.__get_c_char_p_of_string(file) + ftype = self.__get_c_char_p_of_string(ftype) + STEPS_LIB.api_save_sequence_data_to_file(file, ftype, self.toolkit_index) + def get_powerflow_solver_parameter(self, par_type, par_name): """ Get powerflow solver configuration parameter. @@ -3825,6 +4040,17 @@ def build_network_Z_matrix(self): global STEPS_LIB STEPS_LIB.api_build_network_Z_matrix(self.toolkit_index) return + + def build_sequence_network_Y_matrix(self): + """ + Build sequence network complex Y matrix for powerflow solution. + Args: N/A + Rets: N/A + Example: N/A + """ + global STEPS_LIB + STEPS_LIB.api_build_sequence_network_Y_matrix(self.toolkit_index) + return def save_network_Y_matrix(self, file, export_full=False): """ @@ -3894,6 +4120,48 @@ def save_network_Z_matrix(self, file): STEPS_LIB.api_save_network_Z_matrix(file, self.toolkit_index) return + def save_positive_sequence_network_Y_matrix(self, file): + """ + Save positive sequence network complex Y matrix to file. + Args: + (1) file: String of target file name of sparse Y matrix. + Rets: N/A + Example: + simulator.save_positive_sequence_network_Y_matrix("y.csv") + """ + global STEPS_LIB + file = self.__get_c_char_p_of_string(file) + STEPS_LIB.api_save_positive_sequence_network_Y_matrix(file, self.toolkit_index) + return + + def save_negative_sequence_network_Y_matrix(self, file): + """ + Save negative sequence network complex Y matrix to file. + Args: + (1) file: String of target file name of sparse Y matrix. + Rets: N/A + Example: + simulator.save_negative_sequence_network_Y_matrix("y.csv") + """ + global STEPS_LIB + file = self.__get_c_char_p_of_string(file) + STEPS_LIB.api_save_negative_sequence_network_Y_matrix(file, self.toolkit_index) + return + + def save_zero_sequence_network_Y_matrix(self, file): + """ + Save zero sequence network complex Y matrix to file. + Args: + (1) file: String of target file name of sparse Y matrix. + Rets: N/A + Example: + simulator.save_zero_sequence_network_Y_matrix("y.csv") + """ + global STEPS_LIB + file = self.__get_c_char_p_of_string(file) + STEPS_LIB.api_save_zero_sequence_network_Y_matrix(file, self.toolkit_index) + return + def check_network_connectivity(self, remove_void_islands=False): """ Check network connectivity. @@ -3904,6 +4172,199 @@ def check_network_connectivity(self, remove_void_islands=False): global STEPS_LIB STEPS_LIB.api_check_network_connectivity(remove_void_islands, self.toolkit_index) + def get_short_circuit_solver_parameter(self, par_type, par_name): + """ + Get short circuit solver configuration parameter. + Args: + (1) par_type: String of parameter type. Choose one from {"I", "F", "D", "S", "B"}. + (2) par_name: String of parameter name. + Rets: + (1) Value of parameter. + Tips: + The par_type meaning: "I": integer number, "F" or "D": float number, "S": string, "B": boolean data. + The type of given parameter MUST be consistent with the given parameter type. Otherwise, 0, 0.0, "", or False will be returned. + Example: N/A + """ + global STEPS_LIB + par_type = par_type.upper() + if par_type not in ['I', 'INT', 'INTEGER', 'F', 'D', 'FLOAT', 'DOUBLE', 'B', 'BOOL', 'BOOLEAN']: + return None + par_name = self.__get_c_char_p_of_string(par_name) + if par_type in ['I', 'INT', 'INTEGER']: + return int(STEPS_LIB.api_get_short_circuit_solver_integer_parameter(par_name, self.toolkit_index)) + if par_type in ['F', 'D', 'FLOAT', 'DOUBLE']: + return STEPS_LIB.api_get_short_circuit_solver_float_parameter(par_name, self.toolkit_index) + if par_type in ['B', 'BOOL', 'BOOLEAN']: + return STEPS_LIB.api_get_short_circuit_solver_boolean_parameter(par_name, self.toolkit_index) + return None + + def set_short_circuit_solver_parameter(self, par_type, par_name, value): + """ + Set short circuit solver configuration parameter. + Args: + (1) par_type: String of parameter type. Choose one from {"I", "F", "D", "S", "B"}. + (2) par_name: String of parameter name. + (3) value: Value of parameter. + Rets: N/A + Tips: + The par_type meaning: "I": integer number, "F" or "D": float number, "S": string, "B": boolean data. + The type of given parameter MUST be consistent with the given parameter type. Otherwise, nothing will be changed. + Example: N/A + """ + global STEPS_LIB + par_type = par_type.upper() + if par_type not in ['I', 'INT', 'INTEGER', 'F', 'D', 'FLOAT', 'DOUBLE', 'B', 'BOOL', 'BOOLEAN']: + return + par_name = self.__get_c_char_p_of_string(par_name) + if par_type in ['I', 'INT', 'INTEGER']: + return STEPS_LIB.api_set_short_circuit_solver_integer_parameter(par_name, value, self.toolkit_index) + if par_type in ['F', 'D', 'FLOAT', 'DOUBLE']: + return STEPS_LIB.api_set_short_circuit_solver_float_parameter(par_name, value, self.toolkit_index) + if par_type in ['B', 'BOOL', 'BOOLEAN']: + return STEPS_LIB.api_set_short_circuit_solver_boolean_parameter(par_name, value, self.toolkit_index) + return + + def solve_short_circuit(self): + """ + Solve short circuit. + Args: N/A + Rets: N/A + Example: N/A + """ + global STEPS_LIB + STEPS_LIB.api_solve_short_circuit(self.toolkit_index) + return + + def set_short_circuit_bus_fault(self, bus, fault_type, fault_shunt): + """ + Set bus fault. + Args: + (1) bus: Bus number. + (2) fault_type: String of fault type. THREE PHASES FAULT, SINGLE PHASE GROUNDED FAULT, DOUBLE PHASES FAULT, DOUBLE PHASES GROUNDED FAULT. + (3) fault_shunt: tuple of complex per unit fault shunt in the form of (g, b). the shunt is g+jb + Rets: N/A + Tips: + The fault shunt is represented as conductance and susceptance based on system base power and bus base voltage. + The susceptance is usually set as NEGATIVE to mimic the voltage drop due to fault. + The absolute value of the fault shunt should not be too great. Otherwise, network solution may fail to converge. Typically, |b|<1e6. + Example: + bus = 1 + shunt = (0.0, -2e4) + simulator.set_bus_fault(bus, "three phase fault", shunt) + """ + global STEPS_LIB + fault_type = self.__get_c_char_p_of_string(fault_type) + STEPS_LIB.api_short_circuit_set_bus_fault(bus, fault_type, fault_shunt[0], fault_shunt[1], self.toolkit_index) + return + + def set_short_circuit_line_fault(self, line, fault_type, fault_location, fault_shunt): + """ + Set transmission line fault. + Args: + (1) line: Transmission line device id in format of (ibus, jbus, ickt). + (2) fault_type: String of fault type. THREE PHASES FAULT, SINGLE PHASE GROUNDED FAULT, DOUBLE PHASES FAULT, DOUBLE PHASES GROUNDED FAULT. + (3) fault_location: Relative fault location to ibus. + (4) fault_shunt: tuple of complex per unit fault shunt in the form of (g, b). the shunt is g+jb + Rets: N/A + Tips: + The fault location should be in the range of [0, 1.0], including 0 and 1.0. It represent the relative location of the fault on the line to the ibus. + For example, 0.5 means the fault is set at the middle of the line. 0 means the fault is set at exactly ibus. 1.0 means the fault is set at exactly jbus. + The fault shunt is represented as conductance and susceptance based on system base power and bus base voltage. + The susceptance is usually set as NEGATIVE to mimic the voltage drop due to fault. + The absolute value of the fault shunt should not be too great. Otherwise, network solution may fail to converge. Typically, |b|<1e6. + Multiple faults are supported on single line at different fault locations. + Example: + line = (1, 2, "1#") + location = 0.2 + shunt = (0.0, -2e4) + simulator.set_line_fault(line, "three phase fault", location, shunt) + """ + global STEPS_LIB + ibus, jbus, ickt = self.__extract_double_bus_device_id(line) + ickt = self.__get_c_char_p_of_string(ickt) + fault_type = self.__get_c_char_p_of_string(fault_type) + STEPS_LIB.api_short_circuit_set_line_fault(ibus, jbus, ickt, fault_type, fault_location, fault_shunt[0], fault_shunt[1], self.toolkit_index) + return + + def clear_short_circuit_fault(self): + """ + Clear short circuit fault. + Args:N/A + Rets: N/A + Example: + simulator.clear_short_circuit_fault() + """ + global STEPS_LIB + STEPS_LIB.api_short_circuit_clear_fault(self.toolkit_index) + return + + def get_short_circuit_result_data(self, par_type, par_name): + """ + Get short circuit result data. + Args: + (1) par_type: String of parameter type. Choose one from {"I", "F", "D", "S", "B"}. + (2) par_name: String of parameter name. + Rets: + (1) Value of parameter. + Tips: + The par_type meaning: "I": integer number, "F" or "D": float number, "S": string, "B": boolean data. + The type of given parameter MUST be consistent with the given parameter type. Otherwise, 0, 0.0, "", or False will be returned. + Example: N/A + """ + global STEPS_LIB + par_type = par_type.upper() + if par_type not in ['I', 'INT', 'INTEGER', 'F', 'D', 'FLOAT', 'DOUBLE', 'B', 'BOOL', 'BOOLEAN']: + return None + par_name = self.__get_c_char_p_of_string(par_name) + if par_type in ['I', 'INT', 'INTEGER']: + return None + if par_type in ['F', 'D', 'FLOAT', 'DOUBLE']: + return STEPS_LIB.api_get_short_circuit_result_float_data(par_name, self.toolkit_index) + if par_type in ['B', 'BOOL', 'BOOLEAN']: + return None + return None + + def show_short_circuit_result(self): + """ + Show short circuit result in log. + Args: N/A + Rets: N/A + Example: N/A + """ + global STEPS_LIB + STEPS_LIB.api_show_short_circuit_result(self.toolkit_index) + return + + def save_short_circuit_result(self, file): + """ + Save short circuit result to file. + Args: + (1) file: String of target file name. + Rets: N/A + Tips: + The result exported by save_short_circuit_result() is briefer than that exported by save_extended_short_circuit_result(). + Example: N/A + """ + global STEPS_LIB + file = self.__get_c_char_p_of_string(file) + STEPS_LIB.api_save_short_circuit_result_to_file(file, self.toolkit_index) + return + + def save_extended_short_circuit_result(self, file): + """ + Save extended short circuit result to file. + Args: + (1) file: String of target file name. + Rets: N/A + Tips: + The result exported by save_extended_short_circuit_result() is more detailed than that exported by save_short_circuit_result(). + Example: N/A + """ + global STEPS_LIB + file = self.__get_c_char_p_of_string(file) + STEPS_LIB.api_save_extended_short_circuit_result_to_file(file, self.toolkit_index) + return + def load_dynamic_data(self, file, ftype): """ Load dynamic data from file.