groundinsight 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Christian Ehlert
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,328 @@
1
+ Metadata-Version: 2.1
2
+ Name: groundinsight
3
+ Version: 0.1.0
4
+ Summary: Simulation for grounding systems of electrical power grids
5
+ Home-page: https://github.com/Ce1ectric/groundinsight
6
+ License: MIT
7
+ Author: Christian Ehlert
8
+ Author-email: christian.ehlert@mailbox.org
9
+ Requires-Python: >=3.12,<4.0
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Requires-Dist: black (>=24.8.0,<25.0.0)
15
+ Requires-Dist: licensecheck (>=2024.3,<2025.0)
16
+ Requires-Dist: matplotlib (>=3.9.2,<4.0.0)
17
+ Requires-Dist: mypy (>=1.11.1,<2.0.0)
18
+ Requires-Dist: numpy (>=2.1.0,<3.0.0)
19
+ Requires-Dist: polars (>=1.5.0,<2.0.0)
20
+ Requires-Dist: pydantic (>=2.8.2,<3.0.0)
21
+ Requires-Dist: pytest (>=8.3.2,<9.0.0)
22
+ Requires-Dist: pytest-cov (>=5.0.0,<6.0.0)
23
+ Requires-Dist: scipy (>=1.14.1,<2.0.0)
24
+ Requires-Dist: sqlalchemy (>=2.0.32,<3.0.0)
25
+ Requires-Dist: sympy (>=1.13.2,<2.0.0)
26
+ Project-URL: Repository, https://github.com/Ce1ectric/groundinsight
27
+ Description-Content-Type: text/markdown
28
+
29
+ # Project Title
30
+ **Groundinsight: Advanced Analytics in Grounding Systems**
31
+
32
+ # Project Description
33
+ Groundinsight is a Python package for analyzing the behavior of grounding systems during phase-to-ground faults. It allows you to create a network structure with buses, branches, and fault current sources.
34
+
35
+ The main concept of the project is the creation of Pydantic models representing the physical grid elements and a calculation core using NumPy and SciPy solvers for linear equations.
36
+
37
+ The SQLite interface enables saving and loading networks or element types from data storage using SQLAlchemy. Beyond storing to a database, the use of Pydantic models allows serialization of all elements and saving them as JSON files.
38
+
39
+ Finally, the calculation results can be presented as plots using predefined Matplotlib functions or as a Polars DataFrame, making it easy to filter information or export results with the extensive range of Polars functions.
40
+
41
+ The project has some challenges to be addressed in the future. Large networks with a wide range of frequencies require significant computation time, which could be optimized in future versions with multithreading or multiprocessing. Another aspect is the addition of more interfaces, such as a REST API or additional database interfaces beyond SQLite.
42
+
43
+ In future versions, it could be directly used by other power system calculation tools to extend their functionality to grounding systems.
44
+
45
+ # Technical Background
46
+ Electrical power grids consist of different elements like substations or towers, which are called bus elements, and the connections between them are cables or transmission lines. Below the conducting part for the power supply from the power plants to the consumers are grounding conductors—such as cable shields or grounding wires of an overhead line—which are part of the network. These grounding parts define the behavior of the whole system during phase-to-ground faults.
47
+
48
+ ```mermaid
49
+ mindmap
50
+ root((Power Grids))
51
+ Power Supply System
52
+ Elements
53
+ Buses
54
+ (Substations)
55
+ Branches
56
+ (cables)
57
+ (overhead lines)
58
+ Actions
59
+ (Loadflow)
60
+ (Short-Circuit)
61
+
62
+ Grounding Systems
63
+ Elements
64
+ Grounding Branches
65
+ (cable shields)
66
+ (grounding wires)
67
+ Grounding Buses
68
+ Actions
69
+ (Current Injection)
70
+ ```
71
+
72
+ The general structure of grounding networks and power supply networks is the same, and general methods like node analysis can be performed as in simple load flow analysis.
73
+
74
+ To analyze a grounding network, the general procedure is:
75
+
76
+ 1. Perform a short-circuit calculation.
77
+ 2. Use the results as input for the grounding network.
78
+ 3. Perform the current injection calculations in the grounding network.
79
+
80
+ The physical models used in Groundinsight are based on the following ideas:
81
+
82
+ There are four different elements:
83
+ 1. **Bus elements** which represent the connection to the remote earth (no influence of mutual coupling).
84
+ 2. **Branch elements** which represent the connection between two buses (influence of mutual coupling).
85
+ 3. **Current sources** at a bus.
86
+ 4. **Fault locations** at a bus.
87
+
88
+ To generalize the variety of different buses (substations, towers, or perhaps the connections of a whole low-voltage grid), the relevant parameter is the grounding impedance as a function of two parameters:
89
+ 1. The specific earth resistance ($\rho_E$).
90
+ 2. Frequency ($f$).
91
+
92
+ $$
93
+ Z_G = f(\rho_E, f)
94
+ $$
95
+
96
+ The branches have two different impedances:
97
+ 1. **Self impedance**
98
+ 2. **Mutual impedance** (describes the mutual coupling between the fault current and the grounding conductor).
99
+
100
+ Both impedances depend, like the grounding impedance, on $\rho_E$, $f$, and the length of the conductor.
101
+
102
+ The calculations are based on the general matrix form:
103
+
104
+ $$
105
+ u = Y^{-1}i
106
+ $$
107
+
108
+ - **u** is the node voltage vector for each bus, representing the earth potential rise.
109
+ - **Y** is the admittance matrix filled with the grounding impedances of buses and self impedances of the branches.
110
+ - **i** is the fault current vector filled with the currents of the sources and the mutual coupling currents for each branch.
111
+
112
+ All of the elements can be set as frequency-dependent values.
113
+
114
+ # How to Install and Run the Project
115
+ The package can be installed using pip:
116
+
117
+ ```bash
118
+ pip install groundinsight
119
+ ```
120
+
121
+ # How to Use the Project
122
+ The general workflow of the package is visualized in the diagram:
123
+
124
+ ```mermaid
125
+ ---
126
+ title: Main Concept of Groundinsight
127
+ ---
128
+ flowchart TD
129
+ start((Start))
130
+ finish((End))
131
+ net[Creating a Network]
132
+ types[Creating Relevant Bus and Branch Types]
133
+ buses[Creating Bus Instances]
134
+ source[Creating Current Sources, Faults, and Branches]
135
+ db[(Database)]
136
+ run[Run Calculations]
137
+ analyze[Analyze the Results as DataFrames or Plots]
138
+ start --> net
139
+ net --> types
140
+ types --> buses
141
+ buses --> source
142
+ source --> run
143
+ run --> analyze
144
+ run --> db
145
+ db --> finish
146
+ analyze --> finish
147
+ ```
148
+
149
+ ## Creating Networks and Calculations
150
+
151
+ First, import the main module:
152
+
153
+ ```python
154
+ import groundinsight as gi
155
+ ```
156
+
157
+ Create a network which serves as the base for all other elements and calculations. In this case, this network will perform calculations for different harmonic frequencies of 50 Hz.
158
+
159
+ ```python
160
+ net = gi.create_network(name="MyTestNetwork", frequencies=[50, 250, 350, 450, 550])
161
+ ```
162
+
163
+ The next step is to create a simple bus type and branch type:
164
+
165
+ ```python
166
+ bus_type = gi.BusType(
167
+ name="BusTypeFormulaTest",
168
+ description="Example bus type with parameters",
169
+ system_type="Substation",
170
+ voltage_level=110,
171
+ impedance_formula="rho * 1 + j * f * 1/50",
172
+ )
173
+
174
+ branch_type = gi.BranchType(
175
+ name="TestBranchType",
176
+ description="A test branch type",
177
+ grounding_conductor=True,
178
+ self_impedance_formula="(rho * 0 + 0.25 + j * f * 0.012)*l",
179
+ mutual_impedance_formula="(rho * 0 + 0.0 + j * f * 0.010)*l"
180
+ )
181
+ ```
182
+
183
+ Now, create instances of buses and branches:
184
+
185
+ ```python
186
+ gi.create_bus(name="bus1", type=bus_type, network=net, specific_earth_resistance=100.0)
187
+ gi.create_bus(name="bus2", type=bus_type, network=net, specific_earth_resistance=100.0)
188
+
189
+ gi.create_branch(
190
+ name="branch1",
191
+ type=branch_type,
192
+ from_bus="bus1",
193
+ to_bus="bus2",
194
+ length=line_length,
195
+ specific_earth_resistance=100.0,
196
+ network=net
197
+ )
198
+ ```
199
+
200
+ Add a current source to `bus1`:
201
+
202
+ ```python
203
+ gi.create_source(
204
+ name="source1",
205
+ bus="bus1",
206
+ values={50: 60, 250: 60, 350: 60, 450: 60, 550: 60},
207
+ network=net
208
+ )
209
+ ```
210
+
211
+ Add a fault with corresponding fault scaling to `bus2`. The default scaling is 1 if no other coefficient is given, using a dictionary:
212
+
213
+ ```python
214
+ fault_scaling = {50: 1.0, 250: 0.5, 350: 0.5}
215
+ gi.create_fault(
216
+ name="fault1",
217
+ bus="bus2",
218
+ description="A fault at bus2",
219
+ scalings=fault_scaling,
220
+ network=net
221
+ )
222
+ ```
223
+
224
+ After completing the network and all its components, it is necessary to create the paths from the sources to the faults. This step is optional; if there are no paths in the network object, the fault calculation will run this function:
225
+
226
+ ```python
227
+ gi.create_paths(network=net)
228
+ ```
229
+
230
+ Now, the network object has all the information to calculate the electrical network representation:
231
+
232
+ ```python
233
+ gi.run_fault(network=net, fault_name="fault1")
234
+ ```
235
+
236
+ The results are directly written into the Network object. The results are encapsulated in Pydantic classes as dictionaries within the network.
237
+
238
+ To access the results of the buses or branches, use the available methods. These methods provide the results for all buses or branches during a specific fault:
239
+
240
+ ```python
241
+ res_buses = net.res_buses(fault="fault1")
242
+ res_branches = net.res_branches(fault="fault1")
243
+ ```
244
+
245
+ If you want to get the results for a specific element, you can use the `filter` method from Polars DataFrames:
246
+
247
+ ```python
248
+ import polars as pl
249
+ res_bus1 = res_buses.filter(pl.col("bus_name") == "bus1")
250
+ ```
251
+
252
+ There is one special method that summarizes all faults of the network and returns a DataFrame with the grounding impedances and the reduction factors for each fault:
253
+
254
+ ```python
255
+ net.res_all_impedances()
256
+ ```
257
+
258
+ ## Import and Export
259
+
260
+ In Groundinsight, it is possible to save and load bus or branch types in a SQLite database. The **overwrite** argument can be used to update an existing type.
261
+
262
+ ```python
263
+ gi.start_dbsession() # Default project_path/grounding.db
264
+
265
+ gi.save_bustype_to_db(bus_type, overwrite=True)
266
+ gi.save_branchtype_to_db(branch_type)
267
+
268
+ gi.close_dbsession()
269
+ ```
270
+
271
+ To load types from the database, use a similar method. This will return a dictionary of all types stored in the database:
272
+
273
+ ```python
274
+ gi.start_dbsession(sqlite_path="path_to_data.db")
275
+ bus_types = gi.load_bustypes_from_db()
276
+
277
+ # Print all names of the bus types
278
+ for name, bt in bus_types.items():
279
+ # Iterate over all properties of a bustype
280
+ for prop in bt.__dict__:
281
+ print(f"{prop}: {bt.__dict__[prop]}")
282
+ # Print a newline for readability
283
+ print("\n")
284
+ ```
285
+
286
+ Saving an entire network to the SQLite database can be done with:
287
+
288
+ ```python
289
+ gi.start_dbsession(sqlite_path="path_to_data.db")
290
+ gi.save_network_to_db(network=net, overwrite=False)
291
+ loaded_net = gi.load_network_from_db(name="MyTestNetwork")
292
+ ```
293
+
294
+ Another way to store the network you are currently working on is to export it as a JSON file:
295
+
296
+ ```python
297
+ gi.save_network_to_json(network=net, path="json_path.json")
298
+ loaded_json_net = gi.load_network_from_json(path="json_path.json")
299
+ ```
300
+
301
+ ## Plot the Results
302
+ Groundinsight has simple built-in plot functions. The plot functions are based on the concept that they read a result class and extract the relevant data from it.
303
+
304
+ The earth potential rise over each bus of the network can be visualized with:
305
+
306
+ ```python
307
+ result_1 = net.results["fault1"]
308
+ gi.plot_bus_voltages(result=result_1, title="EPR RMS Values")
309
+ gi.plot_bus_voltages(result=result_1, frequencies=[50], title="EPR for 50 Hz")
310
+ ```
311
+
312
+ Besides the bus voltages, the currents can be plotted as bar charts:
313
+
314
+ ```python
315
+ gi.plot_branch_currents(result=result_1, title="Branch Currents RMS Values")
316
+ gi.plot_bus_currents(result=result_1, title="Bus Currents RMS Values")
317
+ ```
318
+
319
+ # Contributing
320
+ Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
321
+
322
+ Please make sure to update tests as appropriate.
323
+
324
+ # License
325
+ **MIT License** - see the license file for details.
326
+
327
+
328
+
@@ -0,0 +1,299 @@
1
+ # Project Title
2
+ **Groundinsight: Advanced Analytics in Grounding Systems**
3
+
4
+ # Project Description
5
+ Groundinsight is a Python package for analyzing the behavior of grounding systems during phase-to-ground faults. It allows you to create a network structure with buses, branches, and fault current sources.
6
+
7
+ The main concept of the project is the creation of Pydantic models representing the physical grid elements and a calculation core using NumPy and SciPy solvers for linear equations.
8
+
9
+ The SQLite interface enables saving and loading networks or element types from data storage using SQLAlchemy. Beyond storing to a database, the use of Pydantic models allows serialization of all elements and saving them as JSON files.
10
+
11
+ Finally, the calculation results can be presented as plots using predefined Matplotlib functions or as a Polars DataFrame, making it easy to filter information or export results with the extensive range of Polars functions.
12
+
13
+ The project has some challenges to be addressed in the future. Large networks with a wide range of frequencies require significant computation time, which could be optimized in future versions with multithreading or multiprocessing. Another aspect is the addition of more interfaces, such as a REST API or additional database interfaces beyond SQLite.
14
+
15
+ In future versions, it could be directly used by other power system calculation tools to extend their functionality to grounding systems.
16
+
17
+ # Technical Background
18
+ Electrical power grids consist of different elements like substations or towers, which are called bus elements, and the connections between them are cables or transmission lines. Below the conducting part for the power supply from the power plants to the consumers are grounding conductors—such as cable shields or grounding wires of an overhead line—which are part of the network. These grounding parts define the behavior of the whole system during phase-to-ground faults.
19
+
20
+ ```mermaid
21
+ mindmap
22
+ root((Power Grids))
23
+ Power Supply System
24
+ Elements
25
+ Buses
26
+ (Substations)
27
+ Branches
28
+ (cables)
29
+ (overhead lines)
30
+ Actions
31
+ (Loadflow)
32
+ (Short-Circuit)
33
+
34
+ Grounding Systems
35
+ Elements
36
+ Grounding Branches
37
+ (cable shields)
38
+ (grounding wires)
39
+ Grounding Buses
40
+ Actions
41
+ (Current Injection)
42
+ ```
43
+
44
+ The general structure of grounding networks and power supply networks is the same, and general methods like node analysis can be performed as in simple load flow analysis.
45
+
46
+ To analyze a grounding network, the general procedure is:
47
+
48
+ 1. Perform a short-circuit calculation.
49
+ 2. Use the results as input for the grounding network.
50
+ 3. Perform the current injection calculations in the grounding network.
51
+
52
+ The physical models used in Groundinsight are based on the following ideas:
53
+
54
+ There are four different elements:
55
+ 1. **Bus elements** which represent the connection to the remote earth (no influence of mutual coupling).
56
+ 2. **Branch elements** which represent the connection between two buses (influence of mutual coupling).
57
+ 3. **Current sources** at a bus.
58
+ 4. **Fault locations** at a bus.
59
+
60
+ To generalize the variety of different buses (substations, towers, or perhaps the connections of a whole low-voltage grid), the relevant parameter is the grounding impedance as a function of two parameters:
61
+ 1. The specific earth resistance ($\rho_E$).
62
+ 2. Frequency ($f$).
63
+
64
+ $$
65
+ Z_G = f(\rho_E, f)
66
+ $$
67
+
68
+ The branches have two different impedances:
69
+ 1. **Self impedance**
70
+ 2. **Mutual impedance** (describes the mutual coupling between the fault current and the grounding conductor).
71
+
72
+ Both impedances depend, like the grounding impedance, on $\rho_E$, $f$, and the length of the conductor.
73
+
74
+ The calculations are based on the general matrix form:
75
+
76
+ $$
77
+ u = Y^{-1}i
78
+ $$
79
+
80
+ - **u** is the node voltage vector for each bus, representing the earth potential rise.
81
+ - **Y** is the admittance matrix filled with the grounding impedances of buses and self impedances of the branches.
82
+ - **i** is the fault current vector filled with the currents of the sources and the mutual coupling currents for each branch.
83
+
84
+ All of the elements can be set as frequency-dependent values.
85
+
86
+ # How to Install and Run the Project
87
+ The package can be installed using pip:
88
+
89
+ ```bash
90
+ pip install groundinsight
91
+ ```
92
+
93
+ # How to Use the Project
94
+ The general workflow of the package is visualized in the diagram:
95
+
96
+ ```mermaid
97
+ ---
98
+ title: Main Concept of Groundinsight
99
+ ---
100
+ flowchart TD
101
+ start((Start))
102
+ finish((End))
103
+ net[Creating a Network]
104
+ types[Creating Relevant Bus and Branch Types]
105
+ buses[Creating Bus Instances]
106
+ source[Creating Current Sources, Faults, and Branches]
107
+ db[(Database)]
108
+ run[Run Calculations]
109
+ analyze[Analyze the Results as DataFrames or Plots]
110
+ start --> net
111
+ net --> types
112
+ types --> buses
113
+ buses --> source
114
+ source --> run
115
+ run --> analyze
116
+ run --> db
117
+ db --> finish
118
+ analyze --> finish
119
+ ```
120
+
121
+ ## Creating Networks and Calculations
122
+
123
+ First, import the main module:
124
+
125
+ ```python
126
+ import groundinsight as gi
127
+ ```
128
+
129
+ Create a network which serves as the base for all other elements and calculations. In this case, this network will perform calculations for different harmonic frequencies of 50 Hz.
130
+
131
+ ```python
132
+ net = gi.create_network(name="MyTestNetwork", frequencies=[50, 250, 350, 450, 550])
133
+ ```
134
+
135
+ The next step is to create a simple bus type and branch type:
136
+
137
+ ```python
138
+ bus_type = gi.BusType(
139
+ name="BusTypeFormulaTest",
140
+ description="Example bus type with parameters",
141
+ system_type="Substation",
142
+ voltage_level=110,
143
+ impedance_formula="rho * 1 + j * f * 1/50",
144
+ )
145
+
146
+ branch_type = gi.BranchType(
147
+ name="TestBranchType",
148
+ description="A test branch type",
149
+ grounding_conductor=True,
150
+ self_impedance_formula="(rho * 0 + 0.25 + j * f * 0.012)*l",
151
+ mutual_impedance_formula="(rho * 0 + 0.0 + j * f * 0.010)*l"
152
+ )
153
+ ```
154
+
155
+ Now, create instances of buses and branches:
156
+
157
+ ```python
158
+ gi.create_bus(name="bus1", type=bus_type, network=net, specific_earth_resistance=100.0)
159
+ gi.create_bus(name="bus2", type=bus_type, network=net, specific_earth_resistance=100.0)
160
+
161
+ gi.create_branch(
162
+ name="branch1",
163
+ type=branch_type,
164
+ from_bus="bus1",
165
+ to_bus="bus2",
166
+ length=line_length,
167
+ specific_earth_resistance=100.0,
168
+ network=net
169
+ )
170
+ ```
171
+
172
+ Add a current source to `bus1`:
173
+
174
+ ```python
175
+ gi.create_source(
176
+ name="source1",
177
+ bus="bus1",
178
+ values={50: 60, 250: 60, 350: 60, 450: 60, 550: 60},
179
+ network=net
180
+ )
181
+ ```
182
+
183
+ Add a fault with corresponding fault scaling to `bus2`. The default scaling is 1 if no other coefficient is given, using a dictionary:
184
+
185
+ ```python
186
+ fault_scaling = {50: 1.0, 250: 0.5, 350: 0.5}
187
+ gi.create_fault(
188
+ name="fault1",
189
+ bus="bus2",
190
+ description="A fault at bus2",
191
+ scalings=fault_scaling,
192
+ network=net
193
+ )
194
+ ```
195
+
196
+ After completing the network and all its components, it is necessary to create the paths from the sources to the faults. This step is optional; if there are no paths in the network object, the fault calculation will run this function:
197
+
198
+ ```python
199
+ gi.create_paths(network=net)
200
+ ```
201
+
202
+ Now, the network object has all the information to calculate the electrical network representation:
203
+
204
+ ```python
205
+ gi.run_fault(network=net, fault_name="fault1")
206
+ ```
207
+
208
+ The results are directly written into the Network object. The results are encapsulated in Pydantic classes as dictionaries within the network.
209
+
210
+ To access the results of the buses or branches, use the available methods. These methods provide the results for all buses or branches during a specific fault:
211
+
212
+ ```python
213
+ res_buses = net.res_buses(fault="fault1")
214
+ res_branches = net.res_branches(fault="fault1")
215
+ ```
216
+
217
+ If you want to get the results for a specific element, you can use the `filter` method from Polars DataFrames:
218
+
219
+ ```python
220
+ import polars as pl
221
+ res_bus1 = res_buses.filter(pl.col("bus_name") == "bus1")
222
+ ```
223
+
224
+ There is one special method that summarizes all faults of the network and returns a DataFrame with the grounding impedances and the reduction factors for each fault:
225
+
226
+ ```python
227
+ net.res_all_impedances()
228
+ ```
229
+
230
+ ## Import and Export
231
+
232
+ In Groundinsight, it is possible to save and load bus or branch types in a SQLite database. The **overwrite** argument can be used to update an existing type.
233
+
234
+ ```python
235
+ gi.start_dbsession() # Default project_path/grounding.db
236
+
237
+ gi.save_bustype_to_db(bus_type, overwrite=True)
238
+ gi.save_branchtype_to_db(branch_type)
239
+
240
+ gi.close_dbsession()
241
+ ```
242
+
243
+ To load types from the database, use a similar method. This will return a dictionary of all types stored in the database:
244
+
245
+ ```python
246
+ gi.start_dbsession(sqlite_path="path_to_data.db")
247
+ bus_types = gi.load_bustypes_from_db()
248
+
249
+ # Print all names of the bus types
250
+ for name, bt in bus_types.items():
251
+ # Iterate over all properties of a bustype
252
+ for prop in bt.__dict__:
253
+ print(f"{prop}: {bt.__dict__[prop]}")
254
+ # Print a newline for readability
255
+ print("\n")
256
+ ```
257
+
258
+ Saving an entire network to the SQLite database can be done with:
259
+
260
+ ```python
261
+ gi.start_dbsession(sqlite_path="path_to_data.db")
262
+ gi.save_network_to_db(network=net, overwrite=False)
263
+ loaded_net = gi.load_network_from_db(name="MyTestNetwork")
264
+ ```
265
+
266
+ Another way to store the network you are currently working on is to export it as a JSON file:
267
+
268
+ ```python
269
+ gi.save_network_to_json(network=net, path="json_path.json")
270
+ loaded_json_net = gi.load_network_from_json(path="json_path.json")
271
+ ```
272
+
273
+ ## Plot the Results
274
+ Groundinsight has simple built-in plot functions. The plot functions are based on the concept that they read a result class and extract the relevant data from it.
275
+
276
+ The earth potential rise over each bus of the network can be visualized with:
277
+
278
+ ```python
279
+ result_1 = net.results["fault1"]
280
+ gi.plot_bus_voltages(result=result_1, title="EPR RMS Values")
281
+ gi.plot_bus_voltages(result=result_1, frequencies=[50], title="EPR for 50 Hz")
282
+ ```
283
+
284
+ Besides the bus voltages, the currents can be plotted as bar charts:
285
+
286
+ ```python
287
+ gi.plot_branch_currents(result=result_1, title="Branch Currents RMS Values")
288
+ gi.plot_bus_currents(result=result_1, title="Bus Currents RMS Values")
289
+ ```
290
+
291
+ # Contributing
292
+ Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
293
+
294
+ Please make sure to update tests as appropriate.
295
+
296
+ # License
297
+ **MIT License** - see the license file for details.
298
+
299
+
@@ -0,0 +1,36 @@
1
+ [tool.poetry]
2
+ name = "groundinsight"
3
+ version = "0.1.0"
4
+ description = "Simulation for grounding systems of electrical power grids"
5
+ authors = ["Christian Ehlert <christian.ehlert@mailbox.org>"]
6
+ license = "MIT"
7
+ repository = "https://github.com/Ce1ectric/groundinsight"
8
+ readme = "README.md"
9
+ packages = [
10
+ { include = "groundinsight", from = "src" }
11
+ ]
12
+
13
+ [tool.poetry.dependencies]
14
+ python = "^3.12"
15
+ pytest = "^8.3.2"
16
+ pytest-cov = "^5.0.0"
17
+ black = "^24.8.0"
18
+ mypy = "^1.11.1"
19
+ pydantic = "^2.8.2"
20
+ numpy = "^2.1.0"
21
+ sqlalchemy = "^2.0.32"
22
+ polars = "^1.5.0"
23
+ sympy = "^1.13.2"
24
+ matplotlib = "^3.9.2"
25
+ scipy = "^1.14.1"
26
+ licensecheck = "^2024.3"
27
+
28
+
29
+ [tool.poetry.group.dev.dependencies]
30
+ alembic = "^1.13.2"
31
+ sqlalchemy-stubs = "^0.4"
32
+ ipykernel = "^6.29.5"
33
+
34
+ [build-system]
35
+ requires = ["poetry-core"]
36
+ build-backend = "poetry.core.masonry.api"