power-grid-model 1.12.69__py3-none-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl

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.

Potentially problematic release.


This version of power-grid-model might be problematic. Click here for more details.

Files changed (65) hide show
  1. power_grid_model/__init__.py +54 -0
  2. power_grid_model/_core/__init__.py +3 -0
  3. power_grid_model/_core/buffer_handling.py +493 -0
  4. power_grid_model/_core/data_handling.py +195 -0
  5. power_grid_model/_core/data_types.py +143 -0
  6. power_grid_model/_core/dataset_definitions.py +109 -0
  7. power_grid_model/_core/enum.py +226 -0
  8. power_grid_model/_core/error_handling.py +206 -0
  9. power_grid_model/_core/errors.py +130 -0
  10. power_grid_model/_core/index_integer.py +17 -0
  11. power_grid_model/_core/options.py +71 -0
  12. power_grid_model/_core/power_grid_core.py +563 -0
  13. power_grid_model/_core/power_grid_dataset.py +535 -0
  14. power_grid_model/_core/power_grid_meta.py +257 -0
  15. power_grid_model/_core/power_grid_model.py +969 -0
  16. power_grid_model/_core/power_grid_model_c/__init__.py +3 -0
  17. power_grid_model/_core/power_grid_model_c/get_pgm_dll_path.py +63 -0
  18. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/basics.h +255 -0
  19. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/buffer.h +108 -0
  20. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/dataset.h +316 -0
  21. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/dataset_definitions.h +1052 -0
  22. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/handle.h +99 -0
  23. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/meta_data.h +189 -0
  24. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/model.h +125 -0
  25. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/options.h +142 -0
  26. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/serialization.h +118 -0
  27. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c.h +36 -0
  28. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/basics.hpp +65 -0
  29. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/buffer.hpp +61 -0
  30. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/dataset.hpp +220 -0
  31. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/handle.hpp +108 -0
  32. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/meta_data.hpp +84 -0
  33. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/model.hpp +63 -0
  34. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/options.hpp +52 -0
  35. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/serialization.hpp +124 -0
  36. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/utils.hpp +81 -0
  37. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp.hpp +19 -0
  38. power_grid_model/_core/power_grid_model_c/lib/cmake/power_grid_model/power_grid_modelConfig.cmake +37 -0
  39. power_grid_model/_core/power_grid_model_c/lib/cmake/power_grid_model/power_grid_modelConfigVersion.cmake +65 -0
  40. power_grid_model/_core/power_grid_model_c/lib/cmake/power_grid_model/power_grid_modelTargets-release.cmake +19 -0
  41. power_grid_model/_core/power_grid_model_c/lib/cmake/power_grid_model/power_grid_modelTargets.cmake +144 -0
  42. power_grid_model/_core/power_grid_model_c/lib64/libpower_grid_model_c.so +0 -0
  43. power_grid_model/_core/power_grid_model_c/lib64/libpower_grid_model_c.so.1.12.69 +0 -0
  44. power_grid_model/_core/power_grid_model_c/share/LICENSE +292 -0
  45. power_grid_model/_core/power_grid_model_c/share/README.md +15 -0
  46. power_grid_model/_core/serialization.py +317 -0
  47. power_grid_model/_core/typing.py +20 -0
  48. power_grid_model/_core/utils.py +798 -0
  49. power_grid_model/data_types.py +321 -0
  50. power_grid_model/enum.py +27 -0
  51. power_grid_model/errors.py +37 -0
  52. power_grid_model/py.typed +3 -0
  53. power_grid_model/typing.py +43 -0
  54. power_grid_model/utils.py +473 -0
  55. power_grid_model/validation/__init__.py +25 -0
  56. power_grid_model/validation/_rules.py +1171 -0
  57. power_grid_model/validation/_validation.py +1172 -0
  58. power_grid_model/validation/assertions.py +93 -0
  59. power_grid_model/validation/errors.py +602 -0
  60. power_grid_model/validation/utils.py +313 -0
  61. power_grid_model-1.12.69.dist-info/METADATA +178 -0
  62. power_grid_model-1.12.69.dist-info/RECORD +65 -0
  63. power_grid_model-1.12.69.dist-info/WHEEL +6 -0
  64. power_grid_model-1.12.69.dist-info/entry_points.txt +3 -0
  65. power_grid_model-1.12.69.dist-info/licenses/LICENSE +292 -0
@@ -0,0 +1,313 @@
1
+ # SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
2
+ #
3
+ # SPDX-License-Identifier: MPL-2.0
4
+
5
+ """
6
+ Utilities used for validation. Only errors_to_string() is intended for end users.
7
+ """
8
+
9
+ import re
10
+ from typing import Any, cast
11
+
12
+ import numpy as np
13
+
14
+ from power_grid_model._core.dataset_definitions import ComponentType, DatasetType
15
+ from power_grid_model._core.power_grid_meta import power_grid_meta_data
16
+ from power_grid_model.data_types import SingleArray, SingleComponentData, SingleDataset
17
+ from power_grid_model.validation.errors import ValidationError
18
+
19
+
20
+ def _eval_expression(data: np.ndarray, expression: int | float | str) -> np.ndarray:
21
+ """
22
+ Wrapper function that checks the type of the 'expression'. If the expression is a string, it is assumed to be a
23
+ field expression and the expression is validated. Otherwise it is assumed to be a numerical value and the value
24
+ is casted to a numpy 'array'.
25
+
26
+ Args:
27
+ data: A numpy structured array
28
+ expression: A numerical value, or a string, representing a (combination of) field(s)
29
+
30
+ Returns: The number or an evaluation of the field name(s) in the data, always represented as a Numpy 'array'.
31
+
32
+ Examples:
33
+ 123 -> np.array(123)
34
+ 123.4 -> np.array(123.4)
35
+ 'value' -> data['value']
36
+ 'foo/bar' -> data['foo'] / data[bar]
37
+
38
+ """
39
+ if isinstance(expression, str):
40
+ return _eval_field_expression(data, expression)
41
+ return np.array(expression)
42
+
43
+
44
+ def _eval_field_expression(data: np.ndarray, expression: str) -> np.ndarray:
45
+ """
46
+ A field expression can either be the name of a field (e.g. 'field_x') in the data, or a ratio between two fields
47
+ (e.g. 'field_x / field_y'). The expression is checked on validity and then the fields are checked to be present in
48
+ the data. If the expression is a single field name, the field is returned. If it is a ratio, the ratio is
49
+ calculated and returned. Values divided by 0 will result in nan values without warning.
50
+
51
+ Args:
52
+ data: A numpy structured array
53
+ expression: A string, representing a (combination of) field(s)
54
+
55
+ Expression should be a combination of:
56
+ - field names (may contain lower case letters, numbers and underscores)
57
+ - a single mathematical operator /
58
+
59
+ Returns: An evaluation of the field name(s) in the data.
60
+
61
+ Examples:
62
+ 'value' -> data['value']
63
+ 'foo/bar' -> data['foo'] / data['bar']
64
+
65
+ """
66
+ # Validate the expression
67
+ match = re.fullmatch(r"[a-z][a-z0-9_]*(\s*/\s*[a-z][a-z0-9_]*)?", expression)
68
+ if not match:
69
+ raise ValueError(f"Invalid field expression '{expression}'")
70
+
71
+ if data.dtype.names is None:
72
+ raise ValueError("No attributes available in meta")
73
+
74
+ # Find all field names and check if they exist in the dataset
75
+ fields = [f.strip() for f in expression.split("/")]
76
+ for field in fields:
77
+ if field not in data.dtype.names:
78
+ raise KeyError(f"Invalid field name {field}")
79
+
80
+ if len(fields) == 1:
81
+ return data[fields[0]]
82
+
83
+ max_num_fields = 2
84
+ if len(fields) != max_num_fields:
85
+ raise ValueError(f"There should be exactly {max_num_fields} fields, got {len(fields)} fields")
86
+ zero_div = np.logical_or(np.equal(data[fields[1]], 0.0), np.logical_not(np.isfinite(data[fields[1]])))
87
+ if np.any(zero_div):
88
+ result = np.full_like(data[fields[0]], np.nan)
89
+ np.true_divide(data[fields[0]], data[fields[1]], out=result, where=~zero_div)
90
+ return result
91
+ return np.true_divide(data[fields[0]], data[fields[1]])
92
+
93
+
94
+ def _update_input_data(input_data: SingleDataset, update_data: SingleDataset):
95
+ """
96
+ Update the input data using the available non-nan values in the update data.
97
+ """
98
+
99
+ merged_data = {component: array.copy() for component, array in input_data.items()}
100
+ for component in update_data:
101
+ _update_component_data(component, merged_data[component], update_data[component])
102
+ return merged_data
103
+
104
+
105
+ def _update_component_data(
106
+ component: ComponentType, input_data: SingleComponentData, update_data: SingleComponentData
107
+ ) -> None:
108
+ """
109
+ Update the data in a single component data set, with another single component data set,
110
+ indexed on the "id" field and only non-NaN values are overwritten.
111
+ """
112
+ if isinstance(input_data, np.ndarray) and isinstance(update_data, np.ndarray):
113
+ return _update_component_array_data(component=component, input_data=input_data, update_data=update_data)
114
+
115
+ raise NotImplementedError # TODO(mgovers): add support for columnar data
116
+
117
+
118
+ def _update_component_array_data(component: ComponentType, input_data: SingleArray, update_data: SingleArray) -> None:
119
+ """
120
+ Update the data in a numpy array, with another numpy array,
121
+ indexed on the "id" field and only non-NaN values are overwritten.
122
+ """
123
+ batch_dataset_ndim = 2
124
+ if update_data.dtype.names is None:
125
+ raise ValueError("Invalid data format")
126
+
127
+ optional_ids_active = (
128
+ "id" in update_data.dtype.names
129
+ and np.all(update_data["id"] == np.iinfo(update_data["id"].dtype).min)
130
+ and len(update_data["id"]) == len(input_data["id"])
131
+ )
132
+ update_data_ids = input_data["id"] if optional_ids_active else update_data["id"]
133
+
134
+ for field in update_data.dtype.names:
135
+ if field == "id":
136
+ continue
137
+ nan = _nan_type(component, field, DatasetType.update)
138
+ mask = ~np.isnan(update_data[field]) if np.isnan(nan) else np.not_equal(update_data[field], nan)
139
+
140
+ if mask.ndim == batch_dataset_ndim:
141
+ for phase in range(mask.shape[1]):
142
+ # find indexers of to-be-updated object
143
+ sub_mask = mask[:, phase]
144
+ idx = _get_indexer(input_data["id"], update_data_ids[sub_mask])
145
+ # update
146
+ input_data[field][idx, phase] = update_data[field][sub_mask, phase]
147
+ else:
148
+ # find indexers of to-be-updated object
149
+ idx = _get_indexer(input_data["id"], update_data_ids[mask])
150
+ # update
151
+ input_data[field][idx] = update_data[field][mask]
152
+
153
+
154
+ def errors_to_string(
155
+ errors: list[ValidationError] | dict[int, list[ValidationError]] | None,
156
+ name: str = "the data",
157
+ details: bool = False,
158
+ id_lookup: list[str] | dict[int, str] | None = None,
159
+ ) -> str:
160
+ """
161
+ Convert a set of errors (list or dict) to a human readable string representation.
162
+
163
+ Args:
164
+ errors: The error objects. List for input_data only, dict for batch data.
165
+ name: Human understandable name of the dataset, e.g. input_data, or update_data.
166
+ details: Display object ids and error specific information.
167
+ id_lookup: A list or dict (int->str) containing textual object ids
168
+
169
+ Returns:
170
+ A human readable string representation of a set of errors.
171
+ """
172
+ if errors is None or len(errors) == 0:
173
+ return f"{name}: OK"
174
+ if isinstance(errors, dict):
175
+ return "\n".join(errors_to_string(err, f"{name}, batch #{i}", details) for i, err in sorted(errors.items()))
176
+ if len(errors) == 1 and not details:
177
+ return f"There is a validation error in {name}:\n\t{errors[0]}"
178
+ if len(errors) == 1:
179
+ msg = f"There is a validation error in {name}:\n"
180
+ else:
181
+ msg = f"There are {len(errors)} validation errors in {name}:\n"
182
+ if details:
183
+ for error in errors:
184
+ msg += "\n\t" + str(error) + "\n"
185
+ msg += "".join(f"\t\t{k}: {v}\n" for k, v in error.get_context(id_lookup).items())
186
+ else:
187
+ msg += "\n".join(f"{i + 1:>4}. {err}" for i, err in enumerate(errors))
188
+ return msg
189
+
190
+
191
+ def _nan_type(component: ComponentType, field: str, data_type: DatasetType = DatasetType.input):
192
+ """Helper function to retrieve the nan value for a certain field as defined in the power_grid_meta_data."""
193
+ return power_grid_meta_data[data_type][component].nans[field]
194
+
195
+
196
+ def _get_indexer(source: np.ndarray, target: np.ndarray, default_value: int | None = None) -> np.ndarray:
197
+ """
198
+ Given array of values from a source and a target dataset.
199
+ Find the position of each value in the target dataset in the context of the source dataset.
200
+ This is needed to update values in the dataset by id lookup.
201
+ Internally this is done by sorting the input ids, then using binary search lookup.
202
+
203
+ E.g.: Find the position of each id in an update (target) dataset in the input (source) dataset
204
+
205
+ >>> input_ids = [1, 2, 3, 4, 5]
206
+ >>> update_ids = [3]
207
+ >>> assert _get_indexer(input_ids, update_ids) == np.array([2])
208
+
209
+ Args:
210
+ source: array of values in the source dataset
211
+ target: array of values in the target dataset
212
+ default_value (optional): the default index to provide for target values not in source
213
+
214
+ Returns:
215
+ np.ndarray: array of positions of the values from target dataset in the source dataset
216
+ if default_value is None, (source[result] == target)
217
+ else, ((source[result] == target) | (source[result] == default_value))
218
+
219
+ Raises:
220
+ IndexError: if default_value is None and there were values in target that were not in source
221
+ """
222
+
223
+ permutation_sort = np.argsort(source) # complexity O(N_input * logN_input)
224
+ indices = np.searchsorted(source, target, sorter=permutation_sort) # complexity O(N_update * logN_input)
225
+
226
+ if default_value is None:
227
+ return permutation_sort[indices]
228
+
229
+ if len(source) == 0:
230
+ return np.full_like(target, fill_value=default_value)
231
+
232
+ clipped_indices = np.take(permutation_sort, indices, mode="clip")
233
+ return np.where(source[clipped_indices] == target, permutation_sort[clipped_indices], default_value)
234
+
235
+
236
+ def _set_default_value(
237
+ data: SingleDataset, component: ComponentType, field: str, default_value: int | float | np.ndarray
238
+ ):
239
+ """
240
+ This function sets the default value in the data that is to be validated, so the default values are included in the
241
+ validation.
242
+
243
+ Args:
244
+ data: The input/update data set for all components
245
+ component: The component of interest
246
+ field: The field of interest
247
+ default_value: Some values are not required, but will receive a default value in the C++ core. To do a proper
248
+ input validation, these default values should be included in the validation. It can be a fixed value for the
249
+ entire column (int/float) or be different for each element (np.ndarray).
250
+
251
+ Returns:
252
+
253
+ """
254
+ if np.isnan(_nan_type(component, field)):
255
+ mask = np.isnan(data[component][field])
256
+ else:
257
+ mask = data[component][field] == _nan_type(component, field)
258
+ if isinstance(default_value, np.ndarray):
259
+ data[component][field][mask] = default_value[mask]
260
+ else:
261
+ data[component][field][mask] = default_value
262
+
263
+
264
+ def _get_valid_ids(data: SingleDataset, ref_components: ComponentType | list[ComponentType]) -> list[int]:
265
+ """
266
+ This function returns the valid IDs specified by all ref_components.
267
+
268
+ Args:
269
+ data: The input/update data set for all components
270
+ ref_components: The component or components in which we want to look for ids
271
+
272
+ Returns:
273
+ list[int]: the list of valid IDs
274
+ """
275
+ # For convenience, ref_component may be a string and we'll convert it to a 'list' containing that string as it's
276
+ # single element.
277
+ if isinstance(ref_components, (str, ComponentType)):
278
+ ref_components = cast(list[ComponentType], [ref_components])
279
+
280
+ # Create a set of ids by chaining the ids of all ref_components
281
+ valid_ids = set()
282
+ for ref_component in ref_components:
283
+ if ref_component in data:
284
+ nan = _nan_type(ref_component, "id")
285
+ if np.isnan(nan):
286
+ mask = ~np.isnan(data[ref_component]["id"])
287
+ else:
288
+ mask = np.not_equal(data[ref_component]["id"], nan)
289
+ valid_ids.update(data[ref_component]["id"][mask])
290
+
291
+ return list(valid_ids)
292
+
293
+
294
+ def _get_mask(data: SingleDataset, component: ComponentType, field: str, **filters: Any) -> np.ndarray:
295
+ """
296
+ Get a mask based on the specified filters. E.g. measured_terminal_type=MeasuredTerminalType.source.
297
+
298
+ Args:
299
+ data: The input/update data set for all components
300
+ component: The component of interest
301
+ field: The field of interest
302
+ ref_components: The component or components in which we want to look for ids
303
+ **filters: One or more filters on the dataset. E.
304
+
305
+ Returns:
306
+ np.ndarray: the mask
307
+ """
308
+ values = data[component][field]
309
+ mask = np.ones(shape=values.shape, dtype=bool)
310
+ for filter_field, filter_value in filters.items():
311
+ mask = np.logical_and(mask, data[component][filter_field] == filter_value)
312
+
313
+ return mask
@@ -0,0 +1,178 @@
1
+ Metadata-Version: 2.4
2
+ Name: power-grid-model
3
+ Version: 1.12.69
4
+ Summary: Python/C++ library for distribution power system analysis
5
+ Author-Email: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
6
+ License-Expression: MPL-2.0
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Programming Language :: Python :: Implementation :: CPython
9
+ Classifier: Programming Language :: C++
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Operating System :: Microsoft :: Windows
14
+ Classifier: Operating System :: POSIX :: Linux
15
+ Classifier: Operating System :: MacOS
16
+ Classifier: Topic :: Scientific/Engineering :: Physics
17
+ Project-URL: Home-page, https://lfenergy.org/projects/power-grid-model/
18
+ Project-URL: GitHub, https://github.com/PowerGridModel/power-grid-model
19
+ Project-URL: Documentation, https://power-grid-model.readthedocs.io/en/stable/
20
+ Project-URL: Mailing-list, https://lists.lfenergy.org/g/powergridmodel
21
+ Project-URL: Discussion, https://github.com/orgs/PowerGridModel/discussions
22
+ Requires-Python: >=3.11
23
+ Requires-Dist: numpy>=2.0.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: msgpack; extra == "dev"
26
+ Requires-Dist: pre-commit; extra == "dev"
27
+ Requires-Dist: pytest; extra == "dev"
28
+ Requires-Dist: pytest-cov; extra == "dev"
29
+ Requires-Dist: ruff; extra == "dev"
30
+ Provides-Extra: doc
31
+ Requires-Dist: sphinx; extra == "doc"
32
+ Requires-Dist: breathe; extra == "doc"
33
+ Requires-Dist: myst_nb; extra == "doc"
34
+ Requires-Dist: sphinx_rtd_theme; extra == "doc"
35
+ Requires-Dist: readthedocs-sphinx-search; extra == "doc"
36
+ Requires-Dist: sphinx-hoverxref; extra == "doc"
37
+ Requires-Dist: sphinxcontrib-mermaid>=1.0.0; extra == "doc"
38
+ Requires-Dist: sphinxcontrib-tikz; extra == "doc"
39
+ Requires-Dist: numpydoc; extra == "doc"
40
+ Requires-Dist: pandas; extra == "doc"
41
+ Requires-Dist: gitpython; extra == "doc"
42
+ Requires-Dist: pylint; extra == "doc"
43
+ Description-Content-Type: text/markdown
44
+
45
+ <!--
46
+ SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
47
+
48
+ SPDX-License-Identifier: MPL-2.0
49
+ -->
50
+
51
+ [![PyPI version](https://badge.fury.io/py/power-grid-model.svg?no-cache)](https://badge.fury.io/py/power-grid-model) <!-- markdownlint-disable-line first-line-h1 line-length -->
52
+ [![Anaconda-Server Badge](https://anaconda.org/conda-forge/power-grid-model/badges/version.svg?no-cache)](https://anaconda.org/conda-forge/power-grid-model)
53
+ [![License: MPL2.0](https://img.shields.io/badge/License-MPL2.0-informational.svg)](https://github.com/PowerGridModel/power-grid-model/blob/main/LICENSE)
54
+ [![Downloads](https://static.pepy.tech/badge/power-grid-model)](https://pepy.tech/project/power-grid-model)
55
+ [![Downloads](https://static.pepy.tech/badge/power-grid-model/month)](https://pepy.tech/project/power-grid-model)
56
+
57
+ [![CI Build](https://github.com/PowerGridModel/power-grid-model/actions/workflows/ci.yml/badge.svg)](https://github.com/PowerGridModel/power-grid-model/actions/workflows/ci.yml)
58
+ [![docs](https://readthedocs.org/projects/power-grid-model/badge/)](https://power-grid-model.readthedocs.io/en/stable/)
59
+
60
+ [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=PowerGridModel_power-grid-model&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=PowerGridModel_power-grid-model)
61
+ [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=PowerGridModel_power-grid-model&metric=coverage)](https://sonarcloud.io/summary/new_code?id=PowerGridModel_power-grid-model)
62
+ [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=PowerGridModel_power-grid-model&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=PowerGridModel_power-grid-model)
63
+ [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=PowerGridModel_power-grid-model&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=PowerGridModel_power-grid-model)
64
+ [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=PowerGridModel_power-grid-model&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=PowerGridModel_power-grid-model)
65
+ [![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=PowerGridModel_power-grid-model&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=PowerGridModel_power-grid-model)
66
+
67
+ [![Nightly build](https://github.com/PowerGridModel/power-grid-model/actions/workflows/nightly.yml/badge.svg)](https://github.com/PowerGridModel/power-grid-model/actions/workflows/nightly.yml)
68
+
69
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.8054429.svg)](https://zenodo.org/record/8054429)
70
+
71
+ [![Power Grid Model logo](https://github.com/PowerGridModel/.github/blob/main/artwork/svg/color.svg)](#) <!-- markdownlint-disable-line no-empty-links line-length -->
72
+
73
+ # Power Grid Model
74
+
75
+ `power-grid-model` is a library for steady-state distribution power system analysis distributed for Python and C.
76
+ The core of the library is written in C++.
77
+ Currently, it supports the following calculations:
78
+
79
+ * Power Flow
80
+ * State Estimation
81
+ * Short Circuit
82
+
83
+ See the [power-grid-model documentation](https://power-grid-model.readthedocs.io/en/stable/) for more information.
84
+ For various conversions to the power-grid-model, refer to the
85
+ [power-grid-model-io](https://github.com/PowerGridModel/power-grid-model-io) repository.
86
+ For an extended python interface to the the power-grid-model, refer to the
87
+ [power-grid-model-ds](https://github.com/PowerGridModel/power-grid-model-ds) repository.
88
+
89
+ ```{note}
90
+ Want to be updated on the latest news and releases? Subscribe to the Power Grid Model mailing list by sending an (empty)
91
+ email to: powergridmodel+subscribe@lists.lfenergy.org
92
+ ```
93
+
94
+ ## Installation
95
+
96
+ ### Install from PyPI
97
+
98
+ You can directly install the package from PyPI.
99
+
100
+ ```sh
101
+ pip install power-grid-model
102
+ ```
103
+
104
+ ### Install from Conda
105
+
106
+ If you are using `conda`, you can directly install the package from `conda-forge` channel.
107
+
108
+ ```sh
109
+ conda install -c conda-forge power-grid-model
110
+ ```
111
+
112
+ ### Build and install from Source
113
+
114
+ To install the library from source, refer to the
115
+ [Build Guide](https://power-grid-model.readthedocs.io/en/stable/advanced_documentation/build-guide.html).
116
+
117
+ ## Examples
118
+
119
+ Please refer to [Examples](https://github.com/PowerGridModel/power-grid-model-workshop/tree/main/examples) for more
120
+ detailed examples for power flow and state estimation.
121
+ Notebooks for validating the input data and exporting input/output data are also included.
122
+
123
+ ## License
124
+
125
+ This project is licensed under the Mozilla Public License, version 2.0 - see
126
+ [LICENSE](https://github.com/PowerGridModel/power-grid-model/blob/main/LICENSE) for details.
127
+
128
+ ## Licenses third-party libraries
129
+
130
+ This project includes third-party libraries,
131
+ which are licensed under their own respective Open-Source licenses.
132
+ SPDX-License-Identifier headers are used to show which license is applicable.
133
+ The concerning license files can be found in the
134
+ [LICENSES](https://github.com/PowerGridModel/power-grid-model/tree/main/LICENSES) directory.
135
+
136
+ ## Contributing
137
+
138
+ Please read [CODE_OF_CONDUCT](https://github.com/PowerGridModel/.github/blob/main/CODE_OF_CONDUCT.md),
139
+ [CONTRIBUTING](https://github.com/PowerGridModel/.github/blob/main/CONTRIBUTING.md),
140
+ [PROJECT GOVERNANCE](https://github.com/PowerGridModel/.github/blob/main/GOVERNANCE.md) and
141
+ [RELEASE](https://github.com/PowerGridModel/.github/blob/main/RELEASE.md) for details on the process for submitting pull
142
+ requests to us.
143
+
144
+ Visit [Contribute](https://github.com/PowerGridModel/power-grid-model/contribute) for a list of good first issues in
145
+ this repo.
146
+
147
+ ## Citations
148
+
149
+ If you are using Power Grid Model in your research work, please consider citing our library using the following
150
+ references.
151
+
152
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.8054429.svg)](https://zenodo.org/record/8054429)
153
+
154
+ ```bibtex
155
+ @software{Xiang_PowerGridModel_power-grid-model,
156
+ author = {Xiang, Yu and Salemink, Peter and van Westering, Werner and Bharambe, Nitish and Govers, Martinus G.H. and van den Bogaard, Jonas and Stoeller, Bram and Wang, Zhen and Guo, Jerry Jinfeng and Figueroa Manrique, Santiago and Jagutis, Laurynas and Wang, Chenguang and van Raalte, Marc and {Contributors to the LF Energy project Power Grid Model}},
157
+ doi = {10.5281/zenodo.8054429},
158
+ license = {MPL-2.0},
159
+ title = {{PowerGridModel/power-grid-model}},
160
+ url = {https://github.com/PowerGridModel/power-grid-model}
161
+ }
162
+ @inproceedings{Xiang2023,
163
+ author = {Xiang, Yu and Salemink, Peter and Stoeller, Bram and Bharambe, Nitish and van Westering, Werner},
164
+ booktitle={27th International Conference on Electricity Distribution (CIRED 2023)},
165
+ title={Power grid model: a high-performance distribution grid calculation library},
166
+ year={2023},
167
+ volume={2023},
168
+ number={},
169
+ pages={1089-1093},
170
+ keywords={},
171
+ doi={10.1049/icp.2023.0633}
172
+ }
173
+ ```
174
+
175
+ ## Contact
176
+
177
+ Please read [SUPPORT](https://github.com/PowerGridModel/.github/blob/main/SUPPORT.md) for how to connect and get into
178
+ contact with the Power Grid Model project.
@@ -0,0 +1,65 @@
1
+ power_grid_model/__init__.py,sha256=MCR8e5waIpbrq_7mPL7PxGxkQgfJ_Qh8de8RvfGCrc0,1379
2
+ power_grid_model/data_types.py,sha256=F-AcNx_qBtwoNvdMg8TDds8QO-l5G7ZDb_TFBu_SJao,9909
3
+ power_grid_model/enum.py,sha256=ZF3C3maM2RGaqR42qNbNQeKjocFxvHDALdHP3Kzn6bY,701
4
+ power_grid_model/errors.py,sha256=EYsbYk1l8t_Fc8GiPFSuI6mKbOlaJvA4Lr4gW4etSOM,951
5
+ power_grid_model/py.typed,sha256=_vY4oOk4Z8YqiFeJ3N6UKKXdI6MBROOBRnfAOmFNI-8,133
6
+ power_grid_model/typing.py,sha256=sKQftXz-LbKoaGn23ijLGMvUZIwhvXHfLwYPGajGCj8,1289
7
+ power_grid_model/utils.py,sha256=Fv360Majx-UaJa8UOiJbUMxBEkdofVR--zdLCiGGH2c,17420
8
+ power_grid_model/_core/__init__.py,sha256=qwbj1j-Aa_yRB-E3j35pEVtF3mgH8CVIXAnog5mOry0,138
9
+ power_grid_model/_core/buffer_handling.py,sha256=nEYYE0Hif0Vm5mwIu2A7xiUMnWjX9duXV9NtZ0s68FY,15453
10
+ power_grid_model/_core/data_handling.py,sha256=TCnoNYoLxYn0yDMN7FPp4PH3nK5wVX_q75QaujHcSyw,6930
11
+ power_grid_model/_core/data_types.py,sha256=KCOnBpQ6X833jZw61fbAAZ7Rwd-uSQ3J-7Y268YgaMM,4739
12
+ power_grid_model/_core/dataset_definitions.py,sha256=HytgmDLzjqt8R6VnVO0QwuM5dGPXcWehNVLJ8sWq_-k,3305
13
+ power_grid_model/_core/enum.py,sha256=cGRC_Ua0_S6t9w8TxRpQ8OZivQc1_vH98z30ixg4oVA,4936
14
+ power_grid_model/_core/error_handling.py,sha256=vtZ04Q3c3CC94W4aEXgA1y9-Gps5ZUN2qz295BM_jE4,8816
15
+ power_grid_model/_core/errors.py,sha256=1votmXwlXbHEW8GL0_DKScJACLr3X7iuj4Wnc0tnT2U,3346
16
+ power_grid_model/_core/index_integer.py,sha256=-9xutg1yIn5lpfFl1jOofAym1922Z5xDDYoO9eqvDS8,351
17
+ power_grid_model/_core/options.py,sha256=i__QhCgk0idg-WF1jXUXae5PZ5qh1RMIgwYe8kb4fSI,1878
18
+ power_grid_model/_core/power_grid_core.py,sha256=sE1I6DEanAifUEnAgiVLUzMdMR1CCLO3f8jl20cpR2c,17059
19
+ power_grid_model/_core/power_grid_dataset.py,sha256=W50zKT1IyXVQYRENqoQThtEHDPttwGjM9EMdxR3wSkU,18372
20
+ power_grid_model/_core/power_grid_meta.py,sha256=pR1pLy_jGplTCnzaZBcm8WUSbvbwejyB8U4G-AFwflU,7758
21
+ power_grid_model/_core/power_grid_model.py,sha256=3wZj0Kp1ypXrXl0-210UHmZ0yR9EEZD30XDYDXAlW_c,40005
22
+ power_grid_model/_core/serialization.py,sha256=aZBr9qjYiYi1jcwfDk267euMf7WSHlMvNgcDYZ5KCBA,10049
23
+ power_grid_model/_core/typing.py,sha256=Mt1DJ62tHS3R9SQzdvM64L6Q8tvMCPQVAKGHAt8GM0U,637
24
+ power_grid_model/_core/utils.py,sha256=n2n2NnbwiL89kxNIg7-EBHOYNR5e9a4O2ExP5uaxz7M,31171
25
+ power_grid_model/_core/power_grid_model_c/__init__.py,sha256=qwbj1j-Aa_yRB-E3j35pEVtF3mgH8CVIXAnog5mOry0,138
26
+ power_grid_model/_core/power_grid_model_c/get_pgm_dll_path.py,sha256=GAgIamBAMNA40KejjE9ODny6RpFQ-9MvN3kjr_xC5fc,2161
27
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_c.h,sha256=Z6z4vSMpgvkCT-mw0ATXnANg7qSEKM6LTs8VFCLr3S0,1704
28
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp.hpp,sha256=YoXBbYoxyBiOfbbrM1kheKZaCyobVzclTP4BREYSeOQ,655
29
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/basics.h,sha256=ticq5jaRFhjCMVPs2oHk9EicI5m2Vao--OuZpLaSXL8,7514
30
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/buffer.h,sha256=A-ByuDfQmPCYf5HCeOHim872DiwA66ORHcw17HnptIE,4658
31
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/dataset.h,sha256=yuCnInKgUEHn77htlt4Pqq2QKsthcRIUFPCWpPeaYUM,14468
32
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/dataset_definitions.h,sha256=d87mYGjzDjlk5oD_5OAsHpYhjPyiFtjbG0Gu9LHDi-Y,74571
33
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/handle.h,sha256=bxHBCqdewukaqKKKfCih95zbf06hDCMKf7tnxE5-jBQ,3100
34
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/meta_data.h,sha256=JacYKWKTW-x8uiKtsA76pLFLmWXEkksCQa_l3eDQPWo,6064
35
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/model.h,sha256=5YvpIUdMNgI0CTiEERhwpQQy6A3yreEe3bFjSI4ZNnA,5039
36
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/options.h,sha256=8H9lsT8Ho3c-2gvBJx1xTvMeOALnC4493n0Pb_dLfBQ,4546
37
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/serialization.h,sha256=e72XduQwRZme-HIa01FDrjf0tcY7O9N1mBtdOMxv-5U,5196
38
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/basics.hpp,sha256=qv3ZjkNBKj9pQT0waggWjF8TcOzq4Ib0NEb0n9DRtEA,2213
39
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/buffer.hpp,sha256=eX1wEMFM3hPbYGQiikA58pW0zo6MArm5NeLkwSF57Gg,2397
40
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/dataset.hpp,sha256=IkJwBbkrBix-Ef0G26RxqzEUPVQ7zrm2fENh1QYdFDc,9159
41
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/handle.hpp,sha256=D_9HSwGKqxucesOr-VsHl5m102r5sV-XJ25t3SxGb24,4059
42
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/meta_data.hpp,sha256=amqU0GvxKifuEvi9pxg1vsJcEtXumWZF89rd8wRKugE,3252
43
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/model.hpp,sha256=WCQX4px3Ts6v69UD98suq-TLUdaFFyAmJdN0fxV3xrQ,2228
44
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/options.hpp,sha256=unyQ10NEUIgP_cx2jH6w9lseEFtYfn9DTwganUT2bHg,1842
45
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/serialization.hpp,sha256=LIkQYR3EMEOVP2RzmlZjIRBxshEvju2IcWvzCu4edLM,5488
46
+ power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/utils.hpp,sha256=6ChIg9Oen4T3kCGkhPbPlTaVg82ujJ28OUSfXsJlWRI,2968
47
+ power_grid_model/_core/power_grid_model_c/lib/cmake/power_grid_model/power_grid_modelConfig.cmake,sha256=9Dg_TwOMLciG7TTk1TKehfUbAErFtJlRagTeu_QC8Vg,1243
48
+ power_grid_model/_core/power_grid_model_c/lib/cmake/power_grid_model/power_grid_modelConfigVersion.cmake,sha256=kYVm6iShodg7gwd3HjD8CqEkAEamFSM0-80hk2rmdcg,2768
49
+ power_grid_model/_core/power_grid_model_c/lib/cmake/power_grid_model/power_grid_modelTargets-release.cmake,sha256=D8cpmXLfyYoNR2WkROODJw0iqQ8c2MZ_ckymUw9CW_g,1010
50
+ power_grid_model/_core/power_grid_model_c/lib/cmake/power_grid_model/power_grid_modelTargets.cmake,sha256=q8v9QYCdmb_xsFXU1A_iSJv9_-euneAsmIgKBS4dBCI,6564
51
+ power_grid_model/_core/power_grid_model_c/lib64/libpower_grid_model_c.so,sha256=UcB3F37xp7gN9AHY0rb5o1fpFW25N8WvXe5XjnZ3LTw,2563848
52
+ power_grid_model/_core/power_grid_model_c/lib64/libpower_grid_model_c.so.1.12.69,sha256=UcB3F37xp7gN9AHY0rb5o1fpFW25N8WvXe5XjnZ3LTw,2563848
53
+ power_grid_model/_core/power_grid_model_c/share/LICENSE,sha256=7Pm2fWFFHHUG5lDHed1vl5CjzxObIXQglnYsEdtjo_k,14907
54
+ power_grid_model/_core/power_grid_model_c/share/README.md,sha256=X2nGLPPQW6-7ZcyMxAw98j-69z5-gFwSoUCuFFDhjlA,588
55
+ power_grid_model/validation/__init__.py,sha256=3k2wLJS3nkEdsM17_k4-zNMHgbflLmPOnsfR34pUPpA,818
56
+ power_grid_model/validation/_rules.py,sha256=Bj1UTtHYEec-H0SUGkiFxS13lIhOforXLAgZuSI405I,52157
57
+ power_grid_model/validation/_validation.py,sha256=z40DDIPAf3MUEGQmwOrZYg3YYAnp_Wq4gkCEIK0pl6g,48781
58
+ power_grid_model/validation/assertions.py,sha256=VmbiLTU04Lu5GDywKrcjNVEQcDiGxQLoUE-hlI790_Q,4102
59
+ power_grid_model/validation/errors.py,sha256=hpXM46rNvlELJvyr3_rLOoGeJb6MLdPx-CylFuPuRF0,20453
60
+ power_grid_model/validation/utils.py,sha256=A5ciWb8fwM6r0uzMmgz5TPtmXhr-oJeRKrCtTO4j5TM,12784
61
+ power_grid_model-1.12.69.dist-info/METADATA,sha256=JwLQgYSoF-lALDGNcGWMdFSuOhaHPTUVS8ATSa2jjuo,9062
62
+ power_grid_model-1.12.69.dist-info/WHEEL,sha256=O4BEFiq2MTWo7p3DyZlV4VLDSelqndzLPZAsLfQTYz0,151
63
+ power_grid_model-1.12.69.dist-info/entry_points.txt,sha256=KgNx7mGcOVAVuwCBeP30AH5h_8UrKf0DQA9Cs5td69w,75
64
+ power_grid_model-1.12.69.dist-info/RECORD,,
65
+ power_grid_model-1.12.69.dist-info/licenses/LICENSE,sha256=7Pm2fWFFHHUG5lDHed1vl5CjzxObIXQglnYsEdtjo_k,14907
@@ -0,0 +1,6 @@
1
+ Wheel-Version: 1.0
2
+ Generator: scikit-build-core 0.11.6
3
+ Root-Is-Purelib: false
4
+ Tag: py3-none-manylinux_2_26_x86_64
5
+ Tag: py3-none-manylinux_2_28_x86_64
6
+
@@ -0,0 +1,3 @@
1
+ [cmake.root]
2
+ power_grid_model = power_grid_model._core.power_grid_model_c
3
+