Welcome to GridCal’s documentation!¶
GridCal (abbreviation of Grid Calculator) is a power systems software that has been used for research and power systems consultancy since 2015.
GridCal aims at being a fully usable software product by end users, while allowing power users to tweak it and extend it at will. GridCal is designed as a software library with a graphical user interface, and because of this you can use GridCal as a conventional software, or you may embed it into your own programs.
You may also power systems theory used in GridCal along with interesting information in the author’s simulation guide.
About GridCal¶
GridCal is a research oriented power systems software.
Research oriented? How? Well, it is a fruit of research. It is designed to be modular. As a researcher I found that the available software (not even talking about commercial options) are hard to expand or adapt to achieve complex simulations. GridCal is designed to allow you to build and reuse modules, which eventually will boost your productivity and the possibilities that are at hand.
I have made other projects (even another open source one: fPotencia in C++). I believe that this project encapsulates my half life of programming experience and the curiosity I have developed for power systems.
So, I do really hope you enjoy it, and if you have comments, suggestions or just want to collaborate, do not hesitate to contact.
Cheers,
Santiago
Getting Started¶
Installation¶
GridCal is designed to work with Python 3.6 and onwards, hence retro-compatibility is not guaranteed.
Standalone setup¶
You can install GridCal as a separated standalone program without having to bother about setting up python.
Remember to update the program to the latest version once installed. You’ll find an update script in the installation folder.
Python Package Installation¶
GridCal is multiplatform and it will work in Linux, Windows and OSX.
The recommended way to install GridCal if you have a python distribution already is to open a console and type:
- Windows:
pip install GridCal
- OSX / Linux:
pip3 install GridCal
You must have Python 3.6 or higher installed to work with the GUI.
Check out the video on how to install Python and GridCal on Windows 10.
Manual package installation
Sometimes pip
does not download the lattest version for some reason. In those
cases, follow this link and download the
latest GridCal file: GridCal-x.xx.tar.gz.
From a console install the file manually:
- Windows:
pip install GridCal-x.xx.tar.gz
- OSX / Linux:
pip3 install GridCal-x.xx.tar.gz
Installation from GitHub
To install the development version of GridCal that lives under src, open a console and type:
python3 -m pip install -e 'git+git://github.com/SanPen/GridCal.git#egg=GridCal&subdirectory=src'
Installing GridCal from GitHub, pip can still freeze the version using a commit hash:
python -m pip install -e 'git+git://github.com/SanPen/GridCal.git@5c4dcb96998ae882412b5fee977cf0cff7a40d3c#egg=GridCal&subdirectory=UnderDevelopment'
Here 5c4dcb96998ae882412b5fee977cf0cff7a40d3c
is the git version.
PySide2 vs. PyQt5¶
Now GridCal has been completely ported to PySide2. The reason for this is because PySide2 has been endorsed by Qt as the main python wrapper for the Qt Library and therefore it is expected to have the best support.
However there are plenty of other libraries that depend of PyQt5 which is an alternative wrapper for the Qt framework (and used to be the best one though)
After some test, I can tell you that if GridCal does not work and you installed Python via the Anaconda distribution, go to your anaconda main folder and remove the file qt.conf. No other real solution out is there really.
Video tutorial¶
If you want to start using GridCal with the user interface, the best way might be this tutorial:

There are many other features not shown in the tutorial, but the video guides you through the basics with an example
Running GridCal¶
You must have Python 3.6 or higher installed to work with the GUI. From a Python console:
from GridCal.ExecuteGridCal import run
run()
To see a walk through the user interface go to Graphical User Interface.
Windows¶
To run GridCal with GUI directly from a system console, type:
python -c "from GridCal.ExecuteGridCal import run; run()"
You can embed this command in a shortcut file, and have a windows shortcut in the desktop for GridCal.
Linux / OSX¶
To run GridCal with GUI directly from a system console, type:
python3 -c "from GridCal.ExecuteGridCal import run; run()"
Using GridCal as a library¶
You can use the calculation engine directly or from other applications:
from GridCal.Engine import *
This will provide access to all the objects in the internal engine of GridCal. Refer to the API Reference and the examples for more details.
Power systems scripting¶
GridCal is a Python library for power systems simulation. As such you can seamlessly use the graphical user interface (GUI) or use GridCal as a library to program your own software. Using GridCal as a library might be useful when automatizing tasks or when you need to build a custom study or new tool.
5-node grid creation script¶
This example creates the five-node grid from the fantastic book “Power System Load Flow Analysis” and runs a power flow. After the power flow is executed, the results are printed on the console.
from GridCal.Engine import *
np.set_printoptions(precision=4)
grid = MultiCircuit()
# Add the buses and the generators and loads attached
bus1 = Bus('Bus 1', vnom=20)
# bus1.is_slack = True
grid.add_bus(bus1)
gen1 = Generator('Slack Generator', voltage_module=1.0)
grid.add_generator(bus1, gen1)
bus2 = Bus('Bus 2', vnom=20)
grid.add_bus(bus2)
grid.add_load(bus2, Load('load 2', P=40, Q=20))
bus3 = Bus('Bus 3', vnom=20)
grid.add_bus(bus3)
grid.add_load(bus3, Load('load 3', P=25, Q=15))
bus4 = Bus('Bus 4', vnom=20)
grid.add_bus(bus4)
grid.add_load(bus4, Load('load 4', P=40, Q=20))
bus5 = Bus('Bus 5', vnom=20)
grid.add_bus(bus5)
grid.add_load(bus5, Load('load 5', P=50, Q=20))
# add branches (Lines in this case)
grid.add_branch(Branch(bus1, bus2, 'line 1-2', r=0.05, x=0.11, b=0.02))
grid.add_branch(Branch(bus1, bus3, 'line 1-3', r=0.05, x=0.11, b=0.02))
grid.add_branch(Branch(bus1, bus5, 'line 1-5', r=0.03, x=0.08, b=0.02))
grid.add_branch(Branch(bus2, bus3, 'line 2-3', r=0.04, x=0.09, b=0.02))
grid.add_branch(Branch(bus2, bus5, 'line 2-5', r=0.04, x=0.09, b=0.02))
grid.add_branch(Branch(bus3, bus4, 'line 3-4', r=0.06, x=0.13, b=0.03))
grid.add_branch(Branch(bus4, bus5, 'line 4-5', r=0.04, x=0.09, b=0.02))
options = PowerFlowOptions(SolverType.NR, verbose=False)
power_flow = PowerFlow(grid, options)
power_flow.run()
print('\n\n', grid.name)
print('\t|V|:', abs(power_flow.results.voltage))
print('\t|Sbranch|:', abs(power_flow.results.Sbranch))
print('\t|loading|:', abs(power_flow.results.loading) * 100)
print('\terr:', power_flow.results.error)
print('\tConv:', power_flow.results.converged)
grid.plot_graph()
plt.show()
Other examples¶
Examples are included in Tutorials folder of the GitHub repository. In addition, the tests under src/tests may serve as valuable examples.
Lastly, the GitHub wiki includes a few more examples.
API reference¶
GridCal uses an object oriented approach for all the data and simulation
management. However the object orientation is very inefficient when used in numerical
computation, that is why there are compile()
functions that extract the
information out of the objects and turn this information into vectors, matrices and
DataFrames in order to have efficient numerical computations. After having been
involved in quite some number-crunching software developments, I have found this
approach to be the best compromise between efficiency and code scalability and
maintainability.
The whole idea can be summarized as:
Object oriented structures -> intermediate objects holding arrays -> Numerical modules
GridCal package¶
Subpackages¶
GridCal.Engine package¶
Subpackages¶
-
class
GridCal.Engine.Core.calculation_inputs.
CalculationInputs
(nbus, nbr, ntime, nbat, nctrlgen)¶ Bases:
object
nbus (int): Number of buses nbr (int): Number of branches ntime (int): Number of time steps nbat (int): Number of batteries nctrlgen (int): Number of voltage controlled generators
-
build_linear_ac_sys_mat
()¶ Get the AC linear approximation matrices :return:
-
compile_types
(types_new=None)¶ Compile the types :param types_new: new array of types to consider :return: Nothing
-
compute_branch_results
(V)¶ Compute the branch magnitudes from the voltages :param V: Voltage vector solution in p.u. :return: CalculationResults instance with all the grid magnitudes
-
consolidate
()¶ Compute the magnitudes that cannot be computed vector-wise
-
get_island
(bus_idx, branch_idx, gen_idx, bat_idx)¶ Get a sub-island :param bus_idx: bus indices of the island :param branch_idx: branch indices of the island :return: CalculationInputs instance
-
get_structure
(structure_type)¶ Get a DataFrame with the input.
Arguments:
structure_type (str): ‘Vbus’, ‘Sbus’, ‘Ibus’, ‘Ybus’, ‘Yshunt’, ‘Yseries’ or ‘Types’Returns:
pandas DataFrame
-
print
(bus_names)¶ print in console :return:
-
re_calc_admittance_matrices
(tap_mod)¶ Recalculate the admittance matrices as the tap changes :param tap_mod: tap modules per bus :return: Nothing, the matrices are changed in-place
-
trim_profiles
(time_idx)¶ Trims the profiles with the passed time indices and stores those time indices for later :param time_idx: array of time indices
-
-
class
GridCal.Engine.Core.multi_circuit.
MultiCircuit
(name='')¶ Bases:
object
The concept of circuit should be easy enough to understand. It represents a set of nodes (buses) and branches (lines, transformers or other impedances).
The MultiCircuit class is the main object in GridCal. It represents a circuit that may contain islands. It is important to understand that a circuit split in two or more islands cannot be simulated as is, because the admittance matrix would be singular. The solution to this is to split the circuit in island-circuits. Therefore MultiCircuit identifies the islands and creates individual Circuit objects for each of them.
GridCal uses an object oriented approach for the data management. This allows to group the data in a smart way. In GridCal there are only two types of object directly declared in a Circuit or MultiCircuit object. These are the Bus and the Branch. The branches connect the buses and the buses contain all the other possible devices like loads, generators, batteries, etc. This simplifies enormously the management of element when adding, associating and deleting.
from GridCal.Engine.Core.multi_circuit import MultiCircuit grid = MultiCircuit(name="My grid")
-
add_battery
(bus: GridCal.Engine.Devices.bus.Bus, api_obj=None)¶ Add a Battery object to a Bus.
Arguments:
-
add_generator
(bus: GridCal.Engine.Devices.bus.Bus, api_obj=None)¶ Add a (controlled) Generator object to a Bus.
Arguments:
-
add_overhead_line
(obj: GridCal.Engine.Devices.tower.Tower)¶ Add overhead line (tower) template to the collection :param obj: Tower instance
-
add_sequence_line
(obj: GridCal.Engine.Devices.sequence_line.SequenceLineType)¶ Add sequence line to the collection :param obj: SequenceLineType instance
-
add_shunt
(bus: GridCal.Engine.Devices.bus.Bus, api_obj=None)¶ -
Arguments:
-
add_static_generator
(bus: GridCal.Engine.Devices.bus.Bus, api_obj=None)¶ Add a StaticGenerator object to a Bus.
Arguments:
api_obj (StaticGenerator): StaticGenerator object
-
add_transformer_type
(obj: GridCal.Engine.Devices.transformer.TransformerType)¶ Add transformer template :param obj: TransformerType instance
-
add_underground_line
(obj: GridCal.Engine.Devices.underground_line.UndergroundLineType)¶ Add underground line :param obj: UndergroundLineType instance
-
add_wire
(obj: GridCal.Engine.Devices.wire.Wire)¶ Add Wire to the collection :param obj: Wire instance
-
apply_all_branch_types
()¶ Apply all the branch types
-
apply_lp_profiles
()¶ Apply the LP results as device profiles.
-
assign_circuit
(circ)¶ Assign a circuit object to this object.
Arguments:
circ (MultiCircuit): MultiCircuit object
-
build_graph
()¶ Returns a networkx DiGraph object of the grid.
-
clear
()¶ Clear the multi-circuit (remove the bus and branch objects)
-
compile
(use_opf_vals=False, opf_time_series_results=None, logger=[]) → GridCal.Engine.Core.numerical_circuit.NumericalCircuit¶ Compile the circuit assets into an equivalent circuit that only contains matrices and vectors for calculation. This method returns the numerical circuit, but it also assigns it to self.numerical_circuit, which is used when the MultiCircuit object is passed onto a simulation driver, for example:
from GridCal.Engine import * grid = MultiCircuit() grid.load_file("grid.xlsx") grid.compile() options = PowerFlowOptions() power_flow = PowerFlowMP(grid, options) power_flow.run()
Arguments:
use_opf_vals (bool, False): Use OPF results as inputs
opf_time_series_results (list, None): OPF results to be used as inputs
logger (list, []): Message log
Returns:
self.numerical_circuit (NumericalCircuit): Compiled numerical circuit of the grid
-
copy
()¶ Returns a deep (true) copy of this circuit.
-
create_profiles
(steps, step_length, step_unit, time_base: datetime.datetime = datetime.datetime(2019, 7, 1, 16, 38, 22, 248662))¶ Set the default profiles in all the objects enabled to have profiles.
Arguments:
steps (int): Number of time steps
step_length (int): Time length (1, 2, 15, …)
step_unit (str): Unit of the time step (“h”, “m” or “s”)
time_base (datetime, datetime.now()): Date to start from
-
delete_branch
(obj: GridCal.Engine.Devices.branch.Branch)¶ Delete a Branch object from the grid.
Arguments:
-
delete_overhead_line
(i)¶ Delete tower from the collection :param i: index
-
delete_sequence_line
(i)¶ Delete sequence line from the collection :param i: index
-
delete_transformer_type
(i)¶ Delete transformer type from the colection :param i: index
-
delete_underground_line
(i)¶ Delete underground line :param i: index
-
delete_wire
(i)¶ Delete wire from the collection :param i: index
-
device_type_name_dict
= None¶ self.type_name = ‘Shunt’
self.properties_with_profile = [‘Y’]
-
dispatch
()¶ Dispatch either load or generation using a simple equalised share rule of the shedding to be done.
-
export_pf
(file_name, power_flow_results)¶ Export power flow results to file.
Arguments:
file_name (str): Excel file name
-
export_profiles
(file_name)¶ Export object profiles to file.
Arguments:
file_name (str): Excel file name
-
format_profiles
(index)¶ Format the pandas profiles in place using a time index.
Arguments:
index: Time profile
-
get_Jacobian
(sparse=False)¶ Returns the grid Jacobian matrix.
Arguments:
sparse (bool, False): Return the matrix in CSR sparse format (True) or as full matrix (False)
-
get_catalogue_dict
(branches_only=False)¶ Returns a dictionary with the catalogue types and the associated list of objects.
Arguments:
branches_only (bool, False): Only branch types
-
get_catalogue_dict_by_name
(type_class=None)¶
-
get_elements_by_type
(element_type: GridCal.Engine.Devices.meta_devices.DeviceType)¶ Get set of elements and their parent nodes :param element_type: DeviceTYpe instance :return: List of elements, it raises an exception if the elements are unknown
-
get_json_dict
(id)¶ Returns a JSON dictionary of the MultiCircuit instance with the following values: id, type, phases, name, Sbase, comments.
Arguments:
id: Arbitrary identifier
-
get_node_elements_by_type
(element_type: GridCal.Engine.Devices.meta_devices.DeviceType)¶ Get set of elements and their parent nodes.
Arguments:
element_type (str): Element type, either “Load”, “StaticGenerator”, “Generator”, “Battery” or “Shunt”Returns:
List of elements, list of matching parent buses
-
get_static_generators
()¶ Returns a list of StaticGenerator objects in the grid.
-
get_static_generators_names
()¶ Returns a list of StaticGenerator names.
-
plot_graph
(ax=None)¶ Plot the grid. :param ax: Matplotlib axis object :return:
-
save_calculation_objects
(file_path)¶ Save all the calculation objects of all the grids.
Arguments:
file_path (str): Path to file
-
set_power
(S)¶ Set the power array in the circuits.
Arguments:
S (list): Array of power values in MVA for all the nodes in all the islands
-
set_state
(t)¶ Set the profiles state at the index t as the default values.
-
-
class
GridCal.Engine.Core.numerical_circuit.
NumericalCircuit
(n_bus, n_br, n_ld, n_gen, n_sta_gen, n_batt, n_sh, n_time, Sbase)¶ Bases:
object
-
R_corrected
(t=None)¶ Returns temperature corrected resistances (numpy array) based on a formula provided by: NFPA 70-2005, National Electrical Code, Table 8, footnote #2; and https://en.wikipedia.org/wiki/Electrical_resistivity_and_conductivity#Linear_approximation (version of 2019-01-03 at 15:20 EST).
-
compute
(add_storage=True, add_generation=True, apply_temperature=False, branch_tolerance_mode=<BranchImpedanceMode.Specified: 0>) → List[GridCal.Engine.Core.calculation_inputs.CalculationInputs]¶ Compute the cross connectivity matrices to determine the circuit connectivity towards the calculation. Additionally, compute the calculation matrices. :param add_storage: :param add_generation: :param apply_temperature: :param branch_tolerance_mode: :return: list of CalculationInputs instances where each one is a circuit island
-
compute_ts
(add_storage=True, add_generation=True, apply_temperature=False, branch_tolerance_mode=<BranchImpedanceMode.Specified: 0>) → Dict[int, List[GridCal.Engine.Core.calculation_inputs.CalculationInputs]]¶ Compute the cross connectivity matrices to determine the circuit connectivity towards the calculation. Additionally, compute the calculation matrices. :param add_storage: :param add_generation: :param apply_temperature: :param branch_tolerance_mode: :return: dictionary of lists of CalculationInputs instances where each one is a circuit island
-
get_B
(apply_temperature=False)¶ Parameters: apply_temperature – Returns:
-
get_different_states
()¶ Get a dictionary of different connectivity states :return: dictionary of states {master state index -> list of states associated}
-
get_raw_circuit
(add_generation, add_storage) → GridCal.Engine.Core.calculation_inputs.CalculationInputs¶ Parameters: - add_generation –
- add_storage –
Returns:
-
plot
(stop=True)¶ Plot the grid as a graph :param stop: stop the execution while displaying
-
power_flow_post_process
(V, only_power=False, t=0)¶ Compute the power flows trough the branches for the complete circuit taking into account the islands @param V: Voltage solution array for the circuit buses @param only_power: compute only the power injection @return: Sbranch (MVA), Ibranch (p.u.), loading (p.u.), losses (MVA), Sbus(MVA)
-
print
(islands_only=False)¶ print the connectivity matrices :return:
-
-
GridCal.Engine.Core.numerical_circuit.
calc_connectivity
(branch_active, C_branch_bus_f, C_branch_bus_t, apply_temperature, R_corrected, R, X, G, B, branch_tolerance_mode: GridCal.Engine.basic_structures.BranchImpedanceMode, impedance_tolerance, tap_mod, tap_ang, tap_t, tap_f, Ysh)¶ Build all the admittance related objects :param branch_active: array of branch active :param C_branch_bus_f: branch-bus from connectivity matrix :param C_branch_bus_t: branch-bus to connectivity matrix :param apply_temperature: apply temperature correction? :param R_corrected: Use the corrected resistance? :param R: array of resistance :param X: array of reactance :param G: array of conductance :param B: array of susceptance :param branch_tolerance_mode: branch tolerance mode (enum: BranchImpedanceMode) :param impedance_tolerance: impedance tolerance :param tap_mod: tap modules array :param tap_ang: tap angles array :param tap_t: virtual tap to array :param tap_f: virtual tap from array :param Ysh: shunt admittance injections :return: Ybus: Admittance matrix
Yf: Admittance matrix of the from buses Yt: Admittance matrix of the to buses B1: Fast decoupled B’ matrix B2: Fast decoupled B’’ matrix Yseries: Admittance matrix of the series elements Ys: array of series admittances GBc: array of shunt conductances Cf: Branch-bus from connectivity matrix Ct: Branch-to from connectivity matrix C_bus_bus: Adjacency matrix C_branch_bus: branch-bus connectivity matrix islands: List of islands bus indices (each list element is a list of bus indices of the island)
-
GridCal.Engine.Core.numerical_circuit.
calc_islands
(circuit: GridCal.Engine.Core.calculation_inputs.CalculationInputs, C_bus_bus, C_branch_bus, C_gen_bus, C_batt_bus, nbus, nbr, time_idx=None) → List[GridCal.Engine.Core.calculation_inputs.CalculationInputs]¶ Partition the circuit in islands for the designated time intervals :param circuit: CalculationInputs instance with all the data regardless of the islands and the branch states :param C_bus_bus: bus-bus connectivity matrix :param C_branch_bus: branch-bus connectivity matrix :param C_gen_bus: gen-bus connectivity matrix :param C_batt_bus: battery-bus connectivity matrix :param nbus: number of buses :param nbr: number of branches :param time_idx: array with the time indices where this set of islands belongs to
(if None all the time series are kept)Returns: list of CalculationInputs instances
-
GridCal.Engine.Core.numerical_circuit.
get_branches_of_the_island
(island, C_branch_bus)¶ Get the branch indices of the island :param island: array of bus indices of the island :param C_branch_bus: connectivity matrix of the branches and the buses :return: array of indices of the branches
-
class
GridCal.Engine.Devices.battery.
Battery
(name='batt', active_power=0.0, power_factor=0.8, voltage_module=1.0, is_controlled=True, Qmin=-9999, Qmax=9999, Snom=9999, Enom=9999, p_min=-9999, p_max=9999, op_cost=1.0, power_prof=None, power_factor_prof=None, vset_prof=None, active=True, Sbase=100, enabled_dispatch=True, mttf=0.0, mttr=0.0, charge_efficiency=0.9, discharge_efficiency=0.9, max_soc=0.99, min_soc=0.3, soc=0.8, charge_per_cycle=0.1, discharge_per_cycle=0.1)¶ Bases:
GridCal.Engine.Devices.generator.Generator
Battery (voltage controlled and dispatchable).
Arguments:
name (str, “batt”): Name of the battery
active_power (float, 0.0): Active power in MW
power_factor (float, 0.8): Power factor
voltage_module (float, 1.0): Voltage setpoint in per unit
is_controlled (bool, True): Is the unit voltage controlled (if so, the connection bus becomes a PV bus)
Qmin (float, -9999): Minimum reactive power in MVAr
Qmax (float, 9999): Maximum reactive power in MVAr
Snom (float, 9999): Nominal apparent power in MVA
Enom (float, 9999): Nominal energy capacity in MWh
p_min (float, -9999): Minimum dispatchable power in MW
p_max (float, 9999): Maximum dispatchable power in MW
op_cost (float, 1.0): Operational cost in Eur (or other currency) per MW
power_prof (DataFrame, None): Pandas DataFrame with the active power profile in MW
power_factor_prof (DataFrame, None): Pandas DataFrame with the power factor profile
vset_prof (DataFrame, None): Pandas DataFrame with the voltage setpoint profile in per unit
active (bool, True): Is the battery active?
Sbase (float, 100): Base apparent power in MVA
enabled_dispatch (bool, True): Is the battery enabled for OPF?
mttf (float, 0.0): Mean time to failure in hours
mttr (float, 0.0): Mean time to recovery in hours
charge_efficiency (float, 0.9): Efficiency when charging
discharge_efficiency (float, 0.9): Efficiency when discharging
max_soc (float, 0.99): Maximum state of charge
min_soc (float, 0.3): Minimum state of charge
soc (float, 0.8): Current state of charge
charge_per_cycle (float, 0.1): Per unit of power to take per cycle when charging
discharge_per_cycle (float, 0.1): Per unit of power to deliver per cycle when discharging
-
get_json_dict
(id, bus_dict)¶ Get json dictionary :param id: ID: Id for this object :param bus_dict: Dictionary of buses [object] -> ID :return: json-compatible dictionary
-
get_processed_at
(t, dt, store_values=True)¶ Get the processed power at the time index t :param t: time index :param dt: time step in hours :param store_values: store the values? :return: active power processed by the battery control in MW
-
initialize_arrays
(index, arr=None, arr_in_pu=False)¶ Create power profile based on index :param index: time index associated :param arr: array of values :param arr_in_pu: is the array in per unit?
-
process
(P, dt, charge_if_needed=False)¶ process a cycle in the battery :param P: proposed power in MW :param dt: time increment in hours :param charge_if_needed: True / False :param store_values: Store the values into the internal arrays? :return: Amount of power actually processed in MW
-
reset
()¶ Set the battery to its initial state
-
-
class
GridCal.Engine.Devices.branch.
Branch
(bus_from: GridCal.Engine.Devices.bus.Bus, bus_to: GridCal.Engine.Devices.bus.Bus, name='Branch', r=1e-20, x=1e-20, g=1e-20, b=1e-20, rate=1.0, tap=1.0, shift_angle=0, active=True, tolerance=0, cost=0.0, mttf=0, mttr=0, r_fault=0.0, x_fault=0.0, fault_pos=0.5, branch_type: GridCal.Engine.Devices.types.BranchType = <BranchType.Line: ('line', )>, length=1, vset=1.0, temp_base=20, temp_oper=20, alpha=0.0033, bus_to_regulated=False, template=<GridCal.Engine.Devices.branch.BranchTemplate object>)¶ Bases:
GridCal.Engine.Devices.meta_devices.EditableDevice
The Branch class represents the connections between nodes (i.e. buses) in GridCal. A branch is an element (cable, line, capacitor, transformer, etc.) with an electrical impedance. The basic Branch class includes basic electrical attributes for most passive elements, but other device types may be passed to the Branch constructor to configure it as a specific type.
For example, a transformer may be created with the following code:
from GridCal.Engine.Core.multi_circuit import MultiCircuit from GridCal.Engine.Devices import * from GridCal.Engine.Devices.types import * # Create grid grid = MultiCircuit() # Create buses POI = Bus(name="POI", vnom=100, #kV is_slack=True) grid.add_bus(POI) B_C3 = Bus(name="B_C3", vnom=10) #kV grid.add_bus(B_C3) # Create transformer types SS = TransformerType(name="SS", hv_nominal_voltage=100, # kV lv_nominal_voltage=10, # kV nominal_power=100, # MVA copper_losses=10000, # kW iron_losses=125, # kW no_load_current=0.5, # % short_circuit_voltage=8) # % grid.add_transformer_type(SS) # Create transformer X_C3 = Branch(bus_from=POI, bus_to=B_C3, name="X_C3", branch_type=BranchType.Transformer, template=SS, ) # Add transformer to grid grid.add_branch(X_C3)
Refer to the
GridCal.Engine.Devices.branch.TapChanger
class for an example using a voltage regulator.Arguments:
bus_from (GridCal.Engine.Devices.bus module): “From” bus object
bus_to (GridCal.Engine.Devices.bus module): “To” bus object
name (str, “Branch”): Name of the branch
r (float, 1e-20): Branch resistance in per unit
x (float, 1e-20): Branch reactance in per unit
g (float, 1e-20): Branch shunt conductance in per unit
b (float, 1e-20): Branch shunt susceptance in per unit
rate (float, 1.0): Branch rate in MVA
tap (float, 1.0): Branch tap module
shift_angle (int, 0): Tap shift angle in radians
active (bool, True): Is the branch active?
tolerance (float, 0): Tolerance specified for the branch impedance in %
mttf (float, 0.0): Mean time to failure in hours
mttr (float, 0.0): Mean time to recovery in hours
r_fault (float, 0.0): Mid-line fault resistance in per unit (SC only)
x_fault (float, 0.0): Mid-line fault reactance in per unit (SC only)
fault_pos (float, 0.0): Mid-line fault position in per unit (0.0 = bus_from, 0.5 = middle, 1.0 = bus_to)
branch_type (BranchType, BranchType.Line): Device type enumeration (ex.:
GridCal.Engine.Devices.transformer.TransformerType
)length (float, 0.0): Length of the branch in km
vset (float, 1.0): Voltage set-point of the voltage controlled bus in per unit
temp_base (float, 20.0): Base temperature at which r is measured in °C
temp_oper (float, 20.0): Operating temperature in °C
alpha (float, 0.0033): Thermal constant of the material in °C
bus_to_regulated (bool, False): Is the bus_to voltage regulated by this branch?
template (BranchTemplate, BranchTemplate()): Basic branch template
-
R_corrected
¶ Returns a temperature corrected resistance based on a formula provided by: NFPA 70-2005, National Electrical Code, Table 8, footnote #2; and https://en.wikipedia.org/wiki/Electrical_resistivity_and_conductivity#Linear_approximation (version of 2019-01-03 at 15:20 EST).
-
apply_tap_changer
(tap_changer: GridCal.Engine.Devices.branch.TapChanger)¶ Apply a new tap changer
Argument:
tap_changer (GridCal.Engine.Devices.branch.TapChanger
): Tap changer object
-
apply_template
(obj, Sbase, logger=[])¶ Apply a branch template to this object
Arguments:
obj: TransformerType or Tower object
Sbase (float): Nominal power in MVA
logger (list, []): Log list
-
branch_type_converter
(val_string)¶ function to convert the branch type string into the BranchType :param val_string: :return: branch type conversion
-
copy
(bus_dict=None)¶ Returns a copy of the branch @return: A new with the same content as this
-
get_json_dict
(id, bus_dict)¶ Get json dictionary :param id: ID: Id for this object :param bus_dict: Dictionary of buses [object] -> ID :return:
-
get_save_data
()¶ Return the data that matches the edit_headers :return:
-
get_virtual_taps
()¶ Get the branch virtual taps
The virtual taps generate when a transformer nominal winding voltage differs from the bus nominal voltage.
Returns:
tap_f (float, 1.0): Virtual tap at the from side
tap_t (float, 1.0): Virtual tap at the to side
-
plot_profiles
(time_series=None, my_index=0, show_fig=True)¶ Plot the time series results of this object :param time_series: TimeSeries Instance :param my_index: index of this object in the simulation :param show_fig: Show the figure?
-
tap_down
()¶ Move the tap changer one position up
-
tap_up
()¶ Move the tap changer one position up
-
-
class
GridCal.Engine.Devices.branch.
BranchTemplate
(name='BranchTemplate', tpe=<BranchType.Branch: ('branch', )>)¶ Bases:
object
-
get_save_data
()¶
-
-
class
GridCal.Engine.Devices.branch.
BranchTypeConverter
(tpe: GridCal.Engine.Devices.types.BranchType)¶ Bases:
object
-
class
GridCal.Engine.Devices.branch.
TapChanger
(taps_up=5, taps_down=5, max_reg=1.1, min_reg=0.9)¶ Bases:
object
The TapChanger class defines a transformer’s tap changer, either onload or offload. It needs to be attached to a predefined transformer (i.e. a Branch object).
The following example shows how to attach a tap changer to a transformer tied to a voltage regulated GridCal.Engine.Devices.bus module:
from GridCal.Engine.Core.multi_circuit import MultiCircuit from GridCal.Engine.devices import * from GridCal.Engine.device_types import * # Create grid grid = MultiCircuit() # Create buses POI = Bus(name="POI", vnom=100, #kV is_slack=True) grid.add_bus(POI) B_C3 = Bus(name="B_C3", vnom=10) #kV grid.add_bus(B_C3) # Create transformer types SS = TransformerType(name="SS", hv_nominal_voltage=100, # kV lv_nominal_voltage=10, # kV nominal_power=100, # MVA copper_losses=10000, # kW iron_losses=125, # kW no_load_current=0.5, # % short_circuit_voltage=8) # % grid.add_transformer_type(SS) # Create transformer X_C3 = Branch(bus_from=POI, bus_to=B_C3, name="X_C3", branch_type=BranchType.Transformer, template=SS, bus_to_regulated=True, vset=1.05) # Attach tap changer X_C3.tap_changer = TapChanger(taps_up=16, taps_down=16, max_reg=1.1, min_reg=0.9) X_C3.tap_changer.set_tap(X_C3.tap_module) # Add transformer to grid grid.add_branch(X_C3)
Arguments:
taps_up (int, 5): Number of taps position up
taps_down (int, 5): Number of tap positions down
max_reg (float, 1.1): Maximum regulation up i.e 1.1 -> +10%
min_reg (float, 0.9): Maximum regulation down i.e 0.9 -> -10%
Additional Properties:
tap (int, 0): Current tap position-
get_tap
()¶ Get the tap voltage regulation module
-
set_tap
(tap_module)¶ Set the integer tap position corresponding to a tap value
Attribute:
tap_module (float): Tap module centered around 1.0
-
tap_down
()¶ Go to the next upper tap position
-
tap_up
()¶ Go to the next upper tap position
-
-
class
GridCal.Engine.Devices.bus.
Bus
(name='Bus', vnom=10, vmin=0.9, vmax=1.1, r_fault=0.0, x_fault=0.0, xpos=0, ypos=0, height=0, width=0, active=True, is_slack=False, area='Default', zone='Default', substation='Default')¶ Bases:
GridCal.Engine.Devices.meta_devices.EditableDevice
The Bus object is the container of all the possible devices that can be attached to a bus bar or substation. Such objects can be loads, voltage controlled generators, static generators, batteries, shunt elements, etc.
Arguments:
name (str, “Bus”): Name of the bus
vnom (float, 10.0): Nominal voltage in kV
vmin (float, 0.9): Minimum per unit voltage
vmax (float, 1.1): Maximum per unit voltage
r_fault (float, 0.0): Resistance of the fault in per unit (SC only)
x_fault (float, 0.0): Reactance of the fault in per unit (SC only)
xpos (int, 0): X position in pixels (GUI only)
ypos (int, 0): Y position in pixels (GUI only)
height (int, 0): Height of the graphic object (GUI only)
width (int, 0): Width of the graphic object (GUI only)
active (bool, True): Is the bus active?
is_slack (bool, False): Is this bus a slack bus?
area (str, “Default”): Name of the area
zone (str, “Default”): Name of the zone
substation (str, “Default”): Name of the substation
Additional Properties:
Qmin_sum (float, 0): Minimum reactive power of this bus (inferred from the devices)
Qmax_sum (float, 0): Maximum reactive power of this bus (inferred from the devices)
loads (list, list()): List of loads attached to this bus
controlled_generators (list, list()): List of controlled generators attached to this bus
shunts (list, list()): List of shunts attached to this bus
batteries (list, list()): List of batteries attached to this bus
static_generators (list, list()): List of static generators attached to this bus
measurements (list, list()): List of measurements
-
apply_lp_profiles
(Sbase)¶ Sets the lp solution to the regular generators profile
-
copy
()¶ Deep copy of this object :return: New instance of this object
-
create_profiles
(index)¶ Delete all profiles
-
delete_profiles
()¶ Delete all profiles
-
determine_bus_type
()¶ Infer the bus type from the devices attached to it @return: Nothing
-
get_fault_impedance
()¶ Get the fault impedance :return: complex value of fault impedance
-
get_json_dict
(id)¶ Return Json-like dictionary :return: Dictionary
-
initialize_lp_profiles
()¶ Dimension the LP var profiles :return: Nothing
-
merge
(other_bus)¶ Add the elements of the “Other bus” to this bus :param other_bus: Another instance of Bus
-
plot_profiles
(time_profile, ax_load=None, ax_voltage=None, time_series_driver=None, my_index=0)¶ plot the profiles of this bus :param time_profile: Master profile of time steps (stored in the MultiCircuit) :param time_series_driver: time series driver :param ax_load: Load axis, if not provided one will be created :param ax_voltage: Voltage axis, if not provided one will be created :param my_index: index of this object in the time series results
-
retrieve_graphic_position
()¶ Get the position set by the graphic object into this object’s variables :return: Nothing
-
set_profile_values
(t)¶ Set the default values from the profiles at time index t :param t: profile time index
-
set_state
(t)¶ Set the profiles state of the objects in this bus to the value given in the profiles at the index t :param t: index of the profile :return: Nothing
-
-
class
GridCal.Engine.Devices.generator.
Generator
(name='gen', active_power=0.0, power_factor=0.8, voltage_module=1.0, is_controlled=True, Qmin=-9999, Qmax=9999, Snom=9999, power_prof=None, power_factor_prof=None, vset_prof=None, Cost_prof=None, active=True, p_min=0.0, p_max=9999.0, op_cost=1.0, Sbase=100, enabled_dispatch=True, mttf=0.0, mttr=0.0)¶ Bases:
GridCal.Engine.Devices.meta_devices.EditableDevice
Voltage controlled generator. This generators supports several reactive power control modes (see
GridCal.Engine.Simulations.PowerFlow.power_flow_driver.ReactivePowerControlMode
) to regulate the voltage on its GridCal.Engine.Devices.bus module during power flow simulations.Arguments:
name (str, “gen”): Name of the generator
active_power (float, 0.0): Active power in MW
power_factor (float, 0.8): Power factor
voltage_module (float, 1.0): Voltage setpoint in per unit
is_controlled (bool, True): Is the generator voltage controlled?
Qmin (float, -9999): Minimum reactive power in MVAr
Qmax (float, 9999): Maximum reactive power in MVAr
Snom (float, 9999): Nominal apparent power in MVA
power_prof (DataFrame, None): Pandas DataFrame with the active power profile in MW
power_factor_prof (DataFrame, None): Pandas DataFrame with the power factor profile
vset_prof (DataFrame, None): Pandas DataFrame with the voltage setpoint profile in per unit
active (bool, True): Is the generator active?
p_min (float, 0.0): Minimum dispatchable power in MW
p_max (float, 9999): Maximum dispatchable power in MW
op_cost (float, 1.0): Operational cost in Eur (or other currency) per MW
Sbase (float, 100): Nominal apparent power in MVA
enabled_dispatch (bool, True): Is the generator enabled for OPF?
mttf (float, 0.0): Mean time to failure in hours
mttr (float, 0.0): Mean time to recovery in hours
-
apply_lp_profile
(Sbase)¶ Set LP profile to the regular profile :return:
-
apply_lp_vars
(at=None)¶ Set the LP vars to the main value or the profile
-
copy
()¶ Make a deep copy of this object :return: Copy of this object
-
get_json_dict
(id, bus_dict)¶ Get json dictionary :param id: ID: Id for this object :param bus_dict: Dictionary of buses [object] -> ID :return: json-compatible dictionary
-
get_lp_var_profile
(index)¶ Get the profile of the LP solved values into a Pandas DataFrame :param index: time index :return: DataFrame with the LP values
-
initialize_lp_vars
()¶ Initialize the LP variables
-
-
class
GridCal.Engine.Devices.load.
Load
(name='Load', G=0.0, B=0.0, Ir=0.0, Ii=0.0, P=0.0, Q=0.0, cost=0.0, G_prof=None, B_prof=None, Ir_prof=None, Ii_prof=None, P_prof=None, Q_prof=None, active=True, mttf=0.0, mttr=0.0)¶ Bases:
GridCal.Engine.Devices.meta_devices.EditableDevice
The load object implements the so-called ZIP model, in which the load can be represented by a combination of power (P), current(I), and impedance (Z).
The sign convention is: Positive to act as a load, negative to act as a generator.
Arguments:
name (str, “Load”): Name of the load
G (float, 0.0): Conductance in equivalent MW
B (float, 0.0): Susceptance in equivalent MVAr
Ir (float, 0.0): Real current in equivalent MW
Ii (float, 0.0): Imaginary current in equivalent MVAr
P (float, 0.0): Active power in MW
Q (float, 0.0): Reactive power in MVAr
G_prof (DataFrame, None): Pandas DataFrame with the conductance profile in equivalent MW
B_prof (DataFrame, None): Pandas DataFrame with the susceptance profile in equivalent MVAr
Ir_prof (DataFrame, None): Pandas DataFrame with the real current profile in equivalent MW
Ii_prof (DataFrame, None): Pandas DataFrame with the imaginary current profile in equivalent MVAr
P_prof (DataFrame, None): Pandas DataFrame with the active power profile in equivalent MW
Q_prof (DataFrame, None): Pandas DataFrame with the reactive power profile in equivalent MVAr
active (bool, True): Is the load active?
mttf (float, 0.0): Mean time to failure in hours
mttr (float, 0.0): Mean time to recovery in hours
-
copy
()¶
-
get_json_dict
(id, bus_dict)¶ Get json dictionary :param id: ID: Id for this object :param bus_dict: Dictionary of buses [object] -> ID :return:
-
-
class
GridCal.Engine.Devices.measurement.
Measurement
(value, uncertainty, mtype: GridCal.Engine.Devices.measurement.MeasurementType)¶ Bases:
object
-
class
GridCal.Engine.Devices.meta_devices.
DeviceType
¶ Bases:
enum.Enum
An enumeration.
-
BatteryDevice
= 'Battery'¶
-
BranchDevice
= 'Branch'¶
-
BusDevice
= 'Bus'¶
-
GeneratorDevice
= 'Generator'¶
-
LoadDevice
= 'Load'¶
-
SequenceLineDevice
= 'Sequence line'¶
-
ShuntDevice
= 'Shunt'¶
-
StaticGeneratorDevice
= 'Static Generator'¶
-
TowerDevice
= 'Tower'¶
-
TransformerTypeDevice
= 'Transformer type'¶
-
UnderGroundLineDevice
= 'Underground line'¶
-
WireDevice
= 'Wire'¶
-
-
class
GridCal.Engine.Devices.meta_devices.
EditableDevice
(name, active, device_type: GridCal.Engine.Devices.meta_devices.DeviceType, editable_headers: Dict[str, GridCal.Engine.Devices.meta_devices.GCProp], non_editable_attributes: List[str], properties_with_profile: Dict[str, Optional[Any]])¶ Bases:
object
-
create_profile
(magnitude, index, arr=None, arr_in_pu=False)¶ Create power profile based on index :param magnitude: name of the property :param index: pandas time index :param arr: array of values to set :param arr_in_pu: is the array in per-unit?
-
create_profiles
(index)¶ Create the load object default profiles Args: :param index: pandas time index
-
delete_profiles
()¶ Delete the object profiles (set all to None)
-
ensure_profiles_exist
(index)¶ It might be that when loading the GridCal Model has properties that the file has not. Those properties must be initialized as well :param index: Time series index (timestamps)
-
get_headers
() → List[AnyStr]¶ Return a list of headers
-
get_save_data
()¶ Return the data that matches the edit_headers :return:
-
resize_profiles
(index, time_frame: GridCal.Engine.Devices.meta_devices.TimeFrame)¶ Resize the profiles in this object :param index: pandas time index :param time_frame: Time frame to use (Short term, Long term)
-
set_profile_values
(t)¶ Set the profile values at t :param t: time index (integer)
-
-
class
GridCal.Engine.Devices.meta_devices.
GCProp
(units, tpe, definition, profile_name='')¶ Bases:
object
-
class
GridCal.Engine.Devices.sequence_line.
SequenceLineType
(name='SequenceLine', rating=1, R=0, X=0, G=0, B=0, R0=0, X0=0, G0=0, B0=0, tpe=<BranchType.Line: ('line', )>)¶
-
class
GridCal.Engine.Devices.shunt.
Shunt
(name='shunt', G=0.0, B=0.0, G_prof=None, B_prof=None, active=True, mttf=0.0, mttr=0.0)¶ Bases:
GridCal.Engine.Devices.meta_devices.EditableDevice
Arguments:
name (str, “shunt”): Name of the shunt
G (float, 0.0): Conductance in MW at 1 p.u. voltage
B (float, 0.0): Susceptance in MW at 1 p.u. voltage
G_prof (DataFrame, None): Pandas DataFrame with the conductance profile in MW at 1 p.u. voltage
B_prof (DataFrame, None): Pandas DataFrame with the susceptance profile in MW at 1 p.u. voltage
active (bool, True): Is the shunt active?
mttf (float, 0.0): Mean time to failure in hours
mttr (float, 0.0): Mean time to recovery in hours
-
copy
()¶ Copy of this object :return: a copy of this object
-
get_json_dict
(id, bus_dict)¶ Get json dictionary :param id: ID: Id for this object :param bus_dict: Dictionary of buses [object] -> ID :return:
-
-
class
GridCal.Engine.Devices.static_generator.
StaticGenerator
(name='StaticGen', P=0.0, Q=0.0, P_prof=None, Q_prof=None, active=True, mttf=0.0, mttr=0.0)¶ Bases:
GridCal.Engine.Devices.meta_devices.EditableDevice
Arguments:
name (str, “StaticGen”): Name of the static generator
P (float, 0.0): Active power in MW
Q (float, 0.0): Reactive power in MVAr
P_prof (DataFrame, None): Pandas DataFrame with the active power profile in MW
Q_prof (DataFrame, None): Pandas DataFrame with the reactive power profile in MVAr
active (bool, True): Is the static generator active?
mttf (float, 0.0): Mean time to failure in hours
mttr (float, 0.0): Mean time to recovery in hours
-
copy
()¶ Deep copy of this object :return:
-
get_json_dict
(id, bus_dict)¶ Get json dictionary :param id: ID: Id for this object :param bus_dict: Dictionary of buses [object] -> ID :return:
-
-
class
GridCal.Engine.Devices.tower.
Tower
(parent=None, edit_callback=None, name='Tower', tpe=<BranchType.Branch: ('branch', )>)¶ Bases:
GridCal.Engine.Devices.meta_devices.EditableDevice
-
check
(logger=[])¶ Check that the wires configuration make sense :return:
-
compute
()¶ Compute the tower matrices :return:
-
compute_rating
()¶ Compute the sum of the wires max current in A :return: max current iof the tower in A
-
get_save_data
(dta_list=[])¶ store the tower data into dta_list in a SQL-like fashion to avoid 3D like structures :param dta_list: list to append the data to :return: nothing
-
get_save_headers
()¶ Return the tower header + wire header :return:
-
get_wire_properties
()¶ Get the wire properties in a list :return: list of properties (list of lists)
-
is_used
(wire)¶ Parameters: wire – Returns:
-
plot
(ax=None)¶ Plot wires position :param ax: Axis object
-
y_shunt
()¶ positive sequence shunt admittance in S per unit of length
-
z_series
()¶ positive sequence series impedance in Ohm per unit of length
-
-
GridCal.Engine.Devices.tower.
abc_2_seq
(mat)¶ Convert to sequence components Args:
mat:Returns:
-
GridCal.Engine.Devices.tower.
calc_y_matrix
(wires: list, f=50, rho=100)¶ Impedance matrix :param wires: list of wire objects :param f: system frequency (Hz) :param rho: earth resistivity :return: 4 by 4 impedance matrix where the order of the phases is: N, A, B, C
-
GridCal.Engine.Devices.tower.
calc_z_matrix
(wires: list, f=50, rho=100)¶ Impedance matrix :param wires: list of wire objects :param f: system frequency (Hz) :param rho: earth resistivity :return: 4 by 4 impedance matrix where the order of the phases is: N, A, B, C
-
GridCal.Engine.Devices.tower.
get_D_ij
(xi, yi, xj, yj)¶ Distance module between the wire i and the image of the wire j :param xi: x position of the wire i :param yi: y position of the wire i :param xj: x position of the wire j :param yj: y position of the wire j :return: Distance module between the wire i and the image of the wire j
-
GridCal.Engine.Devices.tower.
get_d_ij
(xi, yi, xj, yj)¶ Distance module between wires :param xi: x position of the wire i :param yi: y position of the wire i :param xj: x position of the wire j :param yj: y position of the wire j :return: distance module
-
GridCal.Engine.Devices.tower.
kron_reduction
(mat, keep, embed)¶ Perform the Kron reduction :param mat: primitive matrix :param keep: indices to keep :param embed: indices to remove / embed :return:
-
GridCal.Engine.Devices.tower.
wire_bundling
(phases_set, primitive, phases_vector)¶ Algorithm to bundle wires per phase :param phases_set: set of phases (list with unique occurrences of each phase values, i.e. [0, 1, 2, 3]) :param primitive: Primitive matrix to reduce by bundling wires :param phases_vector: Vector that contains the phase of each wire :return: reduced primitive matrix, corresponding phases
-
GridCal.Engine.Devices.tower.
z_ii
(r_i, x_i, h_i, gmr_i, f, rho)¶ Self impedance Formula 4.3 from ATP-EMTP theory book :param r_i: wire resistance :param x_i: wire reactance :param h_i: wire vertical position (m) :param gmr_i: wire geometric mean radius (m) :param f: system frequency (Hz) :param rho: earth resistivity (Ohm / m^3) :return: self impedance in Ohm / m
-
GridCal.Engine.Devices.tower.
z_ij
(x_i, x_j, h_i, h_j, d_ij, f, rho)¶ Mutual impedance Formula 4.4 from ATP-EMTP theory book :param x_i: wire i horizontal position (m) :param x_j: wire j horizontal position (m) :param h_i: wire i vertical position (m) :param h_j: wire j vertical position (m) :param d_ij: Distance module between the wires i and j :param f: system frequency (Hz) :param rho: earth resistivity (Ohm / m^3) :return: mutual impedance in Ohm / m
-
class
GridCal.Engine.Devices.transformer.
TransformerType
(hv_nominal_voltage=0, lv_nominal_voltage=0, nominal_power=0.001, copper_losses=0, iron_losses=0, no_load_current=0, short_circuit_voltage=0, gr_hv1=0.5, gx_hv1=0.5, name='TransformerType', tpe=<BranchType.Transformer: ('transformer', )>)¶ Bases:
GridCal.Engine.Devices.meta_devices.EditableDevice
Arguments:
hv_nominal_voltage (float, 0.0): Primary side nominal voltage in kV (tied to the Branch’s bus_from)
lv_nominal_voltage (float, 0.0): Secondary side nominal voltage in kV (tied to the Branch’s bus_to)
nominal_power (float, 0.0): Transformer nominal apparent power in MVA
copper_losses (float, 0.0): Copper losses in kW (also known as short circuit power)
iron_losses (float, 0.0): Iron losses in kW (also known as no-load power)
no_load_current (float, 0.0): No load current in %
short_circuit_voltage (float, 0.0): Short circuit voltage in %
gr_hv1 (float, 0.5): Resistive contribution to the primary side in per unit (at the Branch’s bus_from)
gx_hv1 (float, 0.5): Reactive contribution to the primary side in per unit (at the Branch’s bus_from)
name (str, “TransformerType”): Name of the type
tpe (BranchType, BranchType.Transformer): Device type enumeration
-
get_impedances
()¶ Compute the branch parameters of a transformer from the short circuit test values.
Returns:
zs (complex): Series impedance in per unit
zsh (complex): Shunt impedance in per unit
-
-
class
GridCal.Engine.Devices.underground_line.
UndergroundLineType
(name='UndergroundLine', rating=1, R=0, X=0, G=0, B=0, R0=0, X0=0, G0=0, B0=0)¶ Bases:
GridCal.Engine.Devices.meta_devices.EditableDevice
-
y_shunt
()¶ positive sequence shunt admittance in S per unit of length
-
z_series
()¶ positive sequence series impedance in Ohm per unit of length
-
-
class
GridCal.Engine.Devices.wire.
Wire
(name='', xpos=0, ypos=0, gmr=0.01, r=0.01, x=0.0, max_current=1, phase=0)¶ Bases:
GridCal.Engine.Devices.meta_devices.EditableDevice
-
copy
()¶ Copy of the wire :return:
-
-
class
GridCal.Engine.Devices.wire.
WiresCollection
(parent=None)¶ Bases:
PySide2.QtCore.QAbstractTableModel
-
add
(wire: GridCal.Engine.Devices.wire.Wire)¶ Add wire :param wire: :return:
-
columnCount
(self, parent:PySide2.QtCore.QModelIndex=Invalid(PySide2.QtCore.QModelIndex)) → int¶
-
data
(self, index:PySide2.QtCore.QModelIndex, role:int=PySide2.QtCore.Qt.ItemDataRole.DisplayRole) → typing.Any¶
-
delete
(index)¶ Delete wire :param index: :return:
-
flags
(self, index:PySide2.QtCore.QModelIndex) → PySide2.QtCore.Qt.ItemFlags¶
-
headerData
(self, section:int, orientation:PySide2.QtCore.Qt.Orientation, role:int=PySide2.QtCore.Qt.ItemDataRole.DisplayRole) → typing.Any¶
-
is_used
(name)¶ checks if the name is used
-
parent
(self) → PySide2.QtCore.QObject¶ parent(self, child:PySide2.QtCore.QModelIndex) -> PySide2.QtCore.QModelIndex
-
rowCount
(self, parent:PySide2.QtCore.QModelIndex=Invalid(PySide2.QtCore.QModelIndex)) → int¶
-
setData
(index, value, role=PySide2.QtCore.Qt.ItemDataRole.DisplayRole)¶ Set data by simple editor (whatever text) :param index: :param value: :param role:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Engine.IO.cim_parser.
ACLineSegment
(id, tpe)¶
-
class
GridCal.Engine.IO.cim_parser.
CIMCircuit
¶ Bases:
object
-
static
check_type
(xml, class_types, starter='<cim:', ender='</cim:')¶ Checks if we are starting an object of the predefined types :param xml: some text :param class_types: list of CIM types :param starter string to add prior to the class when opening an object :param ender string to add prior to a class when closing an object :return: start_recording, end_recording, the found type or None if no one was found
-
clear
()¶ Clear the circuit
-
find_references
(recognised={})¶ Replaces the references of the classes given :return:
-
parse_file
(file_name, classes_=None)¶ Parse CIM file and add all the recognised objects :param file_name: file name or path :return:
-
static
-
class
GridCal.Engine.IO.cim_parser.
CIMExport
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit)¶ Bases:
object
-
save
(file_name)¶ Save XML CIM version of a grid Args:
file_name: file path
-
-
class
GridCal.Engine.IO.cim_parser.
CIMImport
¶ Bases:
object
-
add_node_terminal_relation
(connectivity_node, terminal)¶ Add the relation between a Connectivity Node and a Terminal :param terminal: :param connectivity_node: :return:
-
any_in_dict
(dict, keys)¶
-
get_elements
(dict, keys)¶
-
load_cim_file
(equipment_file, topology_file=None)¶ Load CIM file :param equipment_file: Main CIM file :param topology_file: Secondary CIM file that may contain the terminals-connectivity node relations
-
try_properties
(dictionary, properties, defaults=None)¶ Parameters: - dictionary –
- properties –
Returns:
-
-
class
GridCal.Engine.IO.cim_parser.
ConformLoad
(id, tpe)¶
-
class
GridCal.Engine.IO.cim_parser.
GeneralContainer
(id, tpe, resources=[], class_replacements={})¶ Bases:
object
-
get_xml
(level=0)¶ Returns an XML representation of the object Args:
level:Returns:
-
merge
(other)¶ Merge the properties of this object with another :param other: GeneralContainer instance
-
parse_line
(line)¶ Parse xml line that eligibly belongs to this object :param line: xml text line
-
print
()¶
-
-
class
GridCal.Engine.IO.cim_parser.
PowerTransformer
(id, tpe)¶
-
class
GridCal.Engine.IO.cim_parser.
SynchronousMachine
(id, tpe)¶
-
class
GridCal.Engine.IO.cim_parser.
Winding
(id, tpe)¶
-
GridCal.Engine.IO.cim_parser.
index_find
(string, start, end)¶ version of substring that matches :param string: string :param start: string to start splitting :param end: string to end splitting :return: string between start and end
# This file is part of GridCal. # # GridCal is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # GridCal is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GridCal. If not, see <http://www.gnu.org/licenses/>.
-
GridCal.Engine.IO.dgs_parser.
data_to_grid_object
(data, pos_dict, codification='utf-8')¶ Turns the read data dictionary into a GridCal MultiCircuit object Args:
data: Dictionary of data read from a DGS file pos_dict: Dictionary of objects and their positions read from a DGS fileReturns: GridCal MultiCircuit object
-
GridCal.Engine.IO.dgs_parser.
dgs_to_circuit
(filename)¶
-
GridCal.Engine.IO.dgs_parser.
read_DGS
(filename)¶ Read a DigSilent Power Factory .dgs file and return a dictionary with the data Args:
filename: File name or path- Returns: Dictionary of data where the keys are the object types and the values
- are the data of the objects of the key object type
-
GridCal.Engine.IO.dpx_parser.
load_dpx
(file_name, contraction_factor=1000)¶ Read DPX file :param file_name: file name :return: MultiCircuit
-
GridCal.Engine.IO.dpx_parser.
read_dpx_data
(file_name)¶ Read the DPX file into a structured dictionary :param file_name: :return:
-
GridCal.Engine.IO.dpx_parser.
reformat
(val)¶ Pick string and give it format :param val: string value :return: int, float or string
-
GridCal.Engine.IO.dpx_parser.
repack
(data_structures, logger=[], verbose=False)¶ Pack the values as DataFrames with headers where available :param data_structures: Raw data structures :param logger: logger (inherited) :return:
-
GridCal.Engine.IO.excel_interface.
check_names
(names)¶ Check that the names are allowed :param names: :return:
-
GridCal.Engine.IO.excel_interface.
create_data_frames
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit)¶ Pack the circuit information into tables (DataFrames) :param circuit: MultiCircuit instance :return: dictionary of DataFrames
-
GridCal.Engine.IO.excel_interface.
get_allowed_sheets
(circuit=<GridCal.Engine.Core.multi_circuit.MultiCircuit object>)¶ Parameters: circuit – Returns:
-
GridCal.Engine.IO.excel_interface.
get_objects_dictionary
(circuit=<GridCal.Engine.Core.multi_circuit.MultiCircuit object>)¶ Parameters: circuit – Returns:
-
GridCal.Engine.IO.excel_interface.
interpret_excel_v3
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, data)¶ Interpret the file version 3 In this file version there are no complex numbers saved :param circuit: :param data: Dictionary with the excel file sheet labels and the corresponding DataFrame :return: Nothing, just applies the loaded data to this MultiCircuit instance
-
GridCal.Engine.IO.excel_interface.
interprete_excel_v2
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, data)¶ Interpret the file version 2 :param circuit: :param data: Dictionary with the excel file sheet labels and the corresponding DataFrame :return: Nothing, just applies the loaded data to this MultiCircuit instance
-
GridCal.Engine.IO.excel_interface.
load_from_xls
(filename)¶ Loads the excel file content to a dictionary for parsing the data
-
GridCal.Engine.IO.excel_interface.
save_excel
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, file_path)¶ Save the circuit information in excel format :param circuit: MultiCircuit instance :param file_path: path to the excel file :return: logger with information
-
class
GridCal.Engine.IO.file_handler.
FileOpen
(file_name)¶ Bases:
object
-
open
(text_func=None, progress_func=None)¶ Load GridCal compatible file :param text_func: pointer to function that prints the names :param progress_func: pointer to function that prints the progress 0~100 :return: logger with information
-
-
class
GridCal.Engine.IO.file_handler.
FileOpenThread
(file_name)¶ Bases:
PySide2.QtCore.QThread
-
cancel
()¶
-
done_signal
= <PySide2.QtCore.Signal object>¶
-
progress_signal
= <PySide2.QtCore.Signal object>¶
-
progress_text
= <PySide2.QtCore.Signal object>¶
-
run
()¶ run the file open procedure
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Engine.IO.file_handler.
FileSave
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, file_name, text_func=None, progress_func=None)¶ Bases:
object
-
save
()¶ Save the file in the corresponding format :return: logger with information
-
save_cim
()¶ Save the circuit information in CIM format :return: logger with information
-
save_excel
()¶ Save the circuit information in excel format :return: logger with information
-
save_json
()¶ Save the circuit information in json format :return:logger with information
-
save_zip
()¶ Save the circuit information in zip format :return: logger with information
-
-
class
GridCal.Engine.IO.file_handler.
FileSaveThread
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, file_name)¶ Bases:
PySide2.QtCore.QThread
-
cancel
()¶
-
done_signal
= <PySide2.QtCore.Signal object>¶
-
progress_signal
= <PySide2.QtCore.Signal object>¶
-
progress_text
= <PySide2.QtCore.Signal object>¶
-
run
()¶ run the file save procedure @return:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
GridCal.Engine.IO.h5_interface.
load_dict_from_hdf5
(filename)¶ Parameters: filename – Returns:
-
GridCal.Engine.IO.h5_interface.
open_h5
(file_path)¶
-
GridCal.Engine.IO.h5_interface.
recursively_load_dict_contents_from_group
(h5file, path)¶ Parameters: - h5file –
- path –
Returns:
-
GridCal.Engine.IO.h5_interface.
recursively_save_dict_contents_to_group
(h5file, path, dic)¶ Parameters: - h5file –
- path –
- dic –
Returns:
-
GridCal.Engine.IO.h5_interface.
save_dict_to_hdf5
(dic, filename)¶ Parameters: - dic –
- filename –
Returns:
-
GridCal.Engine.IO.h5_interface.
save_h5
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, file_path)¶ Save the circuit information in excel format :param circuit: MultiCircuit instance :param file_path: path to the excel file :return: logger with information
-
GridCal.Engine.IO.json_parser.
parse_json
(file_name)¶ Parse JSON file into Circuit :param file_name: :return: GridCal MultiCircuit
-
GridCal.Engine.IO.json_parser.
parse_json_data
(data)¶ Parse JSON structure into GridCal MultiCircuit :param data: JSON structure (list of dictionaries) :return: GridCal MultiCircuit
-
GridCal.Engine.IO.json_parser.
save_json_file
(file_path, circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit)¶ Save JSON file :param file_path: file path :param circuit: GridCal MultiCircuit element
-
GridCal.Engine.IO.matpower_branch_definitions.
branch_headers
= ['fbus', 'tbus', 'r', 'x', 'b', 'rateA', 'rateB', 'rateC', 'ratio', 'angle', 'status', 'angmin', 'angmax', 'Pf', 'Qf', 'Pt', 'Qt', 'Mu_Sf', 'Mu_St', 'Mu_AngMin', 'Mu_AngMax', 'Current', 'Loading', 'Losses', 'Original_index']¶ Defines constants for named column indices to dcline matrix.
Some examples of usage, after defining the constants using the line above, are:
ppc.dcline(4, c[‘BR_STATUS’]) = 0 take branch 4 out of serviceThe index, name and meaning of each column of the branch matrix is given below:
- columns 1-17 must be included in input matrix (in case file)
- 1 F_BUS f, “from” bus number 2 T_BUS t, “to” bus number 3 BR_STATUS initial branch status, 1 - in service, 0 - out of service 4 PF MW flow at “from” bus (“from” -> “to”) 5 PT MW flow at “to” bus (“from” -> “to”) 6 QF MVAr injection at “from” bus (“from” -> “to”) 7 QT MVAr injection at “to” bus (“from” -> “to”) 8 VF voltage setpoint at “from” bus (p.u.) 9 VT voltage setpoint at “to” bus (p.u.)
10 PMIN lower limit on PF (MW flow at “from” end) 11 PMAX upper limit on PF (MW flow at “from” end) 12 QMINF lower limit on MVAr injection at “from” bus 13 QMAXF upper limit on MVAr injection at “from” bus 14 QMINT lower limit on MVAr injection at “to” bus 15 QMAXT upper limit on MVAr injection at “to” bus 16 LOSS0 constant term of linear loss function (MW) 17 LOSS1 linear term of linear loss function (MW/MW)
(loss = LOSS0 + LOSS1 * PF)columns 18-23 are added to matrix after OPF solution they are typically not present in the input matrix
(assume OPF objective function has units, u)18 MU_PMIN Kuhn-Tucker multiplier on lower flow lim at “from” bus (u/MW) 19 MU_PMAX Kuhn-Tucker multiplier on upper flow lim at “from” bus (u/MW) 20 MU_QMINF Kuhn-Tucker multiplier on lower VAr lim at “from” bus (u/MVAr) 21 MU_QMAXF Kuhn-Tucker multiplier on upper VAr lim at “from” bus (u/MVAr) 22 MU_QMINT Kuhn-Tucker multiplier on lower VAr lim at “to” bus (u/MVAr) 23 MU_QMAXT Kuhn-Tucker multiplier on upper VAr lim at “to” bus (u/MVAr)
@see: L{toggle_dcline}
-
GridCal.Engine.IO.matpower_branch_definitions.
get_transformer_impedances
(HV_nominal_voltage, LV_nominal_voltage, Nominal_power, Copper_losses, Iron_losses, No_load_current, Short_circuit_voltage, GR_hv1, GX_hv1)¶ Compute the branch parameters of a transformer from the short circuit test values @param HV_nominal_voltage: High voltage side nominal voltage (kV) @param LV_nominal_voltage: Low voltage side nominal voltage (kV) @param Nominal_power: Transformer nominal power (MVA) @param Copper_losses: Copper losses (kW) @param Iron_losses: Iron Losses (kW) @param No_load_current: No load current (%) @param Short_circuit_voltage: Short circuit voltage (%) @param GR_hv1: @param GX_hv1: @return:
leakage_impedance: Series impedance magnetizing_impedance: Shunt impedance
-
GridCal.Engine.IO.matpower_bus_definitions.
bustypes
(bus, gen, storage, Sbus, storage_dispatch_mode=<StorageDispatchMode.no_dispatch: (0, )>)¶ Builds index lists of each type of bus (C{REF}, C{PV}, C{PQ}).
Generators with “out-of-service” status are treated as L{PQ} buses with zero generation (regardless of C{Pg}/C{Qg} values in gen). Expects C{bus} and C{gen} have been converted to use internal consecutive bus numbering.
@param bus: bus data @param gen: generator data @return: index lists of each bus type
@author: Ray Zimmerman (PSERC Cornell)
-
GridCal.Engine.IO.matpower_gen_definitions.
gen_headers
= ['bus', 'Pg', 'Qg', 'Qmax', 'Qmin', 'Vg', 'mBase', 'status', 'Pmax', 'Pmin', 'Pc1', 'Pc2', 'Qc1min', 'Qc1max', 'Qc2min', 'Qc2max', 'ramp_agc', 'ramp_10', 'ramp_30', 'ramp_q', 'apf', 'MU_PMAX', 'MU_PMIN', 'MU_QMAX', 'MU_QMIN', 'Dispatchable', 'Fix_power']¶ Defines constants for named column indices to gencost matrix.
Some examples of usage, after defining the constants using the line above, are:
start = gencost[3, STARTUP] # get startup cost of generator 4 gencost[2, [MODEL, NCOST:COST+2]] = [POLYNOMIAL, 2, 30, 0] # set the cost of generator 2 to a linear function COST = 30 * Pg
The index, name and meaning of each column of the gencost matrix is given below:
- columns 1-5
- C{MODEL} cost model, 1 - piecewise linear, 2 - polynomial
- C{STARTUP} startup cost in US dollars
- C{SHUTDOWN} shutdown cost in US dollars
4. C{NCOST} number of cost coefficients to follow for polynomial cost function, or number of data points for piecewise linear 5. C{COST} 1st column of cost parameters cost data defining total cost function For polynomial cost (highest order coeff first):
e.g. cn, ..., c1, c0
where the polynomial is C{c0 + c1*P + … + cn*P^n} For piecewise linear cost:
x0, y0, x1, y1, x2, y2, ...
where C{x0 < x1 < x2 < …} and the points C{(x0,y0), (x1,y1), (x2,y2), …} are the end- and break-points of the total cost function.
- additional constants, used to assign/compare values in the C{MODEL} column
- C{PW_LINEAR} piecewise linear generator cost model
- C{POLYNOMIAL} polynomial generator cost model
@author: Ray Zimmerman (PSERC Cornell) @author: Richard Lincoln
# This file is part of GridCal. # # GridCal is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # GridCal is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GridCal. If not, see <http://www.gnu.org/licenses/>.
-
GridCal.Engine.IO.matpower_parser.
find_between
(s, first, last)¶ Find sting between two sub-strings Args:
s: Main string first: first sub-string last: second sub-stringExample find_between(‘[Hello]’, ‘[‘, ‘]’) -> returns ‘Hello’ Returns:
String between the first and second sub-strings, if any was found otherwise returns an empty string
-
GridCal.Engine.IO.matpower_parser.
interpret_data_v1
(circuit, data)¶ Pass the loaded table-like data to the structures @param data: Data dictionary @return:
-
GridCal.Engine.IO.matpower_parser.
parse_matpower_file
(filename, export=False)¶ - Args:
- filename: export:
Returns:
-
GridCal.Engine.IO.matpower_parser.
parse_matpower_file_old
(filename, export=False)¶ Converts a MatPower file to GridCal basic dictionary @param filename: @return:
-
GridCal.Engine.IO.matpower_parser.
txt2mat
(txt, line_splitter=';', col_splitter='\t', to_float=True)¶ - Args:
- txt: line_splitter: col_splitter:
Returns:
-
class
GridCal.Engine.IO.psse_parser.
PSSeArea
(data, version, logger: list)¶ Bases:
object
-
class
GridCal.Engine.IO.psse_parser.
PSSeBranch
(data, version, logger: list)¶ Bases:
object
-
get_object
(psse_bus_dict, logger: list)¶ Return GridCal branch object Args:
psse_bus_dict: Dictionary that relates PSSe bus indices with GridCal Bus objects- Returns:
- Gridcal Branch object
-
-
class
GridCal.Engine.IO.psse_parser.
PSSeBus
(data, version, logger: list)¶ Bases:
object
-
class
GridCal.Engine.IO.psse_parser.
PSSeGenerator
(data, version, logger: list)¶ Bases:
object
-
get_object
(logger: list)¶ Return GridCal Load object Returns:
Gridcal Load object
-
-
class
GridCal.Engine.IO.psse_parser.
PSSeGrid
(data)¶ Bases:
object
-
BASFRQ
= None¶ Case Identification Data Bus Data Load Data Fixed Bus Shunt Data Generator Data Non-Transformer Branch Data Transformer Data Area Interchange Data Two-Terminal DC Transmission Line Data Voltage Source Converter (VSC) DC Transmission Line Data Transformer Impedance Correction Tables Multi-Terminal DC Transmission Line Data Multi-Section Line Grouping Data Zone Data Interarea Transfer Data Owner Data FACTS Device Data Switched Shunt Data GNE Device Data Induction Machine Data Q Record
-
IC
= None¶ Case Identification Data Bus Data Load Data Fixed Bus Shunt Data Generator Data Non-Transformer Branch Data Transformer Data Area Interchange Data Two-Terminal DC Transmission Line Data Voltage Source Converter (VSC) DC Transmission Line Data Transformer Impedance Correction Tables Multi-Terminal DC Transmission Line Data Multi-Section Line Grouping Data Zone Data Interarea Transfer Data Owner Data FACTS Device Data Switched Shunt Data GNE Device Data Induction Machine Data Q Record
-
NXFRAT
= None¶ Case Identification Data Bus Data Load Data Fixed Bus Shunt Data Generator Data Non-Transformer Branch Data Transformer Data Area Interchange Data Two-Terminal DC Transmission Line Data Voltage Source Converter (VSC) DC Transmission Line Data Transformer Impedance Correction Tables Multi-Terminal DC Transmission Line Data Multi-Section Line Grouping Data Zone Data Interarea Transfer Data Owner Data FACTS Device Data Switched Shunt Data GNE Device Data Induction Machine Data Q Record
-
REV
= None¶ Case Identification Data Bus Data Load Data Fixed Bus Shunt Data Generator Data Non-Transformer Branch Data Transformer Data Area Interchange Data Two-Terminal DC Transmission Line Data Voltage Source Converter (VSC) DC Transmission Line Data Transformer Impedance Correction Tables Multi-Terminal DC Transmission Line Data Multi-Section Line Grouping Data Zone Data Interarea Transfer Data Owner Data FACTS Device Data Switched Shunt Data GNE Device Data Induction Machine Data Q Record
-
SBASE
= None¶ Case Identification Data Bus Data Load Data Fixed Bus Shunt Data Generator Data Non-Transformer Branch Data Transformer Data Area Interchange Data Two-Terminal DC Transmission Line Data Voltage Source Converter (VSC) DC Transmission Line Data Transformer Impedance Correction Tables Multi-Terminal DC Transmission Line Data Multi-Section Line Grouping Data Zone Data Interarea Transfer Data Owner Data FACTS Device Data Switched Shunt Data GNE Device Data Induction Machine Data Q Record
-
XFRRAT
= None¶ Case Identification Data Bus Data Load Data Fixed Bus Shunt Data Generator Data Non-Transformer Branch Data Transformer Data Area Interchange Data Two-Terminal DC Transmission Line Data Voltage Source Converter (VSC) DC Transmission Line Data Transformer Impedance Correction Tables Multi-Terminal DC Transmission Line Data Multi-Section Line Grouping Data Zone Data Interarea Transfer Data Owner Data FACTS Device Data Switched Shunt Data GNE Device Data Induction Machine Data Q Record
-
get_circuit
(logger: list)¶ Return GridCal circuit Returns:
-
-
class
GridCal.Engine.IO.psse_parser.
PSSeInductionMachine
(data, version, logger: list)¶ Bases:
object
-
get_object
(logger: list)¶ Return GridCal Load object Returns:
Gridcal Load object
-
-
class
GridCal.Engine.IO.psse_parser.
PSSeLoad
(data, version, logger: list)¶ Bases:
object
-
get_object
(bus: GridCal.Engine.Devices.bus.Bus, logger: list)¶ Return GridCal Load object Returns:
Gridcal Load object
-
-
class
GridCal.Engine.IO.psse_parser.
PSSeParser
(file_name)¶ Bases:
object
-
parse_psse
() -> (<class 'GridCal.Engine.Core.multi_circuit.MultiCircuit'>, typing.List[typing.AnyStr])¶ - Parser implemented according to:
- POM section 4.1.1 Power Flow Raw Data File Contents (v.29)
- POM section 5.2.1 (v.33)
- POM section 5.2.1 (v.32)
Returns: MultiCircuit, List[str]
-
read_and_split
()¶ Read the text file and split it into sections :return:
-
-
class
GridCal.Engine.IO.psse_parser.
PSSeShunt
(data, version, logger: list)¶ Bases:
object
-
get_object
(bus: GridCal.Engine.Devices.bus.Bus, logger: list)¶ Return GridCal Load object Returns:
Gridcal Load object
-
-
class
GridCal.Engine.IO.psse_parser.
PSSeTransformer
(data, version, logger: list)¶ Bases:
object
-
NOMV2
= None¶ I,J,K,CKT,CW,CZ,CM,MAG1,MAG2,NMETR,’NAME’,STAT,O1,F1,…,O4,F4 R1-2,X1-2,SBASE1-2,R2-3,X2-3,SBASE2-3,R3-1,X3-1,SBASE3-1,VMSTAR,ANSTAR
WINDV1,NOMV1,ANG1,RATA1,RATB1,RATC1,COD,CONT,RMA,RMI,VMA,VMI,NTP,TAB,CR,CX
WINDV2,NOMV2,ANG2,RATA2,RATB2,RATC2
WINDV3,NOMV3,ANG3,RATA3,RATB3,RATC3
-
WINDV2
= None¶ I,J,K,CKT,CW,CZ,CM,MAG1,MAG2,NMETR,’NAME’,STAT,O1,F1,…,O4,F4 R1-2,X1-2,SBASE1-2,R2-3,X2-3,SBASE2-3,R3-1,X3-1,SBASE3-1,VMSTAR,ANSTAR
WINDV1,NOMV1,ANG1,RATA1,RATB1,RATC1,COD,CONT,RMA,RMI,VMA,VMI,NTP,TAB,CR,CX
WINDV2,NOMV2,ANG2,RATA2,RATB2,RATC2
WINDV3,NOMV3,ANG3,RATA3,RATB3,RATC3
-
get_object
(psse_bus_dict, logger: list)¶ Return GridCal branch object Args:
psse_bus_dict: Dictionary that relates PSSe bus indices with GridCal Bus objects- Returns:
- Gridcal Branch object
-
windings
= None¶ I,J,K,CKT,CW,CZ,CM,MAG1,MAG2,NMETR,’NAME’,STAT,O1,F1,…,O4,F4,VECGRP R1-2,X1-2,SBASE1-2,R2-3,X2-3,SBASE2-3,R3-1,X3-1,SBASE3-1,VMSTAR,ANSTAR WINDV1,NOMV1,ANG1,RATA1,RATB1,RATC1,COD1,CONT1,RMA1,RMI1,VMA1,VMI1,NTP1,TAB1,CR1,CX1,CNXA1 WINDV2,NOMV2,ANG2,RATA2,RATB2,RATC2,COD2,CONT2,RMA2,RMI2,VMA2,VMI2,NTP2,TAB2,CR2,CX2,CNXA2 WINDV3,NOMV3,ANG3,RATA3,RATB3,RATC3,COD3,CONT3,RMA3,RMI3,VMA3,VMI3,NTP3,TAB3,CR3,CX3,CNXA3
-
-
class
GridCal.Engine.IO.psse_parser.
PSSeTwoTerminalDCLine
(data, version, logger: list)¶ Bases:
object
-
get_object
(psse_bus_dict, logger: list)¶ GEt equivalent object :param psse_bus_dict: :param logger: :return:
-
-
class
GridCal.Engine.IO.psse_parser.
PSSeVscDCLine
(data, version, logger: list)¶ Bases:
object
-
get_object
(psse_bus_dict, logger: list)¶ GEt equivalent object :param psse_bus_dict: :param logger: :return:
-
-
class
GridCal.Engine.IO.psse_parser.
PSSeZone
(data, version, logger: list)¶ Bases:
object
-
GridCal.Engine.IO.psse_parser.
interpret_line
(line, splitter=', ')¶ Split text into arguments and parse each of them to an appropriate format (int, float or string) Args:
line: splitter:Returns: list of arguments
-
GridCal.Engine.IO.psse_parser.
process_raw_file
(root_folder, destination_folder, fname)¶ process a .raw file :param root_folder: folder :param fname: file name (in the folder) :return: nothing
-
GridCal.Engine.IO.sqlite_interface.
open_sqlite
(file_path)¶
-
GridCal.Engine.IO.sqlite_interface.
save_sqlite
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, file_path)¶ Save the circuit information in excel format :param circuit: MultiCircuit instance :param file_path: path to the excel file :return: logger with information
-
GridCal.Engine.IO.zip_interface.
open_data_frames_from_zip
(file_name_zip, text_func=None, progress_func=None)¶ Open the csv files from a zip file :param file_name_zip: name of the zip file :param text_func: pointer to function that prints the names :param progress_func: pointer to function that prints the progress 0~100 :return: list of DataFrames
-
GridCal.Engine.IO.zip_interface.
save_data_frames_to_zip
(dfs: Dict[str, pandas.core.frame.DataFrame], filename_zip='file.zip', text_func=None, progress_func=None)¶ Save a list of DataFrames to a zip file without saving to disk the csv files :param dfs: dictionary of pandas dataFrames {name: DataFrame} :param filename_zip: file name where to save all :param text_func: pointer to function that prints the names :param progress_func: pointer to function that prints the progress 0~100
Modified to fit GridCal’s purposes when using PySOT
-
class
GridCal.Engine.Replacements.poap_controller.
BaseWorkerThread
(controller)¶ Bases:
threading.Thread
Worker base class for use with the thread controller.
The BaseWorkerThread class has a run routine that actually handles the worker event loop, and a set of helper routines for dispatching messages into the worker event loop (usually from the controller) and dispatching messages to the controller (usually from the worker).
-
add_message
(message)¶ Send message to be executed at the controller.
-
add_worker
()¶ Add worker back to the work queue.
-
eval
(record)¶ Start evaluation.
- Args:
- record: Function evaluation record
-
finish_cancelled
(record)¶ Finish recording cancelled on a record and add ourselves back.
-
finish_killed
(record)¶ Finish recording killed on a record and add ourselves back.
-
finish_success
(record, value)¶ Finish successful work on a record and add ourselves back.
-
handle_eval
(record)¶ Process an eval request.
-
handle_kill
(record)¶ Process a kill request
-
handle_terminate
()¶ Handle any cleanup on a terminate request
-
kill
(record)¶ Send kill message to worker.
- Args:
- record: Function evaluation record
-
run
()¶ Run requests as long as we get them.
-
terminate
()¶ Send termination message to worker.
NB: if the worker is not running in a daemon thread, a call to the terminate method only returns after the the thread has terminated.
-
-
class
GridCal.Engine.Replacements.poap_controller.
BasicWorkerThread
(controller, objective)¶ Bases:
GridCal.Engine.Replacements.poap_controller.BaseWorkerThread
Basic worker for use with the thread controller.
The BasicWorkerThread calls a Python objective function when asked to do an evaluation. This is concurrent, but only results in parallelism if the objective function implementation itself allows parallelism (e.g. because it communicates with an external entity via a pipe, socket, or whatever).
-
handle_eval
(record)¶ Process an eval request.
-
-
class
GridCal.Engine.Replacements.poap_controller.
Controller
¶ Bases:
object
Base class for controller.
- Attributes:
- strategy: Strategy for choosing optimization actions. fevals: Database of function evaluations. feval_callbacks: List of callbacks to execute on new eval record term_callbacks: List of callbacks to execute on termination
-
add_feval_callback
(callback)¶ Add a callback for notification on new fevals.
-
add_term_callback
(callback)¶ Add a callback for cleanup on termination.
-
add_timer
(timeout, callback)¶ Add a task to be executed after a timeout (e.g. for monitoring).
- Args:
- timeout: Time to wait before execution callback: Function to call when timeout elapses
-
best_point
(merit=None, filter=None)¶ Return the best point in the database satisfying some criterion.
- Args:
- merit: Function to minimize (default is r.value) filter: Predicate to use for filtering candidates
- Returns:
- Record minimizing merit() and satisfying filter(); or None if nothing satisfies the filter
-
call_term_callbacks
()¶ Call termination callbacks.
-
can_work
()¶ Return whether we can currently perform work.
-
new_feval
(params, extra_args=None)¶ Add a function evaluation record to the database.
In addition to adding the record with status ‘pending’, we run the feval_callbacks on the new record.
- Args:
- params: Parameters to the objective function
- Returns:
- New EvalRecord object
-
ping
()¶ Tell controller to consult strategies when possible (if asynchronous)
-
remove_feval_callback
(callback)¶ Remove a callback from the feval callback list.
-
remove_term_callback
(callback)¶ Remove a callback from the term callback list.
-
class
GridCal.Engine.Replacements.poap_controller.
Monitor
(controller)¶ Bases:
object
Monitor events observed by a controller.
The monitor object provides hooks to monitor the progress of an optimization run by a controller. Users should inherit from Monitor and add custom version of the methods
on_new_feval(self, record) on_update(self, record) on_complete(self, record) on_kill(self, record) on_cancel(self, record) on_terminate(self)-
on_cancel
(record)¶ Handle record cancelled
-
on_complete
(record)¶ Handle feval completion
-
on_kill
(record)¶ Handle record killed
-
on_new_feval
(record)¶ Handle new function evaluation request.
-
on_terminate
()¶ Handle termination.
-
on_update
(record)¶ Handle feval update.
-
-
class
GridCal.Engine.Replacements.poap_controller.
ProcessWorkerThread
(controller)¶ Bases:
GridCal.Engine.Replacements.poap_controller.BaseWorkerThread
Subprocess worker for use with the thread controller.
The ProcessWorkerThread is meant for use as a base class. Implementations that inherit from ProcessWorkerThread should define a handle_eval method that sets the process field so that it can be interrupted if needed. This allows use of blocking communication primitives while at the same time allowing interruption.
-
kill
(record)¶ Send kill message.
-
terminate
()¶ Send termination message.
-
-
class
GridCal.Engine.Replacements.poap_controller.
ScriptedController
¶ Bases:
GridCal.Engine.Replacements.poap_controller.Controller
Run a test script of actions from the controller.
The ScriptedController is meant to test that a strategy adheres to an expected sequence of proposed actions in a given scenario.
- Attributes:
- strategy: Strategy for choosing optimization actions. fevals: Database of function evaluations
-
accept_eval
(args=None, pred=None, skip=False)¶ Assert next proposal is an eval, which we accept.
- Args:
- args: expected evaluation args (if not None) pred: test predicate to run on proposal (if not None) skip: if True, skip over all None proposals
- Returns:
- proposal record
-
accept_kill
(r=None, skip=False)¶ Assert next proposal is a kill, which we accept.
- Args:
- r: record to be killed. skip: if True, skip over all None proposals
-
accept_terminate
(skip=False)¶ Assert next proposal is a kill, which we accept.
- Args:
- skip: if True, skip over all None proposals
-
add_timer
(timeout, callback)¶ Add timer.
-
can_work
()¶ Return True if worker available.
-
check_eval
(proposal, args=None, pred=None)¶ Check whether a proposal is an expected eval proposal.
- Args:
- proposal: proposal to check args: expected evaluation args (if not None) pred: test predicate to run on proposal (if not None)
-
check_kill
(proposal, r=None)¶ Check whether a proposal is an expected kill proposal.
- Args:
- proposal: proposal to check r: record to be killed (or None if no check)
-
check_terminate
(proposal)¶ Check whether a proposal is an expected terminate proposal.
- Args:
- proposal: proposal to check
-
no_proposal
()¶ Assert that next proposed action is None.
-
proposal
(skip=False)¶ Return strategy proposal.
- Args:
- skip: if True, skip over all None proposals
-
reject_eval
(args=None, pred=None, skip=False)¶ Assert next proposal is an eval, which we reject.
- Args:
- args: expected evaluation args (if not None) pred: test predicate to run on proposal (if not None) skip: if True, skip over all None proposals
-
reject_kill
(r=None, skip=False)¶ Assert next proposal is a kill, which we reject.
- Args:
- r: record to be killed. skip: if True, skip over all None proposals
-
reject_terminate
(skip=False)¶ Assert next proposal is a terminate, which we reject.
- Args:
- skip: if True, skip over all None proposals
-
set_worker
(v)¶ Set worker availability status.
-
terminate
()¶ Terminate the script.
-
class
GridCal.Engine.Replacements.poap_controller.
SerialController
(objective, skip=False)¶ Bases:
GridCal.Engine.Replacements.poap_controller.Controller
Serial optimization controller.
- Attributes:
- strategy: Strategy for choosing optimization actions. objective: Objective function fevals: Database of function evaluations skip: if True, skip over “None” proposals
-
run
(merit=None, filter=None, reraise=True, stop_at=False, stop_value=0)¶ Run the optimization and return the best value.
- Args:
merit: Function to minimize (default is r.value) filter: Predicate to use for filtering candidates reraise: Flag indicating whether exceptions in the
objective function evaluations should be re-raised, terminating the optimization.- Returns:
- Record minimizing merit() and satisfying filter(); or None if nothing satisfies the filter
-
class
GridCal.Engine.Replacements.poap_controller.
SimTeamController
(objective, delay, workers)¶ Bases:
GridCal.Engine.Replacements.poap_controller.Controller
Simulated parallel optimization controller.
Run events in simulated time. If two events are scheduled at the same time, we prioritize by when the event was added to the queue.
- Attributes:
- strategy: Strategy for choosing optimization actions. objective: Objective function delay: Time delay function workers: Number of workers available fevals: Database of function evaluations time: Current simulated time time_events: Time-stamped event heap
-
add_timer
(timeout, event)¶ Add a task to be executed after a timeout (e.g. for monitoring).
- Args:
- timeout: Time to wait before execution callback: Function to call when timeout elapses
-
advance_time
()¶ Advance time to the next event.
-
can_work
()¶ Check if there are workers available.
-
kill_work
(proposal)¶ Submit a kill event.
-
run
(merit=None, filter=None)¶ Run the optimization and return the best value.
- Args:
- merit: Function to minimize (default is r.value) filter: Predicate to use for filtering candidates
- Returns:
- Record minimizing merit() and satisfying filter(); or None if nothing satisfies the filter
-
submit_work
(proposal)¶ Submit a work event.
-
class
GridCal.Engine.Replacements.poap_controller.
ThreadController
¶ Bases:
GridCal.Engine.Replacements.poap_controller.Controller
Thread-based optimization controller.
The optimizer dispatches work to a queue of workers. Each worker has methods of the form
worker.eval(record) worker.kill(record)These methods are asynchronous: they start a function evaluation or termination, but do not necessarily complete it. The worker must respond to eval requests, but may ignore kill requests. On eval requests, the worker should either attempt the evaluation or mark the record as killed. The worker sends status updates back to the controller in terms of lambdas (executed at the controller) that update the relevant record. When the worker becomes available again, it should use add_worker to add itself back to the queue.
- Attributes:
- strategy: Strategy for choosing optimization actions. fevals: Database of function evaluations workers: Queue of available worker threads messages: Queue of messages from workers
-
add_message
(message=None)¶ Queue up a message.
- Args:
- message: callback function with no arguments or None (default)
- if None, a dummy message is queued to ping the controller
-
add_timer
(timeout, callback)¶ Add a task to be executed after a timeout (e.g. for monitoring).
- Args:
- timeout: Time to wait before execution callback: Function to call when timeout elapses
-
add_worker
(worker)¶ Add a worker and queue a ‘wake-up’ message.
- Args:
- worker: a worker thread object
-
can_work
()¶ Claim we can work if a worker is available.
-
launch_worker
(worker, daemon=False)¶ Launch and take ownership of a new worker thread.
- Args:
worker: a worker thread object daemon: if True, the worker is launched in a daemon thread
(default is False)
-
ping
()¶ Tell controller to consult strategies when possible
-
run
(merit=None, filter=None)¶ Run the optimization and return the best value.
- Args:
- merit: Function to minimize (default is r.value) filter: Predicate to use for filtering candidates
- Returns:
- Record minimizing merit() and satisfying filter(); or None if nothing satisfies the filter
-
class
GridCal.Engine.Replacements.strategy.
AddArgStrategy
(strategy, extra_args=None)¶ Bases:
GridCal.Engine.Replacements.strategy.BaseStrategy
Add extra arguments to evaluation proposals.
Decorates evaluation proposals with extra arguments. These may reflect termination criteria, advice to workers about which of several methods to use, etc. The extra arguments can be static (via the extra_args attribute), or they may be returned from the get_extra_args function, which child classes can override. The strategy overwrites any existing list of extra arguments, so it is probably a mistake to compose strategies in a way that involves multiple objects of this type.
- Attributes:
- strategy: Parent strategy extra_args: Extra arguments to be added
-
add_extra_args
(record)¶ Add any extra arguments to an eval record.
- Args:
- record: Record to be decorated
-
on_reply_accept
(proposal)¶ Handle proposal acceptance.
-
propose_action
()¶
-
class
GridCal.Engine.Replacements.strategy.
BaseStrategy
¶ Bases:
object
Base strategy class.
The BaseStrategy class provides some support for the basic callback flow common to most strategies: handlers are called when an evaluation is accepted or rejected; and if an evaluation proposal is accepted, the record is decorated so that an on_update handler is called for subsequent updates.
Note that not all strategies follow this pattern – the only requirement for a strategy is that it implement propose_action.
-
decorate_proposal
(proposal)¶ Add a callback to an existing proposal (for nested strategies).
-
on_complete
(record)¶ Process completed record.
-
on_kill
(record)¶ Process killed or cancelled record.
-
on_kill_reply
(proposal)¶ Default handling of kill proposal.
-
on_kill_reply_accept
(proposal)¶ Handle proposal acceptance.
-
on_kill_reply_reject
(proposal)¶ Handle proposal rejection.
-
on_reply
(proposal)¶ Default handling of eval proposal.
-
on_reply_accept
(proposal)¶ Handle proposal acceptance.
-
on_reply_reject
(proposal)¶ Handle proposal rejection.
-
on_terminate_reply
(proposal)¶ Default handling of terminate proposal.
-
on_terminate_reply_accept
(proposal)¶ Handle proposal acceptance.
-
on_terminate_reply_reject
(proposal)¶ Handle proposal rejection.
-
on_update
(record)¶ Process update.
-
propose_eval
(*args)¶ Generate an eval proposal with a callback to on_reply.
-
propose_kill
(r)¶ Generate a kill proposal with a callback to on_reply_kill.
-
propose_terminate
()¶ Generate a terminate proposal with a callback to on_terminate.
-
-
class
GridCal.Engine.Replacements.strategy.
ChaosMonkeyStrategy
(controller, strategy, mtbf=1)¶ Bases:
object
Randomly kill running function evaluations.
The ChaosMonkeyStrategy kills function evaluations at random from among all active function evaluations. Attacks are associated with a Poisson process where the mean time between failures is specified at startup. Useful mostly for testing the resilience of strategies to premature termination of their evaluations. The controller may decide to ignore the proposed kill actions, in which case the monkey’s attacks are ultimately futile.
-
on_new_feval
(record)¶ On every feval, add a callback.
-
on_timer
()¶
-
on_update
(record)¶ On every completion, remove from list
-
propose_action
()¶
-
-
class
GridCal.Engine.Replacements.strategy.
CheckWorkerStrategy
(controller, strategy)¶ Bases:
object
Preemptively kill eval proposals when there are no workers.
A strategy like the fixed sampler is simple-minded, and will propose a function evaluation even if the controller has no workers available to carry it out. This wrapper strategy intercepts proposals from a wrapped strategy like the fixed sampler, and only submits evaluation proposals if workers are available.
-
propose_action
()¶ Generate filtered action proposal.
-
-
class
GridCal.Engine.Replacements.strategy.
CoroutineBatchStrategy
(coroutine, rvalue=<function CoroutineBatchStrategy.<lambda>>)¶ Bases:
GridCal.Engine.Replacements.strategy.BaseStrategy
Event-driven to synchronous parallel adapter using coroutines.
The coroutine strategy runs a synchronous parallel optimization algorithm in a Python coroutine, with which the strategy communicates via send/yield directives. The optimization coroutine yields batches of parameters (as lists) at which it would like function values; the strategy then requests the function evaluation and returns the records associated with those function evaluations when all have been completed.
NB: Within a given batch, function evaluations are attempted in the reverse of the order in which they are specified. This should make no difference for most things (the batch is not assumed to have any specific order), but it is significant for testing.
- Attributes:
- coroutine: Optimizer coroutine retry: Retry strategy for in-flight actions results: Completion records to be returned to the coroutine
-
on_complete
(record)¶ Return or re-request on completion or cancellation.
-
on_reply_accept
(proposal)¶ If proposal accepted, wait for result.
-
propose_action
()¶ If we have a pending request, propose it.
-
start_batch
(xs)¶ Start evaluation of a batch of points.
-
class
GridCal.Engine.Replacements.strategy.
CoroutineStrategy
(coroutine, rvalue=<function CoroutineStrategy.<lambda>>)¶ Bases:
GridCal.Engine.Replacements.strategy.BaseStrategy
Event-driven to serial adapter using coroutines.
The coroutine strategy runs a standard sequential optimization algorithm in a Python coroutine, with which the strategy communicates via send/yield directives. The optimization coroutine yields the parameters at which it would like function values; the strategy then requests the function evaluation and returns the value with a send command when it becomes available.
- Attributes:
- coroutine: Optimizer coroutine rvalue: Function to map records to values retry: Retry manager
-
on_complete
(record)¶ Return point to coroutine
-
propose_action
()¶ If we have a pending request, propose it.
-
class
GridCal.Engine.Replacements.strategy.
EvalRecord
(params, extra_args=None, status='pending')¶ Bases:
object
Represent progress of a function evaluation.
An evaluation record includes the evaluation point, status of the evaluation, and a list of callbacks. The status may be pending, running, killed (deliberately), cancelled (due to a crash or failure) or completed. Once the function evaluation is completed, the value is stored as an attribute in the evaluation record. Other information, such as gradients, Hessians, or function values used to compute constraints, may also be stored in the record.
The evaluation record callbacks are triggered on any relevant event, including not only status changes but also intermediate results. The nature of these intermediate results (lower bounds, initial estimates, etc) is somewhat application-dependent.
NB: Callbacks that handle record updates should be insensitive to order: it is important not to modify attributes that might be used by later callbacks (e.g. the proposal.accepted flag).
- Attributes:
- params: Evaluation point for the function status: Status of the evaluation (pending, running, killed, completed) value: Return value (if completed) callbacks: Functions to call on status updates
-
add_callback
(callback)¶ Add a callback for update events.
-
cancel
()¶ Change status to ‘cancelled’ and execute callbacks.
-
complete
(value)¶ Change status to ‘completed’ and execute callbacks.
-
is_cancelled
¶ Check whether evaluation was cancelled
-
is_completed
¶ Check for successful completion of evaluation
-
is_done
¶ Check whether the status indicates the evaluation is finished.
-
is_killed
¶ Check whether evaluation is killed
-
is_pending
¶ Check if status is pending.
-
is_running
¶ Check if status is running.
-
kill
()¶ Change status to ‘killed’ and execute callbacks.
-
remove_callback
(callback)¶ Remove a callback subscriber.
-
running
()¶ Change status to ‘running’ and execute callbacks.
-
status
¶
-
update
(**kwargs)¶ Update fields and execute callbacks.
-
update_dict
(dict)¶ Update fields and execute callbacks.
- Args:
- dict: Dictionary of attributes to set on the record
-
class
GridCal.Engine.Replacements.strategy.
FixedSampleStrategy
(points)¶ Bases:
GridCal.Engine.Replacements.strategy.BaseStrategy
Sample at a fixed set of points.
The fixed sampling strategy is appropriate for any non-adaptive sampling scheme. Since the strategy is non-adaptive, we can employ as many available workers as we have points to process. We keep trying any evaluation that fails, and suggest termination only when all evaluations are complete. The points in the experimental design can be provided as any iterable object (e.g. a list or a generator function). One can use a generator for an infinite sequence if the fixed sampling strategy is used in combination with a strategy that provides a termination criterion.
-
propose_action
()¶ Propose an action based on outstanding points.
-
-
class
GridCal.Engine.Replacements.strategy.
InputStrategy
(controller, strategy)¶ Bases:
GridCal.Engine.Replacements.strategy.BaseStrategy
Insert requests from the outside world (e.g. from a GUI).
-
eval
(params, retry=True)¶ Request a new function evaluation
-
kill
(record, retry=False)¶ Request a function evaluation be killed
-
propose_action
()¶
-
terminate
(retry=True)¶ Request termination of the optimization
-
-
class
GridCal.Engine.Replacements.strategy.
MaxEvalStrategy
(controller, max_counter)¶ Bases:
object
Recommend termination of the iteration after some number of evals.
Recommends termination after observing some number of completed function evaluations. We allow more than the requisite number of evaluations to be started, since there’s always the possibility that one of our outstanding evaluations won’t finish.
- Attributes:
- counter: Number of completed evals max_counter: Max number of evals
-
on_new_feval
(record)¶ On every feval, add a callback.
-
on_update
(record)¶ On every completion, increment the counter.
-
propose_action
()¶ Propose termination once the eval counter is high enough.
-
class
GridCal.Engine.Replacements.strategy.
MultiStartStrategy
(controller, strategies)¶ Bases:
object
Merge several strategies by taking the first valid eval proposal.
This strategy is similar to the SimpleMergedStrategy, except that we only terminate once all the worker strategies have voted to terminate.
- Attributes:
- controller: Controller object used to determine whether we can eval strategies: Prioritized list of strategies
-
propose_action
()¶ Go through strategies in order and choose the first valid action. Terminate iff all workers vote to terminate.
-
class
GridCal.Engine.Replacements.strategy.
PromiseStrategy
(rvalue=<function PromiseStrategy.<lambda>>, block=True)¶ Bases:
GridCal.Engine.Replacements.strategy.BaseStrategy
Provides a promise-based asynchronous evaluation interface.
A promise (aka a future) is a common concurrent programming abstraction. A caller requests an asynchronous evaluation, and the call returns immediately with a promise object. The caller can check the promise object to see if it has a value ready, or wait for the value to become ready. The callee can set the value when it is ready.
- Attributes:
- proposalq: Queue of proposed actions caused by optimizer. valueq: Queue of function values from proposed actions. rvalue: Function to extract return value from a record block: Flag whether to block on proposal pop
-
class
Promise
(valueq)¶ Bases:
object
Evaluation promise.
- Properties:
- value: Promised value. Block on read if not ready.
-
ready
()¶ Check whether the value is ready (at consumer)
-
value
¶ Wait on the value (at consumer)
-
blocking_eval
(*args)¶ Request a function evaluation and block until done.
-
blocking_evals
(xs)¶ Request a list of function evaluations.
-
on_complete
(record)¶ Send the value to the consumer via the promise.
-
on_kill
(record)¶ Re-submit the proposal with the same promise.
-
on_reply_accept
(proposal)¶ Make sure we copy over the promise to the feval record.
-
on_reply_reject
(proposal)¶ Re-submit the proposal with the same promise.
-
on_terminate
()¶ Throw an exception at the consumer if still running on termination
-
on_terminate_reply_reject
(proposal)¶ Re-submit the termination proposal.
-
promise_eval
(*args)¶ Request a function evaluation and return a promise object.
-
propose_action
()¶ Provide proposals from the queue.
-
terminate
()¶ Request termination.
-
class
GridCal.Engine.Replacements.strategy.
Proposal
(action, *args)¶ Bases:
object
Represent a proposed action.
We currently recognize three types of proposals: evaluation requests (“eval”), requests to stop an evaluation (“kill”), and requests to terminate the optimization (“terminate”). When an evaluation proposal is accepted, the controller adds an evaluation record to the proposal before notifying subscribers.
NB: Callbacks that handle proposal accept/reject should be insensitive to order: it is important not to modify attributes that might be used by later callbacks (e.g. the proposal.accepted flag).
- Attributes:
- action: String describing the action args: Tuple of arguments to pass to the action accepted: Flag set on accept/reject decision callbacks: Functions to call on accept/reject of action record: Evaluation record for accepted evaluation proposals
-
accept
()¶ Mark the action as accepted and execute callbacks.
-
add_callback
(callback)¶ Add a callback subscriber to the action.
-
copy
()¶ Make a copy of the proposal.
-
reject
()¶ Mark action as rejected and execute callbacks.
-
remove_callback
(callback)¶ Remove a callback subscriber.
-
class
GridCal.Engine.Replacements.strategy.
RetryStrategy
¶ Bases:
GridCal.Engine.Replacements.strategy.BaseStrategy
Retry strategy class.
The RetryStrategy class manages a queue of proposals to be retried, either because they were rejected or because they correspond to a function evaluation that was killed.
If a proposal is submitted to a retry strategy and it has already been marked with the .retry attribute, we do not attempt to manage retries, as another object is assumed to have taken responsibility for retrying the proposal on failure. This prevents us from having redundant retries.
When a proposal is submitted to the retry class, we make a copy (the proposal draft) for safe-keeping. If at any point it is necessary to resubmit, we submit the draft copy to the retry class. The draft will have any modifications or callbacks that were added before the proposal reached this strategy, and none of those that were added afterward (including those added afterward by the RetryStrategy itself). The intent is that retried proposals inserted into the strategy hierarchy at the place where they were recorded should require no special treatment to avoid adding multiple copies of callbacks (for example).
- Attributes:
- proposals: Queue of outstanding proposals num_eval_pending: Number of pending evaluations num_eval_running: Number of running evaluations num_eval_outstanding: Number of outstanding evaluations
-
empty
()¶ Check if the queue is empty
-
get
()¶ Pop a proposal from the queue.
-
num_eval_outstanding
¶ Number of outstanding function evaluations.
-
on_complete
(record)¶ Clean up after completed eval+retry
-
on_kill
(record)¶ Resubmit proposal for killed or cancelled eval+retry
-
on_kill_reply_reject
(proposal)¶ Resubmit rejected kill+retry proposal
-
on_reply_accept
(proposal)¶ Process accepted eval+retry proposal
-
on_reply_reject
(proposal)¶ Resubmit rejected eval+retry proposal
-
on_terminate_reply_reject
(proposal)¶ Resubmit rejected termination+retry proposal
-
put
(proposal)¶ Put a non-retry proposal in the queue.
-
rput
(proposal)¶ Put a retry proposal in the queue.
-
exception
GridCal.Engine.Replacements.strategy.
RunTerminatedException
¶ Bases:
Exception
-
class
GridCal.Engine.Replacements.strategy.
SimpleMergedStrategy
(controller, strategies)¶ Bases:
object
Merge several strategies by taking the first valid proposal from them.
The simplest combination strategy is to keep a list of several possible strategies in some priority order, query them for proposals in priority order, and pass on the first plausible proposal to the controller.
- Attributes:
- controller: Controller object used to determine whether we can eval strategies: Prioritized list of strategies
-
propose_action
()¶ Go through strategies in order and choose the first valid action.
-
class
GridCal.Engine.Replacements.strategy.
ThreadStrategy
(controller, optimizer, rvalue=<function ThreadStrategy.<lambda>>)¶ Bases:
GridCal.Engine.Replacements.strategy.PromiseStrategy
Event-driven to serial adapter using threads.
The thread strategy runs a standard sequential optimization algorithm in a separate thread of control, with which the strategy communicates via promises. The optimizer thread intercepts function evaluation requests and completion and turns them into proposals for the strategy, which it places in a proposal queue. The optimizer then waits for the requested values (if any) to appear in the reply queue.
- Attributes:
- optimizer: Optimizer function (takes objective as an argument) proposalq: Queue of proposed actions caused by optimizer. valueq: Queue of function values from proposed actions. thread: Thread in which the optimizer runs. proposal: Proposal that the strategy is currently requesting. rvalue: Function mapping records to values
-
class
OptimizerThread
(strategy, optimizer)¶ Bases:
threading.Thread
-
run
()¶ Method representing the thread’s activity.
You may override this method in a subclass. The standard run() method invokes the callable object passed to the object’s constructor as the target argument, if any, with sequential and keyword arguments taken from the args and kwargs arguments, respectively.
-
-
on_terminate
()¶ Throw an exception at the consumer if still running on termination
-
class
GridCal.Engine.Replacements.tcpserve.
ProcessSocketWorker
(sockname, retries=0)¶ Bases:
GridCal.Engine.Replacements.tcpserve.SocketWorker
Socket worker that runs an evaluation in a subprocess
The ProcessSocketWorker is a base class for simulations that run a simulation in an external subprocess. This class provides functionality just to allow graceful termination of the external simulations.
- Attributes:
- process: Handle for external subprocess
-
kill
(record_id)¶ Kill a function evaluation
-
kill_process
()¶ Kill the child process
-
terminate
()¶ Terminate the worker
-
class
GridCal.Engine.Replacements.tcpserve.
SimpleSocketWorker
(objective, sockname, retries=0)¶ Bases:
GridCal.Engine.Replacements.tcpserve.SocketWorker
Simple socket worker that runs a local objective function
The SimpleSocketWorker is a socket worker that runs a local Python function and returns the result. It is probably mostly useful for testing – the ProcessSocketWorker is a better option for external simulations.
-
eval
(record_id, params)¶ Evaluate the function and send back a result.
If the function evaluation crashes, we send back a ‘cancel’ request for the record. If, on the other hand, there is a problem with calling send, we probably want to let the worker error out.
- Args:
- record_id: Feval record identifier used by server/controller params: Parameters sent to the function to be evaluated
-
-
class
GridCal.Engine.Replacements.tcpserve.
SocketWorker
(sockname, retries=0)¶ Bases:
object
Base class for workers that connect to SocketServer interface
The socket server interface is a server to which workers can connect. The socket worker is the client to that interface. It connects to a given TCP/IP port, then attempts to do work on the controller’s behalf.
- Attributes:
- running: True if the socket is active sock: Worker TCP socket
-
eval
(record_id, params)¶ Compute a function value
-
kill
(record_id)¶ Kill a function evaluation
-
marshall
(*args)¶ Marshall data to wire format
-
run
(loop=True)¶ Main loop
-
send
(*args)¶ Send a message to the controller
-
terminate
()¶ Terminate the worker
-
unmarshall
(data)¶ Convert data from wire format back to Python tuple
-
class
GridCal.Engine.Replacements.tcpserve.
SocketWorkerHandler
(request, client_address, server)¶ Bases:
socketserver.BaseRequestHandler
Manage a remote worker for a thread controller.
The SocketWorkerHandler is a request handler for incoming workers. It implements the socketserver request handler interface, and also the worker interface expected by the ThreadController.
-
eval
(record)¶ Send an evaluation request to remote worker
-
handle
()¶ Main event loop called from SocketServer
-
kill
(record)¶ Send a kill request to a remote worker
-
terminate
()¶ Send a termination request to a remote worker
-
-
class
GridCal.Engine.Replacements.tcpserve.
ThreadedTCPServer
(sockname=('localhost', 0), strategy=None, handlers={})¶ Bases:
socketserver.ThreadingMixIn
,socketserver.TCPServer
,object
SocketServer interface for workers to connect to controller.
The socket server interface lets workers connect to a given TCP/IP port and exchange updates with the controller.
The server sends messages of the form
(‘eval’, record_id, args, extra_args) (‘eval’, record_id, args) (‘kill’, record_id) (‘terminate’)The default messages received are
(‘running’, record_id) (‘kill’, record_id) (‘cancel’, record_id) (‘complete’, record_id, value)The set of handlers can also be extended with a dictionary of named callbacks to be invoked whenever a record update comes in. For example, to set a lower bound field, we might use the handler
- def set_lb(rec, value):
- rec.lb = value
handlers = {‘lb’ : set_lb }
This is useful for adding new types of updates without mucking around in the EvalRecord implementation.
- Attributes:
- controller: ThreadController that manages the optimization handlers: dictionary of specialized message handlers strategy: redirects to the controller strategy
-
marshall
(*args)¶ Convert an argument list to wire format.
-
run
(merit=<function ThreadedTCPServer.<lambda>>, filter=None)¶
-
sockname
¶
-
strategy
¶
-
unmarshall
(data)¶ Convert wire format back to Python arg list.
-
class
GridCal.Engine.Simulations.ContinuationPowerFlow.continuation_power_flow.
VCParametrization
¶ Bases:
enum.Enum
An enumeration.
-
ArcLength
= 'Arc Length'¶
-
Natural
= 'Natural'¶
-
PseudoArcLength
= 'Pseudo Arc Length'¶
-
-
class
GridCal.Engine.Simulations.ContinuationPowerFlow.continuation_power_flow.
VCStopAt
¶ Bases:
enum.Enum
An enumeration.
-
Full
= 'Full curve'¶
-
Nose
= 'Nose'¶
-
-
GridCal.Engine.Simulations.ContinuationPowerFlow.continuation_power_flow.
continuation_nr
(Ybus, Ibus_base, Ibus_target, Sbus_base, Sbus_target, V, pv, pq, step, approximation_order: GridCal.Engine.Simulations.ContinuationPowerFlow.continuation_power_flow.VCParametrization, adapt_step, step_min, step_max, error_tol=0.001, tol=1e-06, max_it=20, stop_at=<VCStopAt.Nose: 'Nose'>, verbose=False, call_back_fx=None)¶ Runs a full AC continuation power flow using a normalized tangent predictor and selected approximation_order scheme. :param Ybus: Admittance matrix :param Ibus_base: :param Ibus_target: :param Sbus_base: Power array of the base solvable case :param Sbus_target: Power array of the case to be solved :param V: Voltage array of the base solved case :param pv: Array of pv indices :param pq: Array of pq indices :param step: Adaptation step :param approximation_order: order of the approximation {Natural, Arc, Pseudo arc} :param adapt_step: use adaptive step size? :param step_min: minimum step size :param step_max: maximum step size :param error_tol: Error tolerance :param tol: Solutions tolerance :param max_it: Maximum iterations :param stop_at: Value of Lambda to stop at. It can be a number or {‘NOSE’, ‘FULL’} :param verbose: Display additional intermediate information? :param call_back_fx: Function to call on every iteration passing the lambda parameter :return: Voltage_series: List of all the voltage solutions from the base to the target
Lambda_series: Lambda values used in the continuation- Ported from MATPOWER
Copyright (c) 1996-2015 by Power System Engineering Research Center (PSERC) by Ray Zimmerman, PSERC Cornell, Shrirang Abhyankar, Argonne National Laboratory, and Alexander Flueck, IIT
$Id: runcpf.m 2644 2015-03-11 19:34:22Z ray $
This file is part of MATPOWER. Covered by the 3-clause BSD License (see LICENSE file for details). See http://www.pserc.cornell.edu/matpower/ for more info.
-
GridCal.Engine.Simulations.ContinuationPowerFlow.continuation_power_flow.
corrector
(Ybus, Ibus, Sbus, V0, pv, pq, lam0, Sxfr, Vprv, lamprv, z, step, parametrization, tol, max_it, verbose)¶ Solves the corrector step of a continuation power flow using a full Newton method with selected parametrization scheme.
solves for bus voltages and lambda given the full system admittance matrix (for all buses), the complex bus power injection vector (for all buses), the initial vector of complex bus voltages, and column vectors with the lists of bus indices for the swing bus, PV buses, and PQ buses, respectively. The bus voltage vector contains the set point for generator (including ref bus) buses, and the reference angle of the swing bus, as well as an initial guess for remaining magnitudes and angles.
Uses default options if this parameter is not given. Returns the final complex voltages, a flag which indicates whether it converged or not, the number of iterations performed, and the final lambda.Parameters: - Ybus – Admittance matrix (CSC sparse)
- Ibus – Bus current injections
- Sbus – Bus power injections
- V0 – Bus initial voltages
- pv – list of pv nodes
- pq – list of pq nodes
- lam0 – initial value of lambda (loading parameter)
- Sxfr – [delP+j*delQ] transfer/loading vector for all buses
- Vprv – final complex V corrector solution from previous continuation step
- lamprv – final lambda corrector solution from previous continuation step
- z – normalized predictor for all buses
- step – continuation step size
- parametrization –
- tol –
- max_it –
- verbose –
Returns: V, CONVERGED, I, LAM
-
GridCal.Engine.Simulations.ContinuationPowerFlow.continuation_power_flow.
corrector_new
(Ybus, Ibus, Sbus, V0, pv, pq, lam0, Sxfr, Vprv, lamprv, z, step, parametrization, tol, max_it, verbose, max_it_internal=10)¶ Solves the corrector step of a continuation power flow using a full Newton method with selected parametrization scheme.
solves for bus voltages and lambda given the full system admittance matrix (for all buses), the complex bus power injection vector (for all buses), the initial vector of complex bus voltages, and column vectors with the lists of bus indices for the swing bus, PV buses, and PQ buses, respectively. The bus voltage vector contains the set point for generator (including ref bus) buses, and the reference angle of the swing bus, as well as an initial guess for remaining magnitudes and angles.
Uses default options if this parameter is not given. Returns the final complex voltages, a flag which indicates whether it converged or not, the number of iterations performed, and the final lambda.Parameters: - Ybus – Admittance matrix (CSC sparse)
- Ibus – Bus current injections
- Sbus – Bus power injections
- V0 – Bus initial voltages
- pv – list of pv nodes
- pq – list of pq nodes
- lam0 – initial value of lambda (loading parameter)
- Sxfr – [delP+j*delQ] transfer/loading vector for all buses
- Vprv – final complex V corrector solution from previous continuation step
- lamprv – final lambda corrector solution from previous continuation step
- z – normalized predictor for all buses
- step – continuation step size
- parametrization –
- tol –
- max_it –
- verbose –
Returns: V, CONVERGED, I, LAM
-
GridCal.Engine.Simulations.ContinuationPowerFlow.continuation_power_flow.
cpf_p
(parametrization: GridCal.Engine.Simulations.ContinuationPowerFlow.continuation_power_flow.VCParametrization, step, z, V, lam, V_prev, lamprv, pv, pq, pvpq)¶ Computes the value of the Current Parametrization Function :param parametrization: Value of option (1: Natural, 2:Arc-length, 3: pseudo arc-length) :param step: continuation step size :param z: normalized tangent prediction vector from previous step :param V: complex bus voltage vector at current solution :param lam: scalar lambda value at current solution :param V_prev: complex bus voltage vector at previous solution :param lamprv: scalar lambda value at previous solution :param pv: vector of indices of PV buses :param pq: vector of indices of PQ buses :param pvpq: vector of indices of PQ and PV buses :return: value of the parametrization function at the current point
-
GridCal.Engine.Simulations.ContinuationPowerFlow.continuation_power_flow.
cpf_p_jac
(parametrization: GridCal.Engine.Simulations.ContinuationPowerFlow.continuation_power_flow.VCParametrization, z, V, lam, Vprv, lamprv, pv, pq, pvpq)¶ Computes partial derivatives of Current Parametrization Function (CPF). :param parametrization: :param z: normalized tangent prediction vector from previous step :param V: complex bus voltage vector at current solution :param lam: scalar lambda value at current solution :param Vprv: complex bus voltage vector at previous solution :param lamprv: scalar lambda value at previous solution :param pv: vector of indices of PV buses :param pq: vector of indices of PQ buses :param pvpq: vector of indices of PQ and PV buses :return: partial of parametrization function w.r.t. voltages
partial of parametrization function w.r.t. lambda
-
GridCal.Engine.Simulations.ContinuationPowerFlow.continuation_power_flow.
predictor
(V, Ibus, lam, Ybus, Sxfr, pv, pq, step, z, Vprv, lamprv, parametrization: GridCal.Engine.Simulations.ContinuationPowerFlow.continuation_power_flow.VCParametrization)¶ Computes a prediction (approximation) to the next solution of the continuation power flow using a normalized tangent predictor. :param V: complex bus voltage vector at current solution :param Ibus: :param lam: scalar lambda value at current solution :param Ybus: complex bus admittance matrix :param Sxfr: complex vector of scheduled transfers (difference between bus injections in base and target cases) :param pv: vector of indices of PV buses :param pq: vector of indices of PQ buses :param step: continuation step length :param z: normalized tangent prediction vector from previous step :param Vprv: complex bus voltage vector at previous solution :param lamprv: scalar lambda value at previous solution :param parametrization: Value of cpf parametrization option. :return: V0 : predicted complex bus voltage vector
LAM0 : predicted lambda continuation parameter Z : the normalized tangent prediction vector
-
class
GridCal.Engine.Simulations.ContinuationPowerFlow.voltage_collapse_driver.
VoltageCollapse
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, options: GridCal.Engine.Simulations.ContinuationPowerFlow.voltage_collapse_driver.VoltageCollapseOptions, inputs: GridCal.Engine.Simulations.ContinuationPowerFlow.voltage_collapse_driver.VoltageCollapseInput)¶ Bases:
PySide2.QtCore.QThread
-
cancel
()¶
-
done_signal
= <PySide2.QtCore.Signal object>¶
-
get_steps
()¶ List of steps
-
progress_callback
(l)¶ Send progress report :param l: lambda value :return: None
-
progress_signal
= <PySide2.QtCore.Signal object>¶
-
progress_text
= <PySide2.QtCore.Signal object>¶
-
run
()¶ run the voltage collapse simulation @return:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Engine.Simulations.ContinuationPowerFlow.voltage_collapse_driver.
VoltageCollapseInput
(Sbase, Vbase, Starget)¶ Bases:
object
-
class
GridCal.Engine.Simulations.ContinuationPowerFlow.voltage_collapse_driver.
VoltageCollapseOptions
(step=0.01, approximation_order=<VCParametrization.Natural: 'Natural'>, adapt_step=True, step_min=0.0001, step_max=0.2, error_tol=0.001, tol=1e-06, max_it=20, stop_at=<VCStopAt.Nose: 'Nose'>, verbose=False)¶ Bases:
object
-
class
GridCal.Engine.Simulations.ContinuationPowerFlow.voltage_collapse_driver.
VoltageCollapseResults
(nbus, nbr)¶ Bases:
object
-
apply_from_island
(voltage_collapse_res, pf_res: GridCal.Engine.Simulations.PowerFlow.power_flow_results.PowerFlowResults, bus_original_idx, branch_original_idx, nbus_full)¶ Apply the results of an island to this VoltageCollapseResults instance :param voltage_collapse_res: VoltageCollapseResults instance of the island :param pf_res: Power flow results instance :param bus_original_idx: indices of the buses in the complete grid :param branch_original_idx: indices of the branches in the complete grid :param nbus_full: total number of buses in the complete grid
-
get_results_dict
()¶ Returns a dictionary with the results sorted in a dictionary :return: dictionary of 2D numpy arrays (probably of complex numbers)
-
plot
(result_type=<ResultTypes.BusVoltage: ('Bus voltage', <DeviceType.BusDevice: 'Bus'>)>, ax=None, indices=None, names=None)¶ Plot the results :param result_type: :param ax: :param indices: :param names: :return:
-
save
(fname)¶ Export as pickle
-
-
class
GridCal.Engine.Simulations.Dynamics.dynamic_modules.
DiffEqSolver
¶ Bases:
enum.Enum
An enumeration.
-
EULER
= (1,)¶
-
RUNGE_KUTTA
= 2¶
-
-
class
GridCal.Engine.Simulations.Dynamics.dynamic_modules.
DoubleCageAsynchronousMotor
(H, Rr, Xr, Rs, Xs, a, Xm, Rr2, Xr2, MVA_Rating, Sbase, bus_idx, fn=50)¶ Bases:
object
Double Cage Asynchronous Machine Model
Model equations based on section 15.2.5 of: Milano, F., “Power System Modelling and Scripting”, Springer-Verlag, 2010
-
calc_currents
(vt)¶ Calculate machine current injections (in network reference frame)
-
calc_tmech
(s)¶ Calculate mechanical load torque (with a quadratic load model)
-
check_diffs
()¶ Check if differential equations are zero (on initialisation)
-
get_yg
()¶ Get the generator admittance :return: shunt admittance
-
initialise
(vt0, S0)¶ Initialise machine signals and states based on load flow voltage and complex power injection NOTE: currently only initialised at standstill
-
solve_step
(Edp, Eqp, Edpp, Eqpp)¶ Solve machine differential equations for the next stage in the integration step
-
-
class
GridCal.Engine.Simulations.Dynamics.dynamic_modules.
DynamicModels
¶ Bases:
enum.Enum
An enumeration.
-
AsynchronousDoubleCageMotor
= 6¶
-
AsynchronousSingleCageMotor
= (5,)¶
-
ExternalGrid
= (4,)¶
-
NoModel
= (0,)¶
-
SynchronousGeneratorOrder4
= (1,)¶
-
SynchronousGeneratorOrder6
= (2,)¶
-
VoltageSourceConverter
= (3,)¶
-
-
class
GridCal.Engine.Simulations.Dynamics.dynamic_modules.
ExternalGrid
(Xdp, H, fn, bus_idx)¶ Bases:
object
External Grid Model Class Grid is modelled as a constant voltage behind a transient reactance and two differential equations representing the swing equations.
-
calc_currents
(vt)¶ Solve grid current injections (in network reference frame)
-
function
(Eqp, Edp, omega)¶ Solve machine differential equations for the next stage in the integration step
-
get_yg
()¶ Return the shunt admittance Returns:
-
initialise
(vt0, S0)¶ Initialise grid emf based on load flow voltage and grid current injection
-
-
class
GridCal.Engine.Simulations.Dynamics.dynamic_modules.
SingleCageAsynchronousMotor
(H, Rr, Xr, Rs, Xs, a, Xm, MVA_Rating, Sbase, bus_idx, fn=50)¶ Bases:
object
Single Cage Asynchronous Motor Model
Model equations based on section 15.2.4 of: Milano, F., “Power System Modelling and Scripting”, Springer-Verlag, 2010
-
calc_currents
(vt)¶ Calculate machine current injections (in network reference frame)
-
calc_tmech
(s)¶ Calculate mechanical load torque (with a quadratic load model) :param s: slip :return:
-
check_diffs
()¶ Check if differential equations are zero (on initialisation)
-
function
(Edp, Eqp)¶ Solve machine differential equations for the next stage in the integration step
-
get_yg
()¶ Get the generator admittance :return: shunt admittance
-
initialise
(vt0, S0)¶ Initialise machine signals and states based on load flow voltage and complex power injection NOTE: currently only initialised at standstill
-
-
class
GridCal.Engine.Simulations.Dynamics.dynamic_modules.
SynchronousMachineOrder4
(H, Ra, Xd, Xdp, Xdpp, Xq, Xqp, Xqpp, Td0p, Tq0p, base_mva, Sbase, bus_idx, fn=50, speed_volt=False, solver=<DiffEqSolver.RUNGE_KUTTA: 2>)¶ Bases:
object
4th Order Synchronous Machine Model https://wiki.openelectrical.org/index.php?title=Synchronous_Machine_Models#4th_Order_.28Two-Axis.29_Model Copyright (C) 2014-2015 Julius Susanto. All rights reserved.
typical values: Ra = 0.0 Xa = 0.0 Xd = 1.68 Xq = 1.61 Xdp = 0.32 Xqp = 0.32 Xdpp = 0.2 Xqpp = 0.2 Td0p = 5.5 Tq0p = 4.60375 Td0pp = 0.0575 Tq0pp = 0.0575 H = 2
-
calc_currents
(Vbus, Ibus)¶ Calculate machine current injections (in network reference frame) :param vt: complex initial voltage :return:
-
check_diffs
()¶ Check if differential equations are zero (on initialisation)
-
function
(h, Eqp, Edp, omega)¶ Compute the magnitude’s derivatives :param Eqp: :param Edp: :param omega: :return:
-
get_yg
()¶ Get the generator admittance :return: shunt admittance
-
initialise
(vt0, S0)¶ Initialise machine signals and states based on load flow voltage and complex power injection :param vt0: complex initial voltage :param S0: complex initial power :return:
-
solve
(h)¶ Solve using Runge-Kutta Args:
h: step sizeReturns: self.Eqp, self.Edp, self.omega, self.delta
-
-
class
GridCal.Engine.Simulations.Dynamics.dynamic_modules.
SynchronousMachineOrder6SauerPai
(H, Ra, Xa, Xd, Xdp, Xdpp, Xq, Xqp, Xqpp, Td0p, Tq0p, Td0pp, Tq0pp, base_mva, Sbase, bus_idx, fn=50, speed_volt=False)¶ Bases:
object
PYPOWER-Dynamics 6th Order Synchronous Machine Model Based on Sauer-Pai model Sauer, P.W., Pai, M. A., “Power System Dynamics and Stability”, Stipes Publishing, 2006
-
calc_currents
(vt)¶ Calculate machine current injections (in network reference frame)
-
check_diffs
()¶ Check if differential equations are zero (on initialisation)
-
function
(Eqp, Edp, omega)¶ Solve machine differential equations for the next stage in the integration step :param Eqp: :param Edp: :param omega: :return:
-
get_yg
()¶ Get the generator admittance :return: shunt admittance
-
initialise
(vt0, S0)¶ Initialise machine signals and states based on load flow voltage and complex power injection
-
-
class
GridCal.Engine.Simulations.Dynamics.dynamic_modules.
TransientStabilityEvents
¶ Bases:
object
-
add
(t, evt_type, obj, param)¶ Add elements :param t: time in seconds :param evt_type: event type :param obj: object selected :param param: extra parameters
-
remove_at
(i)¶ Remove the elements at a position :param i: index
-
-
class
GridCal.Engine.Simulations.Dynamics.dynamic_modules.
TransientStabilityResults
¶ Bases:
object
-
plot
(result_type, ax=None, indices=None, names=None, LINEWIDTH=2)¶ Plot the results :param result_type: :param ax: :param indices: :param names: :return:
-
-
class
GridCal.Engine.Simulations.Dynamics.dynamic_modules.
VoltageSourceConverterAverage
(Rl, Xl, fn, bus_idx)¶ Bases:
object
Voltage Source Converter Model Class Average model of a VSC in voltage-control mode (i.e. controlled voltage source behind an impedance). Copyright (C) 2014-2015 Julius Susanto. All rights reserved.
-
calc_currents
(vt)¶ Solve grid current injections (in network reference frame) :param vt: complex voltage :return:
-
function
(h, d)¶ Solve machine differential equations for the next stage in the integration step :param h: solve step in seconds
-
get_yg
()¶ Get the generator admittance :return: shunt admittance
-
initialise
(vt0, S0)¶ Initialise converter emf based on load flow voltage and grid current injection :param vt0: complex voltage :param S0: complex power
-
-
GridCal.Engine.Simulations.Dynamics.dynamic_modules.
dynamic_simulation
(n, Vbus, Sbus, Ybus, Sbase, fBase, t_sim, h, dynamic_devices=[], bus_indices=[], callback=None)¶ Dynamic transient simulation of a power system Args:
n: number of nodes Vbus: Ybus: Sbase: fBase: base frequency i.e. 50Hz t_sim: h: dynamic_devices: objects of each machine bus_indices:Returns:
-
class
GridCal.Engine.Simulations.Dynamics.transient_stability_driver.
TransientStability
(grid: GridCal.Engine.Core.multi_circuit.MultiCircuit, options: GridCal.Engine.Simulations.Dynamics.transient_stability_driver.TransientStabilityOptions, pf_res: GridCal.Engine.Simulations.PowerFlow.power_flow_results.PowerFlowResults)¶ Bases:
PySide2.QtCore.QThread
-
done_signal
= <PySide2.QtCore.Signal object>¶
-
get_steps
()¶ Get time steps list of strings
-
progress_signal
= <PySide2.QtCore.Signal object>¶
-
progress_text
= <PySide2.QtCore.Signal object>¶
-
run
()¶ Run transient stability
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
status
(txt, progress)¶ Emit status :param txt: text to display :param progress: progress 0-100
-
-
class
GridCal.Engine.Simulations.Dynamics.transient_stability_driver.
TransientStabilityOptions
(h=0.001, t_sim=15, max_err=0.0001, max_iter=25)¶ Bases:
object
-
class
GridCal.Engine.Simulations.OPF.ac_opf.
AcOpf
(multi_circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, verbose=False, allow_load_shedding=False, allow_generation_shedding=False, load_shedding_weight=10000, generation_shedding_weight=10000)¶ Bases:
object
-
build_solvers
()¶ Builds the solvers for each island :return:
-
get_batteries_power
()¶ Get array of battery dispatched power
-
get_branch_flows
()¶ Return the DC branch flows :return: numpy array
-
get_branch_flows_df
()¶ Get hte DC branch flows DataFrame
-
get_controlled_generation
()¶ Get array of controlled generators power
-
get_gen_results_df
()¶ Get the generation values DataFrame
-
get_generation_shedding
()¶ Load shedding array
-
get_load_shedding
()¶ Load shedding array
-
get_loading
()¶
-
get_overloads
()¶ get the overloads into an array
-
get_voltage
()¶ Get the complex voltage composition from the LP angles solution
-
get_voltage_results_df
()¶ Get the voltage angles DataFrame
-
save
()¶ Save all the problem instances
-
set_default_state
()¶ Set the default loading state
-
set_state
(load_power, static_gen_power, gen_power, Emin=None, Emax=None, E=None, dt=0, force_batteries_to_charge=False, bat_idx=None, battery_loading_pu=0.01)¶ Set the current state :param load_power: vector of load power (same size as the number of loads) :param static_gen_power: vector of static generators load (same size as the static gen objects) :param gen_power: vector of controlled generators power (same size as the ctrl. generatos) :param force_batteries_to_charge: shall we force batteries to charge? :param bat_idx: battery indices that shall be forced to charge :param battery_loading_pu: amount of the changing band to force to charge
-
set_state_at
(t, force_batteries_to_charge=False, bat_idx=None, battery_loading_pu=0.01, Emin=None, Emax=None, E=None, dt=0)¶ Set the problem state at at time index :param t: time index
-
solve
(verbose=False)¶ Solve all islands (the results remain in the variables…)
-
-
class
GridCal.Engine.Simulations.OPF.ac_opf.
AcOpf_old
(calculation_input: GridCal.Engine.Core.calculation_inputs.CalculationInputs, buses=[], branches=[], options=None, voltage_band=0.1)¶ Bases:
object
-
build
(t_idx=None)¶ Formulate and Solve the AC LP problem :return: Nothing
-
copy
()¶
-
get_results
(save_lp_file=False, t_idx=None, realistic=False)¶ Return the optimization results :param save_lp_file: :param t_idx: :param realistic: compute the realistic values associated with the voltage solution :return: OptimalPowerFlowResults instance
-
print
()¶
-
set_loads
(t_idx=None)¶ Add the loads to the LP problem Args:
t_idx: time index, if none, the default object values are taken
-
solve
()¶ Solve the LP OPF problem
-
-
GridCal.Engine.Simulations.OPF.dc_opf.
Cproduct
(C, vect)¶ Connectivity matrix-vector product :param C: Connectivity matrix :param vect: vector of object type :return:
-
class
GridCal.Engine.Simulations.OPF.dc_opf.
DcOpf
(multi_circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, verbose=False, allow_load_shedding=False, allow_generation_shedding=False, load_shedding_weight=10000, generation_shedding_weight=10000)¶ Bases:
object
-
build_solvers
()¶ Builds the solvers for each island :return:
-
get_batteries_power
()¶ Get array of battery dispatched power
-
get_branch_flows
()¶ Return the DC branch flows :return: numpy array
-
get_branch_flows_df
()¶ Get hte DC branch flows DataFrame
-
get_controlled_generation
()¶ Get array of controlled generators power
-
get_gen_results_df
()¶ Get the generation values DataFrame
-
get_generation_shedding
()¶ Load shedding array
-
get_load_shedding
()¶ Load shedding array
-
get_loading
()¶
-
get_overloads
()¶ get the overloads into an array
-
get_voltage
()¶ Get the complex voltage composition from the LP angles solution
-
get_voltage_results_df
()¶ Get the voltage angles DataFrame
-
save
()¶ Save all the problem instances
-
set_default_state
()¶ Set the default loading state
-
set_state
(load_power, static_gen_power, generator_power, Emin=None, Emax=None, E=None, dt=0, force_batteries_to_charge=False, bat_idx=None, battery_loading_pu=0.01)¶ Set the loading and batteries state :param load_power: vector of load power (same size as the number of loads) :param static_gen_power: vector of static generators load (same size as the static gen objects) :param generator_power: vector of controlled generators power (same size as the ctrl. generators) :param Emin: Minimum energy per battery in MWh / Sbase -> 1/h :param Emax: Maximum energy per battery in MWh / Sbase -> 1/h :param E: Current energy charge in MWh / Sbase -> 1/h :param dt: time step in hours :param force_batteries_to_charge: shall we force batteries to charge? :param bat_idx: battery indices that shall be forced to charge :param battery_loading_pu: amount of the nominal band to charge to use (0.1=10%)
-
set_state_at
(t, force_batteries_to_charge=False, bat_idx=None, battery_loading_pu=0.01, Emin=None, Emax=None, E=None, dt=0)¶ Set the problem state at at time index :param t: time index
-
solve
(verbose=False)¶ Solve all islands (the results remain in the variables…)
-
-
class
GridCal.Engine.Simulations.OPF.nelder_mead_opf.
AcOpfNelderMead
(multi_circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, options: GridCal.Engine.Simulations.PowerFlow.power_flow_driver.PowerFlowOptions, verbose=False, break_at_value=True, good_enough_value=0)¶ Bases:
object
-
build_solvers
()¶
-
f_obj
(x)¶
-
get_batteries_power
()¶
-
get_branch_flows
()¶
-
get_controlled_generation
()¶
-
get_generation_shedding
()¶
-
get_load_shedding
()¶
-
get_loading
()¶
-
get_overloads
()¶
-
get_voltage
()¶
-
set_default_state
()¶ Set the default loading state
-
set_state
(load_power, static_gen_power, controlled_gen_power, storage_power, Emin=None, Emax=None, E=None, dt=0, force_batteries_to_charge=False, bat_idx=None, battery_loading_pu=0.01)¶
-
set_state_at
(t, force_batteries_to_charge=False, bat_idx=None, battery_loading_pu=0.01, Emin=None, Emax=None, E=None, dt=0)¶ Set the problem state at at time index Args:
t: force_batteries_to_charge: bat_idx: battery_loading_pu: Emin: Emax: E: dt:Returns:
-
solve
(verbose=False)¶
-
-
GridCal.Engine.Simulations.OPF.nelder_mead_opf.
nelder_mead
(objective_function, x_start, step=0.1, no_improve_thr=1e-05, no_improv_break=10, max_iter=0, alpha=1.0, gamma=2.0, rho=-0.5, sigma=0.5, break_at_value=False, good_enough_value=0.0, init_res=[], callback=None)¶ - Args:
- objective_function: function to optimize, must return a scalar score
- and operate over a numpy array of the same dimensions as x_start
x_start: initial position LB: lower bounds (can be None) UB: upper bound (can be None) step: look-around radius in initial step no_improve_thr, no_improv_break: break after no_improv_break iterations with an improvement lower than no_improv_thr max_iter: always break after this number of iterations. Set it to 0 to loop indefinitely. alpha: gamma: rho: sigma:
Returns: xsol, fsol
-
GridCal.Engine.Simulations.OPF.nelder_mead_opf.
nelder_mead_test
()¶
-
class
GridCal.Engine.Simulations.OPF.opf_driver.
OptimalPowerFlow
(grid: GridCal.Engine.Core.multi_circuit.MultiCircuit, options: GridCal.Engine.Simulations.OPF.opf_driver.OptimalPowerFlowOptions)¶ Bases:
PySide2.QtCore.QRunnable
-
cancel
()¶
-
get_steps
()¶ Get time steps list of strings
-
opf
(t_idx=None, collect=True)¶ Run a power flow for every circuit @return: OptimalPowerFlowResults object
-
run
()¶ Returns:
-
run_at
(t)¶ Run power flow at the time series object index t @param t: time index @return: OptimalPowerFlowResults object
-
-
class
GridCal.Engine.Simulations.OPF.opf_driver.
OptimalPowerFlowOptions
(verbose=False, load_shedding=False, generation_shedding=False, solver=<SolverType.DC_OPF: (14, )>, realistic_results=False, control_batteries=True, faster_less_accurate=False, generation_shedding_weight=10000, load_shedding_weight=10000, power_flow_options=None, bus_types=None, non_sequential=False)¶ Bases:
object
-
class
GridCal.Engine.Simulations.OPF.opf_results.
OptimalPowerFlowResults
(Sbus=None, voltage=None, load_shedding=None, generation_shedding=None, battery_power=None, controlled_generation_power=None, Sbranch=None, overloads=None, loading=None, losses=None, converged=None, bus_types=None)¶ Bases:
object
OPF results.
Arguments:
Sbus: bus power injections
voltage: bus voltages
load_shedding: load shedding values
Sbranch: branch power values
overloads: branch overloading values
loading: branch loading values
losses: branch losses
converged: converged?
-
copy
()¶ Return a copy of this @return:
-
initialize
(n, m)¶ Initialize the arrays @param n: number of buses @param m: number of branches @return:
-
plot
(result_type, ax=None, indices=None, names=None)¶ Plot the results :param result_type: type of results (string) :param ax: matplotlib axis object :param indices: element indices :param names: element names :return: DataFrame of the results (or None if the result was not understood)
-
-
class
GridCal.Engine.Simulations.OPF.opf_time_series_driver.
NonSequentialOptimalPowerFlow
(grid: GridCal.Engine.Core.multi_circuit.MultiCircuit, options: GridCal.Engine.Simulations.OPF.opf_driver.OptimalPowerFlowOptions, start_=0, end_=None)¶ Bases:
PySide2.QtCore.QThread
-
cancel
()¶
-
done_signal
= <PySide2.QtCore.Signal object>¶
-
get_steps
()¶ Get time steps list of strings
-
opf
()¶ Run a power flow for every circuit @return: OptimalPowerFlowResults object
-
progress_signal
= <PySide2.QtCore.Signal object>¶
-
progress_text
= <PySide2.QtCore.Signal object>¶
-
run
()¶ Returns:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Engine.Simulations.OPF.opf_time_series_driver.
OptimalPowerFlowTimeSeriesResults
(n, m, nt, ngen=0, nbat=0, nload=0, time=None, is_dc=False)¶ Bases:
object
-
init_object_results
(ngen, nbat)¶ declare the generator results. This is done separately since these results are known at the end of the simulation :param ngen: number of generators :param nbat: number of batteries
-
plot
(result_type, ax=None, indices=None, names=None)¶ Plot the results :param result_type: :param ax: :param indices: :param names: :return:
-
set_at
(t, res: GridCal.Engine.Simulations.OPF.opf_results.OptimalPowerFlowResults)¶ Set the results :param t: time index :param res: OptimalPowerFlowResults instance
-
-
class
GridCal.Engine.Simulations.OPF.opf_time_series_driver.
SequentialOptimalPowerFlowTimeSeries
(grid: GridCal.Engine.Core.multi_circuit.MultiCircuit, options: GridCal.Engine.Simulations.OPF.opf_driver.OptimalPowerFlowOptions, start_=0, end_=None)¶ Bases:
PySide2.QtCore.QThread
-
cancel
()¶ Set the cancel state
-
done_signal
= <PySide2.QtCore.Signal object>¶
-
get_steps
()¶ Get time steps list of strings
-
initialize_lp_vars
()¶ initialize all the bus LP profiles :return:
-
progress_signal
= <PySide2.QtCore.Signal object>¶
-
progress_text
= <PySide2.QtCore.Signal object>¶
-
run
()¶ Run the time series simulation @return:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Engine.Simulations.Optimization.optimization_driver.
Optimize
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, options: GridCal.Engine.Simulations.PowerFlow.power_flow_driver.PowerFlowOptions, max_iter=1000)¶ Bases:
PySide2.QtCore.QThread
-
cancel
()¶ Cancel the simulation
-
done_signal
= <PySide2.QtCore.Signal object>¶
-
plot
(ax=None)¶ Plot the optimization convergence
-
progress_signal
= <PySide2.QtCore.Signal object>¶
-
progress_text
= <PySide2.QtCore.Signal object>¶
-
run
()¶ Run the optimization @return: Nothing
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Engine.Simulations.Optimization.optimization_driver.
VoltageOptimizationProblem
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, options: GridCal.Engine.Simulations.PowerFlow.power_flow_driver.PowerFlowOptions, max_iter=1000, callback=None)¶ Bases:
pySOT.optimization_problems.OptimizationProblem
Variables: - dim – Number of dimensions
- lb – Lower variable bounds
- ub – Upper variable bounds
- int_var – Integer variables
- cont_var – Continuous variables
- min – Global minimum value
- minimum – Global minimizer
- info – String with problem info
-
eval
(x)¶ Evaluate the Ackley function at x
Parameters: x (numpy.array) – Data point Returns: Value at x Return type: float
-
GridCal.Engine.Simulations.PowerFlow.fast_decoupled_power_flow.
FDPF
(Vbus, Sbus, Ibus, Ybus, B1, B2, pq, pv, pqpv, tol=1e-09, max_it=100)¶ Fast decoupled power flow Args:
Vbus: Sbus: Ibus: Ybus: B1: B2: pq: pv: pqpv: tol:Returns:
Method implemented from the article: Online voltage stability assessment for load areas based on the holomorphic embedding method by Chengxi Liu, Bin Wang, Fengkai Hu, Kai Sun and Claus Leth Bak
Implemented by Santiago Peñate Vera 2018 This implementation computes W[n] for all the buses outside the system matrix leading to better results
-
GridCal.Engine.Simulations.PowerFlow.helm_power_flow.
assign_solution
(x, bus_idx, pvpos, pv, nbus)¶ Assign the solution vector to the appropriate coefficients :param x: solution vector :param bus_idx: array from 0..nbus-1 :param nbus2: two times the number of buses (integer) :param pvpos: array from 0..npv :return: Array of:
- voltage coefficients
- reactive power
of order n
-
GridCal.Engine.Simulations.PowerFlow.helm_power_flow.
calc_W
(n, V, W)¶ Calculation of the inverse coefficients W. @param n: Order of the coefficients @param V: Structure of voltage coefficients (Ncoeff x nbus elements) @param W: Structure of inverse voltage coefficients (Ncoeff x nbus elements) @return: Array of inverse voltage coefficients for the order n
-
GridCal.Engine.Simulations.PowerFlow.helm_power_flow.
get_rhs
(n, V, W, Q, Vbus, Vst, Sbus, Pbus, nsys, nbus2, pv, pq, pvpos)¶ Right hand side :param n: order of the coefficients :param V: Voltage coefficients (order, all buses) :param W: Inverse voltage coefficients (order, pv buses) :param Q: Reactive power coefficients (order, pv buses) :param Vbus: Initial bus estimate (only used to pick the PV buses set voltage) :param Vst: Start voltage due to slack injections :param Pbus: Active power injections (all the buses) :param nsys: number of rows or cols in the system matrix A :param nbus2: two times the number of buses :param pv: list of pv indices in the grid :param pvpos: array from 0..npv :return: right hand side vector to solve the coefficients of order n
-
GridCal.Engine.Simulations.PowerFlow.helm_power_flow.
helm
(Vbus, Sbus, Ybus, pq, pv, ref, pqpv, tol=1e-09, max_coefficient_count=30)¶ Helm Method :param Vbus: voltages array :param Sbus: Power injections array :param Ibus: Currents injection array :param Ybus: System admittance matrix :param pq: list of pq node indices :param pv: list of pv node indices :param ref: list of slack node indices :param pqpv: list of pq and pv node indices sorted :param tol: tolerance :return: Voltage array and the power mismatch
-
GridCal.Engine.Simulations.PowerFlow.helm_power_flow.
pade_approximation
(n, an, s=1)¶ Computes the n/2 pade approximant of the series an at the approximation point s
- Arguments:
- an: coefficient matrix, (number of coefficients, number of series) n: order of the series s: point of approximation
- Returns:
- pade approximation at s
-
GridCal.Engine.Simulations.PowerFlow.helm_power_flow.
prepare_system_matrices
(Ybus, Vbus, bus_idx, pqpv, pq, pv, ref)¶ Prepare the system matrices :param Ybus: :param Vbus: :param pqpv: :param ref: :return:
-
GridCal.Engine.Simulations.PowerFlow.helm_power_flow.
res_2_df
(V, Sbus, tpe)¶ Create dataframe to display the results nicely :param V: Voltage complex vector :param Sbus: Power complex vector :param tpe: Types :return: Pandas DataFrame
-
GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.
ContinuousNR
(Ybus, Sbus, V0, Ibus, pv, pq, tol, max_it=15)¶ Solves the power flow using a full Newton’s method with the backtrack improvement algorithm Args:
Ybus: Admittance matrix Sbus: Array of nodal power injections V0: Array of nodal voltages (initial solution) Ibus: Array of nodal current injections pv: Array with the indices of the PV buses pq: Array with the indices of the PQ buses tol: Tolerance max_it: Maximum number of iterations robust: Boolean variable for the use of the Iwamoto optimal step factor.- Returns:
- Voltage solution, converged?, error, calculated power injections
@author: Ray Zimmerman (PSERC Cornell) @Author: Santiago Penate Vera
-
GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.
F
(V, Ybus, S, I, pq, pv)¶ Parameters: - V –
- Ybus –
- S –
- I –
- pq –
- pv –
- pvpq –
Returns:
-
GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.
IwamotoNR
(Ybus, Sbus, V0, Ibus, pv, pq, tol, max_it=15, robust=False)¶ Solves the power flow using a full Newton’s method with the Iwamoto optimal step factor. Args:
Ybus: Admittance matrix Sbus: Array of nodal power injections V0: Array of nodal voltages (initial solution) Ibus: Array of nodal current injections pv: Array with the indices of the PV buses pq: Array with the indices of the PQ buses tol: Tolerance max_it: Maximum number of iterations robust: Boolean variable for the use of the Iwamoto optimal step factor.- Returns:
- Voltage solution, converged?, error, calculated power injections
@author: Ray Zimmerman (PSERC Cornell) @Author: Santiago Penate Vera
-
GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.
Jacobian
(Ybus, V, Ibus, pq, pvpq)¶ Computes the system Jacobian matrix Args:
Ybus: Admittance matrix V: Array of nodal voltages Ibus: Array of nodal current injections pq: Array with the indices of the PQ buses pvpq: Array with the indices of the PV and PQ buses- Returns:
- The system Jacobian matrix
-
GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.
Jacobian_I
(Ybus, V, pq, pvpq)¶ Computes the system Jacobian matrix Args:
Ybus: Admittance matrix V: Array of nodal voltages pq: Array with the indices of the PQ buses pvpq: Array with the indices of the PV and PQ buses- Returns:
- The system Jacobian matrix in current equations
-
GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.
LevenbergMarquardtPF
(Ybus, Sbus, V0, Ibus, pv, pq, tol, max_it=50)¶ Solves the power flow problem by the Levenberg-Marquardt power flow algorithm. It is usually better than Newton-Raphson, but it takes an order of magnitude more time to converge. Args:
Ybus: Admittance matrix Sbus: Array of nodal power injections V0: Array of nodal voltages (initial solution) Ibus: Array of nodal current injections pv: Array with the indices of the PV buses pq: Array with the indices of the PQ buses tol: Tolerance max_it: Maximum number of iterations- Returns:
- Voltage solution, converged?, error, calculated power injections
@Author: Santiago Peñate Vera
-
GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.
NR_I_LS
(Ybus, Sbus_sp, V0, Ibus_sp, pv, pq, tol, max_it=15)¶ Solves the power flow using a full Newton’s method in current equations with current mismatch with line search Args:
Ybus: Admittance matrix Sbus_sp: Array of nodal specified power injections V0: Array of nodal voltages (initial solution) Ibus_sp: Array of nodal specified current injections pv: Array with the indices of the PV buses pq: Array with the indices of the PQ buses tol: Tolerance max_it: Maximum number of iterations- Returns:
- Voltage solution, converged?, error, calculated power injections
@Author: Santiago Penate Vera
-
GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.
NR_LS
(Ybus, Sbus, V0, Ibus, pv, pq, tol, max_it=15)¶ Solves the power flow using a full Newton’s method with the backtrack improvement algorithm Args:
Ybus: Admittance matrix Sbus: Array of nodal power injections V0: Array of nodal voltages (initial solution) Ibus: Array of nodal current injections pv: Array with the indices of the PV buses pq: Array with the indices of the PQ buses tol: Tolerance max_it: Maximum number of iterations robust: Boolean variable for the use of the Iwamoto optimal step factor.- Returns:
- Voltage solution, converged?, error, calculated power injections
@author: Ray Zimmerman (PSERC Cornell) @Author: Santiago Penate Vera
-
GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.
dSbus_dV
(Ybus, V, I)¶ Computes partial derivatives of power injection w.r.t. voltage. :param Ybus: Admittance matrix :param V: Bus voltages array :param I: Bus current injections array :return:
-
GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.
fx
(x, Ybus, S, I, pq, pv, pvpq, j1, j2, j3, j4, j5, j6, Va, Vm)¶ Parameters: - x –
- Ybus –
- S –
- I –
- pq –
- pv –
- pvpq –
Returns:
-
GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.
mu
(Ybus, Ibus, J, incS, dV, dx, pvpq, pq)¶ Calculate the Iwamoto acceleration parameter as described in: “A Load Flow Calculation Method for Ill-Conditioned Power Systems” by Iwamoto, S. and Tamura, Y.” Args:
Ybus: Admittance matrix J: Jacobian matrix incS: mismatch vector dV: voltage increment (in complex form) dx: solution vector as calculated dx = solve(J, incS) pvpq: array of the pq and pv indices pq: array of the pq indices- Returns:
- the Iwamoto’s optimal multiplier for ill conditioned systems
-
GridCal.Engine.Simulations.PowerFlow.linearized_power_flow.
dcpf
(Ybus, Sbus, Ibus, V0, ref, pvpq, pq, pv)¶ Solves a DC power flow. :param Ybus: Normal circuit admittance matrix :param Sbus: Complex power injections at all the nodes :param Ibus: Complex current injections at all the nodes :param V0: Array of complex seed voltage (it contains the ref voltages) :param ref: array of the indices of the slack nodes :param pvpq: array of the indices of the non-slack nodes :param pq: array of the indices of the pq nodes :param pv: array of the indices of the pv nodes :return:
Complex voltage solution Converged: Always true Solution error Computed power injections given the found solution
-
GridCal.Engine.Simulations.PowerFlow.linearized_power_flow.
lacpf
(Y, Ys, S, I, Vset, pq, pv)¶ Linearized AC Load Flow
form the article:
- Linearized AC Load Flow Applied to Analysis in Electric Power Systems
- by: P. Rossoni, W. M da Rosa and E. A. Belati
- Args:
- Y: Admittance matrix Ys: Admittance matrix of the series elements S: Power injections vector of all the nodes Vset: Set voltages of all the nodes (used for the slack and PV nodes) pq: list of indices of the pq nodes pv: list of indices of the pv nodes
Returns: Voltage vector, converged?, error, calculated power and elapsed time
-
class
GridCal.Engine.Simulations.PowerFlow.power_flow_driver.
PowerFlow
(grid: GridCal.Engine.Core.multi_circuit.MultiCircuit, options: GridCal.Engine.Simulations.PowerFlow.power_flow_driver.PowerFlowOptions)¶ Bases:
PySide2.QtCore.QRunnable
Power flow wrapper to use with Qt
-
cancel
()¶
-
get_steps
()¶
-
run
()¶ Pack run_pf for the QThread :return:
-
run_pf
(circuit: GridCal.Engine.Core.calculation_inputs.CalculationInputs, Vbus, Sbus, Ibus)¶ Run a power flow for every circuit @return:
-
-
class
GridCal.Engine.Simulations.PowerFlow.power_flow_driver.
PowerFlowMP
(grid: GridCal.Engine.Core.multi_circuit.MultiCircuit, options: GridCal.Engine.Simulations.PowerFlow.power_flow_driver.PowerFlowOptions)¶ Bases:
object
Power flow without QT to use with multi processing.
Arguments:
grid (MultiCircuit): Electrical grid to run the power flow in
options (PowerFlowOptions): Power flow options to use
-
cancel
()¶
-
static
compile_types
(Sbus, types=None, logger=[])¶ Compile the types.
-
static
control_q_direct
(V, Vset, Q, Qmax, Qmin, types, original_types, verbose)¶ Change the buses type in order to control the generators reactive power.
Arguments:
pq (list): array of pq indices
pv (list): array of pq indices
ref (list): array of pq indices
V (list): array of voltages (all buses)
Vset (list): Array of set points (all buses)
Q (list): Array of reactive power (all buses)
types (list): Array of types (all buses)
original_types (list): Types as originally intended (all buses)
verbose (bool): output messages via the console
Returns:
Vnew (list): New voltage values
Qnew (list): New reactive power values
types_new (list): Modified types array
any_control_issue (bool): Was there any control issue?
ON PV-PQ BUS TYPE SWITCHING LOGIC IN POWER FLOW COMPUTATION Jinquan Zhao
Bus i is a PQ bus in the previous iteration and its reactive power was fixed at its lower limit:
If its voltage magnitude Vi ≥ Viset, then
it is still a PQ bus at current iteration and set Qi = Qimin .
If Vi < Viset , then
compare Qi with the upper and lower limits.
- If Qi ≥ Qimax , then
it is still a PQ bus but set Qi = Qimax .
- If Qi ≤ Qimin , then
it is still a PQ bus and set Qi = Qimin .
- If Qimin < Qi < Qi max , then
it is switched to PV bus, set Vinew = Viset.
Bus i is a PQ bus in the previous iteration and its reactive power was fixed at its upper limit:
- If its voltage magnitude Vi ≤ Viset , then:
bus i still a PQ bus and set Q i = Q i max.
If Vi > Viset , then
Compare between Qi and its upper/lower limits
- If Qi ≥ Qimax , then
it is still a PQ bus and set Q i = Qimax .
- If Qi ≤ Qimin , then
it is still a PQ bus but let Qi = Qimin in current iteration.
- If Qimin < Qi < Qimax , then
it is switched to PV bus and set Vinew = Viset
Bus i is a PV bus in the previous iteration.
Compare Q i with its upper and lower limits.
- If Qi ≥ Qimax , then
it is switched to PQ and set Qi = Qimax .
- If Qi ≤ Qimin , then
it is switched to PQ and set Qi = Qimin .
- If Qi min < Qi < Qimax , then
it is still a PV bus.
-
control_q_iterative
(V, Vset, Q, Qmax, Qmin, types, original_types, verbose, k)¶ Change the buses type in order to control the generators reactive power using iterative changes in Q to reach Vset.
Arguments:
V (list): array of voltages (all buses)
Vset (list): Array of set points (all buses)
Q (list): Array of reactive power (all buses)
Qmin (list): Array of minimal reactive power (all buses)
Qmax (list): Array of maximal reactive power (all buses)
types (list): Array of types (all buses)
original_types (list): Types as originally intended (all buses)
verbose (list): output messages via the console
k (float, 30): Steepness factor
Return:
Qnew (list): New reactive power values
types_new (list): Modified types array
any_control_issue (bool): Was there any control issue?
-
static
control_taps_direct
(voltage, T, bus_to_regulated_idx, tap_position, tap_module, min_tap, max_tap, tap_inc_reg_up, tap_inc_reg_down, vset, verbose=False)¶ Change the taps and compute the continuous tap magnitude.
Arguments:
voltage (list): array of bus voltages solution
T (list): array of indices of the “to” buses of each branch
bus_to_regulated_idx (list): array with the indices of the branches that regulate the bus “to”
tap_position (list): array of branch tap positions
tap_module (list): array of branch tap modules
min_tap (list): array of minimum tap positions
max_tap (list): array of maximum tap positions
tap_inc_reg_up (list): array of tap increment when regulating up
tap_inc_reg_down (list): array of tap increment when regulating down
vset (list): array of set voltages to control
Returns:
stable (bool): Is the system stable (i.e.: are controllers stable)?
tap_magnitude (list): Tap module at each bus in per unit
tap_position (list): Tap position at each bus
-
control_taps_iterative
(voltage, T, bus_to_regulated_idx, tap_position, tap_module, min_tap, max_tap, tap_inc_reg_up, tap_inc_reg_down, vset, verbose=False)¶ Change the taps and compute the continuous tap magnitude.
Arguments:
voltage (list): array of bus voltages solution
T (list): array of indices of the “to” buses of each branch
bus_to_regulated_idx (list): array with the indices of the branches that regulate the bus “to”
tap_position (list): array of branch tap positions
tap_module (list): array of branch tap modules
min_tap (list): array of minimum tap positions
max_tap (list): array of maximum tap positions
tap_inc_reg_up (list): array of tap increment when regulating up
tap_inc_reg_down (list): array of tap increment when regulating down
vset (list): array of set voltages to control
Returns:
stable (bool): Is the system stable (i.e.: are controllers stable)?
tap_magnitude (list): Tap module at each bus in per unit
tap_position (list): Tap position at each bus
-
static
get_q_increment
(V1, V2, k)¶ Logistic function to get the Q increment gain using the difference between the current voltage (V1) and the target voltage (V2).
The gain varies between 0 (at V1 = V2) and inf (at V2 - V1 = inf).
The default steepness factor k was set through trial an error. Other values may be specified as a PowerFlowOptions.
Arguments:
V1 (float): Current voltage
V2 (float): Target voltage
k (float, 30): Steepness factor
Returns:
Q increment gain
-
static
power_flow_post_process
(calculation_inputs: GridCal.Engine.Core.calculation_inputs.CalculationInputs, V, only_power=False)¶ Compute the power flows trough the branches.
Arguments:
calculation_inputs: instance of Circuit
V: Voltage solution array for the circuit buses
only_power: compute only the power injection
Returns:
Sbranch (MVA), Ibranch (p.u.), loading (p.u.), losses (MVA), Sbus(MVA)
-
run
()¶ Run a power flow for a circuit (wrapper for run_pf).
Returns:
PowerFlowResults instance (self.results)
-
run_multi_island
(numerical_circuit, calculation_inputs, Vbus, Sbus, Ibus)¶ Power flow execution for optimization purposes.
Arguments:
numerical_circuit:
calculation_inputs:
Vbus:
Sbus:
Ibus:
Returns:
PowerFlowResults instance
-
run_pf
(circuit: GridCal.Engine.Core.calculation_inputs.CalculationInputs, Vbus, Sbus, Ibus)¶ Run a power flow for a circuit. In most cases, the run method should be used instead.
Arguments:
circuit (CalculationInputs): CalculationInputs instance
Vbus (list): Initial voltage at each bus in complex per unit
Sbus (list): Power injection at each bus in complex MVA
Ibus (list): Current injection at each bus in complex amperes
Returns:
PowerFlowResults instance
-
single_power_flow
(circuit: GridCal.Engine.Core.calculation_inputs.CalculationInputs, solver_type: GridCal.Engine.Simulations.PowerFlow.power_flow_driver.SolverType, voltage_solution, Sbus, Ibus)¶ Run a power flow simulation for a single circuit using the selected outer loop controls. This method shouldn’t be called directly.
Arguments:
circuit: CalculationInputs instance
solver_type: type of power flow to use first
voltage_solution: vector of initial voltages
Sbus: vector of power injections
Ibus: vector of current injections
Return:
PowerFlowResults instance
-
static
solve
(solver_type, V0, Sbus, Ibus, Ybus, Yseries, B1, B2, pq, pv, ref, pqpv, tolerance, max_iter)¶ Run a power flow simulation using the selected method (no outer loop controls).
solver_type:
V0: Voltage solution vector
Sbus: Power injections vector
Ibus: Current injections vector
Ybus: Admittance matrix
Yseries: Series elements’ Admittance matrix
B1: B’ for the fast decoupled method
B2: B’’ for the fast decoupled method
pq: list of pq nodes
pv: list of pv nodes
ref: list of slack nodes
pqpv: list of pq and pv nodes
tolerance: power error tolerance
max_iter: maximum iterations
Returns:
V0 (Voltage solution), converged (converged?), normF (error in power), Scalc (Computed bus power), iterations, elapsed
-
static
tap_down
(tap, min_tap)¶ Go to the next upper tap position
-
static
tap_up
(tap, max_tap)¶ Go to the next upper tap position
-
-
class
GridCal.Engine.Simulations.PowerFlow.power_flow_driver.
PowerFlowOptions
(solver_type: GridCal.Engine.Simulations.PowerFlow.power_flow_driver.SolverType = <SolverType.NR: 1>, retry_with_other_methods=True, verbose=False, initialize_with_existing_solution=True, tolerance=1e-06, max_iter=25, max_outer_loop_iter=100, control_q=<ReactivePowerControlMode.NoControl: 'NoControl'>, control_taps=<TapsControlMode.NoControl: 'NoControl'>, multi_core=False, dispatch_storage=False, control_p=False, apply_temperature_correction=False, branch_impedance_tolerance_mode=<BranchImpedanceMode.Specified: 0>, q_steepness_factor=30)¶ Bases:
object
Power flow options class; its object is used as an argument for the PowerFlowMP constructor.
Arguments:
solver_type (SolverType, SolverType.NR): Solver type
retry_with_other_methods (bool, True): Use a battery of methods to tackle the problem if the main solver fails
verbose (bool, False): Print additional details in the logger
initialize_with_existing_solution (bool, True): To be detailed
tolerance (float, 1e-6): Solution tolerance for the power flow numerical methods
max_iter (int, 25): Maximum number of iterations for the power flow numerical method
max_outer_loop_iter (int, 100): Maximum number of iterations for the controls outer loop
control_q (ReactivePowerControlMode, ReactivePowerControlMode.NoControl): Control mode for the PV nodes reactive power limits
control_taps (TapsControlMode, TapsControlMode.NoControl): Control mode for the transformer taps equipped with a voltage regulator (as part of the outer loop)
multi_core (bool, False): Use multi-core processing? applicable for time series
dispatch_storage (bool, False): Dispatch storage?
control_p (bool, False): Control active power (optimization dispatch)
apply_temperature_correction (bool, False): Apply the temperature correction to the resistance of the branches?
branch_impedance_tolerance_mode (BranchImpedanceMode, BranchImpedanceMode.Specified): Type of modification of the branches impedance
q_steepness_factor (float, 30): Steepness factor
for the ReactivePowerControlMode iterative control
-
class
GridCal.Engine.Simulations.PowerFlow.power_flow_driver.
ReactivePowerControlMode
¶ Bases:
enum.Enum
The ReactivePowerControlMode offers 3 modes to control how Generator objects supply reactive power:
NoControl: In this mode, the generators don’t try to regulate the voltage at their bus.
Direct: In this mode, the generators try to regulate the voltage at their bus. GridCal does so by applying the following algorithm in an outer control loop. For grids with numerous generators tied to the same system, for example wind farms, this control method sometimes fails with some generators not trying hard enough*. In this case, the simulation converges but the voltage controlled buses do not reach their target voltage, while their generator(s) haven’t reached their reactive power limit. In this case, the slower Iterative control mode may be used (see below).
ON PV-PQ BUS TYPE SWITCHING LOGIC IN POWER FLOW COMPUTATION Jinquan Zhao
Bus i is a PQ bus in the previous iteration and its reactive power was fixed at its lower limit:
If its voltage magnitude Vi >= Viset, then
it is still a PQ bus at current iteration and set Qi = Qimin .
If Vi < Viset , then
compare Qi with the upper and lower limits.
- If Qi >= Qimax , then
it is still a PQ bus but set Qi = Qimax .
- If Qi <= Qimin , then
it is still a PQ bus and set Qi = Qimin .
- If Qimin < Qi < Qi max , then
it is switched to PV bus, set Vinew = Viset.
Bus i is a PQ bus in the previous iteration and its reactive power was fixed at its upper limit:
- If its voltage magnitude Vi <= Viset , then:
bus i still a PQ bus and set Q i = Q i max.
If Vi > Viset , then
Compare between Qi and its upper/lower limits
- If Qi >= Qimax , then
it is still a PQ bus and set Q i = Qimax .
- If Qi <= Qimin , then
it is still a PQ bus but let Qi = Qimin in current iteration.
- If Qimin < Qi < Qimax , then
it is switched to PV bus and set Vinew = Viset
Bus i is a PV bus in the previous iteration.
Compare Q i with its upper and lower limits.
- If Qi >= Qimax , then
it is switched to PQ and set Qi = Qimax .
- If Qi <= Qimin , then
it is switched to PQ and set Qi = Qimin .
- If Qi min < Qi < Qimax , then
it is still a PV bus.
Iterative: As mentioned above, the Direct control mode may not yield satisfying results in some isolated cases. The Direct control mode tries to jump to the final solution in a single or few iterations, but in grids where a significant change in reactive power at one generator has a significant impact on other generators, additional iterations may be required to reach a satisfying solution.
Instead of trying to jump to the final solution, the Iterative mode raises or lowers each generator’s reactive power incrementally. The increment is determined using a logistic function based on the difference between the current bus voltage its target voltage. The steepness factor
k
of the logistic function was determined through trial and error, with the intent of reducing the number of iterations while avoiding instability. Other values may be specified in PowerFlowOptions.The
in per unit is determined by:
Where:
k = 30 (by default)-
Direct
= 'Direct'¶
-
Iterative
= 'Iterative'¶
-
NoControl
= 'NoControl'¶
-
class
GridCal.Engine.Simulations.PowerFlow.power_flow_driver.
SolverType
¶ Bases:
enum.Enum
Refer to the Power Flow section for details about the different algorithms supported by GridCal.
-
AC_OPF
= (15,)¶
-
CONTINUATION_NR
= (9,)¶
-
DC
= (5,)¶
-
DC_OPF
= (14,)¶
-
DYCORS_OPF
= (17,)¶
-
FASTDECOUPLED
= (12,)¶
-
GAUSS
= 4¶
-
GA_OPF
= (18,)¶
-
HELM
= (6,)¶
-
HELMZ
= (10,)¶
-
IWAMOTO
= (8,)¶
-
LACPF
= (13,)¶
-
LM
= 11¶
-
NELDER_MEAD_OPF
= 19¶
-
NR
= 1¶
-
NRFD_BX
= 3¶
-
NRFD_XB
= 2¶
-
NRI
= (16,)¶
-
ZBUS
= (7,)¶
-
-
class
GridCal.Engine.Simulations.PowerFlow.power_flow_driver.
TapsControlMode
¶ Bases:
enum.Enum
The TapsControlMode offers 3 modes to control how transformers’ tap changer regulate voltage on their regulated bus:
NoControl: In this mode, the transformers don’t try to regulate the voltage at their bus.
Direct: In this mode, the transformers try to regulate the voltage at their bus. GridCal does so by jumping straight to the tap that corresponds to the desired transformation ratio, or the highest or lowest tap if the desired ratio is outside of the tap range.
This behavior may fail in certain cases, especially if both the TapControlMode and ReactivePowerControlMode are set to Direct. In this case, the simulation converges but the voltage controlled buses do not reach their target voltage, while their generator(s) haven’t reached their reactive power limit. When this happens, the slower Iterative control mode may be used (see below).
Iterative: As mentioned above, the Direct control mode may not yield satisfying results in some isolated cases. The Direct control mode tries to jump to the final solution in a single or few iterations, but in grids where a significant change of tap at one transformer has a significant impact on other transformers, additional iterations may be required to reach a satisfying solution.
Instead of trying to jump to the final solution, the Iterative mode raises or lowers each transformer’s tap incrementally.
-
Direct
= 'Direct'¶
-
Iterative
= 'Iterative'¶
-
NoControl
= 'NoControl'¶
-
-
GridCal.Engine.Simulations.PowerFlow.power_flow_driver.
power_flow_worker
(t, options: GridCal.Engine.Simulations.PowerFlow.power_flow_driver.PowerFlowOptions, circuit: GridCal.Engine.Core.calculation_inputs.CalculationInputs, Vbus, Sbus, Ibus, return_dict)¶ - Power flow worker to schedule parallel power flows
- **t: execution index **options: power flow options **circuit: circuit **Vbus: Voltages to initialize **Sbus: Power injections **Ibus: Current injections **return_dict: parallel module dictionary in wich to return the values
Returns:
-
GridCal.Engine.Simulations.PowerFlow.power_flow_driver.
power_flow_worker_args
(args)¶ Power flow worker to schedule parallel power flows
args -> t, options: PowerFlowOptions, circuit: Circuit, Vbus, Sbus, Ibus, return_dict
Returns:
-
class
GridCal.Engine.Simulations.PowerFlow.power_flow_results.
PowerFlowResults
(Sbus=None, voltage=None, Sbranch=None, Ibranch=None, loading=None, losses=None, tap_module=None, flow_direction=None, Vbranch=None, error=None, converged=None, Qpv=None, battery_power_inc=None, inner_it=None, outer_it=None, elapsed=None, methods=None, bus_types=None)¶ Bases:
object
A PowerFlowResults object is create as an attribute of the PowerFlowMP (as PowerFlowMP.results) when the power flow is run. It provides access to the simulation results through its class attributes.
Attributes:
Sbus (list): Power at each bus in complex MVA
voltage (list): Voltage at each bus in complex per unit
Sbranch (list): Power through each branch in complex MVA
Ibranch (list): Current through each branch in complex per unit
loading (list): Loading of each branch in per unit
losses (list): Losses in each branch in complex MVA
tap_module (list): Computed tap module at each branch in per unit
flow_direction (list): Flow direction at each branch
Vbranch (list): Voltage increment at each branch
error (float): Power flow computed error
converged (bool): Did the power flow converge?
Qpv (list): Reactive power at each PV node in per unit
inner_it (int): Number of inner iterations
outer_it (int): Number of outer iterations
elapsed (float): Simulation duration in seconds
methods (list): Power flow methods used
-
apply_from_island
(results, b_idx, br_idx)¶ Apply results from another island circuit to the circuit results represented here.
Arguments:
results: PowerFlowResults
b_idx: bus original indices
br_idx: branch original indices
-
check_limits
(F, T, Vmax, Vmin, wo=1, wv1=1, wv2=1)¶ Check the grid violations on the whole circuit
Arguments:
F:
T:
Vmax:
Vmin:
wo:
wv1:
wv2:
Returns:
Summation of the deviations
-
copy
()¶ Return a copy of this @return:
-
export_all
()¶ Exports all the results to DataFrames.
Returns:
Bus results, Branch reuslts
-
get_convergence_report
()¶
-
get_report_dataframe
(island_idx=0)¶ Get a DataFrame containing the convergence report.
Arguments:
island_idx: (optional) island indexReturns:
DataFrame
-
initialize
(n, m)¶ Initialize the arrays @param n: number of buses @param m: number of branches @return:
-
plot
(result_type: GridCal.Engine.Simulations.result_types.ResultTypes, ax=None, indices=None, names=None)¶ Plot the results.
Arguments:
result_type: ResultTypes
ax: matplotlib axis
indices: Indices f the array to plot (indices of the elements)
names: Names of the elements
Returns:
DataFrame
-
-
class
GridCal.Engine.Simulations.PowerFlow.time_Series_input.
TimeSeriesInput
(s_profile: pandas.core.frame.DataFrame = None, i_profile: pandas.core.frame.DataFrame = None, y_profile: pandas.core.frame.DataFrame = None)¶ Bases:
object
-
apply_from_island
(res, bus_original_idx, branch_original_idx, nbus_full, nbranch_full)¶ Parameters: - res – TimeSeriesInput
- bus_original_idx –
- branch_original_idx –
- nbus_full –
- nbranch_full –
Returns:
-
compile
()¶ Generate time-consistent arrays @return:
-
copy
()¶
-
get_at
(t)¶ Returns the necessary values @param t: time index @return:
-
get_from_buses
(bus_idx)¶ @param bus_idx: @return:
-
-
class
GridCal.Engine.Simulations.PowerFlow.time_series_driver.
TimeSeries
(grid: GridCal.Engine.Core.multi_circuit.MultiCircuit, options: GridCal.Engine.Simulations.PowerFlow.power_flow_driver.PowerFlowOptions, use_opf_vals=False, opf_time_series_results=None, start_=0, end_=None)¶ Bases:
PySide2.QtCore.QThread
-
cancel
()¶ Cancel the simulation
-
done_signal
= <PySide2.QtCore.Signal object>¶
-
get_steps
()¶ Get time steps list of strings
-
progress_signal
= <PySide2.QtCore.Signal object>¶
-
progress_text
= <PySide2.QtCore.Signal object>¶
-
run
()¶ Run the time series simulation @return:
-
run_multi_thread
() → GridCal.Engine.Simulations.PowerFlow.time_series_driver.TimeSeriesResults¶ Run multi thread time series :return: TimeSeriesResults instance
-
run_single_thread
() → GridCal.Engine.Simulations.PowerFlow.time_series_driver.TimeSeriesResults¶ Run single thread time series :return: TimeSeriesResults instance
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Engine.Simulations.PowerFlow.time_series_driver.
TimeSeriesResults
(n, m, nt, start, end, time=None)¶ Bases:
GridCal.Engine.Simulations.PowerFlow.power_flow_results.PowerFlowResults
-
analyze
()¶ Analyze the results @return:
-
apply_from_island
(results, b_idx, br_idx, index, grid_idx)¶ Apply results from another island circuit to the circuit results represented here @param results: PowerFlowResults @param b_idx: bus original indices @param br_idx: branch original indices @return:
-
get_results_dict
()¶ Returns a dictionary with the results sorted in a dictionary :return: dictionary of 2D numpy arrays (probably of complex numbers)
-
static
merge_if
(df, arr, ind, cols)¶ @param df: @param arr: @param ind: @param cols: @return:
-
plot
(result_type: GridCal.Engine.Simulations.result_types.ResultTypes, ax=None, indices=None, names=None)¶ Plot the results :param result_type: :param ax: :param indices: :param names: :return:
-
save
(fname)¶ Export as pickle
-
set_at
(t, results: GridCal.Engine.Simulations.PowerFlow.power_flow_results.PowerFlowResults)¶ Set the results at the step t @param t: time index @param results: PowerFlowResults instance
-
-
GridCal.Engine.Simulations.ShortCircuit.short_circuit.
short_circuit_3p
(bus_idx, Zbus, Vbus, Zf, baseMVA)¶ Executes a 3-phase balanced short circuit study Args:
bus_idx: Index of the bus at which the short circuit is being studied Zbus: Inverse of the admittance matrix Vbus: Voltages of the buses in the steady state Zf: Fault impedance arrayReturns: Voltages after the short circuit (p.u.), Short circuit power in MVA
-
class
GridCal.Engine.Simulations.ShortCircuit.short_circuit_driver.
ShortCircuit
(grid: GridCal.Engine.Core.multi_circuit.MultiCircuit, options: GridCal.Engine.Simulations.ShortCircuit.short_circuit_driver.ShortCircuitOptions, pf_results: GridCal.Engine.Simulations.PowerFlow.power_flow_results.PowerFlowResults)¶ Bases:
PySide2.QtCore.QRunnable
-
cancel
()¶
-
static
compile_zf
(grid)¶
-
static
compute_branch_results
(calculation_inputs: GridCal.Engine.Core.calculation_inputs.CalculationInputs, V)¶ Compute the power flows trough the branches @param calculation_inputs: instance of Circuit @param V: Voltage solution array for the circuit buses @return: Sbranch, Ibranch, loading, losses
-
get_steps
()¶ Get time steps list of strings
-
run
()¶ Run a power flow for every circuit @return:
-
single_short_circuit
(calculation_inputs: GridCal.Engine.Core.calculation_inputs.CalculationInputs, Vpf, Zf)¶ Run a power flow simulation for a single circuit @param calculation_inputs: @param Vpf: Power flow voltage vector applicable to the island @param Zf: Short circuit impedance vector applicable to the island @return: short circuit results
-
static
split_branch
(branch: GridCal.Engine.Devices.branch.Branch, fault_position, r_fault, x_fault)¶ Split a branch by a given distance :param branch: Branch of a circuit :param fault_position: per unit distance measured from the “from” bus (0 ~ 1) :param r_fault: Fault resistance in p.u. :param x_fault: Fault reactance in p.u. :return: the two new branches and the mid short circuited bus
-
-
class
GridCal.Engine.Simulations.ShortCircuit.short_circuit_driver.
ShortCircuitOptions
(bus_index=[], branch_index=[], branch_fault_locations=[], branch_fault_impedance=[], branch_impedance_tolerance_mode=<BranchImpedanceMode.Specified: 0>, verbose=False)¶ Bases:
object
-
class
GridCal.Engine.Simulations.ShortCircuit.short_circuit_driver.
ShortCircuitResults
(Sbus=None, voltage=None, Sbranch=None, Ibranch=None, loading=None, losses=None, SCpower=None, error=None, converged=None, Qpv=None)¶ Bases:
GridCal.Engine.Simulations.PowerFlow.power_flow_results.PowerFlowResults
-
apply_from_island
(results, b_idx, br_idx)¶ Apply results from another island circuit to the circuit results represented here @param results: PowerFlowResults @param b_idx: bus original indices @param br_idx: branch original indices @return:
-
copy
()¶ Return a copy of this @return:
-
initialize
(n, m)¶ Initialize the arrays @param n: number of buses @param m: number of branches @return:
-
plot
(result_type, ax=None, indices=None, names=None)¶ Plot the results Args:
result_type: ax: indices: names:Returns:
-
-
GridCal.Engine.Simulations.StateEstimation.state_estimation.
Jacobian_SE
(Ybus, Yf, Yt, V, f, t, inputs, pvpq)¶ Parameters: - Ybus –
- Yf –
- Yt –
- V –
- f –
- t –
- inputs – instance of StateEstimationInput
- pvpq –
Returns:
-
GridCal.Engine.Simulations.StateEstimation.state_estimation.
dIbr_dV
(Yf, Yt, V)¶ Computes partial derivatives of branch currents w.r.t. voltage :param Yf: :param Yt: :param V: :return:
-
GridCal.Engine.Simulations.StateEstimation.state_estimation.
dSbr_dV
(Yf, Yt, V, f, t)¶ Parameters: - Yf –
- Yt –
- V –
- f –
- t –
Returns:
-
GridCal.Engine.Simulations.StateEstimation.state_estimation.
dSbus_dV
(Ybus, V)¶ Parameters: - Ybus –
- V –
Returns:
-
GridCal.Engine.Simulations.StateEstimation.state_estimation.
solve_se_lm
(Ybus, Yf, Yt, f, t, se_input, ref, pq, pv)¶ Solve the state estimation problem using the Levenberg-Marquadt method :param Ybus: :param Yf: :param Yt: :param f: array with the from bus indices of all the branches :param t: array with the to bus indices of all the branches :param inputs: state estimation imput instance (contains the measurements) :param ref: :param pq: :param pv: :return:
-
class
GridCal.Engine.Simulations.StateEstimation.state_stimation_driver.
StateEstimation
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit)¶ Bases:
PySide2.QtCore.QRunnable
-
static
collect_measurements
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, bus_idx, branch_idx)¶ Form the input from the circuit measurements :return: nothing, the input object is stored in this class
-
run
()¶ Run state estimation :return:
-
static
-
class
GridCal.Engine.Simulations.StateEstimation.state_stimation_driver.
StateEstimationInput
¶ Bases:
object
-
clear
()¶ Clear
-
consolidate
()¶ consolidate the measurements into “measurements” and “sigma” :return: measurements, sigma
-
-
class
GridCal.Engine.Simulations.StateEstimation.state_stimation_driver.
StateEstimationResults
(Sbus=None, voltage=None, Sbranch=None, Ibranch=None, loading=None, losses=None, error=None, converged=None, Qpv=None)¶ Bases:
GridCal.Engine.Simulations.PowerFlow.power_flow_results.PowerFlowResults
-
class
GridCal.Engine.Simulations.Stochastic.blackout_driver.
CascadeType
¶ Bases:
enum.Enum
An enumeration.
-
LatinHypercube
= 1¶
-
PowerFlow
= (0,)¶
-
-
class
GridCal.Engine.Simulations.Stochastic.blackout_driver.
Cascading
(grid: GridCal.Engine.Core.multi_circuit.MultiCircuit, options: GridCal.Engine.Simulations.PowerFlow.power_flow_driver.PowerFlowOptions, triggering_idx=None, max_additional_islands=1, cascade_type_: GridCal.Engine.Simulations.Stochastic.blackout_driver.CascadeType = <CascadeType.LatinHypercube: 1>, n_lhs_samples_=1000)¶ Bases:
PySide2.QtCore.QThread
-
cancel
()¶ Cancel the simulation :return:
-
done_signal
= <PySide2.QtCore.Signal object>¶
-
get_failed_idx
()¶ Return the array of all failed branches Returns:
array of all failed branches
-
get_table
()¶ Get DataFrame of the failed elements :return: DataFrame
-
perform_step_run
()¶ Perform only one step cascading Returns:
Nothing
-
progress_signal
= <PySide2.QtCore.Signal object>¶
-
progress_text
= <PySide2.QtCore.Signal object>¶
-
static
remove_elements
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, loading_vector, idx=None)¶ Remove branches based on loading Returns:
Nothing
-
static
remove_probability_based
(numerical_circuit: GridCal.Engine.Core.numerical_circuit.NumericalCircuit, results: GridCal.Engine.Simulations.Stochastic.monte_carlo_results.MonteCarloResults, max_val, min_prob)¶ Remove branches based on their chance of overload :param numerical_circuit: :param results: :param max_val: :param min_prob: :return: list of indices actually removed
-
run
()¶ Run the monte carlo simulation @return:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Engine.Simulations.Stochastic.blackout_driver.
CascadingReportElement
(removed_idx, pf_results, criteria)¶ Bases:
object
-
class
GridCal.Engine.Simulations.Stochastic.blackout_driver.
CascadingResults
(cascade_type: GridCal.Engine.Simulations.Stochastic.blackout_driver.CascadeType)¶ Bases:
object
-
get_failed_idx
()¶ Return the array of all failed branches Returns:
array of all failed branches
-
get_table
()¶ Get DataFrame of the failed elements :return: DataFrame
-
plot
()¶
-
-
class
GridCal.Engine.Simulations.Stochastic.lhs_driver.
LatinHypercubeSampling
(grid: GridCal.Engine.Core.multi_circuit.MultiCircuit, options: GridCal.Engine.Simulations.PowerFlow.power_flow_driver.PowerFlowOptions, sampling_points=1000)¶ Bases:
PySide2.QtCore.QThread
-
cancel
()¶ Cancel the simulation
-
done_signal
= <PySide2.QtCore.Signal object>¶
-
get_steps
()¶ Get time steps list of strings
-
progress_signal
= <PySide2.QtCore.Signal object>¶
-
progress_text
= <PySide2.QtCore.Signal object>¶
-
run
()¶ Run the monte carlo simulation @return:
-
run_multi_thread
()¶ Run the monte carlo simulation @return:
-
run_single_thread
()¶ Run the monte carlo simulation @return:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Engine.Simulations.Stochastic.monte_carlo_driver.
MonteCarlo
(grid: GridCal.Engine.Core.multi_circuit.MultiCircuit, options: GridCal.Engine.Simulations.PowerFlow.power_flow_driver.PowerFlowOptions, mc_tol=0.001, batch_size=100, max_mc_iter=10000)¶ Bases:
PySide2.QtCore.QThread
-
cancel
()¶ Cancel the simulation :return:
-
done_signal
= <PySide2.QtCore.Signal object>¶
-
get_steps
()¶ Get time steps list of strings
-
progress_signal
= <PySide2.QtCore.Signal object>¶
-
progress_text
= <PySide2.QtCore.Signal object>¶
-
run
()¶ Run the monte carlo simulation @return:
-
run_multi_thread
()¶ Run the monte carlo simulation @return:
-
run_single_thread
()¶ Run the monte carlo simulation @return:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
GridCal.Engine.Simulations.Stochastic.monte_carlo_driver.
make_monte_carlo_input
(numerical_input_island: GridCal.Engine.Core.calculation_inputs.CalculationInputs)¶ Generate a monte carlo input instance :param numerical_input_island: :return:
-
class
GridCal.Engine.Simulations.Stochastic.monte_carlo_results.
MonteCarloResults
(n, m, p=0)¶ Bases:
object
-
append_batch
(mcres)¶ Append a batch (a MonteCarloResults object) to this object @param mcres: MonteCarloResults object @return:
-
compile
()¶ Compiles the final Monte Carlo values by running an online mean and @return:
-
get_index_loading_cdf
(max_val=1.0)¶ Find the elements where the CDF is greater or equal to a velue :param max_val: value to compare :return: indices, associated probability
-
get_results_dict
()¶ Returns a dictionary with the results sorted in a dictionary :return: dictionary of 2D numpy arrays (probably of complex numbers)
-
get_voltage_sum
()¶ Return the voltage summation @return:
-
open
(fname)¶ open pickle Args:
fname: file nameReturns: true if succeeded, false otherwise
-
plot
(result_type: GridCal.Engine.Simulations.result_types.ResultTypes, ax=None, indices=None, names=None)¶ Plot the results :param result_type: :param ax: :param indices: :param names: :return:
-
query_voltage
(power_array)¶ Fantastic function that allows to query the voltage from the sampled points without having to run power flows Args:
power_array: power injections vectorReturns: Interpolated voltages vector
-
save
(fname)¶ Export as pickle
-
-
class
GridCal.Engine.Simulations.Stochastic.reliability_driver.
ReliabilityStudy
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, pf_options: GridCal.Engine.Simulations.PowerFlow.power_flow_driver.PowerFlowOptions)¶ Bases:
PySide2.QtCore.QThread
-
cancel
()¶
-
done_signal
= <PySide2.QtCore.Signal object>¶
-
progress_callback
(l)¶ Send progress report :param l: lambda value :return: None
-
progress_signal
= <PySide2.QtCore.Signal object>¶
-
progress_text
= <PySide2.QtCore.Signal object>¶
-
run
()¶ run the voltage collapse simulation @return:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
GridCal.Engine.Simulations.Stochastic.reliability_driver.
get_failure_time
(mttf)¶ Get an array of possible failure times :param mttf: mean time to failure
-
GridCal.Engine.Simulations.Stochastic.reliability_driver.
get_reliability_events
(horizon, mttf, mttr, tpe: GridCal.Engine.Devices.meta_devices.DeviceType)¶ Get random fail-repair events until a given time horizon in hours :param horizon: maximum horizon in hours :return: list of events, Each event tuple has: (time in hours, element index, activation state (True/False))
-
GridCal.Engine.Simulations.Stochastic.reliability_driver.
get_reliability_scenario
(nc: GridCal.Engine.Core.numerical_circuit.NumericalCircuit, horizon=10000)¶ Get reliability events Args:
nc: numerical circuit instance horizon: time horizon in hoursReturns: dictionary of events Each event tuple has: (time in hours, element index, activation state (True/False))
-
GridCal.Engine.Simulations.Stochastic.reliability_driver.
get_repair_time
(mttr)¶ Get an array of possible repair times :param mttr: mean time to recovery
-
GridCal.Engine.Simulations.Stochastic.reliability_driver.
run_events
(nc: GridCal.Engine.Core.numerical_circuit.NumericalCircuit, events_list: list)¶
-
class
GridCal.Engine.Simulations.Topology.topology_driver.
TopologyReduction
(grid: GridCal.Engine.Core.multi_circuit.MultiCircuit, branch_indices)¶ Bases:
PySide2.QtCore.QThread
-
cancel
()¶ Cancel the simulation :return:
-
done_signal
= <PySide2.QtCore.Signal object>¶
-
progress_signal
= <PySide2.QtCore.Signal object>¶
-
progress_text
= <PySide2.QtCore.Signal object>¶
-
run
()¶ Run the monte carlo simulation @return:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Engine.Simulations.Topology.topology_driver.
TopologyReductionOptions
(rx_criteria=False, rx_threshold=1e-05, selected_types=<BranchType.Branch: ('branch', )>)¶ Bases:
object
-
GridCal.Engine.Simulations.Topology.topology_driver.
get_branches_of_bus
(B, j)¶ Get the indices of the branches connected to the bus j :param B: Branch-bus CSC matrix :param j: bus index :return: list of branches in the bus
-
GridCal.Engine.Simulations.Topology.topology_driver.
reduce_buses
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, buses_to_reduce: List[GridCal.Engine.Devices.bus.Bus])¶ Reduce the uses in the grid This function removes the buses but whenever a bus is removed, the devices connected to it are inherited by the bus of higher voltage that is connected. If the bus is isolated, those devices are lost. :param circuit: MultiCircuit instance :param buses_to_reduce: list of Bus objects :return: Nothing
-
GridCal.Engine.Simulations.Topology.topology_driver.
reduce_grid_brute
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, removed_br_idx)¶ Remove the first branch found to be removed. this function is meant to be called until it returns false Args:
circuit: Circuit to modify in-place removed_br_idx: branch indexReturns: Nothing
-
GridCal.Engine.Simulations.Topology.topology_driver.
select_branches_to_reduce
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, rx_criteria=True, rx_threshold=1e-05, selected_types=<BranchType.Branch: ('branch', )>)¶ Find branches to remove Args:
circuit: Circuit to modify in-place rx_criteria: use the r+x threshold to select branches? rx_threshold: r+x threshold selected_types: branch types to select
-
class
GridCal.Engine.Simulations.result_types.
ResultTypes
¶ Bases:
enum.Enum
An enumeration.
-
BatteryEnergy
= ('Battery energy', <DeviceType.BatteryDevice: 'Battery'>)¶
-
BatteryPower
= ('Battery power', <DeviceType.BatteryDevice: 'Battery'>)¶
-
BranchAngles
= ('Branch voltage angles', <DeviceType.BranchDevice: 'Branch'>)¶
-
BranchCurrent
= ('Branch current', <DeviceType.BranchDevice: 'Branch'>)¶
-
BranchCurrentAverage
= ('Branch current avg', <DeviceType.BranchDevice: 'Branch'>)¶
-
BranchCurrentCDF
= ('Branch current CDF', <DeviceType.BranchDevice: 'Branch'>)¶
-
BranchCurrentStd
= ('Branch current std', <DeviceType.BranchDevice: 'Branch'>)¶
-
BranchLoading
= ('Branch loading', <DeviceType.BranchDevice: 'Branch'>)¶
-
BranchLoadingAverage
= ('Branch loading avg', <DeviceType.BranchDevice: 'Branch'>)¶
-
BranchLoadingCDF
= ('Branch loading CDF', <DeviceType.BranchDevice: 'Branch'>)¶
-
BranchLoadingStd
= ('Branch loading std', <DeviceType.BranchDevice: 'Branch'>)¶
-
BranchLosses
= ('Branch losses', <DeviceType.BranchDevice: 'Branch'>)¶
-
BranchLossesAverage
= ('Branch losses avg', <DeviceType.BranchDevice: 'Branch'>)¶
-
BranchLossesCDF
= ('Branch losses CDF', <DeviceType.BranchDevice: 'Branch'>)¶
-
BranchLossesStd
= ('Branch losses std', <DeviceType.BranchDevice: 'Branch'>)¶
-
BranchOverloads
= ('Branch overloads', <DeviceType.BranchDevice: 'Branch'>)¶
-
BranchPower
= ('Branch power', <DeviceType.BranchDevice: 'Branch'>)¶
-
BranchVoltage
= ('Branch voltage drop', <DeviceType.BranchDevice: 'Branch'>)¶
-
BusActivePower
= ('Bus active power', <DeviceType.BusDevice: 'Bus'>)¶
-
BusPower
= ('Bus power', <DeviceType.BusDevice: 'Bus'>)¶
-
BusPowerCDF
= ('Bus power CDF', <DeviceType.BusDevice: 'Bus'>)¶
-
BusReactivePower
= ('Bus reactive power', <DeviceType.BusDevice: 'Bus'>)¶
-
BusShortCircuitPower
= ('Bus short circuit power', <DeviceType.BusDevice: 'Bus'>)¶
-
BusVoltage
= ('Bus voltage', <DeviceType.BusDevice: 'Bus'>)¶
-
BusVoltageAngle
= ('Bus voltage angle', <DeviceType.BusDevice: 'Bus'>)¶
-
BusVoltageAverage
= ('Bus voltage avg', <DeviceType.BusDevice: 'Bus'>)¶
-
BusVoltageCDF
= ('Bus voltage CDF', <DeviceType.BusDevice: 'Bus'>)¶
-
BusVoltageModule
= ('Bus voltage module', <DeviceType.BusDevice: 'Bus'>)¶
-
BusVoltagePolar
= ('Bus voltage (polar)', <DeviceType.BusDevice: 'Bus'>)¶
-
BusVoltageStd
= ('Bus voltage std', <DeviceType.BusDevice: 'Bus'>)¶
-
ControlledGeneratorPower
= ('Controlled generator power', <DeviceType.GeneratorDevice: 'Generator'>)¶
-
ControlledGeneratorShedding
= ('Controlled generator shedding', <DeviceType.GeneratorDevice: 'Generator'>)¶
-
LoadShedding
= ('Load shedding', <DeviceType.LoadDevice: 'Load'>)¶
-
SimulationError
= ('Error', <DeviceType.BusDevice: 'Bus'>)¶
-
-
class
GridCal.Engine.Simulations.result_types.
SimulationTypes
¶ Bases:
enum.Enum
An enumeration.
-
Cascade_run
= 'Cascade'¶
-
LatinHypercube_run
= 'Latin Hypercube'¶
-
MonteCarlo_run
= 'Monte Carlo'¶
-
OPFTimeSeries_run
= 'OPF Time series'¶
-
OPF_run
= 'Optimal power flow'¶
-
PowerFlow_run
= 'power flow'¶
-
ShortCircuit_run
= 'Short circuit'¶
-
TimeSeries_run
= 'Time series power flow'¶
-
TopologyReduction_run
= 'Topology reduction'¶
-
TransientStability_run
= 'Transient stability'¶
-
VoltageCollapse_run
= 'Voltage collapse'¶
-
Submodules¶
-
class
GridCal.Engine.basic_structures.
BranchImpedanceMode
¶ Bases:
enum.Enum
An enumeration.
-
Lower
= 2¶
-
Specified
= 0¶
-
Upper
= 1¶
-
-
class
GridCal.Engine.basic_structures.
BusMode
¶ Bases:
enum.Enum
An enumeration.
-
NONE
= (4,)¶
-
PQ
= (1,)¶
-
PV
= (2,)¶
-
REF
= (3,)¶
-
STO_DISPATCH
= 5¶
-
-
class
GridCal.Engine.basic_structures.
CDF
(data)¶ Bases:
object
Inverse Cumulative density function of a given array of data
-
get_at
(prob)¶ Samples a number of uniform distributed points and returns the corresponding probability values given the CDF. @param prob: probability from 0 to 1 @return: Corresponding CDF value
-
get_sample
(npoints=1)¶ Samples a number of uniform distributed points and returns the corresponding probability values given the CDF. @param npoints: Number of points to sample, 1 by default @return: Corresponding probabilities
-
plot
(ax=None)¶ Plots the CFD @param ax: MatPlotLib axis to plot into @return:
-
-
class
GridCal.Engine.basic_structures.
StatisticalCharacterization
(gen_P, load_P, load_Q)¶ Bases:
object
Object to store the statistical characterization It is useful because the statistical characterizations can be: - not grouped - grouped by day - grouped by hour
-
get_sample
(load_enabled_idx, gen_enabled_idx, npoints=1)¶ Returns a 2D array containing for load and generation profiles, shape (time, load) The profile is sampled from the original data CDF functions
@param npoints: number of sampling points @return: PG: generators profile S: loads profile
-
plot
(ax)¶ Plot this statistical characterization @param ax: matplotlib index @return:
-
-
GridCal.Engine.basic_structures.
classify_by_day
(t: pandas.core.indexes.datetimes.DatetimeIndex)¶ Passes an array of TimeStamps to an array of arrays of indices classified by day of the year @param t: Pandas time Index array @return: list of lists of integer indices
-
GridCal.Engine.basic_structures.
classify_by_hour
(t: pandas.core.indexes.datetimes.DatetimeIndex)¶ Passes an array of TimeStamps to an array of arrays of indices classified by hour of the year @param t: Pandas time Index array @return: list of lists of integer indices
-
class
GridCal.Engine.grid_analysis.
TimeSeriesResultsAnalysis
(numerical_circuit: GridCal.Engine.Core.numerical_circuit.NumericalCircuit, results: GridCal.Engine.Simulations.PowerFlow.time_series_driver.TimeSeriesResults)¶ Bases:
object
GridCal.Gui package¶
Subpackages¶
-
class
GridCal.Gui.Analysis.AnalysisDialogue.
GridAnalysisGUI
(parent=None, object_types=[], circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit = None)¶ Bases:
PySide2.QtWidgets.QDialog
-
analyze_click
()¶ Analyze all the circuit data
-
analyze_object_type
(object_type)¶ Analyze all
-
msg
(text, title='Warning')¶ Message box :param text: Text to display :param title: Name of the window
-
object_type_selected
()¶ On click-plot Returns:
-
plot_analysis
(object_type, fig=None)¶ PLot data + histogram Args:
object_type: fig:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.Analysis.AnalysisDialogue.
GridErrorLog
(parent=None)¶ Bases:
PySide2.QtCore.QAbstractTableModel
-
add
(object_type, element_name, element_index, severity, property, message)¶
-
clear
()¶ Delete all logs
-
columnCount
(self, parent:PySide2.QtCore.QModelIndex=Invalid(PySide2.QtCore.QModelIndex)) → int¶
-
data
(self, index:PySide2.QtCore.QModelIndex, role:int=PySide2.QtCore.Qt.ItemDataRole.DisplayRole) → typing.Any¶
-
headerData
(self, section:int, orientation:PySide2.QtCore.Qt.Orientation, role:int=PySide2.QtCore.Qt.ItemDataRole.DisplayRole) → typing.Any¶
-
rowCount
(self, parent:PySide2.QtCore.QModelIndex=Invalid(PySide2.QtCore.QModelIndex)) → int¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.Analysis.AnalysisDialogue.
PandasModel
(data, parent=None)¶ Bases:
PySide2.QtCore.QAbstractTableModel
Class to populate a Qt table view with a pandas data frame
-
columnCount
(self, parent:PySide2.QtCore.QModelIndex=Invalid(PySide2.QtCore.QModelIndex)) → int¶
-
data
(self, index:PySide2.QtCore.QModelIndex, role:int=PySide2.QtCore.Qt.ItemDataRole.DisplayRole) → typing.Any¶
-
headerData
(self, section:int, orientation:PySide2.QtCore.Qt.Orientation, role:int=PySide2.QtCore.Qt.ItemDataRole.DisplayRole) → typing.Any¶
-
rowCount
(self, parent:PySide2.QtCore.QModelIndex=Invalid(PySide2.QtCore.QModelIndex)) → int¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
GridCal.Gui.Analysis.AnalysisDialogue.
get_list_model
(iterable)¶ get Qt list model from a simple iterable :param iterable: :return: List model
-
class
GridCal.Gui.Analysis.matplotlibwidget.
MatplotlibWidget
(parent=None)¶ Bases:
PySide2.QtWidgets.QWidget
-
clear
(force=False)¶ Clear the interface Args:
force: Remove the object and create a new one (brute force)Returns:
-
get_axis
()¶
-
get_figure
()¶
-
plot
(x, y, title='', xlabel='', ylabel='')¶ Plot series Args:
x: X values y: Y values title: Title xlabel: Label for X ylabel: Label for YReturns:
-
redraw
()¶ Redraw the interface Returns:
-
setTitle
(text)¶ Sets the figure title
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.Analysis.matplotlibwidget.
MplCanvas
¶ Bases:
matplotlib.backends.backend_qt5agg.FigureCanvasQTAgg
-
pan_factory
(ax)¶ Mouse pan handler
-
rec_zoom
()¶
-
setTitle
(text)¶ Sets the figure title
-
set_graph_mode
()¶ Sets the borders to nicely display graphs
-
set_last_zoom
()¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
zoom_factory
(ax, base_scale=1.2)¶ Mouse zoom handler
-
Script to update correctly the main GUI (.py) file from the Qt design (.ui) file
-
GridCal.Gui.Main.icons_rc.
qCleanupResources
()¶
-
GridCal.Gui.Main.icons_rc.
qInitResources
()¶
Script to update correctly the main GUI (.py) file from the Qt design (.ui) file
-
GridCal.Gui.ProfilesInput.icons_rc.
qCleanupResources
()¶
-
GridCal.Gui.ProfilesInput.icons_rc.
qInitResources
()¶
-
class
GridCal.Gui.ProfilesInput.matplotlibwidget.
MatplotlibWidget
(parent=None)¶ Bases:
PySide2.QtWidgets.QWidget
-
clear
(force=False)¶ Clear the interface Args:
force: Remove the object and create a new one (brute force)Returns:
-
get_axis
()¶
-
get_figure
()¶
-
plot
(x, y, title='', xlabel='', ylabel='')¶ Plot series Args:
x: X values y: Y values title: Title xlabel: Label for X ylabel: Label for YReturns:
-
redraw
()¶ Redraw the interface Returns:
-
setTitle
(text)¶ Sets the figure title
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.ProfilesInput.matplotlibwidget.
MplCanvas
¶ Bases:
matplotlib.backends.backend_qt5agg.FigureCanvasQTAgg
-
pan_factory
(ax)¶ Mouse pan handler
-
rec_zoom
()¶
-
setTitle
(text)¶ Sets the figure title
-
set_graph_mode
()¶ Sets the borders to nicely display graphs
-
set_last_zoom
()¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
zoom_factory
(ax, base_scale=1.2)¶ Mouse zoom handler
-
-
class
GridCal.Gui.ProfilesInput.profile_dialogue.
MultiplierType
¶ Bases:
enum.Enum
An enumeration.
-
Cosfi
= 2¶
-
Mult
= (1,)¶
-
-
class
GridCal.Gui.ProfilesInput.profile_dialogue.
PandasModel
(data, parent=None)¶ Bases:
PySide2.QtCore.QAbstractTableModel
Class to populate a Qt table view with a pandas data frame
-
columnCount
(self, parent:PySide2.QtCore.QModelIndex=Invalid(PySide2.QtCore.QModelIndex)) → int¶
-
data
(self, index:PySide2.QtCore.QModelIndex, role:int=PySide2.QtCore.Qt.ItemDataRole.DisplayRole) → typing.Any¶
-
headerData
(self, section:int, orientation:PySide2.QtCore.Qt.Orientation, role:int=PySide2.QtCore.Qt.ItemDataRole.DisplayRole) → typing.Any¶
-
rowCount
(self, parent:PySide2.QtCore.QModelIndex=Invalid(PySide2.QtCore.QModelIndex)) → int¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.ProfilesInput.profile_dialogue.
ProfileInputGUI
(parent=None, list_of_objects=[], magnitudes=[''])¶ Bases:
PySide2.QtWidgets.QDialog
-
assignation_table_double_click
()¶ Set the selected profile into the clicked slot
-
auto_link
()¶ Performs an automatic link between the sources and the objectives based on the names
-
display_associations
()¶ @return:
-
do_it
()¶ Close. The data has to be queried later to the object by the parent by calling get_association_data
-
get_association_data
()¶ Return a dictionary with the data association @return:
-
get_multiplier
()¶ Gets the necessary multiplier to pass the profile units to Mega Remember that the power units in GridCal are the MVA
-
get_profile
(parent=None, labels=None, alsoQ=None)¶ Return ths assigned profiles @return:
Array of profiles assigned to the input objectives Array specifying which objectives are not assigned
-
import_profile
()¶ Select a file to be loaded
-
link_to_all
()¶ Links the selected origin with all the destinations
-
link_to_selection
()¶ Links the selected origin with the selected destinations
-
make_association
(source_idx, obj_idx, scale=None, cosfi=None, mult=None, col_idx=None)¶ Makes an association in the associations table
-
msg
(text, title='Warning')¶ Message box :param text: Text to display :param title: Name of the window
-
static
normalize_string
(s)¶ Normalizes a string
-
objectives_list_double_click
()¶ Link source to objective when the objective item is double clicked :return:
-
print_profile
()¶ prints the profile clicked on the table @return:
-
rnd_link
()¶ Random link
-
set_multiplier
(type)¶ Set the table multipliers
-
sources_list_double_click
()¶ When an item in the sources list is double clicked, plot the series :return:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
GridCal.Gui.ProfilesInput.profile_dialogue.
get_list_model
(iterable)¶ get Qt list model from a simple iterable :param iterable: :return: List model
Script to update correctly the main GUI (.py) file from the Qt design (.ui) file
-
class
GridCal.Gui.TowerBuilder.LineBuilderDialogue.
TowerBuilderGUI
(parent=None, tower=None, wires_catalogue=[])¶ Bases:
PySide2.QtWidgets.QDialog
-
add_wire_to_collection
()¶ Add new wire to collection :return:
-
add_wire_to_tower
()¶ Add wire to tower :return:
-
compute
()¶ Returns:
-
delete_wire_from_collection
()¶ Delete wire from the collection :return:
-
delete_wire_from_tower
()¶ Delete wire from the tower :return:
-
example_1
()¶
-
example_2
()¶
-
msg
(text, title='Warning')¶ Message box :param text: Text to display :param title: Name of the window
-
name_changed
()¶ Change name :return:
-
plot
()¶ PLot the tower distribution
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
GridCal.Gui.TowerBuilder.icons_rc.
qCleanupResources
()¶
-
GridCal.Gui.TowerBuilder.icons_rc.
qInitResources
()¶
-
class
GridCal.Gui.TowerBuilder.matplotlibwidget.
MatplotlibWidget
(parent=None)¶ Bases:
PySide2.QtWidgets.QWidget
-
clear
(force=False)¶ Clear the interface Args:
force: Remove the object and create a new one (brute force)Returns:
-
get_axis
()¶
-
get_figure
()¶
-
plot
(x, y, title='', xlabel='', ylabel='')¶ Plot series Args:
x: X values y: Y values title: Title xlabel: Label for X ylabel: Label for YReturns:
-
redraw
()¶ Redraw the interface Returns:
-
setTitle
(text)¶ Sets the figure title
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.TowerBuilder.matplotlibwidget.
MplCanvas
¶ Bases:
matplotlib.backends.backend_qt5agg.FigureCanvasQTAgg
-
pan_factory
(ax)¶ Mouse pan handler
-
rec_zoom
()¶
-
setTitle
(text)¶ Sets the figure title
-
set_graph_mode
()¶ Sets the borders to nicely display graphs
-
set_last_zoom
()¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
zoom_factory
(ax, base_scale=1.2)¶ Mouse zoom handler
-
-
class
GridCal.Gui.TowerBuilder.test_.
TowerBuilderGUI
(parent=None)¶ Bases:
PySide2.QtWidgets.QDialog
-
add_wire_to_collection
()¶ Add new wire to collection :return:
-
delete_wire_from_collection
()¶ Delete wire from the collection :return:
-
msg
(text, title='Warning')¶ Message box :param text: Text to display :param title: Name of the window
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.TowerBuilder.test_.
Wire
(name, x, y, gmr, r)¶ Bases:
object
-
class
GridCal.Gui.TowerBuilder.test_.
WiresCollection
(parent=None)¶ Bases:
PySide2.QtCore.QAbstractTableModel
-
add
(wire: GridCal.Gui.TowerBuilder.test_.Wire)¶ Add wire :param wire: :return:
-
columnCount
(self, parent:PySide2.QtCore.QModelIndex=Invalid(PySide2.QtCore.QModelIndex)) → int¶
-
data
(self, index:PySide2.QtCore.QModelIndex, role:int=PySide2.QtCore.Qt.ItemDataRole.DisplayRole) → typing.Any¶
-
delete
(index)¶ Delete wire :param index: :return:
-
headerData
(self, section:int, orientation:PySide2.QtCore.Qt.Orientation, role:int=PySide2.QtCore.Qt.ItemDataRole.DisplayRole) → typing.Any¶
-
parent
(self) → PySide2.QtCore.QObject¶ parent(self, child:PySide2.QtCore.QModelIndex) -> PySide2.QtCore.QModelIndex
-
rowCount
(self, parent:PySide2.QtCore.QModelIndex=Invalid(PySide2.QtCore.QModelIndex)) → int¶
-
setData
(index, value, role=PySide2.QtCore.Qt.ItemDataRole.DisplayRole)¶ Set data by simple editor (whatever text) :param index: :param value: :param role:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.TowerBuilder.tower_model.
TowerModel
(parent=None, edit_callback=None, tower: GridCal.Engine.Devices.tower.Tower = None)¶ Bases:
PySide2.QtCore.QAbstractTableModel
-
add
(wire: GridCal.Engine.Devices.wire.Wire)¶ Add wire :param wire: :return:
-
columnCount
(parent=None)¶ Parameters: parent – Returns:
-
data
(index, role=PySide2.QtCore.Qt.ItemDataRole.DisplayRole)¶ Parameters: - index –
- role –
Returns:
-
delete
(index)¶ Delete wire :param index: :return:
-
delete_by_name
(wire: GridCal.Engine.Devices.wire.Wire)¶ Delete wire by name :param wire: Wire object
-
flags
(index)¶ Parameters: index – Returns:
-
headerData
(p_int, orientation, role)¶ Parameters: - p_int –
- orientation –
- role –
Returns:
-
is_used
(wire: GridCal.Engine.Devices.wire.Wire)¶ Parameters: wire – Returns:
-
rowCount
(parent=None)¶ Parameters: parent – Returns:
-
setData
(index, value, role=PySide2.QtCore.Qt.ItemDataRole.DisplayRole)¶ Set data by simple editor (whatever text) :param index: :param value: :param role:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
Script to update correctly the main GUI (.py) file from the Qt design (.ui) file
Submodules¶
-
class
GridCal.Gui.ConsoleWidget.
ConsoleWidget
(customBanner=None, *args, **kwargs)¶ Bases:
qtconsole.rich_jupyter_widget.RichJupyterWidget
Convenience class for a live IPython console widget. We can replace the standard banner using the customBanner argument
-
clear
()¶ Clears the terminal
-
execute_command
(command)¶ Execute a command in the frame of the console widget
-
print_text
(text)¶ Prints some plain text to the console
-
push_vars
(variableDict)¶ Given a dictionary containing name / value pairs, push those variables to the IPython console widget
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.GeneralDialogues.
ElementsDialogue
(name, elements: [])¶ Bases:
PySide2.QtWidgets.QDialog
Selected elements dialogue window
-
accept_click
()¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.GeneralDialogues.
LogsDialogue
(name, logs: [])¶ Bases:
PySide2.QtWidgets.QDialog
New profile dialogue window
-
accept_click
()¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.GeneralDialogues.
NewProfilesStructureDialogue
¶ Bases:
PySide2.QtWidgets.QDialog
New profile dialogue window
-
accept_click
()¶
-
get_values
()¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.GeneralDialogues.
ProfileTypes
¶ Bases:
enum.Enum
An enumeration.
-
Generators
= 2¶
-
Loads
= (1,)¶
-
-
GridCal.Gui.GeneralDialogues.
get_list_model
(lst, checks=False)¶ Pass a list to a list model
-
class
GridCal.Gui.GridEditorWidget.
BatteryGraphicItem
(parent, api_obj, diagramScene)¶ Bases:
PySide2.QtWidgets.QGraphicsItemGroup
-
contextMenuEvent
(event)¶ Display context menu @param event: @return:
-
enable_disable_toggle
()¶ @return:
-
mousePressEvent
(QGraphicsSceneMouseEvent)¶ mouse press: display the editor :param QGraphicsSceneMouseEvent: :return:
-
plot
()¶ Plot API objects profiles
-
remove
()¶ Remove this element @return:
-
set_enable
(val=True)¶ Set the enable value, graphically and in the API @param val: @return:
-
update_line
(pos)¶ Update the line that joins the parent and this object :param pos: position of this object
-
-
class
GridCal.Gui.GridEditorWidget.
BranchGraphicItem
(fromPort, toPort, diagramScene, width=5, branch: GridCal.Engine.Devices.branch.Branch = None)¶ Bases:
PySide2.QtWidgets.QGraphicsLineItem
-
add_to_templates
()¶ Open the appropriate editor dialogue :return:
-
contextMenuEvent
(event)¶ Show context menu @param event: @return:
-
edit
()¶ Open the appropriate editor dialogue :return:
-
enable_disable_toggle
()¶ @return:
-
make_reactance_symbol
()¶ Make the reactance symbol :return:
-
make_switch_symbol
()¶ Mathe the switch symbol :return:
-
make_transformer_symbol
()¶ create the transformer simbol :return:
-
mouseDoubleClickEvent
(event)¶ On double click, edit :param event: :return:
-
mousePressEvent
(QGraphicsSceneMouseEvent)¶ mouse press: display the editor :param QGraphicsSceneMouseEvent: :return:
-
plot_profiles
()¶ Plot the time series profiles @return:
-
redraw
()¶ Redraw the line with the given positions @return:
-
reduce
()¶ Reduce this branch
-
remove
()¶ Remove this object in the diagram and the API @return:
-
remove_symbol
()¶
-
remove_widget
()¶ Remove this object in the diagram @return:
-
setBeginPos
(pos1)¶ Set the starting position @param pos1: @return:
-
setEndPos
(endpos)¶ Set the starting position @param endpos: @return:
-
setFromPort
(fromPort)¶ Set the From terminal in a connection @param fromPort: @return:
-
setToPort
(toPort)¶ Set the To terminal in a connection @param toPort: @return:
-
setToolTipText
(toolTip: str)¶ Set branch tool tip text Args:
toolTip: text
-
set_enable
(val=True)¶ Set the enable value, graphically and in the API @param val: @return:
-
set_pen
(pen)¶ Set pen to all objects Args:
pen:
-
tap_down
()¶ Set one tap down
-
tap_up
()¶ Set one tap up
-
update_symbol
()¶ Make the branch symbol :return:
-
-
class
GridCal.Gui.GridEditorWidget.
BusGraphicItem
(diagramScene, name='Untitled', parent=None, index=0, editor=None, bus: GridCal.Engine.Devices.bus.Bus = None, pos: PySide2.QtCore.QPoint = None)¶ Bases:
PySide2.QtWidgets.QGraphicsRectItem
Represents a block in the diagram Has an x and y and width and height width and height can only be adjusted with a tip in the lower right corner.
- in and output ports
- parameters
- description
-
adapt
()¶ Set the bus width according to the label text
-
add_battery
(api_obj=None)¶ Returns:
-
add_big_marker
(color=PySide2.QtCore.Qt.GlobalColor.red)¶ Add a big marker to the bus Args:
color: Qt Color ot the marker
-
add_generator
(api_obj=None)¶ Returns:
-
add_load
(api_obj=None)¶ Returns:
-
add_shunt
(api_obj=None)¶ Returns:
-
add_static_generator
(api_obj=None)¶ Returns:
-
arrange_children
()¶ This function sorts the load and generators icons Returns:
Nothing
-
change_size
(w, h)¶ Resize block function @param w: @param h: @return:
-
contextMenuEvent
(event)¶ Display context menu @param event: @return:
-
create_children_icons
()¶ Create the icons of the elements that are attached to the API bus object Returns:
Nothing
-
delete_all_connections
()¶
-
delete_big_marker
()¶ Delete the big marker
-
enable_disable_sc
()¶ Returns:
-
enable_disable_toggle
()¶ Toggle bus element state @return:
-
merge
(other_bus_graphic)¶
-
mouseDoubleClickEvent
(event)¶ Mouse double click :param event: event object
-
mouseMoveEvent
(event: PySide2.QtWidgets.QGraphicsSceneMouseEvent)¶ On mouse move of this object… Args:
event: QGraphicsSceneMouseEvent inherited
-
mousePressEvent
(event)¶ mouse press: display the editor :param QGraphicsSceneMouseEvent: :return:
-
plot_profiles
()¶ @return:
-
reduce
()¶ Reduce this bus :return:
-
remove
()¶ Remove this element @return:
-
set_tile_color
(brush)¶ Set the color of the title Args:
brush: Qt Color
-
update
()¶ Update the object :return:
-
class
GridCal.Gui.GridEditorWidget.
Circle
(parent)¶ Bases:
GridCal.Gui.GridEditorWidget.LineUpdateMixin
,PySide2.QtWidgets.QGraphicsEllipseItem
-
class
GridCal.Gui.GridEditorWidget.
DiagramScene
(parent=None, circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit = None)¶ Bases:
PySide2.QtWidgets.QGraphicsScene
-
mouseMoveEvent
(mouseEvent)¶ @param mouseEvent: @return:
-
mouseReleaseEvent
(mouseEvent)¶ @param mouseEvent: @return:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.GridEditorWidget.
EditorGraphicsView
(scene, parent=None, editor=None, lat0=42, lon0=55, zoom=3)¶ Bases:
PySide2.QtWidgets.QGraphicsView
-
adapt_map_size
()¶
-
add_bus
(bus: GridCal.Engine.Devices.bus.Bus, explode_factor=1.0)¶ Add bus Args:
bus: GridCal Bus object explode_factor: factor to position the node
-
dragEnterEvent
(event)¶ @param event: @return:
-
dragMoveEvent
(event)¶ Move element @param event: @return:
-
dropEvent
(event)¶ Create an element @param event: @return:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
view_map
(flag=True)¶ Parameters: flag – Returns:
-
wheelEvent
(event)¶ Zoom @param event: @return:
-
-
class
GridCal.Gui.GridEditorWidget.
GeneralItem
¶ Bases:
object
-
contextMenuEvent
(event)¶
-
delete_all_connections
()¶
-
editParameters
()¶
-
remove_
()¶ @return:
-
rotate
(angle)¶
-
rotate_clockwise
()¶
-
rotate_counterclockwise
()¶
-
-
class
GridCal.Gui.GridEditorWidget.
GeneratorGraphicItem
(parent, api_obj, diagramScene)¶ Bases:
PySide2.QtWidgets.QGraphicsItemGroup
-
contextMenuEvent
(event)¶ Display context menu @param event: @return:
-
enable_disable_toggle
()¶ @return:
-
mousePressEvent
(QGraphicsSceneMouseEvent)¶ mouse press: display the editor :param QGraphicsSceneMouseEvent: :return:
-
plot
()¶ Plot API objects profiles
-
remove
()¶ Remove this element @return:
-
set_enable
(val=True)¶ Set the enable value, graphically and in the API @param val: @return:
-
update_line
(pos)¶ Update the line that joins the parent and this object :param pos: position of this object
-
-
class
GridCal.Gui.GridEditorWidget.
GridEditor
(circuit: GridCal.Engine.Core.multi_circuit.MultiCircuit, lat0=42, lon0=55, zoom=3)¶ Bases:
PySide2.QtWidgets.QSplitter
-
add_branch
(branch)¶ Add branch to the schematic :param branch: Branch object
-
auto_layout
()¶ Automatic layout of the nodes
-
bigger_nodes
()¶ Expand the grid @return:
-
center_nodes
()¶ Center the view in the nodes @return: Nothing
-
export
(filename, w=1920, h=1080)¶ Save the grid to a png file :return:
-
sceneMouseMoveEvent
(event)¶ @param event: @return:
-
sceneMouseReleaseEvent
(event)¶ Finalize the branch creation if its drawing ends in a terminal @param event: @return:
-
schematic_from_api
(explode_factor=1.0)¶ Generate schematic from the API :param explode_factor: factor to separate the nodes :return: Nothing
-
set_limits
(min_x, max_x, min_y, max_y, margin_factor=0.1)¶ Set the picture limits :param min_x: Minimum x value of the buses location :param max_x: Maximum x value of the buses location :param min_y: Minimum y value of the buses location :param max_y: Maximum y value of the buses location :param margin_factor: factor of separation between the buses
-
smaller_nodes
()¶ Contract the grid @return:
-
startConnection
(port: GridCal.Gui.GridEditorWidget.TerminalItem)¶ Start the branch creation @param port: @return:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.GridEditorWidget.
HandleItem
(parent=None)¶ Bases:
PySide2.QtWidgets.QGraphicsEllipseItem
A handle that can be moved by the mouse: Element to resize the boxes
-
itemChange
(change, value)¶ @param change: @param value: @return:
-
-
class
GridCal.Gui.GridEditorWidget.
LibraryModel
(parent=None)¶ Bases:
PySide2.QtGui.QStandardItemModel
Items model to host the draggable icons
-
mimeData
(idxs)¶ @param idxs: @return:
-
mimeTypes
()¶ @return:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.GridEditorWidget.
LineEditor
(branch: GridCal.Engine.Devices.branch.Branch, Sbase=100)¶ Bases:
PySide2.QtWidgets.QDialog
-
accept_click
()¶ Set the values :return:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.GridEditorWidget.
LineUpdateMixin
(parent)¶ Bases:
object
-
itemChange
(change, value)¶
-
-
class
GridCal.Gui.GridEditorWidget.
LoadGraphicItem
(parent, api_obj, diagramScene)¶ Bases:
PySide2.QtWidgets.QGraphicsItemGroup
-
contextMenuEvent
(event)¶ Display context menu @param event: @return:
-
enable_disable_toggle
()¶ @return:
-
mousePressEvent
(QGraphicsSceneMouseEvent)¶ mouse press: display the editor :param QGraphicsSceneMouseEvent: :return:
-
plot
()¶
-
remove
()¶ Remove this element @return:
-
set_enable
(val=True)¶ Set the enable value, graphically and in the API @param val: @return:
-
update_line
(pos)¶ Update the line that joins the parent and this object :param pos: position of this object
-
-
class
GridCal.Gui.GridEditorWidget.
MapWidget
(scene: PySide2.QtWidgets.QGraphicsScene, view: PySide2.QtWidgets.QGraphicsView, lat0=42, lon0=55, zoom=3)¶ Bases:
PySide2.QtWidgets.QGraphicsRectItem
-
change_size
(w, h)¶ Resize block function @param w: @param h: @return:
-
load_map
(lat0=42, lon0=55, zoom=3)¶ Load a map image into the widget :param lat0: :param lon0: :param zoom: 1~14
-
paint
(painter, option, widget=None)¶ Action that happens on widget repaint :param painter: :param option: :param widget:
-
repaint
()¶ Reload with the last parameters
-
-
class
GridCal.Gui.GridEditorWidget.
ObjectFactory
¶ Bases:
object
-
get_box
()¶ @return:
-
get_circle
()¶ @return:
-
-
class
GridCal.Gui.GridEditorWidget.
ParameterDialog
(parent=None)¶ Bases:
PySide2.QtWidgets.QDialog
-
OK
()¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.GridEditorWidget.
Polygon
(parent)¶ Bases:
GridCal.Gui.GridEditorWidget.LineUpdateMixin
,PySide2.QtWidgets.QGraphicsPolygonItem
-
class
GridCal.Gui.GridEditorWidget.
QLine
(parent)¶ Bases:
GridCal.Gui.GridEditorWidget.LineUpdateMixin
,PySide2.QtWidgets.QGraphicsLineItem
-
class
GridCal.Gui.GridEditorWidget.
ShuntGraphicItem
(parent, api_obj, diagramScene)¶ Bases:
PySide2.QtWidgets.QGraphicsItemGroup
-
contextMenuEvent
(event)¶ Display context menu @param event: @return:
-
enable_disable_toggle
()¶ @return:
-
mousePressEvent
(QGraphicsSceneMouseEvent)¶ mouse press: display the editor :param QGraphicsSceneMouseEvent: :return:
-
plot
()¶ Plot API objects profiles
-
remove
()¶ Remove this element @return:
-
set_enable
(val=True)¶ Set the enable value, graphically and in the API @param val: @return:
-
update_line
(pos)¶ Update the line that joins the parent and this object :param pos: position of this object
-
-
class
GridCal.Gui.GridEditorWidget.
Square
(parent)¶ Bases:
GridCal.Gui.GridEditorWidget.LineUpdateMixin
,PySide2.QtWidgets.QGraphicsRectItem
-
class
GridCal.Gui.GridEditorWidget.
StaticGeneratorGraphicItem
(parent, api_obj, diagramScene)¶ Bases:
PySide2.QtWidgets.QGraphicsItemGroup
-
contextMenuEvent
(event)¶ Display context menu @param event: @return:
-
enable_disable_toggle
()¶ @return:
-
mousePressEvent
(QGraphicsSceneMouseEvent)¶ mouse press: display the editor :param QGraphicsSceneMouseEvent: :return:
-
plot
()¶ Plot API objects profiles
-
remove
()¶ Remove this element @return:
-
set_enable
(val=True)¶ Set the enable value, graphically and in the API @param val: @return:
-
update_line
(pos)¶ Update the line that joins the parent and this object :param pos: position of this object
-
-
class
GridCal.Gui.GridEditorWidget.
TerminalItem
(name, editor=None, parent=None, h=10, w=10)¶ Bases:
PySide2.QtWidgets.QGraphicsRectItem
Represents a connection point to a subsystem
-
itemChange
(change, value)¶ @param change: @param value: This is a QPointF object with the coordinates of the upper left corner of the TerminalItem @return:
-
mousePressEvent
(event)¶ Start a connection Args:
event:Returns:
-
process_callbacks
(value)¶
-
remove_all_connections
()¶ Removes all the terminal connections Returns:
-
-
class
GridCal.Gui.GuiFunctions.
BranchObjectModel
(objects, editable_headers, parent=None, editable=False, non_editable_attributes=[], transposed=False, check_unique=[], catalogue_dict={})¶ Bases:
GridCal.Gui.GuiFunctions.ObjectsModel
-
set_delegates
()¶ Set the cell editor types depending on the attribute_types array :return:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.GuiFunctions.
ComboDelegate
(parent, objects, object_names)¶ Bases:
PySide2.QtWidgets.QItemDelegate
-
commitData
= <PySide2.QtCore.Signal object>¶ A delegate that places a fully functioning QComboBox in every cell of the column to which it’s applied
-
createEditor
(self, parent:PySide2.QtWidgets.QWidget, option:PySide2.QtWidgets.QStyleOptionViewItem, index:PySide2.QtCore.QModelIndex) → PySide2.QtWidgets.QWidget¶
-
currentIndexChanged
()¶
-
setEditorData
(self, editor:PySide2.QtWidgets.QWidget, index:PySide2.QtCore.QModelIndex)¶
-
setModelData
(self, editor:PySide2.QtWidgets.QWidget, model:PySide2.QtCore.QAbstractItemModel, index:PySide2.QtCore.QModelIndex)¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.GuiFunctions.
ComplexDelegate
(parent)¶ Bases:
PySide2.QtWidgets.QItemDelegate
-
commitData
= <PySide2.QtCore.Signal object>¶ A delegate that places a fully functioning Complex Editor in every cell of the column to which it’s applied
-
createEditor
(parent, option, index)¶ Parameters: - parent –
- option –
- index –
Returns:
-
returnPressed
()¶ Returns:
-
setEditorData
(editor, index)¶ Parameters: - editor –
- index –
Returns:
-
setModelData
(editor, model, index)¶ Parameters: - editor –
- model –
- index –
Returns:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.GuiFunctions.
EnumModel
(list_of_enums)¶ Bases:
PySide2.QtCore.QAbstractListModel
-
data
(self, index:PySide2.QtCore.QModelIndex, role:int=PySide2.QtCore.Qt.ItemDataRole.DisplayRole) → typing.Any¶
-
rowCount
(self, parent:PySide2.QtCore.QModelIndex=Invalid(PySide2.QtCore.QModelIndex)) → int¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.GuiFunctions.
FloatDelegate
(parent, min_=-9999, max_=9999)¶ Bases:
PySide2.QtWidgets.QItemDelegate
-
commitData
= <PySide2.QtCore.Signal object>¶ A delegate that places a fully functioning QDoubleSpinBox in every cell of the column to which it’s applied
-
createEditor
(self, parent:PySide2.QtWidgets.QWidget, option:PySide2.QtWidgets.QStyleOptionViewItem, index:PySide2.QtCore.QModelIndex) → PySide2.QtWidgets.QWidget¶
-
returnPressed
()¶
-
setEditorData
(self, editor:PySide2.QtWidgets.QWidget, index:PySide2.QtCore.QModelIndex)¶
-
setModelData
(self, editor:PySide2.QtWidgets.QWidget, model:PySide2.QtCore.QAbstractItemModel, index:PySide2.QtCore.QModelIndex)¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.GuiFunctions.
MeasurementsModel
(circuit)¶ Bases:
PySide2.QtCore.QAbstractListModel
-
data
(self, index:PySide2.QtCore.QModelIndex, role:int=PySide2.QtCore.Qt.ItemDataRole.DisplayRole) → typing.Any¶
-
rowCount
(self, parent:PySide2.QtCore.QModelIndex=Invalid(PySide2.QtCore.QModelIndex)) → int¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.GuiFunctions.
ObjectHistory
(max_undo_states=100)¶ Bases:
object
-
add_state
(action_name, data: dict)¶ Add an undo state :param action_name: name of the action that was performed :param data: dictionary {column index -> profile array}
-
can_redo
()¶ is it possible to redo? :return: True / False
-
can_undo
()¶ Is it possible to undo? :return: True / False
-
redo
()¶ Re-do table :return: table instance
-
undo
()¶ Un-do table :return: table instance
-
-
class
GridCal.Gui.GuiFunctions.
ObjectsModel
(objects, editable_headers, parent=None, editable=False, non_editable_attributes=[], transposed=False, check_unique=[])¶ Bases:
PySide2.QtCore.QAbstractTableModel
Class to populate a Qt table view with the properties of objects
-
attr_taken
(attr, val)¶ Checks if the attribute value is taken :param attr: :param val: :return:
-
columnCount
(parent=None)¶ Get number of columns :param parent: :return:
-
copy_to_column
(index)¶ Copy the value pointed by the index to all the other cells in the column :param index: QModelIndex instance :return:
-
data
(index, role=None)¶ Get the data to display :param index: :param role: :return:
-
data_with_type
(index)¶ Get the data to display :param index: :return:
-
flags
(index)¶ Get the display mode :param index: :return:
-
headerData
(p_int, orientation, role)¶ Get the headers to display :param p_int: :param orientation: :param role: :return:
-
rowCount
(parent=None)¶ Get number of rows :param parent: :return:
-
setData
(index, value, role=None)¶ Set data by simple editor (whatever text) :param index: :param value: :param role: :return:
-
set_delegates
()¶ Set the cell editor types depending on the attribute_types array :return:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
update
()¶ update table
-
-
class
GridCal.Gui.GuiFunctions.
PandasModel
(data: pandas.core.frame.DataFrame, parent=None, editable=False, editable_min_idx=-1, decimals=6)¶ Bases:
PySide2.QtCore.QAbstractTableModel
Class to populate a Qt table view with a pandas data frame
-
columnCount
(parent=None)¶ Parameters: parent – Returns:
-
copy_to_clipboard
(mode=None)¶ Copy profiles to clipboard Args:
mode: ‘real’, ‘imag’, ‘abs’
-
copy_to_column
(row, col)¶ Copies one value to all the column @param row: Row of the value @param col: Column of the value @return: Nothing
-
data
(index, role=PySide2.QtCore.Qt.ItemDataRole.DisplayRole)¶ Parameters: - index –
- role –
Returns:
-
flags
(self, index:PySide2.QtCore.QModelIndex) → PySide2.QtCore.Qt.ItemFlags¶
-
get_data
(mode=None)¶ - Args:
- mode: ‘real’, ‘imag’, ‘abs’
Returns: index, columns, data
-
headerData
(p_int, orientation, role)¶ Parameters: - p_int –
- orientation –
- role –
Returns:
-
rowCount
(parent=None)¶ Parameters: parent – Returns:
-
save_to_excel
(file_name, mode)¶ - Args:
- file_name: mode: ‘real’, ‘imag’, ‘abs’
Returns:
-
setData
(index, value, role=PySide2.QtCore.Qt.ItemDataRole.DisplayRole)¶ Parameters: - index –
- value –
- role –
Returns:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.GuiFunctions.
ProfilesModel
(multi_circuit, device_type: GridCal.Engine.Devices.meta_devices.DeviceType, magnitude, format, parent, max_undo_states=100)¶ Bases:
PySide2.QtCore.QAbstractTableModel
Class to populate a Qt table view with profiles from objects
-
add_state
(columns, action_name='')¶ Compile data of an action and store the data in the undo history :param columns: list of column indices changed :param action_name: name of the action :return: None
-
columnCount
(parent=None)¶ Get number of columns :param parent: :return:
-
copy_to_clipboard
()¶ Copy profiles to clipboard
-
data
(index, role=PySide2.QtCore.Qt.ItemDataRole.DisplayRole)¶ Get the data to display :param index: :param role: :return:
-
flags
(index)¶ Get the display mode :param index: :return:
-
headerData
(p_int, orientation, role)¶ Get the headers to display :param p_int: :param orientation: :param role: :return:
-
paste_from_clipboard
(row_idx=0, col_idx=0)¶ - Args:
- row_idx: col_idx:
-
redo
()¶ Re-do table changes
-
restore
(data: dict)¶ Set profiles data from undo history :param data: dictionary comming from the history :return:
-
rowCount
(parent=None)¶ Get number of rows :param parent: :return:
-
setData
(index, value, role=PySide2.QtCore.Qt.ItemDataRole.DisplayRole)¶ Set data by simple editor (whatever text) :param index: :param value: :param role: :return:
-
set_delegates
()¶ Set the cell editor types depending on the attribute_types array :return:
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
undo
()¶ Un-do table changes
-
update
()¶
-
-
class
GridCal.Gui.GuiFunctions.
TextDelegate
(parent)¶ Bases:
PySide2.QtWidgets.QItemDelegate
-
commitData
= <PySide2.QtCore.Signal object>¶ A delegate that places a fully functioning QLineEdit in every cell of the column to which it’s applied
-
createEditor
(self, parent:PySide2.QtWidgets.QWidget, option:PySide2.QtWidgets.QStyleOptionViewItem, index:PySide2.QtCore.QModelIndex) → PySide2.QtWidgets.QWidget¶
-
returnPressed
()¶
-
setEditorData
(self, editor:PySide2.QtWidgets.QWidget, index:PySide2.QtCore.QModelIndex)¶
-
setModelData
(self, editor:PySide2.QtWidgets.QWidget, model:PySide2.QtCore.QAbstractItemModel, index:PySide2.QtCore.QModelIndex)¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
GridCal.Gui.GuiFunctions.
TreeDelegate
(parent, data={})¶ Bases:
PySide2.QtWidgets.QItemDelegate
-
commitData
= <PySide2.QtCore.Signal object>¶ A delegate that places a fully functioning QComboBox in every cell of the column to which it’s applied
-
createEditor
(self, parent:PySide2.QtWidgets.QWidget, option:PySide2.QtWidgets.QStyleOptionViewItem, index:PySide2.QtCore.QModelIndex) → PySide2.QtWidgets.QWidget¶
-
double_click
()¶
-
setEditorData
(self, editor:PySide2.QtWidgets.QWidget, index:PySide2.QtCore.QModelIndex)¶
-
setModelData
(self, editor:PySide2.QtWidgets.QWidget, model:PySide2.QtCore.QAbstractItemModel, index:PySide2.QtCore.QModelIndex)¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
GridCal.Gui.GuiFunctions.
get_checked_indices
(mdl: <PySide2.QtGui.QStandardItemModel object at 0x7f00ff9f3e48>)¶ Get a list of the selected indices in a QStandardItemModel :param mdl: :return:
-
GridCal.Gui.GuiFunctions.
get_list_model
(lst, checks=False)¶ Pass a list to a list model
Theory behind GridCal¶
GridCal has a great deal of numerical algorithms with little innovations that make this program possible. The featured sections try to describe these innovations such that you can extend on them.
The assets manager: from objects to matrices¶
One of the key things that make GridCal special is that the devices of the electrical grids are handled by an object-oriented asset manager. This means that the real-life objects like generators are objects in GridCal too, instead of a row in a database or table. This makes the handling of the information very flexible and maintainable. If I had to pinpoint the biggest advantage of GridCal it would be this one.
Most (if not all) other open source grid calculation tools use tables as input; The advantage of a table based management of the information is that it is more or less easy to compose the calculation matrices from those tables. The disadvantage is that maintaining and extending a table-based model is hard. GridCal started out being table-based too, but soon this approach was disregarded because of the limitations this design imposes.
This object oriented approach and the structure used in GridCal seems to make it harder for most electrical engineers when getting started developing with GridCal. It is hard, because the structure might seem over-engineered, however it is this structure what enables seamless multi-island calculations and the easy handling of time series, so it is key to explain “why” and “how”. In this section I’ll explain the information “compilation” procedure used in GridCal, hoping that this makes GridCal more approachable for future contributors.
Structure¶
The structure used to compile the information might seem convoluted and unnecessary. Experience has proven that this structure is very fast and it scales well (it is future-proof). Bear in mind that GridCal is not only a calculation library, but it tries to make it as simple as possible for the user to input data, hence there is a careful equilibrium between usability and performance.
MultiCircuit¶
The multi-circuit, or asset manager is the main object in GridCal. It represents a group of objects conforming an electrical grid
NumericalCircuit¶
The numerical circuit contains the information of the objects in 1-dimensional arrays (vectors) ready to compute the topology of the grid and the calculation matrices and vectors. It also contains the connectivity matrices between objects.
This module is the one doing all the heavy lifting; For the computations ahead we will need to have a number of admittance-based matrices. We will compose matrices and vectors for the complete circuit, and then split those per circuit island (CalculationInputs objects). Remember that the calculation matrices are only valid for island circuits, this is because multi-island circuits present singular admittance matrices that lead to no numerical solution by their own.

Element bus aggregations
The logic is to have a vector of magnitudes of an object type (i.e. all the active power power for all the generators) and a connectivity matrix that relates the generators with the buses of the grid. Multiplying the connectivity matrix by the element magnitudes vector we obtain the buses magnitudes vector that we need for calculation.
Power, current and voltage vectors¶
Power injections complex array:
Current complex injections array:
Where:
Magnitude | Dimensions | Description |
---|---|---|
![]() |
#bus, 1 | Array of complex power injections due to the load (will have a negative sign). Size: number of buses. |
![]() |
#load, #bus | Connectivity of loads and buses. |
![]() |
#load, 1 | Array of complex load power values |
![]() |
#bus, 1 | Connectivity of loads and buses. |
![]() |
#generators, #bus | Connectivity of generators and buses. |
![]() |
#generators, #1 | Array of generators power injections. |
![]() |
#bus, 1 | Nodal power injections array (positive: generation, negative: load). |
![]() |
#load, 1 | Array of complex load current values |
![]() |
#bus, 1 | Nodal current injections array (positive: generation, negative: load). |
Admittance matrix¶
The calculation of the admittance matrix in GridCal is completely vectorized. It features
Put together the branch magnitudes to composes the Series admittance the shunt admittance and the tap shift.
Where:
Magnitude | Dimensions | Units | Description |
---|---|---|---|
![]() |
#branch, 1 | p.u. | Array of branch series admittances. |
![]() |
#branch, 1 | p.u. | Array of branch shunt admittances. |
![]() |
#branch, 1 | p.u. | Array of branch complex tap shifts. |
![]() |
#branch, 1 | p.u. | Array of branch resistance. |
![]() |
#branch, 1 | p.u. | Array of branch reactances. |
![]() |
#branch, 1 | p.u. | Array of branch conductances. |
![]() |
#branch, 1 | p.u. | Array of branch susceptances. |
![]() |
#branch, 1 | p.u. | Array of tap modules. |
![]() |
#branch, 1 | Radians | Array of tap shift angles. |
Compute the branch primitives:
Magnitude | Dimensions | Description |
---|---|---|
|
#branch, 1 | Arrays of the bus connected admittances from-from, to-to, from-to and to-from |
![]() ![]() |
#branch, 1 | Array of tap modules that appear due to the voltage difference rating from transformers and the bus rating at the “from” and “to” side of a transformer branch. |
Compose the “from”, “to” and complete admittance matrices:
Where:
Magnitude | Dimensions | Description |
---|---|---|
![]() |
#bus, #bus | Diagonal sparse matrix of the shunt admittances due to the load admittance component and the shunt admittances. |
![]() |
#shunt, #bus | Connectivity of shunts and buses. |
![]() |
#shunt, 1 | Array of complex admittances from the shunt devices. |
![]() |
#load, #bus | Connectivity of loads and buses. |
![]() |
#load, 1 | Array of complex admittances from the load devices. |
![]() ![]() |
#branch, #bus | Connectivity matrices of branches and “from” and “to” buses. |
![]() ![]() |
#branch, #bus | Admittance matrices of branches and “from” and “to” buses. |
![]() |
#bus, #bus | Circuit admittance matrix. |
A snippet from the code where the admittances are computed:
# form the connectivity matrices with the states applied
states_dia = diags(self.branch_states)
Cf = states_dia * self.C_branch_bus_f
Ct = states_dia * self.C_branch_bus_t
# use the specified of the temperature-corrected resistance
if apply_temperature:
R = self.R_corrected
else:
R = self.R
# modify the branches impedance with the lower, upper tolerance values
if branch_tolerance_mode == BranchImpedanceMode.Lower:
R *= (1 - self.impedance_tolerance / 100.0)
elif branch_tolerance_mode == BranchImpedanceMode.Upper:
R *= (1 + self.impedance_tolerance / 100.0)
else:
pass
Ys = 1.0 / (R + 1.0j * self.X)
GBc = self.G + 1.0j * self.B
tap = self.tap_mod * np.exp(1.0j * self.tap_ang)
# branch primitives in vector form
Ytt = (Ys + GBc / 2.0) / (self.tap_t * self.tap_t)
Yff = (Ys + GBc / 2.0) / (self.tap_f * self.tap_f * tap * np.conj(tap))
Yft = - Ys / (self.tap_f * self.tap_t * np.conj(tap))
Ytf = - Ys / (self.tap_t * self.tap_f * tap)
# form the admittance matrices
Yf = diags(Yff) * Cf + diags(Yft) * Ct
Yt = diags(Ytf) * Cf + diags(Ytt) * Ct
Ybus = csc_matrix(Cf.T * Yf + Ct.T * Yt + diags(Ysh))
Adjacency matrix¶
The computation of the circuit adjacency matrix from matrices that we need anyway for the admittance matrix computation is a very efficient way of dealing with the topological computation. First we establish the total branch-bus connectivity matrix:
Then we compute the bus-bus connectivity matrix, which is the graph adjacency matrix:
Islands detection¶
The admittance matrix of a circuit with more than one island is singular. Therefore, the circuit has to be split in sub-circuits in order to be solved. The suggested algorithm to find the islands of a circuit is the Depth First Search algorithm (DFS).
Previously it was already determined that the circuit complete graph is given by
the Bus-Bus connectivity matrix . This matrix is also known as the
node adjacency matrix. For algorithmic purposes we will call it the adjacency matrix
.
As a side note, the matrix
is a sparse matrix.
For algorithmic purposes, is chosen to be a CSC sparse matrix.
This is important because the following algorithm uses the CSC sparse structure to
find the adjacent elements of a node.
The following function implements the non-recursive (hence faster) version of the DFS algorithm, which traverses the bus-bus connectivity matrix (also known as the adjacent graph matrix)
def find_islands(A):
"""
Method to get the islands of a graph
This is the non-recursive version
:param: A: Circuit adjacency sparse matrix in CSC format
:return: islands list where each element is a list of the node indices of the island
"""
# Mark all the vertices as not visited
visited = np.zeros(self.node_number, dtype=bool)
# storage structure for the islands (list of lists)
islands = list()
# set the island index
island_idx = 0
# go though all the vertices...
for node in range(self.node_number):
# if the node has not been visited...
if not visited[node]:
# add new island, because the recursive process has already
# visited all the island connected to v
islands.append(list())
# -------------------------------------------------------------------------
# DFS: store all the reachable vertices into the island from current
# vertex "node".
# declare a stack with the initial node to visit (node)
stack = list()
stack.append(node)
while len(stack) > 0:
# pick the first element of the stack
v = stack.pop(0)
# if v has not been visited...
if not visited[v]:
# mark as visited
visited[v] = True
# add element to the island
islands[island_idx].append(v)
# Add the neighbours of v to the stack
start = A.indptr[v]
end = A.indptr[v + 1]
for i in range(start, end):
k = A.indices[i] # get the column index in the CSC scheme
if not visited[k]:
stack.append(k)
else:
pass
else:
pass
# -----------------------------------------------------------------------
# increase the islands index, because all the other connected vertices
# have been visited
island_idx += 1
else:
pass
# sort the islands to maintain raccord
for island in islands:
island.sort()
return islands
The function returns a list (island) where each element is a list of the node indices of the island. These are used to slice the previously computed arrays so that each array slice is copied to the apropriate instance of CalculationInputs.
CalculationInputs¶
This object contains the calculation arrays already split by island. Hence this object contains information such as the island admittance matrix, the power injections and any other numerical array that the solvers may need.
Universal Branch Model¶
This section describes the branch model implemented in GridCal. This branch model is a positive sequence model that has been formulated such that it is state of the art.

π model of a branch
To define the π branch model we need to specify the following magnitudes:
Where:
Magnitude | Units | Description |
---|---|---|
![]() |
p.u. | Resistance of the equivalent branch model. |
![]() |
p.u. | Reactance of the equivalent branch model. |
![]() |
p.u. | Shunt conductance of the equivalent branch model. |
![]() |
p.u. | Shunt susceptance of the equivalent branch model. |
![]() |
p.u. | Transformer tap module. This value indicates the internal voltage regulation and it is around 1. i.e. 0.98, or 1.05. |
![]() |
radians | Phase shift angle. |
![]() |
p.u. | Virtual tap that appears because the difference of bus HV rating and the transformer HV rating. |
![]() |
p.u. | Virtual tap that appears because the difference of bus LV rating and the transformer LV rating. |
GridCal computes and
automatically from the values. Also bear in mind that the sense in
which the transformer is connected matters. This is dealt with automatically as well.
The basic complex magnitudes are:
The compete formulation of the branch primitives for the admittance matrix is:
In GridCal the primitives of all the branches are computed at once in a matrix fashion, but for didactic purposes the non-matrix formulas are included here.
Temperature correction¶
The general branch model of gridCal features correction of the resistance due to the temperature. This feature is most applicable to lines. Usually the wires’ catalogue resistance is measured at 20ºC. To account for corrections GridCal
Where is a parameter that depends of the material of the wires anf
is the temperature
difference between the base and the operational temperatures.
For example
Material | Test temperature (ºC) | ![]() |
---|---|---|
Copper | 20 | 0.004041 |
Copper | 75 | 0.00323 |
Annealed copper | 20 | 0.00393 |
Aluminum | 20 | 0.004308 |
Aluminum | 75 | 0.00330 |
Embedded Tap changer¶
The general branch model features a discrete tap changer to be able to regulate the parameter manually
and automatically from the power flow routines in a realistic way.
Transformer definition from SC test values¶
The transformers are modeled as π branches too. In order to get the series impedance and shunt admittance of the transformer to match the branch model, it is advised to transform the specification sheet values of the device into the desired values. The values to take from the specs sheet are:
: Nominal power in MVA.
: Voltage at the high-voltage side in kV.
: Voltage at the low-voltage side in kV.
: Short circuit voltage in %.
: Copper losses in kW.
: No load current in %.
: Reactance contribution to the HV side. Value from 0 to 1.
: Resistance contribution to the HV side Value from 0 to 1.
Then, the series and shunt impedances are computed as follows:
- Nominal impedance HV (Ohm):
- Nominal impedance LV (Ohm):
- Short circuit impedance (p.u.):
- Short circuit resistance (p.u.):
- Short circuit reactance (p.u.):
- HV resistance (p.u.):
- LV resistance (p.u.):
- HV shunt reactance (p.u.):
- LV shunt reactance (p.u.):
If and
, then:
- Shunt resistance (p.u.):
- Magnetization impedance (p.u.):
- Magnetization reactance (p.u.):
- Magnetizing resistance (p.u.):
else:
- Magnetization reactance (p.u.):
- Magnetizing resistance (p.u.):
The final complex calculated parameters in per unit are:
- Magnetizing impedance (or series impedance):
- Leakage impedance (or shunt impedance):
- Shunt admittance:
Inverse definition of SC values from π model¶
In GridCal I found the need to find the short circuit values () from the branch values (R, X, G, B). Hence the following formulas:
Power Flow¶
The following subsections include theory about the power flow algorithms supported by GridCal. For control modes (both reactive power control and transformer OLTC control), refer to the Power Flow Driver API Reference.
Newton-Raphson¶
All the explanations on this section are implemented here.
Canonical Newton-Raphson¶
The Newton-Raphson method is the standard power flow method tough at schools. GridCal implements slight but important modifications of this method that turns it into a more robust, industry-standard algorithm. The Newton-Raphson method is the first order Taylor approximation of the power flow equation.
The expression to update the voltage solution in the Newton-Raphson algorithm is the following:
Where:
: Voltage vector at the iteration t (current voltage).
: Voltage vector at the iteration t+1 (new voltage).
: Jacobian matrix.
: Specified power vector.
: Calculated power vector using
.
In matrix form we get:
Jacobian in power equations¶
The Jacobian matrix is the derivative of the power flow equation for a given voltage set of values.
Where:
Where:
Here we introduced two complex-valued derivatives:
Where:
: Diagonal matrix formed by a voltage solution.
: Diagonal matrix formed by a voltage solution, where every voltage is divided by its module.
: Diagonal matrix formed by the current injections.
: And of course, this is the circuit full admittance matrix.
This Jacobian form can be used for other methods.
Newton-Raphson-Iwamoto¶
In 1982 S. Iwamoto and Y. Tamura present a method [1] where the Jacobian matrix J is only computed at the beginning, and the iteration control parameter µ is computed on every iteration. In GridCal, J and µ are computed on every iteration getting a more robust method on the expense of a greater computational effort.
The Iwamoto and Tamura’s modification to the Newton-Raphson algorithm consist in finding an optimal acceleration parameter µ that determines the length of the iteration step such that, the very iteration step does not affect negatively the solution process, which is one of the main drawbacks of the Newton-Raphson method:
Here µ is the Iwamoto optimal step size parameter. To compute the parameter µ we must do the following:
The matrix is the Jacobian matrix computed using
the voltage derivative numerically computed as the voltage increment
(voltage difference between the
current and the previous iteration).
There will be three solutions to the polynomial . Only the last solution
will be real, and therefore it is the only valid value for
. The polynomial
can be solved numerically using 1 as the seed.
[1] | Iwamoto, S., and Y. Tamura. “A load flow calculation method for ill-conditioned power systems.”IEEE transactions on power apparatus and systems 4 (1981): 1736-1743. |
Newton-Raphson Line Search¶
The method consists in adding a heuristic piece to the Newton-Raphson routine. This heuristic rule is to set µ=1, and decrease it is the computed error as a result of the voltage update is higher than before. The logic here is to decrease the step length because the update might have gone too far away. The proposed rule is to divide µ by 4 every time the error increases. There are more sophisticated ways to achieve this, but this rule proves to be useful.
The algorithm is then:
Start.
Compute the power mismatch vector
using the initial voltage solution
.
Compute the error. Equation ref{eq:nr_error}.
While
or
:
Compute the Jacobian
Solve the linear system.
Set
.
Assign
to
.
Compute the power mismatch vector
using the latest voltage solution
.
Compute the error.
If the
from the previous iteration:
g1. Decrease
g2. Assign
to
.
g3. Compute the power mismatch vector
using the latest voltage solution
.
g4. Compute the error.
End.
The Newton-Raphson method tends to diverge if the grid is not
perfectly balanced in loading and well conditioned (i.e.: the impedances are not wildly
different in per unit and X>R). The control parameter turns the
Newton-Raphson method into a more controlled method that converges
in most situations.
Newton-Raphson in Current Equations¶
Newton-Raphson in current equations is similar to the regular Newton-Raphson algorithm presented before, but the mismatch is computed with the current instead of power.
The Jacobian is then:
Where:
The mismatch is computed as increments of current:
Where:
The steps of the algorithm are equal to the the algorithm presented in Newton-Raphson.
Levenberg-Marquardt¶
The Levenberg-Marquardt iterative method is often used to solve non-linear least squares problems. in those problems one reduces the calculated error by iteratively solving a system of equations that provides the increment to add to the solution in order to decrease the solution error. So conceptually it applies to the power flow problem.
Set the initial values:
In every iteration:
- Compute the jacobian matrix if ComputeH is true:
- Compute the mismatch in the same order as the jacobian:
- Compute the auxiliary jacobian transformations:
- Compute the first value of
(only in the first iteration):
- Compute the system Matrix:
- Compute the linear system right hand side:
- Solve the system increment:
- Compute the objective function:
- Compute the decision function:
Update values:
If
- Update the voltage solution using
.
Else
Compute the convergence:
As you can see it takes more steps than Newton-Raphson. It is a slower method, but it works better for ill-conditioned and large grids.
DC approximation¶
The so called direct current power flow (or just DC power flow) is a convenient oversimplification of the power flow procedure.
It assumes that in any branch the reactive part of the impedance is much larger than
the resistive part, hence the resistive part is neglected, and that all the voltages
modules are the nominal per unit values. This is, for load nodes and
for the generator nodes, where $v_{set}$ is the generator set
point value.
In order to compute the DC approximation we must perform a transformation. The slack
nodes are removed from the grid, and their influence is maintained by introducing
equivalent currents in all the nodes. The equivalent admittance matrix
() is obtained by removing the rows and columns corresponding
to the slack nodes. Likewise the removed elements conform the
(
) matrix.

Matrix reduction (VD: Slack, PV: Voltage controlled, PQ: Power controlled)
The previous equation computes the DC power injections as the sum of the different factors mentioned:
: Real part of the reduced power injections.
: Currents that appear by removing the slack nodes while keeping their influence, multiplied by the voltage module to obtain power.
: Real part of the grid reduced current injections, multiplied by the voltage module to obtain power.
Once the power injections are computed, the new voltage angles are obtained by:
The new voltage is then:
This solution does usually produces a large power mismatch. That is to be expected because the method is an oversimplification with no iterative convergence criteria, just a straight forward set of operations.
Linear AC Power Flow¶
Following the formulation presented in Linearized AC Load Flow Applied to Analysis in Electric Power Systems [1], we obtain a way to solve circuits in one shot (without iterations) and with quite positive results for a linear approximation.
Where:
Here, is the normal circuit admittance matrix and
is the admittance matrix formed with only series elements of the
model,
this is neglecting all the shunt admittances.
Solving the vector we get
for the pq and pv nodes and
for the pq nodes.
For equivalence with the paper:
[1] | Rossoni, P. / Moreti da Rosa, W. / Antonio Belati, E., Linearized AC Load Flow Applied to Analysis in Electric Power Systems, IEEE Latin America Transactions, 14, 9; 4048-4053, 2016 |
Holomorphic Embedding¶
First introduced by Antonio Trias in 2012 [1], promises to be a non-divergent power flow method. Trias originally developed a version with no voltage controlled nodes (PV), in which the convergence properties are excellent (With this software try to solve any grid without PV nodes to check this affirmation).
The version programmed in GridCal has been adapted from the master thesis of Muthu Kumar Subramanian at the Arizona State University (ASU) [2]. This version includes a formulation of the voltage controlled nodes. My experience indicates that the introduction of the PV control deteriorates the convergence properties of the holomorphic embedding method. However, in many cases, it is the best approximation to a solution. especially when Newton-Raphson does not provide one.
GridCal’s integration contains a vectorized version of the algorithm. This means that the execution in python is much faster than a previous version that uses loops.
Concepts¶
All the power flow algorithms until the HELM method was introduced were iterative and recursive. The helm method is iterative but not recursive. A simple way to think of this is that traditional power flow methods are exploratory, while the HELM method is a planned journey. In theory the HELM method is superior, but in practice the numerical degeneration makes it less ideal.
The fundamental idea of the recursive algorithms is that given a voltage initial point (1 p.u. at every node, usually) the algorithm explores the surroundings of the initial point until a suitable voltage solution is reached or no solution at all is found because the initial point is supposed to be far from the solution.
On the HELM methods, we form a curve that departures from a known mathematically exact solution that is obtained from solving the grid with no power injections. This is possible because with no power injections, the grid equations become linear and straight forward to solve. The arriving point of the curve is the solution that we want to achieve. That curve is best approximated by a Padè approximation. To compute the Padè approximation we need to compute the coefficients of the unknown variables, in our case the voltages (and possibly the reactive powers at the PV nodes).
The HELM formulation consists in the derivation of formulas that enable the calculation of the coefficients of the series that describes the curve from the mathematically know solution to the unknown solution. Once the coefficients are obtained, the Padè approximation computes the voltage solution at the end of the curve, providing the desired voltage solution. The more coefficients we compute the more exact the solution is (this is true until the numerical precision limit is reached).
All this sounds very strange, but it works ;)
If you want to get familiar with this concept, you should read about the homotopy concept. In practice the continuation power flow does the same as the HELM algorithm, it takes a known solution and changes the loading factors until a solution for another state is reached.
Fundamentals¶
The fundamental equation that defines the power flow problem is:
Most usefully represented like this:
The holomorphic embedding is to insert a “travelling” parameter , such
that for
we have an mathematically exact solution of the problem (but
not the solution we’re looking for…), and for
we have the solution
we’re looking for. The other thing to do is to represent the variables to be computed
as McLaurin series. Let’s go step by step.
For we say that
, in this way the
base equation becomes linear, and its solution is mathematically exact.
But for that to be useful in our case we need to split the admittance matrix
into
and
.
is a diagonal matrix,
so it can be expressed as a vector instead (no need for matrix-vector product).
This is what will allow us to find the zero “state” in the holomorphic series
calculation. For we say that
, so we don’t know the voltage
solution, however we can determine a path to get there:
Wait, what?? did you just made this stuff up??, well so far my reasoning is:
- The voltage
is what I have to convert into a series, and the
- series depend of
, so it makes sense to say that
, as it is dependent of
, becomes
.
- The voltage
- Regarding the
that multiplies
, the amount of power
- (
) is what I vary during the travel from
to
, so that is why S has to be accompanied by the traveling parameter
.
- Regarding the
- In my opinion the
is to provoke the first
- voltage coefficients to be one.
, makes
. This is essential for later steps (is a condition to be able to use Padè).
- In my opinion the
The series are expressed as McLaurin equations:
Theorem - Holomorphicity check There’s still something to do. The magnitude
has to be converted into
. This is done in order to make the
function be holomorphic. The holomorphicity condition is tested by the
Cauchy-Riemann condition, this is
, let’s check that:
Which is not zero, obviously. Now with the proposed change:
Yay!, now we’re mathematically happy, since this stuff has no effect in practice because our $alpha$ is not going to be a complex parameter, but for sake of being correct the equation is now:
(End of Theorem)
The fact that is dividing is problematic. We need to
express it as its inverse so it multiplies instead of divide.
Expanding the series and identifying terms of we obtain the expression
to compute the inverse voltage series coefficients:
Now, this equation becomes:
Substituting the series by their McLaurin expressions:
Expanding the series an identifying terms of we obtain the expression
for the voltage coefficients:
This is the HELM fundamental formula derivation for a grid with no voltage controlled nodes (no PV nodes). Once a sufficient number of coefficients are obtained, we still need to use the Padè approximation to get voltage values out of the series.
In the previous formulas, the number of the bus has not been explicitly detailed. All
the and the
are matrices of dimension
(number of coefficients by number of buses in the grid) This
structures are depicted in the figure
Coefficients Structure. For instance
is the
row of the coefficients structure
.

Coefficients Structure
Padè approximation¶
The McLaurinV equation provides us with an expression to obtain the voltage from
the coefficients, knowing that for we get the final voltage results.
So, why do we need any further operation?, and what is this Padè thing?
Well, it is true that the McLaurinV equation provides an approximation of the voltage by means of a series (this is similar to a Taylor approximation), but in practice, the approximation might provide a wrong value for a given number of coefficients. The Padè approximation accelerates the convergence of any given series, so that you get a more accurate result with less coefficients. This means that for the same series of voltage coefficients, using the McLaurinV equation could give a completely wrong result, whereas by applying Padè to those coefficients one could obtain a fairly accurate result.
The Padè approximation is a rational approximation of a function. In our case the
function is , represented by the coefficients structure
. The approximation is valid over a small domain of the function, in
our case the domain is
. The method requires the function to be
continuous and differentiable for
. Hence the Cauchy-Riemann condition.
And yes, our function meets this condition, we tested it before.
GridCal implements two algorithms that perform the Padè approximation; The Padè canonical algorithm, and Wynn’s Padè approximation.
Padè approximation algorithm
The canonical Padè algorithm for our problem is described by:
Here , where
is the number of available voltage coefficients,
which has to be an even number to be exactly divisible by
.
and
are polynomials which coefficients
and
must be
computed. It turns out that if we make the first term of
be
, the function to be approximated is given by the McLaurin expression
(What a happy coincidence!)
The problem now boils down to find the coefficients and
. This
is done by solving two systems of equations. The first one to find
which
does not depend on
, and the second one to get
which does depend
on
.
First linear system: The only unknowns are the coefficients.
Second linear System: The only unknowns are the coefficients.
Once the coefficients are there, you would have defined completely the polynomials
and
, and it is only a matter of evaluating the
Padè approximation equation for
.
This process is done for every column of coefficients
of the structure depicted in the
coefficients structure figure. This means that we have
to perform a Padè approximation for every node, using the one columns of the voltage
coefficients per Padé approximation.
Wynn’s Padè approximation algorithm
Wynn published a paper in 1969 [4] where he proposed a simple calculation method to obtain the Padè approximation. This method is based on a table. Weniger in 1989 publishes his thesis [5] where a faster version of Wynn’s algorithm is provided in Fortran code.
That very Fortran piece of code has been translated into Python and included in GridCal.
One of the advantages of this method over the canonical Padè approximation implementation is that it can be used for every iteration. In the beginning I thought it would be faster but it turns out that it is not faster since the amount of computation increases with the number of coefficients, whereas with the canonical implementation the order of the matrices does not grow dramatically and it is executed the half of the times.
On top of that my experience shows that the canonical implementation provides a more consistent convergence.
Anyway, both implementations are there to be used in the code.
Formulation with PV nodes¶
The section Fundamentals introduces the canonical HELM algorithm. That algorithm does not include the formulation of PV nodes. Other articles published on the subject feature PV formulations that work more or less to some degree. The formulation below is a formulation corrected by myself from a formulation contained here [3], which does not work as published, hence the correction.
Embedding
The following embedding equations are proposed instead of the canonical HELM equations from section Fundamentals.
For Slack nodes:
For PQ nodes:
For PV nodes:
This embedding translates into the following formulation:
Step 1
The formulas are adapted to exemplify a 3-bus system where the bus1 is a slack, the bus 2 is PV and the bus 3 is PQ. This follows the example of the Appendix A of [3].
Compute the initial no-load solution ():
Form the solution vector you can compute the buses calculated
power and then get the reactive power at the PV nodes to initialize
:
The initial inverse voltage coefficients are obtained by:
This step is entirely equivalent to find the no load solution using the Z-Matrix reduction.
Step 2
Construct the system of equations to solve the coefficients of order greater than zero
(). Note that the matrix is the same as constructed for the previous step,
but adding a column and a row for each PV node to account for the reactive power
coefficients. In our 3-bus example, there is only one PV node, so we add only one
column and one row.
Where:
The convolution is defined as:
The system matrix () is the same for all the orders of
,
therefore we only build it once, and we factorize it to solve the subsequent
coefficients.
After the voltages and the reactive power at the PV nodes
is obtained solving the linear system (this equation), we must solve
the inverse voltage coefficients of order
for all the buses:
Step 3
Repeat step 2 until a sufficiently low error is achieved or a maximum number of iterations (coefficients).
The error is computed by comparing the calculated power (eq
Scalc) with the specified power injections
:
[1] | Trias, Antonio. “The holomorphic embedding load flow method.” Power and Energy Society General Meeting, 2012 IEEE. IEEE, 2012. |
[2] | Subramanian, Muthu Kumar. Application of holomorphic embedding to the power-flow problem. Diss. Arizona State University, 2014. |
[3] | (1, 2) Liu, Chengxi, et al. “A multi-dimensional holomorphic embedding method to solve AC power flows.” IEEE Access 5 (2017): 25270-25285. |
[4] | Wynn, P. “The epsilon algorithm and operational formulas of numerical analysis.” Mathematics of Computation 15.74 (1961): 151-158. |
[5] | Weniger, Ernst Joachim. “Nonlinear sequence transformations for the acceleration of convergence and the summation of divergent series.” Computer Physics Reports 10.5-6 (1989): 189-371. |
Post Power Flow (Loading and Losses)¶
As we have seen, the power flow routines compute the voltage at every bus of an island grid. However we do not get from those routines the “power flow” values, this is the power that flows through the branches of the grid. In this section I show how the post power flow values are computed.
First we compute the branches per unit currents:
These are matrix-vector multiplications. The result is the per unit currents flowing through a branch seen from the from bus or from the to bus.
Then we compute the power values:
These are element-wise multiplications, resulting in the per unit power flowing through a branch seen from the from bus or from the to bus.
Now we can compute the losses in MVA as:
And also the branches loading in per unit as:
The variables are:
: From and To bus-branch admittance matrices
: Array of currents at the from buses in p.u.
: Array of currents at the to buses in p.u.
: Array of powers at the from buses in p.u.
: Array of powers at the to buses in p.u.
: Array of voltages at the from buses in p.u.
: Array of voltages at the to buses in p.u.
: Array of branch ratings in MVA.
Continuation power flow¶
The continuation power flow is a technique that traces a trajectory from a base situation given to a combination
of power and voltage
, to another situation determined by another combination of power
. When the final power situation is undefined, then the algorithm continues until the Jacobian is singular,
tracing the voltage collapse curve.
The method uses a predictor-corrector technique to trace this trajectory.
Predictor¶
Corrector¶
Optimal power flow¶
Linear optimal power flow¶
General indices and dimensions
Variable | Description |
---|---|
n | Number of nodes |
m | Number of branches |
ng | Number of generators |
nb | Number of batteries |
nl | Number of loads |
pqpv | Vector of node indices of the the PQ and PV buses. |
vd | Vector of node indices of the the Slack (or VD) buses. |
Objective function¶
The objective function minimizes the cost of generation plus all the slack variables set in the problem.
Power injections¶
This equation is not a restriction but the computation of the power injections (fix and LP variables) that
are injected per node, such that the vector is dimensionally coherent with the number of buses.
Variable | Description | Dimensions | Type | Units |
---|---|---|---|---|
![]() |
Vector of active power per node. | n | Float + LP | p.u. |
![]() |
Bus-Generators connectivity matrix. | n, ng | int | 1/0 |
![]() |
Vector of generators active power. | ng | LP | p.u. |
![]() |
Bus-Batteries connectivity matrix. | nb | int | 1/0 |
![]() |
Vector of batteries active power. | nb | LP | p.u. |
![]() |
Bus-Generators connectivity matrix. | n, nl | int | 1/0 |
![]() |
Vector of active power loads. | nl | Float | p.u. |
![]() |
Vector of active power load slack variables. | nl | LP | p.u. |
Nodal power balance¶
These two restrictions are set as hard equality constraints because we want the electrical balance to be fulfilled.
Note that this formulation splits the slack nodes from the non-slack nodes. This is faithful to the original DC power flow formulation which allows for implicit losses computation.
Equilibrium at the non slack nodes.
Equilibrium at the slack nodes.
Variable | Description | Dimensions | Type | Units |
---|---|---|---|---|
![]() |
Matrix of susceptances. Ideally if the imaginary part of Ybus. | n, n | Float | p.u. |
![]() |
Vector of active power per node. | n | Float + LP | p.u. |
![]() |
Vector of generators voltage angles. | n | LP | radians. |
Branch loading restriction¶
Something else that we need to do is to check that the branch flows respect the established limits. Note that because of the linear simplifications, the computed solution in active power might actually be dangerous for the grid. That is why a real power flow should counter check the OPF solution.
First we compute the arrays of nodal voltage angles for each of the “from” and “to” sides of each branch. This is not a restriction but a simple calculation to aid the next restrictions that apply per branch.
Now, these are restrictions that define that the “from->to” and the “to->from” flows must respect the branch rating.
Another restriction that we may impose is that the loading slacks must be equal, since they represent the extra line capacity required to transport the power in both senses of the transportation.
Variable | Description | Dimensions | Type | Units |
---|---|---|---|---|
![]() |
Vector of series susceptances of the branches. Can be computed as |
m | Float | p.u. |
![]() |
Branch-Bus connectivity matrix at the “from” end of the branches. | m, n | int | 1/0 |
![]() |
Branch-Bus connectivity matrix at the “to” end of the branches. | m, n | int | 1/0 |
![]() |
Vector of bus voltage angles at the “from” end of the branches. | m | LP | radians. |
![]() |
Vector of bus voltage angles at the “to” end of the branches. | m | LP | radians. |
![]() |
Vector of bus voltage angles. | n | LP | radians. |
![]() |
Vector of branch ratings. | m | Float | p.u. |
![]() |
Vector of branch rating slacks in the from->to sense. | m | LP | p.u. |
![]() |
Vector of branch rating slacks in the to->from sense. | m | LP | p.u. |
Linear optimal power flow time series¶
General indices and dimensions
Variable | Description |
---|---|
n | Number of nodes |
m | Number of branches |
ng | Number of generators |
nb | Number of batteries |
nl | Number of loads |
nt | Number of time steps |
pqpv | Vector of node indices of the the PQ and PV buses. |
vd | Vector of node indices of the the Slack (or VD) buses. |
Objective function¶
The objective function minimizes the cost of generation plus all the slack variables set in the problem.
Power injections¶
This equation is not a restriction but the computation of the power injections (fix and LP variables) that
are injected per node, such that the vector is dimensionally coherent with the number of buses.
Variable | Description | Dimensions | Type | Units |
---|---|---|---|---|
![]() |
Matrix of active power per node and time step. | n, nt | Float + LP | p.u. |
![]() |
Bus-Generators connectivity matrix. | n, ng | int | 1/0 |
![]() |
Matrix of generators active power per time step. | ng, nt | LP | p.u. |
![]() |
Bus-Batteries connectivity matrix. | nb | int | 1/0 |
![]() |
Matrix of batteries active power per time step. | nb, nt | LP | p.u. |
![]() |
Bus-Generators connectivity matrix. | n, nl | int | 1/0 |
![]() |
Matrix of active power loads per time step. | nl, nt | Float | p.u. |
![]() |
Matrix of active power load slack variables per time step. | nl, nt | LP | p.u. |
Nodal power balance¶
These two restrictions are set as hard equality constraints because we want the electrical balance to be fulfilled.
Note that this formulation splits the slack nodes from the non-slack nodes. This is faithful to the original DC power flow formulation which allows for implicit losses computation.
Equilibrium at the non slack nodes.
Equilibrium at the slack nodes.
Variable | Description | Dimensions | Type | Units |
---|---|---|---|---|
![]() |
Matrix of susceptances. Ideally if the imaginary part of Ybus. | n, n | Float | p.u. |
![]() |
Matrix of active power per node and per time step. | n, nt | Float + LP | p.u. |
![]() |
Matrix of generators voltage angles per node and per time step. | n, nt | LP | radians. |
Branch loading restriction¶
Something else that we need to do is to check that the branch flows respect the established limits. Note that because of the linear simplifications, the computed solution in active power might actually be dangerous for the grid. That is why a real power flow should counter check the OPF solution.
First we compute the arrays of nodal voltage angles for each of the “from” and “to” sides of each branch. This is not a restriction but a simple calculation to aid the next restrictions that apply per branch.
Now, these are restrictions that define that the “from->to” and the “to->from” flows must respect the branch rating.
Another restriction that we may impose is that the loading slacks must be equal, since they represent the extra line capacity required to transport the power in both senses of the transportation.
Variable | Description | Dimensions | Type | Units |
---|---|---|---|---|
![]() |
Vector of series susceptances of the branches. Can be computed as |
m | Float | p.u. |
![]() |
Branch-Bus connectivity matrix at the “from” end of the branches. | m, n | int | 1/0 |
![]() |
Branch-Bus connectivity matrix at the “to” end of the branches. | m, n | int | 1/0 |
![]() |
Matrix of bus voltage angles at the “from” end of the branches per bus and time step. | m, nt | LP | radians. |
![]() |
Matrix of bus voltage angles at the “to” end of the branches per bus and time step. | m, nt | LP | radians. |
![]() |
Matrix of bus voltage angles per bus and time step. | n, nt | LP | radians. |
![]() |
Matrix of branch ratings per branch and time step. | m, nt | Float | p.u. |
![]() |
Matrix of branch rating slacks in the from->to sense per branch and time step. | m, nt | LP | p.u. |
![]() |
Matrix of branch rating slacks in the to->from sense per branch and time step. | m, nt | LP | p.u. |
Battery discharge restrictions¶
The first value of the batteries’ energy is the initial state of charge () times the battery capacity.
The capacity in the subsequent time steps is the previous capacity minus the power dispatched. Note that the convention is that the positive power is discharged by the battery and the negative power values represent the power charged by the battery.
The batteries’ energy has to be kept within the batteries’ operative ranges.
Variable | Description | Dimensions | Type | Units |
---|---|---|---|---|
![]() |
Matrix of energy stored in the batteries. | nb, nt | LP | p.u. |
![]() |
Vector of initial states of charge. | nb | Float | p.u. |
![]() |
Vector of maximum states of charge. | nb | Float | p.u. |
![]() |
Vector of minimum states of charge. | nb | Float | p.u. |
![]() |
Vector of battery capacities. | nb | Float | h ![]() |
![]() |
Time increment in the interval [t-1, t]. | 1 | Float | |
![]() |
Vector of battery power injections. | nb | LP | p.u. |
![]() |
Vector of Battery efficiency for charge and discharge. | nb | Float | p.u. |
Short Circuit¶
3-Phase Short Circuit¶
First, declare an array of zeros of size equal to the number of nodes in the circuit.
Then, compute the short circuit current at the selected bus and assign
that value in the
position of the array
.
Then, compute the voltage increment for all the circuit nodes as:
Finally, define the voltage at all the nodes as:
Magnitudes:
: Array of fault currents at the system nodes.
: Array of system voltages prior to the failure. This is obtained from the power flow study.
: Impedance of the failure itself. This is a given value, although you can set it to zero if you don’t know.
: system impedance matrix. Obtained as the inverse of the complete system admittance matrix.
Graphical User Interface¶
The user interface of GridCal is written using the Qt graphical interface framework. This allows GridCal to be multi-platform and to have sufficient performance to handle thousands of graphical items in the editor, to be responsive and plenty of other attributes of consumer software.
The graphical user interface (GUI) makes extensive use of tooltip texts. These area yellow tags that appear when you hover the mouse cursor over a button from the interface. The tooltip texts are meant to be explanatory so that reading a manual is not really needed unless you need the technical details. Nevertheless this guide hopes to guide you through the GUI well enough so that the program is usable.
Model view¶
The model view is where all the editing is done.
Schematic editor¶
The schematic view is where you construct the grid in GridCal. The usage is quite simple:
- Drag & Drop the buses from the left upper side into the main panel.
- Click on a bus bar (black line) and drag the link into another bus bar, a branch will be created.
- Branch types can be selected (branch, transformer, line, switch, reactance).
- If you double click a branch and the type is Line or Transformer, a simplified editor will pop up.
- To add loads, generators, shunts, etc… just right click on bus and select from the context menu.
- The context menu from the buses allow plenty of operations such as view the bus profiles (extended is time series results are present) or setting a bus as a short circuit point.
The schematic objects are coloured based on the results of the latest simulation.
When more than one simulation is available (i.e. power flow and power flow time series) the schematic editor is augmented with a bar that allows you to select the appropriate simulation colouring of the grid. When the simulation has a time component, like time series or voltage collapse, the bar will allow you to visualize each individual step of the simulation and navigate through them.
Tabular editor¶
Some times is far more practical to edit the objects in bulk. For that, GridCal features the tabular view of the objects. All the static properties of the objects can be edited here. For the properties with time series we have the “time events” tab.
There are some filtering options that can be performed; The first thing is to set the property to filter by in the drop down menu. Then in the text box you can type a filter criteria. The available criteria area the following:
Symbol | Description | Example |
---|---|---|
< | Less than | <200, <foo |
> | Greater than | >200, >bar |
<= | Less or equal to | <=200, <=foo |
>= | Greater or equal to | >=200, >=bar |
= | Exactly equal. | =node or =600 |
!= | Different from. | !=node or !=600 |
* | The field contains this. This command is only available for strings. | *bus |
For strings the comparison does not take into account the case.
If the branch objects are selected, then it is possible to extend the view with the catalogue of template elements available to assign to each branch. When a template is assigned to a branch, some properties are affected by the template. The properties affected are the resistance (R), reactance (X), Conductance (G), Susceptance (B) and the branch rating (Rate).
Grid analysis and diagnostic¶
GridCal features an analysis and diagnostics tool (F8) that allows to inspect at a glance the main magnitudes of the grid objects. For instance if there were outliers in the branches resistance, it would be evident from the histogram charts.
A detailed table of common problems is provided in the diagnostics tab. This allows you to go back to the tabular editor and fix the issues found.
Templates¶
The branch templates are defined here. The templates are designed to ease the process of defining the properties of the branch objects.
- Wires: A wire is not strictly a branch, but it is required to be able to define an overhead line.
- Overhead lines: It is a composition of wires bundled by phase (A:1, B:2, C:3, Neutral:0) that represents an overhead line. The overhead lines can be further edited using the Overhead Line Editor (see below)
- Underground lines: Underground lines are defined with the zero sequence and positive sequence parameters.
- Sequence lines: Generic sequence lines are defined with the zero sequence and positive sequence parameters.
- Transformers: The three phase transformers are defined with the short circuit study parameters.
Visit the theory section to learn more about these models.
Overhead line editor¶
The overhead line editor allows you to define an overhead line in any way you want, bundling many wires per phase if you need and including the neutral. The equations for this functionality are taken from the EMTP theory book.
Z: This tab shows the series impedance matrices with the reduced neutral (3x3) and without the reduced neutral (4x4) if the neutral wire is present.
Y: This tab shows the shunt admittance matrices with the reduced neutral (3x3) and without the reduced neutral (4x4) if the neutral wire is present.
Time series¶
This screen allows you to visualize, create and manipulate the profiles of the various magnitudes of the program.
The time series is what make GridCal what it is. To handle time series efficiently by design is what made me design this program.
Profiles importer¶
From the time series you can access the time series importer. This is a program to read excel and csv files from which to import the profiles. Each column of the imported file is treated as an individual profile. The imported profiles can be normalized and scaled. Each profile can be assigned in a number of ways to the objects for which the profiles are being imported.
Linking methods:
- Automatically based on the profile name and the object’s names.
- Random links between profiles and objects; Each object is assigned with a random profile.
- Assign the selected profile to all objects.
- Assign the selected profile to the selected objects.
Array viewer¶
The array viewer is an utility to inspect the array-like objects that are being passed to the numerical methods. These are arranged per island of the circuit.
Results¶
The results view is where ou can visualize the results for all the available simulations. This feature stands out from the commercial power systems software where to simply view the results is not standarized or simple.
Tabular view¶
The tabular view of the results displays the same information as the graphical view but numerically such that you can copy it to a spreadsheet software, or save them for later use.
Console¶
The console in GridCal is a very nice addition that allows some degree of automation within the graphical user interface. The console is a normal python console (embedded in a python program!) where the circuit declared in the user interface (app) is accessible (App.circuit).
Some logs from the simulations will be displayed here. Apart from this any python command or operation that you can perform with scripts can be done here.
Settings¶
The general settings are:
- Base power
- GridCal works with the magnitudes in per unit. In the per unit system the base magnitude is set in advance. This is the base value of the power in MVA. It is advised not to be changed.
- Frequency
- The value of the frequency of the grid in Hertz (Hz).
- Use multiprocessing
- For simulations that can be run in parallel, the software allows to use all the processing power by launching simulations ina parallel. This is only available for UNIX systems due to the way parallelism is implemented in the windows versions of python.
- Export visualization
- Factor of resolution when exporting the schematic. This is a multiplier of the resolution 1080 x 1920 pixels.
- Plotting style
- Matplotlib plotting style.
Power flow¶
- Solver
The power flow solver to use.
- Newton-Raphson in power:
- Newton-Raphson in current:
- Newton-Raphson-Iwamoto:
- Levenberg-Marquardt:
- Fast-Decoupled:
- Holomorphic-Embedding:
- Linear AC approximation:
- DC approximation:
All these solvers are covered in the theory section.
- Retry with other methods is failed:
- This option tries other numerical solvers to try to find a power flow solution. This option is relevant because different numerical algorithms may be more suited to certain grid configurations. In general the Newton-Raphson implementation in GridCal includes back-tracing and other innovations that make it a very competitive method to consider by default.
- Automatic precision
- The precision to use for the numerical solvers depends on the magnitude of the power injections. If we are dealing with hundreds of MW, the precision may be 1e-3, but if we are dealing with Watts, the precision has to be greater. The automatic precision checks the loading for a suitable precision such that the results are fine.
- Precision
- Exponent of the numerical precision. i.e. 4 corresponds to 1e-4 MW in p.u. of precision
- Numerical method max. iterations
- Number of “inner” iterations of the numerical method before terminating.
- Outer loop max. iterations
- Number of “outer loop” iterations to figure out the values of the set controls.
- Reactive power control mode
This is the mode of reactive power control for the generators that are set in PV mode.
- No control: The reactive power limits are not enforced.
- Direct: The classic pq-pv switching algorithm.
- Iterative: An iterative algorithm that uses the power flow as objective function to find suitable reactive power limits.
- Q steepness factor (iterative ctrl.)
- Steepness factor for the iterative reactive power control.
Transformer taps control mode
- No control: The transformer voltage taps control is not enforced.
- Direct:
- Iterative:
- Apply temperature correction
- When selected the branches apply the correction of the resistance due to the temperature.
- Apply impedance tolerances
- ???
Optimal power flow¶
- Solver
Optimal power flow solver to use
DC OPF: classic optimal power flow mixing active power with lines reactance. AC OPF: Innovative linear AC optimal power flow based on the AC linear power flow implemented in GridCal.
- Load shedding
- This option activates the load shedding slack. It is possible to assign an arbitrary weight to this slack.
- Generation shedding
- This option activated the generation shedding slack. It is possible to assign an arbitrary weight to this slack.
- Show the real associated values
- Compute a power flow with the OPF results and show that as the OPF results.
- Control batteries
- Control the batteries state of charge when running the optimization in time series.
Voltage stability¶
- Max. Iterations
- Number of iteration to perform at each voltage stability (predictor-corrector) stage.
- Stop at
Point of the curve to top at
- Nose: Stop at the voltage collapse point
- Full: Trace the full curve.
- Use alpha target from the base situation
- The voltage collapse (stability) simulation is a “travel” from a base situation towards a “final” one. When this mode is selected the final situation is a linear combination of the base situation. All the power values are multiplied by the same number.
- Use departure and target points from time series
- When this option is selected the base and the target points are given by time series points. This allows that the base and the final situations to have non even relationships while evolving from the base situation to the target situation.
Stochastic power flow¶
- Precision
- Monte carlo standard deviation to achieve. The number represents the exponent of the precision. i.e. 3 corresponds to 1e-3
- Max. Iterations
- Maximum iterations for Monte Carlo sampling if the simulation does not achieve the selected standard deviation.
- Samples
- Number of samples for the latin hypercube sampling.
- Additional islands until stop
- When simulating the blackout cascading, this is the number of islands that determine the stop of a simulation
Topology¶
- Select branch types to reduce
- The topological reduction is a top feature of GridCal. With it you can remove the influence of the redundant branches. This is specially relevant when you are provided with grids that have thousands of switches and connection branches that add no simulation value. Those can be removed in a very smart way.
- Filter by r+x under threshold
- This feature establishes if to topologically remove branches whose resistance + reactance is lower than a threshold. The threshold is given by the exponent number. i.e. 5 corresponds to r+x < 1e-5.
- Automatic layout algorithm
- Another nice feature in GridCal is the ability to sort bus bar locations according to a graph algorithm. This is especially useful when you are provided with a grid that has no schematic, where the graphical representation depict all the bus bars in the same place.
- Ask before applying
- Raise a question before applying the graph layout algorithm.
- Node expansion factor
- The nodes in GridCal can be expanded (far from each other) or shrink (closer) this parameter set the “explosion” factor that determines how far from each other shall the nodes become.
- Branch rating factor
- For the branch automatic rating, this is the rate multiplier.
- Override values
- If selected any non-zero rate is overridden by the calculated value.
Development¶
Contributing¶
You have found a bug in GridCal or have a suggestion for a new functionality? Then get in touch with us by opening up an issue on the issue board to discuss possible new developments with the community and the maintainers.
Setup your git repository
Note: The following setup is just a suggestion of how to setup your repository and is supposed to make contributing easier, especially for newcomers. If you have a different setup that you are more comfortable with, you do not have to adopt this setup.
If you want to contribute for the first time, you can set up your environment like this:
- If you have not done it yet: install git and create a GitHub account;
- Create a fork of the official GridCal repository by clicking on “Fork” in the official repository;
- Clone the forked repository to your local machine: git clone https://github.com/YOUR-USERNAME/GridCal.git
- Copy the following configuration at the bottom of to the gridcal/.git/config file (the .git folder is hidden, so you might have to enable showing hidden folders) and insert your github username:
[remote "origin"]
url = https://github.com/YOUR-USERNAME/GridCal.git
fetch = +refs/heads/*:refs/remotes/origin/*
pushurl = https://github.com/YOUR-USERNAME/GridCal.git
[remote "upstream"]
url = https://github.com/SanPen/GridCal.git
fetch = +refs/heads/*:refs/remotes/upstream/*
[branch "master"]
remote = origin
merge = refs/heads/master
The master branch is now configured to automatically track the official GridCal master branch. So if you are on the master branch and use:
git fetch upstream
git merge upstream/master
…your local repository will be updated with the newest changes in the official GridCal repository.
Since you cannot push directly to the official GridCal repository, if you are on master and do:
git push
…your push is by default routed to your own fork instead of the official GridCal repository with the setting as defined above.
Contribute
All contributions to the GridCal repository are made through pull requests to the master branch. You can either submit a pull request from the develop branch of your fork or create a special feature branch that you keep the changes on. A feature branch is the way to go if you have multiple issues that you are working on in parallel and want to submit with seperate pull requests. If you only have small, one-time changes to submit, you can also use the master branch to submit your pull request.
If you wish to discuss a contribution before the pull request is ready to be officially submitted, create an issue in the official repository and link to your own fork. Do not create pull requests that are not ready to be merged!
Note: The following guide assumes the remotes are set up as described above. If you have a different setup, you will have to adapt the commands accordingly.
Test Suite
GridCal uses pytest for automatic software testing.
If you make changes to GridCal that you plan to submit, first make sure that all tests are still passing. You can do this locally with:
pytest
If you have added new functionality, you should also add a new function that tests this functionality. pytest automatically detects all functions in the src/tests folder that start with test_ and are located in a file that also starts with test_ as relevant test cases.
Testing with pytest¶
Unit test (for pytest) are included in src/tests. As defined in pytest.ini, all files matching test_*.py are executed by running:
pytest
Files matching *_test.py are not executed; they were not formatted specifically for pytest but were mostly done for manual testing and documentation purposes.
Additional tests should be developped for each new and existing feature. pytest should be run before each commit to prevent easily detectable bugs.
Change log¶
This section describes the changes introduced at each version.
* Short releases indicate the fix of a critical bug.
* Notice that some versions skip numbers. This is not an error, this is because the stupid policy of pypi to not allow to correct packages. Hence if something goes wrong, you need to re-upload with a new version number.
version 3.4.2¶
- Fixed branch saving code (forever hopefully)
version 3.4.1¶
- Added branch voltage and angle drops in the power flow and power flow time series simulations.
- Added cost profiles for the use in the OPF programs.
- Fixed critical bug when applying profile to snapshot.
- Fixed pySide related bug when converting dates.
- Fixed ui bug when setting values in the profiles manually.
version 3.4.0¶
- Now when highlighting the selection, the buses on the schematic are selected. This feature allows to move buses in bulk after any selection kind.
- Added feature to highlight buses based on any numeric property from the grid objects.
- Added “master” delete from the schematic. Now any selection of buses from the schematic can be deleted at once.
version 3.3.9¶
- Improved object filtering.
- Fixed critical bug involving the change to setuptools.
version 3.3.7¶
- Added filtering capabilities to the object browser.
- Added Bus reduction.
- Added bus highlight based on the object filtering.
version 3.3.6¶
- Continued to improved PSS/e .raw support.
- Fixed the bug caused by PySide2 with the excel sheet selection window.
version 3.3.5¶
- Greatly improved PSS/e .raw file import support.
version 3.3.4¶
- The tower names are displayed correctly now.
- Completely switched from PyQt5 to PySide2.
- Added support for PSS/e RAW file format version 29.
- Overall bug fix.
version 3.3.0¶
- Now the branches and the buses have activation profiles. This allows to run time series where the topology changes. Only available for time series for the moment.
- The branches now allow to profile their temperature. This allows to change the resistance to explore heat effects.
- Added undo / redo to the profiles editor. This improves usability quite a bit.
- Added csv files into zip files as the GridCal default format. This allows to use the same logic as with the excel files but with much faster saving and loading times. Especially suited for large grids with large profiles.
- Added error logging for the power flow time series.
- Massive refactoring of the the files in the program structure, hoping to provide a more intuitive interface.
- Replace the internal profiles from Pandas DataFrames to numpy arrays. This makes the processing simpler and more robust.
- Added rating to cables.
- Changed the TransformerType inner property names to shorter ones.
- Plenty of bug fixes.
This documentation is generated using Sphinx and autodoc.